Skip to content

Commit a73f005

Browse files
committed
run_tests: make access to shared variables thread safe
1 parent 4767d23 commit a73f005

1 file changed

Lines changed: 29 additions & 16 deletions

File tree

tests/run-tests

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import sys
66
import platform
77
import argparse
88
import re
9+
import threading
910
from glob import glob
1011

1112
# Tests require at least CPython 3.3. If your default python3 executable
@@ -197,13 +198,27 @@ def run_micropython(pyb, args, test_file, is_special=False):
197198
def run_feature_check(pyb, args, base_path, test_file):
198199
return run_micropython(pyb, args, base_path + "/feature_check/" + test_file, is_special=True)
199200

201+
class ThreadSafeCounter:
202+
def __init__(self, start=0):
203+
self._value = start
204+
self._lock = threading.Lock()
205+
206+
def add(self, to_add):
207+
with self._lock: self._value += to_add
208+
209+
def append(self, arg):
210+
self.add([arg])
211+
212+
@property
213+
def value(self):
214+
return self._value
200215

201216
def run_tests(pyb, tests, args, base_path="."):
202-
test_count = 0
203-
testcase_count = 0
204-
passed_count = 0
205-
failed_tests = []
206-
skipped_tests = []
217+
test_count = ThreadSafeCounter()
218+
testcase_count = ThreadSafeCounter()
219+
passed_count = ThreadSafeCounter()
220+
failed_tests = ThreadSafeCounter([])
221+
skipped_tests = ThreadSafeCounter([])
207222

208223
skip_tests = set()
209224
skip_native = False
@@ -355,8 +370,6 @@ def run_tests(pyb, tests, args, base_path="."):
355370
skip_tests.add('micropython/schedule.py') # native code doesn't check pending events
356371

357372
def run_one_test(test_file):
358-
nonlocal test_count, testcase_count, passed_count, failed_tests
359-
360373
test_file = test_file.replace('\\', '/')
361374
test_basename = os.path.basename(test_file)
362375
test_name = os.path.splitext(test_basename)[0]
@@ -417,14 +430,14 @@ def run_tests(pyb, tests, args, base_path="."):
417430
skipped_tests.append(test_name)
418431
return
419432

420-
testcase_count += len(output_expected.splitlines())
433+
testcase_count.add(len(output_expected.splitlines()))
421434

422435
filename_expected = test_basename + ".exp"
423436
filename_mupy = test_basename + ".out"
424437

425438
if output_expected == output_mupy:
426439
print("pass ", test_file)
427-
passed_count += 1
440+
passed_count.add(1)
428441
rm_f(filename_expected)
429442
rm_f(filename_mupy)
430443
else:
@@ -439,18 +452,18 @@ def run_tests(pyb, tests, args, base_path="."):
439452
print("FAIL ", test_file)
440453
failed_tests.append(test_name)
441454

442-
test_count += 1
455+
test_count.add(1)
443456

444457
for test_file in tests:
445458
run_one_test(test_file)
446459

447-
print("{} tests performed ({} individual testcases)".format(test_count, testcase_count))
448-
print("{} tests passed".format(passed_count))
460+
print("{} tests performed ({} individual testcases)".format(test_count.value, testcase_count.value))
461+
print("{} tests passed".format(passed_count.value))
449462

450-
if len(skipped_tests) > 0:
451-
print("{} tests skipped: {}".format(len(skipped_tests), ' '.join(skipped_tests)))
452-
if len(failed_tests) > 0:
453-
print("{} tests failed: {}".format(len(failed_tests), ' '.join(failed_tests)))
463+
if len(skipped_tests.value) > 0:
464+
print("{} tests skipped: {}".format(len(skipped_tests.value), ' '.join(skipped_tests.value)))
465+
if len(failed_tests.value) > 0:
466+
print("{} tests failed: {}".format(len(failed_tests.value), ' '.join(failed_tests.value)))
454467
return False
455468

456469
# all tests succeeded

0 commit comments

Comments
 (0)