test_manifest_xml.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # -*- coding:utf-8 -*-
  2. #
  3. # Copyright (C) 2019 The Android Open Source Project
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. """Unittests for the manifest_xml.py module."""
  17. from __future__ import print_function
  18. import os
  19. import unittest
  20. import xml.dom.minidom
  21. import error
  22. import manifest_xml
  23. class ManifestValidateFilePaths(unittest.TestCase):
  24. """Check _ValidateFilePaths helper.
  25. This doesn't access a real filesystem.
  26. """
  27. def check_both(self, *args):
  28. manifest_xml.XmlManifest._ValidateFilePaths('copyfile', *args)
  29. manifest_xml.XmlManifest._ValidateFilePaths('linkfile', *args)
  30. def test_normal_path(self):
  31. """Make sure good paths are accepted."""
  32. self.check_both('foo', 'bar')
  33. self.check_both('foo/bar', 'bar')
  34. self.check_both('foo', 'bar/bar')
  35. self.check_both('foo/bar', 'bar/bar')
  36. def test_symlink_targets(self):
  37. """Some extra checks for symlinks."""
  38. def check(*args):
  39. manifest_xml.XmlManifest._ValidateFilePaths('linkfile', *args)
  40. # We allow symlinks to end in a slash since we allow them to point to dirs
  41. # in general. Technically the slash isn't necessary.
  42. check('foo/', 'bar')
  43. # We allow a single '.' to get a reference to the project itself.
  44. check('.', 'bar')
  45. def test_bad_paths(self):
  46. """Make sure bad paths (src & dest) are rejected."""
  47. PATHS = (
  48. '..',
  49. '../',
  50. './',
  51. 'foo/',
  52. './foo',
  53. '../foo',
  54. 'foo/./bar',
  55. 'foo/../../bar',
  56. '/foo',
  57. './../foo',
  58. '.git/foo',
  59. # Check case folding.
  60. '.GIT/foo',
  61. 'blah/.git/foo',
  62. '.repo/foo',
  63. '.repoconfig',
  64. # Block ~ due to 8.3 filenames on Windows filesystems.
  65. '~',
  66. 'foo~',
  67. 'blah/foo~',
  68. # Block Unicode characters that get normalized out by filesystems.
  69. u'foo\u200Cbar',
  70. )
  71. # Make sure platforms that use path separators (e.g. Windows) are also
  72. # rejected properly.
  73. if os.path.sep != '/':
  74. PATHS += tuple(x.replace('/', os.path.sep) for x in PATHS)
  75. for path in PATHS:
  76. self.assertRaises(
  77. error.ManifestInvalidPathError, self.check_both, path, 'a')
  78. self.assertRaises(
  79. error.ManifestInvalidPathError, self.check_both, 'a', path)
  80. class ValueTests(unittest.TestCase):
  81. """Check utility parsing code."""
  82. def _get_node(self, text):
  83. return xml.dom.minidom.parseString(text).firstChild
  84. def test_bool_default(self):
  85. """Check XmlBool default handling."""
  86. node = self._get_node('<node/>')
  87. self.assertIsNone(manifest_xml.XmlBool(node, 'a'))
  88. self.assertIsNone(manifest_xml.XmlBool(node, 'a', None))
  89. self.assertEqual(123, manifest_xml.XmlBool(node, 'a', 123))
  90. node = self._get_node('<node a=""/>')
  91. self.assertIsNone(manifest_xml.XmlBool(node, 'a'))
  92. def test_bool_invalid(self):
  93. """Check XmlBool invalid handling."""
  94. node = self._get_node('<node a="moo"/>')
  95. self.assertEqual(123, manifest_xml.XmlBool(node, 'a', 123))
  96. def test_bool_true(self):
  97. """Check XmlBool true values."""
  98. for value in ('yes', 'true', '1'):
  99. node = self._get_node('<node a="%s"/>' % (value,))
  100. self.assertTrue(manifest_xml.XmlBool(node, 'a'))
  101. def test_bool_false(self):
  102. """Check XmlBool false values."""
  103. for value in ('no', 'false', '0'):
  104. node = self._get_node('<node a="%s"/>' % (value,))
  105. self.assertFalse(manifest_xml.XmlBool(node, 'a'))
  106. def test_int_default(self):
  107. """Check XmlInt default handling."""
  108. node = self._get_node('<node/>')
  109. self.assertIsNone(manifest_xml.XmlInt(node, 'a'))
  110. self.assertIsNone(manifest_xml.XmlInt(node, 'a', None))
  111. self.assertEqual(123, manifest_xml.XmlInt(node, 'a', 123))
  112. node = self._get_node('<node a=""/>')
  113. self.assertIsNone(manifest_xml.XmlInt(node, 'a'))
  114. def test_int_good(self):
  115. """Check XmlInt numeric handling."""
  116. for value in (-1, 0, 1, 50000):
  117. node = self._get_node('<node a="%s"/>' % (value,))
  118. self.assertEqual(value, manifest_xml.XmlInt(node, 'a'))
  119. def test_int_invalid(self):
  120. """Check XmlInt invalid handling."""
  121. with self.assertRaises(error.ManifestParseError):
  122. node = self._get_node('<node a="xx"/>')
  123. manifest_xml.XmlInt(node, 'a')