From 8226dcf469f58b2d78a3335cd70e6009aeca659f Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Mon, 17 May 2021 19:39:45 +0000 Subject: [PATCH 1/4] Merge branch 'fix/run-selected-tests' into 'master' Fix/run selected tests See merge request dumux-repositories/dumux!2615 (cherry picked from commit 346d4efe46794f7da9ee79febae983ff246bca83) d74a0748 [bin][runselected] pass regex pattern to ctest --- bin/testing/runselectedtests.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/testing/runselectedtests.py b/bin/testing/runselectedtests.py index 9a9630e5b2..c7b22e61c4 100755 --- a/bin/testing/runselectedtests.py +++ b/bin/testing/runselectedtests.py @@ -46,9 +46,12 @@ def runTests(config, script='', flags=['-j4', '--output-on-failure']): print('No tests to be run. Letting dune-ctest produce empty report.') tests = ['NOOP'] + # turn test names into a regular expression + testRegEx = '|'.join(tests) + # if not given, try system-wide call to dune-ctest script = ['dune-ctest'] if not script else script - subprocess.run([script] + flags + ['-R'] + tests, check=True) + subprocess.run([script] + flags + ['-R', testRegEx], check=True) if __name__ == '__main__': -- GitLab From 6730127d4e3cdd6331da90c460007cbf84d78f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gl=C3=A4ser?= Date: Tue, 18 May 2021 12:15:13 +0000 Subject: [PATCH 2/4] Merge branch 'feature/ci-use-exact-mathing-test-regex' into 'master' [ci] Use exact regex match for test names in selection stage See merge request dumux-repositories/dumux!2618 --- bin/testing/runselectedtests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/testing/runselectedtests.py b/bin/testing/runselectedtests.py index c7b22e61c4..7fa8076ed5 100755 --- a/bin/testing/runselectedtests.py +++ b/bin/testing/runselectedtests.py @@ -47,7 +47,7 @@ def runTests(config, script='', flags=['-j4', '--output-on-failure']): tests = ['NOOP'] # turn test names into a regular expression - testRegEx = '|'.join(tests) + testRegEx = '|'.join(["^{}$".format(t) for t in tests]) # if not given, try system-wide call to dune-ctest script = ['dune-ctest'] if not script else script -- GitLab From 29be54c95f7d902f4282310cc97375f96cf49853 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Tue, 18 May 2021 12:24:42 +0000 Subject: [PATCH 3/4] Merge branch 'feature/ci-test-selection-parallel' into 'master' Feature/ci test selection parallel See merge request dumux-repositories/dumux!2605 --- .gitlab-ci.yml | 1 + .gitlab-ci/default.yml | 3 ++- bin/testing/findtests.py | 54 ++++++++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2328300ad0..8a252c8943 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,6 +28,7 @@ workflow: strategy: depend variables: TRIGGER_SOURCE: $CI_PIPELINE_SOURCE + MR_TARGET_BRANCH_NAME: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME rules: - if: $CI_PIPELINE_SOURCE == "schedule" when: always diff --git a/.gitlab-ci/default.yml b/.gitlab-ci/default.yml index 06a1a2262a..7d89b104b6 100644 --- a/.gitlab-ci/default.yml +++ b/.gitlab-ci/default.yml @@ -12,6 +12,7 @@ workflow: variables: TRIGGER_SOURCE: "unknown" + MR_TARGET_BRANCH_NAME: "master" select tests: stage: configure @@ -21,7 +22,7 @@ select tests: if [[ "$TRIGGER_SOURCE" == "merge_request_event" ]]; then dunecontrol --opts=$DUNE_OPTS_FILE --current all pushd build-cmake - python3 ../bin/testing/findtests.py -f ../affectedtests.json -t origin/master + python3 ../bin/testing/findtests.py -f ../affectedtests.json -t origin/$MR_TARGET_BRANCH_NAME popd else echo "Skipping test selection, build/test stages will consider all tests!" diff --git a/bin/testing/findtests.py b/bin/testing/findtests.py index f92322c665..c7cd20c292 100755 --- a/bin/testing/findtests.py +++ b/bin/testing/findtests.py @@ -12,6 +12,8 @@ from argparse import ArgumentParser from glob import glob from subprocess import PIPE import os +from multiprocessing import Pool +from functools import partial # Check if the set a contains a member of list b @@ -44,7 +46,7 @@ def buildCommandAndDir(testConfig, cache): # check if a test is affected by changes in the given files -def isAffectedTest(testConfigFile, changed_files): +def isAffectedTest(testConfigFile, changedFiles): with open(testConfigFile) as configFile: testConfig = json.load(configFile) @@ -66,12 +68,12 @@ def isAffectedTest(testConfigFile, changed_files): def isProjectHeader(headerPath): return projectDir in headerPath - test_files = [os.path.relpath(mainFile.lstrip(". "), projectDir)] - test_files.extend([os.path.relpath(header.lstrip(". "), projectDir) + testFiles = [os.path.relpath(mainFile.lstrip(". "), projectDir)] + testFiles.extend([os.path.relpath(header.lstrip(". "), projectDir) for header in filter(isProjectHeader, headers)]) - test_files = set(test_files) + testFiles = set(testFiles) - if hasCommonMember(changed_files, test_files): + if hasCommonMember(changedFiles, testFiles): return True, testConfig["name"], testConfig["target"] return False, testConfig["name"], testConfig["target"] @@ -81,21 +83,26 @@ if __name__ == '__main__': # parse input arguments parser = ArgumentParser(description='Find tests affected by changes') - parser.add_argument('-s', '--source', required=False, default='HEAD', + parser.add_argument('-s', '--source', + required=False, default='HEAD', help='The source tree (default: `HEAD`)') - parser.add_argument('-t', '--target', required=False, default='master', + parser.add_argument('-t', '--target', + required=False, default='master', help='The tree to compare against (default: `master`)') - parser.add_argument('-f', '--outfile', required=False, - default='affectedtests.json', + parser.add_argument('-np', '--num-processes', + required=False, type=int, default=4, + help='Number of processes (default: 4)') + parser.add_argument('-f', '--outfile', + required=False, default='affectedtests.json', help='The file in which to write the affected tests') args = vars(parser.parse_args()) # find the changes files - changed_files = subprocess.check_output(["git", "diff-tree", - "-r", "--name-only", - args['source'], args['target']], - encoding='ascii').splitlines() - changed_files = set(changed_files) + changedFiles = subprocess.check_output( + ["git", "diff-tree", "-r", "--name-only", args['source'], args['target']], + encoding='ascii' + ).splitlines() + changedFiles = set(changedFiles) # clean build directory subprocess.run(["make", "clean"]) @@ -106,15 +113,18 @@ if __name__ == '__main__': # detect affected tests print("Detecting affected tests:") - count = 0 affectedTests = {} - for test in glob("TestMetaData/*json"): - affected, name, target = isAffectedTest(test, changed_files) - if affected: - print("\t- {}".format(name)) - affectedTests[name] = {'target': target} - count += 1 - print("Detected {} affected tests".format(count)) + tests = glob("TestMetaData/*json") + + numProcesses = max(1, args['num_processes']) + findAffectedTest = partial(isAffectedTest, changedFiles=changedFiles) + with Pool(processes=numProcesses) as p: + for affected, name, target in p.imap_unordered(findAffectedTest, tests, chunksize=4): + if affected: + affectedTests[name] = {'target': target} + print('\t- {} (target: {})'.format(name, target)) + + print("Detected {} affected tests".format(len(affectedTests))) with open(args['outfile'], 'w') as jsonFile: json.dump(affectedTests, jsonFile) -- GitLab From 7462ad7709cac0768f7e99f95a742ee20898ecae Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Tue, 18 May 2021 14:17:22 +0000 Subject: [PATCH 4/4] Merge branch 'fix/ci-use-correct-skipped-target' into 'master' Fix/ci use correct skipped target See merge request dumux-repositories/dumux!2619 --- .gitlab-ci/default.yml | 1 - bin/testing/findtests.py | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci/default.yml b/.gitlab-ci/default.yml index 7d89b104b6..54338ba6c7 100644 --- a/.gitlab-ci/default.yml +++ b/.gitlab-ci/default.yml @@ -16,7 +16,6 @@ variables: select tests: stage: configure - image: $IMAGE_REGISTRY_URL/full:dune-2.7-gcc-ubuntu-20.04 script: - | if [[ "$TRIGGER_SOURCE" == "merge_request_event" ]]; then diff --git a/bin/testing/findtests.py b/bin/testing/findtests.py index c7cd20c292..f9a810522d 100755 --- a/bin/testing/findtests.py +++ b/bin/testing/findtests.py @@ -4,6 +4,9 @@ Find those tests that are affected by changes Run this in the build directory Warning: This runs 'make clean' on the build directory +Note: This only works with compilers that support the following flags: + - "-MM": write included user headers (no system headers) to stdout + - "-H": Show header includes and nesting depth """ import json @@ -26,7 +29,11 @@ def getCompileCommand(testConfig): lines = subprocess.check_output(["make", "--dry-run", testConfig["target"]], encoding='ascii').splitlines() - commands = list(filter(lambda comm: 'g++' in comm, lines)) + + def hasCppCommand(line): + return any(cpp in line for cpp in ['g++', 'clang++']) + + commands = list(filter(lambda line: hasCppCommand(line), lines)) assert len(commands) <= 1 return commands[0] if commands else None -- GitLab