Beispiel #1
0
    def test_SortedQuery_do_not_optimize_ancients(self, monkeypatch):
        from blm import testblm

        oid1 = ObjectId()
        toi1 = self.ctx.createToi(blm.testblm.Test, oid1, {'name': ['foobar']})
        oid2 = ObjectId()
        toi2 = self.ctx.createToi(blm.testblm.Test, oid2, {'name': ['gazonk']})
        oid3 = ObjectId()
        toi3 = self.ctx.createToi(blm.testblm.Test, oid3, {'name': ['zonka']})
        self.sync()

        query = blm.testblm.Test._query(name=Query.Like('foo*'))

        link = Link.LinkSortedQuery(
            self.clientId, self.linkId, {
                'criteria': query,
                'attrList': ['name'],
                'subscription': True,
                'sorting': 'name'
            })
        link.run()
        r = self._getResult()
        assert list(r['toiDiffs'].keys()) == [str(oid1)]  # sanity

        self.ctx._query_cache.clear()  # xxx we didn't need to do this in py2
        self.ctx.changeToi(toi2, {'name': ['foooo']})
        mongo.update_one(self.database.links, {
            'client': self.clientId,
            'link': self.linkId
        }, {
            '$set': {
                'outdatedBy': ObjectId(),
                'outdatedToids': [],
                'ancient': True
            }
        })
        self.sync()

        link = Link.LinkFactory().create(None, self.clientId, self.linkId)

        runQuery = self.ctx.runQuery
        queries = []

        def _runQuery(query):
            queries.append(query)
            return runQuery(query)

        monkeypatch.setattr(self.ctx, 'runQuery', _runQuery)
        link.run()
        r = self._getResult()
        assert r['diffops'] == [[1, 1, [toi2]]]
        assert r['toiDiffs'][str(oid2)].diffAttrs == {'name': ['foooo']}

        assert queries == [query]  # whitebox
Beispiel #2
0
 def outdate(self, toids=[]):
     mongo.update_one(self.database.links, {
         'client': self.clientId,
         'link': self.linkId
     }, {
         '$set': {
             'outdatedBy': ObjectId()
         },
         '$addToSet': {
             'outdatedToids': {
                 '$each': toids
             }
         }
     })
     self.sync()
Beispiel #3
0
 def _runQuery(query):
     queries.append(query)
     result = list(runQuery(query))
     mongo.update_one(self.database.links, {
         'client': self.clientId,
         'link': self.linkId
     }, {
         '$set': {
             'outdatedBy': cid2
         },
         '$addToSet': {
             'outdatedToids': oid1
         }
     })
     return result
Beispiel #4
0
    def test_SortedQuery_rerun_optimization_on_id(self, monkeypatch):
        from blm import testblm

        oid1 = ObjectId()
        toi1 = self.ctx.createToi(blm.testblm.Test, oid1, {'name': ['foobar']})
        self.sync()

        query = blm.testblm.Test._query(id=Query.In([str(oid1)]))

        link = Link.LinkSortedQuery(
            self.clientId, self.linkId, {
                'criteria': query,
                'attrList': ['name'],
                'subscription': True,
                'sorting': 'name'
            })
        link.run()
        r = self._getResult()
        assert list(r['toiDiffs'].keys()) == [str(oid1)]  # sanity

        self.ctx.changeToi(toi1, {'name': ['foooo']})
        mongo.update_one(self.database.links, {
            'client': self.clientId,
            'link': self.linkId
        }, {'$set': {
            'outdatedBy': ObjectId(),
            'outdatedToids': [oid1]
        }})
        self.sync()

        link = Link.LinkFactory().create(None, self.clientId, self.linkId)

        runQuery = self.ctx.runQuery
        queries = []

        def _runQuery(query):
            queries.append(query)
            return runQuery(query)

        monkeypatch.setattr(self.ctx, 'runQuery', _runQuery)
        link.run()
        r = self._getResult()
        assert r['diffops'] == []
        assert r['toiDiffs'][str(oid1)].diffAttrs == {'name': ['foooo']}

        assert queries == [blm.testblm.Test._query(id=[oid1])]  # whitebox
