From fdb9ac44de9cb09a0098c34e2d30d86bad0a8898 Mon Sep 17 00:00:00 2001 From: Ervin Teng Date: Thu, 21 Feb 2019 12:34:03 -0800 Subject: [PATCH 1/6] Change gym-unity tests to use Mock instead of MockCommunicator --- gym-unity/tests/test_gym.py | 64 +++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/gym-unity/tests/test_gym.py b/gym-unity/tests/test_gym.py index 3f704833dc..d8ccf17c7b 100644 --- a/gym-unity/tests/test_gym.py +++ b/gym-unity/tests/test_gym.py @@ -6,17 +6,32 @@ from gym_unity.envs import UnityEnv, UnityGymException from mock_communicator import MockCommunicator -@mock.patch('mlagents.envs.UnityEnvironment.executable_launcher') -@mock.patch('mlagents.envs.UnityEnvironment.get_communicator') -def test_gym_wrapper(mock_communicator, mock_launcher): - mock_communicator.return_value = MockCommunicator( - discrete_action=False, visual_inputs=0, stack=False, num_agents=1) +@mock.patch('gym_unity.envs.unity_env.UnityEnvironment') +def test_gym_wrapper(mock_env): + mock_env.return_value.academy_name = 'MockAcademy' + mock_brain = mock.Mock(); - # Test for incorrect number of agents. - with pytest.raises(UnityGymException): - UnityEnv(' ', use_visual=False, multiagent=True) + # Create mock Brain + mock_brain.return_value.number_visual_observations = 0 + mock_brain.return_value.num_stacked_vector_observations = 1 + mock_brain.return_value.vector_action_space_type = 'continuous' + mock_brain.return_value.vector_observation_space_size = 3 + mock_brain.return_value.vector_action_space_size = [2] + + # Create mock BrainInfo + mock_braininfo = mock.Mock() + mock_braininfo.return_value.vector_observations = np.array([[1, 2, 3,]]) + mock_braininfo.return_value.rewards = [1.0] + mock_braininfo.return_value.local_done = [False] + mock_braininfo.return_value.text_observations = [''] + mock_braininfo.return_value.agents = [0] + + mock_env.return_value.brains = {'MockBrain':mock_brain()} + mock_env.return_value.external_brain_names = ['MockBrain'] + mock_env.return_value.reset.return_value = {'MockBrain':mock_braininfo()} + mock_env.return_value.step.return_value = {'MockBrain':mock_braininfo()} - env = UnityEnv(' ', use_visual=False) + env = UnityEnv(' ', use_visual=False, multiagent=False) assert isinstance(env, UnityEnv) assert isinstance(env.reset(), np.ndarray) actions = env.action_space.sample() @@ -27,11 +42,30 @@ def test_gym_wrapper(mock_communicator, mock_launcher): assert isinstance(done, bool) assert isinstance(info, dict) -@mock.patch('mlagents.envs.UnityEnvironment.executable_launcher') -@mock.patch('mlagents.envs.UnityEnvironment.get_communicator') -def test_multi_agent(mock_communicator, mock_launcher): - mock_communicator.return_value = MockCommunicator( - discrete_action=False, visual_inputs=0, stack=False, num_agents=2) +@mock.patch('gym_unity.envs.unity_env.UnityEnvironment') +def test_multi_agent(mock_env): + mock_env.return_value.academy_name = 'MockAcademy' + mock_brain = mock.Mock(); + + # Create mock Brain + mock_brain.return_value.number_visual_observations = 0 + mock_brain.return_value.num_stacked_vector_observations = 1 + mock_brain.return_value.vector_action_space_type = 'continuous' + mock_brain.return_value.vector_observation_space_size = 3 + mock_brain.return_value.vector_action_space_size = [2] + + # Create mock BrainInfo + mock_braininfo = mock.Mock() + mock_braininfo.return_value.vector_observations = np.array([[1, 2, 3,],[1, 2, 3]]) + mock_braininfo.return_value.rewards = [1.0, 1.0] + mock_braininfo.return_value.local_done = [False, False] + mock_braininfo.return_value.text_observations = ['', ''] + mock_braininfo.return_value.agents = [0, 1] + + mock_env.return_value.brains = {'MockBrain':mock_brain()} + mock_env.return_value.external_brain_names = ['MockBrain'] + mock_env.return_value.reset.return_value = {'MockBrain':mock_braininfo()} + mock_env.return_value.step.return_value = {'MockBrain':mock_braininfo()} # Test for incorrect number of agents. with pytest.raises(UnityGymException): @@ -49,6 +83,8 @@ def test_multi_agent(mock_communicator, mock_launcher): @mock.patch('gym_unity.envs.unity_env.UnityEnvironment') def test_branched_flatten(mock_env): mock_env.return_value.academy_name = 'MockAcademy' + + # Create mock Brain mock_brain = mock.Mock(); mock_brain.return_value.number_visual_observations = 0 mock_brain.return_value.num_stacked_vector_observations = 1 From e78ebb76468f891afb7a529b280d7bee8ea530ad Mon Sep 17 00:00:00 2001 From: Ervin Teng Date: Thu, 21 Feb 2019 14:03:20 -0800 Subject: [PATCH 2/6] move creation of mock objects into helper functions --- gym-unity/tests/test_gym.py | 112 ++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 57 deletions(-) diff --git a/gym-unity/tests/test_gym.py b/gym-unity/tests/test_gym.py index d8ccf17c7b..b24a62d387 100644 --- a/gym-unity/tests/test_gym.py +++ b/gym-unity/tests/test_gym.py @@ -6,30 +6,13 @@ from gym_unity.envs import UnityEnv, UnityGymException from mock_communicator import MockCommunicator +# Tests + @mock.patch('gym_unity.envs.unity_env.UnityEnvironment') def test_gym_wrapper(mock_env): - mock_env.return_value.academy_name = 'MockAcademy' - mock_brain = mock.Mock(); - - # Create mock Brain - mock_brain.return_value.number_visual_observations = 0 - mock_brain.return_value.num_stacked_vector_observations = 1 - mock_brain.return_value.vector_action_space_type = 'continuous' - mock_brain.return_value.vector_observation_space_size = 3 - mock_brain.return_value.vector_action_space_size = [2] - - # Create mock BrainInfo - mock_braininfo = mock.Mock() - mock_braininfo.return_value.vector_observations = np.array([[1, 2, 3,]]) - mock_braininfo.return_value.rewards = [1.0] - mock_braininfo.return_value.local_done = [False] - mock_braininfo.return_value.text_observations = [''] - mock_braininfo.return_value.agents = [0] - - mock_env.return_value.brains = {'MockBrain':mock_brain()} - mock_env.return_value.external_brain_names = ['MockBrain'] - mock_env.return_value.reset.return_value = {'MockBrain':mock_braininfo()} - mock_env.return_value.step.return_value = {'MockBrain':mock_braininfo()} + mock_brain = create_mock_brainparams() + mock_braininfo = create_mock_vector_braininfo() + setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo) env = UnityEnv(' ', use_visual=False, multiagent=False) assert isinstance(env, UnityEnv) @@ -44,30 +27,10 @@ def test_gym_wrapper(mock_env): @mock.patch('gym_unity.envs.unity_env.UnityEnvironment') def test_multi_agent(mock_env): - mock_env.return_value.academy_name = 'MockAcademy' - mock_brain = mock.Mock(); - - # Create mock Brain - mock_brain.return_value.number_visual_observations = 0 - mock_brain.return_value.num_stacked_vector_observations = 1 - mock_brain.return_value.vector_action_space_type = 'continuous' - mock_brain.return_value.vector_observation_space_size = 3 - mock_brain.return_value.vector_action_space_size = [2] - - # Create mock BrainInfo - mock_braininfo = mock.Mock() - mock_braininfo.return_value.vector_observations = np.array([[1, 2, 3,],[1, 2, 3]]) - mock_braininfo.return_value.rewards = [1.0, 1.0] - mock_braininfo.return_value.local_done = [False, False] - mock_braininfo.return_value.text_observations = ['', ''] - mock_braininfo.return_value.agents = [0, 1] - - mock_env.return_value.brains = {'MockBrain':mock_brain()} - mock_env.return_value.external_brain_names = ['MockBrain'] - mock_env.return_value.reset.return_value = {'MockBrain':mock_braininfo()} - mock_env.return_value.step.return_value = {'MockBrain':mock_braininfo()} + mock_brain = create_mock_brainparams() + mock_braininfo = create_mock_vector_braininfo(num_agents=2) + setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo) - # Test for incorrect number of agents. with pytest.raises(UnityGymException): UnityEnv(' ', multiagent=False) @@ -82,19 +45,10 @@ def test_multi_agent(mock_env): @mock.patch('gym_unity.envs.unity_env.UnityEnvironment') def test_branched_flatten(mock_env): - mock_env.return_value.academy_name = 'MockAcademy' + mock_brain = create_mock_brainparams(vector_action_space_type='discrete', vector_action_space_size=[2,2,3]) + mock_braininfo = create_mock_vector_braininfo(num_agents=1) + setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo) - # Create mock Brain - mock_brain = mock.Mock(); - mock_brain.return_value.number_visual_observations = 0 - mock_brain.return_value.num_stacked_vector_observations = 1 - mock_brain.return_value.vector_action_space_type = 'discrete' - mock_brain.return_value.vector_observation_space_size = 1 - # Unflattened action space - mock_brain.return_value.vector_action_space_size = [2,2,3] - - mock_env.return_value.brains = {'MockBrain':mock_brain()} - mock_env.return_value.external_brain_names = ['MockBrain'] env = UnityEnv(' ', use_visual=False, multiagent=False, flatten_branched=True) assert isinstance(env.action_space, spaces.Discrete) assert env.action_space.n==12 @@ -104,3 +58,47 @@ def test_branched_flatten(mock_env): # Check that False produces a MultiDiscrete env = UnityEnv(' ', use_visual=False, multiagent=False, flatten_branched=False) assert isinstance(env.action_space, spaces.MultiDiscrete) + +# Helper methods + +def create_mock_brainparams(number_visual_observations = 0, num_stacked_vector_observations = 1, + vector_action_space_type = 'continuous', vector_observation_space_size = 3, vector_action_space_size = [2]): + """ + Creates a mock BrainParameters object with parameters. + """ + mock_brain = mock.Mock(); + mock_brain.return_value.number_visual_observations = number_visual_observations + mock_brain.return_value.num_stacked_vector_observations = num_stacked_vector_observations + mock_brain.return_value.vector_action_space_type = vector_action_space_type + mock_brain.return_value.vector_observation_space_size = vector_observation_space_size + mock_brain.return_value.vector_action_space_size = vector_action_space_size + return mock_brain() + +def create_mock_vector_braininfo(num_agents = 1): + """ + Creates a mock BrainInfo with vector observations. Imitates constant + vector observations, rewards, dones, and agents. + + :int num_agents: Number of "agents" to imitate in your BrainInfo values. + """ + mock_braininfo = mock.Mock() + mock_braininfo.return_value.vector_observations = np.array([num_agents*[1, 2, 3,]]) + mock_braininfo.return_value.rewards = num_agents*[1.0] + mock_braininfo.return_value.local_done = num_agents*[False] + mock_braininfo.return_value.text_observations = num_agents*[''] + mock_braininfo.return_value.agents = range(0,num_agents) + return mock_braininfo() + +def setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo): + """ + Takes in a mock UnityEnvironment and adds the appropriate . + + :Mock mock_env: A mock UnityEnvironment, usually empty. + :Mock mock_brain: A mock Brain object that specifies the params of this environment. + :Mock mock_braininfo: A mock BrainInfo object that will be returned at each step and reset. + """ + mock_env.return_value.academy_name = 'MockAcademy' + mock_env.return_value.brains = {'MockBrain':mock_brain} + mock_env.return_value.external_brain_names = ['MockBrain'] + mock_env.return_value.reset.return_value = {'MockBrain':mock_braininfo} + mock_env.return_value.step.return_value = {'MockBrain':mock_braininfo} From 5ddef54090dd91c04834b55b35594ed6285af6f1 Mon Sep 17 00:00:00 2001 From: Ervin Teng Date: Thu, 21 Feb 2019 14:04:25 -0800 Subject: [PATCH 3/6] Fix comment --- gym-unity/tests/test_gym.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gym-unity/tests/test_gym.py b/gym-unity/tests/test_gym.py index b24a62d387..18d1b07145 100644 --- a/gym-unity/tests/test_gym.py +++ b/gym-unity/tests/test_gym.py @@ -91,7 +91,8 @@ def create_mock_vector_braininfo(num_agents = 1): def setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo): """ - Takes in a mock UnityEnvironment and adds the appropriate . + Takes in a mock UnityEnvironment and adds the appropriate properties, defined by the mock + BrainParameters and BrainInfo. :Mock mock_env: A mock UnityEnvironment, usually empty. :Mock mock_brain: A mock Brain object that specifies the params of this environment. From 367239b245eb682c9bf14b39d74b36b805b69ae0 Mon Sep 17 00:00:00 2001 From: Ervin Teng Date: Thu, 21 Feb 2019 16:01:43 -0800 Subject: [PATCH 4/6] Fix Codacy errors --- gym-unity/tests/test_gym.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gym-unity/tests/test_gym.py b/gym-unity/tests/test_gym.py index 18d1b07145..8d695bfcec 100644 --- a/gym-unity/tests/test_gym.py +++ b/gym-unity/tests/test_gym.py @@ -61,11 +61,15 @@ def test_branched_flatten(mock_env): # Helper methods -def create_mock_brainparams(number_visual_observations = 0, num_stacked_vector_observations = 1, - vector_action_space_type = 'continuous', vector_observation_space_size = 3, vector_action_space_size = [2]): +def create_mock_brainparams(number_visual_observations=0, num_stacked_vector_observations=1, + vector_action_space_type='continuous', vector_observation_space_size=3, + vector_action_space_size=None): """ Creates a mock BrainParameters object with parameters. """ + # Avoid using mutable object as default param + if vector_action_space_size is None: + vector_action_space_size = [2] mock_brain = mock.Mock(); mock_brain.return_value.number_visual_observations = number_visual_observations mock_brain.return_value.num_stacked_vector_observations = num_stacked_vector_observations @@ -77,9 +81,9 @@ def create_mock_brainparams(number_visual_observations = 0, num_stacked_vector_o def create_mock_vector_braininfo(num_agents = 1): """ Creates a mock BrainInfo with vector observations. Imitates constant - vector observations, rewards, dones, and agents. + vector observations, rewards, dones, and agents. - :int num_agents: Number of "agents" to imitate in your BrainInfo values. + :int num_agents: Number of "agents" to imitate in your BrainInfo values. """ mock_braininfo = mock.Mock() mock_braininfo.return_value.vector_observations = np.array([num_agents*[1, 2, 3,]]) @@ -94,7 +98,7 @@ def setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo): Takes in a mock UnityEnvironment and adds the appropriate properties, defined by the mock BrainParameters and BrainInfo. - :Mock mock_env: A mock UnityEnvironment, usually empty. + :Mock mock_env: A mock UnityEnvironment, usually empty. :Mock mock_brain: A mock Brain object that specifies the params of this environment. :Mock mock_braininfo: A mock BrainInfo object that will be returned at each step and reset. """ From 4ad5b1de1ddbacf7fad6caefc5b0fb8970cb75dd Mon Sep 17 00:00:00 2001 From: Ervin Teng Date: Thu, 21 Feb 2019 16:10:32 -0800 Subject: [PATCH 5/6] Fix ending whitespace --- gym-unity/tests/test_gym.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gym-unity/tests/test_gym.py b/gym-unity/tests/test_gym.py index 8d695bfcec..ba24ce5ae6 100644 --- a/gym-unity/tests/test_gym.py +++ b/gym-unity/tests/test_gym.py @@ -95,7 +95,7 @@ def create_mock_vector_braininfo(num_agents = 1): def setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo): """ - Takes in a mock UnityEnvironment and adds the appropriate properties, defined by the mock + Takes a mock UnityEnvironment and adds the appropriate properties, defined by the mock BrainParameters and BrainInfo. :Mock mock_env: A mock UnityEnvironment, usually empty. From 3e91abc87e3a054b1061e5c172324bbd9df9dd32 Mon Sep 17 00:00:00 2001 From: vincentpierre Date: Thu, 21 Feb 2019 16:35:17 -0800 Subject: [PATCH 6/6] Minor fixes --- gym-unity/tests/test_gym.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gym-unity/tests/test_gym.py b/gym-unity/tests/test_gym.py index ba24ce5ae6..bf84c45f56 100644 --- a/gym-unity/tests/test_gym.py +++ b/gym-unity/tests/test_gym.py @@ -4,10 +4,10 @@ from gym import spaces from gym_unity.envs import UnityEnv, UnityGymException -from mock_communicator import MockCommunicator # Tests + @mock.patch('gym_unity.envs.unity_env.UnityEnvironment') def test_gym_wrapper(mock_env): mock_brain = create_mock_brainparams() @@ -25,6 +25,7 @@ def test_gym_wrapper(mock_env): assert isinstance(done, bool) assert isinstance(info, dict) + @mock.patch('gym_unity.envs.unity_env.UnityEnvironment') def test_multi_agent(mock_env): mock_brain = create_mock_brainparams() @@ -43,6 +44,7 @@ def test_multi_agent(mock_env): assert isinstance(done, list) assert isinstance(info, dict) + @mock.patch('gym_unity.envs.unity_env.UnityEnvironment') def test_branched_flatten(mock_env): mock_brain = create_mock_brainparams(vector_action_space_type='discrete', vector_action_space_size=[2,2,3]) @@ -61,6 +63,7 @@ def test_branched_flatten(mock_env): # Helper methods + def create_mock_brainparams(number_visual_observations=0, num_stacked_vector_observations=1, vector_action_space_type='continuous', vector_observation_space_size=3, vector_action_space_size=None): @@ -78,6 +81,7 @@ def create_mock_brainparams(number_visual_observations=0, num_stacked_vector_obs mock_brain.return_value.vector_action_space_size = vector_action_space_size return mock_brain() + def create_mock_vector_braininfo(num_agents = 1): """ Creates a mock BrainInfo with vector observations. Imitates constant @@ -93,6 +97,7 @@ def create_mock_vector_braininfo(num_agents = 1): mock_braininfo.return_value.agents = range(0,num_agents) return mock_braininfo() + def setup_mock_unityenvironment(mock_env, mock_brain, mock_braininfo): """ Takes a mock UnityEnvironment and adds the appropriate properties, defined by the mock