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 site_utils/build_event.py.""" 8 9 import datetime, logging, mox, unittest 10 # driver must be imported first due to circular imports in base_event and task 11 import driver # pylint: disable-msg=W0611 12 import base_event, build_event, forgiving_config_parser, manifest_versions, task 13 14 15 class BuildEventTestBase(mox.MoxTestBase): 16 """Base class for BuildEvent unit test classes. 17 18 @var BOARD: faux board. 19 """ 20 21 22 BOARD = 'faux_board' 23 24 25 def setUp(self): 26 super(BuildEventTestBase, self).setUp() 27 self.mv = self.mox.CreateMock(manifest_versions.ManifestVersions) 28 29 30 def CreateEvent(self): 31 """Return an instance of the BuildEvent subclass being tested.""" 32 raise NotImplementedError() 33 34 35 def VetBranchBuilds(self, board, branch_manifests, branch_builds): 36 """Assert that branch_builds is derived from branch_manifests. 37 38 @param board: the board to get builds for. 39 @param branch_manifests: {(type, milestone): [manifests]} 40 @param branch_builds: {type-or-milestone: [build-names]} 41 """ 42 for (type, milestone), manifests in branch_manifests.iteritems(): 43 builds = [] 44 if type in task.BARE_BRANCHES: 45 builds = branch_builds[type] 46 for build in builds: 47 self.assertTrue(build.startswith('%s-%s' % (board, type))) 48 else: 49 builds = branch_builds[milestone] 50 for build in builds: 51 self.assertTrue(build.startswith('%s-release' % board)) 52 for build, manifest in zip(builds, manifests): 53 self.assertTrue('R%s-%s' % (milestone, manifest) in build) 54 55 56 def doTestGetBranchBuilds(self, board, branch_manifests): 57 """Set expectations for and run BuildEvent.GetBranchBuildsForBoard(). 58 59 @param board: the board to get builds for. 60 @param branch_manifests: {(type, milestone): [manifests]} 61 @return per-branch builds; {type-or-milestone: [build-names]} 62 """ 63 head = '1cedcafe' 64 self.mv.GetCheckpoint().AndReturn(head) 65 self.mv.ManifestsSinceRev(head, board).AndReturn(branch_manifests) 66 self.mox.ReplayAll() 67 68 event = self.CreateEvent() 69 event.Prepare() 70 return event.GetBranchBuildsForBoard(board) 71 72 73 class NewBuildTest(BuildEventTestBase): 74 """Unit tests for build_event.NewBuild.""" 75 76 77 def CreateEvent(self): 78 return build_event.NewBuild(self.mv, False) 79 80 81 def testMerge(self): 82 initial_hash = '1cedcafe' 83 self.mv.GetCheckpoint().AndReturn(initial_hash) 84 self.mox.ReplayAll() 85 86 event1 = self.CreateEvent() 87 event1.Prepare() 88 event1.Merge(self.CreateEvent()) 89 self.assertEquals(event1._revision, initial_hash) 90 91 92 def testCreateFromAlwaysHandleConfig(self): 93 """Test that creating with always_handle works as intended.""" 94 config = forgiving_config_parser.ForgivingConfigParser() 95 section = base_event.SectionName(build_event.NewBuild.KEYWORD) 96 config.add_section(section) 97 config.set(section, 'always_handle', 'True') 98 self.mox.ReplayAll() 99 100 event = build_event.NewBuild.CreateFromConfig(config, self.mv) 101 self.assertTrue(event.ShouldHandle()) 102 103 104 def testGetBranchBuilds(self): 105 """Ensure that we handle the appearance of new branch builds.""" 106 branch_manifests = {('factory','16'): ['last16'], 107 ('release','17'): ['first17', 'last17']} 108 branch_builds = self.doTestGetBranchBuilds(self.BOARD, branch_manifests) 109 self.VetBranchBuilds(self.BOARD, branch_manifests, branch_builds) 110 111 112 113 def testGetNoBranchBuilds(self): 114 """Ensure that we tolerate the appearance of no new branch builds.""" 115 branch_builds = self.doTestGetBranchBuilds(self.BOARD, {}) 116 self.assertEquals(branch_builds, {}) 117 118 119 def testShouldHandle(self): 120 """Ensure that we suggest Handle() iff new successful builds exist.""" 121 initial_hash = '1cedcafe' 122 expected_hash = 'deadbeef' 123 self.mv.GetCheckpoint().AndReturn(initial_hash) 124 self.mv.AnyManifestsSinceRev(initial_hash).AndReturn(False) 125 self.mv.GetCheckpoint().AndReturn(expected_hash) 126 self.mv.AnyManifestsSinceRev(expected_hash).AndReturn(True) 127 self.mox.ReplayAll() 128 new_build = self.CreateEvent() 129 new_build.Prepare() 130 self.assertFalse(new_build.ShouldHandle()) 131 new_build.UpdateCriteria() 132 self.assertTrue(new_build.ShouldHandle()) 133 134 135 def testRunThrough(self): 136 """Ensure we can run through a couple passes of expected workflow.""" 137 initial_hash = '1cedcafe' 138 expected_hash = 'deadbeef' 139 branch_manifests = {('factory','16'): ['last16'], 140 ('release','17'): ['first17', 'last17']} 141 142 # Expect Prepare() 143 self.mv.GetCheckpoint().AndReturn(initial_hash) 144 145 # Expect one run through. 146 self.mv.AnyManifestsSinceRev(initial_hash).AndReturn(True) 147 self.mv.ManifestsSinceRev(initial_hash, 148 self.BOARD).AndReturn(branch_manifests) 149 self.mv.GetCheckpoint().AndReturn(expected_hash) 150 151 # Expect a second run through. 152 self.mv.AnyManifestsSinceRev(expected_hash).AndReturn(True) 153 self.mv.ManifestsSinceRev(expected_hash, 154 self.BOARD).AndReturn(branch_manifests) 155 self.mox.ReplayAll() 156 157 new_build = self.CreateEvent() 158 159 new_build.Prepare() 160 161 self.assertTrue(new_build.ShouldHandle()) 162 self.assertTrue(new_build.GetBranchBuildsForBoard(self.BOARD)) 163 new_build.Handle(None, {}, self.BOARD) 164 new_build.UpdateCriteria() 165 166 self.assertTrue(new_build.ShouldHandle()) 167 self.assertTrue(new_build.GetBranchBuildsForBoard(self.BOARD)) 168 new_build.Handle(None, {}, self.BOARD) 169 170 171 if __name__ == '__main__': 172 unittest.main() 173