From: Brian Warner Date: Mon, 18 Feb 2008 07:28:56 +0000 (-0700) Subject: test_runner.py: test launching an introducer too X-Git-Url: https://git.rkrishnan.org/specifications//%22%3C?a=commitdiff_plain;h=1af3bfb1d494461494b2552f7f673d050f4c64d7;p=tahoe-lafs%2Ftahoe-lafs.git test_runner.py: test launching an introducer too --- diff --git a/src/allmydata/test/test_runner.py b/src/allmydata/test/test_runner.py index 5bd90ddb..c34d2e25 100644 --- a/src/allmydata/test/test_runner.py +++ b/src/allmydata/test/test_runner.py @@ -99,6 +99,100 @@ class RunNode(unittest.TestCase, testutil.PollMixin): fileutil.make_dirs(basedir) return basedir + def test_introducer(self): + if runtime.platformType == "win32": + # twistd on windows doesn't daemonize. cygwin works normally. + raise unittest.SkipTest("twistd does not fork under windows") + basedir = self.workdir("test_introducer") + c1 = os.path.join(basedir, "c1") + argv = ["--quiet", "create-introducer", "--basedir", c1] + out,err = StringIO(), StringIO() + rc = runner.runner(argv, stdout=out, stderr=err) + self.failUnlessEqual(rc, 0) + # by writing this file, we get ten seconds before the node will + # exit. This insures that even if the test fails (and the 'stop' + # command doesn't work), the client should still terminate. + HOTLINE_FILE = os.path.join(c1, "suicide_prevention_hotline") + open(HOTLINE_FILE, "w").write("") + # now it's safe to start the node + + TWISTD_PID_FILE = os.path.join(c1, "twistd.pid") + + d = defer.succeed(None) + def _start(res): + argv = ["--quiet", "start", c1] + out,err = StringIO(), StringIO() + rc = runner.runner(argv, stdout=out, stderr=err) + open(HOTLINE_FILE, "w").write("") + outs = out.getvalue() ; errs = err.getvalue() + errstr = "rc=%d, OUT: '%s', ERR: '%s'" % (rc, outs, errs) + self.failUnlessEqual(rc, 0, errstr) + self.failUnlessEqual(outs, "", errstr) + self.failUnlessEqual(errs, "", errstr) + + # the parent (twistd) has exited. However, twistd writes the pid + # from the child, not the parent, so we can't expect twistd.pid + # to exist quite yet. + + # the node is running, but it might not have made it past the + # first reactor turn yet, and if we kill it too early, it won't + # remove the twistd.pid file. So wait until it does something + # that we know it won't do until after the first turn. + + d.addCallback(_start) + + INTRODUCER_FURL_FILE = os.path.join(c1, "introducer.furl") + def _node_has_started(): + return os.path.exists(INTRODUCER_FURL_FILE) + d.addCallback(lambda res: self.poll(_node_has_started)) + + def _started(res): + open(HOTLINE_FILE, "w").write("") + self.failUnless(os.path.exists(TWISTD_PID_FILE)) + # rm this so we can detect when the second incarnation is ready + os.unlink(INTRODUCER_FURL_FILE) + argv = ["--quiet", "restart", c1] + out,err = StringIO(), StringIO() + rc = runner.runner(argv, stdout=out, stderr=err) + open(HOTLINE_FILE, "w").write("") + outs = out.getvalue() ; errs = err.getvalue() + errstr = "rc=%d, OUT: '%s', ERR: '%s'" % (rc, outs, errs) + self.failUnlessEqual(rc, 0, errstr) + self.failUnlessEqual(outs, "", errstr) + self.failUnlessEqual(errs, "", errstr) + d.addCallback(_started) + + # again, the second incarnation of the node might not be ready yet, + # so poll until it is + d.addCallback(lambda res: self.poll(_node_has_started)) + + # now we can kill it. TODO: On a slow machine, the node might kill + # itself before we get a chance too, especially if spawning the + # 'tahoe stop' command takes a while. + def _stop(res): + open(HOTLINE_FILE, "w").write("") + self.failUnless(os.path.exists(TWISTD_PID_FILE)) + argv = ["--quiet", "stop", c1] + out,err = StringIO(), StringIO() + rc = runner.runner(argv, stdout=out, stderr=err) + open(HOTLINE_FILE, "w").write("") + # the parent has exited by now + outs = out.getvalue() ; errs = err.getvalue() + errstr = "rc=%d, OUT: '%s', ERR: '%s'" % (rc, outs, errs) + self.failUnlessEqual(rc, 0, errstr) + self.failUnlessEqual(outs, "", errstr) + self.failUnlessEqual(errs, "", errstr) + # the parent was supposed to poll and wait until it sees + # twistd.pid go away before it exits, so twistd.pid should be + # gone by now. + self.failIf(os.path.exists(TWISTD_PID_FILE)) + d.addCallback(_stop) + def _remove_hotline(res): + os.unlink(HOTLINE_FILE) + return res + d.addBoth(_remove_hotline) + return d + def test_client(self): if runtime.platformType == "win32": # twistd on windows doesn't daemonize. cygwin works normally.