diff options
| author | Alexis Metaireau <ametaireau@gmail.com> | 2010-11-13 03:07:41 +0000 |
|---|---|---|
| committer | Alexis Metaireau <ametaireau@gmail.com> | 2010-11-13 03:07:41 +0000 |
| commit | 23b3801ac0c637b00f52bf17a3df078311937aa6 (patch) | |
| tree | ecae1e9b532d92da82d002ddf5cb0537e55c8190 /distutils2/tests | |
| parent | 21b0542823fa265c5c09ecff2b1d21c5e85daaa9 (diff) | |
| download | disutils2-23b3801ac0c637b00f52bf17a3df078311937aa6.tar.gz | |
Add basic installation script + tests.
Diffstat (limited to 'distutils2/tests')
| -rw-r--r-- | distutils2/tests/test_install.py | 173 |
1 files changed, 155 insertions, 18 deletions
diff --git a/distutils2/tests/test_install.py b/distutils2/tests/test_install.py index 84ad1f9..fde33e1 100644 --- a/distutils2/tests/test_install.py +++ b/distutils2/tests/test_install.py @@ -1,14 +1,20 @@ -"""Tests for the distutils2.index.xmlrpc module.""" +"""Tests for the distutils2.install module.""" -from distutils2.tests.pypi_server import use_xmlrpc_server -from distutils2.tests import unittest, run_unittest +import os +from tempfile import mkstemp + +from distutils2 import install from distutils2.index.xmlrpc import Client -from distutils2.install import (get_infos, InstallationException) from distutils2.metadata import DistributionMetadata +from distutils2.tests import run_unittest +from distutils2.tests.support import TempdirManager +from distutils2.tests.pypi_server import use_xmlrpc_server +from distutils2.tests.support import unittest -class FakeDist(object): - """A fake distribution object, for tests""" +class InstalledDist(object): + """Distribution object, represent distributions currently installed on the + system""" def __init__(self, name, version, deps): self.name = name self.version = version @@ -17,17 +23,49 @@ class FakeDist(object): self.metadata['Provides-Dist'] = ['%s (%s)' % (name, version)] def __repr__(self): - return '<FakeDist %s>' % self.name + return '<InstalledDist %s>' % self.name + + +class ToInstallDist(object): + """Distribution that will be installed""" + + def __init__(self, raise_error=False, files=False): + self._raise_error = raise_error + self._files = files + self.install_called = False + self.install_called_with = {} + self.uninstall_called = False + self._real_files = [] + if files: + for f in range(0,3): + self._real_files.append(mkstemp()) + def install(self, *args): + self.install_called = True + self.install_called_with = args + if self._raise_error: + raise Exception('Oops !') + return ['/path/to/foo', '/path/to/bar'] -def get_fake_dists(dists): + def uninstall(self, **args): + self.uninstall_called = True + + def get_installed_files(self, **args): + if self._files: + return [f[1] for f in self._real_files] + + def get_install(self, **args): + return self.get_installed_files() + + +def get_installed_dists(dists): objects = [] for (name, version, deps) in dists: - objects.append(FakeDist(name, version, deps)) + objects.append(InstalledDist(name, version, deps)) return objects -class TestInstallWithDeps(unittest.TestCase): +class TestInstall(TempdirManager, unittest.TestCase): def _get_client(self, server, *args, **kwargs): return Client(server.full_address, *args, **kwargs) @@ -62,8 +100,8 @@ class TestInstallWithDeps(unittest.TestCase): 'requires_dist': [], 'url': archive_path}, ]) - installed = get_fake_dists([('bacon', '0.1', []),]) - output = get_infos("choxie", index=client, + installed = get_installed_dists([('bacon', '0.1', []),]) + output = install.get_infos("choxie", index=client, installed=installed) # we dont have installed bacon as it's already installed on the system. @@ -94,8 +132,8 @@ class TestInstallWithDeps(unittest.TestCase): 'url': archive_path}, ]) - output = get_infos("choxie", index=client, installed= - get_fake_dists([('bacon', '0.1', []),])) + output = install.get_infos("choxie", index=client, installed= + get_installed_dists([('bacon', '0.1', []),])) installed = [(o.name, '%s' % o.version) for o in output['install']] # we need bacon 0.2, but 0.1 is installed. @@ -128,8 +166,8 @@ class TestInstallWithDeps(unittest.TestCase): ]) already_installed = [('bacon', '0.1', []), ('chicken', '1.1', ['bacon (0.1)'])] - output = get_infos("choxie", index=client, installed= - get_fake_dists(already_installed)) + output = install.get_infos("choxie", index=client, installed= + get_installed_dists(already_installed)) # we need bacon 0.2, but 0.1 is installed. # So we expect to remove 0.1 and to install 0.2 instead. @@ -145,13 +183,112 @@ class TestInstallWithDeps(unittest.TestCase): # Test that the isntalled raises an exception if the project does not # exists. client = self._get_client(server) - self.assertRaises(InstallationException, get_infos, + self.assertRaises(install.InstallationException, + install.get_infos, 'unexistant project', index=client) + def test_move_files(self): + # test that the files are really moved, and that the new path is + # returned. + path = self.mkdtemp() + newpath = self.mkdtemp() + files = [os.path.join(path, '%s' % x) for x in range(1, 20)] + for f in files: + file(f, 'a+') + output = [o for o in install.move_files(files, newpath)] + + # check that output return the list of old/new places + for f in files: + self.assertIn((f, '%s%s' % (newpath, f)), output) + + # remove the files + for f in [o[1] for o in output]: # o[1] is the new place + os.remove(f) + + def test_update_infos(self): + tests = [[{'foo': ['foobar', 'foo', 'baz'], 'baz': ['foo', 'foo']}, + {'foo': ['additional_content', 'yeah'], + 'baz': ['test', 'foo']}, + {'foo': ['foobar', 'foo', 'baz', 'additional_content', 'yeah'], + 'baz': ['foo', 'foo', 'test', 'foo']}],] + + for dict1, dict2, expect in tests: + install._update_infos(dict1, dict2) + for key in expect.keys(): + self.assertEqual(expect[key], dict1[key]) + + def test_install_dists_rollback(self): + # if one of the distribution installation fails, call uninstall on all + # installed distributions. + + d1 = ToInstallDist() + d2 = ToInstallDist(raise_error=True) + self.assertRaises(Exception, install.install_dists, [d1, d2]) + for dist in (d1, d2): + self.assertTrue(dist.install_called) + self.assertTrue(d1.uninstall_called) + self.assertFalse(d2.uninstall_called) + + def test_install_dists_success(self): + # test that the install method is called on each of the distributions. + d1 = ToInstallDist() + d2 = ToInstallDist() + install.install_dists([d1, d2]) + for dist in (d1, d2): + self.assertTrue(dist.install_called) + self.assertFalse(d1.uninstall_called) + self.assertFalse(d2.uninstall_called) + + def test_install_from_infos_conflict(self): + # assert conflicts raise an exception + self.assertRaises(install.InstallationConflict, + install.install_from_infos, + conflicts=[ToInstallDist()]) + + def test_install_from_infos_remove_success(self): + old_install_dists = install.install_dists + install.install_dists = lambda x,y=None: None + try: + dists = [] + for i in range(0,2): + dists.append(ToInstallDist(files=True)) + install.install_from_infos(remove=dists) + + # assert that the files have been removed + for dist in dists: + for f in dist.get_installed_files(): + self.assertFalse(os.path.exists(f)) + finally: + install.install_dists = old_install_dists + + def test_install_from_infos_remove_rollback(self): + # assert that if an error occurs, the removed files are restored. + remove = [] + for i in range(0,2): + remove.append(ToInstallDist(files=True, raise_error=True)) + to_install = [ToInstallDist(raise_error=True), + ToInstallDist()] + + install.install_from_infos(remove=remove, install=to_install) + # assert that the files are in the same place + # assert that the files have been removed + for dist in remove: + for f in dist.get_installed_files(): + self.assertTrue(os.path.exists(f)) + + def test_install_from_infos_install_succes(self): + # assert that the distribution can be installed + install_path = "my_install_path" + to_install = [ToInstallDist(), ToInstallDist()] + + install.install_from_infos(install=to_install, + install_path=install_path) + for dist in to_install: + self.assertEquals(dist.install_called_with, (install_path,)) def test_suite(): suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(TestInstallWithDeps)) + suite.addTest(unittest.makeSuite(TestInstall)) return suite if __name__ == '__main__': |
