2022-06-23 13:54:50 +01:00
""" Tests that gym.make works as expected. """
import re
2022-08-30 19:47:26 +01:00
import warnings
2022-07-11 02:45:24 +01:00
from copy import deepcopy
2022-06-23 13:54:50 +01:00
2022-06-24 22:25:58 +02:00
import numpy as np
2022-06-23 13:54:50 +01:00
import pytest
import gym
from gym . envs . classic_control import cartpole
2022-06-24 22:25:58 +02:00
from gym . wrappers import AutoResetWrapper , HumanRendering , OrderEnforcing , TimeLimit
2022-06-23 13:54:50 +01:00
from gym . wrappers . env_checker import PassiveEnvChecker
2022-07-11 02:45:24 +01:00
from tests . envs . test_envs import PASSIVE_CHECK_IGNORE_WARNING
2022-06-23 13:54:50 +01:00
from tests . envs . utils import all_testing_env_specs
from tests . envs . utils_envs import ArgumentEnv , RegisterDuringMakeEnv
from tests . wrappers . utils import has_wrapper
gym . register (
" RegisterDuringMakeEnv-v0 " ,
entry_point = " tests.envs.utils_envs:RegisterDuringMakeEnv " ,
)
gym . register (
id = " test.ArgumentEnv-v0 " ,
entry_point = " tests.envs.utils_envs:ArgumentEnv " ,
kwargs = {
" arg1 " : " arg1 " ,
" arg2 " : " arg2 " ,
} ,
)
2022-06-24 22:25:58 +02:00
gym . register (
id = " test/NoHuman-v0 " ,
entry_point = " tests.envs.utils_envs:NoHuman " ,
)
gym . register (
id = " test/NoHumanOldAPI-v0 " ,
entry_point = " tests.envs.utils_envs:NoHumanOldAPI " ,
)
gym . register (
id = " test/NoHumanNoRGB-v0 " ,
entry_point = " tests.envs.utils_envs:NoHumanNoRGB " ,
)
2022-06-23 13:54:50 +01:00
def test_make ( ) :
env = gym . make ( " CartPole-v1 " , disable_env_checker = True )
assert env . spec . id == " CartPole-v1 "
assert isinstance ( env . unwrapped , cartpole . CartPoleEnv )
env . close ( )
def test_make_deprecated ( ) :
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) :
with pytest . raises (
gym . error . Error ,
match = re . escape (
" Environment version v0 for `Humanoid` is deprecated. Please use `Humanoid-v4` instead. "
) ,
) :
gym . make ( " Humanoid-v0 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
def test_make_max_episode_steps ( ) :
# Default, uses the spec's
env = gym . make ( " CartPole-v1 " , disable_env_checker = True )
assert has_wrapper ( env , TimeLimit )
assert (
env . spec . max_episode_steps == gym . envs . registry [ " CartPole-v1 " ] . max_episode_steps
)
env . close ( )
# Custom max episode steps
env = gym . make ( " CartPole-v1 " , max_episode_steps = 100 , disable_env_checker = True )
assert has_wrapper ( env , TimeLimit )
assert env . spec . max_episode_steps == 100
env . close ( )
# Env spec has no max episode steps
assert gym . spec ( " test.ArgumentEnv-v0 " ) . max_episode_steps is None
env = gym . make (
" test.ArgumentEnv-v0 " , arg1 = None , arg2 = None , arg3 = None , disable_env_checker = True
)
assert has_wrapper ( env , TimeLimit ) is False
env . close ( )
def test_gym_make_autoreset ( ) :
""" Tests that `gym.make` autoreset wrapper is applied only when `gym.make(..., autoreset=True)`. """
env = gym . make ( " CartPole-v1 " , disable_env_checker = True )
assert has_wrapper ( env , AutoResetWrapper ) is False
env . close ( )
env = gym . make ( " CartPole-v1 " , autoreset = False , disable_env_checker = True )
assert has_wrapper ( env , AutoResetWrapper ) is False
env . close ( )
env = gym . make ( " CartPole-v1 " , autoreset = True )
assert has_wrapper ( env , AutoResetWrapper )
env . close ( )
def test_make_disable_env_checker ( ) :
""" Tests that `gym.make` disable env checker is applied only when `gym.make(..., disable_env_checker=False)`. """
2022-07-11 02:45:24 +01:00
spec = deepcopy ( gym . spec ( " CartPole-v1 " ) )
# Test with spec disable env checker
spec . disable_env_checker = False
env = gym . make ( spec )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , PassiveEnvChecker )
env . close ( )
2022-07-11 02:45:24 +01:00
# Test with overwritten spec using make disable env checker
assert spec . disable_env_checker is False
env = gym . make ( spec , disable_env_checker = True )
assert has_wrapper ( env , PassiveEnvChecker ) is False
2022-06-23 13:54:50 +01:00
env . close ( )
2022-07-11 02:45:24 +01:00
# Test with spec enabled disable env checker
spec . disable_env_checker = True
env = gym . make ( spec )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , PassiveEnvChecker ) is False
env . close ( )
2022-07-11 02:45:24 +01:00
# Test with overwritten spec using make disable env checker
assert spec . disable_env_checker is True
env = gym . make ( spec , disable_env_checker = False )
assert has_wrapper ( env , PassiveEnvChecker )
env . close ( )
@pytest.mark.parametrize (
" spec " , all_testing_env_specs , ids = [ spec . id for spec in all_testing_env_specs ]
)
def test_passive_checker_wrapper_warnings ( spec ) :
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) as caught_warnings :
2022-07-11 02:45:24 +01:00
env = gym . make ( spec ) # disable_env_checker=False
env . reset ( )
env . step ( env . action_space . sample ( ) )
# todo, add check for render, bugged due to mujoco v2/3 and v4 envs
env . close ( )
2022-08-30 19:47:26 +01:00
for warning in caught_warnings :
2022-07-11 02:45:24 +01:00
if warning . message . args [ 0 ] not in PASSIVE_CHECK_IGNORE_WARNING :
raise gym . error . Error ( f " Unexpected warning: { warning . message } " )
2022-06-23 13:54:50 +01:00
def test_make_order_enforcing ( ) :
""" Checks that gym.make wrappers the environment with the OrderEnforcing wrapper. """
assert all ( spec . order_enforce is True for spec in all_testing_env_specs )
env = gym . make ( " CartPole-v1 " , disable_env_checker = True )
assert has_wrapper ( env , OrderEnforcing )
# We can assume that there all other specs will also have the order enforcing
env . close ( )
gym . register (
id = " test.OrderlessArgumentEnv-v0 " ,
entry_point = " tests.envs.utils_envs:ArgumentEnv " ,
order_enforce = False ,
kwargs = { " arg1 " : None , " arg2 " : None , " arg3 " : None } ,
)
env = gym . make ( " test.OrderlessArgumentEnv-v0 " , disable_env_checker = True )
assert has_wrapper ( env , OrderEnforcing ) is False
env . close ( )
def test_make_render_mode ( ) :
env = gym . make ( " CartPole-v1 " , disable_env_checker = True )
assert env . render_mode is None
env . close ( )
2022-06-24 22:25:58 +02:00
# Make sure that render_mode is applied correctly
env = gym . make ( " CartPole-v1 " , render_mode = " rgb_array " , disable_env_checker = True )
assert env . render_mode == " rgb_array "
env . reset ( )
renders = env . render ( )
assert isinstance (
renders , list
) # Make sure that the `render` method does what is supposed to
assert isinstance ( renders [ 0 ] , np . ndarray )
env . close ( )
2022-06-23 13:54:50 +01:00
env = gym . make ( " CartPole-v1 " , render_mode = None , disable_env_checker = True )
assert env . render_mode is None
valid_render_modes = env . metadata [ " render_modes " ]
env . close ( )
assert len ( valid_render_modes ) > 0
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) as caught_warnings :
2022-06-23 13:54:50 +01:00
env = gym . make (
" CartPole-v1 " , render_mode = valid_render_modes [ 0 ] , disable_env_checker = True
)
assert env . render_mode == valid_render_modes [ 0 ]
env . close ( )
2022-08-30 19:47:26 +01:00
for warning in caught_warnings :
2022-07-10 02:18:06 +05:30
if not re . compile ( " .*step API.* " ) . match ( warning . message . args [ 0 ] ) :
raise gym . error . Error ( f " Unexpected warning: { warning . message } " )
2022-06-23 13:54:50 +01:00
2022-06-24 22:25:58 +02:00
# Make sure that native rendering is used when possible
env = gym . make ( " CartPole-v1 " , render_mode = " human " , disable_env_checker = True )
assert not has_wrapper ( env , HumanRendering ) # Should use native human-rendering
assert env . render_mode == " human "
env . close ( )
2022-07-01 15:47:10 +02:00
with pytest . warns (
2022-08-30 19:47:26 +01:00
UserWarning ,
2022-07-01 15:47:10 +02:00
match = re . escape (
" You are trying to use ' human ' rendering for an environment that doesn ' t natively support it. The HumanRendering wrapper is being applied to your environment. "
) ,
) :
# Make sure that `HumanRendering` is applied here
env = gym . make (
" test/NoHuman-v0 " , render_mode = " human " , disable_env_checker = True
) # This environment doesn't use native rendering
assert has_wrapper ( env , HumanRendering )
assert env . render_mode == " human "
env . close ( )
2022-06-24 22:25:58 +02:00
with pytest . raises (
2022-07-01 15:47:10 +02:00
TypeError , match = re . escape ( " got an unexpected keyword argument ' render_mode ' " )
) :
gym . make (
" test/NoHumanOldAPI-v0 " , render_mode = " rgb_array " , disable_env_checker = True
)
# Make sure that an additional error is thrown a user tries to use the wrapper on an environment with old API
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) :
with pytest . raises (
gym . error . Error ,
match = re . escape (
" You passed render_mode= ' human ' although test/NoHumanOldAPI-v0 doesn ' t implement human-rendering natively. "
) ,
) :
gym . make (
" test/NoHumanOldAPI-v0 " , render_mode = " human " , disable_env_checker = True
)
2022-06-24 22:25:58 +02:00
2022-07-01 15:47:10 +02:00
# This test ensures that the additional exception "Gym tried to apply the HumanRendering wrapper but it looks like
# your environment is using the old rendering API" is *not* triggered by a TypeError that originate from
# a keyword that is not `render_mode`
with pytest . raises (
TypeError ,
match = re . escape ( " got an unexpected keyword argument ' render ' " ) ,
) :
2022-07-14 13:35:02 +01:00
gym . make ( " CarRacing-v2 " , render = " human " )
2022-07-01 15:47:10 +02:00
2022-06-23 13:54:50 +01:00
def test_make_kwargs ( ) :
env = gym . make (
" test.ArgumentEnv-v0 " ,
arg2 = " override_arg2 " ,
arg3 = " override_arg3 " ,
disable_env_checker = True ,
)
assert env . spec . id == " test.ArgumentEnv-v0 "
assert isinstance ( env . unwrapped , ArgumentEnv )
assert env . arg1 == " arg1 "
assert env . arg2 == " override_arg2 "
assert env . arg3 == " override_arg3 "
env . close ( )
def test_import_module_during_make ( ) :
# Test custom environment which is registered at make
env = gym . make (
" tests.envs.utils:RegisterDuringMakeEnv-v0 " ,
disable_env_checker = True ,
)
assert isinstance ( env . unwrapped , RegisterDuringMakeEnv )
env . close ( )