Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test necessary imports #146

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
96f20ee
initial commit
pseudo-rnd-thoughts Nov 12, 2022
516019a
Update setup.py
pseudo-rnd-thoughts Nov 12, 2022
26f1511
Update setup.py
pseudo-rnd-thoughts Nov 12, 2022
a5f06bc
pre-commit
pseudo-rnd-thoughts Nov 12, 2022
1234987
Merge branch 'main' into add-shimmy
pseudo-rnd-thoughts Nov 16, 2022
6a5c2d2
Remove gym env
pseudo-rnd-thoughts Nov 16, 2022
00d0f21
Merge branch 'main' into add-shimmy
pseudo-rnd-thoughts Nov 18, 2022
5d2ba97
Fix tests
pseudo-rnd-thoughts Nov 18, 2022
030765b
pre-commit
pseudo-rnd-thoughts Nov 18, 2022
7d8cbe8
add deprecation warning
pseudo-rnd-thoughts Nov 18, 2022
7de2831
initial commit
pseudo-rnd-thoughts Nov 18, 2022
1dd4447
Separate testing and all
pseudo-rnd-thoughts Nov 18, 2022
0809bc2
Merge branch 'main' into test-necessary-imports
pseudo-rnd-thoughts Nov 18, 2022
d9dfcc1
Update with main
pseudo-rnd-thoughts Nov 18, 2022
ce56ea0
Merge branch 'main' into add-shimmy
pseudo-rnd-thoughts Nov 19, 2022
42135db
Fix CI issues
pseudo-rnd-thoughts Nov 19, 2022
a284c5f
Merge branch 'add-shimmy' into test-necessary-imports
pseudo-rnd-thoughts Nov 26, 2022
91eb3c4
pre-commit
pseudo-rnd-thoughts Nov 26, 2022
92f5542
Fix python version number
pseudo-rnd-thoughts Nov 26, 2022
a680f07
Remove gym conversion tests and fix build
pseudo-rnd-thoughts Nov 26, 2022
65f8c1c
Fix pytest
pseudo-rnd-thoughts Nov 26, 2022
d0c7790
Merge branch 'main' into test-necessary-imports
pseudo-rnd-thoughts Nov 30, 2022
01f5b82
Merge branch 'main' into test-necessary-imports
pseudo-rnd-thoughts Dec 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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