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
self.cliexec = None
self.introbase = None
self.clientbase = None
+ self.clientport = None
self.mountpoint = None
## Top-level flow control:
def configure_client_layer(self):
print 'Configuring client.'
- introfurl = os.path.join(self.introbase, 'introducer.furl')
-
- # FIXME: Is there a better way to handle this race condition?
- timeout = 10.0 # Timeout seconds.
- pollinterval = 0.2
- totalattempts = int(timeout / pollinterval)
+ self.clientport = random.randrange(1024, 2**15)
- 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)
+ f = open(os.path.join(self.clientbase, 'webport'), 'w')
+ f.write('tcp:%d:interface=127.0.0.1\n' % self.clientport)
+ f.close()
- self.launch_client_layer()
- return # skip the timeout failure.
+ introfurl = os.path.join(self.introbase, 'introducer.furl')
- else:
- time.sleep(pollinterval)
+ # FIXME: Is there a better way to handle this race condition?
+ self.polling_operation(lambda : os.path.isfile(introfurl))
+ shutil.copy(introfurl, self.clientbase)
- tmpl = 'Timeout after waiting for creation of introducer.furl.\n'
- tmpl += 'Waited %.2f seconds (%d polls).'
- raise self.SetupFailure(tmpl, timeout, totalattempts)
+ self.launch_client_layer()
def launch_client_layer(self):
print 'Launching client.'
pat = r'^STARTING (.*?)\nclient node probably started\s*$'
self.check_tahoe_output(output, pat, self.clientbase)
- self.mount_fuse_layer()
+ self.create_test_dirnode_layer()
finally:
print 'Stopping client node.'
print output
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):
print 'Mounting fuse interface.'
self.mountpoint = tempfile.mkdtemp(prefix='tahoe_fuse_mp_')
try:
proc = subprocess.Popen([fusescript, self.mountpoint, '-f'])
# FIXME: Verify the mount somehow?
- # FIXME: Now do tests!
+
+ self.run_test_layer()
+
finally:
if proc.poll() is None:
print 'Killing fuse interface.'
finally:
self.cleanup_dir(self.mountpoint)
+ def run_test_layer(self):
+ raise NotImplementedError()
# Utilities:
print 'Exception removing test directory: %r' % (path,)
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:
class Failure (Exception):
pass