Skip to content

Commit fa88776

Browse files
authored
Merge pull request #3206 from sarahmarshy/examples-test-filters
[Exporter/compile tests] Examples test filters
2 parents 96e1d5b + 119857a commit fa88776

File tree

2 files changed

+121
-94
lines changed

2 files changed

+121
-94
lines changed

tools/test/examples/examples.py

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,24 @@
1212
sys.path.insert(0, ROOT)
1313

1414
from tools.utils import argparse_force_uppercase_type
15+
from tools.utils import argparse_many
16+
from tools.build_api import get_mbed_official_release
1517
import examples_lib as lib
1618
from examples_lib import SUPPORTED_TOOLCHAINS, SUPPORTED_IDES
1719

18-
EXAMPLES = json.load(open(os.path.join(os.path.dirname(__file__),
19-
"examples.json")))
20-
21-
2220
def main():
2321
"""Entry point"""
22+
23+
official_targets = get_mbed_official_release("5")
24+
official_target_names = [x[0] for x in official_targets]
25+
26+
2427
parser = ArgumentParser()
2528
parser.add_argument("-c", dest="config", default="examples.json")
29+
parser.add_argument("-e", "--example",
30+
help=("filter the examples used in the script"),
31+
type=argparse_many(lambda x: x),
32+
default=[])
2633
subparsers = parser.add_subparsers()
2734
import_cmd = subparsers.add_parser("import")
2835
import_cmd.set_defaults(fn=do_import)
@@ -39,60 +46,81 @@ def main():
3946
"toolchains", nargs="*", default=SUPPORTED_TOOLCHAINS,
4047
type=argparse_force_uppercase_type(SUPPORTED_TOOLCHAINS,
4148
"toolchain")),
49+
compile_cmd.add_argument("-m", "--mcu",
50+
help=("build for the given MCU (%s)" %
51+
', '.join(official_target_names)),
52+
metavar="MCU",
53+
type=argparse_many(
54+
argparse_force_uppercase_type(
55+
official_target_names, "MCU")),
56+
default=official_target_names)
4257
export_cmd = subparsers.add_parser("export")
4358
export_cmd.set_defaults(fn=do_export),
4459
export_cmd.add_argument(
4560
"ide", nargs="*", default=SUPPORTED_IDES,
4661
type=argparse_force_uppercase_type(SUPPORTED_IDES,
4762
"ide"))
63+
export_cmd.add_argument("-m", "--mcu",
64+
help=("build for the given MCU (%s)" %
65+
', '.join(official_target_names)),
66+
metavar="MCU",
67+
type=argparse_many(
68+
argparse_force_uppercase_type(
69+
official_target_names, "MCU")),
70+
default=official_target_names)
4871
args = parser.parse_args()
4972
config = json.load(open(os.path.join(os.path.dirname(__file__),
5073
args.config)))
51-
return args.fn(args, config)
74+
75+
all_examples = []
76+
for example in config['examples']:
77+
all_examples = all_examples + [basename(x['repo']) for x in lib.get_repo_list(example)]
78+
examples = [x for x in all_examples if x in args.example] if args.example else all_examples
79+
return args.fn(args, config, examples)
5280

5381

54-
def do_export(args, config):
82+
def do_export(args, config, examples):
5583
"""Do export and build step"""
5684
results = {}
57-
results = lib.export_repos(config, args.ide)
85+
results = lib.export_repos(config, args.ide, args.mcu, examples)
5886

5987
lib.print_summary(results, export=True)
6088
failures = lib.get_num_failures(results, export=True)
6189
print("Number of failures = %d" % failures)
6290
return failures
6391

6492

65-
def do_import(_, config):
93+
def do_import(_, config, examples):
6694
"""Do the import step of this process"""
67-
lib.source_repos(config)
95+
lib.source_repos(config, examples)
6896
return 0
6997

7098

