def test_initialise_test_spec_with_filename(self): root_path = os.path.dirname(os.path.realpath(__file__)) spec_path = os.path.join(root_path, "resources", "test_spec.json") self.test_spec = TestSpec(spec_path) test_builds = self.test_spec.get_test_builds() build = list(filter(lambda x: x.get_name() == "K64F-ARM", test_builds))[0] self.assertEqual(build.get_name(), "K64F-ARM") self.assertEqual(build.get_platform(), "K64F") self.assertEqual(build.get_baudrate(), 9600) self.assertEqual(build.get_path(), "./BUILD/K64F/ARM") self.assertEqual(len(build.get_tests()), 2) self.assertTrue("tests-example-1" in build.get_tests()) self.assertTrue("tests-example-2" in build.get_tests()) test = build.get_tests()["tests-example-1"] self.assertEqual(test.get_name(), "tests-example-1") self.assertEqual( test.get_binary().get_path(), "./BUILD/K64F/ARM/tests-mbedmicro-rtos-mbed-mail.bin") self.assertIs(type(test_builds), list) self.assertEqual(len(test_builds), 2)
def test_create_filtered_test_list(self): test_spec = TestSpec() test_spec.parse(test_spec_def) test_build = test_spec.get_test_builds()[0] test_list = mbed_greentea_cli.create_filtered_test_list( test_build.get_tests(), 'mbed-drivers-test-generic_*', None, test_spec=test_spec) self.assertEqual(set(test_list.keys()), set(['mbed-drivers-test-generic_tests'])) test_list = mbed_greentea_cli.create_filtered_test_list( test_build.get_tests(), '*_strings', None, test_spec=test_spec) self.assertEqual(set(test_list.keys()), set(['mbed-drivers-test-c_strings'])) test_list = mbed_greentea_cli.create_filtered_test_list( test_build.get_tests(), 'mbed*s', None, test_spec=test_spec) expected = set( ['mbed-drivers-test-c_strings', 'mbed-drivers-test-generic_tests']) self.assertEqual(set(test_list.keys()), expected) test_list = mbed_greentea_cli.create_filtered_test_list( test_build.get_tests(), '*-drivers-*', None, test_spec=test_spec) expected = set( ['mbed-drivers-test-c_strings', 'mbed-drivers-test-generic_tests']) self.assertEqual(set(test_list.keys()), expected)
def test_get_test_builds(self): self.test_spec = TestSpec() self.test_spec.parse(self.ts_2_builds) test_builds = self.test_spec.get_test_builds() self.assertIs(type(test_builds), list) self.assertEqual(len(test_builds), 2)
def merge_multiple_test_specifications_from_file_list(test_spec_file_name_list): """! For each file in test_spec_file_name_list merge all test specifications into one @param test_spec_file_name_list List of paths to different test specifications @return TestSpec object with all test specification data inside """ def copy_builds_between_test_specs(source, destination): """! Copies build key-value pairs between two test_spec dicts @param source Source dictionary @param destination Dictionary with will be applied with 'builds' key-values @return Dictionary with merged source """ result = destination.copy() if 'builds' in source and 'builds' in destination: for k in source['builds']: result['builds'][k] = source['builds'][k] return result merged_test_spec = {} for test_spec_file in test_spec_file_name_list: gt_logger.gt_log_tab("using '%s'"% test_spec_file) try: with open(test_spec_file, 'r') as f: test_spec_data = json.load(f) merged_test_spec = copy_builds_between_test_specs(merged_test_spec, test_spec_data) except Exception as e: gt_logger.gt_log_err("Unexpected error while processing '%s' test specification file"% test_spec_file) gt_logger.gt_log_tab(str(e)) merged_test_spec = {} test_spec = TestSpec() test_spec.parse(merged_test_spec) return test_spec
def test_get_test_builds_properties(self): self.test_spec = TestSpec() self.test_spec.parse(self.ts_2_builds) test_builds = self.test_spec.get_test_builds() test_builds_names = [x.get_name() for x in self.test_spec.get_test_builds()] self.assertIn('K64F-ARM', test_builds_names) self.assertIn('K64F-GCC', test_builds_names)
def test_get_test_builds_names(self): self.test_spec = TestSpec() self.test_spec.parse(self.ts_2_builds) test_builds = self.test_spec.get_test_builds() test_builds_names = [x.get_name() for x in self.test_spec.get_test_builds()] self.assertEqual(len(test_builds_names), 2) self.assertIs(type(test_builds_names), list) self.assertIn('K64F-ARM', test_builds_names) self.assertIn('K64F-GCC', test_builds_names)
def test_manually_add_test_build_to_test_spec(self): test_name = "example-test" test = Test(test_name) test_spec = TestSpec(None) build_name = "example-build" test_build = TestBuild(build_name, "K64F", "ARM", 9600, "./") test_build.add_test(test_name, test) self.assertEqual(len(test_spec.get_test_builds()), 0) test_spec.add_test_builds(build_name, test_build) self.assertEqual(len(test_spec.get_test_builds()), 1) self.assertTrue( build_name in test_spec.get_test_builds()[0].get_name())
def test_get_test_builds_names_filter_by_names(self): self.test_spec = TestSpec() self.test_spec.parse(self.ts_2_builds) filter_by_names = ['K64F-ARM'] test_builds = self.test_spec.get_test_builds(filter_by_names=filter_by_names) test_builds_names = [x.get_name() for x in test_builds] self.assertEqual(len(test_builds_names), 1) self.assertIn('K64F-ARM', test_builds_names) filter_by_names = ['K64F-GCC'] test_builds = self.test_spec.get_test_builds(filter_by_names=filter_by_names) test_builds_names = [x.get_name() for x in test_builds] self.assertEqual(len(test_builds_names), 1) self.assertIn('K64F-GCC', test_builds_names) filter_by_names = ['SOME-PLATFORM-NAME'] test_builds = self.test_spec.get_test_builds(filter_by_names=filter_by_names) test_builds_names = [x.get_name() for x in test_builds] self.assertEqual(len(test_builds_names), 0)
def test_get_build_properties(self): self.test_spec = TestSpec() self.test_spec.parse(self.ts_2_builds) test_builds = self.test_spec.get_test_builds() test_builds_names = [x.get_name() for x in self.test_spec.get_test_builds()] self.assertEqual(len(test_builds_names), 2) self.assertIs(type(test_builds_names), list) k64f_arm = self.test_spec.get_test_build('K64F-ARM') k64f_gcc = self.test_spec.get_test_build('K64F-GCC') self.assertNotEqual(None, k64f_arm) self.assertNotEqual(None, k64f_gcc) self.assertEqual('K64F', k64f_arm.get_platform()) self.assertEqual('ARM', k64f_arm.get_toolchain()) self.assertEqual(115200, k64f_arm.get_baudrate()) self.assertEqual('K64F', k64f_gcc.get_platform()) self.assertEqual('GCC_ARM', k64f_gcc.get_toolchain()) self.assertEqual(9600, k64f_gcc.get_baudrate())
def test_initialise_test_spec_with_invalid_filename(self): root_path = os.path.dirname(os.path.realpath(__file__)) spec_path = os.path.join(root_path, "resources", "null.json") self.test_spec = TestSpec(spec_path) test_builds = self.test_spec.get_test_builds()
def get_test_spec(opts): """! Closure encapsulating how we get test specification and load it from file of from yotta module @return Returns tuple of (test specification, ret code). Test specification == None if test spec load was not successful """ test_spec = None # Check if test_spec.json file exist, if so we will pick it up as default file and load it test_spec_file_name = opts.test_spec test_spec_file_name_list = [] # Note: test_spec.json will have higher priority than module.json file # so if we are inside directory with module.json and test_spec.json we will use test spec file # instead of using yotta's module.json file def get_all_test_specs_from_build_dir(path_to_scan): """! Searches for all test_spec.json files @param path_to_scan Directory path used to recursively search for test_spec.json @result List of locations of test_spec.json """ return [ os.path.join(dp, f) for dp, dn, filenames in os.walk(path_to_scan) for f in filenames if f == 'test_spec.json' ] def merge_multiple_test_specifications_from_file_list( test_spec_file_name_list): """! For each file in test_spec_file_name_list merge all test specifications into one @param test_spec_file_name_list List of paths to different test specifications @return TestSpec object with all test specification data inside """ def copy_builds_between_test_specs(source, destination): """! Copies build key-value pairs between two test_spec dicts @param source Source dictionary @param destination Dictionary with will be applied with 'builds' key-values @return Dictionary with merged source """ result = destination.copy() if 'builds' in source and 'builds' in destination: for k in source['builds']: result['builds'][k] = source['builds'][k] return result merged_test_spec = {} for test_spec_file in test_spec_file_name_list: gt_logger.gt_log_tab("using '%s'" % test_spec_file) try: with open(test_spec_file, 'r') as f: test_spec_data = json.load(f) merged_test_spec = copy_builds_between_test_specs( merged_test_spec, test_spec_data) except Exception as e: gt_logger.gt_log_err( "Unexpected error while processing '%s' test specification file" % test_spec_file) gt_logger.gt_log_tab(str(e)) merged_test_spec = {} test_spec = TestSpec() test_spec.parse(merged_test_spec) return test_spec # Test specification look-up if opts.test_spec: # Loading test specification from command line specified file gt_logger.gt_log( "test specification file '%s' (specified with --test-spec option)" % opts.test_spec) elif os.path.exists('test_spec.json'): # Test specification file exists in current directory gt_logger.gt_log("using 'test_spec.json' from current directory!") test_spec_file_name = 'test_spec.json' elif 'BUILD' in os.listdir(os.getcwd()): # Checking 'BUILD' directory for test specifications # Using `os.listdir()` since it preserves case test_spec_file_name_list = get_all_test_specs_from_build_dir('BUILD') elif os.path.exists('.build'): # Checking .build directory for test specifications test_spec_file_name_list = get_all_test_specs_from_build_dir('.build') elif os.path.exists('mbed-os') and 'BUILD' in os.listdir('mbed-os'): # Checking mbed-os/.build directory for test specifications # Using `os.listdir()` since it preserves case test_spec_file_name_list = get_all_test_specs_from_build_dir( os.path.join(['mbed-os', 'BUILD'])) elif os.path.exists(os.path.join('mbed-os', '.build')): # Checking mbed-os/.build directory for test specifications test_spec_file_name_list = get_all_test_specs_from_build_dir( os.path.join(['mbed-os', '.build'])) # Actual load and processing of test specification from sources if test_spec_file_name: # Test specification from command line (--test-spec) or default test_spec.json will be used gt_logger.gt_log("using '%s' from current directory!" % test_spec_file_name) test_spec = TestSpec(test_spec_file_name) if opts.list_binaries: list_binaries_for_builds(test_spec) return None, 0 elif test_spec_file_name_list: # Merge multiple test specs into one and keep calm gt_logger.gt_log( "using multiple test specifications from current directory!") test_spec = merge_multiple_test_specifications_from_file_list( test_spec_file_name_list) if opts.list_binaries: list_binaries_for_builds(test_spec) return None, 0 elif os.path.exists('module.json'): # If inside yotta module load module data and generate test spec gt_logger.gt_log("using 'module.json' from current directory!") if opts.list_binaries: # List available test binaries (names, no extension) list_binaries_for_targets() return None, 0 else: test_spec = get_test_spec_from_yt_module(opts) else: gt_logger.gt_log_err( "greentea should be run inside a Yotta module or --test-spec switch should be used" ) return None, -1 return test_spec, 0
def get_test_spec_from_yt_module(opts): """ Gives test specification created from yotta module environment. :return TestSpec: """ ### Read yotta module basic information yotta_module = YottaModule() yotta_module.init() # Read actual yotta module data # Check if NO greentea-client is in module.json of repo to test, if so abort if not yotta_module.check_greentea_client(): error = """ ***************************************************************************************** * We've noticed that NO 'greentea-client' module is specified in * * dependency/testDependency section of this module's 'module.json' file. * * * * This version of Greentea requires 'greentea-client' module. * * Please downgrade to Greentea before v0.2.0: * * * * $ pip install "mbed-greentea<0.2.0" --upgrade * * * * or port your tests to new Async model: https://github.com/ARMmbed/greentea/pull/78 * ***************************************************************************************** """ raise YottaError(error) test_spec = TestSpec() ### Selecting yotta targets to process yt_targets = [ ] # List of yotta targets specified by user used to process during this run if opts.list_of_targets: yt_targets = opts.list_of_targets.split(',') else: # Trying to use locally set yotta target gt_logger.gt_log("checking for yotta target in current directory") gt_logger.gt_log_tab("reason: no --target switch set") current_target = get_mbed_target_from_current_dir() if current_target: gt_logger.gt_log("assuming default target as '%s'" % gt_logger.gt_bright(current_target)) # Assuming first target printed by 'yotta search' will be used yt_targets = [current_target] else: gt_logger.gt_log_tab( "yotta target in current directory is not set") gt_logger.gt_log_err( "yotta target is not specified. Use '%s' or '%s' command to set target" % (gt_logger.gt_bright('mbedgt -t <yotta_target>'), gt_logger.gt_bright('yotta target <yotta_target>'))) raise YottaError("Yotta target not set in current directory!") ### Use yotta to search mapping between platform names and available platforms # Convert platform:target, ... mapping to data structure yt_target_to_map_platform = {} if opts.map_platform_to_yt_target: gt_logger.gt_log( "user defined platform -> target supported mapping definition (specified with --map-target switch)" ) for mapping in opts.map_platform_to_yt_target.split(','): if len(mapping.split(':')) == 2: yt_target, platform = mapping.split(':') yt_target_to_map_platform[yt_target] = platform gt_logger.gt_log_tab( "mapped yotta target '%s' to be compatible with platform '%s'" % (gt_logger.gt_bright(yt_target), gt_logger.gt_bright(platform))) else: gt_logger.gt_log_tab( "unknown format '%s', use 'target:platform' format" % mapping) for yt_target in yt_targets: if yt_target in yt_target_to_map_platform: platform = yt_target_to_map_platform[yt_target] else: # get it from local Yotta target platform = get_platform_name_from_yotta_target(yt_target) # Toolchain doesn't matter as Greentea does not have to do any selection for it unlike platform toolchain = yt_target yotta_config = YottaConfig() yotta_config.init(yt_target) baud_rate = yotta_config.get_baudrate() base_path = os.path.join('.', 'build', yt_target) tb = TestBuild(yt_target, platform, toolchain, baud_rate, base_path) test_spec.add_test_builds(yt_target, tb) # Find tests ctest_test_list = load_ctest_testsuite( base_path, binary_type=get_binary_type_for_platform(platform)) for name, path in ctest_test_list.items(): t = Test(name) t.add_binary(path, TestBinary.BIN_TYPE_BOOTABLE) tb.add_test(name, t) return test_spec