1616
1717import inspect
1818import os
19+ import re
1920import sys
2021import time
2122import unittest
@@ -40,6 +41,7 @@ class _BaseRunner(object):
4041 def __init__ (self , opts , extra_opts ):
4142 self .opts = opts
4243 self .extra_opts = extra_opts
44+ self .load_errors = set ()
4345
4446 def __enter__ (self ):
4547 self .init_config ()
@@ -168,6 +170,15 @@ def get_fetchers(self):
168170 for candidate in candidates :
169171 if issubclass (candidate .__class__ , ComplianceFetcher ):
170172 fetchers .add (candidate .__class__ )
173+ for load_err in tl .errors :
174+ try :
175+ locate = re .search (
176+ '^Failed to import test module: (.+?)\n .*?' , load_err
177+ )
178+ if locate .group (1 ).split ('.' )[- 1 ].startswith (FETCH_PREFIX ):
179+ self .load_errors .add (load_err )
180+ except AttributeError :
181+ pass
171182 return fetchers
172183
173184 def run_fetchers (self , reruns = None ):
@@ -243,6 +254,7 @@ def init_config(self):
243254 def get_checks (self ):
244255 """Provide the appropriate compliance framework check classes."""
245256 checks = set ()
257+ tests_found = set ()
246258 for loc in self .dirs :
247259 tl = unittest .TestLoader ()
248260 tl .testMethodPrefix = CHECK_PREFIX
@@ -251,6 +263,7 @@ def get_checks(self):
251263 )
252264 for test in [c .__class__ for c in candidates ]:
253265 path = f'{ test .__module__ } .{ test .__name__ } '
266+ tests_found .add (path )
254267 in_accred_grouping = self .controls .is_test_included (
255268 path , self .accreds
256269 )
@@ -264,6 +277,32 @@ def get_checks(self):
264277 )
265278 ]
266279 checks .add (test )
280+ for load_err in tl .errors :
281+ try :
282+ locate = re .search (
283+ '^Failed to import test module: (.+?)\n .*?' , load_err
284+ )
285+ for accred in self .accreds :
286+ for check in self .controls .accred_checks [accred ]:
287+ if check .startswith (locate .group (1 )):
288+ self .load_errors .add (
289+ f'Unable to load { check } \n \n { load_err } '
290+ )
291+ tests_found .add (check )
292+ except AttributeError :
293+ pass
294+ expected_checks = set ()
295+ for accred , checks_in_accred in self .controls .accred_checks .items ():
296+ if accred in self .accreds :
297+ expected_checks .update (checks_in_accred )
298+ for check_not_found in expected_checks - tests_found :
299+ self .load_errors .add (
300+ (
301+ f'Unable to load { check_not_found } \n \n '
302+ f'The check { check_not_found } was not found. '
303+ 'Please validate that the path provided is correct.'
304+ )
305+ )
267306 return checks
268307
269308 def run_checks (self ):
0 commit comments