Esempio n. 1
0
    def testNextVersionMultipleBranchesWithDepth2(self):
        self.addCollection('foo=/localhost@rpl:1//2//3/2:1-2-0.1', [':run'])

        repos = self.openRepository()
        sourceList = [(VFS('/localhost@rpl:2//3/1-2'), ['foo'], deps.Flavor())]
        nextVersions = nextversion.nextVersions(repos, self.openDatabase(),
                                                sourceList)
        assert(nextVersions == [VFS('/localhost@rpl:2//3/1-2-0.2')])
Esempio n. 2
0
 def testNextVersionLatestDevelOnThisBranch(self):
     # depth 3
     self.addCollection('foo=/localhost@rpl:1//2//3/1:1-2-0.0.1', [':run'])
     # depth 2 and latest
     self.addCollection('foo=/localhost@rpl:1//3/2:1-2-0.1[is:x86]', 
                        [':run'])
     sourceList = [(VFS('/localhost@rpl:1//3/1-2'), ['foo'], deps.Flavor())]
     nextVersions = nextversion.nextVersions(self.openRepository(),
                                             self.openDatabase(), sourceList)
     assert(nextVersions == [VFS('/localhost@rpl:1//3/1-2-0.1')])
Esempio n. 3
0
    def testNextVersionMultipleBranchesWithDepth(self):
        # this has depth 3, but the trove we're building has depth 2.
        # so we can't consider it the "latest" and just increment its source
        # count.
        self.addCollection('foo=/localhost@rpl:1//2//3/2:1-2-0.0.1', [':run'])

        repos = self.openRepository()
        sourceList = [(VFS('/localhost@rpl:2//3/1-2'), ['foo'], deps.Flavor())]
        nextVersions = nextversion.nextVersions(repos, self.openDatabase(),
                                                sourceList)
        assert(nextVersions == [VFS('/localhost@rpl:2//3/1-2-0.1')])
Esempio n. 4
0
 def testNextVersions(self):
     trv = self.addComponent('foo:source', '1')
     self.addComponent('foo:run', '1')
     self.addCollection('foo', '1', [':run'])
     localVersion = VFS('/local@local:COOK/1.0-1')
     sourceList = [(trv.getVersion(), ['foo'], deps.Flavor()),
                   (localVersion, ['bar'], deps.Flavor())]
     repos = self.openRepository()
     nextVersions = nextversion.nextVersions(repos, self.openDatabase(),
                                             sourceList)
     assert(nextVersions == [VFS('/localhost@rpl:linux/1-1-2'),
                             VFS('/local@local:COOK/1.0-1-1')])
Esempio n. 5
0
    def testLoadInstalledInRoot(self):
        # make sure that we find this autoconf213 trove even though it's
        # been built.  (RMK-371)
        self.openRepository()
        repos = self.openRmakeRepository()

        sourceV = VFS('/localhost@rpl:1//autoconf213/2.13-1.1')
        binV = sourceV.createShadow(versions.Label('rmakehost@rpl:1'))
        binV.incrementBuildCount()

        loadInstalledRecipe = fixtures.loadInstalledRecipe.replace(
                                "loadInstalled('loaded')",
                                "loadInstalled('loaded=:autoconf213')")
        self.addComponent('loaded:runtime', str(binV))
        trv = self.addCollection('loaded', str(binV), [':runtime'])
        self.updatePkg('loaded=rmakehost@rpl:1')
        self.addComponent('loaded:source', str(sourceV),
                          [('loaded.recipe',
                            fixtures.loadedRecipe.replace('@@', '2.13'))])
        trv = self.addComponent('loadinstalled:source', '1',
                          [('loadinstalled.recipe', loadInstalledRecipe)])
        n,v,f = trv.getNameVersionFlavor()

        db = self.openDatabase()
        source = recipeutil.RemoveHostSource(db, 'rmakehost')
        (loader, recipeClass, localFlags, usedFlags) = \
            recipeutil.loadRecipeClass(repos, n, v, f,
                                       ignoreInstalled=False, 
                                       root=self.cfg.root,
                                       loadInstalledSource=source)
        assert(recipeClass.loadedVersion == '2.13')
