Skip to content

Commit

Permalink
Add cd helper
Browse files Browse the repository at this point in the history
Signed-off-by: Cristian Le <[email protected]>
  • Loading branch information
LecrisUT committed Jun 17, 2024
1 parent 6af5881 commit 7a6f1c9
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 102 deletions.
19 changes: 19 additions & 0 deletions fmf/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" Logging, config, constants & utilities """

import contextlib
import copy
import logging
import os
Expand Down Expand Up @@ -191,6 +192,24 @@ def info(message, newline=True):
sys.stderr.write(message + ("\n" if newline else ""))


@contextlib.contextmanager
def cd(target):
"""
Manage cd in a pushd/popd fashion.
Usage:
with cd(tmpdir):
do something in tmpdir
"""
curdir = os.getcwd()
os.chdir(target)
try:
yield
finally:
os.chdir(curdir)


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Filtering
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
68 changes: 34 additions & 34 deletions tests/unit/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,42 +228,42 @@ def test_find_root(self):
tree = Tree(os.path.join(EXAMPLES, "wget", "protocols"))
assert tree.find("/download/test")

def test_yaml_syntax_errors(self):
def test_yaml_syntax_errors(self, tmp_path):
""" Handle YAML syntax errors """
path = tempfile.mkdtemp()
fmf.cli.main("fmf init", path)
with open(os.path.join(path, "main.fmf"), "w") as main:
main.write("missing\ncolon:")
with pytest.raises(utils.FileError):
fmf.Tree(path)
rmtree(path)

def test_yaml_duplicate_keys(self):
with utils.cd(tmp_path):
fmf.cli.main("fmf init")
with (tmp_path / "main.fmf").open("w") as main:
main.write("missing\ncolon:")
with pytest.raises(utils.FileError):
fmf.Tree(".")
rmtree(tmp_path)

def test_yaml_duplicate_keys(self, tmp_path):
""" Handle YAML duplicate keys """
path = tempfile.mkdtemp()
fmf.cli.main("fmf init", path)

# Simple test
with open(os.path.join(path, "main.fmf"), "w") as main:
main.write("a: b\na: c\n")
with pytest.raises(utils.FileError):
fmf.Tree(path)

# Add some hierarchy
subdir = os.path.join(path, "dir")
os.makedirs(subdir)
with open(os.path.join(subdir, "a.fmf"), "w") as new_file:
new_file.write("a: d\n")
with pytest.raises(utils.FileError):
fmf.Tree(path)

# Remove duplicate key, check that inheritance doesn't
# raise an exception
with open(os.path.join(path, "main.fmf"), "w") as main:
main.write("a: b\n")
fmf.Tree(path)

rmtree(path)
with utils.cd(tmp_path):
fmf.cli.main("fmf init")

# Simple test
with (tmp_path / "main.fmf").open("w") as main:
main.write("a: b\na: c\n")
with pytest.raises(utils.FileError):
fmf.Tree(".")

# Add some hierarchy
subdir = tmp_path / "dir"
subdir.mkdir()
with (subdir / "a.fmf").open("w") as new_file:
new_file.write("a: d\n")
with pytest.raises(utils.FileError):
fmf.Tree(".")

# Remove duplicate key, check that inheritance doesn't
# raise an exception
with (tmp_path / "main.fmf").open("w") as main:
main.write("a: b\n")
fmf.Tree(".")

rmtree(tmp_path)

def test_inaccessible_directories(self):
""" Inaccessible directories should be silently ignored """
Expand Down
139 changes: 74 additions & 65 deletions tests/unit/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import sys
import tempfile

import pytest

Expand All @@ -17,15 +16,17 @@ class TestCommandLine:

def test_smoke(self):
""" Smoke test """
fmf.cli.main("fmf show", WGET)
fmf.cli.main("fmf show --debug", WGET)
fmf.cli.main("fmf show --verbose", WGET)
with utils.cd(WGET):
fmf.cli.main("fmf show")
fmf.cli.main("fmf show --debug")
fmf.cli.main("fmf show --verbose")
fmf.cli.main("fmf --version")

