Skip to content

Commit 2d165d6

Browse files
authored
Merge pull request #262 from bridadan/update-test-walk-code
Adding .mbedignore logic to find_tests function
2 parents 3f22400 + d101c74 commit 2d165d6

File tree

2 files changed

+95
-19
lines changed

2 files changed

+95
-19
lines changed

tools/build_api.py

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
import tempfile
2020
import colorama
2121

22-
22+
from copy import copy
2323
from types import ListType
2424
from shutil import rmtree
2525
from os.path import join, exists, basename, abspath, normpath
26-
from os import getcwd
26+
from os import getcwd, walk
2727
from time import time
28+
import fnmatch
2829

2930
from tools.utils import mkdir, run_cmd, run_cmd_ext, NotSupportedException, ToolException
3031
from tools.paths import MBED_TARGETS_PATH, MBED_LIBRARIES, MBED_API, MBED_HAL, MBED_COMMON
@@ -827,3 +828,63 @@ def write_build_report(build_report, template_filename, filename):
827828

828829
with open(filename, 'w+') as f:
829830
f.write(template.render(failing_builds=build_report_failing, passing_builds=build_report_passing))
831+
832+
833+
def scan_for_source_paths(path, exclude_paths=None):
834+
ignorepatterns = []
835+
paths = []
836+
837+
def is_ignored(file_path):
838+
for pattern in ignorepatterns:
839+
if fnmatch.fnmatch(file_path, pattern):
840+
return True
841+
return False
842+
843+
844+
""" os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
845+
When topdown is True, the caller can modify the dirnames list in-place
846+
(perhaps using del or slice assignment), and walk() will only recurse into
847+
the subdirectories whose names remain in dirnames; this can be used to prune
848+
the search, impose a specific order of visiting, or even to inform walk()
849+
about directories the caller creates or renames before it resumes walk()
850+
again. Modifying dirnames when topdown is False is ineffective, because in
851+
bottom-up mode the directories in dirnames are generated before dirpath
852+
itself is generated.
853+
"""
854+
for root, dirs, files in walk(path, followlinks=True):
855+
# Remove ignored directories
856+
# Check if folder contains .mbedignore
857+
if ".mbedignore" in files :
858+
with open (join(root,".mbedignore"), "r") as f:
859+
lines=f.readlines()
860+
lines = [l.strip() for l in lines] # Strip whitespaces
861+
lines = [l for l in lines if l != ""] # Strip empty lines
862+
lines = [l for l in lines if not re.match("^#",l)] # Strip comment lines
863+
# Append root path to glob patterns
864+
# and append patterns to ignorepatterns
865+
ignorepatterns.extend([join(root,line.strip()) for line in lines])
866+
867+
for d in copy(dirs):
868+
dir_path = join(root, d)
869+
870+
# Always ignore hidden directories
871+
if d.startswith('.'):
872+
dirs.remove(d)
873+
874+
# Remove dirs that already match the ignorepatterns
875+
# to avoid travelling into them and to prevent them
876+
# on appearing in include path.
877+
if is_ignored(join(dir_path,"")):
878+
dirs.remove(d)
879+
880+
if exclude_paths:
881+
for exclude_path in exclude_paths:
882+
rel_path = relpath(dir_path, exclude_path)
883+
if not (rel_path.startswith('..')):
884+
dirs.remove(d)
885+
break
886+
887+
# Add root to include paths
888+
paths.append(root)
889+
890+
return paths

tools/test_api.py

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
from tools.build_api import prep_properties
5656
from tools.build_api import create_result
5757
from tools.build_api import add_result_to_report
58+
from tools.build_api import scan_for_source_paths
5859
from tools.libraries import LIBRARIES, LIBRARY_MAP
5960
from tools.toolchains import TOOLCHAIN_BIN_PATH
6061
from tools.test_exporters import ReportExporter, ResultExporterType
@@ -1965,6 +1966,12 @@ def test_path_to_name(path):
19651966
def find_tests(base_dir):
19661967
"""Given any directory, walk through the subdirectories and find all tests"""
19671968

1969+
def is_subdir(path, directory):
1970+
path = os.path.realpath(path)
1971+
directory = os.path.realpath(directory)
1972+
relative = os.path.relpath(path, directory)
1973+
return not (relative.startswith(os.pardir + os.sep) and relative.startswith(os.pardir))
1974+
19681975
def find_tests_in_tests_directory(directory):
19691976
"""Given a 'TESTS' directory, return a dictionary of test names and test paths.
19701977
The formate of the dictionary is {"test-name": "./path/to/test"}"""
@@ -1975,10 +1982,11 @@ def find_tests_in_tests_directory(directory):
19751982
if d != "host_tests":
19761983
# Loop on test case directories
19771984
for td in os.listdir(os.path.join(directory, d)):
1978-
# Add test case to the results if it is a directory
1979-
test_case_path = os.path.join(directory, d, td)
1980-
if os.path.isdir(test_case_path):
1981-
tests[test_path_to_name(test_case_path)] = test_case_path
1985+
# Add test case to the results if it is a directory and not "host_tests"
1986+
if td != "host_tests":
1987+
test_case_path = os.path.join(directory, d, td)
1988+
if os.path.isdir(test_case_path):
1989+
tests[test_path_to_name(test_case_path)] = test_case_path
19821990

19831991
return tests
19841992

@@ -1994,20 +2002,27 @@ def find_tests_in_tests_directory(directory):
19942002
# Not pointing at a "TESTS" directory, so go find one!
19952003
tests = {}
19962004

1997-
for root, dirs, files in os.walk(base_dir):
1998-
# Don't search build directories
1999-
if '.build' in dirs:
2000-
dirs.remove('.build')
2005+
dirs = scan_for_source_paths(base_dir)
2006+
2007+
test_and_sub_dirs = [x for x in dirs if tests_path in x]
2008+
test_dirs = []
2009+
for potential_test_dir in test_and_sub_dirs:
2010+
good_to_add = True
2011+
if test_dirs:
2012+
for test_dir in test_dirs:
2013+
if is_subdir(potential_test_dir, test_dir):
2014+
good_to_add = False
2015+
break
20012016

2002-
# If a "TESTS" directory is found, find the tests inside of it
2003-
if tests_path in dirs:
2004-
# Remove it from the directory walk
2005-
dirs.remove(tests_path)
2006-
2007-
# Get the tests inside of the "TESTS" directory
2008-
new_tests = find_tests_in_tests_directory(os.path.join(root, tests_path))
2009-
if new_tests:
2010-
tests.update(new_tests)
2017+
if good_to_add:
2018+
test_dirs.append(potential_test_dir)
2019+
2020+
# Only look at valid paths
2021+
for path in test_dirs:
2022+
# Get the tests inside of the "TESTS" directory
2023+
new_tests = find_tests_in_tests_directory(path)
2024+
if new_tests:
2025+
tests.update(new_tests)
20112026

20122027
return tests
20132028

0 commit comments

Comments
 (0)