Beispiel #5
0
    def test_SortedQuery_fulltext_update(self):
        py.test.skip('full text index disabled for now')
        from blm import testblm
        with commit.CommitContext(self.database, user=self.user) as ctx:
            ctx.setMayChange(True)
            oid1 = ObjectId()
            toi1 = ctx.createToi(blm.testblm.Test, oid1, {'name': ['foo']})
            ctx.runCommit([])

        self.sync()

        query = blm.testblm.Test._query(id=Query.Fulltext('bar'))

        link = Link.LinkSortedQuery(
            self.clientId, self.linkId, {
                'criteria': query,
                'attrList': ['name'],
                'subscription': True,
                'sorting': 'name'
            })
        link.run()
        self.sync()
        x = self._getResult()
        assert x['diffops'] == []
        toi1, = blm.testblm.Test._query(id=oid1).run()
        with commit.CommitContext(self.database) as ctx:
            ctx.setMayChange(True)
            ctx.changeToi(toi1, {'name': ['foo bar']})
            ctx.runCommit([])
        mongo.update_one(self.database.links, {
            'client': self.clientId,
            'link': self.linkId
        }, {'$set': {
            'outdatedBy': ObjectId(),
            'outdatedToids': [oid1]
        }})
        self.sync()

        link = Link.LinkFactory().create(None, self.clientId, self.linkId)
        link.run()
        self.sync()
        x = self._getResult()
        assert x['diffops'] == [[0, 0, [toi1]]]
Beispiel #6
0
    def update(self, data, persistent=False, updatelink=lambda x: None):
        if data is not None:
            update = {'type': 'update',
                      'id': self.linkId,
                      'args': data }
            document = {'$push': {'updates': update}}
            log.debug('Updating %s: %r', self, update)
            mongo.update_one(self.database.clients, {'_id': self.clientId},
                             document)

        if persistent:
            outdatedBy = self.link.get('outdatedBy', None)
            spec = {'client': self.clientId,
                    'link': self.linkId,
                    'outdatedBy': outdatedBy}
            doc = {'$set': {'outdatedBy': None,
                            'timestamp': time.time(),
                            'ancient': False}}
            updatelink(doc)
            mongo.update_one(self.database.links, spec, doc)
Beispiel #7
0
    def save(self, params, state):
        log.debug('Saving %s: %r', self, state)

        user = self.context.user
        if user:
            allowRead = [toi.id[0] for toi in user._privileges]
        else:
            allowRead = []

        spec = {'_id': self.link['_id'],
                'client': self.clientId,
                'link': self.linkId}
        document = {'$set':{'params': params,
                            'state': state,
                            'allowRead': allowRead,
                            'type': self.__class__.__name__,
                            'timestamp': time.time(),
                            'ancient': False
                            }
                    }

        mongo.update_one(self.database.links, spec, document, upsert=True)
        self._link = Link._link
