diff --git a/hbp_nrp_virtual_coach/pynrp/simulation.py b/hbp_nrp_virtual_coach/pynrp/simulation.py index 2a8b79f5b8c3ccc9fb4f2138319b221aeb3bc77a..ce3edde15501b48e95d8f2fd11fbab5e407a5589 100644 --- a/hbp_nrp_virtual_coach/pynrp/simulation.py +++ b/hbp_nrp_virtual_coach/pynrp/simulation.py @@ -715,6 +715,7 @@ class Simulation(object): # check for current simulation state and pause simulation if it's running if self.get_state() == 'started': started = True + self.pause() try: status_code, _ = self.__http_client.put(url, body=body) if status_code != http.client.OK: diff --git a/hbp_nrp_virtual_coach/pynrp/tests/test_config.py b/hbp_nrp_virtual_coach/pynrp/tests/test_config.py index c1b8b202e8aff2fc48c3a1f0653d88bb02b8f9c9..40d9cd77e1415243ad9afd97c06cc02989a80aac 100644 --- a/hbp_nrp_virtual_coach/pynrp/tests/test_config.py +++ b/hbp_nrp_virtual_coach/pynrp/tests/test_config.py @@ -27,7 +27,7 @@ Unit tests for the Virtual Coach config parser. from pynrp.config import Config -from mock import patch +from unittest.mock import patch import unittest import copy diff --git a/hbp_nrp_virtual_coach/pynrp/tests/test_simulation.py b/hbp_nrp_virtual_coach/pynrp/tests/test_simulation.py index 3c284d7ac3e5ed0c3a9d7740d824b5815291f6b9..47c72f1120a0dbc39555dad190bd8c5945d08d99 100644 --- a/hbp_nrp_virtual_coach/pynrp/tests/test_simulation.py +++ b/hbp_nrp_virtual_coach/pynrp/tests/test_simulation.py @@ -27,13 +27,12 @@ Unit tests for the Virtual Coach simulation interface. from future import standard_library standard_library.install_aliases() -from builtins import object from pynrp.simulation import Simulation from pynrp.requests_client import RequestsClient from pynrp.config import Config -from mock import Mock, patch, call +from unittest.mock import Mock, patch, call, MagicMock import unittest import http.client @@ -68,7 +67,7 @@ class TestSimulation(unittest.TestCase): self.assertRaises(AssertionError, self._sim.launch, 'id', 'conf', None, None) self.assertRaises(AssertionError, self._sim.launch, 'id', 'conf', 'server', True) - @patch('pynrp.simulation.traceback') + @patch('traceback.print_exc') def test_failed_server_info(self, mocked_traceback): # mock HTTP call to throw Exception self.setUpForLaunch() @@ -76,31 +75,33 @@ class TestSimulation(unittest.TestCase): self._sim._Simulation__http_client.get.side_effect = Exception('something bad failed') # make sure it returns failure - self.assertEqual(self._sim.launch('id', 'conf', 'server', None), False) + self.assertFalse(self._sim.launch('id', 'conf', 'server', None)) self._sim._Simulation__http_client.get.assert_called_once() self._sim._Simulation__http_client.post.assert_not_called() - mocked_traceback.print_exec.assert_called_once() + mocked_traceback.assert_called_once() - @patch('pynrp.simulation.traceback') + @patch('traceback.print_exc') def test_failed_create_conflict(self, mocked_traceback): self.setUpForLaunch() self._sim._Simulation__http_client.post = Mock(return_value=(http.client.CONFLICT, '{}')) - self.assertEqual(self._sim.launch('id', 'conf', 'server-name', None), False) + self.assertFalse(self._sim.launch('id', 'conf', 'server-name', None)) + mocked_traceback.assert_called_once() + self._sim._Simulation__http_client.post.assert_called_once() - mocked_traceback.print_exec.assert_called_once() - @patch('pynrp.simulation.traceback') + @patch('traceback.print_exc') def test_failed_create_other(self, mocked_traceback): self.setUpForLaunch() self._sim._Simulation__http_client.post = Mock(return_value=(http.client.NOT_FOUND, '{}')) self.assertEqual(self._sim.launch('id', 'conf', 'server-name', None), False) + self._sim._Simulation__http_client.post.assert_called_once() - mocked_traceback.print_exec.assert_called_once() + mocked_traceback.assert_called_once() @patch('pynrp.rosbridge_handler.RosBridgeHandlerProcess.initialize') - def test_create(self, mocked_init): + def test_create(self, _mocked_init): self.setUpForLaunch() # mock the call to set simulation state @@ -112,7 +113,7 @@ class TestSimulation(unittest.TestCase): self.assertRaises(Exception, self._sim.launch, 'id', 'conf', 'server-name', 'reservation') @patch('pynrp.rosbridge_handler.RosBridgeHandlerProcess.initialize') - def test_create_cloned(self, mocked_init): + def test_create_cloned(self, _mocked_init): self.setUpForLaunch() # mock the call to set simulation state self._sim._Simulation__set_state = Mock() @@ -172,7 +173,7 @@ class TestSimulation(unittest.TestCase): # mock the OIDC call self._sim._Simulation__http_client.get = Mock(return_value=(http.client.OK, - '{"state": "{}"}')) + '{"state": "{}"}')) self._sim.get_state() assert self._sim._Simulation__http_client.get.mock_calls == [call(u'url/state')] @@ -184,8 +185,7 @@ class TestSimulation(unittest.TestCase): self._sim._Simulation__sim_url = 'url' # mock the OIDC call - self._sim._Simulation__http_client.get = Mock(return_value=(http.client.NOT_FOUND, - None)) + self._sim._Simulation__http_client.get = Mock(return_value=(http.client.NOT_FOUND,None)) self.assertRaises(Exception, self._sim.get_state) self._sim._Simulation__http_client.get.assert_called_once() @@ -336,6 +336,7 @@ class TestSimulation(unittest.TestCase): {})) self._sim.edit_populations({'foo': 'bar'}) + self._sim.start.assert_called_once() self._sim.pause.assert_called_once() @@ -348,7 +349,7 @@ class TestSimulation(unittest.TestCase): self._sim._Simulation__get_simulation_scripts.assert_called_with('brain') self._sim.get_brain() - self._sim._Simulation__get_simulation_scripts.assert_called_twice() + self.assertEqual(self._sim._Simulation__get_simulation_scripts.call_count, 2) # called twice self._sim._Simulation__get_simulation_scripts.assert_called_with('brain') def test_edit_scripts(self): @@ -371,13 +372,17 @@ class TestSimulation(unittest.TestCase): self._sim.get_state = Mock() self._sim.get_state.return_value = 'started' - self._sim.edit_transfer_function('foo', u'bar') - self._sim.start.assert_called_once() - self._sim.pause.assert_called_once() + with patch.object(self._sim, 'start') as start_mock: + with patch.object(self._sim, 'pause') as pause_mock: + self._sim.edit_transfer_function('foo', u'bar') + start_mock.assert_called_once() + pause_mock.assert_called_once() - self._sim.edit_state_machine('foo', u'bar') - self._sim.start.assert_called_once() - self._sim.pause.assert_called_once() + with patch.object(self._sim, 'start') as start_mock: + with patch.object(self._sim, 'pause') as pause_mock: + self._sim.edit_state_machine('foo', u'bar') + start_mock.assert_called_once() + pause_mock.assert_called_once() def test_delete_scripts(self): self.assertRaises(Exception, self._sim.delete_state_machine, 'foo') @@ -396,12 +401,11 @@ class TestSimulation(unittest.TestCase): self._sim._Simulation__http_client.delete.assert_called_once() self._sim.delete_transfer_function('foo') - self._sim._Simulation__http_client.delete.assert_called_once() + self.assertEqual(self._sim._Simulation__http_client.delete.call_count, 2) self.assertRaises(ValueError, self._sim.delete_state_machine, 'nonExistentScript') - self._sim._Simulation__http_client.delete.return_value = (http.client.NOT_FOUND, - None) + self._sim._Simulation__http_client.delete.return_value = (http.client.NOT_FOUND, None) self.assertRaises(Exception, self._sim.delete_state_machine, 'foo') @@ -435,7 +439,7 @@ class TestSimulation(unittest.TestCase): self._sim.save_transfer_functions() self._sim._Simulation__http_client.put.assert_called_once_with( '%s/%s/transferFunctions' % (proxyurl, exp_id), - body={'transferFunctions': ['bar'],'experiment': exp_id}) + body={'transferFunctions': ['bar'], 'experiment': exp_id}) self._sim._Simulation__http_client.put.reset_mock() self._sim.save_state_machines() @@ -462,7 +466,7 @@ class TestSimulation(unittest.TestCase): self._sim._Simulation__http_client.post = Mock(return_value=(http.client.OK, None)) self._sim.save_world() self._sim._Simulation__http_client.post.assert_called_once_with( - '%s/sdf_world' % (self._sim._Simulation__sim_url), + '%s/sdf_world' % self._sim._Simulation__sim_url, body={}) @patch('sys.stdout', new_callable=StringIO) @@ -471,24 +475,25 @@ class TestSimulation(unittest.TestCase): self._sim._Simulation__sim_url = 'url' self._sim._Simulation__get_simulation_scripts = Mock() - self._sim._Simulation__get_simulation_scripts.return_value = {'data': {'foo': 'one', 'bar': 'two', - 'foobar': 'three'}} + self._sim._Simulation__get_simulation_scripts.return_value = {'data': {'foo': 'one', + 'bar': 'two', + 'foobar': 'three'}} self._sim.print_transfer_functions() self._sim.print_state_machines() # The order in which 'foobar', 'foo' and 'bar' appear is no longer guaranteed in python 3.3+ - printStr = mock_stdout.getvalue().strip() - self.assertEqual(len(printStr), 29) - n = printStr.count('\n') + print_str = mock_stdout.getvalue().strip() + self.assertEqual(len(print_str), 29) + n = print_str.count('\n') self.assertEqual(n, 5) - n = printStr.count('foobar') + n = print_str.count('foobar') self.assertEqual(n, 2) - n = printStr.count('foo') + n = print_str.count('foo') self.assertEqual(n, 4) - n = printStr.count('bar') + n = print_str.count('bar') self.assertEqual(n, 4) #self.assertEqual(mock_stdout.getvalue().strip(), 'foobar\nfoo\nbar\nfoobar\nfoo\nbar') - self._sim._Simulation__get_simulation_scripts.assert_called_twice() + self.assertEqual(self._sim._Simulation__get_simulation_scripts.call_count, 2) def test_register_status_callback(self): # override the logger so we can check for messages @@ -514,7 +519,7 @@ class TestSimulation(unittest.TestCase): self._sim.register_status_callback(mock_callback) self.assertEqual(self._sim._Simulation__status_callbacks, [mock_callback]) self._sim._Simulation__logger.warning.assert_called_once_with('Attempting to register duplicate ' - 'status callback, ignoring.') + 'status callback, ignoring.') self.assertEqual(self._sim._Simulation__logger.info.call_count, 1) def test_on_error(self): @@ -616,3 +621,6 @@ class TestSimulation(unittest.TestCase): self._sim._Simulation__http_client.post.assert_called_with(u'url/recorder/start', body='start') self._sim.stop_recording(True,'My description') self._sim._Simulation__http_client.post.assert_called_with(u'url/recorder/reset', body='reset') + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/hbp_nrp_virtual_coach/pynrp/tests/test_virtual_coach.py b/hbp_nrp_virtual_coach/pynrp/tests/test_virtual_coach.py index 067d5b8c3f74d6a8dc6234be5037921a281bd930..d3e22519feaede1afe795136ce6efa7d47a0d439 100644 --- a/hbp_nrp_virtual_coach/pynrp/tests/test_virtual_coach.py +++ b/hbp_nrp_virtual_coach/pynrp/tests/test_virtual_coach.py @@ -30,7 +30,7 @@ standard_library.install_aliases() from builtins import object from pynrp.virtual_coach import VirtualCoach -from mock import Mock, patch, MagicMock +from unittest.mock import Mock, patch, MagicMock import unittest import requests import getpass diff --git a/hbp_nrp_virtual_coach/setup.py b/hbp_nrp_virtual_coach/setup.py index 36781907f53aec16d2b220dc507e9d7a84c4beba..d1331895e1760a988a24d0fe1fb3b210257b7489 100644 --- a/hbp_nrp_virtual_coach/setup.py +++ b/hbp_nrp_virtual_coach/setup.py @@ -45,7 +45,7 @@ elif pip_version_major >= 10: reqs = install_reqs config = { - 'description': 'python interface to the Neurorobotics Platform', + 'description': 'Python interface to the Neurorobotics Platform (NRP)', 'long_description': README, 'long_description_content_type': 'text/markdown', 'author': 'HBP Neurorobotics',