diff options
Diffstat (limited to 'morphlib/builder_tests.py')
-rw-r--r-- | morphlib/builder_tests.py | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/morphlib/builder_tests.py b/morphlib/builder_tests.py new file mode 100644 index 00000000..a8f06462 --- /dev/null +++ b/morphlib/builder_tests.py @@ -0,0 +1,165 @@ +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +import os +import shutil +import unittest + +import morphlib + + +class FakeSubmodule(object): + + def __init__(self, **kwargs): + for name in kwargs: + setattr(self, name, kwargs[name]) + + +class FakeTreeish(object): + + def __init__(self, tempdir, repo, subtreeish=None): + self.repo = tempdir.join(repo) + self.ref = 'master' + self.submodules = [] + + temp_repo = tempdir.join('temp_repo') + + os.mkdir(temp_repo) + ex = morphlib.execute.Execute(temp_repo, lambda s: None) + ex.runv(['git', 'init', '--quiet']) + with open(os.path.join(temp_repo, 'file.txt'), 'w') as f: + f.write('foobar\n') + ex.runv(['git', 'add', 'file.txt']) + ex.runv(['git', 'commit', '--quiet', '-m', 'foo']) + + if subtreeish is not None: + ex.runv(['git', 'submodule', 'add', subtreeish.repo]) + path = os.path.basename(subtreeish.repo) + self.submodules = [FakeSubmodule(repo=subtreeish.repo, + ref='master', + path=path, + treeish=subtreeish)] + + ex = morphlib.execute.Execute(tempdir.dirname, lambda s: None) + ex.runv(['git', 'clone', '-n', temp_repo, self.repo]) + + shutil.rmtree(temp_repo) + + +class FactoryTests(unittest.TestCase): + + def setUp(self): + self.tempdir = morphlib.tempdir.Tempdir() + self.factory = morphlib.builder.Factory(self.tempdir) + + def tearDown(self): + self.tempdir.remove() + + def create_chunk(self): + '''Create a simple binary chunk.''' + + inst = self.tempdir.join('dummy-inst') + os.mkdir(inst) + for x in ['bin', 'etc', 'lib']: + os.mkdir(os.path.join(inst, x)) + + binary = self.tempdir.join('dummy-chunk') + ex = None # this is not actually used by the function! + with open(binary, 'wb') as f: + morphlib.bins.create_chunk(inst, f, ['.'], ex) + return binary + + def test_has_no_staging_area_initially(self): + self.assertEqual(self.factory.staging, None) + + def test_creates_staging_area(self): + self.factory.create_staging() + self.assertEqual(os.listdir(self.factory.staging), []) + + def test_removes_staging_area(self): + self.factory.create_staging() + staging = self.factory.staging + self.factory.remove_staging() + self.assertEqual(self.factory.staging, None) + self.assertFalse(os.path.exists(staging)) + + def test_unpacks_binary_from_file(self): + binary = self.create_chunk() + self.factory.create_staging() + self.factory.unpack_binary_from_file(binary) + self.assertEqual(sorted(os.listdir(self.factory.staging)), + sorted(['bin', 'etc', 'lib'])) + + def test_removes_staging_area_with_contents(self): + binary = self.create_chunk() + self.factory.create_staging() + self.factory.unpack_binary_from_file(binary) + staging = self.factory.staging + self.factory.remove_staging() + self.assertEqual(self.factory.staging, None) + self.assertFalse(os.path.exists(staging)) + + def test_unpacks_onto_system(self): + + # We can't test this by really unpacking onto the system. + # Instead, we rely on the fact that if the normal unpacking + # works, the actual worker function for unpacking works, and + # we can just verify that it gets called with the right + # parameters. + + def fake_unpack(binary, dirname): + self.dirname = dirname + + binary = self.create_chunk() + self.factory._unpack_binary = fake_unpack + self.factory.unpack_binary_from_file_onto_system(binary) + self.assertEqual(self.dirname, '/') + + def test_unpacks_simple_sources(self): + self.factory.create_staging() + srcdir = self.tempdir.join('src') + treeish = FakeTreeish(self.tempdir, 'repo') + self.factory.unpack_sources(treeish, srcdir) + self.assertTrue(os.path.exists(os.path.join(srcdir, 'file.txt'))) + + def test_unpacks_submodules(self): + self.factory.create_staging() + srcdir = self.tempdir.join('src') + subtreeish = FakeTreeish(self.tempdir, 'subrepo') + supertreeish = FakeTreeish(self.tempdir, 'repo', subtreeish=subtreeish) + self.factory.unpack_sources(supertreeish, srcdir) + self.assertEqual(sorted(os.listdir(srcdir)), + sorted(['.git', 'file.txt', 'subrepo'])) + self.assertEqual(sorted(os.listdir(os.path.join(srcdir, 'subrepo'))), + sorted(['.git', 'file.txt'])) + + def test_sets_timestamp_for_unpacked_files(self): + self.factory.create_staging() + srcdir = self.tempdir.join('src') + treeish = FakeTreeish(self.tempdir, 'repo') + self.factory.unpack_sources(treeish, srcdir) + + mtime = None + for dirname, subdirs, basenames in os.walk(srcdir): + pathnames = [os.path.join(dirname, x) for x in basenames] + for pathname in pathnames + [dirname]: + st = os.lstat(pathname) + if mtime is None: + mtime = st.st_mtime + else: + self.assertEqual((pathname, mtime), + (pathname, st.st_mtime)) + |