Esempio n. 6
0
    def testAffinity(self):
        self.addComponent('foo:r', '/localhost@rpl:branch/1.0-1-1',
                          '!readline', ['/usr/bin/foo'])
        self.addComponent('foo:r', '/localhost@rpl:branch/2.0-1-1',
                          'readline,~!ssl', ['/usr/bin/foo'])
        self.addComponent('foo:r', '/localhost@rpl:branch/2.0-1-1',
                          'readline,~ssl', ['/usr/bin/foo'])
        self.addComponent('foo:r', '/localhost@rpl:branch/2.0-1-1',
                          '!readline,~ssl', ['/usr/bin/foo'])
        self.addComponent('foo:r', '/localhost@rpl:branch/2.0-1-1',
                          '!readline,~!ssl', ['/usr/bin/foo'])

        # orig branch - found by very few queries
        self.addComponent('foo:r', '/localhost@rpl:linux/1.0-1-1', 'readline')
        self.updatePkg('foo:r=:branch/1.0[!readline]')

        repos = self.openRepository()

        def _get(affinityDb, versionFilter, flavorFilter, troveSpec):
            return queryrep.getTrovesToDisplay(repos, troveSpec, [], [],
                                               versionFilter, flavorFilter,
                                               self.cfg.installLabelPath,
                                               self.cfg.flavor, affinityDb)

        db = self.openDatabase()
        troveTups = _get(db, VERSION_FILTER_LATEST, FLAVOR_FILTER_BEST,
                         ['foo:r'])
        assert (len(troveTups) == 1)
        assert (troveTups[0][1].branch() == VFS('/localhost@rpl:branch'))
        assert (str(troveTups[0][2]) == '!readline,~ssl')

        troveTups = _get(db, VERSION_FILTER_LATEST, FLAVOR_FILTER_AVAIL,
                         ['foo:r'])

        assert (len(troveTups) == 2)
        flavors = set(str(x[2]) for x in troveTups)
        assert ('readline,~ssl' in flavors)
        assert ('!readline,~ssl' in flavors)

        # system compatible, should ignore db
        troveTups = _get(None, VERSION_FILTER_LATEST, FLAVOR_FILTER_AVAIL,
                         ['foo:r'])

        assert (len(troveTups) == 1)
        assert (troveTups[0][1].branch() == VFS('/localhost@rpl:linux'))
        flavors = set(str(x[2]) for x in troveTups)
        assert ('readline' in flavors)
Esempio n. 7
0
    def testShadowBinaryGroup(self):

        basicSplitGroup = """
class splitGroup(GroupRecipe):
    name = 'group-first'
    version = '1.0'
    checkPathConflicts = False
    clearBuildRequires()
    def setup(self):
        self.addTrove("testcase", ":linux", byDefault=False)
        self.createGroup('group-second')
        self.addTrove("testcase", ":test1",
                      groupName = 'group-second')
        # add group-second to group-first
        self.addNewGroup('group-second')
"""
        repos = self.openRepository()

        (built, d) = self.buildRecipe(recipes.testRecipe1, "TestRecipe1")
        origBuildLabel = self.cfg.buildLabel
        self.cfg.buildLabel = Label('localhost@rpl:test1')
        (built, d) = self.buildRecipe(recipes.testRecipe1, "TestRecipe1")
        self.cfg.buildLabel = origBuildLabel
        (built, d) = self.buildRecipe(basicSplitGroup, "splitGroup")
        n, v, f = [x for x in built if x[0] == 'group-first'][0]
        v = VFS(v)
        shadowVerStr = '/localhost@rpl:linux//shadow/1.0-1-1'
        shadowVer = VFS(shadowVerStr)
        flavor = use.Arch.getCurrentArch()._toDependency()
        group = repos.getTrove(n, v, f)
        self.verifyTroves(
            group, [('testcase', '/localhost@rpl:linux/1.0-1-1', flavor),
                    ('group-second', '/localhost@rpl:linux/1.0-1-1', flavor)])
        self.mkbranch("1.0-1-1",
                      'localhost@rpl:shadow',
                      "group-first",
                      shadow=True,
                      binaryOnly=True)
        group = repos.getTrove('group-first', shadowVer, flavor)
        assert (not group.includeTroveByDefault('testcase', shadowVer, flavor))
        self.verifyTroves(group, [('testcase', shadowVerStr, flavor),
                                  ('group-second', shadowVerStr, flavor)])
        group = repos.getTrove('group-second', shadowVer, flavor)
        self.verifyTroves(
            group,
            [('testcase', '/localhost@rpl:test1//shadow/1.0-1-1', flavor)])
