def test_arch_no_exclude(self): '''Verify arch query string with no exclude option''' criteria = "arch" queue = self.files.database.getQueue() AIdb.getSpecificCriteria(queue, criteria) expect_query = "SELECT arch FROM manifests WHERE arch IS NOT NULL" self.assertEquals(expect_query, self.mockquery.query)
def test_MAXipv4(self): '''Verify single MAX query string ''' criteria = "MAXipv4" queue = self.files.database.getQueue() AIdb.getSpecificCriteria(queue, criteria) expect_query = "SELECT MAXipv4 FROM manifests WHERE MAXipv4 IS " + \ "NOT NULL" self.assertEquals(expect_query, self.mockquery.query)
def test_arch_exclude(self): '''Verify arch query string with exclude option''' criteria = "arch" queue = self.files.database.getQueue() AIdb.getSpecificCriteria(queue, criteria, excludeManifests=["suexml"]) expect_query = "SELECT arch FROM manifests WHERE arch IS NOT NULL " + \ "AND name IS NOT 'suexml'" self.assertEquals(expect_query, self.mockquery.query)
def test_MIN_MAXmac(self): '''Verify mac range query string ''' criteria = "MINmac" criteria2 = "MAXmac" queue = self.files.database.getQueue() AIdb.getSpecificCriteria(queue, criteria, criteria2=criteria2) expect_query = "SELECT HEX(MINmac), HEX(MAXmac) FROM manifests " + \ "WHERE (MINmac IS NOT NULL OR MAXmac IS NOT NULL)" self.assertEquals(expect_query, self.mockquery.query)
def test_MIN_MAXmem(self): '''Verify mem range query string ''' criteria = "MINmem" criteria2 = "MAXmem" queue = self.files.database.getQueue() AIdb.getSpecificCriteria(queue, criteria, criteria2=criteria2) expect_query = "SELECT MINmem, MAXmem FROM manifests WHERE " + \ "(MINmem IS NOT NULL OR MAXmem IS NOT NULL)" self.assertEquals(expect_query, self.mockquery.query)
def find_colliding_criteria(criteria, db, exclude_manifests=None): """ Returns: A dictionary of colliding criteria with keys being manifest name and instance tuples and values being the DB column names which collided Args: criteria - Criteria object holding the criteria that is to be added/set for a manifest. db - AI_database object for the install service. exclude_manifests -A list of manifest names from DB to ignore. This arg is passed in when we're calling this function to find criteria collisions for an already published manifest. Raises: SystemExit if: criteria is not found in database value is not valid for type (integer and hexadecimal checks) range is improper """ class Fields(object): """ Define convenience indexes """ # manifest name is row index 0 MANNAME = 0 # manifest instance is row index 1 MANINST = 1 # criteria is row index 2 (when a single valued criteria) CRIT = 2 # minimum criteria is row index 2 (when a range valued criteria) MINCRIT = 2 # maximum criteria is row index 3 (when a range valued criteria) MAXCRIT = 3 # collisions is a dictionary to hold keys of the form (manifest name, # instance) which will point to a comma-separated string of colliding # criteria collisions = dict() # verify each range criteria in the manifest is well formed and collect # collisions with database entries for crit in criteria: # gather this criteria's values from the manifest man_criterion = criteria[crit] # Determine if this crit is a range criteria or not. is_range_crit = AIdb.isRangeCriteria(db.getQueue(), crit, AIdb.MANIFESTS_TABLE) # Process "value" criteria here (check if the criteria exists in # DB, and then find collisions) if not is_range_crit: # only check criteria in use in the DB if crit not in AIdb.getCriteria(db.getQueue(), onlyUsed=False, strip=False): raise SystemExit( _("Error:\tCriteria %s is not a " + "valid criteria!") % crit) # get all values in the database for this criteria (and # manifest/instance pairs for each value) db_criteria = AIdb.getSpecificCriteria( db.getQueue(), crit, provideManNameAndInstance=True, excludeManifests=exclude_manifests) # will iterate over a list of the form [manName, manInst, crit, # None] for row in db_criteria: # check if a value in the list of values to be added is equal # to a value in the list of values for this criteria for this # row for value in man_criterion: if AIdb.is_in_list(crit, value, str(row[Fields.CRIT]), None): # record manifest name, instance and criteria name try: collisions[row[Fields.MANNAME], row[Fields.MANINST]] += crit + "," except KeyError: collisions[row[Fields.MANNAME], row[Fields.MANINST]] = crit + "," # This is a range criteria. (Check that ranges are valid, that # "unbounded" gets set to 0/+inf, ensure the criteria exists # in the DB, then look for collisions.) else: # Clean-up NULL's and change "unbounded"s to 0 and # really large numbers in case this Python does # not support IEEE754. Note "unbounded"s are already # converted to lower case during manifest processing. if man_criterion[0] == "unbounded": man_criterion[0] = "0" if man_criterion[1] == "unbounded": man_criterion[1] = INFINITY if crit == "mac": # convert hex mac address (w/o colons) to a number try: man_criterion[0] = long(str(man_criterion[0]).upper(), 16) man_criterion[1] = long(str(man_criterion[1]).upper(), 16) except ValueError: raise SystemExit( _("Error:\tCriteria %s " "is not a valid hexadecimal value") % crit) else: # this is a decimal value try: man_criterion = [ long(str(man_criterion[0]).upper()), long(str(man_criterion[1]).upper()) ] except ValueError: raise SystemExit( _("Error:\tCriteria %s " "is not a valid integer value") % crit) # Check for a properly ordered range (with unbounded being 0 or # Inf.) but ensure both are not unbounded. # Check for: # a range of zero to inf -- not a valid range # and # min > max -- range order reversed # if (man_criterion[0] == 0 and man_criterion[1] == long(INFINITY)): raise SystemExit( _("Error:\tCriteria %s is not a valid range, " "MIN and MAX unbounded.") % crit) if ((man_criterion[0] != 0 and man_criterion[1] != long(INFINITY)) and (long(man_criterion[0]) > long(man_criterion[1]))): raise SystemExit( _("Error:\tCriteria %s is not a valid range, " "MIN > MAX.") % crit) # check to see that this criteria exists in the database columns man_crit = AIdb.getCriteria(db.getQueue(), onlyUsed=False, strip=False) if 'MIN' + crit not in man_crit and 'MAX' + crit not in man_crit: raise SystemExit( _("Error:\tCriteria %s is not a " "valid criteria!") % crit) db_criteria = AIdb.getSpecificCriteria( db.getQueue(), 'MIN' + crit, 'MAX' + crit, provideManNameAndInstance=True, excludeManifests=exclude_manifests) # will iterate over a list of the form [manName, manInst, mincrit, # maxcrit] for row in db_criteria: # arbitrarily large number in case this Python does # not support IEEE754 db_criterion = ["0", INFINITY] # now populate in valid database values (i.e. non-NULL values) if row[Fields.MINCRIT]: db_criterion[0] = row[Fields.MINCRIT] if row[Fields.MAXCRIT]: db_criterion[1] = row[Fields.MAXCRIT] if crit == "mac": # use a hexadecimal conversion db_criterion = [ long(str(db_criterion[0]), 16), long(str(db_criterion[1]), 16) ] else: # these are decimal numbers db_criterion = [ long(str(db_criterion[0])), long(str(db_criterion[1])) ] # these three criteria can determine if there's a range overlap if ((man_criterion[1] >= db_criterion[0] and db_criterion[1] >= man_criterion[0]) or man_criterion[0] == db_criterion[1]): # range overlap so record the collision try: collisions[row[Fields.MANNAME], row[Fields.MANINST]] += "MIN" + crit + "," collisions[row[Fields.MANNAME], row[Fields.MANINST]] += "MAX" + crit + "," except KeyError: collisions[row[Fields.MANNAME], row[Fields.MANINST]] = "MIN" + crit + "," collisions[row[Fields.MANNAME], row[Fields.MANINST]] += "MAX" + crit + "," return collisions
def find_colliding_criteria(criteria, db, exclude_manifests=None): """ Returns: A dictionary of colliding criteria with keys being manifest name and instance tuples and values being the DB column names which collided Args: criteria - Criteria object holding the criteria that is to be added/set for a manifest. db - AI_database object for the install service. exclude_manifests -A list of manifest names from DB to ignore. This arg is passed in when we're calling this function to find criteria collisions for an already published manifest. Raises: SystemExit if: criteria is not found in database value is not valid for type (integer and hexadecimal checks) range is improper """ class Fields(object): """ Define convenience indexes """ # manifest name is row index 0 MANNAME = 0 # manifest instance is row index 1 MANINST = 1 # criteria is row index 2 (when a single valued criteria) CRIT = 2 # minimum criteria is row index 2 (when a range valued criteria) MINCRIT = 2 # maximum criteria is row index 3 (when a range valued criteria) MAXCRIT = 3 # collisions is a dictionary to hold keys of the form (manifest name, # instance) which will point to a comma-separated string of colliding # criteria collisions = dict() # verify each range criteria in the manifest is well formed and collect # collisions with database entries for crit in criteria: # gather this criteria's values from the manifest man_criterion = criteria[crit] # Determine if this crit is a range criteria or not. is_range_crit = AIdb.isRangeCriteria(db.getQueue(), crit, AIdb.MANIFESTS_TABLE) # Process "value" criteria here (check if the criteria exists in # DB, and then find collisions) if not is_range_crit: # only check criteria in use in the DB if crit not in AIdb.getCriteria(db.getQueue(), onlyUsed=False, strip=False): raise SystemExit(_("Error:\tCriteria %s is not a " + "valid criteria!") % crit) # get all values in the database for this criteria (and # manifest/instance pairs for each value) db_criteria = AIdb.getSpecificCriteria( db.getQueue(), crit, provideManNameAndInstance=True, excludeManifests=exclude_manifests) # will iterate over a list of the form [manName, manInst, crit, # None] for row in db_criteria: # check if a value in the list of values to be added is equal # to a value in the list of values for this criteria for this # row for value in man_criterion: if AIdb.is_in_list(crit, value, str(row[Fields.CRIT]), None): # record manifest name, instance and criteria name try: collisions[row[Fields.MANNAME], row[Fields.MANINST]] += crit + "," except KeyError: collisions[row[Fields.MANNAME], row[Fields.MANINST]] = crit + "," # This is a range criteria. (Check that ranges are valid, that # "unbounded" gets set to 0/+inf, ensure the criteria exists # in the DB, then look for collisions.) else: # Clean-up NULL's and change "unbounded"s to 0 and # really large numbers in case this Python does # not support IEEE754. Note "unbounded"s are already # converted to lower case during manifest processing. if man_criterion[0] == "unbounded": man_criterion[0] = "0" if man_criterion[1] == "unbounded": man_criterion[1] = INFINITY if crit == "mac": # convert hex mac address (w/o colons) to a number try: man_criterion[0] = long(str(man_criterion[0]).upper(), 16) man_criterion[1] = long(str(man_criterion[1]).upper(), 16) except ValueError: raise SystemExit(_("Error:\tCriteria %s " "is not a valid hexadecimal value") % crit) else: # this is a decimal value try: man_criterion = [long(str(man_criterion[0]).upper()), long(str(man_criterion[1]).upper())] except ValueError: raise SystemExit(_("Error:\tCriteria %s " "is not a valid integer value") % crit) # Check for a properly ordered range (with unbounded being 0 or # Inf.) but ensure both are not unbounded. # Check for: # a range of zero to inf -- not a valid range # and # min > max -- range order reversed # if (man_criterion[0] == 0 and man_criterion[1] == long(INFINITY)): raise SystemExit(_("Error:\tCriteria %s is not a valid range, " "MIN and MAX unbounded.") % crit) if ((man_criterion[0] != 0 and man_criterion[1] != long(INFINITY)) and (long(man_criterion[0]) > long(man_criterion[1]))): raise SystemExit(_("Error:\tCriteria %s is not a valid range, " "MIN > MAX.") % crit) # check to see that this criteria exists in the database columns man_crit = AIdb.getCriteria(db.getQueue(), onlyUsed=False, strip=False) if 'MIN' + crit not in man_crit and 'MAX' + crit not in man_crit: raise SystemExit(_("Error:\tCriteria %s is not a " "valid criteria!") % crit) db_criteria = AIdb.getSpecificCriteria( db.getQueue(), 'MIN' + crit, 'MAX' + crit, provideManNameAndInstance=True, excludeManifests=exclude_manifests) # will iterate over a list of the form [manName, manInst, mincrit, # maxcrit] for row in db_criteria: # arbitrarily large number in case this Python does # not support IEEE754 db_criterion = ["0", INFINITY] # now populate in valid database values (i.e. non-NULL values) if row[Fields.MINCRIT]: db_criterion[0] = row[Fields.MINCRIT] if row[Fields.MAXCRIT]: db_criterion[1] = row[Fields.MAXCRIT] if crit == "mac": # use a hexadecimal conversion db_criterion = [long(str(db_criterion[0]), 16), long(str(db_criterion[1]), 16)] else: # these are decimal numbers db_criterion = [long(str(db_criterion[0])), long(str(db_criterion[1]))] # these three criteria can determine if there's a range overlap if((man_criterion[1] >= db_criterion[0] and db_criterion[1] >= man_criterion[0]) or man_criterion[0] == db_criterion[1]): # range overlap so record the collision try: collisions[row[Fields.MANNAME], row[Fields.MANINST]] += "MIN" + crit + "," collisions[row[Fields.MANNAME], row[Fields.MANINST]] += "MAX" + crit + "," except KeyError: collisions[row[Fields.MANNAME], row[Fields.MANINST]] = "MIN" + crit + "," collisions[row[Fields.MANNAME], row[Fields.MANINST]] += "MAX" + crit + "," return collisions