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 '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 154if __name__ == '__main__': 155 unittest.main() 156