Esempio n. 8
0
    def testLoadRecipeUsingInternalRepos(self):
        self.openRepository()
        repos = self.openRmakeRepository()

        upstreamV = VFS('/localhost@rpl:1/1.0-1')
        sourceV = VFS('/localhost@rpl:1//rmakehost@rpl:1/1.0-1')

        self.addComponent('loaded:source', str(sourceV),
                          [('loaded.recipe', 
                            fixtures.loadedRecipe.replace('@@', '1.0'))])
        self.addComponent('loaded:source', str(upstreamV).replace('1.0', '2.0'),
                          [('loaded.recipe', 
                            fixtures.loadedRecipe.replace('@@', '2.0'))])
        trv = self.addComponent('load:source', str(sourceV),
                          [('load.recipe', fixtures.loadRecipe)])
        job = self.newJob(trv)
        results = recipeutil.getSourceTrovesFromJob(job, repos=repos)
        self.assertEqual(results.values()[0].packages,
            set(['load', 'loaded-2.0']))
Esempio n. 9
0
 def testChecksumMissingError(self):
     try:
         raise errors.TroveChecksumMissing('foo',
                                           VFS('/localhost@rpl:1/1.0-1-1'),
                                           deps.parseFlavor('~!foo'))
     except Exception, err:
         assert (
             str(err) ==
             'Checksum Missing Error: Trove foo=/localhost@rpl:1/1.0-1-1[~!foo] has no sha1 checksum calculated, so it was rejected.  Please upgrade conary.'
         )
Esempio n. 10
0
 def testIntegrityError(self):
     try:
         raise errors.TroveIntegrityError('foo',
                                          VFS('/localhost@rpl:1/1.0-1-1'),
                                          deps.parseFlavor('~!foo'))
     except Exception, err:
         assert (
             str(err) ==
             'Trove Integrity Error: foo=/localhost@rpl:1/1.0-1-1[~!foo] checksum does not match precalculated value'
         )
Esempio n. 11
0
 def testTroveSchemaError(self):
     try:
         raise errors.TroveSchemaError('foo',
                                       VFS('/localhost@rpl:1/1.0-1-1'),
                                       deps.parseFlavor('~!foo'), 10, 5)
     except Exception, err:
         assert (
             str(err) ==
             'Trove Schema Error: attempted to commit foo=/localhost@rpl:1/1.0-1-1[~!foo] with version 10, but repository only supports 5'
         )
Esempio n. 12
0
    def testJobTupFormatter(self):
        # CNY-1742
        repos = self.openRepository()
        db = self.openDatabase()
        dcfg = display.JobDisplayConfig(repos, db)
        formatter = display.JobTupFormatter(dcfg)
        v1 = VFS('/localhost@rpl:devel/1.0-1-1')
        v2 = VFS('/localhost@rpl:devel/1.0-1-2')
        f = Flavor('')
        jobs = [('foo', (None, None), (v1, f), False),
                ('foo', (None, None), (v2, f), False)]
        formatter.prepareJobs(jobs)
        result = ''.join(x for x in formatter.formatJobTups(jobs))
        self.assertEqual(result, 'Install foo=1.0-1-1Install foo=1.0-1-2')

        formatter = display.JobFormatter(dcfg)
        (rc, txt) = self.captureOutput(display.displayJobs, dcfg, formatter,
                                       jobs)
        self.assertEqual(txt, 'Install foo=1.0-1-1\nInstall foo=1.0-1-2\n')
Esempio n. 13
0
 def testGetProductStoreByLabel(self):
     from rbuild_plugins import init
     co = init.Init('init', None, None)
     co.setHandle(mock.MockObject())
     returnTuple = ('product-definition:source', 
                    VFS('/foo.rpath.org@rpl:proddef-1/1.0-1'), deps.Flavor())
     co.handle.facade.conary._findTrove._mock.setReturn(returnTuple,
                 'product-definition:source',
                 'foo.rpath.org@rpl:proddef-1')
     assert(co.getProductVersionByLabel('foo.rpath.org@rpl:proddef-1') 
             == '/foo.rpath.org@rpl:proddef-1/1.0-1')
