| # Copyright 2017 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from __future__ import absolute_import |
| from __future__ import print_function |
| from __future__ import unicode_literals |
| |
| import os |
| import sys |
| import unittest |
| import warnings |
| |
| import mock |
| from six.moves import StringIO |
| |
| from cros_venv import flock |
| from cros_venv import testcases |
| from cros_venv import venvlib |
| |
| |
| class VenvlibTestCase(unittest.TestCase): |
| |
| """TestCase for venvlib functions.""" |
| |
| def test__PACKAGE_DIR(self): |
| """Test that _PACKAGE_DIR exists.""" |
| self.assertTrue(os.path.isdir(venvlib._PACKAGE_DIR)) |
| |
| def test__get_cache_dir(self): |
| got = venvlib._get_cache_dir() |
| self.assertTrue(got.endswith('/.cache/cros_venv')) |
| |
| def test__get_cache_dir_should_be_absolute(self): |
| got = venvlib._get_cache_dir() |
| self.assertTrue(got.startswith('/')) |
| |
| @mock.patch.object(venvlib, 'sys') |
| def test__get_python_version(self, sys): |
| sys.version_info = (2, 7, 12, 'final', 0) |
| self.assertEqual(venvlib._get_python_version(), '2.7.12') |
| |
| |
| class VirtualenvMissingErrorTestCase(unittest.TestCase): |
| |
| """TestCase for VirtualenvMissingError.""" |
| |
| def test_str(self): |
| """Test str() on VirtualenvMissingError.""" |
| self.assertEqual(str(venvlib.VirtualenvMissingError(Exception('foo'))), |
| 'virtualenv is not installed (caused by foo)') |
| |
| def test_repr(self): |
| """Test repr() on VirtualenvMissingError.""" |
| if sys.version_info.major < 3: |
| exp = "VirtualenvMissingError(u'foo')" |
| else: |
| exp = "VirtualenvMissingError('foo')" |
| self.assertEqual(repr(venvlib.VirtualenvMissingError('foo')), exp) |
| |
| |
| class VenvlibTmpDirTestCase(testcases.TmpdirTestCase): |
| |
| """TestCase for venvlib functions that uses a temp directory.""" |
| |
| def test__makedirs_exist_ok(self): |
| """Test _makedirs_exist_ok() ignores existing dir.""" |
| os.mkdir('foo') |
| try: |
| venvlib._makedirs_exist_ok('foo') |
| except OSError: # pragma: no cover |
| self.fail('OSError raised') |
| |
| def test__log_check_call(self): |
| if sys.version_info.major < 3: |
| exp = "Running [u'echo', u'hi']\nhi\n" |
| else: |
| exp = "Running ['echo', 'hi']\nhi\n" |
| with open('tmp', 'w') as f: |
| venvlib._log_check_call(['echo', 'hi'], logfile=f) |
| with open('tmp', 'r') as f: |
| self.assertEqual(f.read(), exp) |
| |
| |
| class VenvPathsTestCase(unittest.TestCase): |
| |
| """Tests for _VenvPaths.""" |
| |
| def test_repr(self): |
| paths = venvlib._VenvPaths('/tmp') |
| if sys.version_info.major < 3: |
| exp = "_VenvPaths(u'/tmp')" |
| else: |
| exp = "_VenvPaths('/tmp')" |
| self.assertEqual(repr(paths), exp) |
| |
| def test_venvdir(self): |
| """Test for venvdir attribute.""" |
| paths = venvlib._VenvPaths('/tmp') |
| self.assertEqual(paths.venvdir, '/tmp') |
| |
| def test_python(self): |
| """Test for python attribute.""" |
| paths = venvlib._VenvPaths('/tmp') |
| self.assertEqual(paths.python, '/tmp/bin/python') |
| |
| def test_lockfile(self): |
| """Test for lockfile attribute.""" |
| paths = venvlib._VenvPaths('/tmp') |
| self.assertEqual(paths.lockfile, '/tmp/change.lock') |
| |
| def test_logfile(self): |
| """Test for logfile attribute.""" |
| paths = venvlib._VenvPaths('/tmp') |
| self.assertEqual(paths.logfile, '/tmp/create.log') |
| |
| def test_spec(self): |
| """Test for spec attribute.""" |
| paths = venvlib._VenvPaths('/tmp') |
| self.assertEqual(paths.spec, '/tmp/spec.json') |
| |
| |
| class VersionedVenvTestCase(unittest.TestCase): |
| |
| """Tests for VersionedVenv.""" |
| |
| def test_repr(self): |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| venv = venvlib.VersionedVenv(spec) |
| with mock.patch.object(venvlib._VenvSpec, '__repr__') as venv_repr: |
| venv_repr.return_value = 'foo' |
| self.assertEqual(repr(venv), |
| "VersionedVenv(foo)") |
| |
| |
| class VersionedVenvTmpDirTestCase(testcases.TmpdirTestCase): |
| |
| """Tests for VersionedVenv that use a temp directory.""" |
| |
| def setUp(self): |
| super(VersionedVenvTmpDirTestCase, self).setUp() |
| patcher = mock.patch.object(venvlib, '_get_cache_dir') |
| get_cache_dir = patcher.start() |
| self.addCleanup(patcher.stop) |
| get_cache_dir.return_value = os.getcwd() |
| |
| @mock.patch.object(venvlib.VersionedVenv, '_create') |
| @mock.patch.object(venvlib.VersionedVenv, '_check') |
| def test__check_or_create_should_create_missing_dir(self, check, create): |
| """Test that _check_or_create() creates when directory is missing.""" |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| venv = venvlib.VersionedVenv(spec) |
| venv._check_or_create() |
| check.assert_not_called() |
| create.assert_called_once_with() |
| |
| @mock.patch.object(venvlib.VersionedVenv, '_create') |
| @mock.patch.object(venvlib.VersionedVenv, '_check') |
| def test__check_or_create_should_create_missing_spec(self, check, create): |
| """Test that _check_or_create() creates when spec file is missing.""" |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| venv = venvlib.VersionedVenv(spec) |
| venvdir = 'venv-1.7.6-5442279a613e6a2c4a93c9bda10e63f4' |
| os.mkdir(venvdir) |
| venv._check_or_create() |
| check.assert_not_called() |
| create.assert_called_once_with() |
| |
| @mock.patch.object(venvlib.VersionedVenv, '_create') |
| @mock.patch.object(venvlib.VersionedVenv, '_check') |
| def test__check_or_create_should_check_with_spec(self, check, create): |
| """Test that _check_or_create() creates when spec file is missing.""" |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| venv = venvlib.VersionedVenv(spec) |
| venvdir = 'venv-1.7.6-5442279a613e6a2c4a93c9bda10e63f4' |
| os.mkdir(venvdir) |
| with open(venvdir + '/spec.json', 'w') as f: |
| f.write('["1.7.6", "foo==1.0.0\\n"]') |
| venv._check_or_create() |
| check.assert_called_once_with(spec) |
| create.assert_not_called() |
| |
| def test__check_should_pass_with_same_spec(self): |
| """Test that _check() passes when spec matches.""" |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| venv = venvlib.VersionedVenv(spec) |
| try: |
| venv._check(spec) |
| except venvlib.SpecMismatchError: # pragma: no cover |
| self.fail('Check did not pass') |
| |
| def test__check_should_fail_with_different_spec(self): |
| """Test that _check() fails when spec does not match.""" |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| venv = venvlib.VersionedVenv(spec) |
| with self.assertRaises(venvlib.SpecMismatchError): |
| venv._check(venvlib._VenvSpec('1.7.6', 'foo=2.0.0\n')) |
| |
| def test_dump_spec_and_load_spec(self): |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| venv = venvlib.VersionedVenv(spec) |
| os.mkdir(venv._paths.venvdir) |
| venv._dump_spec() |
| got = venv._load_spec() |
| self.assertEqual(spec, got) |
| |
| |
| class VenvSpecTestCase(unittest.TestCase): |
| |
| """Tests for _VenvSpec.""" |
| |
| def test_eq(self): |
| self.assertEqual( |
| venvlib._VenvSpec('2.7.3', 'foo==1.0.0\n'), |
| venvlib._VenvSpec('2.7.3', 'foo==1.0.0\n'), |
| ) |
| |
| def test_not_eq(self): |
| self.assertNotEqual( |
| venvlib._VenvSpec('2.7.3', 'foo==1.0.0\n'), |
| venvlib._VenvSpec('2.7.4', 'foo==1.0.0\n'), |
| ) |
| |
| @mock.patch.object(venvlib, '_get_python_version') |
| def test_make_spec(self, get_ver): |
| f = StringIO('foo==1.0.0\n') |
| get_ver.return_value = '1.7.6' |
| self.assertEqual( |
| venvlib.make_spec(f), |
| venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| ) |
| |
| def test__get_reqs_hash(self): |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| self.assertEqual(venvlib._get_reqs_hash(spec), |
| '5442279a613e6a2c4a93c9bda10e63f4') |
| |
| @mock.patch.object(venvlib, '_get_cache_dir') |
| def test__get_venvdir(self, get_cache_dir): |
| get_cache_dir.return_value = '/home/arland/.cache/cros_venv' |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| got = venvlib._get_venvdir(spec) |
| self.assertEqual( |
| got, |
| '/home/arland/.cache/cros_venv' |
| '/venv-1.7.6-5442279a613e6a2c4a93c9bda10e63f4') |
| |
| def test__get_venvdir_should_be_absolute(self): |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| got = venvlib._get_venvdir(spec) |
| self.assertTrue(got.startswith('/')) |
| |
| def test_dump_spec_and_load_spec(self): |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| f = StringIO() |
| venvlib._dump_spec(spec, f) |
| f.seek(0) |
| got = venvlib._load_spec(f) |
| self.assertEqual(spec, got) |
| |
| def test__make_reqs_file_should_cleanup(self): |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| with venvlib._make_reqs_file(spec) as f: |
| self.assertTrue(os.path.exists(f.name)) |
| self.assertFalse(os.path.exists(f.name)) |
| |
| def test__make_reqs_file_content(self): |
| spec = venvlib._VenvSpec('1.7.6', 'foo==1.0.0\n') |
| with venvlib._make_reqs_file(spec) as f, \ |
| open(f.name, 'r') as rfile: |
| self.assertEqual(rfile.read(), |
| 'setuptools==44.0.0\npip==20.0.2\nfoo==1.0.0\n') |