summaryrefslogtreecommitdiff
path: root/lava_dispatcher/actions/lava_test.py
blob: e4405e4e3bed20cf46ab082a605db3497f13dd74 (plain)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/usr/bin/python

# Copyright (C) 2011-2012 Linaro Limited
#
# Author: Paul Larson <paul.larson@linaro.org>
#
# This file is part of LAVA Dispatcher.
#
# LAVA Dispatcher 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 2 of the License, or
# (at your option) any later version.
#
# LAVA Dispatcher 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 this program; if not, see <http://www.gnu.org/licenses>.

import logging

from lava_dispatcher.actions import BaseAction
from lava_dispatcher.errors import OperationFailed
from lava_dispatcher.utils import generate_bundle_file_name


def _install_lava_test(client, session):
    # install bazaar in tester image
    session.run('%s update' % client.aptget_cmd)
    # Install necessary packages for build lava-test
    cmd = ('%s -y --force-yes install '
           'bzr usbutils python-apt python-setuptools '
           'python-simplejson lsb-release python-keyring '
           'python-pip' % client.aptget_cmd)
    session.run(cmd, timeout=2400)

    dispatcher_config = client.context.config

    lava_test_deb = dispatcher_config.lava_test_deb
    if lava_test_deb:
        logging.debug("Installing %s with apt-get" % lava_test_deb)
        session.run("%s -y --force-yes install %s" %
                    (client.aptget_cmd, lava_test_deb))
    else:
        lava_test_url = dispatcher_config.lava_test_url
        logging.debug("Installing %s with pip" % lava_test_url)
        session.run('pip install -e ' + lava_test_url)

    # Test if lava-test installed
    session.run('which lava-test', timeout=60)

    # cleanup the lava-test - old results, cached files...
    session.run('lava-test reset', timeout=60)


class cmd_lava_test_run(BaseAction):

    parameters_schema = {
        'type': 'object',
        'properties': {
            'test_name': {'type': 'string'},
            'test_options': {'type': 'string', 'optional': True},
            'role': {'type': 'string', 'optional': True},
            'timeout': {'type': 'integer', 'optional': True},
        },
        'additionalProperties': False,
    }

    def test_name(self, test_name, test_options="", timeout=-1):
        return super(cmd_lava_test_run, self).test_name() + ' (%s)' % test_name

    def run(self, test_name, test_options="", timeout=-1):
        self.context.any_device_bundles = True
        logging.info("Executing lava_test_run %s command" % test_name)
        with self.client.tester_session() as session:
            session.run('mkdir -p %s' % self.context.config.lava_result_dir)
            session.export_display()
            bundle_name = generate_bundle_file_name(test_name)
            if test_options != "":
                test_options = "-t '%s'" % test_options

            cmd = ('lava-test run %s %s -o %s/%s.bundle' %
                   (test_name, test_options,
                    self.context.config.lava_result_dir, bundle_name))
            try:
                rc = session.run(cmd, timeout=timeout)
            except KeyboardInterrupt:
                raise KeyboardInterrupt
            except:
                logging.exception("session.run failed")
                self.client.proc.sendcontrol('c')
                try:
                    session.run('true', timeout=20)
                except KeyboardInterrupt:
                    raise KeyboardInterrupt
                except:
                    logging.exception("killing test failed, rebooting")
                    self.client.boot_linaro_image()
                raise
            finally:
                # try to make sure the test bundle is safely written to disk
                session.run('sync', timeout=60)

            if rc is None:
                raise OperationFailed("test case getting return value failed")
            elif rc != 0:
                raise OperationFailed(
                    "test case failed with return value: %s" % rc)


class cmd_lava_test_install(BaseAction):
    """
    lava-test deployment to test image rootfs by chroot
    """

    parameters_schema = {
        'type': 'object',
        'properties': {
            'tests': {'type': 'array', 'items': {'type': 'string'}},
            'install_python': {
                'type': 'array', 'items': {'type': 'string'}, 'optional': True
            },
            'install_deb': {
                'type': 'array', 'items': {'type': 'string'}, 'optional': True
            },
            'register': {
                'type': 'array', 'items': {'type': 'string'}, 'optional': True
            },
            'timeout': {'type': 'integer', 'optional': True},
            'role': {'type': 'string', 'optional': True},
            'install_lava_test': {'type': 'boolean', 'optional': True, 'default': True}
        },
        'additionalProperties': False,
    }

    def run_command_with_test_result(self, session, command, test_result_name, timeout):
        try:
            session.run(command, timeout=timeout)
        except OperationFailed as e:
            logging.error("running %r failed" % command)
            self.context.test_data.add_result(test_result_name, 'fail', str(e))
        else:
            self.context.test_data.add_result(test_result_name, 'pass')

    def run(self, tests, install_python=None, install_deb=None, register=None,
            timeout=2400, install_lava_test=True):
        logging.info(
            "Executing lava_test_install (%s) command" % ",".join(tests))

        with self.client.reliable_session() as session:

            lava_proxy = self.context.config.lava_proxy
            if lava_proxy:
                session.run("sh -c 'export http_proxy=%s'" % lava_proxy)

            if install_lava_test:
                _install_lava_test(self.client, session)

            if install_python:
                for module in install_python:
                    self.run_command_with_test_result(
                        session, "pip install -e " + module,
                        'lava_test_install python (%s)' % module, timeout=60)

            if install_deb:
                debs = " ".join(install_deb)
                self.run_command_with_test_result(
                    session, "%s -y --force-yes install %s"
                    % (self.client.aptget_cmd, debs),
                    'lava_test_install deb (%s)' % debs, timeout=timeout)

            if register:
                for test_def_url in register:
                    self.run_command_with_test_result(
                        session, 'lava-test register-test  ' + test_def_url,
                        'lava_test_install register (%s)' % test_def_url, timeout=60)

            for test in tests:
                self.run_command_with_test_result(
                    session, 'lava-test install %s' % test,
                    'lava_test_install (%s)' % test, timeout=timeout)

            session.run('rm -rf lava-test', timeout=60)


class cmd_add_apt_repository(BaseAction):
    """
    add apt repository to test image rootfs by chroot
    arg could be 'deb uri distribution [component1] [component2][...]'
    """

    parameters_schema = {
        'type': 'object',
        'properties': {
            'arg': {
                'type': 'array',
                'items': {'type': 'string'},
            }
        },
        'additionalProperties': False,
    }

    def run(self, arg):
        with self.client.reliable_session() as session:
            # add apt repository
            for repository in arg:
                session.run("echo '%s' >> /etc/apt/sources.list.d/test_repo.list"
                            % repository)
            session.run('%s update' % self.client.aptget_cmd)