control_data.py revision 99c2c6f54e962fe4e7701cd9aaa645fdabacd203
14f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta#!/usr/bin/python
2b38bc68b9edf385f2576a6cbf304187721f562c1Jeenu Viswambharan#
34f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta# Copyright 2008 Google Inc. Released under the GPL v2
44f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
54f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Guptaimport compiler, textwrap, types
64f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
74f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
84f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin GuptaREQUIRED_VARS = set(['author', 'doc', 'name', 'time', 'test_class',
94f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta                     'test_category', 'test_type'])
104f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
114f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Guptaclass ControlVariableException(Exception):
124f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta    pass
134f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
144f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
154f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Guptaclass ControlData(object):
164f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta    def __init__(self, vars, raise_warnings=False):
174f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        # Defaults
184f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        self.dependencies = set()
194f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        self.experimental = False
204f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        self.run_verify = True
214f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        self.sync_count = 1
224f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
234f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        diff = REQUIRED_VARS - set(vars)
244f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        if len(diff) > 0:
254f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            warning = ("WARNING: Not all required control "
264f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta                       "variables were specified.  Please define "
274f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta                       "%s.") % ', '.join(diff)
284f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            if raise_warnings:
294f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta                raise ControlVariableException(warning)
30e2bf57f84109f32da5a5bdbfa430d2b81a7fff02Dan Handley            print textwrap.wrap(warning, 80)
31e2bf57f84109f32da5a5bdbfa430d2b81a7fff02Dan Handley
324f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        for key, val in vars.iteritems():
3397043ac98e13a726dbf8b3b41654dca759e3da2cDan Handley            try:
34738b1fd7c0628e9c6cc89e36629f27bde01559dfSoby Mathew                self.set_attr(key, val, raise_warnings)
35b38bc68b9edf385f2576a6cbf304187721f562c1Jeenu Viswambharan            except Exception, e:
3697043ac98e13a726dbf8b3b41654dca759e3da2cDan Handley                if raise_warnings:
3797043ac98e13a726dbf8b3b41654dca759e3da2cDan Handley                    raise
384f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta                print "WARNING: %s; skipping" % e
394f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
404f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
414f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta    def set_attr(self, attr, val, raise_warnings=False):
424f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        attr = attr.lower()
434f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        try:
444f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            set_fn = getattr(self, 'set_%s' % attr)
454f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            set_fn(val)
464f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        except AttributeError:
474f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            # This must not be a variable we care about
484f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            pass
4907f4e078b6871e5c74f6cb38f2726a2cfcb2b746Achin Gupta
504f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
5107f4e078b6871e5c74f6cb38f2726a2cfcb2b746Achin Gupta    def _set_string(self, attr, val):
5207f4e078b6871e5c74f6cb38f2726a2cfcb2b746Achin Gupta        val = str(val)
534f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        setattr(self, attr, val)
544f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
554f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
564f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta    def _set_option(self, attr, val, options):
5707f4e078b6871e5c74f6cb38f2726a2cfcb2b746Achin Gupta        val = str(val)
5807f4e078b6871e5c74f6cb38f2726a2cfcb2b746Achin Gupta        if val.lower() not in [x.lower() for x in options]:
5907f4e078b6871e5c74f6cb38f2726a2cfcb2b746Achin Gupta            raise ValueError("%s must be one of the following "
6007f4e078b6871e5c74f6cb38f2726a2cfcb2b746Achin Gupta                             "options: %s" % (attr,
614f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta                             ', '.join(options)))
624f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        setattr(self, attr, val)
634f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
644f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
657935d0a59d439c993b79814ab414d37e4a90d9a6Andrew Thoelke    def _set_bool(self, attr, val):
664f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        val = str(val).lower()
674f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        if val == "false":
684f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            val = False
694f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta        elif val == "true":
704f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta            val = True
71e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        else:
72e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux            msg = "%s must be either true or false" % attr
73e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux            raise ValueError(msg)
7479627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux        setattr(self, attr, val)
7579627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux
7679627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux
77e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux    def _set_int(self, attr, val, min=None, max=None):
78e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        val = int(val)
79e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        if min is not None and min > val:
8079627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux            raise ValueError("%s is %d, which is below the "
81e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux                             "minimum of %d" % (attr, val, min))
82e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        if max is not None and max < val:
83e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux            raise ValueError("%s is %d, which is above the "
84e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux                             "maximum of %d" % (attr, val, max))
85e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        setattr(self, attr, val)
86e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux
8779627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux
8879627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux    def _set_set(self, attr, val):
8979627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux        val = str(val)
90e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        items = [x.strip() for x in val.split(',')]
91e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        setattr(self, attr, set(items))
92e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux
9379627dc37259781e578c47e1e63856dd0424b2a2Sandrine Bailleux
94e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux    def set_author(self, val):
95e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux        self._set_string('author', val)
964f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a5Achin Gupta
97a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan
98e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux    def set_dependencies(self, val):
99a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan        self._set_set('dependencies', val)
100e0ae9fab61263bf7ec5beaa8256c573f09c744f0Sandrine Bailleux
101a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan
102a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan    def set_doc(self, val):
103a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan        self._set_string('doc', val)
104a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan
105a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan
106a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan    def set_experimental(self, val):
107a7934d69508872919787742c7680b68807c24361Jeenu Viswambharan        self._set_bool('experimental', val)
1082bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
109674878464a93bb6d6bf6cb746fc4b9dba6e101acSoby Mathew
1102bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    def set_name(self, val):
1112bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke        self._set_string('name', val)
1122bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1132bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1142bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    def set_run_verify(self, val):
1152bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke        self._set_bool('run_verify', val)
1162bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1172bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1182bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    def set_sync_count(self, val):
1192bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke        self._set_int('sync_count', val, min=1)
1202bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1212bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1222bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    def set_time(self, val):
1232bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke        self._set_option('time', val, ['short', 'medium', 'long'])
124674878464a93bb6d6bf6cb746fc4b9dba6e101acSoby Mathew
1252bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1262bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    def set_test_class(self, val):
12712d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew        self._set_string('test_class', val.lower())
12812d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew
12912d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew
13012d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew    def set_test_category(self, val):
13112d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew        self._set_string('test_category', val.lower())
13212d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew
13312d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew
13412d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew    def set_test_type(self, val):
13512d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew        self._set_option('test_type', val, ['client', 'server'])
13612d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew
13712d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew
13812d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathewdef parse_control(path, raise_warnings=False):
13912d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew    mod = compiler.parseFile(path)
14012d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56Soby Mathew
1412bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    assert(mod.__class__ == compiler.ast.Module)
1422bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    assert(mod.node.__class__ == compiler.ast.Stmt)
1432bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    assert(mod.node.nodes.__class__ == list)
1442bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke
1452bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    vars = {}
1462bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke    for n in mod.node.nodes:
1472bf28e620a6f05700753a2b45a888c6623e20723Andrew Thoelke        try:
148c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(n.__class__ == compiler.ast.Assign)
149c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(n.expr.__class__ == compiler.ast.Const)
150c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(n.expr.value.__class__ == str)
151c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(n.nodes.__class__ == list)
152c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(len(n.nodes) == 1)
153c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(n.nodes[0].__class__ == compiler.ast.AssName)
154c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(n.nodes[0].flags.__class__ == str)
155c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            assert(n.nodes[0].name.__class__ == str)
156c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew
157c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            key = n.nodes[0].name.lower()
158c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            val = n.expr.value
159c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew
160c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            vars[key] = val.strip()
161c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew        except AssertionError:
162c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew            pass
163c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew
164c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew    return ControlData(vars, raise_warnings)
165c67b09bd2cf04cac2160968907f0a9fc65472a11Soby Mathew