virt.virt_test_utils: run_autotest - 'tar' needs relative paths to strip the leading '/'
[autotest-zwu.git] / client / common_lib / control_data.py
blobdcc49cd62d4a7ebe3105c877893c0dc5e05bbd56
2 # Copyright 2008 Google Inc. Released under the GPL v2
4 import compiler, textwrap, types
7 REQUIRED_VARS = set(['author', 'doc', 'name', 'time', 'test_class',
8 'test_category', 'test_type'])
10 class ControlVariableException(Exception):
11 pass
14 class ControlData(object):
15 def __init__(self, vars, path, raise_warnings=False):
16 # Defaults
17 self.path = path
18 self.dependencies = set()
19 self.experimental = False
20 self.run_verify = True
21 self.sync_count = 1
22 self.test_parameters = set()
24 diff = REQUIRED_VARS - set(vars)
25 if len(diff) > 0:
26 warning = ("WARNING: Not all required control "
27 "variables were specified in %s. Please define "
28 "%s.") % (self.path, ', '.join(diff))
29 if raise_warnings:
30 raise ControlVariableException(warning)
31 print textwrap.wrap(warning, 80)
33 for key, val in vars.iteritems():
34 try:
35 self.set_attr(key, val, raise_warnings)
36 except Exception, e:
37 if raise_warnings:
38 raise
39 print "WARNING: %s; skipping" % e
42 def set_attr(self, attr, val, raise_warnings=False):
43 attr = attr.lower()
44 try:
45 set_fn = getattr(self, 'set_%s' % attr)
46 set_fn(val)
47 except AttributeError:
48 # This must not be a variable we care about
49 pass
52 def _set_string(self, attr, val):
53 val = str(val)
54 setattr(self, attr, val)
57 def _set_option(self, attr, val, options):
58 val = str(val)
59 if val.lower() not in [x.lower() for x in options]:
60 raise ValueError("%s must be one of the following "
61 "options: %s" % (attr,
62 ', '.join(options)))
63 setattr(self, attr, val)
66 def _set_bool(self, attr, val):
67 val = str(val).lower()
68 if val == "false":
69 val = False
70 elif val == "true":
71 val = True
72 else:
73 msg = "%s must be either true or false" % attr
74 raise ValueError(msg)
75 setattr(self, attr, val)
78 def _set_int(self, attr, val, min=None, max=None):
79 val = int(val)
80 if min is not None and min > val:
81 raise ValueError("%s is %d, which is below the "
82 "minimum of %d" % (attr, val, min))
83 if max is not None and max < val:
84 raise ValueError("%s is %d, which is above the "
85 "maximum of %d" % (attr, val, max))
86 setattr(self, attr, val)
89 def _set_set(self, attr, val):
90 val = str(val)
91 items = [x.strip() for x in val.split(',')]
92 setattr(self, attr, set(items))
95 def set_author(self, val):
96 self._set_string('author', val)
99 def set_dependencies(self, val):
100 self._set_set('dependencies', val)
103 def set_doc(self, val):
104 self._set_string('doc', val)
107 def set_experimental(self, val):
108 self._set_bool('experimental', val)
111 def set_name(self, val):
112 self._set_string('name', val)
115 def set_run_verify(self, val):
116 self._set_bool('run_verify', val)
119 def set_sync_count(self, val):
120 self._set_int('sync_count', val, min=1)
123 def set_time(self, val):
124 self._set_option('time', val, ['short', 'medium', 'long'])
127 def set_test_class(self, val):
128 self._set_string('test_class', val.lower())
131 def set_test_category(self, val):
132 self._set_string('test_category', val.lower())
135 def set_test_type(self, val):
136 self._set_option('test_type', val, ['client', 'server'])
139 def set_test_parameters(self, val):
140 self._set_set('test_parameters', val)
143 def _extract_const(n):
144 assert(n.__class__ == compiler.ast.Assign)
145 assert(n.expr.__class__ == compiler.ast.Const)
146 assert(n.expr.value.__class__ in (str, int, float, unicode))
147 assert(n.nodes.__class__ == list)
148 assert(len(n.nodes) == 1)
149 assert(n.nodes[0].__class__ == compiler.ast.AssName)
150 assert(n.nodes[0].flags.__class__ == str)
151 assert(n.nodes[0].name.__class__ == str)
153 key = n.nodes[0].name.lower()
154 val = str(n.expr.value).strip()
156 return (key, val)
159 def _extract_name(n):
160 assert(n.__class__ == compiler.ast.Assign)
161 assert(n.expr.__class__ == compiler.ast.Name)
162 assert(n.nodes.__class__ == list)
163 assert(len(n.nodes) == 1)
164 assert(n.nodes[0].__class__ == compiler.ast.AssName)
165 assert(n.nodes[0].flags.__class__ == str)
166 assert(n.nodes[0].name.__class__ == str)
167 assert(n.expr.name in ('False', 'True', 'None'))
169 key = n.nodes[0].name.lower()
170 val = str(n.expr.name)
172 return (key, val)
175 def parse_control(path, raise_warnings=False):
176 try:
177 mod = compiler.parseFile(path)
178 except SyntaxError, e:
179 raise ControlVariableException("Error parsing %s because %s" %
180 (path, e))
182 assert(mod.__class__ == compiler.ast.Module)
183 assert(mod.node.__class__ == compiler.ast.Stmt)
184 assert(mod.node.nodes.__class__ == list)
186 vars = {}
187 for n in mod.node.nodes:
188 for fn in (_extract_const, _extract_name):
189 try:
190 key, val = fn(n)
192 vars[key] = val
193 except AssertionError, e:
194 pass
196 return ControlData(vars, path, raise_warnings)