where the words after ok are features that not all regimes
support. Valid in all states.
- Currently defined features:
+ Currently defined capabilities:
- + revert: the testbed will actually revert when it is closed.
- If this feature is not mentioned then changes to the testbed
- are persistent (so destructive tests should not be performed).
+ + revert
+ The testbed will actually revert when it is closed. If this
+ feature is not mentioned then changes to the testbed are
+ persistent (so destructive tests should not be performed).
- + changed-files: the regime will provide a changed-files file
- (see below).
+ + root-on-testbed
+ Commands specified by `execute' will be run as root on the
+ testbed, and copyup/copydown will have full access to the
+ filesystem. Unless this capability is advertised, root access
+ is not (or may not be) available.
+
+ + suggested-normal-user=<username>
+ The caller is advised that <username> would be a good user to
+ use for running tests (and doing other operations) when root
+ is not required. The advertised account will exist on the
+ testbed already. Several suggested-normal-user= capabilities
+ (with distinct <username>s) may be advertised in which case
+ more than one such user is available.
* Command
* Command
- stop <local-pathname>
+ reset
- Stops the testbed. Replaces local-pathname (on the host) with a
- directory containing a representation of the changes to the
- testbed's filesystem; these changes are undone (if `revert' was
- advertised). Then reverts the testbed. State: Open to Closed.
+ Restores the testbed, undoing all of the changes made so far.
+ State: Open, remains Open. Only available if the `revert'
+ capability is advertised. If possible, the testbed's set of running
+ processes will also be restored to the initial state.
* Command
opts.actions.append(Action(kind, af, arghandling, what))
def finalise_options():
- global opts, testbed
+ global opts, tb
- if opts.user is None and 'root-on-testbed' not in caps:
+ if opts.user is None and 'root-on-testbed' not in tb.caps:
opts.user = ''
if opts.user is None:
su = 'suggested-normal-user='
ul = [
e[length(su):]
- for e in caps
+ for e in tb.caps
if e.startswith(su)
]
- if len(ul) > 1:
- print >>sys.stderr, "warning: virtualisation"
- " system offers several suggested-normal-user"
- " values: "+('/'.join(ul))+", using "+ul[0]
if ul:
opts.user = ul[0]
else:
opts.user = ''
if opts.user:
- if 'root-on-testbed' not in caps:
+ if 'root-on-testbed' not in tb.caps:
print >>sys.stderr, "warning: virtualisation"
" system does not offer root on testbed,"
" but --user option specified: failure likely"
if opts.gainroot is None:
opts.gainroot = ''
if opts.user or
- 'root-on-testbed' not in testbed.caps:
+ 'root-on-testbed' not in tb.caps:
opts.gainroot = 'fakeroot'
if opts.gnupghome.startswith('~/'):
if tb.sp is None: return
tb.command('close')
def prepare(tb):
- if tb.modified and 'reset' in caps:
+ if tb.modified and 'reset' in tb.caps:
tb.command('reset')
tb.blamed = []
tb.modified = False
class Restriction_rw_tests_tree(Restriction): pass
class Restriction_breaks_testbed(Restriction):
- if 'reset' not in caps:
+ if 'reset' not in tb.caps:
raise Unsupported(f.lno,
'Test breaks testbed but testbed cannot reset')
def process_actions():
global binaries
+
+ tb.open()
binaries = Binaries()
b.reset()
downtmp = caller.hook_open()
return [downtmp]
-def cmd_close(c, ce):
- global downtmp
+def cmd_reset(c, ce):
cmdnumargs(c, ce)
- if not downtmp: bomb("`close' when not open")
- cleanup()
-
-def cmd_stop(c, ce):
- global downtmp
- cmdnumargs(c, ce, 1)
- if not downtmp: bomb("`stop' when not open")
- caller.hook_stop()
- cleanup()
+ if not downtmp: bomb("`reset' when not open")
+ if not 'revert' in caller.hook_capabilities():
+ bomb("`reset' when `revert' not advertised")
+ caller.hook_reset()
def down_python_script(gobody, functions=''):
# Many things are made much harder by the inability of
downtmp = vsp.execute('mktemp -t -d', downp=True, outp=True)
return downtmp
-def hook_stop():
- vsp.execute('rm -rf --', c[1:2])
- os.mkdir(c[1])
-
def hook_cleanup():
vsp.execute('rm -rf --', [downtmp], downp=True)
import VirtSubproc as vsp
witholder = None
+downtmp = '/root/adt-downtmp'
def parse_args():
global debuglevel, xlargs, gain_root
else: gain_root = opts.gain_root.split()
vsp.down = gain_root + ['adt-xenlvm-on-testbed'] + xlargs + ['--']
-def hook_open():
- hook_cleanup()
+def do_open():
+ assert(withholder is None)
withholder = subprocess.Popen(
gain_root + ['adt-xenlvm-with-testbed'] + xlargs +
['--','sh','-ec','echo y; exec cat'],
if l != "y\n":
bomb("with-testbed sh gave wrong output `%s', not `l'"
% l.rstrip("\n"))
- downtmp = '/root/adt-downtmp'
- vsp.execute('mkdir %s' % downtmp, downp=True)
- return downtmp
+ vsp.execute('mkdir %s' % downtmp, downp=True)
-def hook_stop():
+def do_close():
withholder.stdin.close()
withholder.stdout.close()
rc = withholder.wait()
withholder = None
- if rc: bomb("with-testbed failed at shutdown, code %d" % rc)
+ if rc: bomb("with-testbed failed when closing/resetting, code %d" % rc)
+
+def hook_open():
+ hook_cleanup()
+ do_open()
+ return downtmp
+
+def hook_reset():
+ do_close()
+ do_open()
def hook_cleanup():
if withholder is not None:
- withholder.stdin.close()
- withholder.stdout.close()
- rc = withholder.wait()
- withholder = None
- if rc: print >>sys.stderr, (
- "with-testbed failed during cleanup, code %d" % rc)
+ do_close()
def hook_capabilities():
return ('revert','root-on-testbed','suggest-normal-user=adtxenu')