Esempio n. 14
0
 def testPromoteGroups(self):
     _, facade = self.prep()
     client = mock.MockObject()
     mock.mockMethod(facade._getConaryClient, client)
     success = True
     cs = mock.MockObject()
     groupList = [('group-dist', '/localhost@rpl:devel/1.0-1-1', '')],
     trv = mock.MockObject()
     trv.getNewNameVersionFlavor._mock.setReturn(
         ('group-dist', VFS('/localhost@rpl:qa/1.0-1-1'), ''))
     cs.iterNewTroveList()._mock.setList([trv])
     client.createSiblingCloneChangeSet._mock.setReturn(
         (success, cs), {
             Label('localhost@rpl:devel'): Label('localhost@rpl:qa'),
             Label('other@somewhere:else'): Label('localhost@rpl:qa'),
             Label('yetanother@somewhere:else'): VFS('/localhost@rpl:qa')
         },
         groupList,
         cloneSources=True)
     mock.mockMethod(facade._getRepositoryClient)
     repos = facade._getRepositoryClient()
     rc = facade.promoteGroups(
         groupList, {
             'localhost@rpl:devel': 'localhost@rpl:qa',
             'other@somewhere:else': facade._getLabel('localhost@rpl:qa'),
             'yetanother@somewhere:else': '/localhost@rpl:qa'
         })  # RBLD-91
     assert (rc == [('group-dist', '/localhost@rpl:qa/1.0-1-1', '')])
     repos.commitChangeSet._mock.assertCalled(cs)
     # failureCase
     success = False
     client.createSiblingCloneChangeSet._mock.setReturn(
         (success, None),
         {Label('localhost@rpl:devel'): Label('localhost@rpl:qa')},
         groupList,
         cloneSources=True)
     err = self.assertRaises(errors.RbuildError, facade.promoteGroups,
                             groupList,
                             {'localhost@rpl:devel': 'localhost@rpl:qa'})
     assert (str(err) == 'Promote failed.')
Esempio n. 15
0
 def testFindTroves(self):
     _, facade = self.prep()
     repos = MockRepositoryClient()
     mock.mockMethod(facade._getRepositoryClient, repos)
     results = facade._findTroves([('foo', None, None)],
                                  ['localhost@rpl:1', 'localhost@rpl:2'])
     assert (results == {
         ('foo', None, None):
         [('foo', VFS('/localhost@rpl:1/1.0-1-1'), Flavor(''))]
     })
     results = facade._findTrovesFlattened(
         [('foo', None, None)], ['localhost@rpl:1', 'localhost@rpl:2'])
     assert (results == [('foo', VFS('/localhost@rpl:1/1.0-1-1'),
                          Flavor(''))])
     results = facade._findTroves(['foo[ssl]'], 'localhost@rpl:1')
     assert (results == {
         ('foo[ssl]'):
         [('foo', VFS('/localhost@rpl:1/1.0-1-1'), Flavor('ssl'))]
     })
     results = facade._findTrovesFlattened(['foo[ssl]'], 'localhost@rpl:1')
     assert (results == [('foo', VFS('/localhost@rpl:1/1.0-1-1'),
                          Flavor('ssl'))])
Esempio n. 16
0
 def _checkLatest(self, trove, verType, ver):
     repos = self.openRepository()
     if verType[0] == '/':
         verDict = repos.getTroveLeavesByBranch(
             {trove: {
                 VFS(verType): None
             }})
     else:
         verDict = repos.getTroveLeavesByLabel(
             {trove: {
                 Label(verType): None
             }})
     assert (len(verDict) == 1)
     assert (verDict[trove].keys()[0].asString() == ver)
Esempio n. 17
0
    def testFindTroves(self):
        self.repos = self.openRepository()
        self.setUpGroupOddities()
        ts = TroveListTroveSource(
            self.repos, [('group-foo', VFS('/localhost@rpl:linux/1.0-1-1'),
                          deps.parseFlavor('readline is: x86_64'))])
        assert (len(ts.trovesByName('test4-on-branch')) == 1)
        assert (len(ts.trovesByName('test4-on-branch:runtime')) == 1)
        assert (len(ts.findTrove(None, ('test4-on-branch', None, None))) == 1)

        ts.searchAsDatabase()
        assert (len(
            ts.findTrove(
                None,
                ('test4-on-branch', '/localhost@rpl:branch1', None))) == 1)
Esempio n. 18
0
    def testFlavorDisplayed(self):
        repos = self.openRepository()
        db = self.openDatabase()

        foobar = Flavor('~foo,~bar')
        nofoobar = Flavor('~!foo,~!bar')
        v1 = VFS('/localhost@rpl:devel/1.0-1-1')

        dcfg = display.DisplayConfig(repos, db)
        dcfg.setTroveDisplay(baseFlavors=[Flavor('~foo')])
        formatter = display.TroveTupFormatter(dcfg)
        formatter.prepareTuples([('foo', v1, foobar), ('foo', v1, nofoobar)])

        vStr, flv = formatter.getTupleStrings('foo', v1, foobar)
        assert (str(flv) == '~bar,~foo')

        vStr, flv = formatter.getTupleStrings('foo', v1, nofoobar)
        assert (str(flv) == '~!bar,~!foo')
