CloudOptRL / tests /test_pytorch_integration.py
gagan-devv's picture
Initial submission
cb922bf
Raw History Blame Contribute Delete
3.92 kB
"""
Unit tests for PyTorch integration in CloudResourceEnv.
This module tests the minimal PyTorch tensor-based state representation
added to the environment while ensuring NumPy compatibility is maintained.
"""
import pytest
import numpy as np
import torch
from env.environment import CloudResourceEnv
from env.config import EnvConfig
def test_get_state_tensor_returns_torch_tensor():
"""Test that get_state_tensor returns a PyTorch tensor."""
env = CloudResourceEnv()
env.reset()
state_tensor = env.get_state_tensor()
assert isinstance(state_tensor, torch.Tensor), "get_state_tensor should return a torch.Tensor"
def test_get_state_tensor_matches_numpy_observation():
"""Test that PyTorch tensor state matches NumPy observation."""
env = CloudResourceEnv()
observation = env.reset()
state_tensor = env.get_state_tensor()
# Convert tensor to numpy for comparison
tensor_as_numpy = state_tensor.numpy()
# Should match the observation exactly
np.testing.assert_array_equal(
tensor_as_numpy,
observation,
err_msg="PyTorch tensor state should match NumPy observation"
)
def test_get_state_tensor_after_step():
"""Test that get_state_tensor works correctly after environment steps."""
env = CloudResourceEnv()
env.reset()
# Take a step
observation, reward, done, info = env.step(CloudResourceEnv.ACTION_INCREASE)
# Get tensor representation
state_tensor = env.get_state_tensor()
# Verify it matches the observation
tensor_as_numpy = state_tensor.numpy()
np.testing.assert_array_equal(
tensor_as_numpy,
observation,
err_msg="Tensor state should match observation after step"
)
def test_get_state_tensor_shape():
"""Test that state tensor has correct shape."""
env = CloudResourceEnv()
env.reset()
state_tensor = env.get_state_tensor()
assert state_tensor.shape == (4,), f"State tensor should have shape (4,), got {state_tensor.shape}"
def test_get_state_tensor_dtype():
"""Test that state tensor has correct dtype (float32)."""
env = CloudResourceEnv()
env.reset()
state_tensor = env.get_state_tensor()
assert state_tensor.dtype == torch.float32, f"State tensor should be float32, got {state_tensor.dtype}"
def test_numpy_compatibility_maintained():
"""Test that existing NumPy-based functionality still works."""
env = CloudResourceEnv()
# Reset should still return NumPy array
observation = env.reset()
assert isinstance(observation, np.ndarray), "reset() should still return NumPy array"
# Step should still return NumPy array
observation, reward, done, info = env.step(CloudResourceEnv.ACTION_MAINTAIN)
assert isinstance(observation, np.ndarray), "step() should still return NumPy array"
def test_get_state_tensor_multiple_calls():
"""Test that multiple calls to get_state_tensor return consistent results."""
env = CloudResourceEnv()
env.reset()
tensor1 = env.get_state_tensor()
tensor2 = env.get_state_tensor()
# Should be equal since state hasn't changed
assert torch.equal(tensor1, tensor2), "Multiple calls should return equal tensors"
def test_get_state_tensor_updates_with_state():
"""Test that state tensor updates when environment state changes."""
env = CloudResourceEnv()
env.reset()
tensor_before = env.get_state_tensor().clone()
# Take multiple steps to ensure state changes
for _ in range(5):
observation, reward, done, info = env.step(CloudResourceEnv.ACTION_INCREASE)
if done:
break
tensor_after = env.get_state_tensor()
# Tensors should be different (state has changed)
assert not torch.equal(tensor_before, tensor_after), "State tensor should update with environment state"