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
9import datetime, logging, mox, unittest
10# driver must be imported first due to circular imports in base_event and task
11import driver  # pylint: disable-msg=W0611
12import base_event, build_event, forgiving_config_parser, manifest_versions, task
13
14
15class 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
73class 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
171if __name__ == '__main__':
172  unittest.main()
173