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 os
     10 import signal
     11 import unittest
     12 
     13 import mox
     14 import mock
     15 
     16 import common
     17 from autotest_lib.client.common_lib import base_job, error
     18 from autotest_lib.server.cros import provision
     19 from autotest_lib.server.cros.dynamic_suite import dynamic_suite
     20 from autotest_lib.server.cros.dynamic_suite.suite import Suite
     21 
     22 
     23 class 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                        '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.check_hosts, self._DARGS['check_hosts'])
     95         self.assertEquals(spec.add_experimental,
     96                           self._DARGS['add_experimental'])
     97         self.assertEquals(spec.suite_dependencies,
     98                           self._DARGS['suite_dependencies'])
     99 
    100 
    101     def testDefaultOptionalReimageAndRunArgs(self):
    102         """Should verify that optional args get defaults."""
    103         del(self._DARGS['pool'])
    104         del(self._DARGS['check_hosts'])
    105         del(self._DARGS['add_experimental'])
    106         del(self._DARGS['suite_dependencies'])
    107 
    108         spec = dynamic_suite._SuiteSpec(**self._DARGS)
    109         self.assertEquals(spec.pool, None)
    110         self.assertEquals(spec.check_hosts, True)
    111         self.assertEquals(spec.add_experimental, True)
    112         self.assertEquals(
    113                 spec.suite_dependencies,
    114                 ['cros-version:build_1', 'fwrw-version:fwrw_build_1'])
    115 
    116 
    117     def testReimageAndSIGTERM(self):
    118         """Should reimage_and_run that causes a SIGTERM and fails cleanly."""
    119         def suicide(*_, **__):
    120             """Send SIGTERM to current process to exit.
    121 
    122             @param _: Ignored.
    123             @param __: Ignored.
    124             """
    125             os.kill(os.getpid(), signal.SIGTERM)
    126 
    127         # Mox doesn't play well with SIGTERM, but it does play well with
    128         # with exceptions, so here we're using an exception to simulate
    129         # execution being interrupted by a signal.
    130         class UnhandledSIGTERM(Exception):
    131             """Exception to be raised when SIGTERM is received."""
    132             pass
    133 
    134         def handler(signal_number, frame):
    135             """Handler for receiving a signal.
    136 
    137             @param signal_number: signal number.
    138             @param frame: stack frame object.
    139             """
    140             raise UnhandledSIGTERM()
    141 
    142         signal.signal(signal.SIGTERM, handler)
    143         spec = mock.MagicMock()
    144         spec.builds = self._BUILDS
    145         spec.test_source_build = Suite.get_test_source_build(self._BUILDS)
    146         spec.devserver.stage_artifacts.side_effect = suicide
    147         spec.run_prod_code = False
    148 
    149         self.assertRaises(UnhandledSIGTERM,
    150                           dynamic_suite._perform_reimage_and_run,
    151                           spec, None, None, None)
    152 
    153 
    154 if __name__ == '__main__':
    155     unittest.main()
    156