blob: 657bcf39676cbe38a498a2a9435afb8caa7cbf9e [file] [log] [blame]
Lann Martin4fbdf202018-08-30 12:02:52 -06001# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# 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
Lann Martin4fbdf202018-08-30 12:02:52 -060015from chromite.lib import repo_manifest
16from chromite.lib import repo_manifest_unittest
Mike Frysinger40ffb532021-02-12 07:36:08 -050017from chromite.lib import repo_util
Lann Martin4fbdf202018-08-30 12:02:52 -060018from chromite.scripts import create_manifest_snapshot
19
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
34class CreateManifestSnapshotTest(cros_test_lib.MockTempDirTestCase,
35 repo_manifest_unittest.XMLTestCase):
36 """Unit tests for create_manifest_snapshot."""
37
38 # pylint: disable=protected-access
39
40 def setUp(self):
41 self.manifest = repo_manifest.Manifest.FromString(MANIFEST_XML)
42 self.project_a = self.manifest.GetUniqueProject('project/a')
43 self.project_b = self.manifest.GetUniqueProject('project/b')
44 self.project_c = self.manifest.GetUniqueProject('project/c')
45 self.dupes = [x for x in self.manifest.Projects() if x.name == 'dupe']
46
47 self.mock_is_reachable = self.PatchObject(git, 'IsReachable')
48 self.mock_git_push = self.PatchObject(git, 'GitPush')
49
50 self.repo_root = os.path.join(self.tempdir, 'root')
51 os.makedirs(os.path.join(self.repo_root, '.repo'))
52 self.output_file = os.path.join(self.tempdir, 'snapshot.xml')
53 self.main_args = ['--repo-path', self.repo_root,
54 '--log-level', 'fatal',
55 '--jobs', '1',
56 '--output-file', self.output_file]
57 self.PatchObject(repo_util.Repository, 'Manifest',
58 return_value=self.manifest)
59
60 def testGetUpstreamBranchNoUpstream(self):
61 """Test _GetUpstreamBranch with no upstream."""
62 branch = create_manifest_snapshot._GetUpstreamBranch(self.project_a)
63 self.assertIsNone(branch)
64
65 def testGetUpstreamBranchShortUpstream(self):
66 """Test _GetUpstreamBranch with short upstream ref."""
67 branch = create_manifest_snapshot._GetUpstreamBranch(self.project_b)
68 self.assertEqual(branch, 'short')
69
70 def testGetUpstreamBranchFullUpstream(self):
71 """Test _GetUpstreamBranch with full upstream ref."""
72 branch = create_manifest_snapshot._GetUpstreamBranch(self.project_c)
Mike Frysinger6e3f23c2021-02-17 14:06:19 -050073 self.assertEqual(branch, 'main')
Lann Martin4fbdf202018-08-30 12:02:52 -060074
75 def testNeedsSnapshotReachable(self):
76 """Test _NeedsSnapshot with revision reachable from upstream."""
77 self.mock_is_reachable.return_value = True
78 result = create_manifest_snapshot._NeedsSnapshot('root', self.project_c)
79 self.assertFalse(result)
80 self.mock_is_reachable.assert_called_with(
Mike Frysinger6e3f23c2021-02-17 14:06:19 -050081 'root/project/c', 'deadbeef', 'refs/remotes/origin/main')
Lann Martin4fbdf202018-08-30 12:02:52 -060082
83 def testNeedsSnapshotUnreachable(self):
84 """Test _NeedsSnapshot with revision reachable from upstream."""
85 self.mock_is_reachable.return_value = False
86 result = create_manifest_snapshot._NeedsSnapshot('root', self.project_b)
87 self.assertTrue(result)
88 self.mock_is_reachable.assert_called_with(
89 'root/project/b', 'cafe1234', 'refs/remotes/origin/short')
90
91 def testNeedsSnapshotNoUpstream(self):
92 """Test _NeedsSnapshot with no project upstream."""
93 create_manifest_snapshot._NeedsSnapshot('root', self.project_a)
94 self.mock_is_reachable.assert_called_with(
Mike Frysinger6e3f23c2021-02-17 14:06:19 -050095 'root/project/a', 'f01dab1e', 'refs/remotes/origin/main')
Lann Martin4fbdf202018-08-30 12:02:52 -060096
97 def testNeedsSnapshotIsReachableFailure(self):
98 """Test _NeedsSnapshot with no project upstream."""
Mike Frysinger929f3ba2019-09-12 03:24:59 -040099 self.mock_is_reachable.side_effect = cros_build_lib.RunCommandError('')
Lann Martin4fbdf202018-08-30 12:02:52 -0600100 result = create_manifest_snapshot._NeedsSnapshot('root', self.project_a)
101 self.assertTrue(result)
102
Mike Frysinger6e3f23c2021-02-17 14:06:19 -0500103 def testMakeUniqueRefMain(self):
104 """Test _MakeUniqueRef with upstream main."""
Lann Martin4fbdf202018-08-30 12:02:52 -0600105 used = set()
106 ref1 = create_manifest_snapshot._MakeUniqueRef(self.project_c, 'base', used)
107 ref2 = create_manifest_snapshot._MakeUniqueRef(self.project_c, 'base', used)
108 ref3 = create_manifest_snapshot._MakeUniqueRef(self.project_c, 'base', used)
109 self.assertEqual(ref1, 'base')
110 self.assertEqual(ref2, 'base/1')
111 self.assertEqual(ref3, 'base/2')
112
Mike Frysinger6e3f23c2021-02-17 14:06:19 -0500113 def testMakeUniqueRefNonMain(self):
114 """Test _MakeUniqueRef with non-main upstream."""
Lann Martin4fbdf202018-08-30 12:02:52 -0600115 used = set()
116 ref1 = create_manifest_snapshot._MakeUniqueRef(self.project_b, 'base', used)
117 ref2 = create_manifest_snapshot._MakeUniqueRef(self.project_b, 'base', used)
118 self.assertEqual(ref1, 'base/short')
119 self.assertEqual(ref2, 'base/short/1')
120
121 def testGitPushProjectUpstream(self):
122 """Test _GitPushProjectUpstream."""
123 create_manifest_snapshot._GitPushProjectUpstream(
124 'root', self.project_b, False)
125 self.mock_git_push.assert_called_with(
126 'root/project/b', 'cafe1234', git.RemoteRef('origin', 'short'),
127 dry_run=False)
128
129 def testGitPushProjectUpstreamDryRun(self):
130 """Test _GitPushProjectUpstream with dry_run=True."""
131 create_manifest_snapshot._GitPushProjectUpstream(
132 'root', self.project_b, True)
133 self.mock_git_push.assert_called_with(
134 'root/project/b', 'cafe1234', git.RemoteRef('origin', 'short'),
135 dry_run=True)
136
137 def testMainNoSnapshots(self):
138 """Test main with projects that don't need snapshots."""
139 self.mock_is_reachable.return_value = True
140 create_manifest_snapshot.main(self.main_args)
141 snapshot_xml = osutils.ReadFile(self.output_file)
142 self.AssertXMLAlmostEqual(snapshot_xml, MANIFEST_XML)
143
144 def testMainSnapshots(self):
145 """Test main with projects that need snapshots."""
146 self.mock_is_reachable.return_value = False
147 args = self.main_args + ['--snapshot-ref', 'refs/snap']
148 with parallel_unittest.ParallelMock():
149 create_manifest_snapshot.main(args)
150 snapshot_xml = osutils.ReadFile(self.output_file)
151
152 self.mock_git_push.assert_has_calls([
153 mock.call(os.path.join(self.repo_root, 'project/a'),
154 'f01dab1e', git.RemoteRef('origin', 'refs/snap'),
155 dry_run=False),
156 mock.call(os.path.join(self.repo_root, 'project/b'),
157 'cafe1234', git.RemoteRef('origin', 'refs/snap'),
158 dry_run=False),
159 mock.call(os.path.join(self.repo_root, 'project/c'),
160 'deadbeef', git.RemoteRef('origin', 'refs/snap'),
161 dry_run=False),
162 mock.call(os.path.join(self.repo_root, 'dupe'),
163 'd1', git.RemoteRef('origin', 'refs/snap/dupe'),
164 dry_run=False),
165 mock.call(os.path.join(self.repo_root, 'dupe'),
166 'd2', git.RemoteRef('origin', 'refs/snap/dupe/1'),
167 dry_run=False),
168 ], any_order=True)
169
170 expected = repo_manifest.Manifest.FromString(MANIFEST_XML)
171 for project in expected.Projects():
172 if project.name == 'dupe':
173 if project.revision == 'd1':
174 project.upstream = 'refs/snap/dupe'
175 else:
176 project.upstream = 'refs/snap/dupe/1'
177 else:
178 project.upstream = 'refs/snap'
179 expected_xml = repo_manifest_unittest.ManifestToString(expected)
180 self.AssertXMLAlmostEqual(snapshot_xml, expected_xml)
181
182 def testMainNeedsSnapshotNoSnapshotRef(self):
183 """Test main with projects that need snapshots but no --snapshot-ref."""
184 self.mock_is_reachable.return_value = False
185 with self.assertRaises(SystemExit):
186 create_manifest_snapshot.main(self.main_args)