2007-04-20 01:56:45 +00:00
from twisted . trial import unittest
2009-02-09 09:26:17 +00:00
from twisted . python import usage , runtime
2009-01-22 22:52:13 +00:00
from twisted . internet import utils
2009-01-27 21:37:17 +00:00
import os . path , re , sys
2009-02-09 09:26:17 +00:00
from cStringIO import StringIO
2008-10-29 04:15:48 +00:00
from allmydata . util import fileutil , pollmixin
2009-02-09 09:26:17 +00:00
from allmydata . scripts import runner
2007-04-20 01:56:45 +00:00
2009-01-22 22:38:18 +00:00
from allmydata . test import common_util
2009-01-22 22:52:40 +00:00
import allmydata
2009-01-24 01:34:37 +00:00
bintahoe = os . path . join ( os . path . dirname ( os . path . dirname ( os . path . dirname ( allmydata . __file__ ) ) ) , ' bin ' , ' tahoe ' )
2009-01-27 21:37:17 +00:00
if sys . platform == " win32 " :
bintahoe + = " .exe "
2009-01-24 01:34:37 +00:00
2009-02-09 09:34:00 +00:00
class SkipOnCygwinMixin :
def skip_on_cygwin ( self ) :
if " cygwin " in sys . platform . lower ( ) :
raise unittest . SkipTest ( " We don ' t know how to make this test work on cygwin: spawnProcess seems to hang forever. We don ' t know if ' bin/tahoe start ' can be run on cygwin. " )
2009-02-23 21:43:12 +00:00
class TheRightCode ( common_util . SignalMixin , unittest . TestCase ,
2009-02-09 09:34:00 +00:00
SkipOnCygwinMixin ) :
2009-01-22 22:52:40 +00:00
def test_path ( self ) :
2009-02-09 09:34:00 +00:00
self . skip_on_cygwin ( )
2009-01-24 01:34:37 +00:00
if not os . path . exists ( bintahoe ) :
raise unittest . SkipTest ( " The bin/tahoe script isn ' t to be found in the expected location, and I don ' t want to test a ' tahoe ' executable that I find somewhere else, in case it isn ' t the right executable for this version of tahoe. " )
d = utils . getProcessOutputAndValue ( bintahoe , args = [ " --version-and-path " ] , env = os . environ )
2009-01-22 22:52:40 +00:00
def _cb ( res ) :
out , err , rc_or_sig = res
self . failUnlessEqual ( rc_or_sig , 0 )
# Fail unless the allmydata-tahoe package is *this* version *and* was loaded from *this* source directory.
required_ver_and_path = " allmydata-tahoe: %s ( %s ) " % ( allmydata . __version__ , os . path . dirname ( os . path . dirname ( allmydata . __file__ ) ) )
2009-01-29 17:49:06 +00:00
self . failUnless ( out . startswith ( required_ver_and_path ) , ( out , err , rc_or_sig , required_ver_and_path ) )
2009-01-22 22:52:40 +00:00
d . addCallback ( _cb )
return d
2009-01-22 22:38:18 +00:00
2009-02-09 09:26:17 +00:00
class CreateNode ( unittest . TestCase ) :
# exercise "tahoe create-client", create-introducer,
# create-key-generator, and create-stats-gatherer, by calling the
# corresponding code as a subroutine.
2007-04-20 01:56:45 +00:00
def workdir ( self , name ) :
2007-09-17 09:25:31 +00:00
basedir = os . path . join ( " test_runner " , " CreateNode " , name )
2007-04-20 01:56:45 +00:00
fileutil . make_dirs ( basedir )
return basedir
2009-02-09 09:26:17 +00:00
def run_tahoe ( self , argv ) :
out , err = StringIO ( ) , StringIO ( )
rc = runner . runner ( argv , stdout = out , stderr = err )
return rc , out . getvalue ( ) , err . getvalue ( )
2007-04-20 01:56:45 +00:00
def test_client ( self ) :
basedir = self . workdir ( " test_client " )
c1 = os . path . join ( basedir , " c1 " )
2009-02-09 09:26:17 +00:00
argv = [ " --quiet " , " create-client " , " --basedir " , c1 ]
rc , out , err = self . run_tahoe ( argv )
self . failUnlessEqual ( err , " " )
self . failUnlessEqual ( out , " " )
self . failUnlessEqual ( rc , 0 )
self . failUnless ( os . path . exists ( c1 ) )
self . failUnless ( os . path . exists ( os . path . join ( c1 , " tahoe-client.tac " ) ) )
# creating the client a second time should be rejected
rc , out , err = self . run_tahoe ( argv )
self . failIfEqual ( rc , 0 , str ( ( out , err , rc ) ) )
self . failUnlessEqual ( out , " " )
self . failUnless ( " is not empty. " in err )
# Fail if there is a non-empty line that doesn't end with a
# punctuation mark.
for line in err . splitlines ( ) :
self . failIf ( re . search ( " [ \ S][^ \ .!?]$ " , line ) , ( line , ) )
# test that the non --basedir form works too
2007-04-24 04:28:19 +00:00
c2 = os . path . join ( basedir , " c2 " )
2009-02-09 09:26:17 +00:00
argv = [ " --quiet " , " create-client " , c2 ]
rc , out , err = self . run_tahoe ( argv )
self . failUnless ( os . path . exists ( c2 ) )
self . failUnless ( os . path . exists ( os . path . join ( c2 , " tahoe-client.tac " ) ) )
2009-01-22 22:38:18 +00:00
2009-02-09 09:26:17 +00:00
# make sure it rejects too many arguments
argv = [ " create-client " , " basedir " , " extraarg " ]
self . failUnlessRaises ( usage . UsageError ,
runner . runner , argv ,
run_by_human = False )
2007-04-24 04:28:19 +00:00
2007-04-20 01:56:45 +00:00
def test_introducer ( self ) :
basedir = self . workdir ( " test_introducer " )
c1 = os . path . join ( basedir , " c1 " )
2009-02-09 09:26:17 +00:00
argv = [ " --quiet " , " create-introducer " , " --basedir " , c1 ]
rc , out , err = self . run_tahoe ( argv )
self . failUnlessEqual ( err , " " , err )
self . failUnlessEqual ( out , " " )
self . failUnlessEqual ( rc , 0 )
self . failUnless ( os . path . exists ( c1 ) )
self . failUnless ( os . path . exists ( os . path . join ( c1 , " tahoe-introducer.tac " ) ) )
# creating the introducer a second time should be rejected
rc , out , err = self . run_tahoe ( argv )
self . failIfEqual ( rc , 0 )
self . failUnlessEqual ( out , " " )
self . failUnless ( " is not empty " in err )
# Fail if there is a non-empty line that doesn't end with a
# punctuation mark.
for line in err . splitlines ( ) :
self . failIf ( re . search ( " [ \ S][^ \ .!?]$ " , line ) , ( line , ) )
# test the non --basedir form
2007-04-24 04:28:19 +00:00
c2 = os . path . join ( basedir , " c2 " )
2009-02-09 09:26:17 +00:00
argv = [ " --quiet " , " create-introducer " , c2 ]
rc , out , err = self . run_tahoe ( argv )
self . failUnlessEqual ( err , " " , err )
self . failUnlessEqual ( out , " " )
self . failUnlessEqual ( rc , 0 )
self . failUnless ( os . path . exists ( c2 ) )
self . failUnless ( os . path . exists ( os . path . join ( c2 , " tahoe-introducer.tac " ) ) )
# reject extra arguments
argv = [ " create-introducer " , " basedir " , " extraarg " ]
self . failUnlessRaises ( usage . UsageError ,
runner . runner , argv ,
run_by_human = False )
# and require basedir to be provided in some form
argv = [ " create-introducer " ]
self . failUnlessRaises ( usage . UsageError ,
runner . runner , argv ,
run_by_human = False )
def test_key_generator ( self ) :
basedir = self . workdir ( " test_key_generator " )
kg1 = os . path . join ( basedir , " kg1 " )
argv = [ " --quiet " , " create-key-generator " , " --basedir " , kg1 ]
rc , out , err = self . run_tahoe ( argv )
self . failUnlessEqual ( err , " " )
self . failUnlessEqual ( out , " " )
self . failUnlessEqual ( rc , 0 )
self . failUnless ( os . path . exists ( kg1 ) )
self . failUnless ( os . path . exists ( os . path . join ( kg1 , " tahoe-key-generator.tac " ) ) )
# creating it a second time should be rejected
rc , out , err = self . run_tahoe ( argv )
self . failIfEqual ( rc , 0 , str ( ( out , err , rc ) ) )
self . failUnlessEqual ( out , " " )
self . failUnless ( " is not empty. " in err )
# make sure it rejects too many arguments
argv = [ " create-key-generator " , " basedir " , " extraarg " ]
self . failUnlessRaises ( usage . UsageError ,
runner . runner , argv ,
run_by_human = False )
# make sure it rejects a missing basedir specification
argv = [ " create-key-generator " ]
rc , out , err = self . run_tahoe ( argv )
self . failIfEqual ( rc , 0 , str ( ( out , err , rc ) ) )
self . failUnlessEqual ( out , " " )
self . failUnless ( " a basedir was not provided " in err )
def test_stats_gatherer ( self ) :
basedir = self . workdir ( " test_stats_gatherer " )
sg1 = os . path . join ( basedir , " sg1 " )
argv = [ " --quiet " , " create-stats-gatherer " , " --basedir " , sg1 ]
rc , out , err = self . run_tahoe ( argv )
self . failUnlessEqual ( err , " " )
self . failUnlessEqual ( out , " " )
self . failUnlessEqual ( rc , 0 )
self . failUnless ( os . path . exists ( sg1 ) )
self . failUnless ( os . path . exists ( os . path . join ( sg1 , " tahoe-stats-gatherer.tac " ) ) )
# creating it a second time should be rejected
rc , out , err = self . run_tahoe ( argv )
self . failIfEqual ( rc , 0 , str ( ( out , err , rc ) ) )
self . failUnlessEqual ( out , " " )
self . failUnless ( " is not empty. " in err )
# test the non --basedir form
kg2 = os . path . join ( basedir , " kg2 " )
argv = [ " --quiet " , " create-stats-gatherer " , kg2 ]
rc , out , err = self . run_tahoe ( argv )
self . failUnlessEqual ( err , " " , err )
self . failUnlessEqual ( out , " " )
self . failUnlessEqual ( rc , 0 )
self . failUnless ( os . path . exists ( kg2 ) )
self . failUnless ( os . path . exists ( os . path . join ( kg2 , " tahoe-stats-gatherer.tac " ) ) )
# make sure it rejects too many arguments
argv = [ " create-stats-gatherer " , " basedir " , " extraarg " ]
self . failUnlessRaises ( usage . UsageError ,
runner . runner , argv ,
run_by_human = False )
# make sure it rejects a missing basedir specification
argv = [ " create-stats-gatherer " ]
rc , out , err = self . run_tahoe ( argv )
self . failIfEqual ( rc , 0 , str ( ( out , err , rc ) ) )
self . failUnlessEqual ( out , " " )
self . failUnless ( " a basedir was not provided " in err )
def test_subcommands ( self ) :
# no arguments should trigger a command listing, via UsageError
self . failUnlessRaises ( usage . UsageError ,
runner . runner ,
[ ] ,
run_by_human = False )
2009-01-22 22:38:18 +00:00
2009-02-23 21:43:12 +00:00
class RunNode ( common_util . SignalMixin , unittest . TestCase , pollmixin . PollMixin ,
2009-02-09 09:34:00 +00:00
SkipOnCygwinMixin ) :
# exercise "tahoe start", for both introducer, client node, and
# key-generator, by spawning "tahoe start" as a subprocess. This doesn't
# get us figleaf-based line-level coverage, but it does a better job of
# confirming that the user can actually run "./bin/tahoe start" and
# expect it to work. This verifies that bin/tahoe sets up PYTHONPATH and
# the like correctly.
# This doesn't work on cygwin (it hangs forever), so we skip this test
# when we're on cygwin. It is likely that "tahoe start" itself doesn't
# work on cygwin: twisted seems unable to provide a version of
# spawnProcess which really works there.
2007-09-17 09:25:31 +00:00
def workdir ( self , name ) :
basedir = os . path . join ( " test_runner " , " RunNode " , name )
fileutil . make_dirs ( basedir )
return basedir
2008-02-18 07:28:56 +00:00
def test_introducer ( self ) :
2009-02-09 09:34:00 +00:00
self . skip_on_cygwin ( )
2009-01-24 01:34:37 +00:00
if not os . path . exists ( bintahoe ) :
raise unittest . SkipTest ( " The bin/tahoe script isn ' t to be found in the expected location, and I don ' t want to test a ' tahoe ' executable that I find somewhere else, in case it isn ' t the right executable for this version of tahoe. " )
2008-02-18 07:28:56 +00:00
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 " )
HOTLINE_FILE = os . path . join ( c1 , " suicide_prevention_hotline " )
TWISTD_PID_FILE = os . path . join ( c1 , " twistd.pid " )
2009-01-22 22:38:18 +00:00
INTRODUCER_FURL_FILE = os . path . join ( c1 , " introducer.furl " )
2009-01-24 01:34:37 +00:00
d = utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " create-introducer " , " --basedir " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
def _cb ( res ) :
out , err , rc_or_sig = res
self . failUnlessEqual ( rc_or_sig , 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.
open ( HOTLINE_FILE , " w " ) . write ( " " )
# now it's safe to start the node
d . addCallback ( _cb )
def _then_start_the_node ( res ) :
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " start " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
d . addCallback ( _then_start_the_node )
def _cb2 ( res ) :
out , err , rc_or_sig = res
2008-02-18 07:28:56 +00:00
open ( HOTLINE_FILE , " w " ) . write ( " " )
2009-01-22 22:38:18 +00:00
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2008-02-18 07:28:56 +00:00
# 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.
2009-01-22 22:38:18 +00:00
d . addCallback ( _cb2 )
2008-02-18 07:28:56 +00:00
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 )
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " restart " , c1 ] , env = os . environ )
2008-02-18 07:28:56 +00:00
d . addCallback ( _started )
2009-01-22 22:38:18 +00:00
def _then ( res ) :
out , err , rc_or_sig = res
open ( HOTLINE_FILE , " w " ) . write ( " " )
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2009-01-22 22:38:18 +00:00
d . addCallback ( _then )
2008-02-18 07:28:56 +00:00
# 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 ) )
2009-01-22 22:38:18 +00:00
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " stop " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
d . addCallback ( _stop )
def _after_stopping ( res ) :
out , err , rc_or_sig = res
2008-02-18 07:28:56 +00:00
open ( HOTLINE_FILE , " w " ) . write ( " " )
# the parent has exited by now
2009-01-22 22:38:18 +00:00
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2008-02-18 07:28:56 +00:00
# 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 ) )
2009-01-22 22:38:18 +00:00
d . addCallback ( _after_stopping )
2008-02-18 07:28:56 +00:00
def _remove_hotline ( res ) :
os . unlink ( HOTLINE_FILE )
return res
d . addBoth ( _remove_hotline )
return d
2009-05-07 21:50:12 +00:00
test_introducer . timeout = 240 # This hit the 120-second timeout on "François Lenny-armv5tel"
2008-02-18 07:28:56 +00:00
2009-01-27 00:30:46 +00:00
def test_client_no_noise ( self ) :
2009-02-09 09:34:00 +00:00
self . skip_on_cygwin ( )
2009-01-27 00:30:46 +00:00
if not os . path . exists ( bintahoe ) :
raise unittest . SkipTest ( " The bin/tahoe script isn ' t to be found in the expected location, and I don ' t want to test a ' tahoe ' executable that I find somewhere else, in case it isn ' t the right executable for this version of tahoe. " )
basedir = self . workdir ( " test_client_no_noise " )
c1 = os . path . join ( basedir , " c1 " )
HOTLINE_FILE = os . path . join ( c1 , " suicide_prevention_hotline " )
TWISTD_PID_FILE = os . path . join ( c1 , " twistd.pid " )
PORTNUMFILE = os . path . join ( c1 , " client.port " )
d = utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " create-client " , " --basedir " , c1 , " --webport " , " 0 " ] , env = os . environ )
def _cb ( res ) :
out , err , rc_or_sig = res
errstr = " cc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
assert rc_or_sig == 0 , errstr
self . failUnlessEqual ( rc_or_sig , 0 )
# By writing this file, we get forty seconds before the client will exit. This insures
# that even if the 'stop' command doesn't work (and the test fails), the client should
# still terminate.
open ( HOTLINE_FILE , " w " ) . write ( " " )
open ( os . path . join ( c1 , " introducer.furl " ) , " w " ) . write ( " pb://xrndsskn2zuuian5ltnxrte7lnuqdrkz@127.0.0.1:55617/introducer \n " )
# now it's safe to start the node
d . addCallback ( _cb )
def _start ( res ) :
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " start " , c1 ] , env = os . environ )
d . addCallback ( _start )
def _cb2 ( res ) :
out , err , rc_or_sig = res
errstr = " cc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
open ( HOTLINE_FILE , " w " ) . write ( " " )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr ) # If you emit noise, you fail this test.
2009-01-27 00:46:16 +00:00
self . failUnlessEqual ( err , " " , errstr )
2009-01-27 00:30:46 +00:00
# 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 ( _cb2 )
def _node_has_started ( ) :
return os . path . exists ( PORTNUMFILE )
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 ) :
self . failUnless ( os . path . exists ( TWISTD_PID_FILE ) , ( TWISTD_PID_FILE , os . listdir ( os . path . dirname ( TWISTD_PID_FILE ) ) ) )
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " stop " , c1 ] , env = os . environ )
d . addCallback ( _stop )
return d
test_client_no_noise . todo = " We submitted a patch to Nevow to silence this warning: http://divmod.org/trac/ticket/2830 "
2007-09-17 09:25:31 +00:00
def test_client ( self ) :
2009-02-09 09:34:00 +00:00
self . skip_on_cygwin ( )
2009-01-24 01:34:37 +00:00
if not os . path . exists ( bintahoe ) :
raise unittest . SkipTest ( " The bin/tahoe script isn ' t to be found in the expected location, and I don ' t want to test a ' tahoe ' executable that I find somewhere else, in case it isn ' t the right executable for this version of tahoe. " )
2007-09-18 22:17:26 +00:00
if runtime . platformType == " win32 " :
# twistd on windows doesn't daemonize. cygwin works normally.
2007-09-17 09:25:31 +00:00
raise unittest . SkipTest ( " twistd does not fork under windows " )
basedir = self . workdir ( " test_client " )
c1 = os . path . join ( basedir , " c1 " )
2007-09-18 22:17:26 +00:00
HOTLINE_FILE = os . path . join ( c1 , " suicide_prevention_hotline " )
TWISTD_PID_FILE = os . path . join ( c1 , " twistd.pid " )
2009-01-22 22:38:18 +00:00
PORTNUMFILE = os . path . join ( c1 , " client.port " )
2009-01-24 01:34:37 +00:00
d = utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " create-client " , " --basedir " , c1 , " --webport " , " 0 " ] , env = os . environ )
2009-01-22 22:38:18 +00:00
def _cb ( res ) :
out , err , rc_or_sig = res
self . failUnlessEqual ( rc_or_sig , 0 )
2009-02-12 22:21:31 +00:00
# By writing this file, we get sixty seconds before the client will exit. This insures
2009-01-22 22:38:18 +00:00
# that even if the 'stop' command doesn't work (and the test fails), the client should
# still terminate.
open ( HOTLINE_FILE , " w " ) . write ( " " )
open ( os . path . join ( c1 , " introducer.furl " ) , " w " ) . write ( " pb://xrndsskn2zuuian5ltnxrte7lnuqdrkz@127.0.0.1:55617/introducer \n " )
# now it's safe to start the node
d . addCallback ( _cb )
2007-09-18 22:17:26 +00:00
2007-09-19 20:56:00 +00:00
def _start ( res ) :
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " start " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
d . addCallback ( _start )
def _cb2 ( res ) :
out , err , rc_or_sig = res
2007-09-19 20:56:00 +00:00
open ( HOTLINE_FILE , " w " ) . write ( " " )
2009-01-22 22:38:18 +00:00
errstr = " cc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2007-09-17 09:25:31 +00:00
2007-09-19 20:56:00 +00:00
# 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.
2007-09-18 22:17:26 +00:00
2007-09-19 20:56:00 +00:00
# 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.
2009-01-22 22:38:18 +00:00
d . addCallback ( _cb2 )
2007-09-19 20:56:00 +00:00
2007-09-18 22:17:26 +00:00
def _node_has_started ( ) :
return os . path . exists ( PORTNUMFILE )
2007-09-19 20:56:00 +00:00
d . addCallback ( lambda res : self . poll ( _node_has_started ) )
2007-09-18 22:17:26 +00:00
def _started ( res ) :
2007-09-19 20:56:00 +00:00
open ( HOTLINE_FILE , " w " ) . write ( " " )
2007-09-18 22:17:26 +00:00
self . failUnless ( os . path . exists ( TWISTD_PID_FILE ) )
# rm this so we can detect when the second incarnation is ready
os . unlink ( PORTNUMFILE )
2009-01-22 22:38:18 +00:00
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " restart " , c1 ] , env = os . environ )
2007-09-18 22:17:26 +00:00
d . addCallback ( _started )
2009-01-22 22:38:18 +00:00
def _cb3 ( res ) :
out , err , rc_or_sig = res
open ( HOTLINE_FILE , " w " ) . write ( " " )
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2009-01-22 22:38:18 +00:00
d . addCallback ( _cb3 )
2007-09-18 22:17:26 +00:00
# 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 ) )
2007-09-19 20:56:00 +00:00
# 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
2007-10-11 10:38:24 +00:00
# 'tahoe stop' command takes a while.
2007-09-18 22:17:26 +00:00
def _stop ( res ) :
2007-09-19 20:56:00 +00:00
open ( HOTLINE_FILE , " w " ) . write ( " " )
2008-12-21 22:07:52 +00:00
self . failUnless ( os . path . exists ( TWISTD_PID_FILE ) , ( TWISTD_PID_FILE , os . listdir ( os . path . dirname ( TWISTD_PID_FILE ) ) ) )
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " stop " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
d . addCallback ( _stop )
def _cb4 ( res ) :
out , err , rc_or_sig = res
2007-09-19 20:56:00 +00:00
open ( HOTLINE_FILE , " w " ) . write ( " " )
2007-09-18 22:17:26 +00:00
# the parent has exited by now
2009-01-22 22:38:18 +00:00
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2007-09-18 22:17:26 +00:00
# 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 ) )
2009-01-22 22:38:18 +00:00
d . addCallback ( _cb4 )
2007-09-19 20:56:00 +00:00
def _remove_hotline ( res ) :
os . unlink ( HOTLINE_FILE )
return res
d . addBoth ( _remove_hotline )
2007-09-18 22:17:26 +00:00
return d
2007-09-17 09:25:31 +00:00
2007-09-19 08:50:27 +00:00
def test_baddir ( self ) :
2009-02-09 09:34:00 +00:00
self . skip_on_cygwin ( )
2009-01-24 01:34:37 +00:00
if not os . path . exists ( bintahoe ) :
raise unittest . SkipTest ( " The bin/tahoe script isn ' t to be found in the expected location, and I don ' t want to test a ' tahoe ' executable that I find somewhere else, in case it isn ' t the right executable for this version of tahoe. " )
2007-09-19 08:50:27 +00:00
basedir = self . workdir ( " test_baddir " )
fileutil . make_dirs ( basedir )
2009-01-22 22:38:18 +00:00
2009-01-24 01:34:37 +00:00
d = utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " start " , " --basedir " , basedir ] , env = os . environ )
2009-01-22 22:38:18 +00:00
def _cb ( res ) :
out , err , rc_or_sig = res
self . failUnlessEqual ( rc_or_sig , 1 )
self . failUnless ( " does not look like a node directory " in err )
d . addCallback ( _cb )
2009-01-27 21:32:45 +00:00
def _then_stop_it ( res ) :
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " stop " , " --basedir " , basedir ] , env = os . environ )
d . addCallback ( _then_stop_it )
def _cb2 ( res ) :
out , err , rc_or_sig = res
self . failUnlessEqual ( rc_or_sig , 2 )
self . failUnless ( " does not look like a running node directory " in err )
d . addCallback ( _cb2 )
def _then_start_in_bogus_basedir ( res ) :
not_a_dir = os . path . join ( basedir , " bogus " )
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " start " , " --basedir " , not_a_dir ] , env = os . environ )
d . addCallback ( _then_start_in_bogus_basedir )
def _cb3 ( res ) :
out , err , rc_or_sig = res
self . failUnlessEqual ( rc_or_sig , 1 )
self . failUnless ( " does not look like a directory at all " in err , err )
d . addCallback ( _cb3 )
return d
2007-09-19 08:50:27 +00:00
2008-12-02 00:47:21 +00:00
def test_keygen ( self ) :
2009-02-09 09:34:00 +00:00
self . skip_on_cygwin ( )
2009-01-24 01:34:37 +00:00
if not os . path . exists ( bintahoe ) :
raise unittest . SkipTest ( " The bin/tahoe script isn ' t to be found in the expected location, and I don ' t want to test a ' tahoe ' executable that I find somewhere else, in case it isn ' t the right executable for this version of tahoe. " )
2008-12-02 00:47:21 +00:00
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_keygen " )
c1 = os . path . join ( basedir , " c1 " )
TWISTD_PID_FILE = os . path . join ( c1 , " twistd.pid " )
2009-01-22 22:38:18 +00:00
KEYGEN_FURL_FILE = os . path . join ( c1 , " key_generator.furl " )
2009-01-24 01:34:37 +00:00
d = utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " create-key-generator " , " --basedir " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
def _cb ( res ) :
out , err , rc_or_sig = res
self . failUnlessEqual ( rc_or_sig , 0 )
d . addCallback ( _cb )
2008-12-02 00:47:21 +00:00
def _start ( res ) :
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " start " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
d . addCallback ( _start )
def _cb2 ( res ) :
out , err , rc_or_sig = res
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2008-12-02 00:47:21 +00:00
# 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.
2009-01-22 22:38:18 +00:00
d . addCallback ( _cb2 )
2007-09-17 09:25:31 +00:00
2008-12-02 00:47:21 +00:00
def _node_has_started ( ) :
return os . path . exists ( KEYGEN_FURL_FILE )
d . addCallback ( lambda res : self . poll ( _node_has_started ) )
def _started ( res ) :
self . failUnless ( os . path . exists ( TWISTD_PID_FILE ) )
# rm this so we can detect when the second incarnation is ready
os . unlink ( KEYGEN_FURL_FILE )
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " restart " , c1 ] , env = os . environ )
2008-12-02 00:47:21 +00:00
d . addCallback ( _started )
2009-01-22 22:38:18 +00:00
def _cb3 ( res ) :
out , err , rc_or_sig = res
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2009-01-22 22:38:18 +00:00
d . addCallback ( _cb3 )
2008-12-02 00:47:21 +00:00
# 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 ) :
self . failUnless ( os . path . exists ( TWISTD_PID_FILE ) )
2009-01-24 01:34:37 +00:00
return utils . getProcessOutputAndValue ( bintahoe , args = [ " --quiet " , " stop " , c1 ] , env = os . environ )
2009-01-22 22:38:18 +00:00
d . addCallback ( _stop )
def _cb4 ( res ) :
out , err , rc_or_sig = res
2008-12-02 00:47:21 +00:00
# the parent has exited by now
2009-01-22 22:38:18 +00:00
errstr = " rc= %d , OUT: ' %s ' , ERR: ' %s ' " % ( rc_or_sig , out , err )
self . failUnlessEqual ( rc_or_sig , 0 , errstr )
self . failUnlessEqual ( out , " " , errstr )
2009-01-27 00:30:46 +00:00
# self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise.
2008-12-02 00:47:21 +00:00
# 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 ) )
2009-01-22 22:38:18 +00:00
d . addCallback ( _cb4 )
2008-12-02 00:47:21 +00:00
return d