summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/swift-init3
-rw-r--r--test/bin/test_swift_init.py192
2 files changed, 190 insertions, 5 deletions
diff --git a/bin/swift-init b/bin/swift-init
index b537ba834..ea55f6a65 100755
--- a/bin/swift-init
+++ b/bin/swift-init
@@ -100,8 +100,7 @@ def write_file(path, contents):
os.makedirs(dir)
except OSError, err:
if err.errno == errno.EACCES:
- sys.exit('Unable to create %s. Running as non-root?' %
- dir)
+ sys.exit('Unable to create %s. Running as non-root?' % dir)
with open(path, 'w') as f:
f.write('%s' % contents)
diff --git a/test/bin/test_swift_init.py b/test/bin/test_swift_init.py
index 82437aff6..fcb5dd31d 100644
--- a/test/bin/test_swift_init.py
+++ b/test/bin/test_swift_init.py
@@ -22,6 +22,8 @@ from shutil import rmtree
from contextlib import contextmanager
from tempfile import mkdtemp
from collections import defaultdict
+from threading import Thread
+from time import sleep
from test import bin # for reloading...
from test.bin import swift_init # for testing...
@@ -93,6 +95,10 @@ class TestSwiftInitModule(unittest.TestCase):
self.assertEquals(len(main_plus_rest), len(swift_init.MAIN_SERVERS) +
len(swift_init.REST_SERVERS))
+ def test_setup_env(self):
+ # TODO: tests
+ pass
+
def test_search_tree(self):
# file match & ext miss
with temptree(['asdf.conf', 'blarg.conf', 'asdf.cfg']) as t:
@@ -150,6 +156,16 @@ class TestSwiftInitModule(unittest.TestCase):
with open(file_name, 'r') as f:
contents = f.read()
self.assertEquals(contents, 'test')
+ # and also subdirs
+ file_name = os.path.join(t, 'subdir/test2')
+ swift_init.write_file(file_name, 'test2')
+ with open(file_name, 'r') as f:
+ contents = f.read()
+ self.assertEquals(contents, 'test2')
+ # but can't over-write files
+ file_name = os.path.join(t, 'subdir/test2/test3')
+ self.assertRaises(IOError, swift_init.write_file, file_name,
+ 'test3')
def test_remove_file(self):
with temptree([]) as t:
@@ -656,12 +672,182 @@ class TestSwiftServerClass(unittest.TestCase):
finally:
sys.stdout = old_stdout
- #TODO: more tests
def test_spawn(self):
- pass
+ # mocks
+ class MockProcess():
+
+ NOTHING = 'default besides None'
+ STDOUT = 'stdout'
+ PIPE = 'pipe'
+
+ def __init__(self, pids=None):
+ if pids is None:
+ pids = []
+ self.pids = (p for p in pids)
+
+ def Popen(self, args, **kwargs):
+ return MockProc(self.pids.next(), args, **kwargs)
+
+ class MockProc():
+
+ def __init__(self, pid, args, stdout=MockProcess.NOTHING,
+ stderr=MockProcess.NOTHING):
+ self.pid = pid
+ self.args = args
+ self.stdout = stdout
+ if stderr == MockProcess.STDOUT:
+ self.stderr = self.stdout
+ else:
+ self.stderr = stderr
+
+ # setup running servers
+ server = swift_init.SwiftServer('test')
+
+ with temptree(['test-server.conf']) as swift_dir:
+ swift_init.SWIFT_DIR = swift_dir
+ with temptree([]) as t:
+ swift_init.RUN_DIR = t
+ old_subprocess = swift_init.subprocess
+ try:
+ # test single server process calls spawn once
+ swift_init.subprocess = MockProcess([1])
+ conf_file = self.join_swift_dir('test-server.conf')
+ # spawn server no kwargs
+ server.spawn(conf_file)
+ # test pid file
+ pid_file = self.join_run_dir('test-server.pid')
+ self.assert_(os.path.exists(pid_file))
+ pid_on_disk = int(open(pid_file).read().strip())
+ self.assertEquals(pid_on_disk, 1)
+ # assert procs args
+ self.assert_(server.procs)
+ self.assertEquals(len(server.procs), 1)
+ proc = server.procs[0]
+ expected_args = [
+ 'swift-test-server',
+ conf_file,
+ ]
+ self.assertEquals(proc.args, expected_args)
+ # assert stdout is /dev/null
+ self.assert_(isinstance(proc.stdout, file))
+ self.assertEquals(proc.stdout.name, os.devnull)
+ self.assertEquals(proc.stdout.mode, 'w+b')
+ self.assertEquals(proc.stderr, proc.stdout)
+ # test multi server process calls spawn multiple times
+ swift_init.subprocess = MockProcess([11, 12, 13, 14])
+ conf1 = self.join_swift_dir('test-server/1.conf')
+ conf2 = self.join_swift_dir('test-server/2.conf')
+ conf3 = self.join_swift_dir('test-server/3.conf')
+ conf4 = self.join_swift_dir('test-server/4.conf')
+ server = swift_init.SwiftServer('test')
+ # test server run once
+ server.spawn(conf1, once=True)
+ self.assert_(server.procs)
+ self.assertEquals(len(server.procs), 1)
+ proc = server.procs[0]
+ expected_args = ['swift-test-server', conf1, 'once']
+ self.assertEquals(proc.args, expected_args)
+ # assert stdout is /dev/null
+ self.assert_(isinstance(proc.stdout, file))
+ self.assertEquals(proc.stdout.name, os.devnull)
+ self.assertEquals(proc.stdout.mode, 'w+b')
+ self.assertEquals(proc.stderr, proc.stdout)
+ # test server not daemon
+ server.spawn(conf2, daemon=False)
+ self.assert_(server.procs)
+ self.assertEquals(len(server.procs), 2)
+ proc = server.procs[1]
+ expected_args = ['swift-test-server', conf2, 'verbose']
+ self.assertEquals(proc.args, expected_args)
+ # assert stdout is not changed
+ self.assertEquals(proc.stdout, None)
+ self.assertEquals(proc.stderr, None)
+ # test server wait
+ server.spawn(conf3, wait=True)
+ self.assert_(server.procs)
+ self.assertEquals(len(server.procs), 3)
+ proc = server.procs[2]
+ # assert stdout is piped
+ self.assertEquals(proc.stdout, MockProcess.PIPE)
+ self.assertEquals(proc.stderr, proc.stdout)
+ # test not daemon over-rides wait
+ server.spawn(conf4, wait=True, daemon=False, once=True)
+ self.assert_(server.procs)
+ self.assertEquals(len(server.procs), 4)
+ proc = server.procs[3]
+ expected_args = ['swift-test-server', conf4, 'once',
+ 'verbose']
+ self.assertEquals(proc.args, expected_args)
+ # daemon behavior should trump wait, once shouldn't matter
+ self.assertEquals(proc.stdout, None)
+ self.assertEquals(proc.stderr, None)
+ # assert pids
+ for i, proc in enumerate(server.procs):
+ pid_file = self.join_run_dir('test-server/%d.pid' %
+ (i + 1))
+ pid_on_disk = int(open(pid_file).read().strip())
+ self.assertEquals(pid_on_disk, proc.pid)
+ finally:
+ swift_init.subprocess = old_subprocess
+
+ #TODO: more tests
def test_wait(self):
- pass
+ server = swift_init.SwiftServer('test')
+ self.assertEquals(server.wait(), 0)
+
+ class MockProcess(Thread):
+ def __init__(self, stdout, delay=0.1, fail_to_start=False):
+ Thread.__init__(self)
+ self.stdout = stdout
+ self.delay = delay
+ self.finished = False
+ self.returncode = None
+ if fail_to_start:
+ self.run = self.fail
+
+ def close_stdout(self):
+ with open(os.devnull, 'r+b') as nullfile:
+ try:
+ os.dup2(nullfile.fileno(), self.stdout.fileno())
+ except OSError:
+ pass
+
+ def fail(self):
+ print >>self.stdout, 'mock process started'
+ sleep(self.delay) # perform setup processing
+ print >>self.stdout, 'mock process failed to start'
+ self.returncode = 1
+ self.close_stdout()
+ self.finished = True
+
+ def run(self):
+ print >>self.stdout, 'mock process started'
+ sleep(self.delay) # perform setup processing
+ print >>self.stdout, 'setup complete!'
+ self.close_stdout()
+ sleep(self.delay) # do some more processing
+ print >>self.stdout, 'mock process finished'
+ self.returncode = 0
+ self.finished = True
+
+ with temptree([]) as t:
+ old_stdout = sys.stdout
+ try:
+ with open(os.path.join(t, 'output'), 'w+') as f:
+ # acctually capture the read stdout (for prints)
+ sys.stdout = f
+ stdout = open(os.path.join(t, 'subout'), 'w+')
+ # the proc will have it's stdout redirected to
+ # subprocess.PIPE
+ proc = MockProcess(stdout)
+ proc.start()
+ server.procs = [proc]
+ server.wait(output=True)
+ proc.join()
+ print >>sys.stderr, pop_stream(f)
+ finally:
+ sys.stdout = old_stdout
def test_interact(self):
pass