def test_image_none(self): # Testing if image is None, settings.RELATE_DOCKER_RUNPY_IMAGE is used with mock.patch("docker.client.Client.create_container") as mock_create_ctn: # this will raise KeyError mock_create_ctn.return_value = {} with self.assertRaises(KeyError): request_python_run_with_retries( run_req={}, run_timeout=0.1) self.assertEqual(mock_create_ctn.call_count, 1) self.assertIn("some_other_image", mock_create_ctn.call_args[0])
def test_docker_container_runpy_retries_count(self): with ( mock.patch("course.page.code.request_python_run")) as mock_req_run, ( # noqa mock.patch("course.page.code.is_nuisance_failure")) as mock_is_nuisance_failure: # noqa expected_result = "this is my custom result" mock_req_run.return_value = {"result": expected_result} with self.subTest(actual_retry_count=4): mock_is_nuisance_failure.side_effect = [True, True, True, False] res = request_python_run_with_retries( run_req={}, run_timeout=0.1, retry_count=5) self.assertEqual(res["result"], expected_result) self.assertEqual(mock_req_run.call_count, 4) self.assertEqual(mock_is_nuisance_failure.call_count, 4) mock_req_run.reset_mock() mock_is_nuisance_failure.reset_mock() with self.subTest(actual_retry_count=2): mock_is_nuisance_failure.side_effect = [True, True, True, False] res = request_python_run_with_retries( run_req={}, run_timeout=0.1, retry_count=1) self.assertEqual(res["result"], expected_result) self.assertEqual(mock_req_run.call_count, 2) self.assertEqual(mock_is_nuisance_failure.call_count, 1)
def test_docker_container_ping_return_not_ok(self): with ( mock.patch("docker.client.Client.create_container")) as mock_create_ctn, ( # noqa mock.patch("docker.client.Client.start")) as mock_ctn_start, ( mock.patch("docker.client.Client.logs")) as mock_ctn_logs, ( mock.patch("docker.client.Client.remove_container")) as mock_remove_ctn, ( # noqa mock.patch("docker.client.Client.inspect_container")) as mock_inpect_ctn, ( # noqa mock.patch("six.moves.http_client.HTTPConnection.request")) as mock_ctn_request, ( # noqa mock.patch("six.moves.http_client.HTTPConnection.getresponse")) as mock_ctn_get_response: # noqa mock_create_ctn.return_value = {"Id": "someid"} mock_ctn_start.side_effect = lambda x: None mock_ctn_logs.side_effect = lambda x: None mock_remove_ctn.return_value = None fake_host_ip = "192.168.1.100" fake_host_port = "69999" mock_inpect_ctn.return_value = { "NetworkSettings": { "Ports": {"%d/tcp" % RUNPY_PORT: ( {"HostIp": fake_host_ip, "HostPort": fake_host_port}, )} }} # force timeout with mock.patch("course.page.code.DOCKER_TIMEOUT", 0.0001): with self.subTest( case="Docker ping response not OK"): mock_ctn_request.side_effect = lambda x, y: None mock_ctn_get_response.return_value = six.BytesIO(b"NOT OK") res = request_python_run_with_retries( run_req={}, run_timeout=0.1, retry_count=0) self.assertEqual(res["result"], "uncaught_error") self.assertEqual(res['message'], "Timeout waiting for container.") self.assertEqual(res["exec_host"], fake_host_ip) self.assertIn(InvalidPingResponse.__name__, res["traceback"])
class RequestPythonRunWithRetriesTest(unittest.TestCase): # Testing course.page.code.request_python_run_with_retries, # adding tests for use cases that didn't cover in other tests @override_settings(RELATE_DOCKER_RUNPY_IMAGE="some_other_image") def test_image_none(self): # Testing if image is None, settings.RELATE_DOCKER_RUNPY_IMAGE is used with mock.patch("docker.client.Client.create_container") as mock_create_ctn: # this will raise KeyError mock_create_ctn.return_value = {} with self.assertRaises(KeyError): request_python_run_with_retries( run_req={}, run_timeout=0.1) self.assertEqual(mock_create_ctn.call_count, 1) self.assertIn("some_other_image", mock_create_ctn.call_args[0]) @override_settings(RELATE_DOCKER_RUNPY_IMAGE="some_other_image") def test_image_not_none(self): # Testing if image is None, settings.RELATE_DOCKER_RUNPY_IMAGE is used with mock.patch("docker.client.Client.create_container") as mock_create_ctn: # this will raise KeyError mock_create_ctn.return_value = {} my_image = "my_runpy_image" with self.assertRaises(KeyError): request_python_run_with_retries( run_req={}, image=my_image, run_timeout=0.1) self.assertEqual(mock_create_ctn.call_count, 1) self.assertIn(my_image, mock_create_ctn.call_args[0]) @skipIf(six.PY2, "PY2 doesn't support subTest") def test_docker_container_ping_failure(self): with ( mock.patch("docker.client.Client.create_container")) as mock_create_ctn, ( # noqa mock.patch("docker.client.Client.start")) as mock_ctn_start, ( mock.patch("docker.client.Client.logs")) as mock_ctn_logs, ( mock.patch("docker.client.Client.remove_container")) as mock_remove_ctn, ( # noqa mock.patch("docker.client.Client.inspect_container")) as mock_inpect_ctn, ( # noqa mock.patch("six.moves.http_client.HTTPConnection.request")) as mock_ctn_request: # noqa mock_create_ctn.return_value = {"Id": "someid"} mock_ctn_start.side_effect = lambda x: None mock_ctn_logs.side_effect = lambda x: None mock_remove_ctn.return_value = None fake_host_ip = "192.168.1.100" fake_host_port = "69999" mock_inpect_ctn.return_value = { "NetworkSettings": { "Ports": {"%d/tcp" % RUNPY_PORT: ( {"HostIp": fake_host_ip, "HostPort": fake_host_port}, )} }} with self.subTest(case="Docker ping timeout with BadStatusLine Error"): from six.moves.http_client import BadStatusLine fake_bad_statusline_msg = "my custom bad status" mock_ctn_request.side_effect = BadStatusLine(fake_bad_statusline_msg) # force timeout with mock.patch("course.page.code.DOCKER_TIMEOUT", 0.0001): res = request_python_run_with_retries( run_req={}, run_timeout=0.1, retry_count=0) self.assertEqual(res["result"], "uncaught_error") self.assertEqual(res['message'], "Timeout waiting for container.") self.assertEqual(res["exec_host"], fake_host_ip) self.assertIn(fake_bad_statusline_msg, res["traceback"])
run_req={}, run_timeout=0.1, retry_count=0) self.assertEqual(res["result"], "uncaught_error") self.assertEqual(res['message'], "Timeout waiting for container.") self.assertEqual(res["exec_host"], fake_host_ip) self.assertIn(fake_bad_statusline_msg, res["traceback"]) with self.subTest( case="Docker ping timeout with InvalidPingResponse Error"): invalid_ping_resp_msg = "my custom invalid ping response exception" mock_ctn_request.side_effect = ( InvalidPingResponse(invalid_ping_resp_msg)) # force timeout with mock.patch("course.page.code.DOCKER_TIMEOUT", 0.0001): res = request_python_run_with_retries( run_req={}, run_timeout=0.1, retry_count=0) self.assertEqual(res["result"], "uncaught_error") self.assertEqual(res['message'], "Timeout waiting for container.") self.assertEqual(res["exec_host"], fake_host_ip) self.assertIn(InvalidPingResponse.__name__, res["traceback"]) self.assertIn(invalid_ping_resp_msg, res["traceback"]) with self.subTest( case="Docker ping socket error with erron ECONNRESET"): my_socket_error = socket_error() my_socket_error.errno = errno.ECONNRESET mock_ctn_request.side_effect = my_socket_error # force timeout with mock.patch("course.page.code.DOCKER_TIMEOUT", 0.0001):