blob: ce4225366c02ce80a289c49c12afe65b189046a4 [file] [log] [blame]
Mike Frysinger04122b72019-07-31 23:32:58 -04001# Copyright (C) 2019 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Unittests for the manifest_xml.py module."""
16
Mike Frysingerd9254592020-02-19 22:36:26 -050017import os
Raman Tenneti080877e2021-03-09 15:19:06 -080018import platform
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +020019import re
Mike Frysinger8c1e9cb2020-09-06 14:53:18 -040020import shutil
21import tempfile
Mike Frysinger04122b72019-07-31 23:32:58 -040022import unittest
Mike Frysingerbb8ee7f2020-02-22 05:30:12 -050023import xml.dom.minidom
Mike Frysinger04122b72019-07-31 23:32:58 -040024
25import error
26import manifest_xml
27
28
Mike Frysingera29424e2021-02-25 21:53:49 -050029# Invalid paths that we don't want in the filesystem.
30INVALID_FS_PATHS = (
31 '',
32 '.',
33 '..',
34 '../',
35 './',
Mike Frysinger0458faa2021-03-10 23:35:44 -050036 './/',
Mike Frysingera29424e2021-02-25 21:53:49 -050037 'foo/',
38 './foo',
39 '../foo',
40 'foo/./bar',
41 'foo/../../bar',
42 '/foo',
43 './../foo',
44 '.git/foo',
45 # Check case folding.
46 '.GIT/foo',
47 'blah/.git/foo',
48 '.repo/foo',
49 '.repoconfig',
50 # Block ~ due to 8.3 filenames on Windows filesystems.
51 '~',
52 'foo~',
53 'blah/foo~',
54 # Block Unicode characters that get normalized out by filesystems.
55 u'foo\u200Cbar',
Mike Frysingerf69c7ee2021-04-29 23:15:31 -040056 # Block newlines.
57 'f\n/bar',
58 'f\r/bar',
Mike Frysingera29424e2021-02-25 21:53:49 -050059)
60
61# Make sure platforms that use path separators (e.g. Windows) are also
62# rejected properly.
63if os.path.sep != '/':
64 INVALID_FS_PATHS += tuple(x.replace('/', os.path.sep) for x in INVALID_FS_PATHS)
65
66
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +020067def sort_attributes(manifest):
68 """Sort the attributes of all elements alphabetically.
69
70 This is needed because different versions of the toxml() function from
71 xml.dom.minidom outputs the attributes of elements in different orders.
72 Before Python 3.8 they were output alphabetically, later versions preserve
73 the order specified by the user.
74
75 Args:
76 manifest: String containing an XML manifest.
77
78 Returns:
79 The XML manifest with the attributes of all elements sorted alphabetically.
80 """
81 new_manifest = ''
82 # This will find every element in the XML manifest, whether they have
83 # attributes or not. This simplifies recreating the manifest below.
84 matches = re.findall(r'(<[/?]?[a-z-]+\s*)((?:\S+?="[^"]+"\s*?)*)(\s*[/?]?>)', manifest)
85 for head, attrs, tail in matches:
86 m = re.findall(r'\S+?="[^"]+"', attrs)
87 new_manifest += head + ' '.join(sorted(m)) + tail
88 return new_manifest
89
90
Mike Frysinger37ac3d62021-02-25 04:54:56 -050091class ManifestParseTestCase(unittest.TestCase):
92 """TestCase for parsing manifests."""
93
94 def setUp(self):
95 self.tempdir = tempfile.mkdtemp(prefix='repo_tests')
96 self.repodir = os.path.join(self.tempdir, '.repo')
97 self.manifest_dir = os.path.join(self.repodir, 'manifests')
98 self.manifest_file = os.path.join(
99 self.repodir, manifest_xml.MANIFEST_FILE_NAME)
100 self.local_manifest_dir = os.path.join(
101 self.repodir, manifest_xml.LOCAL_MANIFESTS_DIR_NAME)
102 os.mkdir(self.repodir)
103 os.mkdir(self.manifest_dir)
104
105 # The manifest parsing really wants a git repo currently.
106 gitdir = os.path.join(self.repodir, 'manifests.git')
107 os.mkdir(gitdir)
108 with open(os.path.join(gitdir, 'config'), 'w') as fp:
109 fp.write("""[remote "origin"]
110 url = https://localhost:0/manifest
111""")
112
113 def tearDown(self):
114 shutil.rmtree(self.tempdir, ignore_errors=True)
115
116 def getXmlManifest(self, data):
117 """Helper to initialize a manifest for testing."""
118 with open(self.manifest_file, 'w') as fp:
119 fp.write(data)
120 return manifest_xml.XmlManifest(self.repodir, self.manifest_file)
121
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400122 @staticmethod
123 def encodeXmlAttr(attr):
124 """Encode |attr| using XML escape rules."""
125 return attr.replace('\r', ' ').replace('\n', ' ')
126
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500127
Mike Frysinger04122b72019-07-31 23:32:58 -0400128class ManifestValidateFilePaths(unittest.TestCase):
129 """Check _ValidateFilePaths helper.
130
131 This doesn't access a real filesystem.
132 """
133
134 def check_both(self, *args):
135 manifest_xml.XmlManifest._ValidateFilePaths('copyfile', *args)
136 manifest_xml.XmlManifest._ValidateFilePaths('linkfile', *args)
137
138 def test_normal_path(self):
139 """Make sure good paths are accepted."""
140 self.check_both('foo', 'bar')
141 self.check_both('foo/bar', 'bar')
142 self.check_both('foo', 'bar/bar')
143 self.check_both('foo/bar', 'bar/bar')
144
145 def test_symlink_targets(self):
146 """Some extra checks for symlinks."""
147 def check(*args):
148 manifest_xml.XmlManifest._ValidateFilePaths('linkfile', *args)
149
150 # We allow symlinks to end in a slash since we allow them to point to dirs
151 # in general. Technically the slash isn't necessary.
152 check('foo/', 'bar')
Mike Frysingerae625412020-02-10 17:10:03 -0500153 # We allow a single '.' to get a reference to the project itself.
154 check('.', 'bar')
Mike Frysinger04122b72019-07-31 23:32:58 -0400155
156 def test_bad_paths(self):
157 """Make sure bad paths (src & dest) are rejected."""
Mike Frysingera29424e2021-02-25 21:53:49 -0500158 for path in INVALID_FS_PATHS:
Mike Frysinger04122b72019-07-31 23:32:58 -0400159 self.assertRaises(
160 error.ManifestInvalidPathError, self.check_both, path, 'a')
161 self.assertRaises(
162 error.ManifestInvalidPathError, self.check_both, 'a', path)
Mike Frysingerbb8ee7f2020-02-22 05:30:12 -0500163
164
165class ValueTests(unittest.TestCase):
166 """Check utility parsing code."""
167
168 def _get_node(self, text):
169 return xml.dom.minidom.parseString(text).firstChild
170
171 def test_bool_default(self):
172 """Check XmlBool default handling."""
173 node = self._get_node('')
174 self.assertIsNone(manifest_xml.XmlBool(node, 'a'))
175 self.assertIsNone(manifest_xml.XmlBool(node, 'a', None))
176 self.assertEqual(123, manifest_xml.XmlBool(node, 'a', 123))
177
178 node = self._get_node('')
179 self.assertIsNone(manifest_xml.XmlBool(node, 'a'))
180
181 def test_bool_invalid(self):
182 """Check XmlBool invalid handling."""
183 node = self._get_node('')
184 self.assertEqual(123, manifest_xml.XmlBool(node, 'a', 123))
185
186 def test_bool_true(self):
187 """Check XmlBool true values."""
188 for value in ('yes', 'true', '1'):
189 node = self._get_node('' % (value,))
190 self.assertTrue(manifest_xml.XmlBool(node, 'a'))
191
192 def test_bool_false(self):
193 """Check XmlBool false values."""
194 for value in ('no', 'false', '0'):
195 node = self._get_node('' % (value,))
196 self.assertFalse(manifest_xml.XmlBool(node, 'a'))
197
198 def test_int_default(self):
199 """Check XmlInt default handling."""
200 node = self._get_node('')
201 self.assertIsNone(manifest_xml.XmlInt(node, 'a'))
202 self.assertIsNone(manifest_xml.XmlInt(node, 'a', None))
203 self.assertEqual(123, manifest_xml.XmlInt(node, 'a', 123))
204
205 node = self._get_node('')
206 self.assertIsNone(manifest_xml.XmlInt(node, 'a'))
207
208 def test_int_good(self):
209 """Check XmlInt numeric handling."""
210 for value in (-1, 0, 1, 50000):
211 node = self._get_node('' % (value,))
212 self.assertEqual(value, manifest_xml.XmlInt(node, 'a'))
213
214 def test_int_invalid(self):
215 """Check XmlInt invalid handling."""
216 with self.assertRaises(error.ManifestParseError):
217 node = self._get_node('')
218 manifest_xml.XmlInt(node, 'a')
Mike Frysinger8c1e9cb2020-09-06 14:53:18 -0400219
220
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500221class XmlManifestTests(ManifestParseTestCase):
Mike Frysinger8c1e9cb2020-09-06 14:53:18 -0400222 """Check manifest processing."""
223
Mike Frysinger8c1e9cb2020-09-06 14:53:18 -0400224 def test_empty(self):
225 """Parse an 'empty' manifest file."""
226 manifest = self.getXmlManifest(
227 ''
228 '')
229 self.assertEqual(manifest.remotes, {})
230 self.assertEqual(manifest.projects, [])
231
232 def test_link(self):
233 """Verify Link handling with new names."""
234 manifest = manifest_xml.XmlManifest(self.repodir, self.manifest_file)
235 with open(os.path.join(self.manifest_dir, 'foo.xml'), 'w') as fp:
236 fp.write('')
237 manifest.Link('foo.xml')
238 with open(self.manifest_file) as fp:
239 self.assertIn('', fp.read())
240
241 def test_toxml_empty(self):
242 """Verify the ToXml() helper."""
243 manifest = self.getXmlManifest(
244 ''
245 '')
246 self.assertEqual(manifest.ToXml().toxml(), '')
247
248 def test_todict_empty(self):
249 """Verify the ToDict() helper."""
250 manifest = self.getXmlManifest(
251 ''
252 '')
253 self.assertEqual(manifest.ToDict(), {})
254
Mike Frysinger51e39d52020-12-04 05:32:06 -0500255 def test_repo_hooks(self):
256 """Check repo-hooks settings."""
257 manifest = self.getXmlManifest("""
258
259
260
261
262
263
264""")
265 self.assertEqual(manifest.repo_hooks_project.name, 'repohooks')
266 self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b'])
267
Jack Neusa84f43a2021-09-21 22:23:55 +0000268 def test_repo_hooks_unordered(self):
269 """Check repo-hooks settings work even if the project def comes second."""
270 manifest = self.getXmlManifest("""
271
272
273
274
275
276
277""")
278 self.assertEqual(manifest.repo_hooks_project.name, 'repohooks')
279 self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b'])
280
Raman Tenneti48b2d102021-01-11 12:18:47 -0800281 def test_unknown_tags(self):
282 """Check superproject settings."""
283 manifest = self.getXmlManifest("""
284
285
286
287
288
289 X tags are always ignored
290
291""")
292 self.assertEqual(manifest.superproject['name'], 'superproject')
293 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
294 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200295 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700296 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200297 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700298 ''
299 ''
Raman Tenneti48b2d102021-01-11 12:18:47 -0800300 '')
301
Jack Neus6ea0cae2021-07-20 20:52:33 +0000302 def test_remote_annotations(self):
303 """Check remote settings."""
304 manifest = self.getXmlManifest("""
305
306
307
308
309
310""")
311 self.assertEqual(manifest.remotes['test-remote'].annotations[0].name, 'foo')
312 self.assertEqual(manifest.remotes['test-remote'].annotations[0].value, 'bar')
313 self.assertEqual(
314 sort_attributes(manifest.ToXml().toxml()),
315 ''
316 ''
317 ''
318 ''
319 '')
320
Fredrik de Groot352c93b2020-10-06 12:55:14 +0200321
Mike Frysingera29424e2021-02-25 21:53:49 -0500322class IncludeElementTests(ManifestParseTestCase):
323 """Tests for ."""
Raman Tennetib5c5a5e2021-02-06 09:44:15 -0800324
Mike Frysingera29424e2021-02-25 21:53:49 -0500325 def test_group_levels(self):
Fredrik de Groot352c93b2020-10-06 12:55:14 +0200326 root_m = os.path.join(self.manifest_dir, 'root.xml')
327 with open(root_m, 'w') as fp:
328 fp.write("""
329
330
331
332
333
334
335
336""")
337 with open(os.path.join(self.manifest_dir, 'level1.xml'), 'w') as fp:
338 fp.write("""
339
340
341
342
343""")
344 with open(os.path.join(self.manifest_dir, 'level2.xml'), 'w') as fp:
345 fp.write("""
346
347
348
349""")
350 include_m = manifest_xml.XmlManifest(self.repodir, root_m)
351 for proj in include_m.projects:
352 if proj.name == 'root-name1':
353 # Check include group not set on root level proj.
354 self.assertNotIn('level1-group', proj.groups)
355 if proj.name == 'root-name2':
356 # Check root proj group not removed.
357 self.assertIn('r2g1', proj.groups)
358 if proj.name == 'level1-name1':
359 # Check level1 proj has inherited group level 1.
360 self.assertIn('level1-group', proj.groups)
361 if proj.name == 'level2-name1':
362 # Check level2 proj has inherited group levels 1 and 2.
363 self.assertIn('level1-group', proj.groups)
364 self.assertIn('level2-group', proj.groups)
365 # Check level2 proj group not removed.
366 self.assertIn('l2g1', proj.groups)
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500367
Mike Frysinger54133972021-03-01 21:38:08 -0500368 def test_allow_bad_name_from_user(self):
369 """Check handling of bad name attribute from the user's input."""
Mike Frysingera29424e2021-02-25 21:53:49 -0500370 def parse(name):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400371 name = self.encodeXmlAttr(name)
Mike Frysingera29424e2021-02-25 21:53:49 -0500372 manifest = self.getXmlManifest(f"""
373
374
375
376
377
378""")
379 # Force the manifest to be parsed.
380 manifest.ToXml()
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500381
Mike Frysinger54133972021-03-01 21:38:08 -0500382 # Setup target of the include.
383 target = os.path.join(self.tempdir, 'target.xml')
384 with open(target, 'w') as fp:
385 fp.write('')
386
387 # Include with absolute path.
388 parse(os.path.abspath(target))
389
390 # Include with relative path.
391 parse(os.path.relpath(target, self.manifest_dir))
392
393 def test_bad_name_checks(self):
394 """Check handling of bad name attribute."""
395 def parse(name):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400396 name = self.encodeXmlAttr(name)
Mike Frysinger54133972021-03-01 21:38:08 -0500397 # Setup target of the include.
398 with open(os.path.join(self.manifest_dir, 'target.xml'), 'w') as fp:
399 fp.write(f'')
400
401 manifest = self.getXmlManifest("""
402
403
404
405
406
407""")
408 # Force the manifest to be parsed.
409 manifest.ToXml()
410
Mike Frysingera29424e2021-02-25 21:53:49 -0500411 # Handle empty name explicitly because a different codepath rejects it.
412 with self.assertRaises(error.ManifestParseError):
413 parse('')
414
415 for path in INVALID_FS_PATHS:
416 if not path:
417 continue
418
419 with self.assertRaises(error.ManifestInvalidPathError):
420 parse(path)
421
422
423class ProjectElementTests(ManifestParseTestCase):
424 """Tests for ."""
425
426 def test_group(self):
427 """Check project group settings."""
428 manifest = self.getXmlManifest("""
429
430
431
432
433
434
435""")
436 self.assertEqual(len(manifest.projects), 2)
437 # Ordering isn't guaranteed.
438 result = {
439 manifest.projects[0].name: manifest.projects[0].groups,
440 manifest.projects[1].name: manifest.projects[1].groups,
441 }
442 project = manifest.projects[0]
443 self.assertCountEqual(
444 result['test-name'],
445 ['name:test-name', 'all', 'path:test-path'])
446 self.assertCountEqual(
447 result['extras'],
448 ['g1', 'g2', 'g1', 'name:extras', 'all', 'path:path'])
Raman Tenneti080877e2021-03-09 15:19:06 -0800449 groupstr = 'default,platform-' + platform.system().lower()
450 self.assertEqual(groupstr, manifest.GetGroupsStr())
451 groupstr = 'g1,g2,g1'
452 manifest.manifestProject.config.SetString('manifest.groups', groupstr)
453 self.assertEqual(groupstr, manifest.GetGroupsStr())
Mike Frysingera29424e2021-02-25 21:53:49 -0500454
455 def test_set_revision_id(self):
456 """Check setting of project's revisionId."""
457 manifest = self.getXmlManifest("""
458
459
460
461
462
463""")
464 self.assertEqual(len(manifest.projects), 1)
465 project = manifest.projects[0]
466 project.SetRevisionId('ABCDEF')
467 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200468 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700469 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200470 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700471 ''
Xin Li0e776a52021-06-29 21:42:34 +0000472 ''
Mike Frysingera29424e2021-02-25 21:53:49 -0500473 '')
474
475 def test_trailing_slash(self):
476 """Check handling of trailing slashes in attributes."""
477 def parse(name, path):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400478 name = self.encodeXmlAttr(name)
479 path = self.encodeXmlAttr(path)
Mike Frysingera29424e2021-02-25 21:53:49 -0500480 return self.getXmlManifest(f"""
481
482
483
484
485
486""")
487
488 manifest = parse('a/path/', 'foo')
489 self.assertEqual(manifest.projects[0].gitdir,
490 os.path.join(self.tempdir, '.repo/projects/foo.git'))
491 self.assertEqual(manifest.projects[0].objdir,
492 os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
493
494 manifest = parse('a/path', 'foo/')
495 self.assertEqual(manifest.projects[0].gitdir,
496 os.path.join(self.tempdir, '.repo/projects/foo.git'))
497 self.assertEqual(manifest.projects[0].objdir,
498 os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
499
Mike Frysinger0458faa2021-03-10 23:35:44 -0500500 manifest = parse('a/path', 'foo//////')
501 self.assertEqual(manifest.projects[0].gitdir,
502 os.path.join(self.tempdir, '.repo/projects/foo.git'))
503 self.assertEqual(manifest.projects[0].objdir,
504 os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
505
506 def test_toplevel_path(self):
507 """Check handling of path=. specially."""
508 def parse(name, path):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400509 name = self.encodeXmlAttr(name)
510 path = self.encodeXmlAttr(path)
Mike Frysinger0458faa2021-03-10 23:35:44 -0500511 return self.getXmlManifest(f"""
512
513
514
515
516
517""")
518
519 for path in ('.', './', './/', './//'):
520 manifest = parse('server/path', path)
521 self.assertEqual(manifest.projects[0].gitdir,
522 os.path.join(self.tempdir, '.repo/projects/..git'))
523
Mike Frysingera29424e2021-02-25 21:53:49 -0500524 def test_bad_path_name_checks(self):
525 """Check handling of bad path & name attributes."""
526 def parse(name, path):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400527 name = self.encodeXmlAttr(name)
528 path = self.encodeXmlAttr(path)
Mike Frysingera29424e2021-02-25 21:53:49 -0500529 manifest = self.getXmlManifest(f"""
530
531
532
533
534
535""")
536 # Force the manifest to be parsed.
537 manifest.ToXml()
538
539 # Verify the parser is valid by default to avoid buggy tests below.
540 parse('ok', 'ok')
541
542 # Handle empty name explicitly because a different codepath rejects it.
543 # Empty path is OK because it defaults to the name field.
544 with self.assertRaises(error.ManifestParseError):
545 parse('', 'ok')
546
547 for path in INVALID_FS_PATHS:
548 if not path or path.endswith('/'):
549 continue
550
551 with self.assertRaises(error.ManifestInvalidPathError):
552 parse(path, 'ok')
Mike Frysinger0458faa2021-03-10 23:35:44 -0500553
554 # We have a dedicated test for path=".".
555 if path not in {'.'}:
556 with self.assertRaises(error.ManifestInvalidPathError):
557 parse('ok', path)
Mike Frysingera29424e2021-02-25 21:53:49 -0500558
559
560class SuperProjectElementTests(ManifestParseTestCase):
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500561 """Tests for ."""
562
563 def test_superproject(self):
564 """Check superproject settings."""
565 manifest = self.getXmlManifest("""
566
567
568
569
570
571""")
572 self.assertEqual(manifest.superproject['name'], 'superproject')
573 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
574 self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject')
Xin Lie0b16a22021-09-26 23:20:32 -0700575 self.assertEqual(manifest.superproject['revision'], 'refs/heads/main')
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500576 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200577 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700578 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200579 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700580 ''
581 ''
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500582 '')
583
Xin Lie0b16a22021-09-26 23:20:32 -0700584 def test_superproject_revision(self):
585 """Check superproject settings with a different revision attribute"""
586 self.maxDiff = None
587 manifest = self.getXmlManifest("""
588
589
590
591
592
593""")
594 self.assertEqual(manifest.superproject['name'], 'superproject')
595 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
596 self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject')
597 self.assertEqual(manifest.superproject['revision'], 'refs/heads/stable')
598 self.assertEqual(
599 sort_attributes(manifest.ToXml().toxml()),
600 ''
601 ''
602 ''
603 ''
604 '')
605
606 def test_superproject_revision_default_negative(self):
607 """Check superproject settings with a same revision attribute"""
608 self.maxDiff = None
609 manifest = self.getXmlManifest("""
610
611
612
613
614
615""")
616 self.assertEqual(manifest.superproject['name'], 'superproject')
617 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
618 self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject')
619 self.assertEqual(manifest.superproject['revision'], 'refs/heads/stable')
620 self.assertEqual(
621 sort_attributes(manifest.ToXml().toxml()),
622 ''
623 ''
624 ''
625 ''
626 '')
627
628 def test_superproject_revision_remote(self):
629 """Check superproject settings with a same revision attribute"""
630 self.maxDiff = None
631 manifest = self.getXmlManifest("""
632
633
634
635
636
637""")
638 self.assertEqual(manifest.superproject['name'], 'superproject')
639 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
640 self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject')
641 self.assertEqual(manifest.superproject['revision'], 'refs/heads/stable')
642 self.assertEqual(
643 sort_attributes(manifest.ToXml().toxml()),
644 ''
645 ''
646 ''
647 ''
648 '')
649
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500650 def test_remote(self):
651 """Check superproject settings with a remote."""
652 manifest = self.getXmlManifest("""
653
654
655
656
657
658
659""")
660 self.assertEqual(manifest.superproject['name'], 'platform/superproject')
661 self.assertEqual(manifest.superproject['remote'].name, 'superproject-remote')
662 self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/platform/superproject')
Xin Lie0b16a22021-09-26 23:20:32 -0700663 self.assertEqual(manifest.superproject['revision'], 'refs/heads/main')
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500664 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200665 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700666 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200667 ''
668 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700669 ''
670 ''
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500671 '')
672
673 def test_defalut_remote(self):
674 """Check superproject settings with a default remote."""
675 manifest = self.getXmlManifest("""
676
677
678
679
680
681""")
682 self.assertEqual(manifest.superproject['name'], 'superproject')
683 self.assertEqual(manifest.superproject['remote'].name, 'default-remote')
Xin Lie0b16a22021-09-26 23:20:32 -0700684 self.assertEqual(manifest.superproject['revision'], 'refs/heads/main')
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500685 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200686 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700687 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200688 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700689 ''
690 ''
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500691 '')
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700692
693
694class ContactinfoElementTests(ManifestParseTestCase):
695 """Tests for ."""
696
697 def test_contactinfo(self):
698 """Check contactinfo settings."""
699 bugurl = 'http://localhost/contactinfo'
700 manifest = self.getXmlManifest(f"""
701
702
703
704""")
Raman Tenneti993af5e2021-05-12 12:00:31 -0700705 self.assertEqual(manifest.contactinfo.bugurl, bugurl)
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700706 self.assertEqual(
707 manifest.ToXml().toxml(),
Raman Tenneti2f8fdbe2021-05-04 18:54:52 -0700708 ''
709 f''
710 '')
Jack Neus5ba21202021-06-09 15:21:25 +0000711
712
713class DefaultElementTests(ManifestParseTestCase):
714 """Tests for ."""
715
716 def test_default(self):
717 """Check default settings."""
718 a = manifest_xml._Default()
719 a.revisionExpr = 'foo'
720 a.remote = manifest_xml._XmlRemote(name='remote')
721 b = manifest_xml._Default()
722 b.revisionExpr = 'bar'
723 self.assertEqual(a, a)
724 self.assertNotEqual(a, b)
725 self.assertNotEqual(b, a.remote)
726 self.assertNotEqual(a, 123)
727 self.assertNotEqual(a, None)
728
729
730class RemoteElementTests(ManifestParseTestCase):
731 """Tests for ."""
732
733 def test_remote(self):
734 """Check remote settings."""
735 a = manifest_xml._XmlRemote(name='foo')
Jack Neus6ea0cae2021-07-20 20:52:33 +0000736 a.AddAnnotation('key1', 'value1', 'true')
737 b = manifest_xml._XmlRemote(name='foo')
738 b.AddAnnotation('key2', 'value1', 'true')
739 c = manifest_xml._XmlRemote(name='foo')
740 c.AddAnnotation('key1', 'value2', 'true')
741 d = manifest_xml._XmlRemote(name='foo')
742 d.AddAnnotation('key1', 'value1', 'false')
Jack Neus5ba21202021-06-09 15:21:25 +0000743 self.assertEqual(a, a)
744 self.assertNotEqual(a, b)
Jack Neus6ea0cae2021-07-20 20:52:33 +0000745 self.assertNotEqual(a, c)
746 self.assertNotEqual(a, d)
Jack Neus5ba21202021-06-09 15:21:25 +0000747 self.assertNotEqual(a, manifest_xml._Default())
748 self.assertNotEqual(a, 123)
749 self.assertNotEqual(a, None)
Michael Kelly06da9982021-06-30 01:58:28 -0700750
751
752class RemoveProjectElementTests(ManifestParseTestCase):
753 """Tests for ."""
754
755 def test_remove_one_project(self):
756 manifest = self.getXmlManifest("""
757
758
759
760
761
762
763""")
764 self.assertEqual(manifest.projects, [])
765
766 def test_remove_one_project_one_remains(self):
767 manifest = self.getXmlManifest("""
768
769
770
771
772
773
774
775""")
776
777 self.assertEqual(len(manifest.projects), 1)
778 self.assertEqual(manifest.projects[0].name, 'yourproject')
779
780 def test_remove_one_project_doesnt_exist(self):
781 with self.assertRaises(manifest_xml.ManifestParseError):
782 manifest = self.getXmlManifest("""
783
784
785
786
787
788""")
789 manifest.projects
790
791 def test_remove_one_optional_project_doesnt_exist(self):
792 manifest = self.getXmlManifest("""
793
794
795
796
797
798""")
799 self.assertEqual(manifest.projects, [])