1 #!/usr/bin/python 2 # 3 # Copyright (c) 2013 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 #!/usr/bin/python 8 # 9 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 10 # Use of this source code is governed by a BSD-style license that can be 11 # found in the LICENSE file. 12 13 import datetime, unittest 14 15 import mox 16 17 import common 18 # This must come before the import of complete_failures in order to use the 19 # in memory database. 20 from autotest_lib.frontend import setup_django_readonly_environment 21 from autotest_lib.frontend import setup_test_environment 22 import complete_failures 23 from autotest_lib.client.common_lib import mail 24 from autotest_lib.frontend.tko import models 25 from django import test 26 27 28 GOOD_STATUS_IDX = 6 29 FAIL_STATUS_IDX = 4 30 31 ERROR_STATUS = models.Status(status_idx=2, word='ERROR') 32 ABORT_STATUS = models.Status(status_idx=3, word='ABORT') 33 FAIL_STATUS = models.Status(status_idx=4, word='FAIL') 34 WARN_STATUS = models.Status(status_idx=5, word='WARN') 35 GOOD_STATUS = models.Status(status_idx=6, word='GOOD') 36 ALERT_STATUS = models.Status(status_idx=7, word='ALERT') 37 38 39 def add_statuses(): 40 """ 41 Save the statuses to the in-memory database. 42 43 These normally exist in the database and the code expects them. However, the 44 normal test database setup does not do this for us. 45 """ 46 ERROR_STATUS.save() 47 ABORT_STATUS.save() 48 FAIL_STATUS.save() 49 WARN_STATUS.save() 50 GOOD_STATUS.save() 51 ALERT_STATUS.save() 52 53 54 # During the tests there is a point where Django does a type check on 55 # datetime.datetime. Unfortunately this means when datetime is mocked out, 56 # horrible failures happen when Django tries to do this check. The solution 57 # chosen is to create a pure Python class that inheirits from datetime.datetime 58 # so that the today class method can be directly mocked out. It is necesarry 59 # to mock out datetime.datetime completely as it a C class and so cannot have 60 # parts of itself mocked out. 61 class MockDatetime(datetime.datetime): 62 """Used to mock out parts of datetime.datetime.""" 63 pass 64 65 66 class CompleteFailuresFunctionalTests(mox.MoxTestBase, test.TestCase): 67 """ 68 Does a functional test of the complete_failures script. 69 70 This uses an in-memory database but everything else is a full run. 71 72 """ 73 74 def setUp(self): 75 super(CompleteFailuresFunctionalTests, self).setUp() 76 setup_test_environment.set_up() 77 add_statuses() 78 # All of our tests will involve mocking out the datetime.today() class 79 # method. 80 self.mox.StubOutWithMock(MockDatetime, 'today') 81 self.datetime = datetime.datetime 82 datetime.datetime = MockDatetime 83 # We need to mock out the send function in all tests or else the 84 # emails will be sent out during tests. 85 self.mox.StubOutWithMock(mail, 'send') 86 87 self._orignal_too_late = complete_failures._DAYS_TO_BE_FAILING_TOO_LONG 88 89 90 def tearDown(self): 91 complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = self._orignal_too_late 92 datetime.datetime = self.datetime 93 setup_test_environment.tear_down() 94 super(CompleteFailuresFunctionalTests, self).tearDown() 95 96 97 def test(self): 98 """Does a basic test of as much of the system as possible.""" 99 job = models.Job(job_idx=1) 100 kernel = models.Kernel(kernel_idx=1) 101 machine = models.Machine(machine_idx=1) 102 success_status = models.Status(status_idx=GOOD_STATUS_IDX) 103 fail_status = models.Status(status_idx=FAIL_STATUS_IDX) 104 105 old_passing_test = models.Test(job=job, status=success_status, 106 kernel=kernel, machine=machine, 107 test='test1', 108 started_time=self.datetime(2012, 1, 1)) 109 old_passing_test.save() 110 failing_test = models.Test(job=job, status=fail_status, 111 kernel=kernel, machine=machine, 112 test='test2', 113 started_time=self.datetime(2012,1,1)) 114 failing_test.save() 115 good_test = models.Test(job=job, status=success_status, 116 kernel=kernel, machine=machine, 117 test='test3', 118 started_time=self.datetime(2012, 1, 20)) 119 good_test.save() 120 121 complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = 10 122 MockDatetime.today().AndReturn(self.datetime(2012, 1, 21)) 123 MockDatetime.today().AndReturn(self.datetime(2012, 1, 21)) 124 mail.send('chromeos-test-health (at] google.com', 125 ['chromeos-lab-infrastructure (at] google.com'], 126 [], 127 'Long Failing Tests', 128 '2/3 tests have been failing for at least %d days.\n' 129 'They are the following:\n\ntest1\ntest2' 130 % complete_failures._DAYS_TO_BE_FAILING_TOO_LONG) 131 132 self.mox.ReplayAll() 133 complete_failures.main() 134 135 136 if __name__ == '__main__': 137 unittest.main() 138