示例#1
0
    def test_ordered_versop_expressions(self):
        """Given set of ranges, order them according to version/operator (most recent/specific first)"""
        # simple version ordering, all different versions
        ovop = OrderedVersionOperators()
        versop_exprs = [
            '> 3.0.0',
            '>= 2.5.0',
            '> 2.0.0',
            '== 1.0.0',
        ]
        # add version expressions out of order intentionally
        ovop.add(versop_exprs[1])
        ovop.add(versop_exprs[-1])
        ovop.add(versop_exprs[0])
        ovop.add(versop_exprs[2])

        # verify whether order is what we expect it to be
        self.assertEqual(ovop.versops,
                         [VersionOperator(x) for x in versop_exprs])

        # more complex version ordering, identical/overlapping vesions
        ovop = OrderedVersionOperators()
        versop_exprs = [
            '== 1.0.0',
            '> 1.0.0',
            '< 1.0.0',
        ]
        # add version expressions out of order intentionally
        ovop.add(versop_exprs[-1])
        ovop.add(versop_exprs[1])
        ovop.add(versop_exprs[0])
        # verify whether order is what we expect it to be
        self.assertEqual(ovop.versops,
                         [VersionOperator(x) for x in versop_exprs])
示例#2
0
    def __init__(self):
        """Initialise Squashed instance"""
        self.log = fancylogger.getLogger(self.__class__.__name__, fname=False)

        # OrderedVersionOperators instances to keep track of the data of the matching
        # version and toolchain version sections
        self.versions = OrderedVersionOperators()
        self.tcversions = OrderedVersionOperators()
        self.result = {}
示例#3
0
    def _squash_versop(self, key, value, squashed, sanity, vt_tuple):
        """
        Squash VERSION_OPERATOR_VALUE_TYPES value
            return None or new Squashed instance
        :param key: section key
        :param nested_dict: the nested_dict instance
        :param squashed: Squashed instance
        :param sanity: the sanity dict
        :param vt_tuple: version, tc_name, tc_version tuple
        """
        version, tcname, tcversion = vt_tuple
        if key == 'toolchains':
            # remove any other toolchain from list
            self.log.debug("Filtering 'toolchains' key")

            matching_toolchains = []
            tmp_tc_oversops = {}  # temporary, only for conflict checking
            for tcversop in value:
                tc_overops = tmp_tc_oversops.setdefault(tcversop.tc_name, OrderedVersionOperators())
                self.log.debug("Add tcversop %s to tc_overops %s tcname %s tcversion %s",
                               tcversop, tc_overops, tcname, tcversion)
                tc_overops.add(tcversop)  # test non-conflicting list
                if tcversop.test(tcname, tcversion):
                    matching_toolchains.append(tcversop)

            if matching_toolchains:
                # does this have any use?
                self.log.debug('Matching toolchains %s found (but data not needed)' % matching_toolchains)
            else:
                self.log.debug('No matching toolchains, removing the whole current key %s' % key)
                return Squashed()

        elif key == 'versions':
            self.log.debug("Adding all versions %s from versions key" % value)
            matching_versions = []
            tmp_versops = OrderedVersionOperators()  # temporary, only for conflict checking
            for versop in value:
                tmp_versops.add(versop)  # test non-conflicting list
                if versop.test(version):
                    matching_versions.append(versop)
            if matching_versions:
                # does this have any use?
                self.log.debug('Matching versions %s found (but data not needed)' % matching_versions)
            else:
                self.log.debug('No matching versions, removing the whole current key %s' % key)
                return Squashed()
        else:
            raise EasyBuildError('Unexpected VERSION_OPERATOR_VALUE_TYPES key %s value %s', key, value)

        return None
