def testDirectedMessagesCanAlsoBeAcceptedByObjects(self): observable = Observable() called = [] class Y(object): def method(this): called.append("Y") return yield def observable_name(this): return 'name' class Z(object): def method(this): called.append("Z") return yield observable.addObserver(Y()) observable.addObserver(Z()) list(compose(observable.all["name"].method())) self.assertEquals(['Y'], called) del called[:] list(compose(observable.all.method())) self.assertEquals(['Y', "Z"], called) del called[:] list(compose(observable.all["other"].method())) self.assertEquals([], called)
def testUndirectedObserverMessagingIsUnaffectedByObserverName(self): observable = Observable() called = [] class A(Observable): def method(this): called.append(("A", this.observable_name())) return yield class B(Observable): def method(this): called.append(("B", this.observable_name())) return yield observable.addObserver(A("name")) observable.addObserver(A().observable_setName("anothername")) observable.addObserver(B("anothername")) observable.addObserver(B()) list(compose(observable.all.method())) self.assertEquals([("A", "name"), ("A", "anothername"), ("B", "anothername"), ("B", None)], called) del called[:] list(compose(observable.all["name"].method())) self.assertEquals([("A", "name")], called)
def testEnumerate(self): self.assertEqual(set([]), set(self.storageComponent.listIdentifiers())) list( compose( self.storageComponent.add('some:thing:anId-123', 'somePartName', b'data'))) self.assertEqual(set(['some:thing:anId-123']), set(self.storageComponent.listIdentifiers())) list( compose( self.storageComponent.add('some:thing:anId-123', 'anotherPartName', b'data'))) self.assertEqual(set(['some:thing:anId-123']), set(self.storageComponent.listIdentifiers())) list( compose( self.storageComponent.add('some:thing:anId-122', 'anotherPartName', b'data'))) list( compose( self.storageComponent.add('any:thing:anId-123', 'somePartName', b'data'))) self.assertEqual( set([ 'some:thing:anId-123', 'some:thing:anId-122', 'any:thing:anId-123' ]), set(self.storageComponent.listIdentifiers())) self.assertEqual( set(['some:thing:anId-123', 'any:thing:anId-123']), set(self.storageComponent.listIdentifiers('somePartName')))
def testOnceCalledMethodsMustResultInAGeneratorOrComposeOrNone(self): callLog = [] class MyObserver(Observable): def __init__(self): Observable.__init__(self) self.generatorReturningCallable = partial(lambda arg: (x for x in 'a'), arg='partialed') def noGeneratorFunction(self): callLog.append('function called') def valueReturningFunction(self): return 42 def composedGenerator(self): return compose(x for x in 'a') once = MyObserver() dna = \ (Observable(), (once,), ) root = be(dna) list(compose(root.once.noGeneratorFunction())) self.assertEquals(['function called'], callLog) try: list(compose(root.once.valueReturningFunction())) self.fail("Should have gotten AssertionError because of unexpected return value") except AssertionError, e: self.assertEquals("<bound method MyObserver.valueReturningFunction of MyObserver(name=None)> returned '42'", str(e))
def testInvalid(self): invalidXml = '<lom xmlns="http://ltsc.ieee.org/xsd/LOM_this_should_not_work"/>' try: list( compose( self.observable.any.someMethod(parse( StringIO(invalidXml))))) self.fail('must raise exception') except ValidateException: pass self.assertEqual(['logException'], [m.name for m in self.interceptor.calledMethods]) exception = self.interceptor.calledMethods[0].args[0] self.assertTrue( "ERROR:SCHEMASV:SCHEMAV_CVC_ELT_1: Element '{http://ltsc.ieee.org/xsd/LOM_this_should_not_work}lom': No matching global declaration available for the validation root." in str(exception), str(exception)) self.assertTrue("1 %s" % invalidXml in str(exception), str(exception)) self.assertRaises( ValidateException, lambda: list( compose( self.observable.all.someMethod(parse(StringIO(invalidXml))) ))) self.assertRaises( ValidateException, lambda: list( compose( self.observable.do.someMethod(parse(StringIO(invalidXml)))) )) self.assertRaises( ValidateException, lambda: list( compose( self.observable.call.someMethod(parse(StringIO(invalidXml)) ))))
def testAnyOrCallCallsFirstImplementer(self): class A(object): def f(self): raise StopIteration(A.f) yield def f_sync(self): return A.f class B(object): def f(self): raise StopIteration(B.f) yield def f_sync(self): return B.f def g(self): raise StopIteration(B.g) yield def g_sync(self): return B.g root = be((Observable(), (A(), ), (B(), ))) try: compose(root.any.f()).next() self.fail('Should not happen') except StopIteration, e: self.assertEquals((A.f, ), e.args)
def testComposeInCompose(self): def f(): yield 'a' g = compose(f()) c = compose(g) self.assertEquals(['a'], list(c))
def testWithSorting(self): mockData = { 'yearAndMonth': [('2008-01',1),('2008-02',2),('2007-12',11)], 'year': [('2008',13),('2003',10),('2005',9), ('2007', 15)] } drilldown = CallTrace('Drilldown') def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults): levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0] data = mockData[levelField] if levelSorted: data = sorted(data, cmp=lambda (term0, card0), (term1, card1): cmp(card1, card0)) if levelMax > 0: data = data[:levelMax] raise StopIteration(iter([(levelField, iter(data))])) yield drilldown.drilldown = doDrilldown multi = MultiLevelDrilldown({'date':[('yearAndMonth', 2, False), ('year', 3, True)]}) multi.addObserver(drilldown) result = list(compose(multi.multiLevelDrilldown('bitMatrixRow', ['date']))) self.assertEquals([(('date', 'year'), [('2007', 15), ('2008', 13), ('2003', 10)])], result) multi = MultiLevelDrilldown({'date':[('yearAndMonth', 4, False), ('year', 3, False)]}) multi.addObserver(drilldown) result = list(compose(multi.multiLevelDrilldown('bitMatrixRow', ['date']))) self.assertEquals([(('date', 'yearAndMonth'), [('2008-01',1),('2008-02',2),('2007-12',11)])], result)
def testRequestScopeIsPerRequest(self): class MyObserver(Observable): def handleRequest(self, key, value, *args, **kwargs): self.do.setArg(key, value) yield self.call.getArg() class SetArgObserver(Observable): def setArg(self, key, value): self.ctx.requestScope[key] = value class GetArgObserver(Observable): def getArg(self): return ';'.join('%s=%s' % (k,v) for k,v in self.ctx.requestScope.items()) dna = be((Observable(), (RequestScope(), (MyObserver(), (SetArgObserver(),), (GetArgObserver(),) ) ) )) result0 = list(compose(dna.all.handleRequest("key0", "value0"))) result1 = list(compose(dna.all.handleRequest("key1", "value1"))) self.assertEquals(['key0=value0'], result0) self.assertEquals(['key1=value1'], result1)
def testValidXml(self): component = SruParser() sruHandler = SruHandler() component.addObserver(sruHandler) observer = CallTrace('observer') sruHandler.addObserver(observer) response = Response(total=2, hits=[Hit('id0'), Hit('id1')]) def executeQuery(**kwargs): raise StopIteration(response) yield def retrieveData(**kwargs): raise StopIteration('<bike/>') yield observer.methods['executeQuery'] = executeQuery observer.returnValues['echoedExtraRequestData'] = (f for f in []) observer.returnValues['extraResponseData'] = (f for f in []) observer.methods['extraRecordData'] = lambda hit: (f for f in []) observer.methods['retrieveData'] = retrieveData result = ''.join(compose(component.handleRequest(arguments={'version':['1.1'], 'query': ['aQuery'], 'operation':['searchRetrieve']}))) header, body = result.split('\r\n'*2) assertValid(body, join(schemasPath, 'srw-types1.2.xsd')) self.assertTrue('<bike/>' in body, body) result = ''.join(compose(component.handleRequest(arguments={'version':['1.1'], 'operation':['searchRetrieve']}))) header, body = result.split('\r\n'*2) assertValid(body, join(schemasPath, 'srw-types1.2.xsd')) self.assertTrue('diagnostic' in body, body)
def testDeleteRecord(self): rdf = """<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description> <rdf:type>uri:testDelete</rdf:type> </rdf:Description> </rdf:RDF>""" jenaClient = HttpClient(host='localhost', port=self.jenaPort, synchronous=True) list(compose(jenaClient.add('uri:identifier', rdf))) json = self.query('SELECT ?x WHERE {?x ?y "uri:testDelete"}') self.assertEquals(1, len(json['results']['bindings'])) rdfUpdated = """<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description> <rdf:type>uri:testDeleteUpdated</rdf:type> </rdf:Description> </rdf:RDF>""" list(compose(jenaClient.add('uri:identifier', rdfUpdated))) json = self.query('SELECT ?x WHERE {?x ?y "uri:testDelete"}') self.assertEquals(0, len(json['results']['bindings'])) json = self.query('SELECT ?x WHERE {?x ?y "uri:testDeleteUpdated"}') self.assertEquals(1, len(json['results']['bindings'])) list(compose(jenaClient.delete('uri:identifier'))) json = self.query('SELECT ?x WHERE {?x ?y "uri:testDelete"}') self.assertEquals(0, len(json['results']['bindings'])) json = self.query('SELECT ?x WHERE {?x ?y "uri:testDeleteUpdated"}') self.assertEquals(0, len(json['results']['bindings'])) list(compose(jenaClient.add('uri:record', rdf))) json = self.query('SELECT ?x WHERE {?x ?y "uri:testDelete"}') self.assertEquals(1, len(json['results']['bindings']))
def testShouldValidateHashOnUpdate(self): updatePath = '/service/v2/update' hash = serviceUpdateHash(secret='guessme!', identifier='cc635329-c089-41a8-91be-2a4554851515', type='srv', ipAddress='127.0.0.1', infoport=1234) bodyArgs = { 'identifier': 'cc635329-c089-41a8-91be-2a4554851515', 'type': 'srv', 'ipAddress': '127.0.0.1', 'infoport': '1234', 'hash': hash, 'data': dumps({'VERSION': '2.718281828'}), } postBody = urlencode(bodyArgs) result = ''.join(compose(self.dna.all.handleRequest( path=updatePath, Method='POST', arguments={}, Body=postBody, ))) header, body = httpSplit(result) self.assertTrue('HTTP/1.0 200', header) bodyArgs['hash'] = 'wrong' postBody = urlencode(bodyArgs) result = ''.join(compose(self.dna.all.handleRequest( path=updatePath, Method='POST', arguments={}, Body=postBody, ))) header, body = httpSplit(result) self.assertTrue('HTTP/1.0 400', header) self.assertEquals('Hash does not match expected hash.', body)
def testOneTransactionPerGenerator(self): txId = [] class MyTxParticipant(Observable): def doSomething(self): txId.append(self.ctx.tx.getId()) yield 'A' txId.append(self.ctx.tx.getId()) yield 'B' dna = \ (Observable(), (TransactionScope('name'), (MyTxParticipant(),) ) ) body = be(dna) scope1 = compose(body.all.doSomething()) scope2 = compose(body.all.doSomething()) next(scope1) next(scope2) next(scope1) next(scope2) self.assertTrue(txId[0] != txId[1]) self.assertTrue(txId[1] > 0) self.assertTrue(txId[0] > 0) self.assertEqual(txId[0], txId[2]) self.assertEqual(txId[1], txId[3])
def testSameAddFieldGeneratedTwoTimes(self): __callstack_var_tx__ = CallTrace('TX') __callstack_var_tx__.locals = {'id': 'identifier'} intercept = CallTrace(methods={'add': add}) fields2Xml = Fields2Xml('extra') fields2Xml.addObserver(intercept) def f(): f = yield fields2Xml.beginTransaction() yield f f = compose(f()).next() f.addField('key.sub', 'value') f.addField('key.sub', 'othervalue') f.addField('key.sub', 'value') f.addField('key.sub', 'separatedbyvalue') list(compose(f.commit())) self.assertEquals(['add'], [m.name for m in intercept.calledMethods]) self.assertEquals( dict( identifier='identifier', partname='extra', data= '<extra><key><sub>value</sub></key><key><sub>othervalue</sub></key><key><sub>value</sub></key><key><sub>separatedbyvalue</sub></key></extra>' ), intercept.calledMethods[0].kwargs)
def testOnceInternalsNotOnTracebackUnlessAssertsAndThenOnlyOnce(self): class OnceRaiser(object): def raisesOnCall(self): raise BaseException('Boom') def raisesOnCallGenerator(self): raise BaseException('Ka-Boom') yield dna = (Observable(), # called-from (Observable(), # 1 (Observable(), # 2 (Observable(), # 3 (OnceRaiser(),), # target ) ) ) ) root = be(dna) try: list(compose(root.once.raisesOnCallGenerator())) except BaseException: self.assertFunctionsOnTraceback('testOnceInternalsNotOnTracebackUnlessAssertsAndThenOnlyOnce', 'raisesOnCallGenerator') else: self.fail('Should not happen') try: list(compose(root.once.raisesOnCall())) except BaseException: self.assertFunctionsOnTraceback('testOnceInternalsNotOnTracebackUnlessAssertsAndThenOnlyOnce', 'raisesOnCall') else: self.fail('Should not happen')
def testAnyOrCallCallsFirstImplementer(self): class A(object): def f(self): raise StopIteration(A.f) yield def f_sync(self): return A.f class B(object): def f(self): raise StopIteration(B.f) yield def f_sync(self): return B.f def g(self): raise StopIteration(B.g) yield def g_sync(self): return B.g root = be((Observable(), (A(),), (B(),))) try: compose(root.any.f()).next() self.fail('Should not happen') except StopIteration, e: self.assertEquals((A.f,), e.args)
def testShouldConsiderEverythingFineAfterFistPieceOfData(self): # Data only callablesAndYields = ['data'] self.data.extend(callablesAndYields) result = ''.join( compose( self.dna.all.someMessage(arguments={'http': 'arguments'}, Headers={}, path='/some/path', port=0, otherKwargs='kwargs'))) self.assertEqual('data', result) # Callables, Yields and then data callablesAndYields = [Yield, callable, Yield, lambda: None] self.data.extend(callablesAndYields) self.data.append('data') result = list( compose( self.dna.all.someMessage(arguments={'http': 'arguments'}, Headers={}, path='/some/path', port=0, otherKwargs='kwargs'))) initial, remaining = result[:4], result[4:] remaining = ''.join(remaining) self.assertEqual(callablesAndYields, initial) self.assertEqual('data', remaining)
def testOneTransactionPerGenerator(self): txId = [] class MyTxParticipant(Observable): def doSomething(self): txId.append(self.ctx.tx.getId()) yield 'A' txId.append(self.ctx.tx.getId()) yield 'B' dna = \ (Observable(), (TransactionScope('name'), (MyTxParticipant(),) ) ) body = be(dna) scope1 = compose(body.all.doSomething()) scope2 = compose(body.all.doSomething()) scope1.next() scope2.next() scope1.next() scope2.next() self.assertTrue(txId[0] != txId[1]) self.assertTrue(txId[1] > 0) self.assertTrue(txId[0] > 0) self.assertEquals(txId[0], txId[2]) self.assertEquals(txId[1], txId[3])
def testRequestScopeIsPerRequest(self): class MyObserver(Observable): def handleRequest(self, key, value, *args, **kwargs): self.do.setArg(key, value) yield self.call.getArg() class SetArgObserver(Observable): def setArg(self, key, value): self.ctx.requestScope[key] = value class GetArgObserver(Observable): def getArg(self): return ';'.join( '%s=%s' % (k, v) for k, v in list(self.ctx.requestScope.items())) dna = be((Observable(), (RequestScope(), (MyObserver(), (SetArgObserver(), ), (GetArgObserver(), ))))) result0 = list(compose(dna.all.handleRequest("key0", "value0"))) result1 = list(compose(dna.all.handleRequest("key1", "value1"))) self.assertEqual(['key0=value0'], result0) self.assertEqual(['key1=value1'], result1)
def testHandleDifferentUsers(self): authentication = BasicAuthentication(realm='Test Realm') userdata = {'name': 'aUser'} interceptor = CallTrace('httphandler', returnValues={ 'isValidLogin': True, 'getUser': userdata }, methods={'handleRequest': handleRequest}) authentication.addObserver(interceptor) headers = {'Authorization': b'Basic ' + b64encode(b'aUser:aPassword')} response = authentication.handleRequest(port='8080', RequestURI='/private', Method='GET', Headers=headers) list(compose(response)) self.assertEqual({'name': 'aUser'}, interceptor.calledMethods[2].kwargs['user']) headers = { 'Authorization': b'Basic ' + b64encode(b'anotherUser:anotherPassword') } userdata['name'] = 'anotherUser' response = authentication.handleRequest(port='8080', RequestURI='/private', Method='GET', Headers=headers) list(compose(response)) self.assertEqual({'name': 'anotherUser'}, interceptor.calledMethods[5].kwargs['user'])
def testGlob(self): self.assertEqual( set([]), set(self.storageComponent.glob(('some:thing:anId-123', None)))) list( compose( self.storageComponent.add('some:thing:anId-123', 'somePartName', b'data'))) self.assertEqual(set([('some:thing:anId-123', 'somePartName')]), set(self.storageComponent.glob(('so', None)))) self.assertEqual(set([('some:thing:anId-123', 'somePartName')]), set(self.storageComponent.glob(('some', None)))) self.assertEqual(set([('some:thing:anId-123', 'somePartName')]), set(self.storageComponent.glob(('some:thing', None)))) self.assertEqual( set([('some:thing:anId-123', 'somePartName')]), set(self.storageComponent.glob(('some:thing:anId', None)))) list( compose( self.storageComponent.add('some:thing:anId-123', 'anotherPartName', b'data'))) self.assertEqual( set([('some:thing:anId-123', 'anotherPartName'), ('some:thing:anId-123', 'somePartName')]), set(self.storageComponent.glob(('some:thing:anId', None)))) list( compose( self.storageComponent.add('some:thing:anId-124', 'anotherPartName', b'data'))) self.assertEqual( set([('some:thing:anId-123', 'anotherPartName'), ('some:thing:anId-123', 'somePartName')]), set(self.storageComponent.glob(('some:thing:anId-123', None)))) self.assertEqual( set([('some:thing:anId-123', 'somePartName')]), set( self.storageComponent.glob( ('some:thing:anId-123', 'somePartName')))) self.assertEqual( set([('some:thing:anId-123', 'anotherPartName'), ('some:thing:anId-124', 'anotherPartName')]), set( self.storageComponent.glob( ('some:thing:anId', 'anotherPartName')))) list( compose( self.storageComponent.add('some:thing:else-1', 'anotherPartName', b'data'))) self.assertEqual( set([('some:thing:anId-123', 'anotherPartName'), ('some:thing:anId-124', 'anotherPartName')]), set( self.storageComponent.glob( ('some:thing:anId', 'anotherPartName'))))
def testTransparentUnknownImplementationIsVisibleOnTraceback(self): class Leaf(Observable): def aCall(self): raise RuntimeError('trace') def aAny(self): def lookBusy(): raise RuntimeError('trace') return yield ignored = yield lookBusy() def aAll(self): raise RuntimeError('trace') yield 'ignored' def aDo(self): raise RuntimeError('trace') root = be(( Observable(), ( Transparent(), (Leaf(), ), ), )) try: root.call.aCall() self.fail('Should not happen') except RuntimeError: self.assertFunctionsOnTraceback( 'testTransparentUnknownImplementationIsVisibleOnTraceback', 'call_unknown', 'aCall') try: compose(root.any.aAny()).next() self.fail('Should not happen') except RuntimeError: self.assertFunctionsOnTraceback( 'testTransparentUnknownImplementationIsVisibleOnTraceback', 'any_unknown', 'aAny', 'lookBusy') try: compose(root.all.aAll()).next() self.fail('Should not happen') except RuntimeError: self.assertFunctionsOnTraceback( 'testTransparentUnknownImplementationIsVisibleOnTraceback', 'all_unknown', 'aAll') try: root.do.aDo() self.fail('Should not happen') except RuntimeError: self.assertFunctionsOnTraceback( 'testTransparentUnknownImplementationIsVisibleOnTraceback', 'do_unknown', 'aDo')
def gettypeerrormsg(): def compose(initial, arg1=None): pass try: compose() except TypeError, e: return str(e)
def testCollectInComposeObject(self): from sys import getrefcount def f(): gc.collect() yield compose(f()).next()
def testListRecordsWithPartition(self): self._addRecords(['id:1', 'id:2']) header, body = ''.join(compose(self.oaiList.listRecords(arguments={'verb':['ListRecords'], 'metadataPrefix': ['oai_dc'], 'x-partition': ['2/2']}, **self.httpkwargs))).split(CRLF*2) oai = parse(StringIO(body)) self.assertEquals(['id:1/oai_dc'], xpath(oai, '//mock:record/text()')) header, body = ''.join(compose(self.oaiList.listRecords(arguments={'verb':['ListRecords'], 'metadataPrefix': ['oai_dc'], 'x-partition': ['1/2']}, **self.httpkwargs))).split(CRLF*2) oai = parse(StringIO(body)) self.assertEquals(['id:2/oai_dc'], xpath(oai, '//mock:record/text()'))
def testResolveCallStackVariables(self): do_result = [] call_result = [] class StackVarHolder(Observable): def all_unknown(self, message, *args, **kwargs): __callstack_var_myvar__ = [] yield self.all.unknown(message, *args, **kwargs) yield __callstack_var_myvar__ def any_unknown(self, message, *args, **kwargs): __callstack_var_myvar__ = [] yield self.any.unknown(message, *args, **kwargs) raise StopIteration(__callstack_var_myvar__) def call_unknown(self, message, *args, **kwargs): __callstack_var_myvar__ = [] call_result.append(__callstack_var_myvar__) return self.call.unknown(message, *args, **kwargs) def do_unknown(self, message, *args, **kwargs): __callstack_var_myvar__ = [] do_result.append(__callstack_var_myvar__) self.do.unknown(message, *args, **kwargs) class StackVarUser(Observable): def useVariableAll(self): self.ctx.myvar.append('Thingy') yield 'stuffed' def useVariableAny(self): self.ctx.myvar.append('Thingy') return yield def useVariableCall(self): self.ctx.myvar.append('Thingy') return 'called' def useVariableDo(self): self.ctx.myvar.append('Thingy') dna = \ (Observable(), (StackVarHolder(), (Transparent(), (StackVarUser(),) ) ) ) root = be(dna) self.assertEquals(['stuffed', ['Thingy']], list(compose(root.all.useVariableAll()))) composed = compose(root.any.useVariableAny()) try: while True: composed.next() except StopIteration, e: self.assertEquals((['Thingy'],), e.args)
def testCallCompose(self): try: compose() self.fail() except TypeError, e: self.assertTrue( "compose() takes at least 1 argument (0 given)" in str(e) or # (python 2.5/2.6 C-API differences) "Required argument 'initial' (pos 1) not found" in str(e))
def testAnyViaUnknown(self): class A(object): def any_unknown(self, message, *args, **kwargs): raise StopIteration((message, args, kwargs), ) yield root = be((Observable(), (A(),))) try: compose(root.any.f(1, a=2)).next() except StopIteration, e: r = e.args[0] self.assertEquals(('f', (1,), {'a': 2}), r)
def test(suspendMethod): s1 = compose(suspendMethod(clientIdentifier="a-client-id", prefix='prefix', sets=[], continueAfter='9876')).next() s1(CallTrace('reactor'), lambda: None) compose(suspendMethod(clientIdentifier="a-client-id", prefix='prefix', sets=[], continueAfter='9876')).next() try: s1.getResult() self.fail() except ValueError, e: self.assertEquals("Aborting suspended request because of new request for the same OaiClient with identifier: a-client-id.", str(e))
def test(suspendMethod): with stderr_replaced() as s: s1 = compose(suspendMethod(clientIdentifier="a-client-id", prefix='prefix', sets=[], continueAfter='9876')).next() s1(CallTrace('reactor'), lambda: None) compose(suspendMethod(clientIdentifier="another-client-id", prefix='prefix', sets=[], continueAfter='9876')).next() try: s1.getResult() self.fail() except ForcedResumeException: self.assertEquals("Too many suspended connections in SuspendRegister. One random connection has been resumed.\n", s.getvalue())
def testShouldAllowPostsOnly(self): result = ''.join(compose(self.dna.all.handleRequest(path='/service/v2/update', arguments={}, Method='GET'))) header, body = httpSplit(result) self.assertEquals('HTTP/1.0 405 Method Not Allowed', header) self.assertEquals('', body) result = ''.join(compose(self.dna.all.handleRequest(path='/service/v2/update', arguments={}, Method='HEAD'))) header, body = httpSplit(result) self.assertEquals('HTTP/1.0 405 Method Not Allowed', header) self.assertEquals('', body)
def testUpdateIpFilter(self): observer = CallTrace(methods={'handleRequest': handleRequest}) ipf = IpFilter(allowedIps=['192.168.1.1'], allowedIpRanges=[('10.0.0.1', '10.0.0.2'), '2001:41c8:10:7b::/64']) dna = be( (Observable(), (ipf, (observer,) ) ) ) list(compose(dna.all.handleRequest(Client=('127.0.0.1',), Headers={}))) list(compose(dna.all.handleRequest(Client=('10.0.0.10',), Headers={}))) self.assertEquals(0, len(observer.calledMethods)) list(compose(dna.all.handleRequest(Client=('192.168.1.1',), Headers={}))) self.assertEquals(1, len(observer.calledMethods)) del observer.calledMethods[:] list(compose(dna.all.handleRequest(Client=('2001:41c8:10:7b:aa:6:0:2', ), Headers={}))) self.assertEquals(1, len(observer.calledMethods)) del observer.calledMethods[:] ipf.updateIps(ipAddresses=['127.0.0.1'], ipRanges=[('10.0.0.1', '10.0.0.255'), '2001:41c8:10:7c::/64']) list(compose(dna.all.handleRequest(Client=('192.168.1.1',), Headers={}))) self.assertEquals(0, len(observer.calledMethods)) list(compose(dna.all.handleRequest(Client=('127.0.0.1',), Headers={}))) list(compose(dna.all.handleRequest(Client=('10.0.0.10',), Headers={}))) self.assertEquals(2, len(observer.calledMethods)) list(compose(dna.all.handleRequest(Client=('2001:41c8:10:7b:aa:6:0:2', ), Headers={}))) self.assertEquals(2, len(observer.calledMethods)) list(compose(dna.all.handleRequest(Client=('2001:41c8:10:7c:aa:6:0:2', ), Headers={}))) self.assertEquals(3, len(observer.calledMethods))
def testValid(self): validXml = '<lom xmlns="http://ltsc.ieee.org/xsd/LOM"/>' self.assertEquals(['done'], list(compose(self.observable.all.someMethod(parse(StringIO(validXml)))))) self.assertEquals(['done'], list(compose(self.observable.any.someMethod(parse(StringIO(validXml)))))) self.interceptor.calledMethods.reset() self.observable.do.someMethod(parse(StringIO(validXml))) self.assertEquals(['do_unknown'], [m.name for m in self.interceptor.calledMethods]) self.interceptor.calledMethods.reset() self.assertEquals('done', self.observable.call.someMethod(parse(StringIO(validXml))))
def testAnyViaUnknown(self): class A(object): def any_unknown(self, message, *args, **kwargs): raise StopIteration((message, args, kwargs), ) yield root = be((Observable(), (A(), ))) try: compose(root.any.f(1, a=2)).next() except StopIteration, e: r = e.args[0]
def testParseAndSetAndRemoveSessionVars2(self): arguments = {} def handleRequest(session=None, *args, **kwargs): arguments.update(session) yield 'goodbye' self.observer.handleRequest = handleRequest session = {} list(compose(self.argsInSession.handleRequest(session=session, arguments={'aap': ["+'noot'"]}))) self.assertEquals( ['noot'], arguments['aap']) list(compose(self.argsInSession.handleRequest(session=session, arguments={'aap': ["-'noot'"]}))) self.assertEquals( [], arguments['aap'])
def testFixUpExceptionTraceBack(self): class A: def a(self): raise Exception('A.a') def any_unknown(self, msg, *args, **kwargs): yield self.a() observable = Observable() observable.addObserver(A()) try: list(compose(observable.any.a())) except Exception: self.assertFunctionsOnTraceback("testFixUpExceptionTraceBack", "a") else: self.fail('Should not happen.') try: list(compose(observable.all.a())) except Exception: self.assertFunctionsOnTraceback("testFixUpExceptionTraceBack", "a") else: self.fail('Should not happen.') try: observable.do.a() except Exception: self.assertFunctionsOnTraceback("testFixUpExceptionTraceBack", "a") else: self.fail('Should not happen.') try: observable.call.a() except Exception: self.assertFunctionsOnTraceback("testFixUpExceptionTraceBack", "a") else: self.fail('Should not happen.') try: list(compose(observable.any.unknown('a'))) except Exception: self.assertFunctionsOnTraceback("testFixUpExceptionTraceBack", "a") else: self.fail('Should not happen.') try: list( compose( observable.any.somethingNotThereButHandledByUnknown('a'))) except Exception: self.assertFunctionsOnTraceback("testFixUpExceptionTraceBack", "any_unknown", "a") else: self.fail('Should not happen.')
def testListRecordsProducesResumptionTokenWithPartition(self): self._addRecords(['id:%s' % i for i in xrange(10)]) header, body = ''.join(compose(self.oaiList.listRecords(arguments={'verb':['ListRecords'], 'metadataPrefix': ['oai_dc'], 'x-partition':['1/2']}, **self.httpkwargs))).split(CRLF*2) oai = parse(StringIO(body)) self.assertEquals(2, len(xpath(oai, '/oai:OAI-PMH/oai:ListRecords/mock:record'))) resumptionToken = ResumptionToken.fromString(xpath(oai, '/oai:OAI-PMH/oai:ListRecords/oai:resumptionToken/text()')[0]) self.assertEquals(['id:2/oai_dc', 'id:3/oai_dc'], xpath(oai, '//mock:record/text()')) self.assertEquals('1/2', str(resumptionToken.partition)) header, body = ''.join(compose(self.oaiList.listRecords(arguments={'verb':['ListRecords'], 'resumptionToken': [str(resumptionToken)]}, **self.httpkwargs))).split(CRLF*2) oai = parse(StringIO(body)) self.assertEquals(['id:5/oai_dc', 'id:6/oai_dc'], xpath(oai, '//mock:record/text()'))
def _doDrilldown(self, translate, queryKwargs): observable = be( (Observable(), (TranslateDrilldownFieldnames(translate=translate), (self.observer,) ) ) ) try: compose(observable.any.executeQuery(**queryKwargs)).next() except StopIteration, e: return e.args[0]
def testDelete(self): identifier = ('some:thing:anId-123', 'somePartName') self.storage.put(identifier).close() self.assertTrue(identifier in self.storage) list(compose(self.storageComponent.delete('some:thing:anId-123'))) self.assertTrue(identifier in self.storage) self.storageComponent = StorageComponent( self.tempdir, partsRemovedOnDelete=['somePartName']) self.storage = self.storageComponent._storage list(compose(self.storageComponent.delete('some:thing:anId-123'))) self.assertFalse(identifier in self.storage)
def testRaisingDeclineMessageFromAllMakesNoDifference(self): class SemiTransparent(Observable): def all_unknown(self, message, *args, **kwargs): if message == 'theMessage': yield self.all.unknown(message, *args, **kwargs) raise DeclineMessage root = be((Observable(), (SemiTransparent(), (Responder(41), )), (Responder(42), ))) self.assertEquals([41, 42], list(compose(root.all.theMessage()))) self.assertEquals([42], list(compose(root.all.message())))
def testParse2(self): xmlString = """<tag><content>contents</content></tag>""" self.observable.do.add(identifier="id", partname="partName", data=xmlString) self.observable.call.add(identifier="id", partname="partName", data=xmlString) self.observer.methods['add'] = lambda **kwargs: (x for x in []) list(compose(self.observable.all.add(identifier="id", partname="partName", data=xmlString))) list(compose(self.observable.any.add(identifier="id", partname="partName", data=xmlString))) self.assertEquals(4, len(self.observer.calledMethods)) for i in range(4): xmlNode = self.observer.calledMethods[i].kwargs['lxmlNode'] self.assertEqualsLxml(XML(xmlString), xmlNode)
def testResourceManagerHandlesAttributeError(self): class Resource(object): def beginTransaction(self): raise StopIteration(object()) yield rm = ResourceManager('transaction') rm.addObserver(Resource()) __callstack_var_tx__ = CallTrace('TransactionScope') list(compose(rm.begin('transaction'))) try: list(compose(rm.all.unknown('doesnotexist'))) except AttributeError: self.fail('ResourceManager must ignore unknown methods.')
def testAnyAssertsResultOfCallIsGeneratorOrComposed(self): class A(object): def f(self): return 42 def any_unknown(self, message, *args, **kwargs): return 42 root = be((Observable(), (A(),))) try: compose(root.any.f()).next() self.fail('Should not happen') except AssertionError, e: self.assertTrue("<bound method A.f of <core.observabletest.A object at 0x" in str(e), str(e)) self.assertTrue(">> should have resulted in a generator." in str(e), str(e))
def testHandleYieldsAtLeastOnceAfterEachRecord(self): def add(**kwargs): return yield observer = CallTrace(methods={'add': add}) oaiDownloadProcessor = OaiDownloadProcessor(path="/oai", metadataPrefix="oai_dc", workingDirectory=self.tempdir, xWait=False) oaiDownloadProcessor.addObserver(observer) yields = list(compose(oaiDownloadProcessor.handle(parse(StringIO(LISTRECORDS_RESPONSE % ''))))) self.assertEquals(1, len(yields)) secondRecord = '<record xmlns="http://www.openarchives.org/OAI/2.0/"><header><identifier>oai:identifier:2</identifier><datestamp>2011-08-22T07:41:00Z</datestamp></header><metadata>ignored</metadata></record>' yields = list(compose(oaiDownloadProcessor.handle(parse(StringIO(LISTRECORDS_RESPONSE % secondRecord))))) self.assertEquals(2, len(yields))
def testResourceManagerHandlesAttributeError(self): class Resource(object): def beginTransaction(self): return object() yield rm = ResourceManager('transaction') rm.addObserver(Resource()) __callstack_var_tx__ = CallTrace('TransactionScope') list(compose(rm.begin('transaction'))) try: list(compose(rm.all.unknown('doesnotexist'))) except AttributeError: self.fail('ResourceManager must ignore unknown methods.')
def testHandleDifferentUsers(self): authentication = BasicAuthentication(realm='Test Realm') userdata = {'name':'aUser'} interceptor = CallTrace('httphandler', returnValues={'isValidLogin': True, 'getUser':userdata}, methods={'handleRequest': handleRequest}) authentication.addObserver(interceptor) headers = {'Authorization': 'Basic ' + b64encode('aUser:aPassword')} response = authentication.handleRequest(port='8080', RequestURI='/private', Method='GET', Headers=headers) list(compose(response)) self.assertEquals({'name': 'aUser'}, interceptor.calledMethods[2].kwargs['user']) headers = {'Authorization': 'Basic ' + b64encode('anotherUser:anotherPassword')} userdata['name'] = 'anotherUser' response = authentication.handleRequest(port='8080', RequestURI='/private', Method='GET', Headers=headers) list(compose(response)) self.assertEquals({'name': 'anotherUser'}, interceptor.calledMethods[5].kwargs['user'])
def testFindLocal(self): def f1(): someLocal = 'f1' yield f3() def f2(): someLocal = 'f2' yield f3() def f3(): l = local('someLocal') yield l f = compose(f1()) result = f.next() self.assertEquals('f1', str(result)) self.assertEquals('f2', str(compose(f2()).next()))
def testClientFromMulitpleXForwardedForEntries(self): list(compose(self.top.all.handleRequest( Client=("1.1.1.1", 11111), Headers={"X-Forwarded-For": "2.2.2.2,3.3.3.3,4.4.4.4"}))) self.assertEqual(1, len(self.observer.calledMethods)) handleRequestCallKwargs = self.observer.calledMethods[0].kwargs self.assertEqual('4.4.4.4', handleRequestCallKwargs['Client'][0]) self.assertEqual({"X-Forwarded-For": "2.2.2.2,3.3.3.3,4.4.4.4"}, handleRequestCallKwargs['Headers']) list(compose(self.top.all.handleRequest( Client=("1.1.1.1", 11111), Headers={"X-Forwarded-For": " 2.2.2.2 , 3.3.3.3, 4.4.4.4 ,"}))) self.assertEqual('4.4.4.4', self.observer.calledMethods[1].kwargs['Client'][0])
def testDelete(self): g = compose(self._solrInterface.delete("record&:1")) self._returnValueFromGenerator(g, ["SOME RESPONSE"]) g = compose(self._solrInterface.delete("record&:1")) self.assertRaises( IOError, lambda: self._returnValueFromGenerator(g, "ERROR", '500')) sendData = [] self._solrInterface._send = lambda path, body: sendData.append((path, body)) list(self._solrInterface.delete("record&:1")) self.assertEquals(1, len(sendData)) self.assertEquals(('/solr/update', '<delete><id>%s</id></delete>' % "record&:1"), sendData[0])
def testAdd(self): g = compose(self._solrInterface.add(identifier="recordId", partname="ignored", data="<record><data>recordData</data></record>")) self._returnValueFromGenerator(g, ["SOME RESPONSE"]) g = compose(self._solrInterface.add(identifier="recordId", partname="ignored", data="<record><data>recordData</data></record>")) self.assertRaises( IOError, lambda: self._returnValueFromGenerator(g, ["ERROR"], '500')) sendData = [] self._solrInterface._send = lambda path, body: sendData.append((path, body)) list(self._solrInterface.add(identifier="recordId", partname="ignored", data="<record><data>recordData</data></record>")) self.assertEquals(1, len(sendData)) self.assertEquals(('/solr/update', '<add><record><data>recordData</data></record></add>'), sendData[0])
def testRequestScopeForEveryMethod(self): resultByDo = [] class MyObserver(Observable): def someAnyMethod(self, key, value, *args, **kwargs): self.do.setArg(key, value) result = self.call.getArg(key) return result yield def someAllMethod(self, key, value, *args, **kwargs): self.do.setArg(key, value) yield self.call.getArg(key) def someCallMethod(self, key, value, *args, **kwargs): self.do.setArg(key, value) return self.call.getArg(key) def someDoMethod(self, key, value, *args, **kwargs): self.do.setArg(key, value) resultByDo.append(self.call.getArg(key)) class SetArgObserver(Observable): def setArg(self, key, value): self.ctx.requestScope[key] = value class GetArgObserver(Observable): def getArg(self, key): return self.ctx.requestScope[key] dna = be((Observable(), (RequestScope(), (MyObserver(), (SetArgObserver(), ), (GetArgObserver(), ))))) try: next(compose(dna.any.someAnyMethod(key='anykey', value='anyvalue'))) self.fail() except StopIteration as e: self.assertEqual('anyvalue', e.args[0]) self.assertEqual( ['allvalue'], list(compose(dna.all.someAllMethod(key='allkey', value='allvalue')))) dna.do.someDoMethod(key='dokey', value='dovalue') self.assertEqual(['dovalue'], resultByDo) self.assertEqual( 'callvalue', dna.call.someCallMethod(key='callkey', value='callvalue'))
def testEmptyIdInDeleteNotAllowed(self): __callstack_var_tx__ = CallTrace('Transaction') __callstack_var_tx__.locals={} v = Venturi() try: list(compose(v.delete(''))) self.fail("Should raise an exception") except ValueError as e: self.assertEqual("Empty identifier not allowed.", str(e)) try: list(compose(v.delete(None))) self.fail("Should raise an exception") except ValueError as e: self.assertEqual("Empty identifier not allowed.", str(e))
def testAddMetadataNamespace(self): self.observer.methods['add'] = lambda *args, **kwargs: (x for x in []) list( compose( self.harvestdate.all_unknown( 'add', 'id', 'metadata', 'anotherone', lxmlNode=parse(open("data/harvesterdoc.xml")), identifier='oai:very:secret:09987'))) self.assertEquals(1, len(self.observer.calledMethods)) # for m in self.observer.calledMethods: # print 'method name:',m.name, m.args, m.kwargs result = self.observer.calledMethods[0].kwargs.get('lxmlNode') self.assertEquals(3, len(self.observer.calledMethods[0].args)) arguments = self.observer.calledMethods[0].args self.assertEquals("id", arguments[0]) self.assertEquals("metadata", arguments[1]) metapart = result.xpath("//doc:part[@name='meta']/text()", namespaces=metaNS) mdNamespace = fromstring(metapart[0]).xpath( "//meta:metadataNamespace/text()", namespaces=metaNS) self.assertTrue( len(mdNamespace) == 1 and mdNamespace[0] == "http://www.openarchives.org/OAI/2.0/oai_dc/")
def testTcpPacketListener(self): reactor = CallTrace('reactor') observer = CallTrace('observer', emptyGeneratorMethods=['handlePacket']) tcpPacketListener = TcpPacketListener(reactor, port=1234) server = be((Observable(), (tcpPacketListener, (observer, )))) list(compose(server.once.observer_init())) self.assertEquals('addReader', reactor.calledMethods[0].name) acceptCallback = reactor.calledMethods[0].args[1] data = "TEST" * 1024 sok = socket() sok.connect(('localhost', 1234)) bytesSent = sok.send(data) self.assertEquals(len(data), bytesSent) sok.close() acceptCallback() self.assertEquals('addReader', reactor.calledMethods[1].name) handleCallback = reactor.calledMethods[1].args[1] handleCallback() self.assertEquals('addProcess', reactor.calledMethods[-2].name) reactor.calledMethods[-2].args[0]() self.assertEquals(['observer_init', 'handlePacket'], observer.calledMethodNames()) self.assertEquals(data, observer.calledMethods[1].kwargs['data']) self.assertEquals('removeReader', reactor.calledMethods[-2].name) self.assertEquals('removeProcess', reactor.calledMethods[-1].name)