def testFileObjMissing(self): # create an absolute changeset cs = changeset.ChangeSet() # add a pkg diff flavor = deps.deps.parseFlavor('') v = versions.VersionFromString('/%s/1.0-1-1' %self.cfg.buildLabel.asString()).copy() v.resetTimeStamps() t = trove.Trove('test:test', v, flavor, None) path = self.workDir + '/blah' f = open(path, 'w') f.write('hello, world!\n') f.close() pathId = sha1helper.md5String('/blah') f = files.FileFromFilesystem(path, pathId) # add the file, and SKIP including # the filestream by using cs.addFile(). This creates an # incomplete changeset t.addFile(pathId, '/blah', v, f.fileId()) cs.addFileContents(pathId, f.fileId(), changeset.ChangedFileTypes.file, filecontents.FromFilesystem(path), f.flags.isConfig()) t.computeDigests() diff = t.diff(None, absolute = 1)[0] cs.newTrove(diff) repos = self.openRepository() try: repos.commitChangeSet(cs) assert 0, "Did not raise IntegrityError" except errors.IntegrityError, e: assert(str(e).startswith("Incomplete changeset specified: missing pathId e806729b6a2b568fa7e77c3efa3a9684 fileId"))
def testVersion11Migration(self): dbfile = os.path.join(resources.get_archive(), 'conarydbs', 'conarydb-version-11') fd, fn = tempfile.mkstemp() os.close(fd) shutil.copyfile(dbfile, fn) db, str = self.captureOutput(sqldb.Database, fn) cu = db.db.cursor() # make sure there aren't any install buckets left cu.execute("select count(*) from troveinfo where infoType=?", trove._TROVEINFO_TAG_INSTALLBUCKET) assert (cu.next()[0] == 0) # make sure the path hashs look right for libpng:lib cu.execute( "select data from troveinfo, instances where " "trovename='libpng:lib' and " "troveinfo.instanceid=instances.instanceid " "and infoType=?", trove._TROVEINFO_TAG_PATH_HASHES) ph = trove.PathHashes(cu.next()[0]) cu.execute("select path from instances, dbtrovefiles where " "instances.instanceid=dbtrovefiles.instanceid " "and troveName='libpng:lib'") for path, in cu: hash = md5String(path)[:8] assert (hash in ph) ph.remove(hash) assert (not ph) db.close() os.unlink(fn)
def testFileContentsMissing(self): # currently causes a 500 error #raise testhelp.SkipTestException # create an absolute changeset cs = changeset.ChangeSet() # add a pkg diff flavor = deps.deps.parseFlavor('') v = versions.VersionFromString('/%s/1.0-1-1' %self.cfg.buildLabel.asString()).copy() v.resetTimeStamps() t = trove.Trove('test:test', v, flavor, None) path = self.workDir + '/blah' f = open(path, 'w') f.write('hello, world!\n') f.close() pathId = sha1helper.md5String('/blah') f = files.FileFromFilesystem(path, pathId) # add the file, but munge the fileid fileId = f.fileId() cs.addFile(None, fileId, f.freeze()) t.addFile(pathId, '/blah', v, fileId) # skip adding the file contents t.computeDigests() diff = t.diff(None, absolute = 1)[0] cs.newTrove(diff) repos = self.openRepository() try: repos.commitChangeSet(cs) assert 0, "Did not raise integrity error" except errors.IntegrityError, e: assert(str(e).startswith("Missing file contents for pathId e806729b6a2b568fa7e77c3efa3a9684, fileId"))
def testFileIdWrong(self): # create an absolute changeset cs = changeset.ChangeSet() # add a pkg diff flavor = deps.deps.parseFlavor('') v = versions.VersionFromString('/%s/1.0-1-1' %self.cfg.buildLabel.asString()).copy() v.resetTimeStamps() t = trove.Trove('test:test', v, flavor, None) path = self.workDir + '/blah' f = open(path, 'w') f.write('hello, world!\n') f.close() pathId = sha1helper.md5String('/blah') f = files.FileFromFilesystem(path, pathId) # add the file, but munge the fileid brokenFileId = ''.join(reversed(f.fileId())) cs.addFile(None, brokenFileId, f.freeze()) t.addFile(pathId, '/blah', v, brokenFileId) t.computeDigests() diff = t.diff(None, absolute = 1)[0] cs.newTrove(diff) repos = self.openRepository() try: repos.commitChangeSet(cs) assert 0, "Integrity Error not raised" except errors.TroveIntegrityError, e: assert(str(e) == 'fileObj.fileId() != fileId in changeset for ' 'pathId %s' % sha1helper.md5ToString(pathId))
def testVersion11Migration(self): dbfile = os.path.join(resources.get_archive(), 'conarydbs', 'conarydb-version-11') fd, fn = tempfile.mkstemp() os.close(fd) shutil.copyfile(dbfile, fn) db, str = self.captureOutput(sqldb.Database, fn) cu = db.db.cursor() # make sure there aren't any install buckets left cu.execute("select count(*) from troveinfo where infoType=?", trove._TROVEINFO_TAG_INSTALLBUCKET) assert(cu.next()[0] == 0) # make sure the path hashs look right for libpng:lib cu.execute("select data from troveinfo, instances where " "trovename='libpng:lib' and " "troveinfo.instanceid=instances.instanceid " "and infoType=?", trove._TROVEINFO_TAG_PATH_HASHES) ph = trove.PathHashes(cu.next()[0]) cu.execute("select path from instances, dbtrovefiles where " "instances.instanceid=dbtrovefiles.instanceid " "and troveName='libpng:lib'") for path, in cu: hash = md5String(path)[:8] assert(hash in ph) ph.remove(hash) assert(not ph) db.close() os.unlink(fn)
def _getCacheFilename(self, name, version, flavor, compNames): # hash the version and flavor to give a unique filename versionFlavor = '%s %s' % (version.asString(), flavor.freeze()) if compNames: # we could be generating a different set of troves, # say, :runtime only instead of :runtime + :devel, so add # in the components we're creating versionFlavor += ' %s' % ' '.join(compNames) h = sha1helper.md5ToString(sha1helper.md5String(versionFlavor)) return '%s-%s.ccs' %(name, h)
def _addFile(self, cs, trv, path): pathId = sha1helper.md5String(path) absPath = self.cfg.root + path fileObj = files.FileFromFilesystem(absPath, pathId) fileId = fileObj.fileId() trv.addFile(pathId, path, trv.getVersion(), fileId) cs.addFile(None, fileId, fileObj.freeze()) if fileObj.hasContents: cs.addFileContents(pathId, fileId, changeset.ChangedFileTypes.file, filecontents.FromFilesystem(absPath), False)
def testMergedConfigOrder(self): # Make sure that config files from absolute change sets are merged # correctly relative to config files from relative ones. t1 = self.addComponent('test:runtime', '1.0-1-1', fileContents = [ ("/etc/cfg", "contents1\n") ] ) # This filename is magically designed to have it's pathId before # the pathId for /etc/cfg (the pathId in addComponent is a # simple md5 of the path) o = self.addComponent('other:runtime', '1.0-1-1', fileContents = [ ("/etc/one", "something") ] ) repos = self.openRepository() (fd, path) = tempfile.mkstemp() os.close(fd) repos.createChangeSetFile( [ (o.getName(), (None, None), (o.getVersion(), o.getFlavor()), False), (t1.getName(), (None, None), (t1.getVersion(), t1.getFlavor()), True) ], path) f = util.ExtendedFile(path, "r", buffering = False) os.unlink(path) fc = filecontainer.FileContainer(f) # first comes the set of troveCs objects (name, tag, size) = fc.getNextFile() assert(name == 'CONARYCHANGESET') # next is the diff (name, tag, size) = fc.getNextFile() assert(name[0:16] == sha1helper.md5String("/etc/one")) # and then the config file (name, tag, size) = fc.getNextFile() assert(name[0:16] == sha1helper.md5String("/etc/cfg")) # and that's it rc = fc.getNextFile() assert(rc is None)
def testFileUpdateMissingKey(self): fingerprint = '95B457D16843B21EA3FC73BBC7C32FC1F94E405E' # make a changeset with useful stuff that could be installed cs = changeset.ChangeSet() flavor = deps.parseFlavor('') v = versions.VersionFromString('/%s/1.0-1-1' % self.cfg.buildLabel.asString()).copy() v.resetTimeStamps() t = trove.Trove('test:test', v, flavor, None) path = self.workDir + '/blah' f = open(path, 'w') f.write('hello, world!\n') f.close() pathId = sha1helper.md5String('/blah') f = files.FileFromFilesystem(path, pathId) fileId = f.fileId() t.addFile(pathId, '/blah', v, fileId) cs.addFile(None, fileId, f.freeze()) cs.addFileContents(pathId, fileId, changeset.ChangedFileTypes.file, filecontents.FromFilesystem(path), f.flags.isConfig()) diff = t.diff(None, absolute=1)[0] cs.newTrove(diff) cs.addPrimaryTrove('test:test', v, flavor) # sign the changeset csPath = os.path.join(self.workDir, 'test-1.0-1.ccs') cs = cook.signAbsoluteChangeset(cs, fingerprint) cs.writeToFile(csPath) tmpPath = mkdtemp() keyCache = openpgpkey.getKeyCache() newKeyCache = openpgpkey.OpenPGPKeyFileCache() pubRing = self.cfg.pubRing self.cfg.pubRing = [tmpPath + '/pubring.gpg'] keyCacheCallback = openpgpkey.KeyCacheCallback(None, self.cfg) newKeyCache.setCallback(keyCacheCallback) openpgpkey.setKeyCache(newKeyCache) try: self.updatePkg(self.rootDir, csPath) finally: self.cfg.pubRing = pubRing openpgpkey.setKeyCache(keyCache)
def _getFileInfo(self, hostname, troveString, pathHash): repos = self.getRepos() name, version, flavor = self._getTuple(troveString) try: trv = repos.getTrove(name, version, flavor, withFiles=True) except errors.TroveNotFound: raise NotImplementedError pathHash = sha1helper.md5FromString(pathHash) for pathId, path, fileId, fileVersion in trv.iterFileList(): if pathHash == sha1helper.md5String(path): break else: raise NotImplementedError fileObj = repos.getFileVersion(pathId, fileId, fileVersion) return repos, path, fileVersion, fileObj
def get(self, request, hostname, troveString): repos = self.getRepos() name, version, flavor = self._getTuple(troveString) trv = repos.getTrove(name, version, flavor, withFiles=True) fileList = [] for pathId, path, fileId, fileVersion in trv.iterFileList(): pathHash = sha1helper.md5String(path) fileList.append(models.TroveFile( hostname=hostname, pathId=sha1helper.md5ToString(pathId), pathHash=sha1helper.md5ToString(pathHash), path=path, fileId=sha1helper.sha1ToString(fileId), trove=troveString, fileVersion=fileVersion)) troveModel = models.Trove(hostname=hostname, name=name, version=version, flavor=flavor, files=fileList) return troveModel
def checkMd5(self, path, md5): d = md5String(open(self.rootDir + path).read()) self.assertEquals(md5ToString(d), md5)