示例#4
0
    def test_ordered_versop_add_data(self):
        """Test the add and data handling"""
        ovop = OrderedVersionOperators()
        tests = [
            ('> 1', '5'),
            ('> 2', {
                'x': 3
            }),
        ]
        for versop_txt, data in tests:
            versop = VersionOperator(versop_txt)
            ovop.add(versop)
            # no data was added, this is a new entry, mapper is initialised with None
            self.assertEqual(ovop.get_data(versop), None)
            ovop.add(versop, data)
            # test data
            self.assertEqual(ovop.get_data(versop), data)

        # new data for same versops
        tests = [
            ('> 1', '6'),
            ('> 2', {
                'x': 4
            }),
        ]
        for versop_txt, data in tests:
            versop = VersionOperator(versop_txt)
            ovop.add(versop, data)
            # test updated data
            self.assertEqual(ovop.get_data(versop), data)

        # 'update' a value
        # the data for '> 1' has no .update()
        extra_data = {'y': 4}
        tests = [
            ('> 2', extra_data),
        ]
        for versop_txt, data in tests:
            versop = VersionOperator(versop_txt)
            prevdata = copy.deepcopy(ovop.get_data(versop))
            prevdata.update(extra_data)

            ovop.add(versop, data, update=True)
            # test updated data
            self.assertEqual(ovop.get_data(versop), prevdata)

        # use update=True on new element
        versop = VersionOperator('> 10000')
        new_data = {'new': 5}
        ovop.add(versop, new_data, update=True)
        # test updated data
        self.assertEqual(ovop.get_data(versop), new_data)
示例#5
0
    def _squash_netsed_dict(self, key, nested_dict, squashed, sanity,
                            vt_tuple):
        """
        Squash NestedDict instance, returns dict with already squashed data 
            from possible higher sections 
        @param key: section key
        @param nested_dict: the nested_dict instance
        @param squashed: Squashed instance
        @param sanity: the sanity dict
        @param vt_tuple: version, tc_name, tc_version tuple
        """
        version, tcname, tcversion = vt_tuple
        res_sections = {}

        if isinstance(key, ToolchainVersionOperator):
            # perform sanity check for all toolchains, use .add to check for conflicts
            tc_overops = sanity['toolchains'].setdefault(
                key.tc_name, OrderedVersionOperators())
            tc_overops.add(key)

            if key.test(tcname, tcversion):
                tup = (tcname, tcversion, key)
                self.log.debug(
                    "Found matching marker for specified toolchain '%s, %s': %s"
                    % tup)
                # TODO remove when unifying add_toolchina with .add()
                tmp_squashed = self._squash(vt_tuple, nested_dict, sanity)
                res_sections.update(tmp_squashed.result)
                squashed.add_toolchain(tmp_squashed)
            else:
                tmpl = "Found marker for other toolchain or version '%s', ignoring this (nested) section."
                self.log.debug(tmpl % key)
        elif isinstance(key, VersionOperator):
            # keep track of all version operators, and enforce conflict check
            sanity['versops'].add(key)
            if key.test(version):
                self.log.debug('Found matching version marker %s' % key)
                squashed.add_version(
                    key, self._squash(vt_tuple, nested_dict, sanity))
            else:
                self.log.debug(
                    'Found non-matching version marker %s. Ignoring this (nested) section.'
                    % key)
        else:
            self.log.error("Unhandled section marker '%s' (type '%s')" %
                           (key, type(key)))

        return res_sections
示例#6
0
    def squash(self, version, tcname, tcversion):
        """
        Project the multidimensional easyconfig to single easyconfig
        It (tries to) detect conflicts in the easyconfig.

        @param version: version to keep
        @param tcname: toolchain name to keep
        @param tcversion: toolchain version to keep
        """
        self.log.debug('Start squash with sections %s' % self.sections)

        # dictionary to keep track of all sections, to detect conflicts in the easyconfig
        sanity = {
            'versops': OrderedVersionOperators(),
            'toolchains': {},
        }

        vt_tuple = (version, tcname, tcversion)
        squashed = self._squash(vt_tuple, self.sections, sanity)
        result = squashed.final()

        self.log.debug('End squash with result %s' % result)
        return result