Esempio n. 19
0
    def testPathIdLookupPermissions(self):
        # CNY-1911
        label2 = Label('localhost2@rpl:devel')
        label1 = Label('localhost1@rpl:devel')
        shadowLabel = Label('localhost@rpl:shadow')

        self.openRepository(0)
        self.openRepository(1)
        # Remove anonymous user
        repos = self.openRepository(2)
        repos.deleteUserByName(label2.asString(), "anonymous")

        # Add a file that disappears
        recipe1 = simpleRecipe + "        r.Create('/usr/blip', contents='abc\\n')\n"
        self.makeSourceTrove('test', recipe1, buildLabel=label2)
        built = self.cookFromRepository('test', buildLabel=label2)

        # Extra file goes away
        self.updateSourceTrove('test',
                               simpleRecipe,
                               versionStr=label2.asString())
        built = self.cookFromRepository('test', buildLabel=label2)

        self.assertEqual(built[0][1], '/localhost2@rpl:devel/1.0-2-1')

        # Now shadow
        self.mkbranch(['test:source=' + label2.asString()],
                      label1,
                      shadow=True)

        # Noop change
        newRecipe = simpleRecipe.replace("mode=0755",
                                         "contents='foobar\\n', mode=0755")
        self.updateSourceTrove('test', newRecipe, versionStr=label1.asString())
        # And build in the repo
        built = self.cookFromRepository('test', buildLabel=label1)
        self.assertEqual(
            built[0][1],
            '/localhost2@rpl:devel//localhost1@rpl:devel/1.0-2.1-1')

        # Now shadow again
        self.mkbranch(['test:source=' + label1.asString()],
                      shadowLabel,
                      shadow=True)

        # Add the original file back
        self.updateSourceTrove('test',
                               recipe1,
                               versionStr=shadowLabel.asString())

        # Reset users, client-side
        self.cfg.user.addServerGlob('localhost2', ('test', 'wrongpass'))

        client = conaryclient.ConaryClient(self.cfg)
        repos = client.getRepos()

        # And build in the repo
        built = self.cookFromRepository('test',
                                        buildLabel=shadowLabel,
                                        repos=repos)
        self.assertEqual(
            built[0][1],
            '/localhost2@rpl:devel//localhost1@rpl:devel//localhost@rpl:shadow/1.0-2.1.1-1'
        )

        trvList = repos.getTroves([(x[0], VFS(x[1]), x[2]) for x in built])
        trv = trvList[0]
        # Iterate over all files
        for _, _, _, vr in trv.iterFileList():
            # Make sure the file version is the same as the trove version. If
            # the originating repo didn't reject the request (and the client
            # didn't ignore the reject), then we'd see the file version be on
            # the /localhost2 branch.
            self.assertEqual(vr.asString(), built[0][1])
Esempio n. 20
0
            assert (
                str(err) ==
                'Trove Schema Error: attempted to commit foo=/localhost@rpl:1/1.0-1-1[~!foo] with version 100000, but repository only supports %s'
                % trove.TROVE_VERSION)
        else:
            assert (0)

        t.troveInfo.troveVersion.set(trove.TROVE_VERSION)
        t.computeDigests()
        cs = changeset.ChangeSet()
        cs.newTrove(t.diff(None)[0])
        # let's make sure that there are no other problems with this
        # changeset
        repos.commitChangeSet(cs)

        # access the server with a bad name
        repos.c.map['badserver'] = repos.c.map.values()[0]
        try:
            repos.createChangeSet([('foo', (None, None),
                                    (VFS('/badserver@rpl:devel/1.0-1-1'),
                                     deps.parseFlavor('')), 0)])
        except:
            pass
        # FIXME: Proxies report error differently from direct connections to
        # the server, and it's hard to fix :-(
        #except errors.RepositoryMismatch, err:
        #    assert(str(err) ==
        #           'Repository name mismatch.  The correct repository name '
        #           'is "localhost", but it was accessed as "badserver".  Check for '
        #           'incorrect repositoryMap configuration entries.')
