blob: 35c81da3fcc8bf5947429dfc083a3398b82e881d [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2018 The ChromiumOS Authors
Lann Martin4fbdf202018-08-30 12:02:52 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Tests for scripts/repo_sync_manifest."""
6
Lann Martin4fbdf202018-08-30 12:02:52 -06007import os
Mike Frysinger166fea02021-02-12 05:30:33 -05008from unittest import mock
Lann Martin4fbdf202018-08-30 12:02:52 -06009
Lann Martin4fbdf202018-08-30 12:02:52 -060010from chromite.lib import cros_build_lib
11from chromite.lib import cros_test_lib
12from chromite.lib import git
13from chromite.lib import osutils
14from chromite.lib import parallel_unittest
Mike Frysinger40ffb532021-02-12 07:36:08 -050015from chromite.lib import repo_util
Lann Martin4fbdf202018-08-30 12:02:52 -060016from chromite.scripts import create_manifest_snapshot
Mike Frysingerbf347822022-03-28 19:58:37 -040017from chromite.utils import repo_manifest
18from chromite.utils import repo_manifest_unittest
Lann Martin4fbdf202018-08-30 12:02:52 -060019
20
21MANIFEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
22<manifest>
23 <remote name="origin"/>
24 <default remote="origin"/>
25 <project name="project/a" revision="f01dab1e"/>
26 <project name="project/b" revision="cafe1234" upstream="short"/>
Mike Frysinger6e3f23c2021-02-17 14:06:19 -050027 <project name="project/c" revision="deadbeef" upstream="refs/heads/main"/>
Lann Martin4fbdf202018-08-30 12:02:52 -060028 <project name="dupe" revision="d1" upstream="dupe"/>
29 <project name="dupe" revision="d2" upstream="dupe"/>
30</manifest>
31"""
32
33
Alex Klein1699fab2022-09-08 08:46:06 -060034class CreateManifestSnapshotTest(
35 cros_test_lib.MockTempDirTestCase, repo_manifest_unittest.XMLTestCase
36):
37 """Unit tests for create_manifest_snapshot."""
Lann Martin4fbdf202018-08-30 12:02:52 -060038
Alex Klein1699fab2022-09-08 08:46:06 -060039 # pylint: disable=protected-access
Lann Martin4fbdf202018-08-30 12:02:52 -060040
Alex Klein1699fab2022-09-08 08:46:06 -060041 def setUp(self):
42 self.manifest = repo_manifest.Manifest.FromString(MANIFEST_XML)
43 self.project_a = self.manifest.GetUniqueProject("project/a")
44 self.project_b = self.manifest.GetUniqueProject("project/b")
45 self.project_c = self.manifest.GetUniqueProject("project/c")
46 self.dupes = [x for x in self.manifest.Projects() if x.name == "dupe"]
Lann Martin4fbdf202018-08-30 12:02:52 -060047
Alex Klein1699fab2022-09-08 08:46:06 -060048 self.mock_is_reachable = self.PatchObject(git, "IsReachable")
49 self.mock_git_push = self.PatchObject(git, "GitPush")
Lann Martin4fbdf202018-08-30 12:02:52 -060050
Alex Klein1699fab2022-09-08 08:46:06 -060051 self.repo_root = os.path.join(self.tempdir, "root")
52 os.makedirs(os.path.join(self.repo_root, ".repo"))
53 self.output_file = os.path.join(self.tempdir, "snapshot.xml")
54 self.main_args = [
55 "--repo-path",
56 self.repo_root,
57 "--log-level",
58 "fatal",
59 "--jobs",
60 "1",
61 "--output-file",
62 self.output_file,
63 ]
64 self.PatchObject(
65 repo_util.Repository, "Manifest", return_value=self.manifest
66 )
Lann Martin4fbdf202018-08-30 12:02:52 -060067
Alex Klein1699fab2022-09-08 08:46:06 -060068 def testGetUpstreamBranchNoUpstream(self):
69 """Test _GetUpstreamBranch with no upstream."""
70 branch = create_manifest_snapshot._GetUpstreamBranch(self.project_a)
71 self.assertIsNone(branch)
Lann Martin4fbdf202018-08-30 12:02:52 -060072
Alex Klein1699fab2022-09-08 08:46:06 -060073 def testGetUpstreamBranchShortUpstream(self):
74 """Test _GetUpstreamBranch with short upstream ref."""
75 branch = create_manifest_snapshot._GetUpstreamBranch(self.project_b)
76 self.assertEqual(branch, "short")
Lann Martin4fbdf202018-08-30 12:02:52 -060077
Alex Klein1699fab2022-09-08 08:46:06 -060078 def testGetUpstreamBranchFullUpstream(self):
79 """Test _GetUpstreamBranch with full upstream ref."""
80 branch = create_manifest_snapshot._GetUpstreamBranch(self.project_c)
81 self.assertEqual(branch, "main")
Lann Martin4fbdf202018-08-30 12:02:52 -060082
Alex Klein1699fab2022-09-08 08:46:06 -060083 def testNeedsSnapshotReachable(self):
84 """Test _NeedsSnapshot with revision reachable from upstream."""
85 self.mock_is_reachable.return_value = True
86 result = create_manifest_snapshot._NeedsSnapshot("root", self.project_c)
87 self.assertFalse(result)
88 self.mock_is_reachable.assert_called_with(
89 "root/project/c", "deadbeef", "refs/remotes/origin/main"
90 )
Lann Martin4fbdf202018-08-30 12:02:52 -060091
Alex Klein1699fab2022-09-08 08:46:06 -060092 def testNeedsSnapshotUnreachable(self):
93 """Test _NeedsSnapshot with revision reachable from upstream."""
94 self.mock_is_reachable.return_value = False
95 result = create_manifest_snapshot._NeedsSnapshot("root", self.project_b)
96 self.assertTrue(result)
97 self.mock_is_reachable.assert_called_with(
98 "root/project/b", "cafe1234", "refs/remotes/origin/short"
99 )
Lann Martin4fbdf202018-08-30 12:02:52 -0600100
Alex Klein1699fab2022-09-08 08:46:06 -0600101 def testNeedsSnapshotNoUpstream(self):
102 """Test _NeedsSnapshot with no project upstream."""
103 create_manifest_snapshot._NeedsSnapshot("root", self.project_a)
104 self.mock_is_reachable.assert_called_with(
105 "root/project/a", "f01dab1e", "refs/remotes/origin/main"
106 )
Lann Martin4fbdf202018-08-30 12:02:52 -0600107
Alex Klein1699fab2022-09-08 08:46:06 -0600108 def testNeedsSnapshotIsReachableFailure(self):
109 """Test _NeedsSnapshot with no project upstream."""
110 self.mock_is_reachable.side_effect = cros_build_lib.RunCommandError("")
111 result = create_manifest_snapshot._NeedsSnapshot("root", self.project_a)
112 self.assertTrue(result)
Lann Martin4fbdf202018-08-30 12:02:52 -0600113
Alex Klein1699fab2022-09-08 08:46:06 -0600114 def testMakeUniqueRefMain(self):
115 """Test _MakeUniqueRef with upstream main."""
116 used = set()
117 ref1 = create_manifest_snapshot._MakeUniqueRef(
118 self.project_c, "base", used
119 )
120 ref2 = create_manifest_snapshot._MakeUniqueRef(
121 self.project_c, "base", used
122 )
123 ref3 = create_manifest_snapshot._MakeUniqueRef(
124 self.project_c, "base", used
125 )
126 self.assertEqual(ref1, "base")
127 self.assertEqual(ref2, "base/1")
128 self.assertEqual(ref3, "base/2")
Lann Martin4fbdf202018-08-30 12:02:52 -0600129
Alex Klein1699fab2022-09-08 08:46:06 -0600130 def testMakeUniqueRefNonMain(self):
131 """Test _MakeUniqueRef with non-main upstream."""
132 used = set()
133 ref1 = create_manifest_snapshot._MakeUniqueRef(
134 self.project_b, "base", used
135 )
136 ref2 = create_manifest_snapshot._MakeUniqueRef(
137 self.project_b, "base", used
138 )
139 self.assertEqual(ref1, "base/short")
140 self.assertEqual(ref2, "base/short/1")
Lann Martin4fbdf202018-08-30 12:02:52 -0600141
Alex Klein1699fab2022-09-08 08:46:06 -0600142 def testGitPushProjectUpstream(self):
143 """Test _GitPushProjectUpstream."""
144 create_manifest_snapshot._GitPushProjectUpstream(
145 "root", self.project_b, False
146 )
147 self.mock_git_push.assert_called_with(
148 "root/project/b",
149 "cafe1234",
150 git.RemoteRef("origin", "short"),
151 dry_run=False,
152 )
Lann Martin4fbdf202018-08-30 12:02:52 -0600153
Alex Klein1699fab2022-09-08 08:46:06 -0600154 def testGitPushProjectUpstreamDryRun(self):
155 """Test _GitPushProjectUpstream with dry_run=True."""
156 create_manifest_snapshot._GitPushProjectUpstream(
157 "root", self.project_b, True
158 )
159 self.mock_git_push.assert_called_with(
160 "root/project/b",
161 "cafe1234",
162 git.RemoteRef("origin", "short"),
163 dry_run=True,
164 )
Lann Martin4fbdf202018-08-30 12:02:52 -0600165
Alex Klein1699fab2022-09-08 08:46:06 -0600166 def testMainNoSnapshots(self):
167 """Test main with projects that don't need snapshots."""
168 self.mock_is_reachable.return_value = True
169 create_manifest_snapshot.main(self.main_args)
170 snapshot_xml = osutils.ReadFile(self.output_file)
171 self.AssertXMLAlmostEqual(snapshot_xml, MANIFEST_XML)
Lann Martin4fbdf202018-08-30 12:02:52 -0600172
Alex Klein1699fab2022-09-08 08:46:06 -0600173 def testMainSnapshots(self):
174 """Test main with projects that need snapshots."""
175 self.mock_is_reachable.return_value = False
176 args = self.main_args + ["--snapshot-ref", "refs/snap"]
177 with parallel_unittest.ParallelMock():
178 create_manifest_snapshot.main(args)
179 snapshot_xml = osutils.ReadFile(self.output_file)
Lann Martin4fbdf202018-08-30 12:02:52 -0600180
Alex Klein1699fab2022-09-08 08:46:06 -0600181 self.mock_git_push.assert_has_calls(
182 [
183 mock.call(
184 os.path.join(self.repo_root, "project/a"),
185 "f01dab1e",
186 git.RemoteRef("origin", "refs/snap"),
187 dry_run=False,
188 ),
189 mock.call(
190 os.path.join(self.repo_root, "project/b"),
191 "cafe1234",
192 git.RemoteRef("origin", "refs/snap"),
193 dry_run=False,
194 ),
195 mock.call(
196 os.path.join(self.repo_root, "project/c"),
197 "deadbeef",
198 git.RemoteRef("origin", "refs/snap"),
199 dry_run=False,
200 ),
201 mock.call(
202 os.path.join(self.repo_root, "dupe"),
203 "d1",
204 git.RemoteRef("origin", "refs/snap/dupe"),
205 dry_run=False,
206 ),
207 mock.call(
208 os.path.join(self.repo_root, "dupe"),
209 "d2",
210 git.RemoteRef("origin", "refs/snap/dupe/1"),
211 dry_run=False,
212 ),
213 ],
214 any_order=True,
215 )
Lann Martin4fbdf202018-08-30 12:02:52 -0600216
Alex Klein1699fab2022-09-08 08:46:06 -0600217 expected = repo_manifest.Manifest.FromString(MANIFEST_XML)
218 for project in expected.Projects():
219 if project.name == "dupe":
220 if project.revision == "d1":
221 project.upstream = "refs/snap/dupe"
222 else:
223 project.upstream = "refs/snap/dupe/1"
224 else:
225 project.upstream = "refs/snap"
226 expected_xml = repo_manifest_unittest.ManifestToString(expected)
227 self.AssertXMLAlmostEqual(snapshot_xml, expected_xml)
Lann Martin4fbdf202018-08-30 12:02:52 -0600228
Alex Klein1699fab2022-09-08 08:46:06 -0600229 def testMainNeedsSnapshotNoSnapshotRef(self):
230 """Test main with projects that need snapshots but no --snapshot-ref."""
231 self.mock_is_reachable.return_value = False
232 with self.assertRaises(SystemExit):
233 create_manifest_snapshot.main(self.main_args)