blob: 0d888e77dd8f00c1e4b1584ff9ae6bceda46013d [file] [log] [blame] [edit]
# 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')