| Index: recipe_engine/unittests/package_test.py
|
| diff --git a/recipe_engine/unittests/package_test.py b/recipe_engine/unittests/package_test.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..728c109fcfc71905a408a92737ee9105d47e84e9
|
| --- /dev/null
|
| +++ b/recipe_engine/unittests/package_test.py
|
| @@ -0,0 +1,162 @@
|
| +#!/usr/bin/env python
|
| +
|
| +import doctest
|
| +import os
|
| +import sys
|
| +import unittest
|
| +
|
| +ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(
|
| + os.path.abspath(__file__))))
|
| +THIRD_PARTY = os.path.join(ROOT_DIR, 'recipe_engine', 'third_party')
|
| +sys.path.insert(0, os.path.join(THIRD_PARTY, 'mock-1.0.1'))
|
| +sys.path.insert(0, THIRD_PARTY)
|
| +sys.path.insert(0, ROOT_DIR)
|
| +
|
| +import mock
|
| +from recipe_engine import package
|
| +
|
| +class MockIOThings(object):
|
| + def setUp(self):
|
| + self.mock_os_patcher = mock.patch('recipe_engine.package.os')
|
| + self.mock_os = self.mock_os_patcher.start()
|
| + self.mock_os.path.join = os.path.join
|
| + self.mock_os.path.dirname = os.path.dirname
|
| + self.mock_os.sep = os.sep
|
| +
|
| + self.mock_subprocess_patcher = mock.patch(
|
| + 'recipe_engine.package.subprocess')
|
| + self.mock_subprocess = self.mock_subprocess_patcher.start()
|
| +
|
| + def tearDown(self):
|
| + self.mock_subprocess_patcher.stop()
|
| + self.mock_os_patcher.stop()
|
| +
|
| +
|
| +class TestGitRepoSpec(MockIOThings, unittest.TestCase):
|
| + REPO_URL = 'https://funny.recipes/repo.git'
|
| + def setUp(self):
|
| + super(TestGitRepoSpec, self).setUp()
|
| +
|
| + self.repo_spec = package.GitRepoSpec(
|
| + 'funny_recipes',
|
| + self.REPO_URL,
|
| + 'master',
|
| + 'deadbeef',
|
| + 'path/to/recipes',
|
| + )
|
| + self.context = package.PackageContext(
|
| + recipes_dir='repo/root/recipes',
|
| + package_dir='repo/root/recipes/.recipe_deps',
|
| + repo_root='repo/root',
|
| + )
|
| +
|
| + def test_checkout_nonexistant_package_dir(self):
|
| + self.mock_os.path.exists.return_value = False
|
| + self.mock_os.path.isdir.return_value = False
|
| +
|
| + self.repo_spec.checkout(self.context)
|
| +
|
| + self.mock_subprocess.check_call.assert_any_call(
|
| + ['git', 'clone', self.REPO_URL,
|
| + os.path.join(self.context.package_dir, 'funny_recipes')],
|
| + cwd=None)
|
| + self.mock_subprocess.check_call.assert_any_call(
|
| + ['git', 'reset', '-q', '--hard', 'deadbeef'],
|
| + cwd='repo/root/recipes/.recipe_deps/funny_recipes')
|
| +
|
| +
|
| +class MockProtoFile(package.ProtoFile):
|
| + def __init__(self, path, text):
|
| + super(MockProtoFile, self).__init__(path)
|
| + self._text = text
|
| +
|
| + @property
|
| + def path(self):
|
| + return self._path
|
| +
|
| + def read_text(self):
|
| + return self._text
|
| +
|
| + def write(self, buf):
|
| + pass
|
| +
|
| +
|
| +class TestPackageSpec(MockIOThings, unittest.TestCase):
|
| + def setUp(self):
|
| + super(TestPackageSpec, self).setUp()
|
| +
|
| + self.proto_text = """
|
| +api_version: 1
|
| +project_id: "super_main_package"
|
| +recipes_path: "path/to/recipes"
|
| +deps {
|
| + project_id: "bar"
|
| + url: "https://repo.com/bar.git"
|
| + branch: "superbar"
|
| + revision: "deadd00d"
|
| +}
|
| +deps {
|
| + project_id: "foo"
|
| + url: "https://repo.com/foo.git"
|
| + branch: "master"
|
| + revision: "cafebeef"
|
| +}
|
| +""".lstrip()
|
| + self.proto_file = MockProtoFile('repo/root/infra/config/recipes.cfg',
|
| + self.proto_text)
|
| + self.context = package.PackageContext.from_proto_file(
|
| + 'repo/root', self.proto_file)
|
| +
|
| + # def test_dump_load_inverses(self):
|
| + # Doubles as a test for equality reflexivity.
|
| + package_spec = package.PackageSpec.load_proto(self.proto_file)
|
| + self.assertEqual(self.proto_file.to_text(package_spec.dump()),
|
| + self.proto_text)
|
| + self.assertEqual(package.PackageSpec.load_proto(self.proto_file),
|
| + package_spec)
|
| +
|
| + def test_updates_merged(self):
|
| + """Tests that updates are monotone in each dependency's history and
|
| + that dep rolls stay in their proper dependency."""
|
| +
|
| + package_spec = package.PackageSpec.load_proto(self.proto_file)
|
| + foo_revs = [ "aaaaaa", "123456", "cdabfe" ]
|
| + bar_revs = [ "0156ff", "ffaaff", "aa0000" ]
|
| + package_spec.deps['bar']._raw_updates = mock.Mock(
|
| + return_value='\n'.join(bar_revs))
|
| + package_spec.deps['foo']._raw_updates = mock.Mock(
|
| + return_value='\n'.join(foo_revs))
|
| +
|
| + updates = package_spec.updates(self.context)
|
| + foo_update_ixs = [
|
| + (['cafebeef'] + foo_revs).index(update.spec.deps['foo'].revision)
|
| + for update in updates ]
|
| + bar_update_ixs = [
|
| + (['deadd00d'] + bar_revs).index(update.spec.deps['bar'].revision)
|
| + for update in updates ]
|
| + self.assertEqual(len(updates), 6)
|
| + self.assertEqual(foo_update_ixs, sorted(foo_update_ixs))
|
| + self.assertEqual(bar_update_ixs, sorted(bar_update_ixs))
|
| +
|
| + def test_no_version(self):
|
| + with self.assertRaises(Exception):
|
| + package.PackageSpec.load({
|
| + 'id': 'foo',
|
| + 'deps': {},
|
| + })
|
| +
|
| + def test_unsupported_version(self):
|
| + with self.assertRaises(Exception):
|
| + package.PackageSpec.load({
|
| + 'api_version': 1,
|
| + 'id': 'fizzbar',
|
| + 'deps': {},
|
| + })
|
| +
|
| +def load_tests(loader, tests, ignore):
|
| + tests.addTests(doctest.DocTestSuite(package))
|
| + return tests
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + result = unittest.main()
|
|
|