Beispiel #8
0
    def test_persistent_db_update(self, monkeypatch):
        # create an existing link
        link = self.factory.create('Persistent',
                                   self.clientId,
                                   self.linkId,
                                   params=dict(toid='27', attrs=['foo',
                                                                 'bar']))
        link.run()
        mongo.update_one(self.database.clients, {'_id': self.clientId},
                         {'$set': {
                             'updates': []
                         }})
        self.sync()

        # no new data, but uptodate should be set
        monkeypatch.setattr(LinkPersistent, 'result', None)
        link = self.factory.create('Persistent', self.clientId, self.linkId)
        link.run()
        self.sync()

        clientdata = mongo.find_one(self.database.clients,
                                    {'_id': self.clientId})
        assert clientdata['updates'] == []
        linkdata = mongo.find_one(self.database.links, {
            'client': self.clientId,
            'link': self.linkId
        })
        assert linkdata['outdatedBy'] == None
        monkeypatch.undo()

        monkeypatch.setattr(LinkPersistent, 'state', {'sallad': 'paprika'})

        # now update it
        link = self.factory.create('Persistent', self.clientId, self.linkId)
        link.run()
        self.sync()
        assert link._state == {'gurka': 'tomat'}

        linkdata, = list(
            self.database.links.find({
                'client': self.clientId,
                'link': self.linkId
            }))
        clientdata, = list(self.database.clients.find({'_id': self.clientId}))

        linkdata.pop('_id')  # don't care
        assert linkdata == {
            'type': 'LinkPersistent',
            'client': self.clientId,
            'link': self.linkId,
            'state': {
                'sallad': 'paprika'
            },
            'outdatedBy': None,
            'allowRead': [self.user.id[0]],
            'timestamp': self.time,
            'ancient': False,
            # same params as first time:
            'params': dict(toid='27', attrs=['foo', 'bar'])
        }

        assert clientdata['updates'] == [{
            'type': 'update',
            'id': self.linkId,
            'args': {
                'foo': 'bar'
            }
        }]
Beispiel #9
0
    def test_SortedQuery_timing_error(self, monkeypatch):
        # this test is nearly identical to
        # test_SortedQuery_rerun_optimization but sneakily modifies
        # the link's uptodate state while the link is running
        #
        # (it is possible that this is now a strict superset of
        # test_SortedQuery_rerun_optimization and if so we might want
        #  to consider merging them)
        from blm import testblm

        oid1 = ObjectId()
        toi1 = self.ctx.createToi(blm.testblm.Test, oid1, {'name': ['foobar']})
        oid2 = ObjectId()
        toi2 = self.ctx.createToi(blm.testblm.Test, oid2, {'name': ['gazonk']})
        self.sync()

        query = blm.testblm.Test._query(name=Query.Like('foo*'))

        link = Link.LinkSortedQuery(
            self.clientId, self.linkId, {
                'criteria': query,
                'attrList': ['name'],
                'subscription': True,
                'sorting': 'name'
            })
        link.run()
        r = self._getResult()
        assert list(r['toiDiffs'].keys()) == [str(oid1)]  # sanity

        cid1 = ObjectId()
        self.ctx.changeToi(toi2, {'name': ['foooo']})
        mongo.update_one(self.database.links, {
            'client': self.clientId,
            'link': self.linkId
        }, {'$set': {
            'outdatedBy': cid1,
            'outdatedToids': [oid2]
        }})
        self.sync()

        link = Link.LinkFactory().create(None, self.clientId, self.linkId)

        runQuery = self.ctx.runQuery
        queries = []
        cid2 = ObjectId()

        def _runQuery(query):
            queries.append(query)
            result = list(runQuery(query))
            mongo.update_one(self.database.links, {
                'client': self.clientId,
                'link': self.linkId
            }, {
                '$set': {
                    'outdatedBy': cid2
                },
                '$addToSet': {
                    'outdatedToids': oid1
                }
            })
            return result

        monkeypatch.setattr(self.ctx, 'runQuery', _runQuery)
        link.run()
        r = self._getResult()
        assert r['diffops'] == [[1, 1, [toi2]]]
        assert r['toiDiffs'][str(oid2)].diffAttrs == {'name': ['foooo']}

        assert queries == [blm.testblm.Test._query(id=[oid2])]  # whitebox

        self.sync()

        assert not self.uptodate()
        assert self._getLinkData()['outdatedBy'] == cid2
        assert set(self._getLinkData()['outdatedToids']) == {oid1, oid2}

        monkeypatch.undo()

        link = Link.LinkFactory().create(None, self.clientId, self.linkId)
        link.run()
        self.sync()
        assert self.uptodate()
        assert self._getLinkData()['outdatedBy'] == None
        assert self._getLinkData()['outdatedToids'] == []