~bladernr/checkbox/1095713-set-pipefail-on-sleep-jobs

« back to all changes in this revision

Viewing changes to hwtest/question.py

  • Committer: Marc Tardif
  • Date: 2007-11-01 17:09:53 UTC
  • mfrom: (44.1.50 bug-152956)
  • Revision ID: marc.tardif@canonical.com-20071101170953-xhwsegkpj90y3f37
Added report dumping and loading functionality to fix bug #152956.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
import types
4
4
import logging
5
5
 
 
6
from StringIO import StringIO
 
7
 
6
8
from hwtest.excluder import Excluder
7
9
from hwtest.iterator import Iterator
8
10
from hwtest.repeater import PreRepeater
17
19
SERVER = 'server'
18
20
ALL_CATEGORIES = [DESKTOP, LAPTOP, SERVER]
19
21
 
 
22
I386 = 'i386'
 
23
AMD64 = 'amd64'
 
24
SPARC = 'sparc'
 
25
ALL_ARCHITECTURES = [I386, AMD64, SPARC]
 
26
 
20
27
 
21
28
class QuestionParser(object):
22
29
 
23
30
    def __init__(self):
24
31
        self.questions = []
25
32
 
26
 
    def load_data(self, **data):
27
 
        if "name" not in data:
 
33
    def _load_properties(self, **properties):
 
34
        if "name" not in properties:
28
35
            raise Exception, \
29
 
                "Question data does not contain a 'name': %s" % data
30
 
 
31
 
        logging.info("Loading question data for: %s", data["name"])
32
 
 
33
 
        if filter(lambda q: q["name"] == data["name"], self.questions):
 
36
                "Question properties does not contain a 'name': %s" % properties
 
37
 
 
38
        logging.info("Loading question properties for: %s", properties["name"])
 
39
 
 
40
        if filter(lambda q: q["name"] == properties["name"], self.questions):
34
41
            raise Exception, \
35
42
                "Question %s already has a question of the same name." \
36
 
                % data["name"]
37
 
 
38
 
        self.questions.append(data)
39
 
 
40
 
    def load_path(self, path):
41
 
        logging.info("Loading question from path: %s", path)
42
 
 
43
 
        fd = file(path, "r")
 
43
                % properties["name"]
 
44
 
 
45
        self.questions.append(properties)
 
46
 
 
47
    def _load_descriptor(self, fd, name):
44
48
        for string in reader(fd):
45
 
            data = {}
46
 
 
47
 
            def save(field, value, extended, path):
 
49
            if not string:
 
50
                break
 
51
 
 
52
            properties = {}
 
53
            properties["suite"] = os.path.basename(name)
 
54
 
 
55
            def _save(field, value, extended, name):
48
56
                if value and extended:
49
57
                    raise Exception, \
50
 
                        "Path %s has both a value and an extended value." % path
 
58
                        "Path %s has both a value and an extended value." % name
51
59
                extended = extended.rstrip("\n")
52
60
                if field:
53
 
                    if data.has_key(field):
 
61
                    if properties.has_key(field):
54
62
                        raise Exception, \
55
63
                            "Path %s has a duplicate field '%s' with a new value '%s'." \
56
 
                            % (path, field, value)
57
 
                    data[field] = value or extended
 
64
                            % (name, field, value)
 
65
                    properties[field] = value or extended
58
66
 
59
67
            string = string.strip("\n")
60
68
            field = value = extended = ''
62
70
                line.strip()
63
71
                match = re.search(r"^([-_.A-Za-z0-9]*):\s?(.*)", line)
64
72
                if match:
65
 
                    save(field, value, extended, path)
 
73
                    _save(field, value, extended, name)
66
74
                    field = match.groups()[0].lower()
67
75
                    value = match.groups()[1].rstrip()
68
76
                    extended = ''
92
100
                    continue
93
101
 
94
102
                raise Exception, "Path %s parse error at: %s" \
95
 
                    % (path, line)
96
 
 
97
 
            save(field, value, extended, path)
98
 
            self.load_data(**data)
 
103
                    % (name, line)
 
104
 
 
105
            _save(field, value, extended, name)
 
106
            self._load_properties(**properties)
 
107
 
 
108
    def load_string(self, str):
 
109
        logging.info("Loading question from string")
 
110
        fd = StringIO(str)
 
111
        self._load_descriptor(fd, "string")
 
112
 
 
113
    def load_path(self, path):
 
114
        logging.info("Loading question from path: %s", path)
 
115
 
 
116
        fd = file(path, "r")
 
117
        self._load_descriptor(fd, path)
99
118
 
100
119
    def load_directory(self, directory):
101
120
        logging.info("Loading questions from directory: %s", directory)
148
167
 
149
168
class Question(object):
150
169
 
151
 
    required_fields = ["name", "description"]
 
170
    required_fields = ["name", "description", "suite"]
152
171
    optional_fields = {
 
172
        "architectures": ALL_ARCHITECTURES,
153
173
        "categories": ALL_CATEGORIES,
154
174
        "depends": [],
155
175
        "command": None,
156
176
        "optional": False}
157
177
 
158
178
    def __init__(self, **kwargs):
159
 
        self.data = kwargs
 
179
        self.properties = kwargs
160
180
        self.answer = None
161
181
        self._validate()
162
182
 
 
183
    def get_properties(self):
 
184
        properties = {}
 
185
        for f in Question.required_fields + Question.optional_fields.keys():
 
186
            properties[f] = self.properties[f]
 
187
        if self.answer:
 
188
            properties['answer'] = self.answer.get_properties()
 
189
        return properties
 
190
 
163
191
    def _validate(self):
164
 
        for field in self.data.keys():
 
192
        # Unknown fields
 
193
        for field in self.properties.keys():
165
194
            if field not in self.required_fields + self.optional_fields.keys():
166
195
                raise Exception, \
167
 
                    "Question data contains unknown field: %s" \
 
196
                    "Question properties contains unknown field: %s" \
168
197
                    % field
169
198
 
 
199
        # Required fields
170
200
        for field in self.required_fields:
171
 
            if not self.data.has_key(field):
 
201
            if not self.properties.has_key(field):
172
202
                raise Exception, \
173
 
                    "Question data does not contain a '%s': %s" \
174
 
                    % (field, data)
175
 
 
 
203
                    "Question properties does not contain a '%s': %s" \
 
204
                    % (field, properties)
 
205
 
 
206
        # Typed fields
 
207
        for field in ["architectures", "categories", "depends"]:
 
208
            if self.properties.has_key(field):
 
209
                self.properties[field] = re.split(r"\s*,\s*", self.properties[field])
 
210
 
 
211
        # Optional fields
176
212
        for field in self.optional_fields.keys():
177
 
            if not self.data.has_key(field):
178
 
                self.data[field] = self.optional_fields[field]
 
213
            if not self.properties.has_key(field):
 
214
                self.properties[field] = self.optional_fields[field]
179
215
 
180
216
    def __str__(self):
181
217
        return self.name
182
218
 
183
219
    def __getattr__(self, attr):
184
 
        if attr in self.data:
185
 
            return self.data[attr]
 
220
        if attr in self.properties:
 
221
            return self.properties[attr]
186
222
 
187
223
        raise AttributeError, attr
188
224