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
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()
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
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
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]]]
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)
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
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' } }]
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'] == []