Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes test_cache, test_logger, test_infra, test_pipmanager to pytest, updated requirements.txt #363

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ install:

# Check that we have the expected version and architecture for Python
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""

build: off

test_script:
# Run the project tests
- "%CMD_IN_ENV% python bin/fades -v -r requirements.txt -x nosetests -v -s tests"
- "%CMD_IN_ENV% python bin/fades -v -r requirements.txt -x pytest"
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
language: python

python:
- "3.3"
- "3.4"
- "3.5"
- "3.6"
- "3.7-dev"
install:
- "pip install -r requirements.txt"
- if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then pip install python-coveralls ; fi
script:
- "nosetests --with-xcoverage --cover-package=fades -v fades tests"
- "pytest --cov=fades"
after_script:
- "flake8 fades --max-line-length=99 --select=E,W,F,C,N"

Expand Down
8 changes: 6 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
flake8==3.5.0
logassert==2
mccabe==0.6.1
nose==1.3.7
nosexcover==1.0.10
pep257==0.7.0
pep8==1.7.0
pycodestyle==2.3.1
Expand All @@ -12,3 +10,9 @@ pyxdg==0.25
rst2html5==1.9.3
setuptools>=5.5
wheel==0.26.0
coverage==4.0.3
pytest==4.4.2
pytest-xdist==1.28.0
pytest-sugar==0.9.2
pytest-cov==2.5.1
pytest-mock==1.10.4
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def finalize_options(self):
'install': CustomInstall,
},
install_requires=['setuptools'],
tests_require=['logassert', 'pyxdg', 'pyuca', 'nose', 'flake8',
tests_require=['logassert', 'pyxdg', 'pyuca', 'pytest', 'flake8',
'pep257', 'rst2html5'], # what unittests require
python_requires='>=3.3', # Minimum Python version supported.
extras_require={
Expand Down
2 changes: 1 addition & 1 deletion test
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fi

FADES='./bin/fades -r requirements.txt'

$FADES -x nosetests --with-xcoverage --cover-package=fades -v -s $TARGET_TESTS
$FADES -x pytest --cov=fades

# check if we are using exit() in the code.
if grep -r -n ' exit(' --include="*.py" .; then echo 'Please use sys.exit() instead of exit(). https://github.com/PyAr/fades/issues/280'; fi
2 changes: 1 addition & 1 deletion testdev
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ else
TARGET_TESTS="fades tests"
fi

./bin/fades -r requirements.txt -x nosetests -v -s $TARGET_TESTS
./bin/fades -r requirements.txt -x pytest
2 changes: 1 addition & 1 deletion testdev.bat
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ if not [%*] == [] (
set TARGET_TESTS=fades tests
)

bin\fades -r requirements.txt -x nosetests -v -s %TARGET_TESTS%
bin\fades -r requirements.txt -x pytest -v -s %TARGET_TESTS%
41 changes: 41 additions & 0 deletions tests/cache/test_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Tests for the helpers."""
from fades import cache


def test_missing_file_pytest(tmp_file, mocker):
venvscache = cache.VEnvsCache(str(tmp_file))
mock = mocker.patch.object(venvscache, '_select')
mock.return_value = None
resp = venvscache.get_venv('requirements', 'interpreter', uuid='', options='options')
mock.assert_called_with([], 'requirements', 'interpreter', uuid='', options='options')
assert not resp


def test_empty_file_pytest(tmp_file, mocker):
open(tmp_file, 'wt', encoding='utf8').close()
venvscache = cache.VEnvsCache(tmp_file)
mock = mocker.patch.object(venvscache, '_select', return_value=None)
resp = venvscache.get_venv('requirements', 'interpreter')
mock.assert_called_with([], 'requirements', 'interpreter', uuid='', options=None)
assert not resp


def test_some_file_content_pytest(tmp_file, mocker):
with open(tmp_file, 'wt', encoding='utf8') as fh:
fh.write('foo\nbar\n')
venvscache = cache.VEnvsCache(tmp_file)
mock = mocker.patch.object(venvscache, '_select', return_value="resp")
resp = venvscache.get_venv('requirements', 'interpreter', uuid='', options='options')
mock.assert_called_with(['foo', 'bar'], 'requirements', 'interpreter', uuid='',
options='options')
assert resp == 'resp'


def test_get_by_uuid_pytest(tmp_file, mocker):
with open(tmp_file, 'wt', encoding='utf8') as fh:
fh.write('foo\nbar\n')
venvscache = cache.VEnvsCache(tmp_file)
mock = mocker.patch.object(venvscache, '_select', return_value='resp')
resp = venvscache.get_venv(uuid='uuid')
mock.assert_called_with(['foo', 'bar'], None, '', uuid='uuid', options=None)
assert resp == 'resp'
98 changes: 98 additions & 0 deletions tests/cache/test_comparisons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import json
import pytest

from fades import parsing

from tests.conftest import get_req, get_distrib


@pytest.mark.parametrize("req,installed,expected", [
("==5", "5", "ok"),
("==5", "2", None),
(">5", "4", None),
(">5", "5", None),
(">5", "6", "ok"),
(">=5", "4", None),
(">=5", "5", "ok"),
(">=5", "6", "ok"),
("<5", "4", "ok"),
("<5", "5", None),
("<5", "6", None),
("<=5", "4", "ok"),
("<=5", "5", "ok"),
("<=5", "6", None),
("== 2.5", "2.5.0", "ok"),
("> 2.7", "2.12", "ok"),
("> 2.7a0", "2.7", "ok"),
("> 2.7", "2.7a0", None),
(">1.6,<1.9,!=1.9.6", "1.5.0", None),
(">1.6,<1.9,!=1.9.6", "1.6.7", "ok"),
(">1.6,<1.9,!=1.8.6", "1.8.7", "ok"),
(">1.6,<1.9,!=1.9.6", "1.9.6", None),
])
def test_check_versions(venvscache, req, installed, expected):
"""The comparison in the selection."""
reqs = {"pypi": get_req("dep" + req)}
interpreter = "pythonX.Y"
options = {"foo": "bar"}
venv = json.dumps({
"metadata": "ok",
"installed": {"pypi": {"dep": installed}},
"interpreter": "pythonX.Y",
"options": {"foo": "bar"}
})
resp = venvscache._select([venv], reqs, interpreter, uuid="", options=options)
assert resp == expected


@pytest.mark.parametrize("possible_venvs", [
[
(get_distrib(('dep', '3')), 'venv_best_fit'),
],
[
(get_distrib(('dep1', '3'), ('dep2', '3')), 'venv_best_fit'),
],
[
(get_distrib(('dep', '5')), 'venv_best_fit'),
(get_distrib(('dep', '3')), 'venv_1'),
],
[
(get_distrib(('dep1', '5'), ('dep2', '7')), 'venv_best_fit'),
(get_distrib(('dep1', '3'), ('dep2', '6')), 'venv_1'),
],
[
(get_distrib(('dep1', '3'), ('dep2', '9')), 'venv_1'),
(get_distrib(('dep1', '5'), ('dep2', '7')), 'venv_best_fit'),
],
[
(get_distrib(('dep1', '5'), ('dep2', '7')), 'venv_1'),
(get_distrib(('dep1', '3'), ('dep2', '9')), 'venv_best_fit'),
],
[
(get_distrib(('dep1', '3'), ('dep2', '9'), ('dep3', '4')), 'venv_best_fit'),
(get_distrib(('dep1', '5'), ('dep2', '7'), ('dep3', '2')), 'venv_1'),
],
[
(get_distrib(('dep2', '3'), ('dep1', '2'), ('dep3', '8')), 'venv_best_fit'),
(get_distrib(('dep1', '7'), ('dep3', '5'), ('dep2', '2')), 'venv_1'),
],
[
(get_distrib(('dep1', '3'), ('dep2', '2')), 'venv_1'),
(get_distrib(('dep1', '4'), ('dep2', '2')), 'venv_2'),
(get_distrib(('dep1', '5'), ('dep2', '7')), 'venv_best_fit'),
(get_distrib(('dep1', '5'), ('dep2', '6')), 'venv_3'),
],
[
([parsing.VCSDependency('someurl')], 'venv_best_fit'),
],
[
([parsing.VCSDependency('someurl')] + get_distrib(('dep', '3')), 'venv_best_fit'),
],
[
([parsing.VCSDependency('someurl')] + get_distrib(('dep', '3')), 'venv_best_fit'),
([parsing.VCSDependency('someurl')] + get_distrib(('dep', '1')), 'venv_1'),
],
])
def test_best_fit(venvscache, possible_venvs):
"""Check the venv best fitting decissor."""
assert venvscache._select_better_fit(possible_venvs) == 'venv_best_fit'
86 changes: 86 additions & 0 deletions tests/cache/test_remove.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import json
import os
import time
import pytest

from threading import Thread

from fades import cache


def test_missing_file(tmp_file):
venvscache = cache.VEnvsCache(tmp_file)
venvscache.remove('missing/path')

lines = venvscache._read_cache()
assert lines == []


def test_missing_env_in_cache(tmp_file):
venvscache = cache.VEnvsCache(tmp_file)
options = {'foo': 'bar'}
venvscache.store('installed', {'env_path': 'some/path'}, 'interpreter', options=options)
lines = venvscache._read_cache()
assert len(lines) == 1

venvscache.remove('some/path')

lines = venvscache._read_cache()
assert lines == []


def test_preserve_cache_data_ordering(tmp_file):
venvscache = cache.VEnvsCache(tmp_file)
# store 3 venvs
options = {'foo': 'bar'}
venvscache.store('installed1', {'env_path': 'path/env1'}, 'interpreter', options=options)
venvscache.store('installed2', {'env_path': 'path/env2'}, 'interpreter', options=options)
venvscache.store('installed3', {'env_path': 'path/env3'}, 'interpreter', options=options)

venvscache.remove('path/env2')

lines = venvscache._read_cache()
assert len(lines) == 2
assert json.loads(lines[0]).get('metadata').get('env_path') == 'path/env1'
assert json.loads(lines[1]).get('metadata').get('env_path') == 'path/env3'


@pytest.mark.skip(reason="I dont know why is not working with pytest")
def test_lock_cache_for_remove(tmp_file, mocker):
venvscache = cache.VEnvsCache(tmp_file)
# store 3 venvs
options = {'foo': 'bar'}
venvscache.store('installed1', {'env_path': 'path/env1'}, 'interpreter', options=options)
venvscache.store('installed2', {'env_path': 'path/env2'}, 'interpreter', options=options)
venvscache.store('installed3', {'env_path': 'path/env3'}, 'interpreter', options=options)

# patch _write_cache so it emulates a slow write during which
# another process managed to modify the cache file before the
# first process finished writing the modified cache data
original_write_cache = venvscache._write_cache
p = mocker.patch('fades.cache.VEnvsCache._write_cache')
mock_write_cache = p.start()

t1 = Thread(target=venvscache.remove, args=('path/env1',))

def slow_write_cache(*args, **kwargs):
p.stop()
t1.start()
# wait to ensure t1 thread must wait for lock to be released
time.sleep(0.01)
original_write_cache(*args, **kwargs)

mock_write_cache.side_effect = slow_write_cache

# just a sanity check
assert not os.path.exists(venvscache.filepath + '.lock')
# remove a virtualenv from the cache
venvscache.remove('path/env2')
t1.join()

# when cache file is properly locked both virtualenvs
# will have been removed from the cache
lines = venvscache._read_cache()
assert len(lines) == 1
assert json.loads(lines[0]).get('metadata').get('env_path') == 'path/env3'
assert not os.path.exists(venvscache.filepath + '.lock')
Loading