コード例 #1
0
    def test_map_common_versionsuffixes(self):
        """Test mapping between two toolchain hierarchies"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'robot_path': [test_easyconfigs],
            'silent': True,
            'valid_module_classes': module_classes(),
        })
        get_toolchain_hierarchy.clear()

        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'}

        toolchain_mapping = map_toolchain_hierarchies(iccifort_binutils_tc, gcc_binutils_tc, self.modtool)
        possible_mappings = map_common_versionsuffixes('binutils', iccifort_binutils_tc, toolchain_mapping)
        self.assertEqual(possible_mappings, {'-binutils-2.25': '-binutils-2.26'})

        # Make sure we only map upwards, here it's gzip 1.4 in gcc and 1.6 in iccifort
        possible_mappings = map_common_versionsuffixes('gzip', iccifort_binutils_tc, toolchain_mapping)
        self.assertEqual(possible_mappings, {})

        # newer gzip is picked up other way around (GCC -> iccifort)
        toolchain_mapping = map_toolchain_hierarchies(gcc_binutils_tc, iccifort_binutils_tc, self.modtool)
        possible_mappings = map_common_versionsuffixes('gzip', gcc_binutils_tc, toolchain_mapping)
        self.assertEqual(possible_mappings, {'-gzip-1.4': '-gzip-1.6'})
コード例 #2
0
ファイル: tweak.py プロジェクト: i-mtz/easybuild-framework
    def test_match_minimum_tc_specs(self):
        """Test matching a toolchain to lowest possible in a hierarchy"""
        test_easyconfigs = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'easyconfigs',
            'test_ecs')
        init_config(
            build_options={
                'robot_path': test_easyconfigs,
                'silent': True,
                'valid_module_classes': module_classes(),
            })
        get_toolchain_hierarchy.clear()
        foss_hierarchy = get_toolchain_hierarchy(
            {
                'name': 'foss',
                'version': '2018a'
            }, incl_capabilities=True)
        iimpi_hierarchy = get_toolchain_hierarchy(
            {
                'name': 'iimpi',
                'version': '2016.01'
            }, incl_capabilities=True)
        # Hierarchies are returned with top-level toolchain last, foss has 4 elements here, intel has 2
        self.assertEqual(foss_hierarchy[0]['name'], 'GCC')
        self.assertEqual(foss_hierarchy[1]['name'], 'golf')
        self.assertEqual(foss_hierarchy[2]['name'], 'gompi')
        self.assertEqual(foss_hierarchy[3]['name'], 'foss')
        self.assertEqual(iimpi_hierarchy[0]['name'], 'GCCcore')
        self.assertEqual(iimpi_hierarchy[1]['name'], 'iccifort')
        self.assertEqual(iimpi_hierarchy[2]['name'], 'iimpi')

        # base compiler first (GCCcore which maps to GCC/6.4.0-2.28)
        self.assertEqual(
            match_minimum_tc_specs(iimpi_hierarchy[0], foss_hierarchy), {
                'name': 'GCC',
                'version': '6.4.0-2.28'
            })
        # then iccifort (which also maps to GCC/6.4.0-2.28)
        self.assertEqual(
            match_minimum_tc_specs(iimpi_hierarchy[1], foss_hierarchy), {
                'name': 'GCC',
                'version': '6.4.0-2.28'
            })
        # Then MPI
        self.assertEqual(
            match_minimum_tc_specs(iimpi_hierarchy[2], foss_hierarchy), {
                'name': 'gompi',
                'version': '2018a'
            })
        # Check against own math only subtoolchain for math
        self.assertEqual(
            match_minimum_tc_specs(foss_hierarchy[1], foss_hierarchy), {
                'name': 'golf',
                'version': '2018a'
            })
        # Make sure there's an error when we can't do the mapping
        error_msg = "No possible mapping from source toolchain spec .*"
        self.assertErrorRegex(EasyBuildError, error_msg,
                              match_minimum_tc_specs, foss_hierarchy[3],
                              iimpi_hierarchy)
コード例 #3
0
ファイル: tweak.py プロジェクト: hpcugent/easybuild-framework
    def test_check_capability_mapping(self):
        """Test comparing the functionality of two toolchains"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })
        get_toolchain_hierarchy.clear()
        foss_hierarchy = get_toolchain_hierarchy({'name': 'foss', 'version': '2018a'}, incl_capabilities=True)
        iimpi_hierarchy = get_toolchain_hierarchy({'name': 'iimpi', 'version': '2016.01'},
                                                  incl_capabilities=True)

        # Hierarchies are returned with top-level toolchain last, foss has 4 elements here, intel has 2
        self.assertEqual(foss_hierarchy[0]['name'], 'GCC')
        self.assertEqual(foss_hierarchy[1]['name'], 'golf')
        self.assertEqual(foss_hierarchy[2]['name'], 'gompi')
        self.assertEqual(foss_hierarchy[3]['name'], 'foss')
        self.assertEqual(iimpi_hierarchy[0]['name'], 'GCCcore')
        self.assertEqual(iimpi_hierarchy[1]['name'], 'iccifort')
        self.assertEqual(iimpi_hierarchy[2]['name'], 'iimpi')

        # golf <-> iimpi (should return False)
        self.assertFalse(check_capability_mapping(foss_hierarchy[1], iimpi_hierarchy[1]), "golf requires math libs")
        # gompi <-> iimpi
        self.assertTrue(check_capability_mapping(foss_hierarchy[2], iimpi_hierarchy[2]))
        # GCC <-> iimpi
        self.assertTrue(check_capability_mapping(foss_hierarchy[0], iimpi_hierarchy[2]))
        # GCC <-> iccifort
        self.assertTrue(check_capability_mapping(foss_hierarchy[0], iimpi_hierarchy[1]))
        # GCC <-> GCCcore
        self.assertTrue(check_capability_mapping(foss_hierarchy[0], iimpi_hierarchy[0]))
