def test_wait_for_daemon_to_initialize(self): self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a'} with self._mock_sbus_client('ping') as ping, \ mock.patch(self.base_path + '.time.sleep'): ping.return_value = SBusResponse(True, 'OK') self.assertTrue( self.dfactory.wait_for_daemon_to_initialize('storleta')) self.assertEqual(1, ping.call_count) with self._mock_sbus_client('ping') as ping, \ mock.patch(self.base_path + '.time.sleep'): ping.return_value = SBusResponse(False, 'NG') self.assertFalse( self.dfactory.wait_for_daemon_to_initialize('storleta')) self.assertEqual( self.dfactory.NUM_OF_TRIES_PINGING_STARTING_DAEMON, ping.call_count) self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a', 'storletb': 'path/to/uds/b'} with self._mock_sbus_client('ping') as ping, \ mock.patch(self.base_path + '.time.sleep'): ping.side_effect = SBusClientSendError() self.assertFalse( self.dfactory.wait_for_daemon_to_initialize('storleta')) self.assertEqual( self.dfactory.NUM_OF_TRIES_PINGING_STARTING_DAEMON, ping.call_count)
def test_ping(self): with mock.patch('storlets.gateway.gateways.docker.runtime.' 'SBusClient.ping') as ping: ping.return_value = SBusResponse(True, 'OK') self.assertEqual(self.sbox.ping(), 1) with mock.patch('storlets.gateway.gateways.docker.runtime.' 'SBusClient.ping') as ping: ping.return_value = SBusResponse(False, 'Error') self.assertEqual(self.sbox.ping(), 0) with mock.patch('storlets.gateway.gateways.docker.runtime.' 'SBusClient.ping') as ping: ping.side_effect = SBusClientSendError() self.assertEqual(self.sbox.ping(), -1) with mock.patch('storlets.gateway.gateways.docker.runtime.' 'SBusClient.ping') as ping: ping.side_effect = SBusClientMalformedResponse() self.assertEqual(self.sbox.ping(), -1) with mock.patch('storlets.gateway.gateways.docker.runtime.' 'SBusClient.ping') as ping: ping.side_effect = SBusClientIOError() self.assertEqual(self.sbox.ping(), -1)
def test_invocation_flow(client): client.ping.return_value = SBusResponse(True, 'OK') client.stop_daemon.return_value = SBusResponse(True, 'OK') client.start_daemon.return_value = SBusResponse(True, 'OK') sresp = self.gateway.invocation_flow(st_req, extra_sources) eventlet.sleep(0.1) file_like = FileLikeIter(sresp.data_iter) self.assertEqual(b'something', file_like.read())
def test_shutdown_process(self): # Success self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a', 'storletb': 'path/to/uds/b'} with self._mock_sbus_client('halt') as halt, \ mock.patch(self.waitpid_path): halt.return_value = SBusResponse(True, 'OK') self.dfactory.shutdown_process('storleta') self.assertEqual({'storletb': 1001}, self.dfactory.storlet_name_to_pid) # Failed to send a command to the storlet daemon self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a', 'storletb': 'path/to/uds/b'} with self._mock_sbus_client('halt') as halt, \ mock.patch(self.waitpid_path) as waitpid: halt.side_effect = SBusClientSendError() with self.assertRaises(SDaemonError): self.dfactory.shutdown_process('storleta') self.assertEqual(0, waitpid.call_count) self.assertEqual({ 'storleta': 1000, 'storletb': 1001 }, self.dfactory.storlet_name_to_pid) # Failed to wait self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a', 'storletb': 'path/to/uds/b'} with self._mock_sbus_client('halt') as halt, \ mock.patch(self.waitpid_path) as waitpid: halt.return_value = SBusResponse(True, 'OK') waitpid.side_effect = OSError() with self.assertRaises(SDaemonError): self.dfactory.shutdown_process('storleta') self.assertEqual({ 'storleta': 1000, 'storletb': 1001 }, self.dfactory.storlet_name_to_pid) # If the storlet is not found in pid mapping self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a', 'storletb': 'path/to/uds/b'} with self.assertRaises(SDaemonError): self.dfactory.shutdown_process('storletc')
def test_spawn_subprocess(self): self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a'} class FakePopenObject(object): def __init__(self, pid): self.pid = pid self.stderr = mock.MagicMock() with mock.patch(self.base_path + '.subprocess.Popen') as popen, \ mock.patch(self.base_path + '.time.sleep'), \ mock.patch(self.waitpid_path) as waitpid, \ self._mock_sbus_client('ping') as ping: popen.side_effect = [FakePopenObject(1000), FakePopenObject(1001)] waitpid.return_value = 0, 0 ping.return_value = SBusResponse(True, 'OK') self.dfactory.spawn_subprocess(['arg0', 'argv1', 'argv2'], {'envk0': 'envv0'}, 'storleta') self.assertEqual((1000, 1), waitpid.call_args[0]) self.assertEqual({'storleta': 1000}, self.dfactory.storlet_name_to_pid) with mock.patch(self.base_path + '.subprocess.Popen') as popen, \ mock.patch(self.base_path + '.time.sleep'), \ mock.patch(self.waitpid_path) as waitpid, \ self._mock_sbus_client('ping') as ping: popen.side_effect = [FakePopenObject(1000), FakePopenObject(1001)] waitpid.return_value = 0, 0 ping.return_value = SBusResponse(False, 'NG') with self.assertRaises(SDaemonError): self.dfactory.spawn_subprocess(['arg0', 'argv1', 'argv2'], {'envk0': 'envv0'}, 'storleta') self.assertEqual((1000, 1), waitpid.call_args[0]) self.assertEqual({'storleta': 1000}, self.dfactory.storlet_name_to_pid) with mock.patch(self.base_path + '.subprocess.Popen') as popen, \ mock.patch(self.base_path + '.time.sleep'), \ mock.patch(self.waitpid_path) as waitpid: popen.side_effect = [FakePopenObject(1000), FakePopenObject(1001)] waitpid.return_value = 1000, -1 with self.assertRaises(SDaemonError): self.dfactory.spawn_subprocess(['arg0', 'argv1', 'argv2'], {'envk0': 'envv0'}, 'storleta') self.assertEqual((1000, 1), waitpid.call_args[0]) with mock.patch(self.base_path + '.subprocess.Popen') as popen: popen.side_effect = OSError() with self.assertRaises(SDaemonError): self.dfactory.spawn_subprocess(['arg0', 'argv1', 'argv2'], {'envk0': 'envv0'}, 'storleta')
def test_start_daemon(self): prms = { 'daemon_language': 'java', 'storlet_path': 'path/to/storlet/a', 'storlet_name': 'storleta', 'pool_size': 1, 'uds_path': 'path/to/uds/a', 'log_level': 'TRACE' } # Not running self.dfactory.storlet_name_to_pid = {} self.dfactory.storlet_name_to_pipe_name = {} class FakePopenObject(object): def __init__(self, pid): self.pid = pid self.stderr = mock.MagicMock() with mock.patch(self.base_path + '.subprocess.Popen') as popen, \ mock.patch(self.base_path + '.time.sleep'), \ mock.patch(self.waitpid_path) as waitpid, \ self._mock_sbus_client('ping') as ping, \ self._mock_sbus_client('start_daemon') as start_daemon: popen.side_effect = [FakePopenObject(1000), FakePopenObject(1001)] waitpid.return_value = 0, 0 ping.return_value = SBusResponse(True, 'OK') start_daemon.return_value = SBusResponse(True, 'OK') ret = self.dfactory.start_daemon(DummyDatagram(prms)) self.assertTrue(ret.status) self.assertEqual('OK', ret.message) self.assertTrue(ret.iterable) # Already running self.dfactory.storlet_name_to_pid = {'storleta': 1000} self.dfactory.storlet_name_to_pipe_name = {'storleta': 'path/to/uds/a'} with mock.patch(self.waitpid_path) as waitpid: waitpid.return_value = 0, 0 ret = self.dfactory.start_daemon(DummyDatagram(prms)) self.assertTrue(ret.status) self.assertEqual('The storlet daemon storleta is already running', ret.message) self.assertTrue(ret.iterable) # Unsupported language prms['daemon_language'] = 'foo' ret = self.dfactory.start_daemon(DummyDatagram(prms)) self.assertFalse(ret.status) self.assertEqual('Got unsupported daemon language: foo', ret.message) self.assertTrue(ret.iterable)
def test_wait(self): with mock.patch('storlets.gateway.gateways.docker.runtime.' 'SBusClient.ping') as ping, \ mock.patch('storlets.gateway.gateways.docker.runtime.' 'time.sleep') as sleep: ping.return_value = SBusResponse(True, 'OK') self.sbox.wait() self.assertEqual(sleep.call_count, 0) with mock.patch('storlets.gateway.gateways.docker.runtime.' 'SBusClient.ping') as ping, \ mock.patch('storlets.gateway.gateways.docker.runtime.' 'time.sleep') as sleep: ping.side_effect = [SBusResponse(False, 'Error'), SBusResponse(True, 'OK')] self.sbox.wait() self.assertEqual(sleep.call_count, 1)
def test_shutdown_all_processes(self): # Success self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a', 'storletb': 'path/to/uds/b'} with self._mock_sbus_client('halt') as halt, \ mock.patch(self.waitpid_path): halt.return_value = SBusResponse(True, 'OK') terminated = self.dfactory.shutdown_all_processes() self.assertEqual(2, len(terminated)) self.assertIn('storleta', terminated) self.assertIn('storletb', terminated) self.assertEqual({}, self.dfactory.storlet_name_to_pid) # Failure (try_all = True) self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'patha', 'storletb': 'pathb'} with self._mock_sbus_client('halt') as halt, \ mock.patch(self.waitpid_path) as waitpid: halt.side_effect = SBusClientSendError() exc_pattern = '^Failed to shutdown some storlet daemons: .*' with self.assertRaisesRegexp(SDaemonError, exc_pattern) as e: self.dfactory.shutdown_all_processes() self.assertIn('storleta', str(e.exception)) self.assertIn('storletb', str(e.exception)) self.assertEqual(2, halt.call_count) self.assertEqual(0, waitpid.call_count) self.assertEqual({ 'storleta': 1000, 'storletb': 1001 }, self.dfactory.storlet_name_to_pid) # Failure (try_all = False) self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'patha', 'storletb': 'pathb'} with self._mock_sbus_client('halt') as halt, \ mock.patch(self.waitpid_path) as waitpid: halt.side_effect = SBusClientSendError() exc_pattern = ('^Failed to send halt command to the storlet ' 'daemon storlet[a-b]$') with self.assertRaisesRegexp(SDaemonError, exc_pattern): self.dfactory.shutdown_all_processes(False) self.assertEqual(1, halt.call_count) self.assertEqual(0, waitpid.call_count) self.assertEqual({ 'storleta': 1000, 'storletb': 1001 }, self.dfactory.storlet_name_to_pid)
def test_halt(self): self.dfactory.storlet_name_to_pid = \ {'storleta': 1000, 'storletb': 1001} self.dfactory.storlet_name_to_pipe_name = \ {'storleta': 'path/to/uds/a', 'storletb': 'path/to/uds/b'} with self._mock_sbus_client('halt') as halt, \ mock.patch(self.waitpid_path): halt.return_value = SBusResponse(True, 'OK') resp = self.dfactory.halt(DummyDatagram()) self.assertTrue(resp.status) self.assertEqual('Stopped all storlet daemons. Terminating.', resp.message) self.assertFalse(resp.iterable)
def test_send_execute_command(self): with mock.patch('storlets.gateway.gateways.docker.runtime.SBusClient.' 'execute') as execute: execute.return_value = SBusResponse(True, 'OK', 'someid') self.protocol._send_execute_command() self.assertEqual('someid', self.protocol.task_id) with mock.patch('storlets.gateway.gateways.docker.runtime.SBusClient.' 'execute') as execute: execute.return_value = SBusResponse(True, 'OK') with self.assertRaises(StorletRuntimeException): self.protocol._send_execute_command() with mock.patch('storlets.gateway.gateways.docker.runtime.SBusClient.' 'execute') as execute: execute.return_value = SBusResponse(False, 'NG', 'someid') with self.assertRaises(StorletRuntimeException): self.protocol._send_execute_command() with mock.patch('storlets.gateway.gateways.docker.runtime.SBusClient.' 'execute') as execute: execute.side_effect = SBusClientIOError() with self.assertRaises(StorletRuntimeException): self.protocol._send_execute_command()
def test_process_start_daemon(self): # Not running self.dfactory.storlet_name_to_pid = {} self.dfactory.storlet_name_to_pipe_name = {} class FakePopenObject(object): def __init__(self, pid): self.pid = pid self.stderr = mock.MagicMock() with mock.patch(self.base_path + '.subprocess.Popen') as popen, \ mock.patch(self.base_path + '.time.sleep'), \ mock.patch(self.waitpid_path) as waitpid, \ self._mock_sbus_client('ping') as ping: popen.side_effect = [FakePopenObject(1000), FakePopenObject(1001)] waitpid.return_value = 0, 0 ping.return_value = SBusResponse(True, 'OK') self.assertTrue( self.dfactory.process_start_daemon('java', 'path/to/storlet/a', 'storleta', 1, 'path/to/uds/a', 'TRACE')) self.assertEqual({'storleta': 'path/to/uds/a'}, self.dfactory.storlet_name_to_pipe_name) # Already running self.dfactory.storlet_name_to_pid = {'storleta': 1000} self.dfactory.storlet_name_to_pipe_name = {'storleta': 'path/to/uds/a'} with mock.patch(self.waitpid_path) as waitpid: waitpid.return_value = 0, 0 self.assertFalse( self.dfactory.process_start_daemon('java', 'path/to/storlet/a', 'storleta', 1, 'path/to/uds/a', 'TRACE')) # Unsupported language with self.assertRaises(SDaemonError): self.dfactory.process_start_daemon('foo', 'path/to/storlet/a', 'storleta', 1, 'path/to/uds/a', 'TRACE')