• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2#
3# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Unit tests for server/cros/dynamic_suite/dynamic_suite.py."""
8
9import os
10import signal
11import unittest
12
13import mox
14import mock
15
16import common
17from autotest_lib.client.common_lib import base_job, error
18from autotest_lib.server.cros import provision
19from autotest_lib.server.cros.dynamic_suite import dynamic_suite
20from autotest_lib.server.cros.dynamic_suite.suite import Suite
21
22
23class DynamicSuiteTest(mox.MoxTestBase):
24    """Unit tests for dynamic_suite module methods.
25
26    @var _DARGS: default args to vet.
27    """
28
29    _DEVSERVER_HOST = 'http://devserver1'
30    _BUILDS = {provision.CROS_VERSION_PREFIX: 'build_1',
31               provision.FW_RW_VERSION_PREFIX:'fwrw_build_1'}
32
33    def setUp(self):
34
35        super(DynamicSuiteTest, self).setUp()
36        self._DARGS = {'name': 'name',
37                       'builds': self._BUILDS,
38                       'board': 'board',
39                       'job': self.mox.CreateMock(base_job.base_job),
40                       'num': 1,
41                       'pool': 'pool',
42                       'check_hosts': False,
43                       'add_experimental': False,
44                       'suite_dependencies': ['test_dep'],
45                       'devserver_url': self._DEVSERVER_HOST}
46
47
48
49    def testVetRequiredReimageAndRunArgs(self):
50        """Should verify only that required args are present and correct."""
51        spec = dynamic_suite._SuiteSpec(**self._DARGS)
52        self.assertEquals(spec.builds, self._DARGS['builds'])
53        self.assertEquals(spec.board, 'board:' + self._DARGS['board'])
54        self.assertEquals(spec.name, self._DARGS['name'])
55        self.assertEquals(spec.job, self._DARGS['job'])
56
57
58    def testVetReimageAndRunBuildArgFail(self):
59        """Should fail verification if both |builds| and |build| are not set.
60        """
61        self._DARGS['builds'] = None
62        self.assertRaises(error.SuiteArgumentException,
63                          dynamic_suite._SuiteSpec,
64                          **self._DARGS)
65
66
67    def testVetReimageAndRunBoardArgFail(self):
68        """Should fail verification because |board| arg is bad."""
69        self._DARGS['board'] = None
70        self.assertRaises(error.SuiteArgumentException,
71                          dynamic_suite._SuiteSpec,
72                          **self._DARGS)
73
74
75    def testVetReimageAndRunNameArgFail(self):
76        """Should fail verification because |name| arg is bad."""
77        self._DARGS['name'] = None
78        self.assertRaises(error.SuiteArgumentException,
79                          dynamic_suite._SuiteSpec,
80                          **self._DARGS)
81
82
83    def testVetReimageAndRunJobArgFail(self):
84        """Should fail verification because |job| arg is bad."""
85        self._DARGS['job'] = None
86        self.assertRaises(error.SuiteArgumentException,
87                          dynamic_suite._SuiteSpec,
88                          **self._DARGS)
89
90
91    def testOverrideOptionalReimageAndRunArgs(self):
92        """Should verify that optional args can be overridden."""
93        spec = dynamic_suite._SuiteSpec(**self._DARGS)
94        self.assertEquals(spec.pool, 'pool:' + self._DARGS['pool'])
95        self.assertEquals(spec.num, self._DARGS['num'])
96        self.assertEquals(spec.check_hosts, self._DARGS['check_hosts'])
97        self.assertEquals(spec.add_experimental,
98                          self._DARGS['add_experimental'])
99        self.assertEquals(spec.suite_dependencies,
100                          self._DARGS['suite_dependencies'])
101
102
103    def testDefaultOptionalReimageAndRunArgs(self):
104        """Should verify that optional args get defaults."""
105        del(self._DARGS['pool'])
106        del(self._DARGS['check_hosts'])
107        del(self._DARGS['add_experimental'])
108        del(self._DARGS['num'])
109        del(self._DARGS['suite_dependencies'])
110
111        spec = dynamic_suite._SuiteSpec(**self._DARGS)
112        self.assertEquals(spec.pool, None)
113        self.assertEquals(spec.num, None)
114        self.assertEquals(spec.check_hosts, True)
115        self.assertEquals(spec.add_experimental, True)
116        self.assertEquals(
117                spec.suite_dependencies,
118                ['cros-version:build_1', 'fwrw-version:fwrw_build_1'])
119
120
121    def testReimageAndSIGTERM(self):
122        """Should reimage_and_run that causes a SIGTERM and fails cleanly."""
123        def suicide(*_, **__):
124            """Send SIGTERM to current process to exit.
125
126            @param _: Ignored.
127            @param __: Ignored.
128            """
129            os.kill(os.getpid(), signal.SIGTERM)
130
131        # Mox doesn't play well with SIGTERM, but it does play well with
132        # with exceptions, so here we're using an exception to simulate
133        # execution being interrupted by a signal.
134        class UnhandledSIGTERM(Exception):
135            """Exception to be raised when SIGTERM is received."""
136            pass
137
138        def handler(signal_number, frame):
139            """Handler for receiving a signal.
140
141            @param signal_number: signal number.
142            @param frame: stack frame object.
143            """
144            raise UnhandledSIGTERM()
145
146        signal.signal(signal.SIGTERM, handler)
147        spec = mock.MagicMock()
148        spec.builds = self._BUILDS
149        spec.test_source_build = Suite.get_test_source_build(self._BUILDS)
150        spec.devserver.stage_artifacts.side_effect = suicide
151        spec.run_prod_code = False
152
153        self.assertRaises(UnhandledSIGTERM,
154                          dynamic_suite._perform_reimage_and_run,
155                          spec, None, None, None)
156
157
158if __name__ == '__main__':
159    unittest.main()
160