Esempio n. 21
0
    def _testMerge(self, shadow, switchUsers=False):
        def _assertExists(repos, ver):
            repos.findTrove(None, ('testcase:source', ver, None))

        def checkMetadata(ver, shortDesc):
            md = self.findAndGetTrove('testcase:source=%s' % ver).getMetadata()
            self.assertEquals(md['shortDesc'], shortDesc)

        def updateMetadata(ver, shortDesc):
            repos = self.openRepository()
            mi = self.createMetadataItem(shortDesc=shortDesc)
            trv = repos.findTrove(self.cfg.buildLabel,
                                  ('testcase:source', ver, None))[0]
            repos.addMetadataItems([(trv, mi)])

        def verifyCONARY(ver, verMap, lastMerged=None):
            conaryState = ConaryStateFromFile("CONARY", None)
            sourceState = conaryState.getSourceState()
            assert (sourceState.getVersion().asString() == ver)

            if lastMerged:
                assert (sourceState.getLastMerged().asString() == lastMerged)
            else:
                assert (sourceState.getLastMerged() is None)

            for pathId, path, fileId, version in sourceState.iterFileList():
                foo = verMap.pop(path)
                assert (version.asString() == foo)

            # there should be no paths remaining in the vermap
            assert (not verMap)

        repos = self.openRepository()
        shadowPrefix = self._shadowPrefix(shadow)
        parentPrefix = '/%s/' % (self.cfg.buildLabel.asString())

        self.resetWork()
        os.chdir(self.workDir)
        self.newpkg("testcase")
        os.chdir("testcase")
        # 1.0-1
        self.writeFile("testcase.recipe", recipes.testTransientRecipe1)
        self.writeFile('notChangedOnShadow', 'hello, world\n')
        self.writeFile('removedOnShadow', 'goodbye, world\n')
        self.writeFile('converging', '1\n2\n3\n4\n')
        self.addfile("testcase.recipe")
        self.addfile("notChangedOnShadow", text=True)
        self.addfile("removedOnShadow", text=True)
        self.addfile("converging", text=True)
        self.commit()
        updateMetadata('1.0', 'foo')

        self.mkbranch("1.0-1", shadow, "testcase:source", shadow=True)
        self._checkLatest('testcase:source', shadow, shadowPrefix + '1.0-1')

        # metadata should have transfered with the shadow
        checkMetadata(shadow, 'foo')

        # do shadow operations as the daemon user, so there is always
        if switchUsers:
            origstat = os.stat
            origlstat = os.lstat
            otheruser = StatWrapper(origstat, origlstat, 1, 1)

        # 1.0-1.1
        if switchUsers:
            os.stat = otheruser.stat
            os.lstat = otheruser.lstat
        os.chdir("..")
        shutil.rmtree("testcase")
        self.checkout("testcase", shadow)
        os.chdir("testcase")
        f = open("testcase.recipe", "a")
        f.write("\n# extra comment\n")
        f.close()
        self.writeFile('addedOnShadow', 'hello, world\n')
        self.writeFile('converging', '1\n2\n3\n4\n5\n')
        self.addfile('addedOnShadow', text=True)
        self.remove('removedOnShadow')
        self.commit()

        # 1.1 (upstream change)
        if switchUsers:
            os.stat = origstat
            os.lstat = origlstat
        os.chdir("..")
        shutil.rmtree("testcase")
        self.checkout("testcase")
        os.chdir("testcase")
        self.writeFile("testcase.recipe", recipes.testTransientRecipe2)
        self.writeFile('notChangedOnShadow', 'hello 2\n')
        self.writeFile('removedOnShadow', 'changed\n')
        self.writeFile('converging', '1\n2\n3\n4\n5\n')
        self.commit()
        checkMetadata('1.1', 'foo')
        updateMetadata('1.1', 'upstream change')

        # 1.1-1.1 (merge)
        if switchUsers:
            os.stat = otheruser.stat
            os.lstat = otheruser.lstat
        os.chdir("..")
        shutil.rmtree("testcase")
        self.checkout("testcase", shadow)
        os.chdir("testcase")
        self.merge()
        assert (not os.path.exists('removedOnShadow'))
        # make sure that all the versions are correct
        verifyCONARY(shadowPrefix + '1.0-1.1', {
            'testcase.recipe': parentPrefix + '1.1-1',
            'notChangedOnShadow': parentPrefix + '1.1-1',
            'addedOnShadow': shadowPrefix + '1.0-1.1',
            'converging': parentPrefix + '1.1-1'
        },
                     lastMerged=parentPrefix + '1.1-1')
        self.commit()
        # the merge doesn't override the metadata, metadata doesn't get
        # transferred via merge.
        checkMetadata(shadow, 'foo')
        # after the commit, the source count should be 1.1
        verifyCONARY(
            shadowPrefix + '1.1-1.1',
            {
                'testcase.recipe': shadowPrefix + '1.1-1.1',
                # XXX it would be nice if this was reset to be from
                # the parent instead of a change on the shadow
                'notChangedOnShadow': shadowPrefix + '1.1-1.1',
                'addedOnShadow': shadowPrefix + '1.0-1.1',
                'converging': parentPrefix + '1.1-1'
            })
        self._checkLatest('testcase:source', shadow, shadowPrefix + '1.1-1.1')

        # make sure the intermediate version appears shadowed
        assert (repos.hasTrove('testcase:source', VFS(shadowPrefix + '1.1-1'),
                               deps.Flavor()))

        # check out the latest version on the shadow
        os.chdir("..")
        shutil.rmtree("testcase")
        self.checkout("testcase", shadow)
        os.chdir('testcase')
        verifyCONARY(
            shadowPrefix + '1.1-1.1',
            {
                'testcase.recipe': shadowPrefix + '1.1-1.1',
                # XXX it would be nice if this was reset to be from
                # the parent instead of a change on the shadow
                'notChangedOnShadow': shadowPrefix + '1.1-1.1',
                'addedOnShadow': shadowPrefix + '1.0-1.1',
                'converging': parentPrefix + '1.1-1'
            })

        # change shadowed version to 1.1-1.2
        recipeText = open('testcase.recipe', 'r').read()
        newText = recipeText + '\n#comment bottom\n'
        self.writeFile("testcase.recipe", newText)
        self.commit()
        verifyCONARY(
            shadowPrefix + '1.1-1.2', {
                'testcase.recipe': shadowPrefix + '1.1-1.2',
                'notChangedOnShadow': shadowPrefix + '1.1-1.1',
                'addedOnShadow': shadowPrefix + '1.0-1.1',
                'converging': parentPrefix + '1.1-1'
            })

        # change shadowed version to 2.0-0.1
        newText = recipeText.replace("version = '1.1'", "version = '2.0'")

        self.writeFile("testcase.recipe", newText)
        self.commit()
        verifyCONARY(
            shadowPrefix + '2.0-0.1', {
                'testcase.recipe': shadowPrefix + '2.0-0.1',
                'notChangedOnShadow': shadowPrefix + '1.1-1.1',
                'addedOnShadow': shadowPrefix + '1.0-1.1',
                'converging': parentPrefix + '1.1-1'
            })

        # make two minor revisions upstream to get 1.1-3
        if switchUsers:
            os.stat = origstat
            os.lstat = origlstat
        os.chdir("..")
        shutil.rmtree("testcase")
        self.checkout("testcase")
        os.chdir("testcase")

        newText = open('testcase.recipe', 'r').read() + '\n#minor comment\n'
        self.writeFile("testcase.recipe", newText)
        self.commit()

        newText = '\n#minor comment \n' + newText
        self.writeFile("testcase.recipe", newText)
        self.commit()

        # merge to get 2.0-0.2
        if switchUsers:
            os.stat = otheruser.stat
            os.lstat = otheruser.lstat
        os.chdir("..")
        shutil.rmtree("testcase")
        self.checkout("testcase", shadow)

        os.chdir("testcase")
        verifyCONARY(shadowPrefix + '2.0-0.1', {
            'testcase.recipe': shadowPrefix + '2.0-0.1',
            'notChangedOnShadow': shadowPrefix + '1.1-1.1',
            'addedOnShadow': shadowPrefix + '1.0-1.1',
            'converging': parentPrefix + '1.1-1'
        },
                     lastMerged=None)

        self.merge()
        assert (not os.path.exists('removedOnShadow'))
        # make sure that all the versions are correct
        verifyCONARY(shadowPrefix + '2.0-0.1', {
            'testcase.recipe': parentPrefix + '1.1-3',
            'notChangedOnShadow': shadowPrefix + '1.1-1.1',
            'addedOnShadow': shadowPrefix + '1.0-1.1',
            'converging': parentPrefix + '1.1-1'
        },
                     lastMerged=parentPrefix + '1.1-3')
        self.commit()
        # after the commit, the source count should be 2.0-0.2
        verifyCONARY(
            shadowPrefix + '2.0-0.2', {
                'testcase.recipe': shadowPrefix + '2.0-0.2',
                'notChangedOnShadow': shadowPrefix + '1.1-1.1',
                'addedOnShadow': shadowPrefix + '1.0-1.1',
                'converging': parentPrefix + '1.1-1'
            })
        self._checkLatest('testcase:source', shadow, shadowPrefix + '2.0-0.2')
        assert (not repos.hasTrove('testcase:source',
                                   VFS(shadowPrefix + '1.1-2'), deps.Flavor()))
        assert (repos.hasTrove('testcase:source', VFS(shadowPrefix + '1.1-3'),
                               deps.Flavor()))

        if switchUsers:
            os.stat = origstat
            os.lstat = origlstat