コード例 #4
0
    def test_check_capability_mapping(self):
        """Test comparing the functionality of two toolchains"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })
        get_toolchain_hierarchy.clear()
        foss_hierarchy = get_toolchain_hierarchy({'name': 'foss', 'version': '2018a'}, incl_capabilities=True)
        iimpi_hierarchy = get_toolchain_hierarchy({'name': 'iimpi', 'version': '2016.01'},
                                                  incl_capabilities=True)

        # Hierarchies are returned with top-level toolchain last, foss has 4 elements here, intel has 2
        self.assertEqual(foss_hierarchy[0]['name'], 'GCC')
        self.assertEqual(foss_hierarchy[1]['name'], 'golf')
        self.assertEqual(foss_hierarchy[2]['name'], 'gompi')
        self.assertEqual(foss_hierarchy[3]['name'], 'foss')
        self.assertEqual(iimpi_hierarchy[0]['name'], 'GCCcore')
        self.assertEqual(iimpi_hierarchy[1]['name'], 'iccifort')
        self.assertEqual(iimpi_hierarchy[2]['name'], 'iimpi')

        # golf <-> iimpi (should return False)
        self.assertFalse(check_capability_mapping(foss_hierarchy[1], iimpi_hierarchy[1]), "golf requires math libs")
        # gompi <-> iimpi
        self.assertTrue(check_capability_mapping(foss_hierarchy[2], iimpi_hierarchy[2]))
        # GCC <-> iimpi
        self.assertTrue(check_capability_mapping(foss_hierarchy[0], iimpi_hierarchy[2]))
        # GCC <-> iccifort
        self.assertTrue(check_capability_mapping(foss_hierarchy[0], iimpi_hierarchy[1]))
        # GCC <-> GCCcore
        self.assertTrue(check_capability_mapping(foss_hierarchy[0], iimpi_hierarchy[0]))
コード例 #5
0
ファイル: tweak.py プロジェクト: hpcugent/easybuild-framework
    def test_map_easyconfig_to_target_tc_hierarchy(self):
        """Test mapping of easyconfig to target hierarchy"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'robot_path': test_easyconfigs,
            'silent': True,
            'valid_module_classes': module_classes(),
        })
        get_toolchain_hierarchy.clear()

        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'}
        # The below mapping includes a binutils mapping (2.26 to 2.25)
        tc_mapping = map_toolchain_hierarchies(gcc_binutils_tc, iccifort_binutils_tc, self.modtool)
        ec_spec = os.path.join(test_easyconfigs, 'h', 'hwloc', 'hwloc-1.6.2-GCC-4.9.3-2.26.eb')
        tweaked_spec = map_easyconfig_to_target_tc_hierarchy(ec_spec, tc_mapping)
        tweaked_ec = process_easyconfig(tweaked_spec)[0]
        tweaked_dict = tweaked_ec['ec'].asdict()
        # First check the mapped toolchain
        key, value = 'toolchain', iccifort_binutils_tc
        self.assertTrue(key in tweaked_dict and value == tweaked_dict[key])
        # Also check that binutils has been mapped
        for key, value in {'name': 'binutils', 'version': '2.25', 'versionsuffix': ''}.items():
            self.assertTrue(key in tweaked_dict['builddependencies'][0] and
                            value == tweaked_dict['builddependencies'][0][key])
コード例 #6
0
ファイル: tweak.py プロジェクト: OVGULIU/easybuild-framework
    def test_match_minimum_tc_specs(self):
        """Test matching a toolchain to lowest possible in a hierarchy"""
        test_easyconfigs = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'easyconfigs',
            'test_ecs')
        init_config(
            build_options={
                'valid_module_classes': module_classes(),
                'robot_path': test_easyconfigs,
            })
        get_toolchain_hierarchy.clear()
        goolf_hierarchy = get_toolchain_hierarchy(
            {
                'name': 'goolf',
                'version': '1.4.10'
            }, incl_capabilities=True)
        iimpi_hierarchy = get_toolchain_hierarchy(
            {
                'name': 'iimpi',
                'version': '5.5.3-GCC-4.8.3'
            },
            incl_capabilities=True)
        # Hierarchies are returned with top-level toolchain last, goolf has 4 elements here, intel has 2
        self.assertEqual(goolf_hierarchy[0]['name'], 'GCC')
        self.assertEqual(goolf_hierarchy[1]['name'], 'golf')
        self.assertEqual(goolf_hierarchy[2]['name'], 'gompi')
        self.assertEqual(goolf_hierarchy[3]['name'], 'goolf')
        self.assertEqual(iimpi_hierarchy[0]['name'], 'iccifort')
        self.assertEqual(iimpi_hierarchy[1]['name'], 'iimpi')

        # Compiler first
        self.assertEqual(
            match_minimum_tc_specs(iimpi_hierarchy[0], goolf_hierarchy), {
                'name': 'GCC',
                'version': '4.7.2'
            })
        # Then MPI
        self.assertEqual(
            match_minimum_tc_specs(iimpi_hierarchy[1], goolf_hierarchy), {
                'name': 'gompi',
                'version': '1.4.10'
            })
        # Check against own math only subtoolchain for math
        self.assertEqual(
            match_minimum_tc_specs(goolf_hierarchy[1], goolf_hierarchy), {
                'name': 'golf',
                'version': '1.4.10'
            })
        # Make sure there's an error when we can't do the mapping
        error_msg = "No possible mapping from source toolchain spec .*"
        self.assertErrorRegex(EasyBuildError, error_msg,
                              match_minimum_tc_specs, goolf_hierarchy[3],
                              iimpi_hierarchy)
コード例 #7
0
ファイル: tweak.py プロジェクト: jotelha/easybuild-framework
    def test_find_potential_version_mappings(self):
        """Test ability to find potential version mappings of a dependency for a given toolchain mapping"""
        test_easyconfigs = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'easyconfigs',
            'test_ecs')
        init_config(
            build_options={
                'robot_path': [test_easyconfigs],
                'silent': True,
                'valid_module_classes': module_classes(),
            })
        get_toolchain_hierarchy.clear()

        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {
            'name': 'iccifort',
            'version': '2016.1.150-GCC-4.9.3-2.25'
        }
        # The below mapping includes a binutils mapping (2.26 to 2.25)
        tc_mapping = map_toolchain_hierarchies(gcc_binutils_tc,
                                               iccifort_binutils_tc,
                                               self.modtool)
        ec_spec = os.path.join(test_easyconfigs, 'h', 'hwloc',
                               'hwloc-1.6.2-GCC-4.9.3-2.26.eb')
        parsed_ec = process_easyconfig(ec_spec)[0]
        gzip_dep = [
            dep for dep in parsed_ec['ec']['dependencies']
            if dep['name'] == 'gzip'
        ][0]
        self.assertEqual(gzip_dep['full_mod_name'], 'gzip/1.4-GCC-4.9.3-2.26')

        potential_versions = find_potential_version_mappings(
            gzip_dep, tc_mapping)
        self.assertEqual(len(potential_versions), 1)
        # Should see version 1.6 of gzip with iccifort toolchain
        expected = {
            'path':
            os.path.join(test_easyconfigs, 'g', 'gzip',
                         'gzip-1.6-iccifort-2016.1.150-GCC-4.9.3-2.25.eb'),
            'toolchain': {
                'name': 'iccifort',
                'version': '2016.1.150-GCC-4.9.3-2.25'
            },
            'version':
            '1.6',
        }
        self.assertEqual(potential_versions[0], expected)
