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