Author: fw Date: 2005-09-14 20:48:54 +0000 (Wed, 14 Sep 2005) New Revision: 1983 Modified: Makefile bin/update-packages lib/python/bugs.py lib/python/security_db.py Log: This change groups binary packages for different architectures, as long as they have the same version. Synthesis of testing/stable/oldstable has been disabled (and will be replaced with new code). lib/python/security_db.py (mergeLists): New helper functions to deal with architecture lists. (DB.initSchema): Add parsed column to inodeprints table. Update source_packages and binary_packages table. Split package_status into source_package_status and binary_package_status. (DB.updateSources, DB.updatePackages): Remove and replace with ... (DB.readPackages): ... new method. (DB.availableReleases, DB._updateVersions): Adjust to new schema. (DB.calculateVulnerabilities): Disable synthesis of testing etc. Adjust to new schema. Fix bug in large INSERT INTO statements: Need t.release = p.release instead of t.release = n.release. Add return to disable bug-specific rating code. (test): Update. lib/python/bugs.py (PackageNote.releaseStatus): Rename ... (PackageNote.sourceStatus): ... and make it specific to source packages. (BugFromDB.getDebianBugs): New method to get a list of Debian bug numbers. bin/update-packages (import): Automatically reads the correct directory. Makefile (stamps/packages-imported): Update accordingly. Modified: Makefile ==================================================================--- Makefile 2005-09-14 19:20:56 UTC (rev 1982) +++ Makefile 2005-09-14 20:48:54 UTC (rev 1983) @@ -27,8 +27,7 @@ # update-packages" has been invoked before. stamps/packages-imported: $(PACKAGE_FILES) if test -e stamps/packages-downloaded ; then \ - $(PYTHON) bin/update-packages import \ - $(RELEASES) $(SECURITY_RELEASES) ; \ + $(PYTHON) bin/update-packages import ; \ fi touch $@ Modified: bin/update-packages ==================================================================--- bin/update-packages 2005-09-14 19:20:56 UTC (rev 1982) +++ bin/update-packages 2005-09-14 20:48:54 UTC (rev 1983) @@ -70,35 +70,21 @@ def cmd_import(args): db_file = root_path + ''/data/security.db'' + new_file = not os.path.exists(db_file) db = security_db.DB(db_file, verbose=True) - try: - for release, archs in explodeReleases(args): - for archive in archives: - c = db.writeTxn() - db.maybeUpdateSources(c, release, archive, - nameSources(release, archive)) - db.commit(c) - for arch in archs: - c = db.writeTxn() - db.maybeUpdatePackages(c, release, archive, arch, - namePackages(release, - archive, arch)) - db.commit(c) - except IOError, e: - if e.errno == errno.ENOENT: - sys.stderr.write( -"""error: could not open a file -error: please run ''update-packages download'' first -""") - sys.exit(1) + if new_file: + db.initSchema() + c = db.writeTxn() + db.readPackages(c, root_path + ''/data/packages'') + db.commit(c) cmds = {"download" : cmd_download, "import" : cmd_import} -if len(sys.argv) < 3 or not cmds.has_key(sys.argv[1]): +if len(sys.argv) < 2 or not cmds.has_key(sys.argv[1]): sys.stderr.write(\ """usage: update-packages download URL-BASE RELEASE=ARCH... - update-packages import RELEASE=ARCH... + update-packages import """) sys.exit(1) try: Modified: lib/python/bugs.py ==================================================================--- lib/python/bugs.py 2005-09-14 19:20:56 UTC (rev 1982) +++ lib/python/bugs.py 2005-09-14 20:48:54 UTC (rev 1983) @@ -103,25 +103,32 @@ else: return "unfixed" - def releaseStatus(self, cursor): - """Returns a pair of lists (VULNERABLE, NON-VULNERABLE). + def sourceStatus(self, cursor): + """Returns a pair of lists (VERSION, RELEASE-LIST). - The lists consits of triples (release, archive, architecture). + The first one is the list with the vulnerable versions, the + second one contains fixed versions. """ - vulnerable = [] - non_vulnerable = [] - - for (release, archive, architecture, vuln) in cursor.execute( - """SELECT release, archive, architecture, vulnerable - FROM package_status WHERE note = ?""", (self.id,)): - t = (release, archive,architecture) - if vuln: - vulnerable.append(t) + vulnerable_versions = {} + fixed_versions = {} + for (release, archive, version, vulnerable) in cursor.execute( + """SELECT p.release, p.archive, p.version, s.vulnerable + FROM source_package_status AS s, source_packages AS p + WHERE s.note = ? AND p.rowid = s.package""", (self.id,)): + if vulnerable: + versions = vulnerable_versions else: - non_vulnerable.append(t) + versions = fixed_versions + if not versions.has_key(version): + versions[version] = [] + versions[version].append((release, archive)) - return (vulnerable, non_vulnerable) + def sort(versions): + l = map(debian_support.Version, versions.keys()) + l.sort() + return map(lambda ver: (ver, versions[str(ver)]), l) + return (sort(vulnerable_versions), sort(fixed_versions)) def writeDB(self, cursor, bug_name): """Writes the object to an SQLite database. @@ -342,6 +349,14 @@ return raise ValueError, "unknown bug " + `name` + def getDebianBugs(self, cursor): + """Returns a list of Debian bugs to which the bug report refers.""" + return map(lambda (x,): x, cursor.execute( + """SELECT DISTINCT bug FROM debian_bugs, package_notes + WHERE package_notes.bug_name = ? + AND debian_bugs.note = package_notes.id + ORDER BY bug""", (self.name,))) + class BugReservedCVE(BugBase): """Class for reserved CVE entries.""" def __init__(self, fname, lineno, name, comments=None): Modified: lib/python/security_db.py ==================================================================--- lib/python/security_db.py 2005-09-14 19:20:56 UTC (rev 1982) +++ lib/python/security_db.py 2005-09-14 20:48:54 UTC (rev 1983) @@ -28,7 +28,10 @@ import apsw import bugs +import cPickle +import cStringIO import debian_support +import glob import os import re import sys @@ -49,6 +52,27 @@ def __str__(self): return self.errors[0] + '' [more...]'' +def mergeLists(a, b): + """Merges two lists.""" + if type(a) == types.StringType: + if a == "": + a = [] + else: + a = a.split('','') + if type(b) == types.StringType: + if b == "": + b = [] + else: + b = b.split('','') + result = {} + for x in a: + result[x] = 1 + for x in b: + result[x] = 1 + result = result.keys() + result.sort() + return result + class DB: """Access to the security database. @@ -98,7 +122,8 @@ cursor.execute("""CREATE TABLE inodeprints (file TEXT NOT NULL PRIMARY KEY, - inodeprint TEXT NOT NULL)""") + inodeprint TEXT NOT NULL, + parsed BLOB)""") cursor.execute( """CREATE TABLE nicknames @@ -111,23 +136,30 @@ (id INTEGER NOT NULL PRIMARY KEY, version TEXT NOT NULL UNIQUE)""") - cursor.execute("""CREATE TABLE source_packages - (package TEXT NOT NULL, - release TEXT NOT NULL, archive TEXT NOT NULL, - version TEXT NOT NULL, - version_id INTEGER NOT NULL DEFAULT 0, - PRIMARY KEY (package, release, archive));""") + cursor.execute( + """CREATE TABLE source_packages + (name TEXT NOT NULL, + release TEXT NOT NULL, + archive TEXT NOT NULL, + version TEXT NOT NULL, + version_id INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (name, release, archive))""") - cursor.execute("""CREATE TABLE binary_packages - (package TEXT NOT NULL, - release TEXT NOT NULL, archive TEXT NOT NULL, - architecture TEXT NOT NULL, - version TEXT NOT NULL, - version_id INTEGER NOT NULL DEFAULT 0, - source TEXT NOT NULL, source_version TEXT NOT NULL, - PRIMARY KEY (package, release, archive, architecture));""") - cursor.execute("""CREATE INDEX binary_packages_source - ON binary_packages(source)""") + cursor.execute( + """CREATE TABLE binary_packages + (name TEXT NOT NULL, + release TEXT NOT NULL, + archive TEXT NOT NULL, + version TEXT NOT NULL, + source TEXT NOT NULL, + source_version TEXT NOT NULL, + archs TEXT NOT NULL, + version_id INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY (name, release, archive, version, source, + source_version))""") + cursor.execute( + """CREATE INDEX binary_packages_source + ON binary_packages(source)""") cursor.execute("""CREATE TABLE package_notes (id INTEGER NOT NULL PRIMARY KEY, @@ -175,161 +207,189 @@ reason TEXT NOT NULL, PRIMARY KEY (bug_name, release, note))""") - cursor.execute("""CREATE TABLE package_status + cursor.execute("""CREATE TABLE source_package_status (note INTEGER NOT NULL, - release TEXT NOT NULL, - archive TEXT NOT NULL, - architecture TEXT NOT NULL, - vulnerable INTEGER NOT NULL, - bug_name TEXT NOT NULL, - package TEXT NOT NULL, - source TEXT NOT NULL, - PRIMARY KEY (note, release, archive, architecture))""") + package INTEGER NOT NULL, + vulnerable INTEGER NOT NULL, + PRIMARY KEY (note, package))""") cursor.execute( - "CREATE INDEX package_status_bug ON package_status(bug_name)") + """CREATE INDEX source_package_status_package + ON source_package_status(package)""") + + cursor.execute("""CREATE TABLE binary_package_status + (note INTEGER NOT NULL, + package INTEGER NOT NULL, + vulnerable INTEGER NOT NULL, + PRIMARY KEY (note, package))""") cursor.execute( - "CREATE INDEX package_status_package ON package_status(package)") - cursor.execute( - "CREATE INDEX package_status_source ON package_status(source)") + """CREATE INDEX binary_package_status_package + ON binary_package_status(package)""") - def updateSources(self, cursor, release, archive, packages): - """Reads a Sources file and adds it to the database. + self.commit(cursor) - Old records for the same release/archive pair are removed. + def filePrint(self, filename): + """Returns a fingerprint string for filename.""" - cursor - cursor used to update the database - release - Debian release (e.g. sarge) - archive - fork of a release (e.g. security) - packages - debian_support.PackageFile object with source packages - """ - - cursor.execute(''DELETE FROM source_packages '' - + ''WHERE release = ? AND archive = ?'', - (release, archive)) + st = os.stat(filename) + # The "1" is a version number which can be used to trigger a + # re-read if the code has changed in an incompatible way. + return `(st.st_size, st.st_ino, st.st_mtime, 1)` - for pkg in packages: - pkg_name = None - pkg_version = None - for (name, contents) in pkg: - if name == "Package": - pkg_name = contents - elif name == "Version": - pkg_version = debian_support.Version(contents) - if pkg_name is None: - raise SyntaxError\ - ("package record does not contain package name") - if pkg_version is None: - raise SyntaxError\ - ("package record for %s does not contain version" - % pkg_name) - cursor.execute(''INSERT INTO source_packages '' - + ''(package, release, archive, version) '' - + ''VALUES (?, ?, ?, ?)'', - (pkg_name, release, archive, str(pkg_version))) + def _parseFile(self, cursor, filename): + current_print = self.filePrint(filename) - def updatePackages(self, cursor, - release, archive, architecture, - packages): - """Reads a Packages file and adds it to the database. + def do_parse(packages): + if self.verbose: + print " parseFile: reading " + `filename` - Old records for the same release/archive/architecture - triple are removed. + re_source = re.compile\ + (r''^([a-zA-Z0-9.+-]+)(?:\s+\(([a-zA-Z0-9.+:-]+)\))?$'') - cursor - cursor used to update the database - release - Debian release (e.g. sarge) - archive - fork of a release (e.g. security) - architecture - architecture of binary packages (e.g. i386) - packages - debian_support.PackageFile object with binary packages - """ + data = [] + for pkg in packages: + pkg_name = None + pkg_version = None + pkg_source = None + pkg_source_version = None + for (name, contents) in pkg: + if name == "Package": + pkg_name = contents + elif name == "Version": + pkg_version = contents + elif name == "Source": + match = re_source.match(contents) + if match is None: + raise SyntaxError((''package %s references '' + + ''invalid source package %s'') % + (pkg_name, `contents`)) + (pkg_source, pkg_source_version) = match.groups() + if pkg_name is None: + raise SyntaxError\ + ("package record does not contain package name") + if pkg_version is None: + raise SyntaxError\ + ("package record for %s does not contain version" + % pkg_name) + data.append((pkg_name, pkg_version, + pkg_source, pkg_source_version)) - re_source = re.compile\ - (r''^([a-zA-Z0-9.+-]+)(?:\s+\(([a-zA-Z0-9.+:-]+)\))?$'') + return data - cursor.execute(''DELETE FROM binary_packages '' - + ''WHERE release = ? AND archive = ? AND architecture = ?'', - (release, archive, architecture)) + def toString(data): + result = cStringIO.StringIO() + cPickle.dump(data, result) + return result.getvalue() + + for (old_print, contents) in cursor.execute( + "SELECT inodeprint, parsed FROM inodeprints WHERE file = ?", + (filename,)): + if old_print == current_print: + return cPickle.load(cStringIO.StringIO(contents)) + result = do_parse(debian_support.PackageFile(filename)) + cursor.execute("""UPDATE inodeprints SET inodeprint = ?, parsed = ? + WHERE file = ?""", (current_print, toString(result), filename)) + return result + # No inodeprints entry, load file and add one. + result = do_parse(debian_support.PackageFile(filename)) + cursor.execute("""INSERT INTO inodeprints (file, inodeprint, parsed) + VALUES (?, ?, ?)""", (filename, current_print, toString(result))) + return result - for pkg in packages: - pkg_name = None - pkg_version = None - pkg_source = None - pkg_source_version = None - for (name, contents) in pkg: - if name == "Package": - pkg_name = contents - elif name == "Version": - pkg_version = debian_support.Version(contents) - elif name == "Source": - match = re_source.match(contents) - if match is None: - raise SyntaxError((''binary package %s references '' - + ''invalid source package %s'') % - (pkg_name, `contents`)) - (pkg_source, pkg_source_version) = match.groups() + def readPackages(self, cursor, directory): + """Reads a directory of package files.""" - if pkg_name is None: - raise SyntaxError\ - ("binary package record does not contain package name") - if pkg_version is None: - raise SyntaxError\ - ("binary record for %s does not contain version" - % pkg_name) - if pkg_source is None: - pkg_source = pkg_name - if pkg_source_version is None: - pkg_source_version = pkg_version + if self.verbose: + print "readPackages:" + print " deleting old data" + cursor.execute("DELETE FROM source_packages") + cursor.execute("DELETE FROM binary_packages") - cursor.execute(''INSERT INTO binary_packages '' - + ''(package, release, archive, architecture,'' - + ''version, source, source_version) '' - + ''VALUES (?, ?, ?, ?, ?, ?, ?)'', - (pkg_name, release, archive, architecture, - str(pkg_version), - pkg_source, str(pkg_source_version))) + self._readSourcePackages(cursor, directory) + self._readBinaryPackages(cursor, directory) - def filePrint(self, filename): - """Returns a fingerprint string for filename.""" + if self.verbose: + print " finished" + + def _readSourcePackages(self, cursor, directory): + """Reads from directory with source package files.""" - st = os.stat(filename) - # The "1" is a version number which can be used to trigger a - # re-read if the code has changed in an incompatible way. - return `(st.st_size, st.st_ino, st.st_mtime, 1)` + re_sources = re.compile(r''.*/([a-z-]+)_([a-z-]+)_Sources$'') - def _maybeUpdate(self, cursor, args, filename, action): - """Internal routine used for conditional update.""" + + if self.verbose: + print " reading source packages" + + for filename in glob.glob(directory + ''/*_Sources''): + match = re_sources.match(filename) + if match is None: + raise ValueError, "invalid file name: " + `filename` + + (release, archive) = match.groups() + parsed = self._parseFile(cursor, filename) + + def gen(): + for (name, version, source, source_version) in parsed: + assert source is None + assert source_version is None + yield name, release, archive, version + cursor.executemany( + """INSERT INTO source_packages + (name, release, archive, version) VALUES (?, ?, ?, ?)""", + gen()) - current_print = self.filePrint(filename) + def _readBinaryPackages(self, cursor, directory): + """Reads from a directory with binary package files.""" - for (old_print,) in cursor.execute\ - ("SELECT inodeprint FROM inodeprints WHERE file = ?", (filename,)): - if old_print == current_print: - return - if self.verbose: - print "maybeUpdate: updating", `args` - result = apply(action, (cursor,) + args - + (debian_support.PackageFile(filename),)) - cursor.execute("""UPDATE inodeprints SET inodeprint = ? - WHERE file = ?""", (current_print, filename)) - return result + re_packages \ + = re.compile(r''.*/([a-z-]+)_([a-z-]+)_([a-z0-9]+)_Packages$'') + + if self.verbose: + print " reading binary packages" - # No inodeprints entry, load file and add one. - result = apply(action, (cursor,) + args - + (debian_support.PackageFile(filename),)) - cursor.execute("""INSERT INTO inodeprints (file, inodeprint) - VALUES (?, ?)""", (filename, current_print)) - return result + packages = {} + for filename in glob.glob(directory + ''/*_Packages''): + match = re_packages.match(filename) + if match is None: + raise ValueError, "invalid file name: " + `filename` - def maybeUpdateSources(self, cursor, release, archive, filename): - """Reads the Sources file filename if it has been modified.""" - self._maybeUpdate(cursor, (release, archive), filename, - self.updateSources) + (release, archive, architecture) = match.groups() + parsed = self._parseFile(cursor, filename) + for (name, version, source, source_version) in parsed: + if source is None: + source = name + if source_version is None: + source_version = version + + key = (name, release, archive, version, source, source_version) + if packages.has_key(key): + packages[key][architecture] = 1 + else: + packages[key] = {architecture : 1} - def maybeUpdatePackages(self, cursor, release, archive, arch, filename): - """Reads the Packages file filename if it has been modified.""" - self._maybeUpdate(cursor, (release, archive, arch), filename, - self.updatePackages) + l = packages.keys() + if len(l) == 0: + raise ValueError, "no binary packages found" + + l.sort() + def gen(): + for key in l: + archs = packages[key].keys() + archs.sort() + archs = '',''.join(archs) + yield key + (archs,) + + if self.verbose: + print " storing binary package data" + + cursor.executemany( + """INSERT INTO binary_packages + (name, release, archive, version, + source, source_version, archs) + VALUES (?, ?, ?, ?, ?, ?, ?)""", + gen()) + def deleteBugs(self, cursor): """Deletes all record bug reports from the database.""" cursor.execute("DELETE FROM package_notes") @@ -420,27 +480,27 @@ return warnings def availableReleases(self, cursor=None): - """Returns a list of tuples (RELEASE, ARCHIVE, ARCHITECTURE-LIST).""" + """Returns a list of tuples (RELEASE, ARCHIVE, + SOURCES-PRESENT, ARCHITECTURE-LIST).""" if cursor is None: cursor = self.cursor() releases = {} for r in cursor.execute( "SELECT DISTINCT release, archive FROM source_packages"): - releases[r] = [''(sources)''] + releases[r] = (True, []) - for (rel, archive, arch) in cursor.execute( - """SELECT DISTINCT release, archive, architecture + for (rel, archive, archs) in cursor.execute( + """SELECT DISTINCT release, archive, archs FROM binary_packages"""): - try: - releases[(rel, archive)].append(arch) - except KeyError: - releases[(rel, archive)] = [arch] + key = (rel, archive) + if not releases.has_key(key): + releases[key] = (False, []) + releases[key][1][:] = mergeLists(releases[key][1], archs) result = [] - for ((rel, archive), archs) in releases.items(): - archs.sort() - result.append((rel, archive, archs)) + for ((rel, archive), (sources, archs)) in releases.items(): + result.append((rel, archive, sources, archs)) result.sort() return result @@ -496,12 +556,10 @@ WHERE fixed_version IS NOT NULL UNION ALL SELECT version FROM source_packages UNION ALL SELECT version FROM binary_packages)"""): - if v is None: - continue versions.append(debian_support.Version(v)) if self.verbose: - print " calculating linear oder" + print " calculating linear order" versions.sort() if self.verbose: @@ -561,19 +619,20 @@ print " source packages" cursor.execute( """INSERT INTO source_packages - SELECT package, ?, archive, '''', MAX(version_id) AS vid + SELECT name, ?, archive, '''', MAX(version_id) AS vid FROM source_packages WHERE release IN (?, ?) - GROUP BY package, archive""", + GROUP BY name, archive""", (nickname, realname, realname + ''-security'')) if self.verbose: print " binary packages" cursor.execute( - """INSERT INTO binary_packages - SELECT DISTINCT package, ?, archive, architecture, '''', - MAX (version_id) AS vid, source, source_version + """INSERT INTO binary_packages + SELECT DISTINCT name, ?, archive, + MAX (version_id) AS vid, source, source_version, + '''' FROM binary_packages WHERE release IN (?, ?) - GROUP BY package, archive, architecture""", + GROUP BY name, archive, archs""", (nickname, realname, realname + ''-security'')) if self.verbose: @@ -607,7 +666,7 @@ result = [] self._updateVersions(cursor) - self._synthesizeReleases(cursor) + # self._synthesizeReleases(cursor) if self.verbose: print "calculateVulnerabilities:" @@ -649,7 +708,8 @@ if self.verbose: print " remove old status" - cursor.execute("DELETE FROM package_status") + cursor.execute("DELETE FROM source_package_status") + cursor.execute("DELETE FROM binary_package_status") if self.verbose: print " calculate package status" print " source packages (unqualified)" @@ -660,56 +720,61 @@ # tmp_bug_releases table. cursor.execute( - """INSERT INTO package_status - SELECT n.id, p.release, p.archive, '''' AS architecture, - p.version_id < n.fixed_version_id, - n.bug_name, p.package, p.package AS source + """INSERT INTO source_package_status + SELECT n.id, p.rowid, + p.version_id < n.fixed_version_id FROM package_notes AS n, source_packages AS p - WHERE n.release = '''' AND p.package = n.package + WHERE n.release = '''' AND p.name = n.package AND NOT EXISTS (SELECT * FROM tmp_bug_releases AS t WHERE t.bug_name = n.bug_name - AND t.release = n.release)""") + AND t.release = p.release)""") if self.verbose: print " source packages (qualified)" cursor.execute( - """INSERT INTO package_status - SELECT n.id, p.release, p.archive, '''' AS architecture, - p.version_id < n.fixed_version_id, - n.bug_name, p.package, p.package AS source + """INSERT INTO source_package_status + SELECT n.id, p.rowid, + p.version_id < n.fixed_version_id FROM package_notes AS n, source_packages AS p - WHERE p.package = n.package + WHERE p.name = n.package AND (p.release = n.release - OR p.release = n.release || ''-security'' + OR p.release = (n.release || ''-security'') OR p.release = (SELECT nickname FROM nicknames WHERE realname = n.release))""") - # Same story for binary packages. + # Same story for binary packages. We prefer source packages, + # so we skip all notes which have already source packages + # attached. if self.verbose: - print " binary packages" + print " binary packages (unqualified)" cursor.execute( - """INSERT INTO package_status - SELECT n.id, p.release, p.archive, p.architecture, - p.version_id < n.fixed_version_id AS fixed, - n.bug_name, p.package, p.source + """INSERT INTO binary_package_status + SELECT n.id, p.rowid, + p.version_id < n.fixed_version_id FROM package_notes AS n, binary_packages AS p - WHERE n.release = '''' AND p.package = n.package - AND NOT EXISTS (SELECT * FROM tmp_bug_releases AS t + WHERE n.release = '''' AND p.name = n.package + AND (NOT EXISTS (SELECT * FROM tmp_bug_releases AS t WHERE t.bug_name = n.bug_name - AND t.release = n.release)""") + AND t.release = p.release)) + AND (NOT EXISTS (SELECT * FROM source_package_status AS s + WHERE s.package = p.rowid))""") + if self.verbose: print " binary packages (qualified)" cursor.execute( - """INSERT INTO package_status - SELECT n.id, p.release, p.archive, p.architecture AS architecture, - p.version_id < n.fixed_version_id, - n.bug_name, p.package, p.package AS source + """INSERT INTO binary_package_status + SELECT n.id, p.rowid, + p.version_id < n.fixed_version_id FROM package_notes AS n, binary_packages AS p - WHERE p.package = n.package + WHERE p.name = n.package AND (p.release = n.release OR p.release = n.release || ''-security'' OR p.release = (SELECT nickname FROM nicknames - WHERE realname = n.release))""") + WHERE realname = n.release)) + AND (NOT EXISTS (SELECT * FROM source_package_status AS s + WHERE s.package = p.rowid))""") + + return if self.verbose: @@ -864,31 +929,20 @@ print " architecture:", architecture def test(): + assert mergeLists('''', '''') == [], mergeLists('''', '''') + assert mergeLists('''', []) == [] + assert mergeLists(''a'', ''a'') == [''a''] + assert mergeLists(''a'', ''b'') == [''a'', ''b''] + assert mergeLists(''a,c'', ''b'') == [''a'', ''b'', ''c''] + assert mergeLists(''a,c'', [''b'', ''de'']) == [''a'', ''b'', ''c'', ''de''] + import os - if os.path.exists(''test_security.db''): os.unlink(''test_security.db'') db = DB(''test_security.db'') db.initSchema() - data_prefix = ''../../data/packages/'' cursor = db.writeTxn() - db.updateSources(cursor, ''sarge'', ''main'', - debian_support.PackageFile(data_prefix + ''sarge_main_Sources'')) - db.updatePackages(cursor, ''sarge'', ''main'', ''i386'', - debian_support.PackageFile(data_prefix - + ''sarge_main_i386_Packages'')) - db.updatePackages(cursor, ''sarge'', ''main'', ''ia64'', - debian_support.PackageFile(data_prefix - + ''sarge_main_ia64_Packages'')) - db.commit(cursor) - - assert str(db.getVersion(cursor, ''sarge'', ''ale'')) == ''0.7.1-1'', \ - db.getVersion(cursor, ''sarge'', ''ale'') - - # db.check(cursor) - - cursor = db.writeTxn() db.deleteBugs(cursor) db.insertBugs(cursor, bugs.CVEFile(''../../data/CAN/list'')) db.insertBugs(cursor, bugs.CVEFile(''../../data/CVE/list'',