def test_missing_root(self):
""" Missing root """
with pytest.raises(utils.FileError):
fmf.cli.main("fmf show", "/")
with utils.cd("/"):
with pytest.raises(utils.FileError):
fmf.cli.main("fmf show")

def test_invalid_path(self):
""" Missing root """
Expand All @@ -39,17 +40,20 @@ def test_wrong_command(self):

def test_output(self):
""" There is some output """
output = fmf.cli.main("fmf show", WGET)
with utils.cd(WGET):
output = fmf.cli.main("fmf show")
assert "download" in output

def test_recursion(self):
""" Recursion """
output = fmf.cli.main("fmf show --name recursion/deep", WGET)
with utils.cd(WGET):
output = fmf.cli.main("fmf show --name recursion/deep")
assert "1000" in output

def test_inheritance(self):
""" Inheritance """
output = fmf.cli.main("fmf show --name protocols/https", WGET)
with utils.cd(WGET):
output = fmf.cli.main("fmf show --name protocols/https")
assert "psplicha" in output

def test_sys_argv(self):
Expand All @@ -62,30 +66,34 @@ def test_sys_argv(self):

def test_missing_attribute(self):
""" Missing attribute """
output = fmf.cli.main("fmf show --filter x:y", WGET)
with utils.cd(WGET):
output = fmf.cli.main("fmf show --filter x:y")
assert "wget" not in output

def test_filtering_by_source(self):
""" By source """
output = fmf.cli.main("fmf show --source protocols/ftp/main.fmf", WGET)
with utils.cd(WGET):
output = fmf.cli.main("fmf show --source protocols/ftp/main.fmf")
assert "/protocols/ftp" in output

def test_filtering(self):
""" Filtering """
output = fmf.cli.main(
"fmf show --filter tags:Tier1 --filter tags:TierSecurity", WGET)
assert "/download/test" in output
output = fmf.cli.main(
"fmf show --filter tags:Tier1 --filter tags:Wrong", WGET)
assert "wget" not in output
output = fmf.cli.main(
" fmf show --filter 'tags: Tier[A-Z].*'", WGET)
assert "/download/test" in output
assert "/recursion" not in output
with utils.cd(WGET):
output = fmf.cli.main(
"fmf show --filter tags:Tier1 --filter tags:TierSecurity")
assert "/download/test" in output
output = fmf.cli.main(
"fmf show --filter tags:Tier1 --filter tags:Wrong")
assert "wget" not in output
output = fmf.cli.main(
" fmf show --filter 'tags: Tier[A-Z].*'")
assert "/download/test" in output
assert "/recursion" not in output

def test_key_content(self):
""" Key content """
output = fmf.cli.main("fmf show --key depth")
with utils.cd(WGET):
output = fmf.cli.main("fmf show --key depth")
assert "/recursion/deep" in output
assert "/download/test" not in output

Expand All @@ -97,63 +105,64 @@ def test_format_basic(self):

def test_format_key(self):
""" Custom format (find by key, check the name) """
output = fmf.cli.main(
"fmf show --key depth --format {0} --value name", WGET)
with utils.cd(WGET):
output = fmf.cli.main(
"fmf show --key depth --format {0} --value name")
assert "/recursion/deep" in output

def test_format_functions(self):
""" Custom format (using python functions) """
output = fmf.cli.main(
"fmf show --key depth --format {0} --value os.path.basename(name)",
WGET)
with utils.cd(WGET):
output = fmf.cli.main(
"fmf show --key depth --format {0} --value os.path.basename(name)")
assert "deep" in output
assert "/recursion" not in output

