Home | History | Annotate | Download | only in health
      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