timed_event_unittest.py revision e8bebaf10711ca802d40c0b7f412e3910999159e
1fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone#!/usr/bin/python 2fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone# 3fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 4fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone# Use of this source code is governed by a BSD-style license that can be 5fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone# found in the LICENSE file. 6fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 72d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone"""Unit tests for site_utils/timed_event.py.""" 8fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 993f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masoneimport datetime, logging, mox, unittest 10fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 1193f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masoneimport base_event, deduping_scheduler, forgiving_config_parser 1293f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masoneimport manifest_versions, task, timed_event 13fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 14fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 15013859b492bf4f5b304e31be3300789443eee33eChris Masoneclass TimedEventTestBase(mox.MoxTestBase): 16013859b492bf4f5b304e31be3300789443eee33eChris Masone """Base class for TimedEvent unit test classes.""" 17fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 18fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 19fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def setUp(self): 20013859b492bf4f5b304e31be3300789443eee33eChris Masone super(TimedEventTestBase, self).setUp() 212d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.mox.StubOutWithMock(timed_event.TimedEvent, '_now') 225bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone self.mv = self.mox.CreateMock(manifest_versions.ManifestVersions) 23fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 24fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 25fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def BaseTime(self): 26013859b492bf4f5b304e31be3300789443eee33eChris Masone """Return the TimedEvent trigger-time as a datetime instance.""" 27fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone raise NotImplementedError() 28fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 29fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 305bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone def CreateEvent(self): 31013859b492bf4f5b304e31be3300789443eee33eChris Masone """Return an instance of the TimedEvent subclass being tested.""" 32fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone raise NotImplementedError() 33fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 34fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 35fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def TimeBefore(self, now): 36fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Return a datetime that's before |now|.""" 37fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone raise NotImplementedError() 38fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 39fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 40fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def TimeLaterThan(self, now): 41fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Return a datetime that's later than |now|.""" 42fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone raise NotImplementedError() 43fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 44fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 45fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def doTestDeadlineInFuture(self): 46fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fake_now = self.TimeBefore(self.BaseTime()) 472d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 48fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 49fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 505bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone t = self.CreateEvent() # Deadline gets set for a future time. 512d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertFalse(t.ShouldHandle()) 52fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.VerifyAll() 53fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 54fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ResetAll() 55fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fake_now = self.TimeLaterThan(fake_now) # Jump past that future time. 562d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 57fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 582d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertTrue(t.ShouldHandle()) 59fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 60fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 61fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def doTestDeadlineIsNow(self): 62fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """We happened to create the trigger at the exact right time.""" 632d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(self.BaseTime()) 64fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 655bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone to_test = self.CreateEvent() 662d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertTrue(to_test.ShouldHandle()) 67fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 68fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 69fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def doTestTOCTOU(self): 70fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Even if deadline passes during initialization, trigger must fire.""" 71fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone init_now = self.BaseTime() - datetime.timedelta(seconds=1) 72fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fire_now = self.BaseTime() + datetime.timedelta(seconds=1) 732d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().AndReturn(init_now) 742d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().AndReturn(fire_now) 75fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 76fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 775bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone t = self.CreateEvent() # Deadline gets set for later tonight... 78fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone # ...but has passed by the time we get around to firing. 792d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertTrue(t.ShouldHandle()) 80fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 81fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 82e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone def doTestDeadlineUpdate(self, days_to_jump): 83e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone fake_now = self.TimeBefore(self.BaseTime()) 84e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 85e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.mox.ReplayAll() 86e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 87e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone nightly = self.CreateEvent() # Deadline gets set for tonight. 88e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.assertFalse(nightly.ShouldHandle()) 89e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.mox.VerifyAll() 90e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 91e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.mox.ResetAll() 92e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone fake_now = self.TimeLaterThan(self.BaseTime()) # Jump past deadline. 93e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 94e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.mox.ReplayAll() 95e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 96e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.assertTrue(nightly.ShouldHandle()) 97e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone nightly.UpdateCriteria() # Deadline moves to tomorrow night 98e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.assertFalse(nightly.ShouldHandle()) 99e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.mox.VerifyAll() 100e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 101e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.mox.ResetAll() 102e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone fake_now += datetime.timedelta(days=days_to_jump) # Jump past deadline. 103e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 104e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.mox.ReplayAll() 105e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.assertTrue(nightly.ShouldHandle()) 106e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 107e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 1085bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone def doTestGetBranchBuilds(self, days): 1095bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone board = 'faux_board' 1105bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone branch_manifests = {('factory','16'): ['last16'], 1115bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone ('release','17'): ['first17', 'last17']} 11293f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone self.mv.ManifestsSinceDays(days, board).AndReturn(branch_manifests) 1135bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(self.BaseTime()) 1145bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone self.mox.ReplayAll() 1155bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone 116d17d185d7abd68584f3756a89a7475a5b6109f34Chris Masone branch_builds = self.CreateEvent().GetBranchBuildsForBoard(board) 1175bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone for (type, milestone), manifests in branch_manifests.iteritems(): 1185bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone build = None 11967f06d6003bb11f03f925810272f595d79dce44aChris Masone if type in task.BARE_BRANCHES: 1209ee3eca81228c4479e4b1b0af11d9b69547b1ca7Chris Masone self.assertEquals(len(branch_builds[type]), 1) 1219ee3eca81228c4479e4b1b0af11d9b69547b1ca7Chris Masone build = branch_builds[type][0] 1225bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone self.assertTrue(build.startswith('%s-%s' % (board, type))) 1235bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone else: 1249ee3eca81228c4479e4b1b0af11d9b69547b1ca7Chris Masone self.assertEquals(len(branch_builds[milestone]), 1) 1259ee3eca81228c4479e4b1b0af11d9b69547b1ca7Chris Masone build = branch_builds[milestone][0] 1265bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone self.assertTrue(build.startswith('%s-release' % board)) 1279ee3eca81228c4479e4b1b0af11d9b69547b1ca7Chris Masone self.assertTrue('R%s-%s' % (milestone, manifests[-1]) in build) 1285bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone 1295bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone 130013859b492bf4f5b304e31be3300789443eee33eChris Masoneclass NightlyTest(TimedEventTestBase): 131fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Unit tests for Weekly. 132fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 133fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone @var _HOUR: The time of night to use in these unit tests. 134fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """ 135fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 1362d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone _HOUR = 20 137fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 138fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 139fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def setUp(self): 140fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone super(NightlyTest, self).setUp() 141fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 142fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 143fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def BaseTime(self): 144fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone return datetime.datetime(2012, 1, 1, self._HOUR) 145fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 146fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 1475bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone def CreateEvent(self): 1482d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone """Return an instance of timed_event.Nightly.""" 14993f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone return timed_event.Nightly(self.mv, False, self._HOUR) 1502d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 1512d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 1522d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone def testCreateFromConfig(self): 1532d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone """Test that creating from config is equivalent to using constructor.""" 1542d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config = forgiving_config_parser.ForgivingConfigParser() 15593f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone section = base_event.SectionName(timed_event.Nightly.KEYWORD) 1562d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config.add_section(section) 1572d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config.set(section, 'hour', '%d' % self._HOUR) 1582d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 1592d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(self.BaseTime()) 1602d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.mox.ReplayAll() 1612d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 16293f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone self.assertEquals(self.CreateEvent(), 16393f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone timed_event.Nightly.CreateFromConfig(config, self.mv)) 1642d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 1652d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 1662d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone def testCreateFromEmptyConfig(self): 1672d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone """Test that creating from empty config uses defaults.""" 1682d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config = forgiving_config_parser.ForgivingConfigParser() 1692d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 1702d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(self.BaseTime()) 1712d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.mox.ReplayAll() 1722d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 1732d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertEquals( 17493f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone timed_event.Nightly(self.mv, False, 17593f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone timed_event.Nightly._DEFAULT_HOUR), 17693f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone timed_event.Nightly.CreateFromConfig(config, self.mv)) 177fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 178fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 179fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testDeadlineInPast(self): 180fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Ensure we work if the deadline aready passed today.""" 181fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fake_now = self.BaseTime() + datetime.timedelta(hours=1) 1822d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 183fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 184fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 1855bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone nightly = self.CreateEvent() # Deadline gets set for tomorrow night. 1862d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertFalse(nightly.ShouldHandle()) 187fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.VerifyAll() 188fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 189fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ResetAll() 190fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fake_now += datetime.timedelta(days=1) # Jump to tomorrow night. 1912d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 192fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 1932d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertTrue(nightly.ShouldHandle()) 194fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 195fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 196fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def TimeBefore(self, now): 197fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone return now - datetime.timedelta(hours=1) 198fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 199fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 200fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def TimeLaterThan(self, now): 201fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone return now + datetime.timedelta(hours=2) 202fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 203fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 204fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testDeadlineInFuture(self): 205fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Ensure we work if the deadline is later today.""" 206fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.doTestDeadlineInFuture() 207fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 208fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 209fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testDeadlineIsNow(self): 210fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """We happened to create the trigger at the exact right time.""" 211fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.doTestDeadlineIsNow() 212fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 213fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 214fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testTOCTOU(self): 215fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Even if deadline passes during initialization, trigger must fire.""" 216fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.doTestTOCTOU() 217fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 218fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 219e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone def testDeadlineUpdate(self): 220e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone """Ensure we update the deadline correctly.""" 221e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.doTestDeadlineUpdate(days_to_jump=1) 222e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 223e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 2245bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone def testGetBranchBuilds(self): 2255bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone """Ensure Nightly gets most recent builds in last day.""" 2265bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone self.doTestGetBranchBuilds(days=1) 2275bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone 2285bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone 229013859b492bf4f5b304e31be3300789443eee33eChris Masoneclass WeeklyTest(TimedEventTestBase): 230fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Unit tests for Weekly. 231fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 232fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone @var _DAY: The day of the week to use in these unit tests. 233fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone @var _HOUR: The time of night to use in these unit tests. 234fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """ 235fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 236fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone _DAY = 5 2372d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone _HOUR = 22 238fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 239fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 240fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def setUp(self): 241fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone super(WeeklyTest, self).setUp() 242fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 243fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 244fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def BaseTime(self): 245fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone basetime = datetime.datetime(2012, 1, 1, self._HOUR) 246fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone basetime += datetime.timedelta(self._DAY-basetime.weekday()) 247fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone return basetime 248fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 249fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 2505bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone def CreateEvent(self): 2512d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone """Return an instance of timed_event.Weekly.""" 25293f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone return timed_event.Weekly(self.mv, False, self._DAY, self._HOUR) 2532d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 2542d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 2552d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone def testCreateFromConfig(self): 2562d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone """Test that creating from config is equivalent to using constructor.""" 2572d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config = forgiving_config_parser.ForgivingConfigParser() 25893f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone section = base_event.SectionName(timed_event.Weekly.KEYWORD) 2592d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config.add_section(section) 2602d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config.set(section, 'day', '%d' % self._DAY) 2612d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone config.set(section, 'hour', '%d' % self._HOUR) 2622d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 2632d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(self.BaseTime()) 2642d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.mox.ReplayAll() 2652d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone 26693f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone self.assertEquals(self.CreateEvent(), 26793f51d4da152538007d5b44a2dc9d2bbb1fe3429Chris Masone timed_event.Weekly.CreateFromConfig(config, self.mv)) 268fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 269fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 270fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testDeadlineInPast(self): 271fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Ensure we work if the deadline already passed this week.""" 272fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fake_now = self.BaseTime() + datetime.timedelta(days=1) 2732d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 274fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 275fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 2765bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone weekly = self.CreateEvent() # Deadline gets set for next week. 2772d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertFalse(weekly.ShouldHandle()) 278fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.VerifyAll() 279fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 280fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ResetAll() 281fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fake_now += datetime.timedelta(days=1) # Jump to tomorrow. 2822d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 283fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 2842d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertFalse(weekly.ShouldHandle()) 285fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.VerifyAll() 286fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 287fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ResetAll() 288fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone fake_now += datetime.timedelta(days=7) # Jump to next week. 2892d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone timed_event.TimedEvent._now().MultipleTimes().AndReturn(fake_now) 290fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.mox.ReplayAll() 2912d61ca263d3e571b19604ea4c9d7b55d83c28405Chris Masone self.assertTrue(weekly.ShouldHandle()) 292fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 293fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 294fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def TimeBefore(self, now): 295fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone return now - datetime.timedelta(days=1) 296fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 297fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 298fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def TimeLaterThan(self, now): 299fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone return now + datetime.timedelta(days=2) 300fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 301fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 302fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testDeadlineInFuture(self): 303fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Ensure we work if the deadline is later this week.""" 304fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.doTestDeadlineInFuture() 305fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 306fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 307fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testDeadlineIsNow(self): 308fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """We happened to create the trigger at the exact right time.""" 309fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.doTestDeadlineIsNow() 310fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 311fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 312fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone def testTOCTOU(self): 313fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone """Even if deadline passes during initialization, trigger must fire.""" 314fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone self.doTestTOCTOU() 315fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 316fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone 317e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone def testDeadlineUpdate(self): 318e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone """Ensure we update the deadline correctly.""" 319e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone self.doTestDeadlineUpdate(days_to_jump=7) 320e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 321e8bebaf10711ca802d40c0b7f412e3910999159eChris Masone 3225bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone def testGetBranchBuilds(self): 3235bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone """Ensure Weekly gets most recent builds in last 7 days.""" 3245bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone self.doTestGetBranchBuilds(days=7) 3255bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone 3265bde7dc7d8b0608feb43491d5ac648d11c890f54Chris Masone 327fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masoneif __name__ == '__main__': 328fad911ada4f6126280765f15204eaf8b3b4bc437Chris Masone unittest.main() 329