def __init__(self, release, request, db, mashdir, close_shelf=True): self.request = request if request is UpdateRequest.stable: self.tag = release.stable_tag else: self.tag = release.testing_tag self.db = db self.updates = set() self.builds = {} self._from = config.get('bodhi_email') self.shelf = shelve.open(os.path.join(mashdir, '%s.shelve' % self.tag)) self._fetch_updates() self.uinfo = cr.UpdateInfo() self.comp_type = cr.XZ if release.id_prefix == u'FEDORA-EPEL': # FIXME: I'm not sure which versions of RHEL support xz metadata # compression, so use the lowest common denominator for now. self.comp_type = cr.BZ2 self.uinfo = cr.UpdateInfo() for update in self.updates: if not update.alias: update.assign_alias() self.add_update(update) if close_shelf: self.shelf.close()
def __init__(self, release, request, db, composedir, close_shelf=True): """ Initialize the UpdateInfoMetadata object. Args: release (bodhi.server.models.Release): The Release that is being composed. request (bodhi.server.models.UpdateRequest): The Request that is being composed. db (): A database session to be used for queries. composedir (str): A path to the composedir. close_shelf (bool): Whether to close the shelve, which is used to cache updateinfo between composes. """ self.request = request if request is UpdateRequest.stable: self.tag = release.stable_tag else: self.tag = release.testing_tag self.db = db self.updates = set() self.builds = {} self._from = config.get('bodhi_email') if config.get('cache_dir'): self.shelf = shelve.open( os.path.join(config.get('cache_dir'), '%s.shelve' % self.tag)) else: # If we have no cache dir, let's at least cache in-memory. self.shelf = {} close_shelf = False self._fetch_updates() self.uinfo = cr.UpdateInfo() self.comp_type = cr.XZ # Some repos such as FEDORA-EPEL, are primarily targeted at # distributions that use the yum client, which does not support zchunk metadata self.legacy_repos = ['FEDORA-EPEL'] self.zchunk = True if release.id_prefix in self.legacy_repos: # FIXME: I'm not sure which versions of RHEL support xz metadata # compression, so use the lowest common denominator for now. self.comp_type = cr.BZ2 log.warning( 'Zchunk data is disabled for repo {release.id_prefix} until it moves to a client' ' with Zchunk support') self.zchunk = False self.uinfo = cr.UpdateInfo() for update in self.updates: self.add_update(update) if close_shelf: self.shelf.close()
def __init__(self, release, request, db, path): self.repo = path log.debug('repo = %r' % self.repo) self.request = request if request is UpdateRequest.stable: self.tag = release.stable_tag else: self.tag = release.testing_tag self.repo_path = os.path.join(self.repo, self.tag) self.db = db self.updates = set() self.builds = {} self.missing_ids = [] self._from = config.get('bodhi_email') self.koji = get_session() self._fetch_updates() self.uinfo = cr.UpdateInfo() self.hash_type = cr.SHA256 self.comp_type = cr.XZ if release.id_prefix == u'FEDORA-EPEL': # yum on py2.4 doesn't support sha256 (#1080373) if 'el5' in self.repo or '5E' in self.repo: self.hash_type = cr.SHA1 self.comp_type = cr.GZ else: # FIXME: I'm not sure which versions of RHEL support xz metadata # compression, so use the lowest common denominator for now. self.comp_type = cr.BZ2 # Load from the cache if it exists self.cached_repodata = os.path.join(self.repo, '..', self.tag + '.repocache', 'repodata/') if os.path.isdir(self.cached_repodata): self._load_cached_updateinfo() else: log.debug("Generating new updateinfo.xml") self.uinfo = cr.UpdateInfo() for update in self.updates: if update.alias: self.add_update(update) else: self.missing_ids.append(update.title) if self.missing_ids: log.error("%d updates with missing ID: %r" % (len(self.missing_ids), self.missing_ids))
def __init__(self, release, request, db, mashdir, close_shelf=True): """ Initialize the UpdateInfoMetadata object. Args: release (bodhi.server.models.Release): The Release that is being mashed. request (bodhi.server.models.UpdateRequest): The Request that is being mashed. db (): A database session to be used for queries. mashdir (basestring): A path to the mashdir. close_shelf (bool): Whether to close the shelve, which is used to cache updateinfo between mashes. """ self.request = request if request is UpdateRequest.stable: self.tag = release.stable_tag else: self.tag = release.testing_tag self.db = db self.updates = set() self.builds = {} self._from = config.get('bodhi_email') if config.get('cache_dir'): self.shelf = shelve.open( os.path.join(config.get('cache_dir'), '%s.shelve' % self.tag)) else: # If we have no cache dir, let's at least cache in-memory. self.shelf = {} close_shelf = False self._fetch_updates() self.uinfo = cr.UpdateInfo() self.comp_type = cr.XZ if release.id_prefix == u'FEDORA-EPEL': # FIXME: I'm not sure which versions of RHEL support xz metadata # compression, so use the lowest common denominator for now. self.comp_type = cr.BZ2 self.uinfo = cr.UpdateInfo() for update in self.updates: if not update.alias: update.assign_alias() self.add_update(update) if close_shelf: self.shelf.close()
def test_updateinfo_setters(self): now = datetime.now() # Microseconds are always 0 in updateinfo now = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second, 0) ui = cr.UpdateInfo() self.assertTrue(ui) self.assertEqual(ui.updates, []) rec = cr.UpdateRecord() rec.fromstr = "from" rec.status = "status" rec.type = "type" rec.version = "version" rec.id = "id" rec.title = "title" rec.issued_date = now rec.updated_date = now rec.rights = "rights" rec.release = "release" rec.pushcount = "pushcount" rec.severity = "severity" rec.summary = "summary" rec.description = "description" rec.solution = "solution" rec.reboot_suggested = True ui.append(rec) self.assertEqual(len(ui.updates), 1) rec = ui.updates[0] self.assertEqual(rec.fromstr, "from") self.assertEqual(rec.status, "status") self.assertEqual(rec.type, "type") self.assertEqual(rec.version, "version") self.assertEqual(rec.id, "id") self.assertEqual(rec.title, "title") self.assertEqual(rec.issued_date, now) self.assertEqual(rec.updated_date, now) self.assertEqual(rec.rights, "rights") self.assertEqual(rec.release, "release") self.assertEqual(rec.pushcount, "pushcount") self.assertEqual(rec.severity, "severity") self.assertEqual(rec.summary, "summary") self.assertEqual(rec.description, "description") self.assertEqual(rec.solution, "solution") self.assertEqual(rec.reboot_suggested, True) self.assertEqual(len(rec.references), 0) self.assertEqual(len(rec.collections), 0) rec = cr.UpdateRecord() rec.issued_date = int(now.timestamp()) ui.append(rec) self.assertEqual(len(ui.updates), 2) rec = ui.updates[1] self.assertEqual(rec.issued_date, int(now.timestamp()))
def _test_extended_metadata(self, has_alias): update = self.db.query(Update).one() # Pretend it's pushed to testing update.status = UpdateStatus.testing update.request = None if not has_alias: update.alias = None update.date_pushed = datetime.utcnow() DevBuildsys.__tagged__[update.title] = ['f17-updates-testing'] # Generate the XML md = UpdateInfoMetadata(update.release, update.request, self.db, self.tempcompdir) # Insert the updateinfo.xml into the repository md.insert_updateinfo(self.tempcompdir) updateinfo = self._verify_updateinfo(self.repodata) # Read an verify the updateinfo.xml.gz uinfo = createrepo_c.UpdateInfo(updateinfo) notice = self.get_notice(uinfo, 'mutt-1.5.14-1.fc13') self.assertIsNone(notice) self.assertEquals(len(uinfo.updates), 1) notice = uinfo.updates[0] self.assertIsNotNone(notice) self.assertEquals(notice.title, update.title) self.assertEquals(notice.release, update.release.long_name) self.assertEquals(notice.status, update.status.value) if update.date_modified: self.assertEquals(notice.updated_date, update.date_modified) self.assertEquals(notice.fromstr, config.get('bodhi_email')) self.assertEquals(notice.rights, config.get('updateinfo_rights')) self.assertEquals(notice.description, update.notes) self.assertEquals(notice.id, update.alias) bug = notice.references[0] self.assertEquals(bug.href, update.bugs[0].url) self.assertEquals(bug.id, '12345') self.assertEquals(bug.type, 'bugzilla') cve = notice.references[1] self.assertEquals(cve.type, 'cve') self.assertEquals(cve.href, update.cves[0].url) self.assertEquals(cve.id, update.cves[0].cve_id) col = notice.collections[0] self.assertEquals(col.name, update.release.long_name) self.assertEquals(col.shortname, update.release.name) pkg = col.packages[0] self.assertEquals(pkg.epoch, '0') self.assertEquals(pkg.name, 'TurboGears') self.assertEquals(pkg.src, ( 'https://download.fedoraproject.org/pub/fedora/linux/updates/testing/17/SRPMS/T/' 'TurboGears-1.0.2.2-2.fc17.src.rpm')) self.assertEquals(pkg.version, '1.0.2.2') self.assertFalse(pkg.reboot_suggested) self.assertEquals(pkg.arch, 'src') self.assertEquals(pkg.filename, 'TurboGears-1.0.2.2-2.fc17.src.rpm')
def _test_extended_metadata(self): update = self.db.query(Update).one() # Pretend it's pushed to testing update.status = UpdateStatus.testing update.request = None update.date_pushed = datetime.utcnow() DevBuildsys.__tagged__[update.title] = ['f17-updates-testing'] # Generate the XML md = UpdateInfoMetadata(update.release, update.request, self.db, self.tempcompdir) # Insert the updateinfo.xml into the repository md.insert_updateinfo(self.tempcompdir) updateinfos = self._verify_updateinfos(self.repodata) for updateinfo in updateinfos: # Read an verify the updateinfo.xml.gz uinfo = createrepo_c.UpdateInfo(updateinfo) notice = self.get_notice(uinfo, 'mutt-1.5.14-1.fc13') assert notice is None assert len(uinfo.updates) == 1 notice = uinfo.updates[0] assert notice is not None assert notice.title == update.title assert notice.release == update.release.long_name assert notice.status == update.status.value if update.date_modified: assert notice.updated_date == update.date_modified assert notice.fromstr == config.get('bodhi_email') assert notice.rights == config.get('updateinfo_rights') assert notice.description == update.notes assert notice.id == update.alias assert notice.severity == 'Moderate' bug = notice.references[0] assert bug.href == update.bugs[0].url assert bug.id == '12345' assert bug.type == 'bugzilla' col = notice.collections[0] assert col.name == update.release.long_name assert col.shortname == update.release.name pkg = col.packages[0] assert pkg.epoch == '0' assert pkg.name == 'TurboGears' assert pkg.src == \ ('https://download.fedoraproject.org/pub/fedora/linux/updates/testing/17/SRPMS/T/' 'TurboGears-1.0.2.2-2.fc17.src.rpm') assert pkg.version == '1.0.2.2' assert not pkg.reboot_suggested assert not pkg.relogin_suggested assert pkg.arch == 'src' assert pkg.filename == 'TurboGears-1.0.2.2-2.fc17.src.rpm'
def test_updateinfo_getter(self): ui = cr.UpdateInfo(TEST_UPDATEINFO_03) self.assertTrue(ui) self.assertEqual(len(ui.updates), 6) rec = ui.updates[2] self.assertRaisesRegex(cr.CreaterepoCError, "Unable to parse updateinfo record date: 15mangled2", rec.__getattribute__, "issued_date")
def test_updateinfo_xml_dump_02(self): now = datetime.now() # Microseconds are always 0 in updateinfo now = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second, 0) ui = cr.UpdateInfo() xml = ui.xml_dump() rec = cr.UpdateRecord() rec.fromstr = "from" rec.status = "status" rec.type = "type" rec.version = "version" rec.id = "id" rec.title = "title" rec.issued_date = now rec.updated_date = now rec.rights = "rights" rec.release = "release" rec.pushcount = "pushcount" rec.severity = "severity" rec.summary = "summary" rec.description = "description" rec.solution = "solution" rec.reboot_suggested = True ui.append(rec) xml = ui.xml_dump() self.assertEqual( xml, """<?xml version="1.0" encoding="UTF-8"?> <updates> <update from="from" status="status" type="type" version="version"> <id>id</id> <title>title</title> <issued date="%(now)s"/> <updated date="%(now)s"/> <rights>rights</rights> <release>release</release> <pushcount>pushcount</pushcount> <severity>severity</severity> <summary>summary</summary> <description>description</description> <solution>solution</solution> <reboot_suggested>True</reboot_suggested> <references/> <pkglist/> </update> </updates> """ % {"now": now.strftime("%Y-%m-%d %H:%M:%S")})
def hash_update_record(update): """ Find the hex digest for an update record xml from creatrepo_c. Args: update(createrepo_c.UpdateRecord): update record Returns: str: a hex digest representing the update record """ uinfo = cr.UpdateInfo() uinfo.append(update) return hashlib.sha256(uinfo.xml_dump().encode('utf-8')).hexdigest()
async def parse_updateinfo(updateinfo_xml_path): """ Parse updateinfo.xml to extact update info. Args: updateinfo_xml_path: a path to a downloaded updateinfo.xml Returns: :obj:`list` of :obj:`createrepo_c.UpdateRecord`: parsed update records """ uinfo = cr.UpdateInfo() # TODO: handle parsing errors/warnings, warningcb callback can be used cr.xml_parse_updateinfo(updateinfo_xml_path, uinfo) return uinfo.updates
def parse_updateinfo(path): uinfo = cr.UpdateInfo(path) for update in uinfo.updates: print "From: %s" % update.fromstr print "Status: %s" % update.status print "Type: %s" % update.type print "Version: %s" % update.version print "Id: %s" % update.id print "Title: %s" % update.title print "Issued date: %s" % update.issued_date print "Updated date: %s" % update.updated_date print "Rights: %s" % update.rights print "Release: %s" % update.release print "Pushcount: %s" % update.pushcount print "Severity: %s" % update.severity print "Summary: %s" % update.summary print "Description: %s" % update.description print "Solution: %s" % update.solution print "References:" for ref in update.references: print " Href: %s" % ref.href print " Id: %s" % ref.id print " Type: %s" % ref.type print " Title: %s" % ref.title print " ----------------------------" print "Pkglist (collections):" for col in update.collections: print " Short: %s" % col.shortname print " name: %s" % col.name print " Packages:" for pkg in col.packages: print " Name: %s" % pkg.name print " Version: %s" % pkg.version print " Release: %s" % pkg.release print " Epoch: %s" % pkg.epoch print " Arch: %s" % pkg.arch print " Src: %s" % pkg.src print " Filename: %s" % pkg.filename print " Sum: %s" % pkg.sum print " Sum type: %s (%s)" % ( pkg.sum_type, cr.checksum_name_str(pkg.sum_type)) print " Reboot suggested: %s" % pkg.reboot_suggested print " ----------------------------" print "=============================="
def generate(): pkg = cr.UpdateCollectionPackage() pkg.name = "Foo" pkg.version = "1.2.3" pkg.release = "1" pkg.epoch = "0" pkg.arch = "noarch" pkg.src = "foo.src.rpm" pkg.filename = "foo-1.2.3-1.rpm" pkg.sum = "123456789" pkg.sum_type = cr.MD5 pkg.reboot_suggested = False col = cr.UpdateCollection() col.shortname = "Bar-product" col.name = "Bar Product" col.append(pkg) ref = cr.UpdateReference() ref.href = "http://foo.bar/foobar" ref.id = "123" ref.type = "self" ref.title = "Foo Update" rec = cr.UpdateRecord() rec.fromstr = "*****@*****.**" rec.status = "final" rec.type = "enhancement" rec.version = "1" rec.id = "UPDATE-1" rec.title = "Bar Product Update" rec.issued_date = datetime.datetime(2014, 8, 14) rec.updated_date = datetime.datetime(2014, 8, 14) rec.rights = "Copyright 2014 Bar Inc" rec.summary = "An update for Bar" rec.description = "Fixes a bug" rec.append_collection(col) rec.append_reference(ref) ui = cr.UpdateInfo() ui.append(rec) print ui.xml_dump(),
def test_updateinfo_xml_dump_01(self): ui = cr.UpdateInfo() xml = ui.xml_dump() self.assertEqual( xml, """<?xml version="1.0" encoding="UTF-8"?>\n<updates/>\n""")
def test_updateinfo_xml_dump_05(self): now = datetime.now() # Microseconds are always 0 in updateinfo now = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second, 0) # Collection module with unset fields mod = cr.UpdateCollectionModule() mod.version = 18446744073709551615 mod.context = "deadbeef" mod.arch = "x86" pkg = cr.UpdateCollectionPackage() pkg.name = "foo" pkg.version = "1.2" pkg.release = "3" pkg.epoch = "0" pkg.arch = "x86" pkg.src = "foo.src.rpm" pkg.filename = "foo.rpm" pkg.sum = "abcdef" pkg.sum_type = cr.SHA1 pkg.reboot_suggested = True pkg.restart_suggested = True col = cr.UpdateCollection() col.shortname = "short name" col.name = "long name" col.module = mod col.append(pkg) ref = cr.UpdateReference() ref.href = "href" ref.id = "id" ref.type = "type" ref.title = "title" rec = cr.UpdateRecord() rec.fromstr = "from" rec.status = "status" rec.type = "type" rec.version = "version" rec.id = "id" rec.title = "title" rec.issued_date = now rec.updated_date = now rec.rights = "rights" rec.release = "release" rec.pushcount = "pushcount" rec.severity = "severity" rec.summary = "summary" rec.description = "description" rec.solution = "solution" rec.reboot_suggested = True rec.append_collection(col) rec.append_reference(ref) ui = cr.UpdateInfo() ui.append(rec) xml = ui.xml_dump() self.assertEqual( xml, """<?xml version="1.0" encoding="UTF-8"?> <updates> <update from="from" status="status" type="type" version="version"> <id>id</id> <title>title</title> <issued date="%(now)s"/> <updated date="%(now)s"/> <rights>rights</rights> <release>release</release> <pushcount>pushcount</pushcount> <severity>severity</severity> <summary>summary</summary> <description>description</description> <solution>solution</solution> <reboot_suggested>True</reboot_suggested> <references> <reference href="href" id="id" type="type" title="title"/> </references> <pkglist> <collection short="short name"> <name>long name</name> <module version="18446744073709551615" context="deadbeef" arch="x86"/> <package name="foo" version="1.2" release="3" epoch="0" arch="x86" src="foo.src.rpm"> <filename>foo.rpm</filename> <sum type="sha1">abcdef</sum> <reboot_suggested>True</reboot_suggested> <restart_suggested>True</restart_suggested> </package> </collection> </pkglist> </update> </updates> """ % {"now": now.strftime("%Y-%m-%d %H:%M:%S")})
def _load_cached_updateinfo(self): """ Load the cached updateinfo.xml from '../{tag}.repocache/repodata' """ seen_ids = set() from_cache = set() existing_ids = set() # Parse the updateinfo out of the repomd updateinfo = None repomd_xml = os.path.join(self.cached_repodata, 'repomd.xml') repomd = cr.Repomd() cr.xml_parse_repomd(repomd_xml, repomd) for record in repomd.records: if record.type == 'updateinfo': updateinfo = os.path.join(os.path.dirname( os.path.dirname(self.cached_repodata)), record.location_href) break assert updateinfo, 'Unable to find updateinfo' # Load the metadata with createrepo_c log.info('Loading cached updateinfo: %s', updateinfo) uinfo = cr.UpdateInfo(updateinfo) # Determine which updates are present in the cache for update in uinfo.updates: existing_ids.add(update.id) # Generate metadata for any new builds for update in self.updates: seen_ids.add(update.alias) if not update.alias: self.missing_ids.append(update.title) continue if update.alias in existing_ids: notice = None for value in uinfo.updates: if value.title == update.title: notice = value break if not notice: log.warn('%s ID in cache but notice cannot be found', update.title) self.add_update(update) continue if notice.updated_date: if notice.updated_date < update.date_modified: log.debug('Update modified, generating new notice: %s' % update.title) self.add_update(update) else: log.debug('Loading updated %s from cache' % update.title) from_cache.add(update.alias) elif update.date_modified: log.debug('Update modified, generating new notice: %s' % update.title) self.add_update(update) else: log.debug('Loading %s from cache' % update.title) from_cache.add(update.alias) else: log.debug('Adding new update notice: %s' % update.title) self.add_update(update) # Add all relevant notices from the cache to this document for notice in uinfo.updates: if notice.id in from_cache: log.debug('Keeping existing notice: %s', notice.title) self.uinfo.append(notice) else: # Keep all security notices in the stable repo if self.request is not UpdateRequest.testing: if notice.type == 'security': if notice.id not in seen_ids: log.debug('Keeping existing security notice: %s', notice.title) self.uinfo.append(notice) else: log.debug('%s already added?', notice.title) else: log.debug('Purging cached stable notice %s', notice.title) else: log.debug('Purging cached testing update %s', notice.title)
def test_metadata_updating_with_old_testing_security(self): update = self.db.query(Update).one() update.request = None update.type = UpdateType.security update.status = UpdateStatus.testing update.date_pushed = datetime.utcnow() DevBuildsys.__tagged__[update.title] = ['f17-updates-testing'] # Generate the XML md = ExtendedMetadata(update.release, UpdateRequest.testing, self.db, self.temprepo) # Insert the updateinfo.xml into the repository md.insert_updateinfo() md.cache_repodata() updateinfo = self._verify_updateinfo(self.repodata) # Read an verify the updateinfo.xml.gz uinfo = createrepo_c.UpdateInfo(updateinfo) notice = self.get_notice(uinfo, update.title) self.assertIsNotNone(notice) # Create a new non-security update for the same package newbuild = 'bodhi-2.0-2.fc17' pkg = self.db.query(Package).filter_by(name=u'bodhi').one() build = Build(nvr=newbuild, package=pkg) self.db.add(build) self.db.flush() newupdate = Update(title=newbuild, type=UpdateType.enhancement, status=UpdateStatus.testing, request=None, release=update.release, builds=[build], notes=u'x') newupdate.assign_alias() self.db.add(newupdate) self.db.flush() # Untag the old security build del (DevBuildsys.__tagged__[update.title]) DevBuildsys.__untag__.append(update.title) DevBuildsys.__tagged__[newupdate.title] = [ newupdate.release.testing_tag ] buildrpms = DevBuildsys.__rpms__[0].copy() buildrpms['nvr'] = 'bodhi-2.0-2.fc17' buildrpms['release'] = '2.fc17' DevBuildsys.__rpms__.append(buildrpms) del (DevBuildsys.__rpms__[0]) # Re-initialize our temporary repo shutil.rmtree(self.temprepo) os.mkdir(self.temprepo) mkmetadatadir(join(self.temprepo, 'f17-updates-testing', 'i386')) md = ExtendedMetadata(update.release, UpdateRequest.testing, self.db, self.temprepo) md.insert_updateinfo() updateinfo = self._verify_updateinfo(self.repodata) # Read an verify the updateinfo.xml.gz uinfo = createrepo_c.UpdateInfo(updateinfo) self.assertEquals(len(uinfo.updates), 1) notice = self.get_notice(uinfo, 'bodhi-2.0-1.fc17') self.assertIsNone(notice) notice = self.get_notice(uinfo, 'bodhi-2.0-2.fc17') self.assertIsNotNone(notice)
def test_metadata_updating_with_edited_update(self): update = self.db.query(Update).one() # Pretend it's pushed to testing update.status = UpdateStatus.testing update.request = None update.date_pushed = datetime.utcnow() DevBuildsys.__tagged__[update.title] = ['f17-updates-testing'] # Generate the XML md = ExtendedMetadata(update.release, update.request, self.db, self.temprepo) # Insert the updateinfo.xml into the repository md.insert_updateinfo() md.cache_repodata() updateinfo = self._verify_updateinfo(self.repodata) # Read an verify the updateinfo.xml.gz uinfo = createrepo_c.UpdateInfo(updateinfo) notice = self.get_notice(uinfo, update.title) self.assertIsNotNone(notice) self.assertEquals(notice.title, update.title) self.assertEquals(notice.release, update.release.long_name) self.assertEquals(notice.status, update.status.value) self.assertEquals(notice.updated_date, update.date_modified) self.assertEquals(notice.fromstr, config.get('bodhi_email')) self.assertEquals(notice.description, update.notes) self.assertIsNotNone(notice.issued_date) self.assertEquals(notice.id, update.alias) #self.assertIsNone(notice.epoch) bug = notice.references[0] self.assertEquals(bug.href, update.bugs[0].url) self.assertEquals(bug.id, '12345') self.assertEquals(bug.type, 'bugzilla') cve = notice.references[1] self.assertEquals(cve.type, 'cve') self.assertEquals(cve.href, update.cves[0].url) self.assertEquals(cve.id, update.cves[0].cve_id) # Change the notes on the update *and* the date_modified update.notes = u'x' update.date_modified = datetime.utcnow() # Re-initialize our temporary repo shutil.rmtree(self.temprepo) os.mkdir(self.temprepo) mkmetadatadir(join(self.temprepo, 'f17-updates-testing', 'i386')) md = ExtendedMetadata(update.release, update.request, self.db, self.temprepo) md.insert_updateinfo() updateinfo = self._verify_updateinfo(self.repodata) # Read an verify the updateinfo.xml.gz uinfo = createrepo_c.UpdateInfo(updateinfo) notice = self.get_notice(uinfo, update.title) self.assertIsNotNone(notice) self.assertEquals(notice.description, u'x') self.assertEquals(notice.updated_date.strftime('%Y-%m-%d %H:%M:%S'), update.date_modified.strftime('%Y-%m-%d %H:%M:%S'))