예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
 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())
예제 #4
0
    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')
예제 #5
0
    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')
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
 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)
예제 #10
0
    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()
예제 #11
0
    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')