75c9028095
- Enable new upgrade path for RHEL 8.10 -> RHEL 9.4 (including RHEL with SAP HANA) - Introduce generic transition of systemd services states during the IPU - Introduce possibility to upgrade with local repositories - Improve possibilities of upgrade when a proxy is configured in DNF configutation file - Fix handling of symlinks under /etc/pki when managing certificates - Fix the upgrade with custom https repositories - Default to the NO_RHSM mode when subscription-manager is not installed - Detect customized configuration of dynamic linker - Drop the invalid `tuv` target channel for the --channel option - Fix the issue of going out of bounds in the isccfg parser - Fix traceback when saving the rhsm facts results and the /etc/rhsm/facts directory doesn’t exist yet - Load all rpm repository substitutions that dnf knows about, not just "releasever" only - Simplify handling of upgrades on systems using RHUI, reducing the maintenance burden for cloud providers - Detect possible unexpected RPM GPG keys has been installed during RPM transaction - Resolves: RHEL-16729
173 lines
7.0 KiB
Diff
173 lines
7.0 KiB
Diff
From 6ae2d5aadbf6a626cf27ca4594a3945e2c249122 Mon Sep 17 00:00:00 2001
|
|
From: mhecko <mhecko@redhat.com>
|
|
Date: Tue, 1 Aug 2023 12:44:47 +0200
|
|
Subject: [PATCH 14/38] makefile: add dev_test_no_lint target
|
|
|
|
Add a target for testing individual actors with almost-instant
|
|
execution time. Testing individual actors currently involves
|
|
a process in which every actor is instantiated in a separate
|
|
process, the created instance reports actor information such as actor's
|
|
name and then exits. As many processes are created, this process is
|
|
time consuming (cca 7s) which disrupts developer's workflow and causes
|
|
attention shift.
|
|
|
|
A newly added target `dev_test_no_lint` uses an introduced script
|
|
`find_actors`. To achieve the similar level of framework protection
|
|
as spawning actors in a separate process, the `find_actors` script
|
|
does not execute actors at all, and instead works on their ASTs.
|
|
Specifically, the script looks for all files named `actor.py`, finds
|
|
all classes that (explicitely) subclass Actor, and reads its `name`
|
|
attribute.
|
|
|
|
Usage example:
|
|
ACTOR=check_target_iso make dev_test_no_lint
|
|
---
|
|
Makefile | 15 +++++---
|
|
utils/find_actors.py | 81 ++++++++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 91 insertions(+), 5 deletions(-)
|
|
create mode 100644 utils/find_actors.py
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index b63192e3..e3c40e01 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -16,9 +16,12 @@ REPOSITORIES ?= $(shell ls $(_SYSUPG_REPOS) | xargs echo | tr " " ",")
|
|
SYSUPG_TEST_PATHS=$(shell echo $(REPOSITORIES) | sed -r "s|(,\\|^)| $(_SYSUPG_REPOS)/|g")
|
|
TEST_PATHS:=commands repos/common $(SYSUPG_TEST_PATHS)
|
|
|
|
+# python version to run test with
|
|
+_PYTHON_VENV=$${PYTHON_VENV:-python2.7}
|
|
|
|
ifdef ACTOR
|
|
- TEST_PATHS=`python utils/actor_path.py $(ACTOR)`
|
|
+ TEST_PATHS=`$(_PYTHON_VENV) utils/actor_path.py $(ACTOR)`
|
|
+ APPROX_TEST_PATHS=$(shell $(_PYTHON_VENV) utils/find_actors.py -C repos $(ACTOR)) # Dev only
|
|
endif
|
|
|
|
ifeq ($(TEST_LIBS),y)
|
|
@@ -32,9 +35,6 @@ endif
|
|
# needed only in case the Python2 should be used
|
|
_USE_PYTHON_INTERPRETER=$${_PYTHON_INTERPRETER}
|
|
|
|
-# python version to run test with
|
|
-_PYTHON_VENV=$${PYTHON_VENV:-python2.7}
|
|
-
|
|
# by default use values you can see below, but in case the COPR_* var is defined
|
|
# use it instead of the default
|
|
_COPR_REPO=$${COPR_REPO:-leapp}
|
|
@@ -127,6 +127,7 @@ help:
|
|
@echo " - can be changed by setting TEST_CONTAINER env"
|
|
@echo " test_container_all run lint and tests in all available containers"
|
|
@echo " test_container_no_lint run tests without linting in container, see test_container"
|
|
+ @echo " dev_test_no_lint (advanced users) run only tests of a single actor specified by the ACTOR variable"
|
|
@echo " test_container_all_no_lint run tests without linting in all available containers"
|
|
@echo " clean_containers clean all testing and building container images (to force a rebuild for example)"
|
|
@echo ""
|
|
@@ -486,6 +487,10 @@ fast_lint:
|
|
echo "No files to lint."; \
|
|
fi
|
|
|
|
+dev_test_no_lint:
|
|
+ . $(VENVNAME)/bin/activate; \
|
|
+ $(_PYTHON_VENV) -m pytest $(REPORT_ARG) $(APPROX_TEST_PATHS) $(LIBRARY_PATH)
|
|
+
|
|
dashboard_data:
|
|
. $(VENVNAME)/bin/activate; \
|
|
snactor repo find --path repos/; \
|
|
@@ -494,4 +499,4 @@ dashboard_data:
|
|
popd
|
|
|
|
.PHONY: help build clean prepare source srpm copr_build _build_local build_container print_release register install-deps install-deps-fedora lint test_no_lint test dashboard_data fast_lint
|
|
-.PHONY: test_container test_container_no_lint test_container_all test_container_all_no_lint clean_containers _build_container_image _test_container_ipu
|
|
+.PHONY: test_container test_container_no_lint test_container_all test_container_all_no_lint clean_containers _build_container_image _test_container_ipu dev_test_no_lint
|
|
diff --git a/utils/find_actors.py b/utils/find_actors.py
|
|
new file mode 100644
|
|
index 00000000..25cc2217
|
|
--- /dev/null
|
|
+++ b/utils/find_actors.py
|
|
@@ -0,0 +1,81 @@
|
|
+import argparse
|
|
+import ast
|
|
+import os
|
|
+import sys
|
|
+
|
|
+
|
|
+def is_direct_actor_def(ast_node):
|
|
+ if not isinstance(ast_node, ast.ClassDef):
|
|
+ return False
|
|
+
|
|
+ direcly_named_bases = (base for base in ast_node.bases if isinstance(base, ast.Name))
|
|
+ for class_base in direcly_named_bases:
|
|
+ # We are looking for direct name 'Actor'
|
|
+ if class_base.id == 'Actor':
|
|
+ return True
|
|
+
|
|
+ return False
|
|
+
|
|
+
|
|
+def extract_actor_name_from_def(actor_class_def):
|
|
+ assignment_value_class = ast.Str if sys.version_info < (3,8) else ast.Constant
|
|
+ assignment_value_attrib = 's' if sys.version_info < (3,8) else 'value'
|
|
+
|
|
+ actor_name = None
|
|
+ class_level_assignments = (child for child in actor_class_def.body if isinstance(child, ast.Assign))
|
|
+ # Search for class-level assignment specifying actor's name: `name = 'name'`
|
|
+ for child in class_level_assignments:
|
|
+ assignment = child
|
|
+ for target in assignment.targets:
|
|
+ assignment_adds_name_attrib = isinstance(target, ast.Name) and target.id == 'name'
|
|
+ assignment_uses_a_constant_string = isinstance(assignment.value, assignment_value_class)
|
|
+ if assignment_adds_name_attrib and assignment_uses_a_constant_string:
|
|
+ rhs = assignment.value # <lhs> = <rhs>
|
|
+ actor_name = getattr(rhs, assignment_value_attrib)
|
|
+ break
|
|
+ if actor_name is not None:
|
|
+ break
|
|
+ return actor_name
|
|
+
|
|
+
|
|
+def get_actor_names(actor_path):
|
|
+ with open(actor_path) as actor_file:
|
|
+ try:
|
|
+ actor_def = ast.parse(actor_file.read())
|
|
+ except SyntaxError:
|
|
+ error = ('Failed to parse {0}. The actor might contain syntax errors, or perhaps it '
|
|
+ 'is written with Python3-specific syntax?\n')
|
|
+ sys.stderr.write(error.format(actor_path))
|
|
+ return []
|
|
+ actor_defs = [ast_node for ast_node in actor_def.body if is_direct_actor_def(ast_node)]
|
|
+ actors = [extract_actor_name_from_def(actor_def) for actor_def in actor_defs]
|
|
+ return actors
|
|
+
|
|
+
|
|
+def make_parser():
|
|
+ parser = argparse.ArgumentParser()
|
|
+ parser.add_argument('actor_names', nargs='+',
|
|
+ help='Actor names (the name attribute of the actor class) to look for.')
|
|
+ parser.add_argument('-C', '--change-dir', dest='cwd',
|
|
+ help='Path in which the actors will be looked for.', default='.')
|
|
+ return parser
|
|
+
|
|
+
|
|
+if __name__ == '__main__':
|
|
+ parser = make_parser()
|
|
+ args = parser.parse_args()
|
|
+ cwd = os.path.abspath(args.cwd)
|
|
+ actor_names_to_search_for = set(args.actor_names)
|
|
+
|
|
+ actor_paths = []
|
|
+ for directory, dummy_subdirs, dir_files in os.walk(cwd):
|
|
+ for actor_path in dir_files:
|
|
+ actor_path = os.path.join(directory, actor_path)
|
|
+ if os.path.basename(actor_path) != 'actor.py':
|
|
+ continue
|
|
+
|
|
+ defined_actor_names = set(get_actor_names(actor_path))
|
|
+ if defined_actor_names.intersection(actor_names_to_search_for):
|
|
+ actor_module_path = directory
|
|
+ actor_paths.append(actor_module_path)
|
|
+ print('\n'.join(actor_paths))
|
|
--
|
|
2.41.0
|
|
|