71-
def do_clone(_, config):
99+
def do_clone(_, config, examples):
72100
"""Do the clone step of this process"""
73-
lib.clone_repos(config)
101+
lib.clone_repos(config, examples)
74102
return 0
75103

76104

77-
def do_deploy(_, config):
105+
def do_deploy(_, config, examples):
78106
"""Do the deploy step of this process"""
79-
lib.deploy_repos(config)
107+
lib.deploy_repos(config, examples)
80108
return 0
81109

82110

83-
def do_compile(args, config):
111+
def do_compile(args, config, examples):
84112
"""Do the compile step"""
85113
results = {}
86-
results = lib.compile_repos(config, args.toolchains)
114+
results = lib.compile_repos(config, args.toolchains, args.mcu, examples)
87115

88116
lib.print_summary(results)
89117
failures = lib.get_num_failures(results)
90118
print("Number of failures = %d" % failures)
91119
return failures
92120

93-
def do_versionning(args, config):
121+
def do_versionning(args, config, examples):
94122
""" Test update the mbed-os to the version specified by the tag """
95-
lib.update_mbedos_version(config, args.tag)
123+
lib.update_mbedos_version(config, args.tag, examples)
96124
return 0
97125

98126

tools/test/examples/examples_lib.py

Lines changed: 76 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -75,52 +75,46 @@ def print_summary(results, export=False):
7575

7676
print("#")
7777
print("#"*80)
78-
7978

80-
def target_cross_toolchain(allowed_toolchains,
81-
features=[], targets=[]):
79+
def valid_choices(allowed_choices, all_choices):
80+
if len(allowed_choices) > 0:
81+
return [t for t in all_choices if t in allowed_choices]
82+
else:
83+
return all_choices
84+
85+
86+
def target_cross_toolchain(allowed_targets, allowed_toolchains, features=[]):
8287
"""Generate pairs of target and toolchains
8388
8489
Args:
90+
allowed_targets - a list of all possible targets
8591
allowed_toolchains - a list of all possible toolchains
8692
8793
Kwargs:
8894
features - the features that must be in the features array of a
8995
target
90-
targets - a list of available targets
9196
"""
92-
if len(targets) == 0:
93-
targets=TARGET_MAP.keys()
94-
95-
for target, toolchains in get_mbed_official_release("5"):
96-
for toolchain in toolchains:
97-
if (toolchain in allowed_toolchains and
98-
target in targets and
99-
all(feature in TARGET_MAP[target].features
100-
for feature in features)):
97+
for target in allowed_targets:
98+
for toolchain in allowed_toolchains:
99+
if all(feature in TARGET_MAP[target].features
100+
for feature in features):
101101
yield target, toolchain
102102

103103

