def testFracturedSASL(self): """ PROTON-235 """ assert self.s1.outcome is None # self.t1.trace(Transport.TRACE_FRM) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push(str2bin("AMQP\x03\x01\x00\x00")) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push(str2bin("\x00\x00\x00")) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push( str2bin( "6\x02\x01\x00\x00\x00S@\xc04\x01\xe01\x04\xa3\x05PLAIN\x0aDIGEST-MD5\x09ANONYMOUS\x08CRAM-MD5" )) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push( str2bin("\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00")) out = self.t1.peek(1024) self.t1.pop(len(out)) while out: out = self.t1.peek(1024) self.t1.pop(len(out)) assert self.s1.outcome == SASL.OK, self.s1.outcome
def testFracturedSASL(self): """ PROTON-235 """ assert self.s1.outcome is None # self.t1.trace(Transport.TRACE_FRM) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push(str2bin("AMQP\x03\x01\x00\x00")) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push(str2bin("\x00\x00\x00")) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push(str2bin("6\x02\x01\x00\x00\x00S@\xc04\x01\xe01\x04\xa3\x05PLAIN\x0aDIGEST-MD5\x09ANONYMOUS\x08CRAM-MD5")) out = self.t1.peek(1024) self.t1.pop(len(out)) self.t1.push(str2bin("\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00")) out = self.t1.peek(1024) self.t1.pop(len(out)) while out: out = self.t1.peek(1024) self.t1.pop(len(out)) assert self.s1.outcome == SASL.OK, self.s1.outcome
def testDefaultCreationExpiryDecode(self): # This is a message with everything filled explicitly as null or zero in LIST32 HEADER and PROPERTIES lists data = str2bin( '\x00\x53\x70\xd0\x00\x00\x00\x0a\x00\x00\x00\x05\x42\x40\x40\x42\x52\x00\x00\x53\x73\xd0\x00\x00\x00\x12\x00\x00\x00\x0d\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x52\x00\x40' ) msg2 = Message() msg2.decode(data) assert msg2.expiry_time == 0, (msg2.expiry_time) assert msg2.creation_time == 0, (msg2.creation_time) # The same message with LIST8s instead data = str2bin( '\x00\x53\x70\xc0\x07\x05\x42\x40\x40\x42\x52\x00\x00\x53\x73\xc0\x0f\x0d\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x52\x00\x40' ) msg3 = Message() msg3.decode(data) assert msg2.expiry_time == 0, (msg2.expiry_time) assert msg2.creation_time == 0, (msg2.creation_time) # Minified message with zero length HEADER and PROPERTIES lists data = str2bin('\x00\x53\x70\x45' '\x00\x53\x73\x45') msg4 = Message() msg4.decode(data) assert msg2.expiry_time == 0, (msg2.expiry_time) assert msg2.creation_time == 0, (msg2.creation_time)
def testProtocolNotSupported(self): self.transport.push(str2bin("AMQP\x01\x01\x0a\x00")) p = self.transport.pending() assert p >= 8, p bytes = self.transport.peek(p) assert bytes[:8] == str2bin("AMQP\x00\x01\x00\x00") self.transport.pop(p) self.drain() assert self.transport.closed
def test_strings(self): self.decode_data_file("strings") self.assert_next(Data.BINARY, str2bin("abc\0defg")) self.assert_next(Data.STRING, "abcdefg") self.assert_next(Data.SYMBOL, "abcdefg") self.assert_next(Data.BINARY, str2bin("")) self.assert_next(Data.STRING, "") self.assert_next(Data.SYMBOL, "") assert self.data.next() is None
def testGarbage(self, garbage="GARBAGE_"): self.transport.push(str2bin(garbage)) p = self.transport.pending() assert p >= 8, p bytes = self.transport.peek(p) assert bytes[:8] == str2bin("AMQP\x00\x01\x00\x00") self.transport.pop(p) self.drain() assert self.transport.closed
def testPartial(self): self.transport.push(str2bin("AMQ")) # partial header self.transport.close_tail() p = self.transport.pending() assert p >= 8, p bytes = self.transport.peek(p) assert bytes[:8] == str2bin("AMQP\x00\x01\x00\x00") self.transport.pop(p) self.drain() assert self.transport.closed
def testBuffer(self): try: self.data.put_object(buffer(str2bin("foo"))) except NameError: # python >= 3.0 does not have `buffer` return data = Data() data.decode(self.data.encode()) data.rewind() assert data.next() assert data.type() == Data.BINARY assert data.get_object() == str2bin("foo")
def testMemoryView(self): try: self.data.put_object(memoryview(str2bin("foo"))) except NameError: # python <= 2.6 does not have `memoryview` return data = Data() data.decode(self.data.encode()) data.rewind() assert data.next() assert data.type() == Data.BINARY assert data.get_object() == str2bin("foo")
def testPipelinedServer(self): # Client self.s1.allowed_mechs('ANONYMOUS') c1 = Connection() self.t1.bind(c1) assert self.s1.outcome is None # Push server bytes into client # Commented out lines in this test are where the client input processing doesn't # run after output processing even though there is input waiting self.t1.push(str2bin( # SASL 'AMQP\x03\x01\x00\x00' # @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:ANONYMOUS]] '\x00\x00\x00\x1c\x02\x01\x00\x00\x00S@\xc0\x0f\x01\xe0\x0c\x01\xa3\tANONYMOUS' # @sasl-outcome(68) [code=0] '\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00' # AMQP 'AMQP\x00\x01\x00\x00' # @open(16) [container-id="", channel-max=1234] '\x00\x00\x00!\x02\x00\x00\x00\x00S\x10\xd0\x00\x00\x00\x11\x00\x00\x00\x0a\xa1\x00@@`\x04\xd2@@@@@@' )) consumeAllOuput(self.t1) assert self.s1.outcome == SASL.OK assert c1.state & Endpoint.REMOTE_ACTIVE
def testPipelinedClient(self): # TODO: When PROTON-1136 is fixed then remove this test if "java" in sys.platform: raise Skipped("Proton-J does not support pipelined client input") # Server self.s2.allowed_mechs('ANONYMOUS') c2 = Connection() self.t2.bind(c2) assert self.s2.outcome is None # Push client bytes into server self.t2.push(str2bin( # SASL 'AMQP\x03\x01\x00\x00' # @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@fuschia"] '\x00\x00\x002\x02\x01\x00\x00\x00SA\xd0\x00\x00\x00"\x00\x00\x00\x02\xa3\x09ANONYMOUS\xa0\x11anonymous@fuschia' # AMQP 'AMQP\x00\x01\x00\x00' # @open(16) [container-id="", channel-max=1234] '\x00\x00\x00!\x02\x00\x00\x00\x00S\x10\xd0\x00\x00\x00\x11\x00\x00\x00\x0a\xa1\x00@@`\x04\xd2@@@@@@' )) consumeAllOuput(self.t2) assert self.s2.outcome == SASL.OK assert c2.state & Endpoint.REMOTE_ACTIVE
def testUnpairedPop(self): conn = Connection() self.transport.bind(conn) conn.hostname = "hostname" conn.open() dat1 = self.transport.peek(1024) ssn = conn.session() ssn.open() dat2 = self.transport.peek(1024) assert dat2[: len(dat1)] == dat1 snd = ssn.sender("sender") snd.open() self.transport.pop(len(dat1)) self.transport.pop(len(dat2) - len(dat1)) dat3 = self.transport.peek(1024) self.transport.pop(len(dat3)) assert self.transport.peek(1024) == str2bin("") self.peer.push(dat1) self.peer.push(dat2[len(dat1) :]) self.peer.push(dat3)
def testPipelinedClient(self): # Server self.s2.allowed_mechs('ANONYMOUS') c2 = Connection() self.t2.bind(c2) assert self.s2.outcome is None # Push client bytes into server self.t2.push( str2bin( # SASL 'AMQP\x03\x01\x00\x00' # @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@fuschia"] '\x00\x00\x002\x02\x01\x00\x00\x00SA\xd0\x00\x00\x00"\x00\x00\x00\x02\xa3\x09ANONYMOUS\xa0\x11anonymous@fuschia' # AMQP 'AMQP\x00\x01\x00\x00' # @open(16) [container-id="", channel-max=1234] '\x00\x00\x00!\x02\x00\x00\x00\x00S\x10\xd0\x00\x00\x00\x11\x00\x00\x00\x0a\xa1\x00@@`\x04\xd2@@@@@@' )) consumeAllOuput(self.t2) assert not self.t2.condition assert self.s2.outcome == SASL.OK assert c2.state & Endpoint.REMOTE_ACTIVE
def testPipelinedClient(self): # TODO: When PROTON-1136 is fixed then remove this test if "java" in sys.platform: raise Skipped("Proton-J does not support pipelined client input") # Server self.s2.allowed_mechs('ANONYMOUS') c2 = Connection() self.t2.bind(c2) assert self.s2.outcome is None # Push client bytes into server self.t2.push( str2bin( # SASL 'AMQP\x03\x01\x00\x00' # @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@fuschia"] '\x00\x00\x002\x02\x01\x00\x00\x00SA\xd0\x00\x00\x00"\x00\x00\x00\x02\xa3\x09ANONYMOUS\xa0\x11anonymous@fuschia' # AMQP 'AMQP\x00\x01\x00\x00' # @open(16) [container-id="", channel-max=1234] '\x00\x00\x00!\x02\x00\x00\x00\x00S\x10\xd0\x00\x00\x00\x11\x00\x00\x00\x0a\xa1\x00@@`\x04\xd2@@@@@@' )) consumeAllOuput(self.t2) assert not self.t2.condition assert self.s2.outcome == SASL.OK assert c2.state & Endpoint.REMOTE_ACTIVE
def testIllegalProtocolLayering(self): # TODO: Skip Proton-J for now if "java" in sys.platform: raise Skipped("Proton-J does not set error condition on protocol layering violation") # Server self.s2.allowed_mechs('ANONYMOUS') c2 = Connection() self.t2.bind(c2) assert self.s2.outcome is None # Push client bytes into server self.t2.push(str2bin( # SASL 'AMQP\x03\x01\x00\x00' # @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@fuschia"] '\x00\x00\x002\x02\x01\x00\x00\x00SA\xd0\x00\x00\x00"\x00\x00\x00\x02\xa3\x09ANONYMOUS\xa0\x11anonymous@fuschia' # SASL (again illegally) 'AMQP\x03\x01\x00\x00' # @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@fuschia"] '\x00\x00\x002\x02\x01\x00\x00\x00SA\xd0\x00\x00\x00"\x00\x00\x00\x02\xa3\x09ANONYMOUS\xa0\x11anonymous@fuschia' # AMQP 'AMQP\x00\x01\x00\x00' # @open(16) [container-id="", channel-max=1234] '\x00\x00\x00!\x02\x00\x00\x00\x00S\x10\xd0\x00\x00\x00\x11\x00\x00\x00\x0a\xa1\x00@@`\x04\xd2@@@@@@' )) consumeAllOuput(self.t2) assert self.t2.condition assert self.t2.closed assert not c2.state & Endpoint.REMOTE_ACTIVE
def testUnpairedPop(self): conn = Connection() self.transport.bind(conn) conn.hostname = "hostname" conn.open() dat1 = self.transport.peek(1024) ssn = conn.session() ssn.open() dat2 = self.transport.peek(1024) assert dat2[:len(dat1)] == dat1 snd = ssn.sender("sender") snd.open() self.transport.pop(len(dat1)) self.transport.pop(len(dat2) - len(dat1)) dat3 = self.transport.peek(1024) self.transport.pop(len(dat3)) assert self.transport.peek(1024) == str2bin("") self.peer.push(dat1) self.peer.push(dat2[len(dat1):]) self.peer.push(dat3)
def testPipelinedServer(self): # Client self.s1.allowed_mechs('ANONYMOUS') c1 = Connection() self.t1.bind(c1) assert self.s1.outcome is None # Push server bytes into client # Commented out lines in this test are where the client input processing doesn't # run after output processing even though there is input waiting self.t1.push( str2bin( # SASL 'AMQP\x03\x01\x00\x00' # @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:ANONYMOUS]] '\x00\x00\x00\x1c\x02\x01\x00\x00\x00S@\xc0\x0f\x01\xe0\x0c\x01\xa3\tANONYMOUS' # @sasl-outcome(68) [code=0] '\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00' # AMQP 'AMQP\x00\x01\x00\x00' # @open(16) [container-id="", channel-max=1234] '\x00\x00\x00!\x02\x00\x00\x00\x00S\x10\xd0\x00\x00\x00\x11\x00\x00\x00\x0a\xa1\x00@@`\x04\xd2@@@@@@' )) consumeAllOuput(self.t1) assert self.s1.outcome == SASL.OK assert c1.state & Endpoint.REMOTE_ACTIVE
def testBindAfterOpen(self): conn = Connection() ssn = conn.session() conn.open() ssn.open() conn.container = "test-container" conn.hostname = "test-hostname" trn = Transport() trn.bind(conn) out = trn.peek(1024) assert str2bin("test-container") in out, repr(out) assert str2bin("test-hostname") in out, repr(out) self.transport.push(out) c = Connection() assert c.remote_container == None assert c.remote_hostname == None assert c.session_head(0) == None self.transport.bind(c) assert c.remote_container == "test-container" assert c.remote_hostname == "test-hostname" assert c.session_head(0) != None
def testDefaultPriorityDecode(self): # This is a message with everything filled explicitly as null or zero in LIST32 HEADER and PROPERTIES lists data = str2bin( '\x00\x53\x70\xd0\x00\x00\x00\x0a\x00\x00\x00\x05\x42\x40\x40\x42\x52\x00\x00\x53\x73\xd0\x00\x00\x00\x22\x00\x00\x00\x0d\x40\x40\x40\x40\x40\x40\x40\x40\x83\x00\x00\x00\x00\x00\x00\x00\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x40\x52\x00\x40' ) msg2 = Message() msg2.decode(data) assert msg2.priority == 4, (msg2.priority) # The same message with LIST8s instead data = str2bin( '\x00\x53\x70\xc0\x07\x05\x42\x40\x40\x42\x52\x00\x00\x53\x73\xc0\x1f\x0d\x40\x40\x40\x40\x40\x40\x40\x40\x83\x00\x00\x00\x00\x00\x00\x00\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x40\x52\x00\x40' ) msg3 = Message() msg3.decode(data) assert msg3.priority == 4, (msg3.priority) # Minified message with zero length HEADER and PROPERTIES lists data = str2bin('\x00\x53\x70\x45' '\x00\x53\x73\x45') msg4 = Message() msg4.decode(data) assert msg4.priority == 4, (msg4.priority)
def testSaslAndAmqpInSingleChunk(self): if "java" in sys.platform: raise Skipped("Proton-J does not support client pipelining") self.s1.allowed_mechs('ANONYMOUS') self.s2.allowed_mechs('ANONYMOUS') # send the server's OK to the client # This is still needed for the Java impl out2 = self.t2.peek(1024) self.t2.pop(len(out2)) self.t1.push(out2) # do some work to generate AMQP data c1 = Connection() c2 = Connection() self.t1.bind(c1) c1._transport = self.t1 self.t2.bind(c2) c2._transport = self.t2 c1.open() # get all t1's output in one buffer then pass it all to t2 out1_sasl_and_amqp = str2bin("") t1_still_producing = True while t1_still_producing: out1 = self.t1.peek(1024) self.t1.pop(len(out1)) out1_sasl_and_amqp += out1 t1_still_producing = out1 t2_still_consuming = True while t2_still_consuming: num = min(self.t2.capacity(), len(out1_sasl_and_amqp)) self.t2.push(out1_sasl_and_amqp[:num]) out1_sasl_and_amqp = out1_sasl_and_amqp[num:] t2_still_consuming = num > 0 and len(out1_sasl_and_amqp) > 0 assert len(out1_sasl_and_amqp) == 0, (len(out1_sasl_and_amqp), out1_sasl_and_amqp) # check that t2 processed both the SASL data and the AMQP data assert self.s2.outcome == SASL.OK assert c2.state & Endpoint.REMOTE_ACTIVE
def testSaslAndAmqpInSingleChunk(self): if "java" in sys.platform: raise Skipped("Proton-J does not support client pipelining") self.s1.allowed_mechs('ANONYMOUS') self.s2.allowed_mechs('ANONYMOUS') # do some work to generate AMQP data c1 = Connection() c2 = Connection() self.t1.bind(c1) c1._transport = self.t1 self.t2.bind(c2) c2._transport = self.t2 c1.open() # get all t1's output in one buffer then pass it all to t2 out1_sasl_and_amqp = str2bin("") t1_still_producing = True while t1_still_producing: out1 = self.t1.peek(1024) self.t1.pop(len(out1)) out1_sasl_and_amqp += out1 t1_still_producing = out1 t2_still_consuming = True while t2_still_consuming: num = min(self.t2.capacity(), len(out1_sasl_and_amqp)) self.t2.push(out1_sasl_and_amqp[:num]) out1_sasl_and_amqp = out1_sasl_and_amqp[num:] t2_still_consuming = num > 0 and len(out1_sasl_and_amqp) > 0 assert len(out1_sasl_and_amqp) == 0, (len(out1_sasl_and_amqp), out1_sasl_and_amqp) # check that t2 processed both the SASL data and the AMQP data assert self.s2.outcome == SASL.OK assert c2.state & Endpoint.REMOTE_ACTIVE
def testIllegalProtocolLayering(self): # TODO: Skip Proton-J for now if "java" in sys.platform: raise Skipped( "Proton-J does not set error condition on protocol layering violation" ) # Server self.s2.allowed_mechs('ANONYMOUS') c2 = Connection() self.t2.bind(c2) assert self.s2.outcome is None # Push client bytes into server self.t2.push( str2bin( # SASL 'AMQP\x03\x01\x00\x00' # @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@fuschia"] '\x00\x00\x002\x02\x01\x00\x00\x00SA\xd0\x00\x00\x00"\x00\x00\x00\x02\xa3\x09ANONYMOUS\xa0\x11anonymous@fuschia' # SASL (again illegally) 'AMQP\x03\x01\x00\x00' # @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@fuschia"] '\x00\x00\x002\x02\x01\x00\x00\x00SA\xd0\x00\x00\x00"\x00\x00\x00\x02\xa3\x09ANONYMOUS\xa0\x11anonymous@fuschia' # AMQP 'AMQP\x00\x01\x00\x00' # @open(16) [container-id="", channel-max=1234] '\x00\x00\x00!\x02\x00\x00\x00\x00S\x10\xd0\x00\x00\x00\x11\x00\x00\x00\x0a\xa1\x00@@`\x04\xd2@@@@@@' )) consumeAllOuput(self.t2) assert self.t2.condition assert self.t2.closed assert not c2.state & Endpoint.REMOTE_ACTIVE
def testHeaderBadSize(self): """Verify size > max_frame_size error""" self.transport.max_frame_size = 512 self.testGarbage(str2bin("AMQP\x00\x01\x00\x00\x00\x00\x02\x01\x02\x00\x00\x00"))
def testEOS(self): self.transport.push(str2bin("")) # should be a noop self.transport.close_tail() # should result in framing error self.assert_error(u"amqp:connection:framing-error")
def testEOS(self): self.transport.push(str2bin("")) # should be a noop self.transport.close_tail() p = self.transport.pending() self.drain() assert self.transport.closed
def testPartial(self): self.transport.push(str2bin("AMQ")) # partial header self.transport.close_tail() # should result in framing error self.assert_error(u"amqp:connection:framing-error")
def testPartial(self): self.transport.push(str2bin("AMQ")) # partial header self.transport.close_tail() # should result in framing error self.assert_error(u'amqp:connection:framing-error')
def testSmallGarbage(self): self.testGarbage(str2bin("XXX"))
def testGarbage(self, garbage=str2bin("GARBAGE_")): self.transport.push(garbage) self.assert_error(u"amqp:connection:framing-error") assert self.transport.pending() < 0 self.transport.close_tail() assert self.transport.pending() < 0
def testBinary(self): self._test("binary", str2bin("this"), str2bin("is"), str2bin("a"), str2bin("test"), str2bin("of" "b\x00inary"))
def testBigGarbage(self): self.testGarbage(str2bin("GARBAGE_XXX"))
def testHeader(self): self.transport.push(str2bin("AMQP\x00\x01\x00\x00")) self.transport.close_tail() self.assert_error(u"amqp:connection:framing-error")
def testHeaderBadDOFF2(self): """Verify doff < 2 error""" self.testGarbage(str2bin("AMQP\x00\x01\x00\x00\x00\x00\x00\x08\x01\x00\x00\x00"))
def testUserId(self): self._test("user_id", str2bin(""), (str2bin("asdf"), str2bin("fdsa"), str2bin("asd\x00fdsa"), str2bin("")))
def testDecimal128(self): self._test("decimal128", decimal128(str2bin("fdsaasdf;lkjjkl;")), decimal128(str2bin("x" * 16)))
def testEOS(self): self.transport.push(str2bin("")) # should be a noop self.transport.close_tail() # should result in framing error self.assert_error(u'amqp:connection:framing-error')
def testHeaderBadSize(self): """Verify size > max_frame_size error""" self.transport.max_frame_size = 512 self.testGarbage( str2bin("AMQP\x00\x01\x00\x00\x00\x00\x02\x01\x02\x00\x00\x00"))
def testGarbage(self, garbage=str2bin("GARBAGE_")): self.transport.push(garbage) self.assert_error(u'amqp:connection:framing-error') assert self.transport.pending() < 0 self.transport.close_tail() assert self.transport.pending() < 0
def testHeader(self): self.transport.push(str2bin("AMQP\x00\x01\x00\x00")) self.transport.close_tail() self.assert_error(u'amqp:connection:framing-error')
def testHeaderBadDOFF2(self): """Verify doff < 2 error""" self.testGarbage( str2bin("AMQP\x00\x01\x00\x00\x00\x00\x00\x08\x01\x00\x00\x00"))
def testDecimal128(self): self._test("decimal128", str2bin("fdsaasdf;lkjjkl;"), str2bin("x"*16))