Skip to content

Commit

Permalink
Test necessary imports (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
pseudo-rnd-thoughts authored Dec 1, 2022
1 parent 320b52c commit e9f4655
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 83 deletions.
21 changes: 17 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,29 @@ permissions:
contents: read # to fetch code (actions/checkout)

jobs:
build:
build-all:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
steps:
- uses: actions/checkout@v2
- run: |
docker build -f py.Dockerfile \
docker build -f bin/all-py.Dockerfile \
--build-arg PYTHON_VERSION=${{ matrix.python-version }} \
--tag gymnasium-docker .
--tag gymnasium-all-docker .
- name: Run tests
run: docker run gymnasium-docker pytest
run: docker run gymnasium-all-docker pytest tests/*

build-necessary:
runs-on:
ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: |
docker build -f bin/necessary-py.Dockerfile \
--build-arg PYTHON_VERSION='3.10' \
--tag gymnasium-necessary-docker .
- name: Run tests
run: |
docker run gymnasium-necessary-docker pytest tests/test_core.py tests/envs/test_compatibility.py tests/envs/test_envs.py tests/spaces
2 changes: 1 addition & 1 deletion py.Dockerfile → bin/all-py.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/root/.mujoco/mujoco210/bin"
COPY . /usr/local/gymnasium/
WORKDIR /usr/local/gymnasium/

RUN pip install .[testing] --no-cache-dir
RUN pip install .[all,testing] --no-cache-dir

ENTRYPOINT ["/usr/local/gymnasium/bin/docker_entrypoint"]
25 changes: 25 additions & 0 deletions bin/necessary-py.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# A Dockerfile that sets up a full Gymnasium install with test dependencies
ARG PYTHON_VERSION
FROM python:$PYTHON_VERSION

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

RUN apt-get -y update \
&& apt-get install --no-install-recommends -y \
unzip \
libglu1-mesa-dev \
libgl1-mesa-dev \
libosmesa6-dev \
xvfb \
patchelf \
ffmpeg cmake \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

COPY . /usr/local/gymnasium/
WORKDIR /usr/local/gymnasium/

RUN pip install .[testing] --no-cache-dir

ENTRYPOINT ["/usr/local/gymnasium/bin/docker_entrypoint"]
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Setups the project."""
import itertools
from typing import Dict, List

from setuptools import find_packages, setup

Expand Down Expand Up @@ -32,7 +33,7 @@ def get_version():


# Environment-specific dependencies.
extras = {
extras: Dict[str, List[str]] = {
"atari": ["shimmy[atari]>=0.1.0,<1.0"],
"accept-rom-license": ["autorom[accept-rom-license]~=0.4.2"],
"box2d": ["box2d-py==2.3.5", "pygame==2.1.0", "swig==4.*"],
Expand All @@ -44,15 +45,14 @@ def get_version():
"other": ["lz4>=3.1.0", "opencv-python>=3.0", "matplotlib>=3.0", "moviepy>=1.0.0"],
}

extras["testing"] = list(set(itertools.chain.from_iterable(extras.values()))) + [
"pytest==7.1.3",
]

# All dependency groups - accept rom license as requires user to run
all_groups = set(extras.keys()) - {"accept-rom-license"}
extras["all"] = list(
set(itertools.chain.from_iterable(map(lambda group: extras[group], all_groups)))
)
extras["testing"] = [
"pytest==7.1.3",
]

version = get_version()
header_count, long_description = get_description()
Expand Down
73 changes: 1 addition & 72 deletions tests/envs/test_envs.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import pickle
import warnings

import numpy as np
import pytest

import gymnasium as gym
from gymnasium.envs.registration import EnvSpec
from gymnasium.logger import warn
from gymnasium.utils.env_checker import check_env, data_equivalence
from tests.envs.utils import (
all_testing_env_specs,
Expand Down Expand Up @@ -44,7 +42,7 @@ def test_envs_pass_env_checker(spec):
"""Check that all environments pass the environment checker with no warnings other than the expected."""
with warnings.catch_warnings(record=True) as caught_warnings:
env = spec.make(disable_env_checker=True).unwrapped
check_env(env)
check_env(env, skip_render_check=True)

env.close()

Expand Down Expand Up @@ -119,75 +117,6 @@ def test_env_determinism_rollout(env_spec: EnvSpec):
env_2.close()


def check_rendered(rendered_frame, mode: str):
"""Check that the rendered frame is as expected."""
if mode == "rgb_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "rgb_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 3
assert rendered_frame.shape[2] == 3
assert np.all(rendered_frame >= 0) and np.all(rendered_frame <= 255)
elif mode == "ansi":
assert isinstance(rendered_frame, str)
assert len(rendered_frame) > 0
elif mode == "state_pixels_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "state_pixels":
check_rendered(rendered_frame, "rgb_array")
elif mode == "depth_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "depth_array")
elif mode == "depth_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 2
else:
warn(
f"Unknown render mode: {mode}, cannot check that the rendered data is correct. Add case to `check_rendered`"
)


# We do not check render_mode for some mujoco envs and any old Gym environment wrapped by `GymEnvironment`
render_mode_env_specs = [
spec
for spec in all_testing_env_specs
if "mujoco" not in spec.entry_point or "v4" in spec.id
]


@pytest.mark.parametrize(
"spec", render_mode_env_specs, ids=[spec.id for spec in render_mode_env_specs]
)
def test_render_modes(spec):
"""There is a known issue where rendering a mujoco environment then mujoco-py will cause an error on non-mac based systems.
Therefore, we are only testing with mujoco environments.
"""
env = spec.make()

assert "rgb_array" in env.metadata["render_modes"]

for mode in env.metadata["render_modes"]:
if mode != "human":
new_env = spec.make(render_mode=mode)

new_env.reset()
rendered = new_env.render()
check_rendered(rendered, mode)

new_env.step(new_env.action_space.sample())
rendered = new_env.render()
check_rendered(rendered, mode)

new_env.close()
env.close()


@pytest.mark.parametrize(
"env",
all_testing_initialised_envs,
Expand Down
74 changes: 74 additions & 0 deletions tests/envs/test_rendering.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import numpy as np
import pytest

from gymnasium.logger import warn
from tests.envs.utils import all_testing_env_specs


def check_rendered(rendered_frame, mode: str):
"""Check that the rendered frame is as expected."""
if mode == "rgb_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "rgb_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 3
assert rendered_frame.shape[2] == 3
assert np.all(rendered_frame >= 0) and np.all(rendered_frame <= 255)
elif mode == "ansi":
assert isinstance(rendered_frame, str)
assert len(rendered_frame) > 0
elif mode == "state_pixels_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "state_pixels":
check_rendered(rendered_frame, "rgb_array")
elif mode == "depth_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "depth_array")
elif mode == "depth_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 2
else:
warn(
f"Unknown render mode: {mode}, cannot check that the rendered data is correct. Add case to `check_rendered`"
)


# We do not check render_mode for some mujoco envs and any old Gym environment wrapped by `GymEnvironment`
render_mode_env_specs = [
spec
for spec in all_testing_env_specs
if "mujoco" not in spec.entry_point or "v4" in spec.id
]


@pytest.mark.parametrize(
"spec", render_mode_env_specs, ids=[spec.id for spec in render_mode_env_specs]
)
def test_render_modes(spec):
"""There is a known issue where rendering a mujoco environment then mujoco-py will cause an error on non-mac based systems.
Therefore, we are only testing with mujoco environments.
"""
env = spec.make()

assert "rgb_array" in env.metadata["render_modes"]

for mode in env.metadata["render_modes"]:
if mode != "human":
new_env = spec.make(render_mode=mode)

new_env.reset()
rendered = new_env.render()
check_rendered(rendered, mode)

new_env.step(new_env.action_space.sample())
rendered = new_env.render()
check_rendered(rendered, mode)

new_env.close()
env.close()
1 change: 0 additions & 1 deletion tests/envs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ def try_make_env(env_spec: EnvSpec) -> Optional[gym.Env]:
for ep in ["box2d", "classic_control", "toy_text"]
)
]
# TODO, add minimum testing env spec in testing


def assert_equals(a, b, prefix=None):
Expand Down

0 comments on commit e9f4655

Please sign in to comment.