3 # adt-run <options>... --- <virt-server> [<virt-server-arg>...]
5 # invoke in toplevel of package (not necessarily built)
6 # with package installed
10 # 4 at least one test failed
11 # 8 no tests in this package
12 # 12 erroneous package
14 # 20 other unexpected failures including bad usage
23 from optparse import OptionParser
28 signal.signal(signal.SIGINT, signal.SIG_DFL) # undo stupid Python SIGINT thing
31 def __init__(q,ec,m): q.ec = ec; q.m = m
33 def bomb(m): raise Quit(20, "unexpected error: %s" % m)
34 def badpkg(m): raise Quit(12, "erroneous package: %s" % m)
37 def __init__(p, tb, path, dir=False):
41 if p.tb and p.p[:1] != '/':
42 bomb("path specified as being in testbed but"
43 " not absolute: `%s'" % p.p)
45 if p.dir: return p.p + '/'
47 def append(p, suffix, dir=False):
48 return Path(p.path() + suffix, dir)
50 if p.tb: pfx = '/VIRT'
51 else if p.p[:1] == '/': pfx = '/HOST'
55 if not p.tb: return p.p
57 fixme testbed.command()
61 usage = "%prog <options> -- <virt-server>..."
62 parser = OptionParser(usage=usage)
63 pa = parser.add_option
64 pe = parser.add_option
66 def cb_vserv(op,optstr,value,parser):
67 parser.values.vserver = list(parser.rargs)
70 def cb_path(op,optstr,value,parser, long,tb,dir):
71 name = long.replace('-','_')
72 parser.values.__dict__[name] = Path(tb, value, dir)
74 def pa_path(long, dir, help):
75 def papa_tb(long, ca, pahelp):
76 pa('', long, action='callback', callback=cb_path,
77 nargs=1, type='string', callback_args=ca,
78 help=(help % pahelp), metavar='PATH')
79 papa_tb('--'+long, (long, False, dir), 'host')
80 papa_tb('--'+long+'-tb',(long, True, dir), 'testbed')
82 pa_path('build-tree', True, 'use build tree from PATH on %s')
83 pa_path('control', False, 'read control file PATH on %s')
85 pa('-d', '--debug', action='store_true', dest='debug');
86 pa('','--user', type='string',
87 help='run tests as USER (needs root on testbed)')
89 class SpecialOption(optparse.Option): pass
90 vs_op = SpecialOption('','--VSERVER-DUMMY')
91 vs_op.action = 'callback'
95 vs_op.callback = cb_vserv
96 vs_op.callback_args = ( )
97 vs_op.callback_kwargs = { }
98 vs_op.help = 'introduces virtualisation server and args'
99 vs_op._short_opts = []
100 #vs_op._long_opts = ['--DUMMY']
101 vs_op._long_opts = ['---']
105 (opts,args) = parser.parse_args()
106 if not hasattr(opts,'vserver'):
107 parser.error('you must specifiy --- <virt-server>...')
109 if opts.build_tree is None:
110 opts.build_tree = Path('.', tb=False, dir=True)
111 if opts.control is None:
112 opts.control = opts.build_tree.append('debian/tests/control')
115 def __init__(tb): tb.sp = None
119 tb.sp = subprocess.Popen(opts.vserver,
120 stdin=p, stdout=p, stderr=None)
124 if tb.sp is None: return
125 ec = tb.sp.returncode
132 tb.bomb('testbed gave exit status %d after quit' % ec)
138 if tb.sp is not None:
142 if ec: print >>sys.stderr, ('testbed failing,'
143 ' exit status %d' % ec)
145 raise Quit(16, 'testbed failed: %s' % m)
146 def send(tb, string):
148 print >>tb.sp.stdin, string
152 tb.bomb('cannot send to testbed: %s' %
153 formatexception_only(sys.last_type, sys.last_value))
154 def expect(tb, keyword, nresults=-1):
155 l = tb.sp.stdout.readline()
156 if not l: tb.bomb('unexpected eof from the testbed')
158 if not ll: tb.bomb('unexpected whitespace-only line from the testbed')
160 if tb.lastsend is None:
161 tb.bomb("got banner `%s', expected `%s...'" %
164 tb.bomb("sent `%s', got `%s', expected `%s...'" %
165 (tb.lastsend, l, keyword))
167 if nresults >= 0 and len(ll) != nresults:
168 tb.bomb("sent `%s', got `%s' (%d result parameters),"
169 " expected %d result parameters" %
170 (string, l, len(ll), nresults))
172 def commandr(tb, cmd, nresults, args=()):
173 al = [cmd] + map(urllib.quote, args)
174 tb.send(string.join(cmd))
176 rl = map(urllib.unquote, ll)
178 def command(tb, cmd, args=()):
179 commandr(rb, cmd, 0, args)
182 control = file(hostpath(opts.control), 'r')
185 def print_exception(ei, msgprefix=''):
186 print >>sys.stderr, msgprefix
189 print >>sys.stderr, 'adt-run: ', q.m
192 print >>sys.stderr, "adt-run: unexpected, exceptional, error:"
193 traceback.print_exc()
198 if tmpdir is not None:
199 rm_ec = subprocess.call(['rm','-rf','--',tmpdir])
201 if rm_ec: bomb('rm -rf -- %s failed, code %d' % (tmpdir, ec))
203 print_exception(sys.exc_info(),
204 '\nadt-run: error cleaning up:\n')
210 tmpdir = tempfile.mkdtemp()
215 ec = print_exception(sys.exc_info(), '')