104-
def target_cross_ide(allowed_ides,
105-
features=[], targets=[]):
104+
def target_cross_ide(allowed_targets, allowed_ides, features=[]):
106105
"""Generate pairs of target and ides
107106
108107
Args:
108+
allowed_targets - a list of all possible targets
109109
allowed_ides - a list of all possible IDEs
110110
111111
Kwargs:
112112
features - the features that must be in the features array of a
113113
target
114-
targets - a list of available targets
115114
"""
116-
if len(targets) == 0:
117-
targets=TARGET_MAP.keys()
118-
119-
for target, toolchains in get_mbed_official_release("5"):
115+
for target in allowed_targets:
120116
for ide in allowed_ides:
121-
if (EXPORTERS[ide].TOOLCHAIN in toolchains and
122-
target in EXPORTERS[ide].TARGETS and
123-
target in targets and
117+
if (target in EXPORTERS[ide].TARGETS and
124118
all(feature in TARGET_MAP[target].features
125119
for feature in features)):
126120
yield target, ide
@@ -154,7 +148,7 @@ def get_repo_list(example):
154148
return repos
155149

156150

157-
def source_repos(config):
151+
def source_repos(config, examples):
158152
""" Imports each of the repos and its dependencies (.lib files) associated
159153
with the specific examples name from the json config file. Note if
160154
there is already a clone of the repo then it will first be removed to
@@ -167,13 +161,14 @@ def source_repos(config):
167161
for example in config['examples']:
168162
for repo_info in get_repo_list(example):
169163
name = basename(repo_info['repo'])
170-
if os.path.exists(name):
171-
print("'%s' example directory already exists. Deleting..." % name)
172-
rmtree(name)
173-
174-
subprocess.call(["mbed-cli", "import", repo_info['repo']])
164+
if name in examples:
165+
if os.path.exists(name):
166+
print("'%s' example directory already exists. Deleting..." % name)
167+
rmtree(name)
175168

176-
def clone_repos(config):
169+
subprocess.call(["mbed-cli", "import", repo_info['repo']])
170+
171+
def clone_repos(config, examples):
177172
""" Clones each of the repos associated with the specific examples name from the
178173
json config file. Note if there is already a clone of the repo then it will first
179174
be removed to ensure a clean, up to date cloning.
@@ -185,13 +180,14 @@ def clone_repos(config):
185180
for example in config['examples']:
186181
for repo_info in get_repo_list(example):
187182
name = basename(repo_info['repo'])
188-
if os.path.exists(name):
189-
print("'%s' example directory already exists. Deleting..." % name)
190-
rmtree(name)
183+
if name in examples:
184+
if os.path.exists(name):
185+
print("'%s' example directory already exists. Deleting..." % name)
186+
rmtree(name)
191187

192-
subprocess.call([repo_info['type'], "clone", repo_info['repo']])
188+
subprocess.call([repo_info['type'], "clone", repo_info['repo']])
193189

194-
def deploy_repos(config):
190+
def deploy_repos(config, examples):
195191
""" If the example directory exists as provided by the json config file,
196192
pull in the examples dependencies by using `mbed-cli deploy`.
197193
Args:
@@ -202,13 +198,13 @@ def deploy_repos(config):
202198
for example in config['examples']:
203199
for repo_info in get_repo_list(example):
204200
name = basename(repo_info['repo'])
205-
206-
if os.path.exists(name):
207-
os.chdir(name)
208-
subprocess.call(["mbed-cli", "deploy"])
209-
os.chdir("..")
210-
else:
211-
print("'%s' example directory doesn't exist. Skipping..." % name)
201+
if name in examples:
202+
if os.path.exists(name):
203+
os.chdir(name)
204+
subprocess.call(["mbed-cli", "deploy"])
205+
os.chdir("..")
206+
else:
207+
print("'%s' example directory doesn't exist. Skipping..." % name)
212208

213209

214210
def get_num_failures(results, export=False):
@@ -228,35 +224,36 @@ def get_num_failures(results, export=False):
228224

229225
return num_failures
230226

231-
232-
def export_repos(config, ides):
227+
def export_repos(config, ides, targets, examples):
233228
"""Exports and builds combinations of example programs, targets and IDEs.
234229
235-
The results are returned in a [key: value] dictionary format:
236-
Where key = The example name from the json config file
237-
value = a list containing: pass_status, successes, export failures, build_failures,
238-
and build_skips
239-
240-
where pass_status = The overall pass status for the export of the full
241-
set of example programs comprising the example suite.
242-
(IE they must build and export)
243-
True if all examples pass, false otherwise
244-
successes = list of examples that exported and built (if possible)
245-
If the exporter has no build functionality, then it is a pass
246-
if exported
247-
export_failures = list of examples that failed to export.
248-
build_failures = list of examples that failed to build
249-
build_skips = list of examples that cannot build
250-
251-
Both successes and failures contain the example name, target and IDE
252-
253-
Args:
254-
config - the json object imported from the file.
255-
ides - List of IDES to export to
256-
"""
230+
The results are returned in a [key: value] dictionary format:
231+
Where key = The example name from the json config file
232+
value = a list containing: pass_status, successes, export failures, build_failures,
233+
and build_skips
234+
235+
where pass_status = The overall pass status for the export of the full
236+
set of example programs comprising the example suite.
237+
IE they must build and export) True if all examples pass, false otherwise
238+
successes = list of examples that exported and built (if possible)
239+
If the exporter has no build functionality, then it is a pass
240+
if exported
241+
export_failures = list of examples that failed to export.
242+
build_failures = list of examples that failed to build
243+
build_skips = list of examples that cannot build
244+
245+
Both successes and failures contain the example name, target and IDE
246+
247+
Args:
248+
config - the json object imported from the file.
249+
ides - List of IDES to export to
250+
"""
257251
results = {}
258252
print("\nExporting example repos....\n")
259253
for example in config['examples']:
254+
if example['name'] not in examples:
255+
continue
256+
260257
export_failures = []
261258
build_failures = []
262259
build_skips = []
@@ -269,9 +266,9 @@ def export_repos(config, ides):
269266
os.chdir(example_project_name)
270267
# Check that the target, IDE, and features combinations are valid and return a
271268
# list of valid combinations to work through
272-
for target, ide in target_cross_ide(ides,
273-
example['features'],
274-
example['targets']):
269+
for target, ide in target_cross_ide(valid_choices(example['targets'], targets),
270+
valid_choices(example['exporters'], ides),
271+
example['features']):
275272
example_name = "{} {} {}".format(example_project_name, target,
276273
ide)
277274
def status(message):
@@ -311,7 +308,7 @@ def status(message):
311308
return results
312309

313310

314-
def compile_repos(config, toolchains):
311+
def compile_repos(config, toolchains, targets, examples):
315312
"""Compiles combinations of example programs, targets and compile chains.
316313
317314
The results are returned in a [key: value] dictionary format:
@@ -334,23 +331,23 @@ def compile_repos(config, toolchains):
334331
"""
335332
results = {}
336333
print("\nCompiling example repos....\n")
337-
for example in config['examples']:
334+
for example in config['examples']:
335+
if example['name'] not in examples:
336+
continue
338337
failures = []
339338
successes = []
340339
compiled = True
341340
pass_status = True
342341
if example['compile']:
343-
if len(example['toolchains']) > 0:
344-
toolchains = example['toolchains']
345-
346342
for repo_info in get_repo_list(example):
347343
name = basename(repo_info['repo'])
348344
os.chdir(name)
349345

350346
# Check that the target, toolchain and features combinations are valid and return a
351347
# list of valid combinations to work through
352-
for target, toolchain in target_cross_toolchain(toolchains,
353-
example['features'], example['targets']):
348+
for target, toolchain in target_cross_toolchain(valid_choices(example['targets'], targets),
349+
valid_choices(example['toolchains'], toolchains),
350+
example['features']):
354351
proc = subprocess.Popen(["mbed-cli", "compile", "-t", toolchain,
355352
"-m", target, "--silent"])
356353
proc.wait()
@@ -372,7 +369,7 @@ def compile_repos(config, toolchains):
372369
return results
373370

374371

375-
def update_mbedos_version(config, tag):
372+
def update_mbedos_version(config, tag, examples):
376373
""" For each example repo identified in the config json object, update the version of
377374
mbed-os to that specified by the supplied GitHub tag. This function assumes that each
378375
example repo has already been cloned.
@@ -384,6 +381,8 @@ def update_mbedos_version(config, tag):
384381
"""
385382
print("Updating mbed-os in examples to version %s\n" % tag)
386383
for example in config['examples']:
384+
if example['name'] not in examples:
385+
continue
387386
for repo_info in get_repo_list(example):
388387
update_dir = basename(repo_info['repo']) + "/mbed-os"
389388
print("\nChanging dir to %s\n" % update_dir)

0 commit comments

Comments
 (0)