コード例 #8
0
    def test_list_deps_versionsuffixes(self):
        """Test listing of dependencies' version suffixes"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        build_options = {
            'robot_path': [test_easyconfigs],
            'silent': True,
            'valid_module_classes': module_classes(),
        }
        init_config(build_options=build_options)
        get_toolchain_hierarchy.clear()

        ec_spec = os.path.join(test_easyconfigs, 'g', 'golf', 'golf-2018a.eb')
        self.assertEqual(list_deps_versionsuffixes(ec_spec), ['-serial'])
        ec_spec = os.path.join(test_easyconfigs, 't', 'toy', 'toy-0.0-deps.eb')
        self.assertEqual(list_deps_versionsuffixes(ec_spec), [])
        ec_spec = os.path.join(test_easyconfigs, 'g', 'gzip', 'gzip-1.4-GCC-4.6.3.eb')
        self.assertEqual(list_deps_versionsuffixes(ec_spec), ['-deps'])
コード例 #9
0
ファイル: tweak.py プロジェクト: hpcugent/easybuild-framework
    def test_map_toolchain_hierarchies(self):
        """Test mapping between two toolchain hierarchies"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'robot_path': test_easyconfigs,
            'silent': True,
            'valid_module_classes': module_classes(),
        })
        get_toolchain_hierarchy.clear()
        foss_tc = {'name': 'foss', 'version': '2018a'}
        gompi_tc = {'name': 'gompi', 'version': '2018a'}
        iimpi_tc = {'name': 'iimpi', 'version': '2016.01'}

        # GCCcore is mapped to GCC, iccifort is mapped to GCC, iimpi is mapped to gompi
        expected = {
            'GCCcore': {'name': 'GCC', 'version': '6.4.0-2.28'},
            'iccifort': {'name': 'GCC', 'version': '6.4.0-2.28'},
            'iimpi': {'name': 'gompi', 'version': '2018a'},
        }
        self.assertEqual(map_toolchain_hierarchies(iimpi_tc, foss_tc, self.modtool), expected)

        # GCC is mapped to iccifort, gompi is mapped to iimpi
        expected = {
            'GCC': {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'},
            'gompi': {'name': 'iimpi', 'version': '2016.01'}
        }
        self.assertEqual(map_toolchain_hierarchies(gompi_tc, iimpi_tc, self.modtool), expected)

        # Expect an error when there is no possible mapping
        error_msg = "No possible mapping from source toolchain spec .*"
        self.assertErrorRegex(EasyBuildError, error_msg, map_toolchain_hierarchies,
                              foss_tc, iimpi_tc, self.modtool)

        # Test that we correctly include GCCcore binutils when it is there
        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'}
        # Should see a binutils in the mapping (2.26 will get mapped to 2.25)
        expected = {
            'GCC': {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'},
            'GCCcore': {'name': 'GCCcore', 'version': '4.9.3'},
            'binutils': {'version': '2.25', 'versionsuffix': ''}
        }
        self.assertEqual(map_toolchain_hierarchies(gcc_binutils_tc, iccifort_binutils_tc, self.modtool), expected)
コード例 #10
0
    def test_map_toolchain_hierarchies(self):
        """Test mapping between two toolchain hierarchies"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'robot_path': test_easyconfigs,
            'silent': True,
            'valid_module_classes': module_classes(),
        })
        get_toolchain_hierarchy.clear()
        foss_tc = {'name': 'foss', 'version': '2018a'}
        gompi_tc = {'name': 'gompi', 'version': '2018a'}
        iimpi_tc = {'name': 'iimpi', 'version': '2016.01'}

        # GCCcore is mapped to GCC, iccifort is mapped to GCC, iimpi is mapped to gompi
        expected = {
            'GCCcore': {'name': 'GCC', 'version': '6.4.0-2.28'},
            'iccifort': {'name': 'GCC', 'version': '6.4.0-2.28'},
            'iimpi': {'name': 'gompi', 'version': '2018a'},
        }
        self.assertEqual(map_toolchain_hierarchies(iimpi_tc, foss_tc, self.modtool), expected)

        # GCC is mapped to iccifort, gompi is mapped to iimpi
        expected = {
            'GCC': {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'},
            'gompi': {'name': 'iimpi', 'version': '2016.01'}
        }
        self.assertEqual(map_toolchain_hierarchies(gompi_tc, iimpi_tc, self.modtool), expected)

        # Expect an error when there is no possible mapping
        error_msg = "No possible mapping from source toolchain spec .*"
        self.assertErrorRegex(EasyBuildError, error_msg, map_toolchain_hierarchies,
                              foss_tc, iimpi_tc, self.modtool)

        # Test that we correctly include GCCcore binutils when it is there
        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'}
        # Should see a binutils in the mapping (2.26 will get mapped to 2.25)
        expected = {
            'GCC': {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'},
            'GCCcore': {'name': 'GCCcore', 'version': '4.9.3'},
            'binutils': {'version': '2.25', 'versionsuffix': ''}
        }
        self.assertEqual(map_toolchain_hierarchies(gcc_binutils_tc, iccifort_binutils_tc, self.modtool), expected)
コード例 #11
0
ファイル: tweak.py プロジェクト: i-mtz/easybuild-framework
    def test_map_easyconfig_to_target_tc_hierarchy(self):
        """Test mapping of easyconfig to target hierarchy"""
        test_easyconfigs = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'easyconfigs',
            'test_ecs')
        init_config(
            build_options={
                'robot_path': test_easyconfigs,
                'silent': True,
                'valid_module_classes': module_classes(),
            })
        get_toolchain_hierarchy.clear()

        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {
            'name': 'iccifort',
            'version': '2016.1.150-GCC-4.9.3-2.25'
        }
        # The below mapping includes a binutils mapping (2.26 to 2.25)
        tc_mapping = map_toolchain_hierarchies(gcc_binutils_tc,
                                               iccifort_binutils_tc,
                                               self.modtool)
        ec_spec = os.path.join(test_easyconfigs, 'h', 'hwloc',
                               'hwloc-1.6.2-GCC-4.9.3-2.26.eb')
        tweaked_spec = map_easyconfig_to_target_tc_hierarchy(
            ec_spec, tc_mapping)
        tweaked_ec = process_easyconfig(tweaked_spec)[0]
        tweaked_dict = tweaked_ec['ec'].asdict()
        # First check the mapped toolchain
        key, value = 'toolchain', iccifort_binutils_tc
        self.assertTrue(key in tweaked_dict and value == tweaked_dict[key])
        # Also check that binutils has been mapped
        for key, value in {
                'name': 'binutils',
                'version': '2.25',
                'versionsuffix': ''
        }.items():
            self.assertTrue(
                key in tweaked_dict['builddependencies'][0]
                and value == tweaked_dict['builddependencies'][0][key])
コード例 #12
0
ファイル: tweak.py プロジェクト: hpcugent/easybuild-framework
    def test_match_minimum_tc_specs(self):
        """Test matching a toolchain to lowest possible in a hierarchy"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'robot_path': test_easyconfigs,
            'silent': True,
            'valid_module_classes': module_classes(),
        })
        get_toolchain_hierarchy.clear()
        foss_hierarchy = get_toolchain_hierarchy({'name': 'foss', 'version': '2018a'}, incl_capabilities=True)
        iimpi_hierarchy = get_toolchain_hierarchy({'name': 'iimpi', 'version': '2016.01'},
                                                  incl_capabilities=True)
        # Hierarchies are returned with top-level toolchain last, foss has 4 elements here, intel has 2
        self.assertEqual(foss_hierarchy[0]['name'], 'GCC')
        self.assertEqual(foss_hierarchy[1]['name'], 'golf')
        self.assertEqual(foss_hierarchy[2]['name'], 'gompi')
        self.assertEqual(foss_hierarchy[3]['name'], 'foss')
        self.assertEqual(iimpi_hierarchy[0]['name'], 'GCCcore')
        self.assertEqual(iimpi_hierarchy[1]['name'], 'iccifort')
        self.assertEqual(iimpi_hierarchy[2]['name'], 'iimpi')

        # base compiler first (GCCcore which maps to GCC/6.4.0-2.28)
        self.assertEqual(match_minimum_tc_specs(iimpi_hierarchy[0], foss_hierarchy),
                         {'name': 'GCC', 'version': '6.4.0-2.28'})
        # then iccifort (which also maps to GCC/6.4.0-2.28)
        self.assertEqual(match_minimum_tc_specs(iimpi_hierarchy[1], foss_hierarchy),
                         {'name': 'GCC', 'version': '6.4.0-2.28'})
        # Then MPI
        self.assertEqual(match_minimum_tc_specs(iimpi_hierarchy[2], foss_hierarchy),
                         {'name': 'gompi', 'version': '2018a'})
        # Check against own math only subtoolchain for math
        self.assertEqual(match_minimum_tc_specs(foss_hierarchy[1], foss_hierarchy),
                         {'name': 'golf', 'version': '2018a'})
        # Make sure there's an error when we can't do the mapping
        error_msg = "No possible mapping from source toolchain spec .*"
        self.assertErrorRegex(EasyBuildError, error_msg, match_minimum_tc_specs,
                              foss_hierarchy[3], iimpi_hierarchy)
