~ubuntu-branches/ubuntu/precise/checkbox/precise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#
# This file is part of Checkbox.
#
# Copyright 2008 Canonical Ltd.
#
# Checkbox is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Checkbox is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
#
import os
import re
import posixpath
import signal

from StringIO import StringIO

from checkbox.lib.path import path_expand_recursive
from checkbox.lib.template_i18n import TemplateI18n

from checkbox.job import Job, PASS
from checkbox.plugin import Plugin


class MessageInfo(Plugin):

    def register(self, manager):
        super(MessageInfo, self).register(manager)

        for (rt, rh) in [
             ("report-messages", self.report_messages),
             ("message-directory", self.message_directory),
             ("message-exec", self.message_exec),
             ("message-file", self.message_file),
             ("message-filename", self.message_filename),
             ("message-result", self.message_result)]:
            self._manager.reactor.call_on(rt, rh)

    def report_messages(self, messages):
        for message in messages:
            self._manager.reactor.fire("report-message", message)

    def message_directory(self, directory, blacklist=[], whitelist=[]):
        whitelist_patterns = [re.compile(r"^%s$" % r) for r in whitelist if r]
        blacklist_patterns = [re.compile(r"^%s$" % r) for r in blacklist if r]

        for filename in path_expand_recursive(directory):
            name = posixpath.basename(filename)
            if name.startswith(".") or name.endswith("~"):
                continue

            if whitelist_patterns:
                if not [name for p in whitelist_patterns if p.match(name)]:
                    continue
            elif blacklist_patterns:
                if [name for p in blacklist_patterns if p.match(name)]:
                    continue

            self._manager.reactor.fire("message-filename", filename)

    def message_exec(self, message):
        if "user" not in message:
            def stop():
                os.kill(0, signal.SIGTERM)

            job = Job(message["command"], message.get("environ"),
                message.get("timeout"))

            # Kill the job if the stop event is fired during execution
            event_id = self._manager.reactor.call_on("stop", stop)
            result = job.execute()
            self._manager.reactor.cancel_call(event_id)

            self._manager.reactor.fire("message-result", *result)

    def message_file(self, file, filename="<stream>"):
        template = TemplateI18n()
        messages = template.load_file(file, filename)
        for message in messages:
            long_ext = "_extended"
            for long_key in message.keys():
                if long_key.endswith(long_ext):
                    short_key = long_key.replace(long_ext, "")
                    message[short_key] = message.pop(long_key)

        if messages:
            self._manager.reactor.fire("report-messages", messages)

    def message_filename(self, filename):
        file = open(filename, "r")
        self._manager.reactor.fire("message-file", file, filename)

    def message_result(self, status, data, duration):
        if status == PASS:
            file = StringIO(data)
            self._manager.reactor.fire("message-file", file)


factory = MessageInfo