diff --git a/bin/swift-init b/bin/swift-init index c6e770bd8f..53418d64e1 100644 --- a/bin/swift-init +++ b/bin/swift-init @@ -19,7 +19,7 @@ from optparse import OptionParser from swift.common.manager import Server, Manager, UnknownCommandError -USAGE = """%prog [ +USAGE = """%prog [ ...] Commands: """ + '\n'.join(["%16s: %s" % x for x in Manager.list_commands()]) @@ -63,7 +63,7 @@ def main(): except UnknownCommandError: parser.print_help() print 'ERROR: unknown command, %s' % command - return 1 + status = 1 return 1 if status else 0 diff --git a/swift/common/manager.py b/swift/common/manager.py index d2a8c3f0d0..881cfa4457 100644 --- a/swift/common/manager.py +++ b/swift/common/manager.py @@ -28,6 +28,7 @@ import re SWIFT_DIR = '/etc/swift' RUN_DIR = '/var/run/swift' +# auth-server has been removed from ALL_SERVERS, start it explicitly ALL_SERVERS = ['account-auditor', 'account-server', 'container-auditor', 'container-replicator', 'container-server', 'container-updater', 'object-auditor', 'object-server', 'object-replicator', 'object-updater', @@ -35,7 +36,7 @@ ALL_SERVERS = ['account-auditor', 'account-server', 'container-auditor', MAIN_SERVERS = ['proxy-server', 'account-server', 'container-server', 'object-server'] REST_SERVERS = [s for s in ALL_SERVERS if s not in MAIN_SERVERS] -GRACEFUL_SHUTDOWN_SERVERS = MAIN_SERVERS +GRACEFUL_SHUTDOWN_SERVERS = MAIN_SERVERS + ['auth-server'] START_ONCE_SERVERS = REST_SERVERS KILL_WAIT = 15 # seconds to wait for servers to die @@ -210,7 +211,8 @@ class Manager(): server_pids[server] = signaled_pids # all signaled_pids, i.e. list(itertools.chain(*server_pids.values())) - signaled_pids = [p for server, pids in server_pids.items() for p in pids] + signaled_pids = [p for server, pids in server_pids.items() + for p in pids] # keep track of the pids yeiled back as killed for all servers killed_pids = set() for server, killed_pid in watch_server_pids(server_pids, @@ -253,9 +255,9 @@ class Manager(): kwargs['graceful'] = True status = 0 for server in self.servers: - init = Manager([server.server]) - status += init.stop(**kwargs) - status += init.start(**kwargs) + m = Manager([server.server]) + status += m.stop(**kwargs) + status += m.start(**kwargs) return status @command @@ -398,8 +400,8 @@ class Server(): number = kwargs.get('number', 0) if number: conf_files = self.conf_files(**kwargs) - # limt pid_files the one who translates to the indexed conf_file for - # this given number + # limt pid_files the one who translates to the indexed + # conf_file for this given number pid_files = [pid_file for pid_file in pid_files if self.get_conf_file_name(pid_file) in conf_files] return pid_files diff --git a/test/unit/common/test_manager.py b/test/unit/common/test_manager.py index de39a13cb7..f1def168ab 100644 --- a/test/unit/common/test_manager.py +++ b/test/unit/common/test_manager.py @@ -326,7 +326,7 @@ class TestServer(unittest.TestCase): self.assertEquals(conf_file, server.get_conf_file_name(pid_file)) def test_conf_files(self): - # test get single ini file + # test get single conf file conf_files = ( 'proxy-server.conf', 'proxy-server.ini', @@ -653,7 +653,7 @@ class TestServer(unittest.TestCase): self.assertEquals(manager.os.pid_sigs[1], [signal.SIGHUP]) # start up other servers manager.os = MockOs([11, 12]) - # test multi server kill & ignore graceful on unsupport server + # test multi server kill & ignore graceful on unsupported server self.assertFalse('object-replicator' in manager.GRACEFUL_SHUTDOWN_SERVERS) server = manager.Server('object-replicator') @@ -993,6 +993,7 @@ class TestServer(unittest.TestCase): # stubs conf_files = ( 'proxy-server.conf', + 'auth-server.conf', 'object-server/1.conf', 'object-server/2.conf', 'object-server/3.conf', @@ -1020,7 +1021,11 @@ class TestServer(unittest.TestCase): def __call__(self, conf_file, **kwargs): self.conf_files.append(conf_file) self.kwargs.append(kwargs) - return self.pids.next() + rv = self.pids.next() + if isinstance(rv, Exception): + raise rv + else: + return rv with temptree(conf_files) as swift_dir: manager.SWIFT_DIR = swift_dir @@ -1099,6 +1104,13 @@ class TestServer(unittest.TestCase): 'number': 4 } self.assertEquals(mock_spawn.kwargs, [expected]) + # test cmd does not exist + server = manager.Server('auth') + mock_spawn = MockSpawn([OSError(errno.ENOENT, 'blah')]) + server.spawn = mock_spawn + self.assertEquals(server.launch(), {}) + self.assert_('swift-auth-server does not exist' in + pop_stream(f)) finally: sys.stdout = old_stdout @@ -1455,7 +1467,6 @@ class TestManager(unittest.TestCase): def __call__(self, server): return MockServerFactory.MockServer(self.server_pids[server]) - def mock_watch_server_pids(server_pids, **kwargs): for server, pids in server_pids.items(): for pid in pids: @@ -1498,19 +1509,112 @@ class TestManager(unittest.TestCase): # TODO: more tests def test_shutdown(self): - pass + m = manager.Manager(['test']) + m.stop_was_called = False + + def mock_stop(*args, **kwargs): + m.stop_was_called = True + expected = {'graceful': True} + self.assertEquals(kwargs, expected) + return 0 + m.stop = mock_stop + status = m.shutdown() + self.assertEquals(status, 0) + self.assertEquals(m.stop_was_called, True) def test_restart(self): - pass + m = manager.Manager(['test']) + m.stop_was_called = False + + def mock_stop(*args, **kwargs): + m.stop_was_called = True + return 0 + m.start_was_called = False + + def mock_start(*args, **kwargs): + m.start_was_called = True + return 0 + m.stop = mock_stop + m.start = mock_start + status = m.restart() + self.assertEquals(status, 0) + self.assertEquals(m.stop_was_called, True) + self.assertEquals(m.start_was_called, True) def test_reload(self): - pass + class MockManager(): + called = defaultdict(list) + + def __init__(self, servers): + pass + + @classmethod + def reset_called(cls): + cls.called = defaultdict(list) + + def stop(self, **kwargs): + MockManager.called['stop'].append(kwargs) + return 0 + + def start(self, **kwargs): + MockManager.called['start'].append(kwargs) + return 0 + + _orig_manager = manager.Manager + try: + m = _orig_manager(['auth']) + for server in m.servers: + self.assert_(server.server in + manager.GRACEFUL_SHUTDOWN_SERVERS) + manager.Manager = MockManager + status = m.reload() + self.assertEquals(status, 0) + expected = { + 'start': [{'graceful': True}], + 'stop': [{'graceful': True}], + } + self.assertEquals(MockManager.called, expected) + # test force graceful + MockManager.reset_called() + m = _orig_manager(['*-server']) + self.assert_(len(m.servers), 4) + for server in m.servers: + self.assert_(server.server in + manager.GRACEFUL_SHUTDOWN_SERVERS) + manager.Manager = MockManager + status = m.reload(graceful=False) + self.assertEquals(status, 0) + expected = { + 'start': [{'graceful': True}] * 4, + 'stop': [{'graceful': True}] * 4, + } + self.assertEquals(MockManager.called, expected) + + finally: + manager.Manager = _orig_manager def test_force_reload(self): - pass + m = manager.Manager(['test']) + m.reload_was_called = False + + def mock_reload(*args, **kwargs): + m.reload_was_called = True + return 0 + m.reload = mock_reload + status = m.force_reload() + self.assertEquals(status, 0) + self.assertEquals(m.reload_was_called, True) def test_get_command(self): - pass + m = manager.Manager(['test']) + self.assertEquals(m.start, m.get_command('start')) + self.assertEquals(m.force_reload, m.get_command('force-reload')) + self.assertEquals(m.get_command('force-reload'), + m.get_command('force_reload')) + self.assertRaises(manager.UnknownCommandError, m.get_command, + 'no_command') + self.assertRaises(manager.UnknownCommandError, m.get_command, + '__init__') def test_list_commands(self): for cmd, help in manager.Manager.list_commands(): @@ -1520,8 +1624,20 @@ class TestManager(unittest.TestCase): self.assertEquals(method.__doc__.strip(), help) def test_run_command(self): - pass + m = manager.Manager(['test']) + m.cmd_was_called = False + def mock_cmd(*args, **kwargs): + m.cmd_was_called = True + expected = {'kw1': True, 'kw2': False} + self.assertEquals(kwargs, expected) + return 0 + mock_cmd.publicly_accessible = True + m.mock_cmd = mock_cmd + kwargs = {'kw1': True, 'kw2': False} + status = m.run_command('mock_cmd', **kwargs) + self.assertEquals(status, 0) + self.assertEquals(m.cmd_was_called, True) if __name__ == '__main__': unittest.main()