blob: 18ff0f35e9702a7c76beaedc848a83de7df10276 [file] [log] [blame] [edit]
"""Tests for repo_utils."""
from __future__ import absolute_import
import os
import sys
import tempfile
import unittest
# Allow imports from cq/scripts folder
sys.path.insert(
0,
os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir)))
from helpers import repo_utils # pylint: disable=g-import-not-at-top
SAMPLE_MANIFEST_STRING = """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="https://chromium.googlesource.com/" name="chromium" review="https://chromium-review.googlesource.com/"/>
<remote fetch="https://eureka-internal.googlesource.com/" name="eureka" review="sso://eureka-internal"/>
<default revision="master"/>
<project name="chromium/src" remote="eureka" revision="unfork_m43"/>
<project name="chromiumos/chromite" path="chromite/chromite" remote="chromium"/>
<project name="chromiumos/third_party/autotest" path="autotest" remote="chromium"/>
<project name="continuous-tests" remote="eureka"/>
<project name="fragglerock" remote="eureka"/>
<project name="prebuilt/toolchain" path="toolchain" remote="eureka"/>
<project name="test" remote="eureka"/>
<project name="legacyname.git" path="path/to/legacy" remote="eureka"/>
</manifest>
"""
SAMPLE_MANIFEST_STRING_WITH_DUPLICATE_NAMES = """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="https://chromium.googlesource.com/" name="chromium" review="https://chromium-review.googlesource.com/"/>
<remote fetch="https://eureka-internal.googlesource.com/" name="eureka" review="sso://eureka-internal"/>
<default revision="master"/>
<project name="chromium/src" remote="eureka" revision="unfork_m43"/>
<project name="chromiumos/chromite" path="chromite/chromite" remote="chromium"/>
<project name="chromiumos/third_party/autotest" path="autotest" remote="chromium"/>
<project name="continuous-tests" remote="eureka"/>
<project name="fragglerock" remote="eureka"/>
<project name="prebuilt/toolchain" path="toolchain" remote="eureka"/>
<project name="test" path="test1" remote="eureka"/>
<project name="test" path="test2" remote="eureka"/>
</manifest>
"""
SAMPLE_MANIFEST_INCOMPLETE_STRING = """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="https://chromium.googlesource.com/" name="chromium" review="https://chromium-review.googlesource.com/"/>
<remote fetch="https://eureka-internal.googlesource.com/" name="eureka" review="sso://eureka-internal"/>
<default revision="master"/>
<project name="chromium/src" remote="eureka" revision="unfork_m43"/>
<project name="chromiumos/chromite" path="chromite/chromite" remote="chromium"/>
<project name="chromiumos/third_party/autotest" path="autotest" remote="chromium"/>
<project name="continuous-tests" remote="eureka"/>
<project name="fragglerock" remote="eureka"/>
<project name="prebuilt/toolchain" path="toolchain" remote="eureka"/>
"""
SAMPLE_MANIFEST_WITH_DEFAULT_REMOTE = """
<manifest>
<remote fetch="https://nest-internal.googlesource.com" name="cq-manifest" review="https://nest-internal-review.googlesource.com/"/>
<default remote="cq-manifest" revision="master"/>
<project name="nep/nest-harness-tests" path="nep/nest-harness-tests" />
</manifest>
"""
SAMPLE_MANIFEST_WITH_INTERNAL_GITHUB = """<manifest>
<remote fetch="https://eureka-internal.googlesource.com/" name="eureka" review="sso://eureka-internal"/>
<remote fetch="https://github.googlesource.com" name="github" review="https://github-review.googlesource.com/"/>
<remote fetch="https://chromium.googlesource.com/" name="chromium" review="https://chromium-review.googlesource.com/"/>
<default revision="master"/>
<project name="chromium/src" remote="eureka" revision="unfork_m43"/>
<project name="test-project1" remote="github"/>
<project name="chromiumos/chromite" path="chromite/chromite" remote="chromium"/>
</manifest>
"""
SAMPLE_MANIFEST_WITH_EXTERNAL_GITHUB = """<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="https://eureka-internal.googlesource.com/" name="eureka" review="sso://eureka-internal"/>
<remote fetch="https://github.com" name="github"/>
<remote fetch="https://chromium.googlesource.com/" name="chromium" review="https://chromium-review.googlesource.com/"/>
<default revision="master"/>
<project name="chromium/src" remote="eureka" revision="unfork_m43"/>
<project name="test-project1" remote="github"/>
<project name="chromiumos/chromite" path="chromite/chromite" remote="chromium"/>
</manifest>
"""
TEST_MANIFEST_URL = 'https://foo.bar.googlesource.com/bat/baz'
_SAMPLE_MANIFEST_STRING_WITH_MULTI_REVISIONS_OF_SAME_NAMES = """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="https://chromium.googlesource.com/" name="chromium" review="https://chromium-review.googlesource.com/"/>
<remote fetch="https://eureka-internal.googlesource.com/" name="eureka" review="sso://eureka-internal"/>
<project name="test" path="test1" remote="eureka" revision="branch1"/>
<project name="test" path="test2" remote="eureka" revision="branch2"/>
</manifest>
"""
_SAMPLE_MANIFEST_WITH_UPSTREAMS_SET = """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="https://chromium.googlesource.com/" name="chromium" review="https://chromium-review.googlesource.com/"/>
<remote fetch="https://eureka-internal.googlesource.com/" name="eureka" review="sso://eureka-internal"/>
<project name="test" path="test1" remote="eureka" revision="sha1" upstream="branch1"/>
<project name="test" path="test2" remote="eureka" revision="branch2"/>
</manifest>
"""
class RepoUtilsTest(unittest.TestCase):
"""Tests for the repo utils module."""
def testParseEmptyManifest(self):
"""Tests parsing an empty manifest file."""
manifest = ''
expected_lookup = {
'eureka/manifest': '.repo/manifests',
}
project_lookup = repo_utils.parse_manifest_for_path(
manifest, repo_utils.EUREKA_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
def testParseManifest(self):
"""Tests parsing a manifest file for paths."""
expected_lookup = {
'chromium/src': 'chromium/src',
'chromiumos/chromite': 'chromite/chromite',
'chromiumos/third_party/autotest': 'autotest',
'continuous-tests': 'continuous-tests',
'eureka/manifest': '.repo/manifests',
'fragglerock': 'fragglerock',
'legacyname.git': 'path/to/legacy',
'prebuilt/toolchain': 'toolchain',
'test': 'test'
}
project_lookup = repo_utils.parse_manifest_for_path(
SAMPLE_MANIFEST_STRING,
repo_utils.EUREKA_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
def testParseManifestForNonEurekaManifest(self):
"""Tests parsing a non-eureka manifest for path."""
expected_lookup = {
'bat/baz': '.repo/manifests',
'chromium/src': 'chromium/src',
'chromiumos/chromite': 'chromite/chromite',
'chromiumos/third_party/autotest': 'autotest',
'continuous-tests': 'continuous-tests',
'fragglerock': 'fragglerock',
'legacyname.git': 'path/to/legacy',
'prebuilt/toolchain': 'toolchain',
'test': 'test'
}
try:
original_map = dict(repo_utils.REPO_MANIFEST_URL_TO_PROJECT_NAME)
repo_utils.REPO_MANIFEST_URL_TO_PROJECT_NAME = {TEST_MANIFEST_URL:
'bat/baz'}
project_lookup = repo_utils.parse_manifest_for_path(
SAMPLE_MANIFEST_STRING, TEST_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
finally:
repo_utils.REPO_MANIFEST_URL_TO_PROJECT_NAME = original_map
def testParseManifestRemotes(self):
"""Tests parsing a manifest file for remotes."""
expected_lookup = {
'chromium/src': 'eureka',
'chromiumos/chromite': 'chromium',
'chromiumos/third_party/autotest': 'chromium',
'continuous-tests': 'eureka',
'eureka/manifest': 'origin',
'fragglerock': 'eureka',
'legacyname.git': 'eureka',
'prebuilt/toolchain': 'eureka',
'test': 'eureka'
}
project_lookup = repo_utils.parse_manifest_for_remote(
SAMPLE_MANIFEST_STRING,
repo_utils.EUREKA_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
def testParseManifestRemotesForNonEurekaManifest(self):
"""Tests parsing a non-eureka manifest for remotes."""
expected_lookup = {
'bat/baz': 'origin',
'chromium/src': 'eureka',
'chromiumos/chromite': 'chromium',
'chromiumos/third_party/autotest': 'chromium',
'continuous-tests': 'eureka',
'fragglerock': 'eureka',
'legacyname.git': 'eureka',
'prebuilt/toolchain': 'eureka',
'test': 'eureka'
}
try:
original_map = dict(repo_utils.REPO_MANIFEST_URL_TO_PROJECT_NAME)
repo_utils.REPO_MANIFEST_URL_TO_PROJECT_NAME = {TEST_MANIFEST_URL:
'bat/baz'}
project_lookup = repo_utils.parse_manifest_for_remote(
SAMPLE_MANIFEST_STRING, TEST_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
finally:
repo_utils.REPO_MANIFEST_URL_TO_PROJECT_NAME = original_map
def testParseManifestRemotesForNonEurekaDefaultRemote(self):
expected_lookup = {
'nep/nest-harness-tests': 'cq-manifest'
}
project_lookup = repo_utils.parse_manifest_for_remote(
SAMPLE_MANIFEST_WITH_DEFAULT_REMOTE, TEST_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
def testParseManifestRevisions(self):
"""Tests parsing a manifest file for revisions."""
expected_lookup = {
'chromium/src': 'unfork_m43',
'chromiumos/chromite': 'master',
'chromiumos/third_party/autotest': 'master',
'continuous-tests': 'master',
'eureka/manifest': 'unfork_m51',
'fragglerock': 'master',
'legacyname.git': 'master',
'prebuilt/toolchain': 'master',
'test': 'master'
}
project_lookup = repo_utils.parse_manifest_for_revision(
SAMPLE_MANIFEST_STRING,
repo_utils.EUREKA_MANIFEST_URL,
'unfork_m51')
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
def testParseManifestWithDups(self):
"""Tests parsing a manifest file with duplicates."""
expected_lookup = {
'chromium/src': 'chromium/src',
'chromiumos/chromite': 'chromite/chromite',
'chromiumos/third_party/autotest': 'autotest',
'continuous-tests': 'continuous-tests',
'eureka/manifest': '.repo/manifests',
'fragglerock': 'fragglerock',
'prebuilt/toolchain': 'toolchain',
}
expected_duplicate = 'test'
project_lookup = repo_utils.parse_manifest_for_path(
SAMPLE_MANIFEST_STRING_WITH_DUPLICATE_NAMES,
repo_utils.EUREKA_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(project_lookup[key], expected_value)
with self.assertRaises(repo_utils.DuplicateLookupError):
project_lookup[expected_duplicate] # pylint: disable=pointless-statement
def testLookupDuplicateRepoRaisesError(self):
"""Tests a lookup on a duplicate repo raises an error."""
class MockExecutor(object):
# pylint: disable=invalid-name,no-method-argument, no-self-argument
def exec_subprocess(*args, **kwargs):
del kwargs
return SAMPLE_MANIFEST_STRING_WITH_DUPLICATE_NAMES
lookup = repo_utils.get_project_path_lookup(
MockExecutor(), repo_utils.EUREKA_MANIFEST_URL)
self.assertEqual('continuous-tests', lookup.get('continuous-tests'))
with self.assertRaises(KeyError):
lookup.get('foobar')
with self.assertRaises(repo_utils.DuplicateLookupError):
lookup.get('test')
self.assertEqual('continuous-tests', lookup['continuous-tests'])
with self.assertRaises(KeyError):
lookup['foobar'] # pylint: disable=pointless-statement
with self.assertRaises(repo_utils.DuplicateLookupError):
lookup['test'] # pylint: disable=pointless-statement
def testManifestParseError(self):
"""Tests parsing an incorrect manifest file."""
class MockExecutor(object):
# pylint: disable=invalid-name,no-method-argument, no-self-argument
def exec_subprocess(*args, **kwargs):
del kwargs
return SAMPLE_MANIFEST_INCOMPLETE_STRING
with self.assertRaises(repo_utils.ManifestParseError):
_ = repo_utils.get_manifest(MockExecutor())
def testEmptyChangeDoesNotRequireRepoSync(self):
"""Tests that an empty commit does not require a sync."""
project = 'eureka/manifest'
files = []
self.assertFalse(repo_utils.requires_repo_sync(project, files))
def testSyncNotRequiredForOtherProjects(self):
"""Tests that a sync is not required for other projects."""
project = 'third_party/foobar'
files = ['default.xml']
self.assertFalse(repo_utils.requires_repo_sync(project, files))
def testChangeToAnyManifestFileRequiresRepoSync(self):
"""Tests that a change to any manifest requires a sync."""
project = 'eureka/manifest'
files = ['default.xml']
self.assertTrue(repo_utils.requires_repo_sync(project, files))
files = ['foobar.xml']
self.assertTrue(repo_utils.requires_repo_sync(project, files))
def testProjectLookupWithTrailingSlash(self):
"""Tests searching by project with a trailing slash."""
expected_lookup = {
'chromium/src': 'chromium/src',
'chromiumos/chromite': 'chromite/chromite',
'chromiumos/third_party/autotest': 'autotest',
'continuous-tests': 'continuous-tests',
'eureka/manifest': '.repo/manifests',
'fragglerock': 'fragglerock',
'prebuilt/toolchain': 'toolchain',
'test': 'test'
}
project_lookup = repo_utils.parse_manifest_for_path(
SAMPLE_MANIFEST_STRING,
repo_utils.EUREKA_MANIFEST_URL)
for key, expected_value in expected_lookup.items():
self.assertEqual(expected_value, project_lookup.get(key))
self.assertEqual(expected_value, project_lookup.get(key + '/'))
def testProjectLookupWithGitSuffix(self):
"""Tests finding a project name that has a .git suffix."""
key_without_git_suffix = 'legacyname'
key_with_git_suffix = 'legacyname.git'
expected_path = 'path/to/legacy'
project_lookup = repo_utils.parse_manifest_for_path(
SAMPLE_MANIFEST_STRING,
repo_utils.EUREKA_MANIFEST_URL)
actual_path = project_lookup.get(key_without_git_suffix)
self.assertEqual(expected_path, actual_path)
actual_path = project_lookup.get(key_with_git_suffix)
self.assertEqual(expected_path, actual_path)
def testNormalizeManifestSwapsOutInternalGithub(self):
"""Tests github.com is temporarily used for the remote fetch."""
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
f.write(SAMPLE_MANIFEST_WITH_INTERNAL_GITHUB)
temp_manifest = f.name
with repo_utils.normalize_manifest_if_exists(temp_manifest):
with open(temp_manifest, 'r') as f:
manifest_content = f.read()
self.assertEqual(manifest_content,
SAMPLE_MANIFEST_WITH_EXTERNAL_GITHUB)
with open(temp_manifest, 'r') as f:
manifest_content = f.read()
self.assertEqual(manifest_content, SAMPLE_MANIFEST_WITH_INTERNAL_GITHUB)
os.unlink(temp_manifest)
def testParseManifestWithSameNamesFromDifferentRevisions(self):
project_lookup = repo_utils.parse_manifest_for_path(
_SAMPLE_MANIFEST_STRING_WITH_MULTI_REVISIONS_OF_SAME_NAMES,
repo_utils.EUREKA_MANIFEST_URL)
self.assertEqual(project_lookup[('test', 'branch1')], 'test1')
self.assertEqual(project_lookup[('test', 'branch2')], 'test2')
def testParseManifestUseUpstreamFirstThenRevision(self):
project_lookup = repo_utils.parse_manifest_for_path(
_SAMPLE_MANIFEST_WITH_UPSTREAMS_SET, repo_utils.EUREKA_MANIFEST_URL)
self.assertEqual(project_lookup[('test', 'branch1')], 'test1')
self.assertEqual(project_lookup[('test', 'branch2')], 'test2')
if __name__ == '__main__':
unittest.main()