Esempio n. 22
0
    def testShadowSourceDisappears(self):
        # CNY-462
        class CustomError(Exception):
            errorIsUncatchable = True

        class MFCheckinCallbackFailure(CheckinCallback):
            def missingFiles(self, files):
                raise CustomError(files)

        class MFCheckinCallbackFailure2(CheckinCallback):
            def missingFiles(self, files):
                return False

        class MFCheckinCallbackSuccess(CheckinCallback):
            def missingFiles(self, files):
                return True

        shadow = 'localhost1@rpl:shadow'
        shadowPrefix = self._shadowPrefix(shadow)

        self.openRepository(0)
        self.resetRepository(1)
        repos1 = self.openRepository(1)

        self.resetWork()
        os.chdir(self.workDir)
        self.newpkg("testcase")
        os.chdir("testcase")
        # the origional version, 1.0-1
        self.writeFile("testcase.recipe", recipes.testTransientRecipe1)
        self.addfile("testcase.recipe")
        self.commit()

        # create a shadow of 1.0-1
        self.mkbranch("1.0-1", shadow, "testcase:source", shadow=True)
        self._checkLatest('testcase:source', shadow, shadowPrefix + '1.0-1')

        self.resetWork()
        os.chdir(self.workDir)
        # Source goes away
        self.stopRepository(0)

        # This should be in a different test case: repository is not even
        # available
        self.openRepository(0)

        callbackF = MFCheckinCallbackFailure()
        callbackF2 = MFCheckinCallbackFailure2()
        callbackS = MFCheckinCallbackSuccess()

        os.chdir(self.workDir)
        # This should fail period. (no callback)
        self.assertRaises(repository.errors.FileStreamMissing,
                          self.checkout,
                          "testcase",
                          versionStr=shadow)
        # This call will fail because the callback throws an exception
        self.assertRaises(CustomError,
                          self.checkout,
                          "testcase",
                          versionStr=shadow,
                          callback=callbackF)
        # This call will fail because the callback returns False
        self.assertRaises(repository.errors.FileStreamMissing,
                          self.checkout,
                          "testcase",
                          versionStr=shadow,
                          callback=callbackF2)

        self.stopRepository(0)
        # This should fail period. (no callback)
        self.assertRaises(repository.errors.OpenError,
                          self.checkout,
                          "testcase",
                          versionStr=shadow)

        # In passing, test CNY-1415 (missing files while writing a changeset to
        # a file)
        jobList = [
            ('testcase:source', (None, None), (VFS(shadowPrefix + '1.0-1'),
                                               deps.parseFlavor('')), True),
        ]

        csfile = os.path.join(self.workDir, "changeset-file.ccs")
        # fix up the proxy cfg
        repos1 = self.openRepository(1)
        repos1.createChangeSetFile(jobList, csfile, callback=callbackS)
        cs = repository.changeset.ChangeSetFromFile(csfile)
        self.assertEqual(['testcase:source'],
                         [t.getName() for t in cs.iterNewTroveList()])

        # This call succeeds
        self.checkout("testcase", versionStr=shadow, callback=callbackS)

        # Test the callback
        shutil.rmtree('testcase')

        c = cvccmd.CvcMain()
        cmd = c._supportedCommands['checkout']

        expOutput = """\
Warning: The following files are missing:
testcase.recipe
"""

        (ret,
         strng) = self.captureOutput(c.runCommand, cmd, self.cfg, {},
                                     ['cvc', 'checkout', 'testcase=' + shadow])
        self.assertEqual(strng, expOutput)

        os.chdir("testcase")

        dest = "localhost2@rpl:shadow"
        open("testcase.recipe", "w+").write(simpleRedirectRecipe % dest)
        self.addfile("testcase.recipe")
        self.commit(callback=callbackS)

        os.chdir(self.workDir)
        shutil.rmtree('testcase')