@pytest.mark.skipif(os.geteuid() == 0, reason="Running as root")
def test_init(self):
def test_init(self, tmp_path):
""" Initialize metadata tree """
path = tempfile.mkdtemp()
fmf.cli.main("fmf init", path)
fmf.cli.main("fmf show", path)
# Already exists
with pytest.raises(utils.FileError):
fmf.cli.main("fmf init", path)
version_path = os.path.join(path, ".fmf", "version")
with open(version_path) as version:
assert "1" in version.read()
# Permission denied
secret_path = os.path.join(path, 'denied')
os.makedirs(secret_path)
os.chmod(secret_path, 0o666)
with pytest.raises(utils.FileError):
fmf.cli.main('fmf init --path {}'.format(secret_path), path)
os.chmod(secret_path, 0o777)
# Invalid version
with open(version_path, "w") as version:
version.write("bad")
with pytest.raises(utils.FormatError):
fmf.cli.main("fmf ls", path)
# Missing version
os.remove(version_path)
with pytest.raises(utils.FormatError):
fmf.cli.main("fmf ls", path)
with utils.cd(tmp_path):
fmf.cli.main("fmf init")
fmf.cli.main("fmf show")
# Already exists
with pytest.raises(utils.FileError):
fmf.cli.main("fmf init")
version_path = tmp_path / ".fmf" / "version"
with version_path.open() as version:
assert "1" in version.read()
# Permission denied
secret_path = tmp_path / "denied"
secret_path.mkdir(0o666)
with pytest.raises(utils.FileError):
fmf.cli.main('fmf init --path {}'.format(secret_path))
secret_path.chmod(0o777)
# Invalid version
with version_path.open("w") as version:
version.write("bad")
with pytest.raises(utils.FormatError):
fmf.cli.main("fmf ls")
# Missing version
version_path.unlink()
with pytest.raises(utils.FormatError):
fmf.cli.main("fmf ls")

def test_conditions(self):
""" Advanced filters via conditions """
path = PATH + "/../../examples/conditions"
# Compare numbers
output = fmf.cli.main("fmf ls --condition 'float(release) >= 7'", path)
assert len(output.splitlines()) == 3
output = fmf.cli.main("fmf ls --condition 'float(release) > 7'", path)
assert len(output.splitlines()) == 2
# Access a dictionary key
output = fmf.cli.main(
"fmf ls --condition \"execute['how'] == 'dependency'\"", path)
assert output.strip() == "/top/rhel7"
# Wrong key means unsatisfied condition
output = fmf.cli.main(
"fmf ls --condition \"execute['wrong key'] == 0\"", path)
assert output == ''
with utils.cd(path):
output = fmf.cli.main("fmf ls --condition 'float(release) >= 7'")
assert len(output.splitlines()) == 3
output = fmf.cli.main("fmf ls --condition 'float(release) > 7'")
assert len(output.splitlines()) == 2
# Access a dictionary key
output = fmf.cli.main(
"fmf ls --condition \"execute['how'] == 'dependency'\"")
assert output.strip() == "/top/rhel7"
# Wrong key means unsatisfied condition
output = fmf.cli.main(
"fmf ls --condition \"execute['wrong key'] == 0\"")
assert output == ''

def test_clean(self, tmpdir, monkeypatch):
""" Cache cleanup """
Expand Down
9 changes: 6 additions & 3 deletions tests/unit/test_smoke.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os

import fmf.cli
import fmf.utils as utils

# Prepare path to examples
PATH = os.path.dirname(os.path.realpath(__file__))
Expand All @@ -12,9 +13,11 @@ class TestSmoke:

def test_smoke(self):
""" Smoke test """
fmf.cli.main("fmf ls", WGET)
with utils.cd(WGET):
fmf.cli.main("fmf ls")

def test_output(self):
""" There is some output """
output = fmf.cli.main("fmf ls", WGET)
assert "download" in output
with utils.cd(WGET):
output = fmf.cli.main("fmf ls")
assert "download" in output

0 comments on commit 7a6f1c9

Please sign in to comment.