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

Add status check for Symlink check #1394

Merged
merged 17 commits into from
Feb 21, 2023
Merged
Show file tree
Hide file tree
Changes from 7 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
6 changes: 6 additions & 0 deletions buildtest/builders/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
exists_check,
is_dir_check,
is_file_check,
is_symlink_check,
notcontains_check,
regex_check,
returncode_check,
Expand Down Expand Up @@ -969,6 +970,7 @@ def check_test_state(self):
assert_range_match = False
assert_contains_match = False
assert_notcontains_match = False
assert_is_symlink = False
assert_exists = False
assert_is_dir = False
assert_is_file = False
Expand Down Expand Up @@ -1024,6 +1026,9 @@ def check_test_state(self):
if self.status.get("not_contains"):
assert_notcontains_match = notcontains_check(self)

if self.status.get("is_symlink"):
assert_is_symlink = is_symlink_check(builder=self)

if self.status.get("exists"):
assert_exists = exists_check(builder=self)

Expand Down Expand Up @@ -1051,6 +1056,7 @@ def check_test_state(self):
assert_range_match,
assert_contains_match,
assert_notcontains_match,
assert_is_symlink,
assert_exists,
assert_is_dir,
assert_is_file,
Expand Down
34 changes: 33 additions & 1 deletion buildtest/buildsystem/checks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import logging
import os.path
import re

from buildtest.defaults import console
from buildtest.utils.file import is_dir, is_file, resolve_path
from buildtest.utils.file import is_dir, is_file, is_symlink, resolve_path

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -151,6 +152,37 @@ def regex_check(builder):
return True


def is_symlink_check(builder):
"""This method will perform symlink status check for ``is_symlink`` property. Each item is tested for symblolic link
and returns a boolean to inform if all items are symbolic links or not.

Args:
builder (buildtest.builders.base.BuilderBase): An instance of BuilderBase class used for printing the builder name
Returns:
bool: A boolean for is_symlink status check
"""
assert_exists = []
console.print(
f"[blue]{builder}[/]: Check all items: {builder.status['is_symlink']} for symbolic links"
)
for sym_link in builder.status["is_symlink"]:

if is_symlink(sym_link):
console.print(
f"[blue]{builder}[/]: {sym_link} is a symbolic link to {resolve_path(sym_link)}"
)
assert_exists.append(True)
else:
console.print(
f"[blue]{builder}[/]: {sym_link} is broken or not a symbolic link"
)
assert_exists.append(False)

bool_check = all(assert_exists)
console.print(f"[blue]{builder}[/]: Symlink Check: {bool_check}")
return bool_check


def exists_check(builder):
"""This method will perform status check for ``exists`` property. Each value is tested for file
existence and returns a boolean to inform if all files exist or not.
Expand Down
4 changes: 4 additions & 0 deletions buildtest/schemas/definitions.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@
}
}
},
"is_symlink": {
"description": "Check for list of files or directory paths that are symbolic links",
"$ref": "#/definitions/list_of_strings"
},
"exists": {
"description": "Check for list of file or directory path for existences using os.path.exists",
"$ref": "#/definitions/list_of_strings"
Expand Down
22 changes: 22 additions & 0 deletions buildtest/utils/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,28 @@ def is_dir(dirname):
return os.path.isdir(dirname)


def is_symlink(filename):
"""Check if the given link is a symlink and return ``True``, if it is not a symlink or the symlink is broken return ``False``.

Args:
filename (str): Input filename to check if its a symbolic link

Returns:
bool: True if filename is a symbolic link otherwise return False if its not a symbolic link or broken link
"""

# apply shell expansion when file includes something like $HOME/example
expanded_filepath = os.path.expandvars(filename)

# apply user expansion when file includes something like ~/example
expanded_filepath = os.path.expanduser(expanded_filepath)

# resolve path will return canonical path eliminating any symbolic links encountered
resolved_sym_link = resolve_path(filename)

return os.path.islink(expanded_filepath) and resolved_sym_link


def walk_tree(root_dir, ext=None):
"""This method will traverse a directory tree and return list of files
based on extension type. This method invokes :func:`is_dir` to check if directory
Expand Down
1 change: 1 addition & 0 deletions tests/builders/is_symlink.yml
9 changes: 9 additions & 0 deletions tests/builders/test_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ def test_assert_range():
cmd.build()


def test_assert_is_symlink():
cmd = BuildTest(
buildspecs=[os.path.join(here, "is_symlink.yml")],
buildtest_system=system,
configuration=config,
)
cmd.build()


def test_assert_exists():
cmd = BuildTest(
buildspecs=[os.path.join(here, "exists.yml")],
Expand Down
13 changes: 13 additions & 0 deletions tutorials/test_status/is_symlink.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
buildspecs:
symlink_test:
type: script
executor: generic.local.bash
description: status check based on symbolic link
run: |
ln -s /tmp scratch
ln -s $HOME/.bash_profile $HOME/bash_profile
status:
is_symlink:
- scratch
- $HOME/bash_profile
- ~/bash_profile