コード例 #13
0
ファイル: robot.py プロジェクト: Caylo/easybuild-framework
    def test_get_toolchain_hierarchy(self):
        """Test get_toolchain_hierarchy function."""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs')
        init_config(build_options={
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })

        goolf_hierarchy = get_toolchain_hierarchy({'name': 'goolf', 'version': '1.4.10'})
        self.assertEqual(goolf_hierarchy, [
            {'name': 'GCC', 'version': '4.7.2'},
            {'name': 'gompi', 'version': '1.4.10'},
            {'name': 'goolf', 'version': '1.4.10'},
        ])

        iimpi_hierarchy = get_toolchain_hierarchy({'name': 'iimpi', 'version': '5.5.3-GCC-4.8.3'})
        self.assertEqual(iimpi_hierarchy, [
            {'name': 'iccifort', 'version': '2013.5.192-GCC-4.8.3'},
            {'name': 'iimpi', 'version': '5.5.3-GCC-4.8.3'},
        ])

        # test also including dummy
        init_config(build_options={
            'add_dummy_to_minimal_toolchains': True,
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })

        get_toolchain_hierarchy.clear()
        gompi_hierarchy = get_toolchain_hierarchy({'name': 'gompi', 'version': '1.4.10'})
        self.assertEqual(gompi_hierarchy, [
            {'name': 'dummy', 'version': ''},
            {'name': 'GCC', 'version': '4.7.2'},
            {'name': 'gompi', 'version': '1.4.10'},
        ])

        get_toolchain_hierarchy.clear()
        # check whether GCCcore is considered as subtoolchain, even if it's only listed as a dep
        gcc_hierarchy = get_toolchain_hierarchy({'name': 'GCC', 'version': '4.9.3-2.25'})
        self.assertEqual(gcc_hierarchy, [
            {'name': 'dummy', 'version': ''},
            {'name': 'GCCcore', 'version': '4.9.3'},
            {'name': 'GCC', 'version': '4.9.3-2.25'},
        ])

        get_toolchain_hierarchy.clear()
        iccifort_hierarchy = get_toolchain_hierarchy({'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'})
        self.assertEqual(iccifort_hierarchy, [
            {'name': 'dummy', 'version': ''},
            {'name': 'GCCcore', 'version': '4.9.3'},
            {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'},
        ])
コード例 #14
0
    def test_find_potential_version_mappings(self):
        """Test ability to find potential version mappings of a dependency for a given toolchain mapping"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'robot_path': [test_easyconfigs],
            'silent': True,
            'valid_module_classes': module_classes(),
        })
        get_toolchain_hierarchy.clear()

        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'}
        # The below mapping includes a binutils mapping (2.26 to 2.25)
        tc_mapping = map_toolchain_hierarchies(gcc_binutils_tc, iccifort_binutils_tc, self.modtool)
        ec_spec = os.path.join(test_easyconfigs, 'h', 'hwloc', 'hwloc-1.6.2-GCC-4.9.3-2.26.eb')
        parsed_ec = process_easyconfig(ec_spec)[0]
        gzip_dep = [dep for dep in parsed_ec['ec']['dependencies'] if dep['name'] == 'gzip'][0]
        self.assertEqual(gzip_dep['full_mod_name'], 'gzip/1.4-GCC-4.9.3-2.26')

        potential_versions = find_potential_version_mappings(gzip_dep, tc_mapping)
        self.assertEqual(len(potential_versions), 1)
        # Should see version 1.6 of gzip with iccifort toolchain
        expected = {
            'path': os.path.join(test_easyconfigs, 'g', 'gzip', 'gzip-1.6-iccifort-2016.1.150-GCC-4.9.3-2.25.eb'),
            'toolchain': {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'},
            'version': '1.6',
            'versionsuffix': '',
        }
        self.assertEqual(potential_versions[0], expected)

        # Test that we can override respecting the versionsuffix

        # Create toolchain mapping for OpenBLAS
        gcc_4_tc = {'name': 'GCC', 'version': '4.8.2'}
        gcc_6_tc = {'name': 'GCC', 'version': '6.4.0-2.28'}
        tc_mapping = map_toolchain_hierarchies(gcc_4_tc, gcc_6_tc, self.modtool)
        # Create a dep with the necessary params (including versionsuffix)
        openblas_dep = {
            'toolchain': {'version': '4.8.2', 'name': 'GCC'},
            'name': 'OpenBLAS',
            'system': False,
            'versionsuffix': '-LAPACK-3.4.2',
            'version': '0.2.8'
        }

        self.mock_stderr(True)
        potential_versions = find_potential_version_mappings(openblas_dep, tc_mapping)
        errtxt = self.get_stderr()
        warning_stub = "\nWARNING: There may be newer version(s) of dep 'OpenBLAS' available with a different " \
                       "versionsuffix to '-LAPACK-3.4.2'"
        self.mock_stderr(False)
        self.assertTrue(errtxt.startswith(warning_stub))
        self.assertEqual(len(potential_versions), 0)
        potential_versions = find_potential_version_mappings(openblas_dep, tc_mapping, ignore_versionsuffixes=True)
        self.assertEqual(len(potential_versions), 1)
        expected = {
            'path': os.path.join(test_easyconfigs, 'o', 'OpenBLAS', 'OpenBLAS-0.2.20-GCC-6.4.0-2.28.eb'),
            'toolchain': {'version': '6.4.0-2.28', 'name': 'GCC'},
            'version': '0.2.20',
            'versionsuffix': '',
        }
        self.assertEqual(potential_versions[0], expected)
コード例 #15
0
ファイル: robot.py プロジェクト: fizwit/easybuild-framework
    def test_resolve_dependencies_minimal(self):
        """Test resolved dependencies with minimal toolchain."""

        # replace log.experimental with log.warning to allow experimental code
        easybuild.framework.easyconfig.tools._log.experimental = easybuild.framework.easyconfig.tools._log.warning

        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        self.install_mock_module()

        init_config(build_options={
            'allow_modules_tool_mismatch': True,
            'minimal_toolchains': True,
            'use_existing_modules': True,
            'external_modules_metadata': ConfigObj(),
            'robot_path': test_easyconfigs,
            'valid_module_classes': module_classes(),
            'validate': False,
        })

        barec = os.path.join(self.test_prefix, 'bar-1.2.3-goolf-1.4.10.eb')
        barec_lines = [
            "easyblock = 'ConfigureMake'",
            "name = 'bar'",
            "version = '1.2.3'",
            "homepage = 'http://example.com'",
            "description = 'foo'",
            # deliberately listing components of toolchain as dependencies without specifying subtoolchains,
            # to test resolving of dependencies with minimal toolchain
            # for each of these, we know test easyconfigs are available (which are required here)
            "dependencies = [",
            "   ('OpenMPI', '1.6.4'),",  # available with GCC/4.7.2
            "   ('OpenBLAS', '0.2.6', '-LAPACK-3.4.2'),",  # available with gompi/1.4.10
            "   ('ScaLAPACK', '2.0.2', '-OpenBLAS-0.2.6-LAPACK-3.4.2'),",  # available with gompi/1.4.10
            "   ('SQLite', '3.8.10.2'),",
            "]",
            # toolchain as list line, for easy modification later;
            # the use of %(version_major)s here is mainly to check if templates are being handled correctly
            # (it doesn't make much sense, but it serves the purpose)
            "toolchain = {'name': 'goolf', 'version': '%(version_major)s.4.10'}",
        ]
        write_file(barec, '\n'.join(barec_lines))
        bar = process_easyconfig(barec)[0]

        # all modules in the dep graph, in order
        all_mods_ordered = [
            'GCC/4.7.2',
            'hwloc/1.6.2-GCC-4.7.2',
            'OpenMPI/1.6.4-GCC-4.7.2',
            'gompi/1.4.10',
            'OpenBLAS/0.2.6-gompi-1.4.10-LAPACK-3.4.2',
            'ScaLAPACK/2.0.2-gompi-1.4.10-OpenBLAS-0.2.6-LAPACK-3.4.2',
            'SQLite/3.8.10.2-GCC-4.7.2',
            'FFTW/3.3.3-gompi-1.4.10',
            'goolf/1.4.10',
            'bar/1.2.3-goolf-1.4.10',
        ]

        # no modules available, so all dependencies are retained
        MockModule.avail_modules = []
        res = resolve_dependencies([bar], self.modtool)
        self.assertEqual(len(res), 10)
        self.assertEqual([x['full_mod_name'] for x in res], all_mods_ordered)

        MockModule.avail_modules = [
            'GCC/4.7.2',
            'gompi/1.4.10',
            'goolf/1.4.10',
            'OpenMPI/1.6.4-GCC-4.7.2',
            'OpenBLAS/0.2.6-gompi-1.4.10-LAPACK-3.4.2',
            'ScaLAPACK/2.0.2-gompi-1.4.10-OpenBLAS-0.2.6-LAPACK-3.4.2',
            'SQLite/3.8.10.2-GCC-4.7.2',
        ]

        # test resolving dependencies with minimal toolchain (rather than using goolf/1.4.10 for all of them)
        # existing modules are *not* taken into account when determining minimal subtoolchain, by default
        res = resolve_dependencies([bar], self.modtool)
        self.assertEqual(len(res), 1)
        self.assertEqual(res[0]['full_mod_name'], bar['ec'].full_mod_name)

        # test retaining all dependencies, regardless of whether modules are available or not
        res = resolve_dependencies([bar], self.modtool, retain_all_deps=True)
        self.assertEqual(len(res), 10)
        mods = [x['full_mod_name'] for x in res]
        self.assertEqual(mods, all_mods_ordered)
        self.assertTrue('SQLite/3.8.10.2-GCC-4.7.2' in mods)

        # test taking into account existing modules
        # with an SQLite module with goolf/1.4.10 in place, this toolchain should be used rather than GCC/4.7.2
        MockModule.avail_modules = [
            'SQLite/3.8.10.2-goolf-1.4.10',
        ]

        # parsed easyconfigs are cached, so clear the cache before reprocessing easyconfigs
        ecec._easyconfigs_cache.clear()

        bar = process_easyconfig(barec)[0]
        res = resolve_dependencies([bar], self.modtool, retain_all_deps=True)
        self.assertEqual(len(res), 10)
        mods = [x['full_mod_name'] for x in res]
        self.assertTrue('SQLite/3.8.10.2-goolf-1.4.10' in mods)
        self.assertFalse('SQLite/3.8.10.2-GCC-4.7.2' in mods)

        # Check whether having 2 version of dummy toolchain is ok
        # Clear easyconfig and toolchain caches
        ecec._easyconfigs_cache.clear()
        get_toolchain_hierarchy.clear()

        init_config(build_options={
            'allow_modules_tool_mismatch': True,
            'minimal_toolchains': True,
            'add_dummy_to_minimal_toolchains': True,
            'external_modules_metadata': ConfigObj(),
            'robot_path': test_easyconfigs,
            'valid_module_classes': module_classes(),
            'validate': False,
        })

        impi_txt = read_file(os.path.join(test_easyconfigs, 'i', 'impi', 'impi-4.1.3.049.eb'))
        self.assertTrue(re.search("^toolchain = {'name': 'dummy', 'version': ''}", impi_txt, re.M))
        gzip_txt = read_file(os.path.join(test_easyconfigs, 'g', 'gzip', 'gzip-1.4.eb'))
        self.assertTrue(re.search("^toolchain = {'name': 'dummy', 'version': 'dummy'}", gzip_txt, re.M))

        barec = os.path.join(self.test_prefix, 'bar-1.2.3-goolf-1.4.10.eb')
        barec_lines = [
            "easyblock = 'ConfigureMake'",
            "name = 'bar'",
            "version = '1.2.3'",
            "homepage = 'http://example.com'",
            "description = 'foo'",
            # deliberately listing components of toolchain as dependencies without specifying subtoolchains,
            # to test resolving of dependencies with minimal toolchain
            # for each of these, we know test easyconfigs are available (which are required here)
            "dependencies = [",
            "   ('impi', '4.1.3.049'),",  # has toolchain ('dummy', '')
            "   ('gzip', '1.4'),",  # has toolchain ('dummy', 'dummy')
            "]",
            # toolchain as list line, for easy modification later
            "toolchain = {'name': 'goolf', 'version': '1.4.10'}",
        ]
        write_file(barec, '\n'.join(barec_lines))
        bar = process_easyconfig(barec)[0]

        res = resolve_dependencies([bar], self.modtool, retain_all_deps=True)
        self.assertEqual(len(res), 11)
        mods = [x['full_mod_name'] for x in res]
        self.assertTrue('impi/4.1.3.049' in mods)
        self.assertTrue('gzip/1.4' in mods)
コード例 #16
0
ファイル: robot.py プロジェクト: fizwit/easybuild-framework
    def test_get_toolchain_hierarchy(self):
        """Test get_toolchain_hierarchy function."""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })

        goolf_hierarchy = get_toolchain_hierarchy({'name': 'goolf', 'version': '1.4.10'})
        self.assertEqual(goolf_hierarchy, [
            {'name': 'GCC', 'version': '4.7.2'},
            {'name': 'gompi', 'version': '1.4.10'},
            {'name': 'goolf', 'version': '1.4.10'},
        ])

        iimpi_hierarchy = get_toolchain_hierarchy({'name': 'iimpi', 'version': '5.5.3-GCC-4.8.3'})
        self.assertEqual(iimpi_hierarchy, [
            {'name': 'iccifort', 'version': '2013.5.192-GCC-4.8.3'},
            {'name': 'iimpi', 'version': '5.5.3-GCC-4.8.3'},
        ])

        # test also including dummy
        init_config(build_options={
            'add_dummy_to_minimal_toolchains': True,
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })

        get_toolchain_hierarchy.clear()
        gompi_hierarchy = get_toolchain_hierarchy({'name': 'gompi', 'version': '1.4.10'})
        self.assertEqual(gompi_hierarchy, [
            {'name': 'dummy', 'version': ''},
            {'name': 'GCC', 'version': '4.7.2'},
            {'name': 'gompi', 'version': '1.4.10'},
        ])

        get_toolchain_hierarchy.clear()
        # check whether GCCcore is considered as subtoolchain, even if it's only listed as a dep
        gcc_hierarchy = get_toolchain_hierarchy({'name': 'GCC', 'version': '4.9.3-2.25'})
        self.assertEqual(gcc_hierarchy, [
            {'name': 'dummy', 'version': ''},
            {'name': 'GCCcore', 'version': '4.9.3'},
            {'name': 'GCC', 'version': '4.9.3-2.25'},
        ])

        get_toolchain_hierarchy.clear()
        iccifort_hierarchy = get_toolchain_hierarchy({'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'})
        self.assertEqual(iccifort_hierarchy, [
            {'name': 'dummy', 'version': ''},
            {'name': 'GCCcore', 'version': '4.9.3'},
            {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'},
        ])

        get_toolchain_hierarchy.clear()
        build_options = {
            'add_dummy_to_minimal_toolchains': True,
            'external_modules_metadata': ConfigObj(),
            'robot_path': test_easyconfigs,
        }
        init_config(build_options=build_options)
        craycce_hierarchy = get_toolchain_hierarchy({'name': 'CrayCCE', 'version': '5.1.29'})
        self.assertEqual(craycce_hierarchy, [
            {'name': 'dummy', 'version': ''},
            {'name': 'CrayCCE', 'version': '5.1.29'},
        ])
コード例 #17
0
    def test_map_easyconfig_to_target_tc_hierarchy(self):
        """Test mapping of easyconfig to target hierarchy"""
        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        build_options = {
            'robot_path': [test_easyconfigs],
            'silent': True,
            'valid_module_classes': module_classes(),
        }
        init_config(build_options=build_options)
        get_toolchain_hierarchy.clear()

        gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'}
        iccifort_binutils_tc = {'name': 'iccifort', 'version': '2016.1.150-GCC-4.9.3-2.25'}
        # The below mapping includes a binutils mapping (2.26 to 2.25)
        tc_mapping = map_toolchain_hierarchies(gcc_binutils_tc, iccifort_binutils_tc, self.modtool)
        ec_spec = os.path.join(test_easyconfigs, 'h', 'hwloc', 'hwloc-1.6.2-GCC-4.9.3-2.26.eb')
        tweaked_spec = map_easyconfig_to_target_tc_hierarchy(ec_spec, tc_mapping)
        tweaked_ec = process_easyconfig(tweaked_spec)[0]
        tweaked_dict = tweaked_ec['ec'].asdict()
        # First check the mapped toolchain
        key, value = 'toolchain', iccifort_binutils_tc
        self.assertTrue(key in tweaked_dict and value == tweaked_dict[key])
        # Also check that binutils has been mapped
        for key, value in {'name': 'binutils', 'version': '2.25', 'versionsuffix': ''}.items():
            self.assertTrue(key in tweaked_dict['builddependencies'][0] and
                            value == tweaked_dict['builddependencies'][0][key])

        # Now test the case where we try to update the dependencies
        init_config(build_options=build_options)
        get_toolchain_hierarchy.clear()
        tweaked_spec = map_easyconfig_to_target_tc_hierarchy(ec_spec, tc_mapping, update_dep_versions=True)
        tweaked_ec = process_easyconfig(tweaked_spec)[0]
        tweaked_dict = tweaked_ec['ec'].asdict()
        # First check the mapped toolchain
        key, value = 'toolchain', iccifort_binutils_tc
        self.assertTrue(key in tweaked_dict and value == tweaked_dict[key])
        # Also check that binutils has been mapped
        for key, value in {'name': 'binutils', 'version': '2.25', 'versionsuffix': ''}.items():
            self.assertTrue(
                key in tweaked_dict['builddependencies'][0] and value == tweaked_dict['builddependencies'][0][key]
            )
        # Also check that the gzip dependency was upgraded
        for key, value in {'name': 'gzip', 'version': '1.6', 'versionsuffix': ''}.items():
            self.assertTrue(key in tweaked_dict['dependencies'][0] and value == tweaked_dict['dependencies'][0][key])

        # Make sure there are checksums for our next test
        self.assertTrue(tweaked_dict['checksums'])

        # Test the case where we also update the software version at the same time
        init_config(build_options=build_options)
        get_toolchain_hierarchy.clear()
        new_version = '1.x.3'
        tweaked_spec = map_easyconfig_to_target_tc_hierarchy(ec_spec,
                                                             tc_mapping,
                                                             update_build_specs={'version': new_version},
                                                             update_dep_versions=True)
        tweaked_ec = process_easyconfig(tweaked_spec)[0]
        tweaked_dict = tweaked_ec['ec'].asdict()
        # First check the mapped toolchain
        key, value = 'toolchain', iccifort_binutils_tc
        self.assertTrue(key in tweaked_dict and value == tweaked_dict[key])
        # Also check that binutils has been mapped
        for key, value in {'name': 'binutils', 'version': '2.25', 'versionsuffix': ''}.items():
            self.assertTrue(
                key in tweaked_dict['builddependencies'][0] and value == tweaked_dict['builddependencies'][0][key]
            )
        # Also check that the gzip dependency was upgraded
        for key, value in {'name': 'gzip', 'version': '1.6', 'versionsuffix': ''}.items():
            self.assertTrue(key in tweaked_dict['dependencies'][0] and value == tweaked_dict['dependencies'][0][key])

        # Finally check that the version was upgraded
        key, value = 'version', new_version
        self.assertTrue(key in tweaked_dict and value == tweaked_dict[key])
        # and that the checksum was removed
        self.assertFalse(tweaked_dict['checksums'])

        # Check that if we update a software version, it also updates the version if the software appears in an
        # extension list (like for a PythonBundle)
        ec_spec = os.path.join(test_easyconfigs, 't', 'toy', 'toy-0.0-gompi-2018a-test.eb')
        # Create the trivial toolchain mapping
        toolchain = {'name': 'gompi', 'version': '2018a'}
        tc_mapping = map_toolchain_hierarchies(toolchain, toolchain, self.modtool)
        # Update the software version
        init_config(build_options=build_options)
        get_toolchain_hierarchy.clear()
        new_version = '1.x.3'
        tweaked_spec = map_easyconfig_to_target_tc_hierarchy(ec_spec,
                                                             tc_mapping,
                                                             update_build_specs={'version': new_version},
                                                             update_dep_versions=False)
        tweaked_ec = process_easyconfig(tweaked_spec)[0]
        extensions = tweaked_ec['ec']['exts_list']
        # check one extension with the same name exists and that the version has been updated
        hit_extension = 0
        for extension in extensions:
            if isinstance(extension, tuple) and extension[0] == 'toy':
                self.assertEqual(extension[1], new_version)
                # Make sure checksum has been purged
                self.assertFalse('checksums' in extension[2])
                hit_extension += 1
        self.assertEqual(hit_extension, 1, "Should only have updated one extension")
コード例 #18
0
ファイル: robot.py プロジェクト: fizwit/easybuild-framework
    def test_robot_find_minimal_toolchain_of_dependency(self):
        """Test robot_find_minimal_toolchain_of_dependency."""

        # replace log.experimental with log.warning to allow experimental code
        easybuild.framework.easyconfig.tools._log.experimental = easybuild.framework.easyconfig.tools._log.warning

        test_easyconfigs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        init_config(build_options={
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })

        #
        # First test that it can do basic resolution
        #
        gzip15 = {
            'name': 'gzip',
            'version': '1.5',
            'versionsuffix': '',
            'toolchain': {'name': 'goolf', 'version': '1.4.10'},
        }
        get_toolchain_hierarchy.clear()
        new_gzip15_toolchain = robot_find_minimal_toolchain_of_dependency(gzip15, self.modtool)
        self.assertEqual(new_gzip15_toolchain, gzip15['toolchain'])

        # no easyconfig for gzip 1.4 with matching non-dummy (sub)toolchain
        gzip14 = {
            'name': 'gzip',
            'version': '1.4',
            'versionsuffix': '',
            'toolchain': {'name': 'goolf', 'version': '1.4.10'},
        }
        get_toolchain_hierarchy.clear()
        self.assertEqual(robot_find_minimal_toolchain_of_dependency(gzip14, self.modtool), None)

        gzip14['toolchain'] = {'name': 'gompi', 'version': '1.4.10'}

        #
        # Second test also including dummy toolchain
        #
        init_config(build_options={
            'add_dummy_to_minimal_toolchains': True,
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })
        # specify alternative parent toolchain
        gompi_1410 = {'name': 'gompi', 'version': '1.4.10'}
        get_toolchain_hierarchy.clear()
        new_gzip14_toolchain = robot_find_minimal_toolchain_of_dependency(gzip14, self.modtool, parent_tc=gompi_1410)
        self.assertTrue(new_gzip14_toolchain != gzip14['toolchain'])
        self.assertEqual(new_gzip14_toolchain, {'name': 'dummy', 'version': ''})

        # default: use toolchain from dependency
        gzip14['toolchain'] = gompi_1410
        get_toolchain_hierarchy.clear()
        new_gzip14_toolchain = robot_find_minimal_toolchain_of_dependency(gzip14, self.modtool)
        self.assertTrue(new_gzip14_toolchain != gzip14['toolchain'])
        self.assertEqual(new_gzip14_toolchain, {'name': 'dummy', 'version': ''})

        # check reversed order (parent tc first) and skipping of parent tc itself
        dep = {
            'name': 'SQLite',
            'version': '3.8.10.2',
            'toolchain': {'name': 'goolf', 'version': '1.4.10'},
        }
        res = robot_find_minimal_toolchain_of_dependency(dep, self.modtool)
        self.assertEqual(res, {'name': 'GCC', 'version': '4.7.2'})
        res = robot_find_minimal_toolchain_of_dependency(dep, self.modtool, parent_first=True)
        self.assertEqual(res, {'name': 'goolf', 'version': '1.4.10'})

        #
        # Finally test if it can recognise existing modules and use those
        #
        barec = os.path.join(self.test_prefix, 'bar-1.2.3-goolf-1.4.10.eb')
        barec_txt = '\n'.join([
            "easyblock = 'ConfigureMake'",
            "name = 'bar'",
            "version = '1.2.3'",
            "homepage = 'http://example.com'",
            "description = 'foo'",
            "toolchain = {'name': 'goolf', 'version': '1.4.10'}",
            # deliberately listing components of toolchain as dependencies without specifying subtoolchains,
            # to test resolving of dependencies with minimal toolchain
            # for each of these, we know test easyconfigs are available (which are required here)
            "dependencies = [",
            "   ('OpenMPI', '1.6.4'),",  # available with GCC/4.7.2
            "   ('OpenBLAS', '0.2.6', '-LAPACK-3.4.2'),",  # available with gompi/1.4.10
            "   ('ScaLAPACK', '2.0.2', '-OpenBLAS-0.2.6-LAPACK-3.4.2'),",  # available with gompi/1.4.10
            "   ('SQLite', '3.8.10.2'),",  # available with goolf/1.4.10, gompi/1.4.10 and GCC/4.7.2
            "]",
        ])
        write_file(barec, barec_txt)

        # check without --minimal-toolchains
        init_config(build_options={
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })
        bar = EasyConfig(barec)

        expected_dep_versions = [
            '1.6.4-GCC-4.7.2',
            '0.2.6-gompi-1.4.10-LAPACK-3.4.2',
            '2.0.2-gompi-1.4.10-OpenBLAS-0.2.6-LAPACK-3.4.2',
            '3.8.10.2-goolf-1.4.10',
        ]
        for dep, expected_dep_version in zip(bar.dependencies(), expected_dep_versions):
            self.assertEqual(det_full_ec_version(dep), expected_dep_version)

        # check with --minimal-toolchains enabled
        init_config(build_options={
            'minimal_toolchains': True,
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })
        bar = EasyConfig(barec)

        # check that all bar dependencies have been processed as expected
        expected_dep_versions[-1] = '3.8.10.2-GCC-4.7.2'
        for dep, expected_dep_version in zip(bar.dependencies(), expected_dep_versions):
            self.assertEqual(det_full_ec_version(dep), expected_dep_version)

        # Add the gompi/1.4.10 version of SQLite as an available module
        module_parent = os.path.join(self.test_prefix, 'minimal_toolchain_modules')
        module_file = os.path.join(module_parent, 'SQLite', '3.8.10.2-gompi-1.4.10')
        module_txt = '\n'.join([
            "#%Module",
            "set root /tmp/SQLite/3.8.10.2",
            "setenv EBROOTSQLITE $root",
            "setenv EBVERSIONSQLITE 3.8.10.2",
            "setenv  EBDEVELSQLITE $root/easybuild/SQLite-3.8.10.2-easybuild-devel",
        ])
        write_file(module_file, module_txt)
        os.environ['MODULEPATH'] = module_parent # Add the parent directory to the MODULEPATH
        invalidate_module_caches_for(module_parent)

        # Reinitialize the environment for the updated MODULEPATH and use_existing_modules
        init_config(build_options={
            'minimal_toolchains': True,
            'use_existing_modules': True,
            'valid_module_classes': module_classes(),
            'robot_path': test_easyconfigs,
        })

        # Check gompi is now being picked up
        bar = EasyConfig(barec) # Re-parse the parent easyconfig
        sqlite = bar.dependencies()[3]
        self.assertEqual(det_full_ec_version(sqlite), '3.8.10.2-gompi-1.4.10')

        # Add the goolf version as an available version and check that gets precedence over the gompi version
        module_file = os.path.join(module_parent, 'SQLite', '3.8.10.2-goolf-1.4.10')
        write_file(module_file, module_txt)
        invalidate_module_caches_for(module_parent)
        bar = EasyConfig(barec) # Re-parse the parent easyconfig
        sqlite = bar.dependencies()[3]
        self.assertEqual(det_full_ec_version(sqlite), '3.8.10.2-goolf-1.4.10')