blob: 59f2a779429f34e9900766f206bfe9b68e4ba628 [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
Raman Tenneti48b2d102021-01-11 12:18:47 -0800268 def test_unknown_tags(self):
269 """Check superproject settings."""
270 manifest = self.getXmlManifest("""
271
272
273
274
275
276 X tags are always ignored
277
278""")
279 self.assertEqual(manifest.superproject['name'], 'superproject')
280 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
281 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200282 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700283 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200284 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700285 ''
286 ''
Raman Tenneti48b2d102021-01-11 12:18:47 -0800287 '')
288
Jack Neus6ea0cae2021-07-20 20:52:33 +0000289 def test_remote_annotations(self):
290 """Check remote settings."""
291 manifest = self.getXmlManifest("""
292
293
294
295
296
297""")
298 self.assertEqual(manifest.remotes['test-remote'].annotations[0].name, 'foo')
299 self.assertEqual(manifest.remotes['test-remote'].annotations[0].value, 'bar')
300 self.assertEqual(
301 sort_attributes(manifest.ToXml().toxml()),
302 ''
303 ''
304 ''
305 ''
306 '')
307
Fredrik de Groot352c93b2020-10-06 12:55:14 +0200308
Mike Frysingera29424e2021-02-25 21:53:49 -0500309class IncludeElementTests(ManifestParseTestCase):
310 """Tests for ."""
Raman Tennetib5c5a5e2021-02-06 09:44:15 -0800311
Mike Frysingera29424e2021-02-25 21:53:49 -0500312 def test_group_levels(self):
Fredrik de Groot352c93b2020-10-06 12:55:14 +0200313 root_m = os.path.join(self.manifest_dir, 'root.xml')
314 with open(root_m, 'w') as fp:
315 fp.write("""
316
317
318
319
320
321
322
323""")
324 with open(os.path.join(self.manifest_dir, 'level1.xml'), 'w') as fp:
325 fp.write("""
326
327
328
329
330""")
331 with open(os.path.join(self.manifest_dir, 'level2.xml'), 'w') as fp:
332 fp.write("""
333
334
335
336""")
337 include_m = manifest_xml.XmlManifest(self.repodir, root_m)
338 for proj in include_m.projects:
339 if proj.name == 'root-name1':
340 # Check include group not set on root level proj.
341 self.assertNotIn('level1-group', proj.groups)
342 if proj.name == 'root-name2':
343 # Check root proj group not removed.
344 self.assertIn('r2g1', proj.groups)
345 if proj.name == 'level1-name1':
346 # Check level1 proj has inherited group level 1.
347 self.assertIn('level1-group', proj.groups)
348 if proj.name == 'level2-name1':
349 # Check level2 proj has inherited group levels 1 and 2.
350 self.assertIn('level1-group', proj.groups)
351 self.assertIn('level2-group', proj.groups)
352 # Check level2 proj group not removed.
353 self.assertIn('l2g1', proj.groups)
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500354
Mike Frysinger54133972021-03-01 21:38:08 -0500355 def test_allow_bad_name_from_user(self):
356 """Check handling of bad name attribute from the user's input."""
Mike Frysingera29424e2021-02-25 21:53:49 -0500357 def parse(name):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400358 name = self.encodeXmlAttr(name)
Mike Frysingera29424e2021-02-25 21:53:49 -0500359 manifest = self.getXmlManifest(f"""
360
361
362
363
364
365""")
366 # Force the manifest to be parsed.
367 manifest.ToXml()
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500368
Mike Frysinger54133972021-03-01 21:38:08 -0500369 # Setup target of the include.
370 target = os.path.join(self.tempdir, 'target.xml')
371 with open(target, 'w') as fp:
372 fp.write('')
373
374 # Include with absolute path.
375 parse(os.path.abspath(target))
376
377 # Include with relative path.
378 parse(os.path.relpath(target, self.manifest_dir))
379
380 def test_bad_name_checks(self):
381 """Check handling of bad name attribute."""
382 def parse(name):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400383 name = self.encodeXmlAttr(name)
Mike Frysinger54133972021-03-01 21:38:08 -0500384 # Setup target of the include.
385 with open(os.path.join(self.manifest_dir, 'target.xml'), 'w') as fp:
386 fp.write(f'')
387
388 manifest = self.getXmlManifest("""
389
390
391
392
393
394""")
395 # Force the manifest to be parsed.
396 manifest.ToXml()
397
Mike Frysingera29424e2021-02-25 21:53:49 -0500398 # Handle empty name explicitly because a different codepath rejects it.
399 with self.assertRaises(error.ManifestParseError):
400 parse('')
401
402 for path in INVALID_FS_PATHS:
403 if not path:
404 continue
405
406 with self.assertRaises(error.ManifestInvalidPathError):
407 parse(path)
408
409
410class ProjectElementTests(ManifestParseTestCase):
411 """Tests for ."""
412
413 def test_group(self):
414 """Check project group settings."""
415 manifest = self.getXmlManifest("""
416
417
418
419
420
421
422""")
423 self.assertEqual(len(manifest.projects), 2)
424 # Ordering isn't guaranteed.
425 result = {
426 manifest.projects[0].name: manifest.projects[0].groups,
427 manifest.projects[1].name: manifest.projects[1].groups,
428 }
429 project = manifest.projects[0]
430 self.assertCountEqual(
431 result['test-name'],
432 ['name:test-name', 'all', 'path:test-path'])
433 self.assertCountEqual(
434 result['extras'],
435 ['g1', 'g2', 'g1', 'name:extras', 'all', 'path:path'])
Raman Tenneti080877e2021-03-09 15:19:06 -0800436 groupstr = 'default,platform-' + platform.system().lower()
437 self.assertEqual(groupstr, manifest.GetGroupsStr())
438 groupstr = 'g1,g2,g1'
439 manifest.manifestProject.config.SetString('manifest.groups', groupstr)
440 self.assertEqual(groupstr, manifest.GetGroupsStr())
Mike Frysingera29424e2021-02-25 21:53:49 -0500441
442 def test_set_revision_id(self):
443 """Check setting of project's revisionId."""
444 manifest = self.getXmlManifest("""
445
446
447
448
449
450""")
451 self.assertEqual(len(manifest.projects), 1)
452 project = manifest.projects[0]
453 project.SetRevisionId('ABCDEF')
454 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200455 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700456 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200457 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700458 ''
Xin Li0e776a52021-06-29 21:42:34 +0000459 ''
Mike Frysingera29424e2021-02-25 21:53:49 -0500460 '')
461
462 def test_trailing_slash(self):
463 """Check handling of trailing slashes in attributes."""
464 def parse(name, path):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400465 name = self.encodeXmlAttr(name)
466 path = self.encodeXmlAttr(path)
Mike Frysingera29424e2021-02-25 21:53:49 -0500467 return self.getXmlManifest(f"""
468
469
470
471
472
473""")
474
475 manifest = parse('a/path/', 'foo')
476 self.assertEqual(manifest.projects[0].gitdir,
477 os.path.join(self.tempdir, '.repo/projects/foo.git'))
478 self.assertEqual(manifest.projects[0].objdir,
479 os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
480
481 manifest = parse('a/path', 'foo/')
482 self.assertEqual(manifest.projects[0].gitdir,
483 os.path.join(self.tempdir, '.repo/projects/foo.git'))
484 self.assertEqual(manifest.projects[0].objdir,
485 os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
486
Mike Frysinger0458faa2021-03-10 23:35:44 -0500487 manifest = parse('a/path', 'foo//////')
488 self.assertEqual(manifest.projects[0].gitdir,
489 os.path.join(self.tempdir, '.repo/projects/foo.git'))
490 self.assertEqual(manifest.projects[0].objdir,
491 os.path.join(self.tempdir, '.repo/project-objects/a/path.git'))
492
493 def test_toplevel_path(self):
494 """Check handling of path=. specially."""
495 def parse(name, path):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400496 name = self.encodeXmlAttr(name)
497 path = self.encodeXmlAttr(path)
Mike Frysinger0458faa2021-03-10 23:35:44 -0500498 return self.getXmlManifest(f"""
499
500
501
502
503
504""")
505
506 for path in ('.', './', './/', './//'):
507 manifest = parse('server/path', path)
508 self.assertEqual(manifest.projects[0].gitdir,
509 os.path.join(self.tempdir, '.repo/projects/..git'))
510
Mike Frysingera29424e2021-02-25 21:53:49 -0500511 def test_bad_path_name_checks(self):
512 """Check handling of bad path & name attributes."""
513 def parse(name, path):
Mike Frysingerf69c7ee2021-04-29 23:15:31 -0400514 name = self.encodeXmlAttr(name)
515 path = self.encodeXmlAttr(path)
Mike Frysingera29424e2021-02-25 21:53:49 -0500516 manifest = self.getXmlManifest(f"""
517
518
519
520
521
522""")
523 # Force the manifest to be parsed.
524 manifest.ToXml()
525
526 # Verify the parser is valid by default to avoid buggy tests below.
527 parse('ok', 'ok')
528
529 # Handle empty name explicitly because a different codepath rejects it.
530 # Empty path is OK because it defaults to the name field.
531 with self.assertRaises(error.ManifestParseError):
532 parse('', 'ok')
533
534 for path in INVALID_FS_PATHS:
535 if not path or path.endswith('/'):
536 continue
537
538 with self.assertRaises(error.ManifestInvalidPathError):
539 parse(path, 'ok')
Mike Frysinger0458faa2021-03-10 23:35:44 -0500540
541 # We have a dedicated test for path=".".
542 if path not in {'.'}:
543 with self.assertRaises(error.ManifestInvalidPathError):
544 parse('ok', path)
Mike Frysingera29424e2021-02-25 21:53:49 -0500545
546
547class SuperProjectElementTests(ManifestParseTestCase):
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500548 """Tests for ."""
549
550 def test_superproject(self):
551 """Check superproject settings."""
552 manifest = self.getXmlManifest("""
553
554
555
556
557
558""")
559 self.assertEqual(manifest.superproject['name'], 'superproject')
560 self.assertEqual(manifest.superproject['remote'].name, 'test-remote')
561 self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject')
562 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200563 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700564 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200565 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700566 ''
567 ''
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500568 '')
569
570 def test_remote(self):
571 """Check superproject settings with a remote."""
572 manifest = self.getXmlManifest("""
573
574
575
576
577
578
579""")
580 self.assertEqual(manifest.superproject['name'], 'platform/superproject')
581 self.assertEqual(manifest.superproject['remote'].name, 'superproject-remote')
582 self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/platform/superproject')
583 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200584 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700585 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200586 ''
587 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700588 ''
589 ''
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500590 '')
591
592 def test_defalut_remote(self):
593 """Check superproject settings with a default remote."""
594 manifest = self.getXmlManifest("""
595
596
597
598
599
600""")
601 self.assertEqual(manifest.superproject['name'], 'superproject')
602 self.assertEqual(manifest.superproject['remote'].name, 'default-remote')
603 self.assertEqual(
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200604 sort_attributes(manifest.ToXml().toxml()),
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700605 ''
Peter Kjellerstedt5d58c182021-04-12 21:16:36 +0200606 ''
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700607 ''
608 ''
Mike Frysinger37ac3d62021-02-25 04:54:56 -0500609 '')
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700610
611
612class ContactinfoElementTests(ManifestParseTestCase):
613 """Tests for ."""
614
615 def test_contactinfo(self):
616 """Check contactinfo settings."""
617 bugurl = 'http://localhost/contactinfo'
618 manifest = self.getXmlManifest(f"""
619
620
621
622""")
Raman Tenneti993af5e2021-05-12 12:00:31 -0700623 self.assertEqual(manifest.contactinfo.bugurl, bugurl)
Raman Tenneti1c3f57e2021-05-04 12:32:13 -0700624 self.assertEqual(
625 manifest.ToXml().toxml(),
Raman Tenneti2f8fdbe2021-05-04 18:54:52 -0700626 ''
627 f''
628 '')
Jack Neus5ba21202021-06-09 15:21:25 +0000629
630
631class DefaultElementTests(ManifestParseTestCase):
632 """Tests for ."""
633
634 def test_default(self):
635 """Check default settings."""
636 a = manifest_xml._Default()
637 a.revisionExpr = 'foo'
638 a.remote = manifest_xml._XmlRemote(name='remote')
639 b = manifest_xml._Default()
640 b.revisionExpr = 'bar'
641 self.assertEqual(a, a)
642 self.assertNotEqual(a, b)
643 self.assertNotEqual(b, a.remote)
644 self.assertNotEqual(a, 123)
645 self.assertNotEqual(a, None)
646
647
648class RemoteElementTests(ManifestParseTestCase):
649 """Tests for ."""
650
651 def test_remote(self):
652 """Check remote settings."""
653 a = manifest_xml._XmlRemote(name='foo')
Jack Neus6ea0cae2021-07-20 20:52:33 +0000654 a.AddAnnotation('key1', 'value1', 'true')
655 b = manifest_xml._XmlRemote(name='foo')
656 b.AddAnnotation('key2', 'value1', 'true')
657 c = manifest_xml._XmlRemote(name='foo')
658 c.AddAnnotation('key1', 'value2', 'true')
659 d = manifest_xml._XmlRemote(name='foo')
660 d.AddAnnotation('key1', 'value1', 'false')
Jack Neus5ba21202021-06-09 15:21:25 +0000661 self.assertEqual(a, a)
662 self.assertNotEqual(a, b)
Jack Neus6ea0cae2021-07-20 20:52:33 +0000663 self.assertNotEqual(a, c)
664 self.assertNotEqual(a, d)
Jack Neus5ba21202021-06-09 15:21:25 +0000665 self.assertNotEqual(a, manifest_xml._Default())
666 self.assertNotEqual(a, 123)
667 self.assertNotEqual(a, None)
Michael Kelly06da9982021-06-30 01:58:28 -0700668
669
670class RemoveProjectElementTests(ManifestParseTestCase):
671 """Tests for ."""
672
673 def test_remove_one_project(self):
674 manifest = self.getXmlManifest("""
675
676
677
678
679
680
681""")
682 self.assertEqual(manifest.projects, [])
683
684 def test_remove_one_project_one_remains(self):
685 manifest = self.getXmlManifest("""
686
687
688
689
690
691
692
693""")
694
695 self.assertEqual(len(manifest.projects), 1)
696 self.assertEqual(manifest.projects[0].name, 'yourproject')
697
698 def test_remove_one_project_doesnt_exist(self):
699 with self.assertRaises(manifest_xml.ManifestParseError):
700 manifest = self.getXmlManifest("""
701
702
703
704
705
706""")
707 manifest.projects
708
709 def test_remove_one_optional_project_doesnt_exist(self):
710 manifest = self.getXmlManifest("""
711
712
713
714
715
716""")
717 self.assertEqual(manifest.projects, [])