complete_failures_unittest.py revision 3d8076899b7ae59c6099934b2c797e34553f45bb
11a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood#!/usr/bin/python
21a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood#
31a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
41a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood# Use of this source code is governed by a BSD-style license that can be
51a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood# found in the LICENSE file.
61a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
71a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hoodimport datetime, unittest
81a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
91a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hoodimport mox
101a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
11788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodimport common
12788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood# This must come before the import of complete_failures in order to use the
13788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood# in memory database.
14788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodfrom autotest_lib.frontend import setup_django_readonly_environment
15788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodfrom autotest_lib.frontend import setup_test_environment
16788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodimport complete_failures
171a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hoodfrom autotest_lib.client.common_lib import mail
18788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodfrom autotest_lib.frontend.tko import models
19788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodfrom django import test
201a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
211a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
22788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar HoodGOOD_STATUS_IDX = 6
23788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar HoodFAIL_STATUS_IDX = 4
24788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
25e7b118479a372b12619abc97124396240be191a1Keyar Hood# See complte_failurs_functional_tests.py for why we need this.
26e7b118479a372b12619abc97124396240be191a1Keyar Hoodclass MockDatetime(datetime.datetime):
27e7b118479a372b12619abc97124396240be191a1Keyar Hood    """Used to mock out parts of datetime.datetime."""
28e7b118479a372b12619abc97124396240be191a1Keyar Hood    pass
29e7b118479a372b12619abc97124396240be191a1Keyar Hood
30e7b118479a372b12619abc97124396240be191a1Keyar Hood
313d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hoodclass StoreResultsTests(mox.MoxTestBase):
323d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    """Test that entries are properly stored in the storage object."""
331a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
341a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood    def setUp(self):
353d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        super(StoreResultsTests, self).setUp()
36e7b118479a372b12619abc97124396240be191a1Keyar Hood        self._orig_too_long = complete_failures._DAYS_TO_BE_FAILING_TOO_LONG
371a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
381a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
391a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood    def tearDown(self):
40e7b118479a372b12619abc97124396240be191a1Keyar Hood        complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = self._orig_too_long
413d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        super(StoreResultsTests, self).tearDown()
421a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
431a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
443d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    def test_add_failing_test(self):
453d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        """Test adding a failing test to storage."""
461a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        # We will want to keep all the datetime logic intact and so we need to
471a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        # keep a reference to the unmocked datetime.
481a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.datetime = datetime.datetime
491a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.StubOutWithMock(datetime, 'datetime')
501a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        datetime.datetime.today().AndReturn(self.datetime(2012, 1, 1))
511a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = 60
521a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
531a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        storage = {}
541a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
551a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.ReplayAll()
563d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        complete_failures.store_results(
571a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood                {'test': datetime.datetime.min}, storage)
581a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
591a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.assertEqual(storage['test'], self.datetime(2012, 1, 1))
601a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
611a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
621a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood    def test_remove_test_if_it_has_succeeded_recently_enough(self):
631a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        """Test that we remove a passing test from the storage object."""
641a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        storage = {'test': datetime.datetime(2012, 1, 1)}
651a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = 60
661a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        today = datetime.datetime(2012, 4, 10)
671a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        safe_date = datetime.datetime(2012, 4, 9)
681a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
691a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.StubOutWithMock(datetime, 'datetime')
701a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        datetime.datetime.today().AndReturn(today)
711a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
721a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.ReplayAll()
733d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        complete_failures.store_results({'test': safe_date}, storage)
741a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
751a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.assertTrue('test' not in storage)
761a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
771a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
781a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood    def test_no_crashing_on_test_that_has_never_failed_for_too_long(self):
791a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        """Test that we do not crash for tests that have always passed."""
801a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        storage = {}
811a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = 60
823d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        today = datetime.datetime(2012, 4, 10)
833d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        safe_date = datetime.datetime(2012, 4, 9)
841a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
851a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.StubOutWithMock(datetime, 'datetime')
861a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        datetime.datetime.today().AndReturn(today)
871a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
881a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.ReplayAll()
893d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        complete_failures.store_results({'test': safe_date}, storage)
901a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
911a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.assertTrue('test' not in storage)
921a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
931a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
941a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood    def test_do_not_delete_if_still_failing(self):
951a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        """Test that an old failing test is not removed from storage."""
961a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        # We will want to keep all the datetime logic intact and so we need to
971a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        # keep a reference to the unmocked datetime.
981a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.datetime = datetime.datetime
991a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        today = datetime.datetime(2012, 1, 1)
1001a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.StubOutWithMock(datetime, 'datetime')
1011a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        datetime.datetime.today().AndReturn(today)
1021a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
1031a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        storage = {'test': datetime.datetime.min}
1041a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
1053d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        # The ReplayAll is required or else a mox object sneaks its way into
1063d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        # the storage object somehow.
1073d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        self.mox.ReplayAll()
1083d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        complete_failures.store_results(
1093d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood            {'test': datetime.datetime.min}, storage)
1103d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1113d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        self.assertTrue('test' in storage)
1123d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1133d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1143d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hoodclass EmailAboutTestFailureTests(mox.MoxTestBase):
1153d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    """
1163d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    Tests that emails are sent about failed tests.
1173d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1183d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    This currently means an email is sent about all the entries of the
1193d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    storage object.
1203d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1213d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    """
1223d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    def setUp(self):
1233d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        super(EmailAboutTestFailureTests, self).setUp()
1243d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1253d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        # We need to mock out the send function in all tests or else the
1263d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        # emails will be sent out during tests.
1273d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        self.mox.StubOutWithMock(mail, 'send')
1283d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1293d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        self._orig_too_long = complete_failures._DAYS_TO_BE_FAILING_TOO_LONG
1303d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1313d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1323d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    def tearDown(self):
1333d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = self._orig_too_long
1343d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        super(EmailAboutTestFailureTests, self).tearDown()
1353d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1363d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1373d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood    def test_email_sent_about_all_entries_in_storage(self):
1383d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        """Test that the email report mentions all the entries in storage."""
1393d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        complete_failures._DAYS_TO_BE_FAILING_TOO_LONG = 60
1403d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1414d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood        mail.send(
1424d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood                'chromeos-test-health@google.com',
1434d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood                ['chromeos-lab-infrastructure@google.com'],
1444d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood                [],
1454d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood                'Long Failing Tests',
1464d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood                'The following tests have been failing for at '
1474d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood                'least %i days:\n\ntest'
1484d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood                    % complete_failures._DAYS_TO_BE_FAILING_TOO_LONG)
1494d5f9d1ed2fe6ddc31f30ceede342d525f2e2616Keyar Hood
1503d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        storage = {'test': datetime.datetime.min}
1513d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood
1521a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        # The ReplayAll is required or else a mox object sneaks its way into
1531a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        # the storage object somehow.
1541a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood        self.mox.ReplayAll()
1553d8076899b7ae59c6099934b2c797e34553f45bbKeyar Hood        complete_failures.email_about_test_failure(storage)
156788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
157788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
158005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hoodclass IsValidTestNameTests(test.TestCase):
159005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood    """Tests the is_valid_test_name function."""
160005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
161005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood    def test_returns_true_for_valid_test_name(self):
162005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        """Test that a valid test name returns True."""
163005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        name = 'TestName.TestName'
164005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        self.assertTrue(complete_failures.is_valid_test_name(name))
165005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
166005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
167005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood    def test_returns_false_if_name_has_slash_in_it(self):
168005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        """Test that a name with a slash in it returns False."""
169005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        name = 'path/to/test'
170005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        self.assertFalse(complete_failures.is_valid_test_name(name))
171005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
172005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
173005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood    def test_returns_false_for_try_new_image_entries(self):
174005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        """Test that a name that starts with try_new_image returns False."""
175005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        name = 'try_new_image-blah'
176005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        self.assertFalse(complete_failures.is_valid_test_name(name))
177005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
178005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
179788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodclass GetLastPassTimesTests(mox.MoxTestBase, test.TestCase):
180788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    """Tests the get_last_pass_times function."""
181788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
182788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def setUp(self):
183788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        super(GetLastPassTimesTests, self).setUp()
184788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        setup_test_environment.set_up()
185788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
186788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
187788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def tearDown(self):
188788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        setup_test_environment.tear_down()
189788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        super(GetLastPassTimesTests, self).tearDown()
190788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
191788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
192788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def test_return_most_recent_pass(self):
193788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        """The last time a test passed should be returned."""
194788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        # To add a test entry to the database, Django the test object to
195788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        # be instantiated with various other model instances. We give these
196788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        # instances dummy id values.
197005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        job = models.Job(job_idx=1)
198005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        kernel = models.Kernel(kernel_idx=1)
199005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        machine = models.Machine(machine_idx=1)
200005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        success_status = models.Status(status_idx=GOOD_STATUS_IDX)
201005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
202005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        early_pass = models.Test(job=job, status=success_status,
203005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                 kernel=kernel, machine=machine,
204005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                 test='test',
205005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                 started_time=datetime.datetime(2012, 1, 1))
206788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        early_pass.save()
207005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        late_pass = models.Test(job=job, status=success_status,
208005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                kernel=kernel, machine=machine,
209005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                test='test',
210005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                started_time=datetime.datetime(2012, 1, 2))
211788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        late_pass.save()
212788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
213788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        results = complete_failures.get_last_pass_times()
214788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
215788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.assertEquals(results, {'test': datetime.datetime(2012, 1, 2)})
216788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
217788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
218788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def test_only_return_passing_tests(self):
219788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        """Tests that only tests that have passed at some point are returned."""
220005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        job = models.Job(job_idx=1)
221005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        kernel = models.Kernel(kernel_idx=1)
222005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        machine = models.Machine(machine_idx=1)
223005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        success_status = models.Status(status_idx=GOOD_STATUS_IDX)
224005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        fail_status = models.Status(status_idx=FAIL_STATUS_IDX)
225005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
226005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        passing_test = models.Test(job=job, status=success_status,
227005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   kernel=kernel, machine=machine,
228005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   test='passing_test',
229005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   started_time=datetime.datetime(2012, 1, 1))
230788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        passing_test.save()
231005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        failing_test = models.Test(job=job, status=fail_status,
232005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   kernel=kernel, machine=machine,
233005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   test='failing_test',
234005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   started_time=datetime.datetime(2012, 1, 1))
235788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        failing_test.save()
236788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
237788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        results = complete_failures.get_last_pass_times()
238788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
239788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.assertEquals(results,
240788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood                          {'passing_test': datetime.datetime(2012, 1, 1)})
241788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
242788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
243788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def test_return_all_passing_tests(self):
244788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        """This function returns all tests that passed at least once."""
245005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        job = models.Job(job_idx=1)
246005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        kernel = models.Kernel(kernel_idx=1)
247005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        machine = models.Machine(machine_idx=1)
248005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        success_status = models.Status(status_idx=GOOD_STATUS_IDX)
249005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
250005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        test1 = models.Test(job=job, status=success_status,
251005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                            kernel=kernel, machine=machine,
252005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                            test='test1',
253005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                            started_time=datetime.datetime(2012, 1, 1))
254788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        test1.save()
255005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        test2 = models.Test(job=job, status=success_status,
256005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                            kernel=kernel, machine=machine,
257005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                            test='test2',
258005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                            started_time=datetime.datetime(2012, 1, 2))
259788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        test2.save()
260788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
261788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        results = complete_failures.get_last_pass_times()
262788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
263788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.assertEquals(results, {'test1': datetime.datetime(2012, 1, 1),
264788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood                                    'test2': datetime.datetime(2012, 1, 2)})
265788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
266788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
267005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood    def test_does_not_return_invalid_test_names(self):
268005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        """Tests that tests with invalid test names are not returned."""
269005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        job = models.Job(job_idx=1)
270005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        kernel = models.Kernel(kernel_idx=1)
271005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        machine = models.Machine(machine_idx=1)
272005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        success_status = models.Status(status_idx=GOOD_STATUS_IDX)
273005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        fail_status = models.Status(status_idx=FAIL_STATUS_IDX)
274005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
275005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        invalid_test = models.Test(job=job, status=success_status,
276005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                  kernel=kernel, machine=machine,
277005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                  test='invalid_test/name',
278005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                  started_time=datetime.datetime(2012, 1, 1))
279005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        invalid_test.save()
280005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
281005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        results = complete_failures.get_last_pass_times()
282005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
283005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        self.assertTrue(not results)
284005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
285005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
286e7b118479a372b12619abc97124396240be191a1Keyar Hoodclass GetRecentlyRanTestNamesTests(mox.MoxTestBase, test.TestCase):
287e7b118479a372b12619abc97124396240be191a1Keyar Hood    """Tests the get_recently_ran_test_names function."""
288788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
289788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def setUp(self):
290e7b118479a372b12619abc97124396240be191a1Keyar Hood        super(GetRecentlyRanTestNamesTests, self).setUp()
291e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.mox.StubOutWithMock(MockDatetime, 'today')
292e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.datetime = datetime.datetime
293e7b118479a372b12619abc97124396240be191a1Keyar Hood        datetime.datetime = MockDatetime
294788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        setup_test_environment.set_up()
295e7b118479a372b12619abc97124396240be191a1Keyar Hood        self._orig_cutoff = complete_failures._DAYS_NOT_RUNNING_CUTOFF
296788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
297788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
298788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def tearDown(self):
299e7b118479a372b12619abc97124396240be191a1Keyar Hood        datetime.datetime = self.datetime
300e7b118479a372b12619abc97124396240be191a1Keyar Hood        complete_failures._DAYS_NOT_RUNNING_CUTOFF = self._orig_cutoff
301788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        setup_test_environment.tear_down()
302e7b118479a372b12619abc97124396240be191a1Keyar Hood        super(GetRecentlyRanTestNamesTests, self).tearDown()
303788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
304788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
305e7b118479a372b12619abc97124396240be191a1Keyar Hood    def test_return_all_recently_ran_tests(self):
306788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        """Test that the function does as it says it does."""
307005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        job = models.Job(job_idx=1)
308005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        kernel = models.Kernel(kernel_idx=1)
309005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        machine = models.Machine(machine_idx=1)
310005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        success_status = models.Status(status_idx=GOOD_STATUS_IDX)
311005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
312e7b118479a372b12619abc97124396240be191a1Keyar Hood        recent = models.Test(job=job, status=success_status,
313e7b118479a372b12619abc97124396240be191a1Keyar Hood                             kernel=kernel, machine=machine,
314e7b118479a372b12619abc97124396240be191a1Keyar Hood                             test='recent',
315e7b118479a372b12619abc97124396240be191a1Keyar Hood                             started_time=self.datetime(2012, 1, 1))
316e7b118479a372b12619abc97124396240be191a1Keyar Hood        recent.save()
317e7b118479a372b12619abc97124396240be191a1Keyar Hood        old = models.Test(job=job, status=success_status,
318e7b118479a372b12619abc97124396240be191a1Keyar Hood                          kernel=kernel, machine=machine,
319e7b118479a372b12619abc97124396240be191a1Keyar Hood                          test='old',
320e7b118479a372b12619abc97124396240be191a1Keyar Hood                          started_time=self.datetime(2011, 1, 2))
321e7b118479a372b12619abc97124396240be191a1Keyar Hood        old.save()
322788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
323e7b118479a372b12619abc97124396240be191a1Keyar Hood        datetime.datetime.today().AndReturn(self.datetime(2012, 1, 4))
324e7b118479a372b12619abc97124396240be191a1Keyar Hood        complete_failures._DAYS_NOT_RUNNING_CUTOFF = 60
325788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
326e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.mox.ReplayAll()
327e7b118479a372b12619abc97124396240be191a1Keyar Hood        results = complete_failures.get_recently_ran_test_names()
328e7b118479a372b12619abc97124396240be191a1Keyar Hood
329e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.assertEqual(set(results), set(['recent']))
330788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
331788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
332788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def test_returns_no_duplicate_names(self):
333788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        """Test that each test name appears only once."""
334005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        job = models.Job(job_idx=1)
335005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        kernel = models.Kernel(kernel_idx=1)
336005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        machine = models.Machine(machine_idx=1)
337005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        success_status = models.Status(status_idx=GOOD_STATUS_IDX)
338005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
339005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        test = models.Test(job=job, status=success_status,
340005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                           kernel=kernel, machine=machine,
341005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                           test='test',
342e7b118479a372b12619abc97124396240be191a1Keyar Hood                           started_time=self.datetime(2012, 1, 1))
343788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        test.save()
344005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        duplicate = models.Test(job=job, status=success_status,
345005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                kernel=kernel, machine=machine,
346005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                test='test',
347e7b118479a372b12619abc97124396240be191a1Keyar Hood                                started_time=self.datetime(2012, 1, 2))
348788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        duplicate.save()
349788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
350e7b118479a372b12619abc97124396240be191a1Keyar Hood        datetime.datetime.today().AndReturn(self.datetime(2012, 1, 3))
351e7b118479a372b12619abc97124396240be191a1Keyar Hood        complete_failures._DAYS_NOT_RUNNING_CUTOFF = 60
352e7b118479a372b12619abc97124396240be191a1Keyar Hood
353e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.mox.ReplayAll()
354e7b118479a372b12619abc97124396240be191a1Keyar Hood        results = complete_failures.get_recently_ran_test_names()
355788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
356788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.assertEqual(len(results), 1)
357788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
358788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
359005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood    def test_does_not_return_invalid_test_names(self):
360005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        """Tests that only tests with invalid test names are not returned."""
361005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        job = models.Job(job_idx=1)
362005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        kernel = models.Kernel(kernel_idx=1)
363005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        machine = models.Machine(machine_idx=1)
364005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        success_status = models.Status(status_idx=GOOD_STATUS_IDX)
365005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
366005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        invalid_test = models.Test(job=job, status=success_status,
367005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   kernel=kernel, machine=machine,
368005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood                                   test='invalid_test/name',
369e7b118479a372b12619abc97124396240be191a1Keyar Hood                                   started_time=self.datetime(2012, 1, 1))
370005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        invalid_test.save()
371005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
372e7b118479a372b12619abc97124396240be191a1Keyar Hood        datetime.datetime.today().AndReturn(self.datetime(2012, 1, 2))
373e7b118479a372b12619abc97124396240be191a1Keyar Hood        complete_failures._DAYS_NOT_RUNNING_CUTOFF = 60
374e7b118479a372b12619abc97124396240be191a1Keyar Hood
375e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.mox.ReplayAll()
376e7b118479a372b12619abc97124396240be191a1Keyar Hood        results = complete_failures.get_recently_ran_test_names()
377005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
378005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood        self.assertTrue(not results)
379005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
380005539dbc39ccba6b8c97771cda2dba0d8a163f3Keyar Hood
381788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hoodclass GetTestsToAnalyzeTests(mox.MoxTestBase):
382788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    """Tests the get_tests_to_analyze function."""
383788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
384e7b118479a372b12619abc97124396240be191a1Keyar Hood    def test_returns_recent_test_names(self):
385788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        """Test should return all the test names in the database."""
386788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.mox.StubOutWithMock(complete_failures, 'get_last_pass_times')
387e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.mox.StubOutWithMock(complete_failures,
388e7b118479a372b12619abc97124396240be191a1Keyar Hood            'get_recently_ran_test_names')
389788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
390788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        complete_failures.get_last_pass_times().AndReturn({'passing_test':
391e7b118479a372b12619abc97124396240be191a1Keyar Hood            datetime.datetime(2012, 1 ,1),
392e7b118479a372b12619abc97124396240be191a1Keyar Hood            'old_passing_test': datetime.datetime(2011, 1, 1)})
393e7b118479a372b12619abc97124396240be191a1Keyar Hood        complete_failures.get_recently_ran_test_names().AndReturn(
394e7b118479a372b12619abc97124396240be191a1Keyar Hood            {'passing_test',
395e7b118479a372b12619abc97124396240be191a1Keyar Hood             'failing_test'})
396788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.mox.ReplayAll()
397788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        results = complete_failures.get_tests_to_analyze()
398788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
399e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.assertEqual(results,
400e7b118479a372b12619abc97124396240be191a1Keyar Hood                         {'passing_test': datetime.datetime(2012, 1, 1),
401e7b118479a372b12619abc97124396240be191a1Keyar Hood                          'failing_test': datetime.datetime.min})
402788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
403788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
404788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood    def test_returns_failing_tests_with_min_datetime(self):
405788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        """Test that never-passed tests are paired with datetime.min."""
406788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.mox.StubOutWithMock(complete_failures, 'get_last_pass_times')
407e7b118479a372b12619abc97124396240be191a1Keyar Hood        self.mox.StubOutWithMock(complete_failures,
408e7b118479a372b12619abc97124396240be191a1Keyar Hood                                 'get_recently_ran_test_names')
409788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
410788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        complete_failures.get_last_pass_times().AndReturn({})
411e7b118479a372b12619abc97124396240be191a1Keyar Hood        complete_failures.get_recently_ran_test_names().AndReturn({'test'})
412788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
413788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.mox.ReplayAll()
414788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        results = complete_failures.get_tests_to_analyze()
415788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood
416788e498ae7b6735857c83d88de7f5fffabbc7f8fKeyar Hood        self.assertEqual(results, {'test': datetime.datetime.min})
4171a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
4181a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood
4191a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hoodif __name__ == '__main__':
4201a3c8dd59f71086eb2f5d08b0f13df95428e60faKeyar Hood    unittest.main()
421