mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-19 21:17:54 +00:00
tahoe_fuse: system test: Attempt to create a dirnode to place in <basedir>/private/root_dir.cap, but this fails because the network is too small...
This patch also factors out the "polling_operation" pattern.
This commit is contained in:
parent
1295c1e4ec
commit
1f42953fb4
@ -6,7 +6,8 @@ Note: The API design of the python-fuse library makes unit testing much
|
|||||||
of tahoe-fuse.py tricky business.
|
of tahoe-fuse.py tricky business.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, os, shutil, unittest, subprocess, tempfile, re, time, signal
|
import sys, os, shutil, unittest, subprocess
|
||||||
|
import tempfile, re, time, signal, random, httplib
|
||||||
|
|
||||||
import tahoe_fuse
|
import tahoe_fuse
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ class SystemTest (object):
|
|||||||
self.cliexec = None
|
self.cliexec = None
|
||||||
self.introbase = None
|
self.introbase = None
|
||||||
self.clientbase = None
|
self.clientbase = None
|
||||||
|
self.clientport = None
|
||||||
self.mountpoint = None
|
self.mountpoint = None
|
||||||
|
|
||||||
## Top-level flow control:
|
## Top-level flow control:
|
||||||
@ -138,28 +140,19 @@ class SystemTest (object):
|
|||||||
def configure_client_layer(self):
|
def configure_client_layer(self):
|
||||||
print 'Configuring client.'
|
print 'Configuring client.'
|
||||||
|
|
||||||
|
self.clientport = random.randrange(1024, 2**15)
|
||||||
|
|
||||||
|
f = open(os.path.join(self.clientbase, 'webport'), 'w')
|
||||||
|
f.write('tcp:%d:interface=127.0.0.1\n' % self.clientport)
|
||||||
|
f.close()
|
||||||
|
|
||||||
introfurl = os.path.join(self.introbase, 'introducer.furl')
|
introfurl = os.path.join(self.introbase, 'introducer.furl')
|
||||||
|
|
||||||
# FIXME: Is there a better way to handle this race condition?
|
# FIXME: Is there a better way to handle this race condition?
|
||||||
timeout = 10.0 # Timeout seconds.
|
self.polling_operation(lambda : os.path.isfile(introfurl))
|
||||||
pollinterval = 0.2
|
|
||||||
totalattempts = int(timeout / pollinterval)
|
|
||||||
|
|
||||||
for attempts in range(totalattempts):
|
|
||||||
if os.path.isfile(introfurl):
|
|
||||||
tmpl = '(It took around %.2f seconds before introducer.furl was created.)'
|
|
||||||
print tmpl % ((attempts + 1) * pollinterval,)
|
|
||||||
shutil.copy(introfurl, self.clientbase)
|
shutil.copy(introfurl, self.clientbase)
|
||||||
|
|
||||||
self.launch_client_layer()
|
self.launch_client_layer()
|
||||||
return # skip the timeout failure.
|
|
||||||
|
|
||||||
else:
|
|
||||||
time.sleep(pollinterval)
|
|
||||||
|
|
||||||
tmpl = 'Timeout after waiting for creation of introducer.furl.\n'
|
|
||||||
tmpl += 'Waited %.2f seconds (%d polls).'
|
|
||||||
raise self.SetupFailure(tmpl, timeout, totalattempts)
|
|
||||||
|
|
||||||
def launch_client_layer(self):
|
def launch_client_layer(self):
|
||||||
print 'Launching client.'
|
print 'Launching client.'
|
||||||
@ -170,7 +163,7 @@ class SystemTest (object):
|
|||||||
pat = r'^STARTING (.*?)\nclient node probably started\s*$'
|
pat = r'^STARTING (.*?)\nclient node probably started\s*$'
|
||||||
self.check_tahoe_output(output, pat, self.clientbase)
|
self.check_tahoe_output(output, pat, self.clientbase)
|
||||||
|
|
||||||
self.mount_fuse_layer()
|
self.create_test_dirnode_layer()
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
print 'Stopping client node.'
|
print 'Stopping client node.'
|
||||||
@ -181,6 +174,30 @@ class SystemTest (object):
|
|||||||
print output
|
print output
|
||||||
print 'Ignoring cleanup exception: %r' % (e,)
|
print 'Ignoring cleanup exception: %r' % (e,)
|
||||||
|
|
||||||
|
def create_test_dirnode_layer(self):
|
||||||
|
print 'Creating test dirnode.'
|
||||||
|
targeturl = 'http://127.0.0.1:%d/uri?t=mkdir' % (self.clientport,)
|
||||||
|
|
||||||
|
def make_dirnode():
|
||||||
|
conn = httplib.HTTPConnection('127.0.0.1', self.clientport)
|
||||||
|
conn.request('PUT', '/uri?t=mkdir')
|
||||||
|
resp = conn.getresponse()
|
||||||
|
if resp.status == '200':
|
||||||
|
return resp.read().strip()
|
||||||
|
else:
|
||||||
|
# FIXME: This output can be excessive!
|
||||||
|
print 'HTTP %s reponse while attempting to make node.' % resp.status
|
||||||
|
print resp.read()
|
||||||
|
return False # make another polling attempt...
|
||||||
|
|
||||||
|
cap = self.polling_operation(make_dirnode)
|
||||||
|
|
||||||
|
f = open(os.path.join(self.clientbase, 'private', 'root_dir.cap'), 'w')
|
||||||
|
f.write(cap)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
self.mount_fuse_layer()
|
||||||
|
|
||||||
def mount_fuse_layer(self):
|
def mount_fuse_layer(self):
|
||||||
print 'Mounting fuse interface.'
|
print 'Mounting fuse interface.'
|
||||||
self.mountpoint = tempfile.mkdtemp(prefix='tahoe_fuse_mp_')
|
self.mountpoint = tempfile.mkdtemp(prefix='tahoe_fuse_mp_')
|
||||||
@ -191,7 +208,9 @@ class SystemTest (object):
|
|||||||
try:
|
try:
|
||||||
proc = subprocess.Popen([fusescript, self.mountpoint, '-f'])
|
proc = subprocess.Popen([fusescript, self.mountpoint, '-f'])
|
||||||
# FIXME: Verify the mount somehow?
|
# FIXME: Verify the mount somehow?
|
||||||
# FIXME: Now do tests!
|
|
||||||
|
self.run_test_layer()
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if proc.poll() is None:
|
if proc.poll() is None:
|
||||||
print 'Killing fuse interface.'
|
print 'Killing fuse interface.'
|
||||||
@ -201,6 +220,8 @@ class SystemTest (object):
|
|||||||
finally:
|
finally:
|
||||||
self.cleanup_dir(self.mountpoint)
|
self.cleanup_dir(self.mountpoint)
|
||||||
|
|
||||||
|
def run_test_layer(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
# Utilities:
|
# Utilities:
|
||||||
@ -241,6 +262,45 @@ class SystemTest (object):
|
|||||||
print 'Exception removing test directory: %r' % (path,)
|
print 'Exception removing test directory: %r' % (path,)
|
||||||
print 'Ignoring cleanup exception: %r' % (e,)
|
print 'Ignoring cleanup exception: %r' % (e,)
|
||||||
|
|
||||||
|
def polling_operation(self, operation, timeout = 10.0, pollinterval = 0.2):
|
||||||
|
totaltime = timeout # Fudging for edge-case SetupFailure description...
|
||||||
|
|
||||||
|
totalattempts = int(timeout / pollinterval)
|
||||||
|
|
||||||
|
starttime = time.time()
|
||||||
|
for attempt in range(totalattempts):
|
||||||
|
opstart = time.time()
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = operation()
|
||||||
|
except KeyboardInterrupt, e:
|
||||||
|
raise
|
||||||
|
except Exception, e:
|
||||||
|
result = False
|
||||||
|
|
||||||
|
totaltime = time.time() - starttime
|
||||||
|
|
||||||
|
if result is not False:
|
||||||
|
tmpl = '(Polling for this condition took over %.2f seconds.)'
|
||||||
|
print tmpl % (totaltime,)
|
||||||
|
return result
|
||||||
|
|
||||||
|
elif totaltime > timeout:
|
||||||
|
break
|
||||||
|
|
||||||
|
else:
|
||||||
|
opdelay = time.time() - opstart
|
||||||
|
realinterval = max(0., pollinterval - opdelay)
|
||||||
|
|
||||||
|
#tmpl = '(Poll attempt %d failed after %.2f seconds, sleeping %.2f seconds.)'
|
||||||
|
#print tmpl % (attempt+1, opdelay, realinterval)
|
||||||
|
time.sleep(realinterval)
|
||||||
|
|
||||||
|
tmpl = 'Timeout after waiting for creation of introducer.furl.\n'
|
||||||
|
tmpl += 'Waited %.2f seconds (%d polls).'
|
||||||
|
raise self.SetupFailure(tmpl, totaltime, attempt+1)
|
||||||
|
|
||||||
|
|
||||||
# SystemTest Exceptions:
|
# SystemTest Exceptions:
|
||||||
class Failure (Exception):
|
class Failure (Exception):
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user