summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-07-17 07:38:15 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-07-17 07:38:15 +0000
commitd7666fa97c8bbaced14dadba189f0d5064d67821 (patch)
treeb67672fefc0275e3ac26e2deed8b87e17ee6cd5c /tests
parentReleasing debian version 2.12.1-1. (diff)
downloadpre-commit-d7666fa97c8bbaced14dadba189f0d5064d67821.tar.xz
pre-commit-d7666fa97c8bbaced14dadba189f0d5064d67821.zip
Merging upstream version 2.13.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/commands/run_test.py37
-rw-r--r--tests/conftest.py4
-rw-r--r--tests/languages/docker_test.py147
-rw-r--r--tests/languages/r_test.py29
-rw-r--r--tests/languages/ruby_test.py8
-rw-r--r--tests/store_test.py2
6 files changed, 208 insertions, 19 deletions
diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py
index 4cd70fd..e184340 100644
--- a/tests/commands/run_test.py
+++ b/tests/commands/run_test.py
@@ -526,9 +526,9 @@ def test_merge_conflict(cap_out, store, in_merge_conflict):
def test_merge_conflict_modified(cap_out, store, in_merge_conflict):
# Touch another file so we have unstaged non-conflicting things
- assert os.path.exists('dummy')
- with open('dummy', 'w') as dummy_file:
- dummy_file.write('bar\nbaz\n')
+ assert os.path.exists('placeholder')
+ with open('placeholder', 'w') as placeholder_file:
+ placeholder_file.write('bar\nbaz\n')
ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts())
assert ret == 1
@@ -600,6 +600,29 @@ def test_skip_aliased_hook(cap_out, store, aliased_repo):
assert printed.count(msg) == 1
+def test_skip_bypasses_installation(cap_out, store, repo_with_passing_hook):
+ config = {
+ 'repo': 'local',
+ 'hooks': [
+ {
+ 'id': 'skipme',
+ 'name': 'skipme',
+ 'entry': 'skipme',
+ 'language': 'python',
+ 'additional_dependencies': ['/pre-commit-does-not-exist'],
+ },
+ ],
+ }
+ add_config_to_repo(repo_with_passing_hook, config)
+
+ ret, printed = _do_run(
+ cap_out, store, repo_with_passing_hook,
+ run_opts(all_files=True),
+ {'SKIP': 'skipme'},
+ )
+ assert ret == 0
+
+
def test_hook_id_not_in_non_verbose_output(
cap_out, store, repo_with_passing_hook,
):
@@ -808,9 +831,9 @@ def test_local_hook_passes(cap_out, store, repo_with_passing_hook):
}
add_config_to_repo(repo_with_passing_hook, config)
- with open('dummy.py', 'w') as staged_file:
+ with open('placeholder.py', 'w') as staged_file:
staged_file.write('"""TODO: something"""\n')
- cmd_output('git', 'add', 'dummy.py')
+ cmd_output('git', 'add', 'placeholder.py')
_test_run(
cap_out,
@@ -835,9 +858,9 @@ def test_local_hook_fails(cap_out, store, repo_with_passing_hook):
}
add_config_to_repo(repo_with_passing_hook, config)
- with open('dummy.py', 'w') as staged_file:
+ with open('placeholder.py', 'w') as staged_file:
staged_file.write('"""TODO: something"""\n')
- cmd_output('git', 'add', 'dummy.py')
+ cmd_output('git', 'add', 'placeholder.py')
_test_run(
cap_out,
diff --git a/tests/conftest.py b/tests/conftest.py
index b36ce5a..f38f969 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -90,8 +90,8 @@ def _make_conflict():
@pytest.fixture
def in_merge_conflict(tempdir_factory):
path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
- open(os.path.join(path, 'dummy'), 'a').close()
- cmd_output('git', 'add', 'dummy', cwd=path)
+ open(os.path.join(path, 'placeholder'), 'a').close()
+ cmd_output('git', 'add', 'placeholder', cwd=path)
git_commit(msg=in_merge_conflict.__name__, cwd=path)
conflict_path = tempdir_factory.get()
diff --git a/tests/languages/docker_test.py b/tests/languages/docker_test.py
index 3bed4bf..01b5e27 100644
--- a/tests/languages/docker_test.py
+++ b/tests/languages/docker_test.py
@@ -1,14 +1,155 @@
+import builtins
+import json
+import ntpath
+import os.path
+import posixpath
from unittest import mock
+import pytest
+
from pre_commit.languages import docker
def test_docker_fallback_user():
def invalid_attribute():
raise AttributeError
+
with mock.patch.multiple(
- 'os', create=True,
- getuid=invalid_attribute,
- getgid=invalid_attribute,
+ 'os', create=True,
+ getuid=invalid_attribute,
+ getgid=invalid_attribute,
):
assert docker.get_docker_user() == ()
+
+
+def test_in_docker_no_file():
+ with mock.patch.object(builtins, 'open', side_effect=FileNotFoundError):
+ assert docker._is_in_docker() is False
+
+
+def _mock_open(data):
+ return mock.patch.object(
+ builtins,
+ 'open',
+ new_callable=mock.mock_open,
+ read_data=data,
+ )
+
+
+def test_in_docker_docker_in_file():
+ docker_cgroup_example = b'''\
+12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+11:blkio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+10:freezer:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+9:cpu,cpuacct:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+8:pids:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+7:rdma:/
+6:net_cls,net_prio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+5:cpuset:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+4:devices:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+3:memory:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+2:perf_event:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+1:name=systemd:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
+0::/system.slice/containerd.service
+''' # noqa: E501
+ with _mock_open(docker_cgroup_example):
+ assert docker._is_in_docker() is True
+
+
+def test_in_docker_docker_not_in_file():
+ non_docker_cgroup_example = b'''\
+12:perf_event:/
+11:hugetlb:/
+10:devices:/
+9:blkio:/
+8:rdma:/
+7:cpuset:/
+6:cpu,cpuacct:/
+5:freezer:/
+4:memory:/
+3:pids:/
+2:net_cls,net_prio:/
+1:name=systemd:/init.scope
+0::/init.scope
+'''
+ with _mock_open(non_docker_cgroup_example):
+ assert docker._is_in_docker() is False
+
+
+def test_get_docker_path_not_in_docker_returns_same():
+ with mock.patch.object(docker, '_is_in_docker', return_value=False):
+ assert docker._get_docker_path('abc') == 'abc'
+
+
+@pytest.fixture
+def in_docker():
+ with mock.patch.object(docker, '_is_in_docker', return_value=True):
+ yield
+
+
+def _linux_commonpath():
+ return mock.patch.object(os.path, 'commonpath', posixpath.commonpath)
+
+
+def _nt_commonpath():
+ return mock.patch.object(os.path, 'commonpath', ntpath.commonpath)
+
+
+def _docker_output(out):
+ ret = (0, out, b'')
+ return mock.patch.object(docker, 'cmd_output_b', return_value=ret)
+
+
+def test_get_docker_path_in_docker_no_binds_same_path(in_docker):
+ docker_out = json.dumps([{'Mounts': []}]).encode()
+
+ with _docker_output(docker_out):
+ assert docker._get_docker_path('abc') == 'abc'
+
+
+def test_get_docker_path_in_docker_binds_path_equal(in_docker):
+ binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}]
+ docker_out = json.dumps([{'Mounts': binds_list}]).encode()
+
+ with _linux_commonpath(), _docker_output(docker_out):
+ assert docker._get_docker_path('/project') == '/opt/my_code'
+
+
+def test_get_docker_path_in_docker_binds_path_complex(in_docker):
+ binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}]
+ docker_out = json.dumps([{'Mounts': binds_list}]).encode()
+
+ with _linux_commonpath(), _docker_output(docker_out):
+ path = '/project/test/something'
+ assert docker._get_docker_path(path) == '/opt/my_code/test/something'
+
+
+def test_get_docker_path_in_docker_no_substring(in_docker):
+ binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}]
+ docker_out = json.dumps([{'Mounts': binds_list}]).encode()
+
+ with _linux_commonpath(), _docker_output(docker_out):
+ path = '/projectSuffix/test/something'
+ assert docker._get_docker_path(path) == path
+
+
+def test_get_docker_path_in_docker_binds_path_many_binds(in_docker):
+ binds_list = [
+ {'Source': '/something_random', 'Destination': '/not-related'},
+ {'Source': '/opt/my_code', 'Destination': '/project'},
+ {'Source': '/something-random-2', 'Destination': '/not-related-2'},
+ ]
+ docker_out = json.dumps([{'Mounts': binds_list}]).encode()
+
+ with _linux_commonpath(), _docker_output(docker_out):
+ assert docker._get_docker_path('/project') == '/opt/my_code'
+
+
+def test_get_docker_path_in_docker_windows(in_docker):
+ binds_list = [{'Source': r'c:\users\user', 'Destination': r'c:\folder'}]
+ docker_out = json.dumps([{'Mounts': binds_list}]).encode()
+
+ with _nt_commonpath(), _docker_output(docker_out):
+ path = r'c:\folder\test\something'
+ expected = r'c:\users\user\test\something'
+ assert docker._get_docker_path(path) == expected
diff --git a/tests/languages/r_test.py b/tests/languages/r_test.py
index 5c046ef..66aa7b3 100644
--- a/tests/languages/r_test.py
+++ b/tests/languages/r_test.py
@@ -14,10 +14,12 @@ def _test_r_parsing(
hook_id,
expected_hook_expr={},
expected_args={},
+ config={},
+ expect_path_prefix=True,
):
repo_path = 'r_hooks_repo'
path = make_repo(tempdir_factory, repo_path)
- config = make_config_from_repo(path)
+ config = config or make_config_from_repo(path)
hook = _get_hook_no_install(config, store, hook_id)
ret = r._cmd_from_hook(hook)
expected_cmd = 'Rscript'
@@ -25,7 +27,8 @@ def _test_r_parsing(
'--no-save', '--no-restore', '--no-site-file', '--no-environ',
)
expected_path = os.path.join(
- hook.prefix.prefix_dir, '.'.join([hook_id, 'R']),
+ hook.prefix.prefix_dir if expect_path_prefix else '',
+ f'{hook_id}.R',
)
expected = (
expected_cmd,
@@ -102,3 +105,25 @@ def test_r_parsing_expr_non_Rscirpt(tempdir_factory, store):
msg = execinfo.value.args
assert msg == ('entry must start with `Rscript`.',)
+
+
+def test_r_parsing_file_local(tempdir_factory, store):
+ path = 'path/to/script.R'
+ hook_id = 'local-r'
+ config = {
+ 'repo': 'local',
+ 'hooks': [{
+ 'id': hook_id,
+ 'name': 'local-r',
+ 'entry': f'Rscript {path}',
+ 'language': 'r',
+ }],
+ }
+ _test_r_parsing(
+ tempdir_factory,
+ store,
+ hook_id=hook_id,
+ expected_hook_expr=(path,),
+ config=config,
+ expect_path_prefix=False,
+ )
diff --git a/tests/languages/ruby_test.py b/tests/languages/ruby_test.py
index 0c6cfed..7dff046 100644
--- a/tests/languages/ruby_test.py
+++ b/tests/languages/ruby_test.py
@@ -36,13 +36,13 @@ def test_uses_system_if_both_gem_and_ruby_are_available(find_exe_mck):
def fake_gem_prefix(tmpdir):
gemspec = '''\
Gem::Specification.new do |s|
- s.name = 'pre_commit_dummy_package'
+ s.name = 'pre_commit_placeholder_package'
s.version = '0.0.0'
- s.summary = 'dummy gem for pre-commit hooks'
+ s.summary = 'placeholder gem for pre-commit hooks'
s.authors = ['Anthony Sottile']
end
'''
- tmpdir.join('dummy_gem.gemspec').write(gemspec)
+ tmpdir.join('placeholder_gem.gemspec').write(gemspec)
yield Prefix(tmpdir)
@@ -53,7 +53,7 @@ def test_install_ruby_system(fake_gem_prefix):
# Should be able to activate and use rbenv install
with ruby.in_env(fake_gem_prefix, 'system'):
_, out, _ = cmd_output('gem', 'list')
- assert 'pre_commit_dummy_package' in out
+ assert 'pre_commit_placeholder_package' in out
@xfailif_windows # pragma: win32 no cover
diff --git a/tests/store_test.py b/tests/store_test.py
index 0947144..5a5d69e 100644
--- a/tests/store_test.py
+++ b/tests/store_test.py
@@ -186,7 +186,7 @@ def test_local_resources_reflects_reality():
for res in os.listdir('pre_commit/resources')
if res.startswith('empty_template_')
}
- assert on_disk == set(Store.LOCAL_RESOURCES)
+ assert on_disk == {os.path.basename(x) for x in Store.LOCAL_RESOURCES}
def test_mark_config_as_used(store, tmpdir):