This is an automated email from the ASF dual-hosted git repository.
jdanek pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/qpid-proton.gitThe following commit(s) were added to refs/heads/master by this push:
new dd05347 PROTON-2320 Apply first round of autopep8 (whitespace changes, mostly) (#285)
dd05347 is described below
commit dd0534710e83f2ead0114550a6ee6c9c5abdaf54
Author: Jiri Daněk <
[hidden email]>
AuthorDate: Thu Jan 14 18:36:12 2021 +0100
PROTON-2320 Apply first round of autopep8 (whitespace changes, mostly) (#285)
---
c/src/encodings.h.py | 17 +-
c/src/protocol.h.py | 109 +-
c/src/protocol.py | 135 +-
c/tests/fdlimit.py | 6 +-
python/docs/conf.py | 6 +-
python/examples/abstract_server.py | 6 +-
python/examples/client.py | 11 +-
python/examples/client_http.py | 2 +
python/examples/colour_send.py | 7 +-
python/examples/db_common.py | 6 +-
python/examples/db_ctrl.py | 5 +-
python/examples/db_recv.py | 8 +-
python/examples/db_send.py | 12 +-
python/examples/direct_recv.py | 8 +-
python/examples/direct_send.py | 7 +-
python/examples/helloworld.py | 2 +
python/examples/helloworld_blocking.py | 3 +-
python/examples/helloworld_direct.py | 2 +
python/examples/helloworld_direct_tornado.py | 2 +
python/examples/helloworld_tornado.py | 2 +
python/examples/proton_server.py | 5 +-
python/examples/queue_browser.py | 8 +-
python/examples/recurring_timer.py | 4 +-
python/examples/recurring_timer_tornado.py | 4 +-
python/examples/selected_recv.py | 8 +-
python/examples/server.py | 10 +-
python/examples/server_direct.py | 8 +-
python/examples/server_tx.py | 8 +-
python/examples/simple_recv.py | 8 +-
python/examples/simple_send.py | 7 +-
python/examples/sync_client.py | 9 +-
python/examples/test_examples.py | 10 +-
python/examples/tx_recv.py | 8 +-
python/examples/tx_recv_interactive.py | 9 +-
python/examples/tx_send.py | 7 +-
python/proton/_common.py | 1 +
python/proton/_compat.py | 6 +-
python/proton/_condition.py | 7 +-
python/proton/_data.py | 44 +-
python/proton/_delivery.py | 10 +-
python/proton/_endpoints.py | 14 +-
python/proton/_events.py | 6 -
python/proton/_handlers.py | 14 +-
python/proton/_io.py | 8 +-
python/proton/_message.py | 9 +-
python/proton/_reactor.py | 51 +-
python/proton/_tracing.py | 8 +-
python/proton/_transport.py | 35 +-
python/proton/_url.py | 11 +-
python/proton/_utils.py | 14 +-
python/proton/_wrapper.py | 3 +-
python/setuputils/log.py | 12 +-
python/setuputils/misc.py | 15 +-
python/tests/proton_tests/__main__.py | 2 +-
python/tests/proton_tests/codec.py | 979 ++---
python/tests/proton_tests/common.py | 332 +-
python/tests/proton_tests/connect.py | 37 +-
python/tests/proton_tests/engine.py | 5196 +++++++++++++-------------
python/tests/proton_tests/handler.py | 196 +-
python/tests/proton_tests/interop.py | 24 +-
python/tests/proton_tests/main.py | 983 ++---
python/tests/proton_tests/message.py | 595 +--
python/tests/proton_tests/reactor.py | 19 +-
python/tests/proton_tests/sasl.py | 1103 +++---
python/tests/proton_tests/soak.py | 24 +-
python/tests/proton_tests/ssl.py | 371 +-
python/tests/proton_tests/transport.py | 719 ++--
python/tests/proton_tests/url.py | 16 +-
python/tests/proton_tests/utils.py | 24 +-
tests/py/test_subprocess.py | 5 +-
tools/python/mllib/__init__.py | 76 +-
tools/python/mllib/dom.py | 435 ++-
tools/python/mllib/parsers.py | 122 +-
tools/python/mllib/transforms.py | 216 +-
74 files changed, 6258 insertions(+), 5953 deletions(-)
diff --git a/c/src/encodings.h.py b/c/src/encodings.h.py
index 9f08c6c..c5dd996 100644
--- a/c/src/encodings.h.py
+++ b/c/src/encodings.h.py
@@ -19,7 +19,10 @@
#
from __future__ import print_function
-import mllib, optparse, os, sys
+import mllib
+import optparse
+import os
+import sys
xml = os.path.join(os.path.dirname(__file__), "types.xml")
doc = mllib.xml_parse(xml)
@@ -31,12 +34,12 @@ print()
print("#define PNE_DESCRIPTOR (0x00)")
for enc in doc.query["amqp/section/type/encoding"]:
- name = enc["@name"] or enc.parent["@name"]
- # XXX: a bit hacky
- if name == "ieee-754":
- name = enc.parent["@name"]
- cname = "PNE_" + name.replace("-", "_").upper()
- print("#define %s%s(%s)" % (cname, " "*(20-len(cname)), enc["@code"]))
+ name = enc["@name"] or enc.parent["@name"]
+ # XXX: a bit hacky
+ if name == "ieee-754":
+ name = enc.parent["@name"]
+ cname = "PNE_" + name.replace("-", "_").upper()
+ print("#define %s%s(%s)" % (cname, " "*(20-len(cname)), enc["@code"]))
print()
print("#endif /* encodings.h */")
diff --git a/c/src/protocol.h.py b/c/src/protocol.h.py
index 321cf64..7e1bed5 100644
--- a/c/src/protocol.h.py
+++ b/c/src/protocol.h.py
@@ -30,33 +30,36 @@ print("#include \"proton/type_compat.h\"")
fields = {}
for type in TYPES:
- fidx = 0
- for f in type.query["field"]:
- print("#define %s_%s (%s)" % (field_kw(type), field_kw(f), fidx))
- fidx += 1
- d = f["@default"]
- if d:
- ft = ftype(f)
- # Don't bother to emit a boolean default that is False
- if ft=="boolean" and d=="false": continue
- # Don't output non numerics unless symbol
- # We should really fully resolve to actual restricted value
- # this is really true for symbols too which accidentally work
- if ft=="symbol": d = '"' + d + '"'
- elif d[0] not in '0123456789': continue
- print("#define %s_%s_DEFAULT (%s) /* %s */" % (field_kw(type), field_kw(f), d, ft))
+ fidx = 0
+ for f in type.query["field"]:
+ print("#define %s_%s (%s)" % (field_kw(type), field_kw(f), fidx))
+ fidx += 1
+ d = f["@default"]
+ if d:
+ ft = ftype(f)
+ # Don't bother to emit a boolean default that is False
+ if ft == "boolean" and d == "false":
+ continue
+ # Don't output non numerics unless symbol
+ # We should really fully resolve to actual restricted value
+ # this is really true for symbols too which accidentally work
+ if ft == "symbol":
+ d = '"' + d + '"'
+ elif d[0] not in '0123456789':
+ continue
+ print("#define %s_%s_DEFAULT (%s) /* %s */" % (field_kw(type), field_kw(f), d, ft))
idx = 0
for type in TYPES:
- desc = type["descriptor"]
- name = type["@name"].upper().replace("-", "_")
- print("#define %s_SYM (\"%s\")" % (name, desc["@name"]))
- hi, lo = [int(x, 0) for x in desc["@code"].split(":")]
- code = (hi << 32) + lo
- print("#define %s ((uint64_t) %s)" % (name, code))
- fields[code] = (type["@name"], [f["@name"] for f in type.query["field"]])
- idx += 1
+ desc = type["descriptor"]
+ name = type["@name"].upper().replace("-", "_")
+ print("#define %s_SYM (\"%s\")" % (name, desc["@name"]))
+ hi, lo = [int(x, 0) for x in desc["@code"].split(":")]
+ code = (hi << 32) + lo
+ print("#define %s ((uint64_t) %s)" % (name, code))
+ fields[code] = (type["@name"], [f["@name"] for f in type.query["field"]])
+ idx += 1
print("""
#include <stddef.h>
@@ -79,7 +82,7 @@ for name, fnames in fields.values():
strings.add(name)
strings.update(fnames)
for str in strings:
- istr = str.replace("-", "_");
+ istr = str.replace("-", "_")
print(' const char FIELD_STRINGS_%s[sizeof("%s")];' % (istr, str))
print("};")
print()
@@ -91,7 +94,7 @@ print()
print('const struct FIELD_STRINGS FIELD_STRINGPOOL = {')
print(' "",')
for str in strings:
- print(' "%s",'% str)
+ print(' "%s",' % str)
print("};")
print()
print("/* This is an array of offsets into FIELD_STRINGPOOL */")
@@ -99,11 +102,11 @@ print("const uint16_t FIELD_NAME[] = {")
print(" offsetof(struct FIELD_STRINGS, STRING0),")
index = 1
for i in range(256):
- if i in fields:
- name, fnames = fields[i]
- iname = name.replace("-", "_");
- print(' offsetof(struct FIELD_STRINGS, FIELD_STRINGS_%s), /* %d */' % (iname, index))
- index += 1
+ if i in fields:
+ name, fnames = fields[i]
+ iname = name.replace("-", "_")
+ print(' offsetof(struct FIELD_STRINGS, FIELD_STRINGS_%s), /* %d */' % (iname, index))
+ index += 1
print("};")
print("/* This is an array of offsets into FIELD_STRINGPOOL */")
@@ -111,13 +114,13 @@ print("const uint16_t FIELD_FIELDS[] = {")
print(" offsetof(struct FIELD_STRINGS, STRING0),")
index = 1
for i in range(256):
- if i in fields:
- name, fnames = fields[i]
- if fnames:
- for f in fnames:
- ifname = f.replace("-", "_");
- print(' offsetof(struct FIELD_STRINGS, FIELD_STRINGS_%s), /* %d (%s) */' % (ifname, index, name))
- index += 1
+ if i in fields:
+ name, fnames = fields[i]
+ if fnames:
+ for f in fnames:
+ ifname = f.replace("-", "_")
+ print(' offsetof(struct FIELD_STRINGS, FIELD_STRINGS_%s), /* %d (%s) */' % (ifname, index, name))
+ index += 1
print("};")
print("const pn_fields_t FIELDS[] = {")
@@ -127,23 +130,27 @@ field_count = 1
field_min = 256
field_max = 0
for i in range(256):
- if i in fields:
- if i>field_max: field_max = i
- if i<field_min: field_min = i
+ if i in fields:
+ if i > field_max:
+ field_max = i
+ if i < field_min:
+ field_min = i
for i in range(field_min, field_max+1):
- if i in fields:
- name, fnames = fields[i]
- if fnames:
- print(' {%d, %d, %d}, /* %d (%s) */' % (name_count, field_count, len(fnames), i, name))
- field_count += len(fnames)
+ if i in fields:
+ name, fnames = fields[i]
+ if fnames:
+ print(' {%d, %d, %d}, /* %d (%s) */' % (name_count, field_count, len(fnames), i, name))
+ field_count += len(fnames)
+ else:
+ print(' {%d, 0, 0}, /* %d (%s) */' % (name_count, i, name))
+ name_count += 1
+ if i > field_max:
+ field_max = i
+ if i < field_min:
+ field_min = i
else:
- print(' {%d, 0, 0}, /* %d (%s) */' % (name_count, i, name))
- name_count += 1
- if i>field_max: field_max = i
- if i<field_min: field_min = i
- else:
- print(' {0, 0, 0}, /* %d */' % i)
+ print(' {0, 0, 0}, /* %d */' % i)
print("};")
print()
diff --git a/c/src/protocol.py b/c/src/protocol.py
index 3f04973..921bf0b 100644
--- a/c/src/protocol.py
+++ b/c/src/protocol.py
@@ -16,15 +16,19 @@
# specific language governing permissions and limitations
# under the License.
#
-import mllib, os, sys
+import mllib
+import os
+import sys
doc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "transport.xml"))
mdoc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "messaging.xml"))
tdoc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "transactions.xml"))
sdoc = mllib.xml_parse(os.path.join(os.path.dirname(__file__), "security.xml"))
+
def eq(attr, value):
- return lambda nd: nd[attr] == value
+ return lambda nd: nd[attr] == value
+
TYPEStmp = doc.query["amqp/section/type", eq("@class", "composite")] + \
mdoc.query["amqp/section/type", eq("@class", "composite")] + \
@@ -33,89 +37,98 @@ TYPEStmp = doc.query["amqp/section/type", eq("@class", "composite")] + \
mdoc.query["amqp/section/type", eq("@provides", "section")]
TYPES = []
for ty in TYPEStmp:
- if not ty in TYPES:
- TYPES.append(ty)
+ if not ty in TYPES:
+ TYPES.append(ty)
RESTRICTIONS = {}
COMPOSITES = {}
for type in doc.query["amqp/section/type"] + mdoc.query["amqp/section/type"] + \
- sdoc.query["amqp/section/type"] + tdoc.query["amqp/section/type"]:
+ sdoc.query["amqp/section/type"] + tdoc.query["amqp/section/type"]:
+
+ source = type["@source"]
+ if source:
+ RESTRICTIONS[type["@name"]] = source
+ if type["@class"] == "composite":
+ COMPOSITES[type["@name"]] = type
- source = type["@source"]
- if source:
- RESTRICTIONS[type["@name"]] = source
- if type["@class"] == "composite":
- COMPOSITES[type["@name"]] = type
def resolve(name):
- if name in RESTRICTIONS:
- return resolve(RESTRICTIONS[name])
- else:
- return name
+ if name in RESTRICTIONS:
+ return resolve(RESTRICTIONS[name])
+ else:
+ return name
+
TYPEMAP = {
- "boolean": ("bool", "", ""),
- "binary": ("pn_binary_t", "*", ""),
- "string": ("wchar_t", "*", ""),
- "symbol": ("char", "*", ""),
- "ubyte": ("uint8_t", "", ""),
- "ushort": ("uint16_t", "", ""),
- "uint": ("uint32_t", "", ""),
- "ulong": ("uint64_t", "", ""),
- "timestamp": ("uint64_t", "", ""),
- "list": ("pn_list_t", "*", ""),
- "map": ("pn_map_t", "*", ""),
- "box": ("pn_box_t", "*", ""),
- "*": ("pn_object_t", "*", "")
- }
+ "boolean": ("bool", "", ""),
+ "binary": ("pn_binary_t", "*", ""),
+ "string": ("wchar_t", "*", ""),
+ "symbol": ("char", "*", ""),
+ "ubyte": ("uint8_t", "", ""),
+ "ushort": ("uint16_t", "", ""),
+ "uint": ("uint32_t", "", ""),
+ "ulong": ("uint64_t", "", ""),
+ "timestamp": ("uint64_t", "", ""),
+ "list": ("pn_list_t", "*", ""),
+ "map": ("pn_map_t", "*", ""),
+ "box": ("pn_box_t", "*", ""),
+ "*": ("pn_object_t", "*", "")
+}
CONSTRUCTORS = {
- "boolean": "boolean",
- "string": "string",
- "symbol": "symbol",
- "ubyte": "ubyte",
- "ushort": "ushort",
- "uint": "uint",
- "ulong": "ulong",
- "timestamp": "ulong"
- }
+ "boolean": "boolean",
+ "string": "string",
+ "symbol": "symbol",
+ "ubyte": "ubyte",
+ "ushort": "ushort",
+ "uint": "uint",
+ "ulong": "ulong",
+ "timestamp": "ulong"
+}
NULLABLE = set(["string", "symbol"])
+
def fname(field):
- return field["@name"].replace("-", "_")
+ return field["@name"].replace("-", "_")
+
def tname(t):
- return t["@name"].replace("-", "_")
+ return t["@name"].replace("-", "_")
+
def multi(f):
- return f["@multiple"] == "true"
+ return f["@multiple"] == "true"
+
def ftype(field):
- if multi(field):
- return "list"
- elif field["@type"] in COMPOSITES:
- return "box"
- else:
- return resolve(field["@type"]).replace("-", "_")
+ if multi(field):
+ return "list"
+ elif field["@type"] in COMPOSITES:
+ return "box"
+ else:
+ return resolve(field["@type"]).replace("-", "_")
+
def fconstruct(field, expr):
- type = ftype(field)
- if type in CONSTRUCTORS:
- result = "pn_%s(mem, %s)" % (CONSTRUCTORS[type], expr)
- if type in NULLABLE:
- result = "%s ? %s : NULL" % (expr, result)
- else:
- result = expr
- if multi(field):
- result = "pn_box(mem, pn_boolean(mem, true), %s)" % result
- return result
+ type = ftype(field)
+ if type in CONSTRUCTORS:
+ result = "pn_%s(mem, %s)" % (CONSTRUCTORS[type], expr)
+ if type in NULLABLE:
+ result = "%s ? %s : NULL" % (expr, result)
+ else:
+ result = expr
+ if multi(field):
+ result = "pn_box(mem, pn_boolean(mem, true), %s)" % result
+ return result
+
def declaration(field):
- name = fname(field)
- type = ftype(field)
- t, pre, post = TYPEMAP.get(type, (type, "", ""))
- return t, "%s%s%s" % (pre, name, post)
+ name = fname(field)
+ type = ftype(field)
+ t, pre, post = TYPEMAP.get(type, (type, "", ""))
+ return t, "%s%s%s" % (pre, name, post)
+
def field_kw(field):
- return fname(field).upper()
+ return fname(field).upper()
diff --git a/c/tests/fdlimit.py b/c/tests/fdlimit.py
index 0749edf..8ef60ac 100644
--- a/c/tests/fdlimit.py
+++ b/c/tests/fdlimit.py
@@ -85,8 +85,10 @@ class FdLimitTest(unittest.TestCase):
self.assertEqual(sender.wait(), 0)
# Additional send/receive should succeed now
- self.assertIn("10 messages sent", test_subprocess.check_output(["send", "", b.port], universal_newlines=True))
- self.assertIn("10 messages received", test_subprocess.check_output(["receive", "", b.port], universal_newlines=True))
+ self.assertIn("10 messages sent", test_subprocess.check_output(
+ ["send", "", b.port], universal_newlines=True))
+ self.assertIn("10 messages received", test_subprocess.check_output(
+ ["receive", "", b.port], universal_newlines=True))
if __name__ == "__main__":
diff --git a/python/docs/conf.py b/python/docs/conf.py
index e57ebfe..b85eae8 100644
--- a/python/docs/conf.py
+++ b/python/docs/conf.py
@@ -32,9 +32,9 @@ try:
with open(ver_file_path, 'r') as ver_file:
ver_str = ver_file.read().replace('\n', '')
if '-' in ver_str:
- version = ver_str.split("-")[0] # Strip '-SNAPSHOT' from end of string
+ version = ver_str.split("-")[0] # Strip '-SNAPSHOT' from end of string
else:
- version = ver_str;
+ version = ver_str
release = version
print('Proton version: %s' % version)
except IOError:
@@ -53,7 +53,7 @@ except IOError:
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
- 'sphinx.ext.mathjax', # needed for math formulas on some versions of Sphinx
+ 'sphinx.ext.mathjax', # needed for math formulas on some versions of Sphinx
]
# Add any paths that contain templates here, relative to this directory.
diff --git a/python/examples/abstract_server.py b/python/examples/abstract_server.py
index f536486..6a7e312 100755
--- a/python/examples/abstract_server.py
+++ b/python/examples/abstract_server.py
@@ -22,6 +22,7 @@ from __future__ import print_function
from proton_server import Server
+
class Application(Server):
def __init__(self, host, address):
super(Application, self).__init__(host, address)
@@ -31,7 +32,8 @@ class Application(Server):
self.send(response, reply_to)
print("Request from: %s" % reply_to)
+
try:
Application("localhost:5672", "examples").run()
-except KeyboardInterrupt: pass
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/client.py b/python/examples/client.py
index 86f2c76..b149040 100755
--- a/python/examples/client.py
+++ b/python/examples/client.py
@@ -24,6 +24,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container, DynamicNodeProperties
+
class Client(MessagingHandler):
def __init__(self, url, requests):
super(Client, self).__init__()
@@ -50,10 +51,11 @@ class Client(MessagingHandler):
else:
event.connection.close()
-REQUESTS= ["Twas brillig, and the slithy toves",
- "Did gire and gymble in the wabe.",
- "All mimsy were the borogroves,",
- "And the mome raths outgrabe."]
+
+REQUESTS = ["Twas brillig, and the slithy toves",
+ "Did gire and gymble in the wabe.",
+ "All mimsy were the borogroves,",
+ "And the mome raths outgrabe."]
parser = optparse.OptionParser(usage="usage: %prog [options]",
description="Send requests to the supplied address and print responses.")
@@ -62,4 +64,3 @@ parser.add_option("-a", "--address", default="localhost:5672/examples",
opts, args = parser.parse_args()
Container(Client(opts.address, args or REQUESTS)).run()
-
diff --git a/python/examples/client_http.py b/python/examples/client_http.py
index f756740..add9420 100755
--- a/python/examples/client_http.py
+++ b/python/examples/client_http.py
@@ -27,6 +27,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton_tornado import Container
+
class Client(MessagingHandler):
def __init__(self, host, address):
super(Client, self).__init__()
@@ -72,6 +73,7 @@ class Client(MessagingHandler):
self.container.touch()
return future
+
class ExampleHandler(tornado.web.RequestHandler):
def initialize(self, client):
self.client = client
diff --git a/python/examples/colour_send.py b/python/examples/colour_send.py
index 1da1cf5..c7442d8 100755
--- a/python/examples/colour_send.py
+++ b/python/examples/colour_send.py
@@ -24,6 +24,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class Send(MessagingHandler):
def __init__(self, url, messages):
super(Send, self).__init__()
@@ -42,7 +43,7 @@ class Send(MessagingHandler):
else:
colour = 'green'
content = '%s %d' % (colour, self.sent+1)
- msg = Message(id=(self.sent+1), properties={'colour':colour}, body=content)
+ msg = Message(id=(self.sent+1), properties={'colour': colour}, body=content)
event.sender.send(msg)
self.sent += 1
@@ -55,6 +56,7 @@ class Send(MessagingHandler):
def on_disconnected(self, event):
self.sent = self.confirmed
+
parser = optparse.OptionParser(usage="usage: %prog [options]",
description="Send messages to the supplied address.")
parser.add_option("-a", "--address", default="localhost:5672/examples",
@@ -65,4 +67,5 @@ opts, args = parser.parse_args()
try:
Container(Send(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/db_common.py b/python/examples/db_common.py
index 54af87b..c12417d 100755
--- a/python/examples/db_common.py
+++ b/python/examples/db_common.py
@@ -26,6 +26,7 @@ except:
import sqlite3
import threading
+
class Db(object):
def __init__(self, db, injector):
self.db = db
@@ -35,7 +36,7 @@ class Db(object):
self.pending_events = []
self.running = True
self.thread = threading.Thread(target=self._process)
- self.thread.daemon=True
+ self.thread.daemon = True
self.thread.start()
def close(self):
@@ -110,7 +111,8 @@ class Db(object):
while True:
f(conn)
f = self.tasks.get(False)
- except Queue.Empty: pass
+ except Queue.Empty:
+ pass
conn.commit()
for event in self.pending_events:
self.injector.trigger(event)
diff --git a/python/examples/db_ctrl.py b/python/examples/db_ctrl.py
index 04770ce..a263f96 100755
--- a/python/examples/db_ctrl.py
+++ b/python/examples/db_ctrl.py
@@ -40,8 +40,9 @@ else:
elif sys.argv[1] == "insert":
while True:
l = sys.stdin.readline()
- if not l: break
+ if not l:
+ break
conn.execute("INSERT INTO records(description) VALUES (?)", (l.rstrip(),))
conn.commit()
else:
- print("Unrecognised command: %s" % sys.argv[1])
+ print("Unrecognised command: %s" % sys.argv[1])
diff --git a/python/examples/db_recv.py b/python/examples/db_recv.py
index ce27470..8e293ce 100755
--- a/python/examples/db_recv.py
+++ b/python/examples/db_recv.py
@@ -24,6 +24,7 @@ from proton.handlers import MessagingHandler
from proton.reactor import ApplicationEvent, Container, EventInjector
from db_common import Db
+
class Recv(MessagingHandler):
def __init__(self, url, count):
super(Recv, self).__init__(auto_accept=False)
@@ -65,6 +66,7 @@ class Recv(MessagingHandler):
else:
self.accept(event.delivery)
+
parser = optparse.OptionParser(usage="usage: %prog [options]")
parser.add_option("-a", "--address", default="localhost:5672/examples",
help="address from which messages are received (default %default)")
@@ -74,7 +76,5 @@ opts, args = parser.parse_args()
try:
Container(Recv(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/db_send.py b/python/examples/db_send.py
index c07dcc0..2060079 100755
--- a/python/examples/db_send.py
+++ b/python/examples/db_send.py
@@ -32,6 +32,7 @@ from proton.handlers import MessagingHandler
from proton.reactor import ApplicationEvent, Container, EventInjector
from db_common import Db
+
class Send(MessagingHandler):
def __init__(self, url, count):
super(Send, self).__init__()
@@ -65,14 +66,16 @@ class Send(MessagingHandler):
if not self.records.full():
print("loading records...")
self.load_count += 1
- self.db.load(self.records, event=ApplicationEvent("records_loaded", link=self.sender, subject=self.load_count))
+ self.db.load(self.records, event=ApplicationEvent(
+ "records_loaded", link=self.sender, subject=self.load_count))
def on_sendable(self, event):
self.send()
def send(self):
while self.sender.credit and not self.records.empty():
- if not self.keep_sending(): return
+ if not self.keep_sending():
+ return
record = self.records.get(False)
id = record['id']
self.sender.send(Message(id=id, durable=True, body=record['description']), tag=str(id))
@@ -97,6 +100,7 @@ class Send(MessagingHandler):
print("Rechecking for data...")
self.request_records()
+
parser = optparse.OptionParser(usage="usage: %prog [options]",
description="Send messages to the supplied address.")
parser.add_option("-a", "--address", default="localhost:5672/examples",
@@ -107,5 +111,5 @@ opts, args = parser.parse_args()
try:
Container(Send(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/direct_recv.py b/python/examples/direct_recv.py
index 1c6bf36..50551fc 100755
--- a/python/examples/direct_recv.py
+++ b/python/examples/direct_recv.py
@@ -23,6 +23,7 @@ import optparse
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class Recv(MessagingHandler):
def __init__(self, url, count):
super(Recv, self).__init__()
@@ -45,6 +46,7 @@ class Recv(MessagingHandler):
event.connection.close()
self.acceptor.close()
+
parser = optparse.OptionParser(usage="usage: %prog [options]")
parser.add_option("-a", "--address", default="localhost:5672/examples",
help="address from which messages are received (default %default)")
@@ -54,7 +56,5 @@ opts, args = parser.parse_args()
try:
Container(Recv(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/direct_send.py b/python/examples/direct_send.py
index 35bd2f5..8c29f0e 100755
--- a/python/examples/direct_send.py
+++ b/python/examples/direct_send.py
@@ -24,6 +24,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class Send(MessagingHandler):
def __init__(self, url, messages):
super(Send, self).__init__()
@@ -37,7 +38,7 @@ class Send(MessagingHandler):
def on_sendable(self, event):
while event.sender.credit and self.sent < self.total:
- msg = Message(id=(self.sent+1), body={'sequence':(self.sent+1)})
+ msg = Message(id=(self.sent+1), body={'sequence': (self.sent+1)})
event.sender.send(msg)
self.sent += 1
@@ -51,6 +52,7 @@ class Send(MessagingHandler):
def on_disconnected(self, event):
self.sent = self.confirmed
+
parser = optparse.OptionParser(usage="usage: %prog [options]",
description="Send messages to the supplied address.")
parser.add_option("-a", "--address", default="localhost:5672/examples",
@@ -61,4 +63,5 @@ opts, args = parser.parse_args()
try:
Container(Send(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/helloworld.py b/python/examples/helloworld.py
index 7a91aa4..4e2adc9 100755
--- a/python/examples/helloworld.py
+++ b/python/examples/helloworld.py
@@ -23,6 +23,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class HelloWorld(MessagingHandler):
def __init__(self, server, address):
super(HelloWorld, self).__init__()
@@ -42,4 +43,5 @@ class HelloWorld(MessagingHandler):
print(event.message.body)
event.connection.close()
+
Container(HelloWorld("localhost:5672", "examples")).run()
diff --git a/python/examples/helloworld_blocking.py b/python/examples/helloworld_blocking.py
index 5a5ce6d..fb260d5 100755
--- a/python/examples/helloworld_blocking.py
+++ b/python/examples/helloworld_blocking.py
@@ -26,9 +26,8 @@ from proton.handlers import IncomingMessageHandler
conn = BlockingConnection("localhost:5672")
receiver = conn.create_receiver("examples")
sender = conn.create_sender("examples")
-sender.send(Message(body="Hello World!"));
+sender.send(Message(body="Hello World!"))
msg = receiver.receive(timeout=30)
print(msg.body)
receiver.accept()
conn.close()
-
diff --git a/python/examples/helloworld_direct.py b/python/examples/helloworld_direct.py
index 0292abe..4218b53 100755
--- a/python/examples/helloworld_direct.py
+++ b/python/examples/helloworld_direct.py
@@ -23,6 +23,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class HelloWorld(MessagingHandler):
def __init__(self, url):
super(HelloWorld, self).__init__()
@@ -45,4 +46,5 @@ class HelloWorld(MessagingHandler):
def on_connection_closed(self, event):
self.acceptor.close()
+
Container(HelloWorld("localhost:8888/examples")).run()
diff --git a/python/examples/helloworld_direct_tornado.py b/python/examples/helloworld_direct_tornado.py
index a3b017a..2b3bbd2 100755
--- a/python/examples/helloworld_direct_tornado.py
+++ b/python/examples/helloworld_direct_tornado.py
@@ -23,6 +23,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton_tornado import Container
+
class HelloWorld(MessagingHandler):
def __init__(self, url):
super(HelloWorld, self).__init__()
@@ -45,4 +46,5 @@ class HelloWorld(MessagingHandler):
def on_connection_closed(self, event):
self.acceptor.close()
+
Container(HelloWorld("localhost:8888/examples")).run()
diff --git a/python/examples/helloworld_tornado.py b/python/examples/helloworld_tornado.py
index 0781bbb..5604b21 100755
--- a/python/examples/helloworld_tornado.py
+++ b/python/examples/helloworld_tornado.py
@@ -23,6 +23,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton_tornado import Container
+
class HelloWorld(MessagingHandler):
def __init__(self, server, address):
super(HelloWorld, self).__init__()
@@ -42,4 +43,5 @@ class HelloWorld(MessagingHandler):
print(event.message.body)
event.connection.close()
+
Container(HelloWorld("localhost:5672", "examples")).run()
diff --git a/python/examples/proton_server.py b/python/examples/proton_server.py
index 9351f55..6dfd807 100755
--- a/python/examples/proton_server.py
+++ b/python/examples/proton_server.py
@@ -22,6 +22,7 @@ from proton import Message
from proton.reactor import Container
from proton.handlers import MessagingHandler
+
class Server(MessagingHandler):
def __init__(self, host, address):
super(Server, self).__init__()
@@ -34,7 +35,8 @@ class Server(MessagingHandler):
self.on_request(event.message.body, event.message.reply_to)
def on_connection_close(self, endpoint, error):
- if error: print("Closed due to %s" % error)
+ if error:
+ print("Closed due to %s" % error)
self.conn.close()
def run(self):
@@ -48,4 +50,3 @@ class Server(MessagingHandler):
def on_request(self, request, reply_to):
pass
-
diff --git a/python/examples/queue_browser.py b/python/examples/queue_browser.py
index 34d2377..7f659f0 100755
--- a/python/examples/queue_browser.py
+++ b/python/examples/queue_browser.py
@@ -22,6 +22,7 @@ from __future__ import print_function
from proton.reactor import Container, Copy
from proton.handlers import MessagingHandler
+
class Recv(MessagingHandler):
def __init__(self):
super(Recv, self).__init__()
@@ -35,9 +36,8 @@ class Recv(MessagingHandler):
if event.receiver.queued == 0 and event.receiver.drained:
event.connection.close()
+
try:
Container(Recv()).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/recurring_timer.py b/python/examples/recurring_timer.py
index b59dbe1..58f3ffd 100755
--- a/python/examples/recurring_timer.py
+++ b/python/examples/recurring_timer.py
@@ -21,6 +21,7 @@
from __future__ import print_function
from proton.reactor import Container, Handler
+
class Recurring(Handler):
def __init__(self, period):
self.period = period
@@ -33,11 +34,10 @@ class Recurring(Handler):
print("Tick...")
self.container.schedule(self.period, self)
+
try:
container = Container(Recurring(1.0))
container.run()
except KeyboardInterrupt:
container.stop()
print()
-
-
diff --git a/python/examples/recurring_timer_tornado.py b/python/examples/recurring_timer_tornado.py
index a9a7579..ff4c078 100755
--- a/python/examples/recurring_timer_tornado.py
+++ b/python/examples/recurring_timer_tornado.py
@@ -22,6 +22,7 @@ from __future__ import print_function
from proton.reactor import Handler
from proton_tornado import Container
+
class Recurring(Handler):
def __init__(self, period):
self.period = period
@@ -34,11 +35,10 @@ class Recurring(Handler):
print("Tick...")
self.container.schedule(self.period, self)
+
try:
container = Container(Recurring(1.0))
container.run()
except KeyboardInterrupt:
container.stop()
print()
-
-
diff --git a/python/examples/selected_recv.py b/python/examples/selected_recv.py
index 0f9ded1..43b576b 100755
--- a/python/examples/selected_recv.py
+++ b/python/examples/selected_recv.py
@@ -24,6 +24,7 @@ from proton import Url
from proton.reactor import Container, Selector
from proton.handlers import MessagingHandler
+
class Recv(MessagingHandler):
def __init__(self, url, count):
super(Recv, self).__init__()
@@ -42,6 +43,7 @@ class Recv(MessagingHandler):
event.receiver.close()
event.connection.close()
+
parser = optparse.OptionParser(usage="usage: %prog [options]")
parser.add_option("-a", "--address", default="localhost:5672/examples",
help="address from which messages are received (default %default)")
@@ -51,7 +53,5 @@ opts, args = parser.parse_args()
try:
Container(Recv(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/server.py b/python/examples/server.py
index 5d7650a..eb0d66e 100755
--- a/python/examples/server.py
+++ b/python/examples/server.py
@@ -24,6 +24,7 @@ from proton import Message, Url
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class Server(MessagingHandler):
def __init__(self, url, address):
super(Server, self).__init__()
@@ -40,7 +41,8 @@ class Server(MessagingHandler):
def on_message(self, event):
print("Received", event.message)
self.server.send(Message(address=event.message.reply_to, body=event.message.body.upper(),
- correlation_id=event.message.correlation_id))
+ correlation_id=event.message.correlation_id))
+
parser = optparse.OptionParser(usage="usage: %prog [options]")
parser.add_option("-a", "--address", default="localhost:5672/examples",
@@ -51,7 +53,5 @@ url = Url(opts.address)
try:
Container(Server(url, url.path)).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/server_direct.py b/python/examples/server_direct.py
index 71f73e9..8cc7d9c 100755
--- a/python/examples/server_direct.py
+++ b/python/examples/server_direct.py
@@ -25,6 +25,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class Server(MessagingHandler):
def __init__(self, url):
super(Server, self).__init__()
@@ -58,9 +59,8 @@ class Server(MessagingHandler):
sender.send(Message(address=event.message.reply_to, body=event.message.body.upper(),
correlation_id=event.message.correlation_id))
+
try:
Container(Server("0.0.0.0:8888")).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/server_tx.py b/python/examples/server_tx.py
index 51e734c..731f9eb 100755
--- a/python/examples/server_tx.py
+++ b/python/examples/server_tx.py
@@ -23,6 +23,7 @@ from proton import Message
from proton.reactor import Container
from proton.handlers import MessagingHandler, TransactionHandler
+
class TxRequest(TransactionHandler):
def __init__(self, response, sender, request_delivery):
super(TxRequest, self).__init__()
@@ -71,9 +72,8 @@ class TxServer(MessagingHandler):
if event.connection.remote_offered_capabilities and 'ANONYMOUS-RELAY' in event.connection.remote_offered_capabilities:
self.relay = self.container.create_sender(self.conn, None)
+
try:
Container(TxServer("localhost:5672", "examples")).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/simple_recv.py b/python/examples/simple_recv.py
index 5322500..52724a3 100755
--- a/python/examples/simple_recv.py
+++ b/python/examples/simple_recv.py
@@ -23,6 +23,7 @@ import optparse
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class Recv(MessagingHandler):
def __init__(self, url, count):
super(Recv, self).__init__()
@@ -44,6 +45,7 @@ class Recv(MessagingHandler):
event.receiver.close()
event.connection.close()
+
parser = optparse.OptionParser(usage="usage: %prog [options]")
parser.add_option("-a", "--address", default="localhost:5672/examples",
help="address from which messages are received (default %default)")
@@ -53,7 +55,5 @@ opts, args = parser.parse_args()
try:
Container(Recv(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/simple_send.py b/python/examples/simple_send.py
index 7717a16..2cff11c 100755
--- a/python/examples/simple_send.py
+++ b/python/examples/simple_send.py
@@ -24,6 +24,7 @@ from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container
+
class Send(MessagingHandler):
def __init__(self, url, messages):
super(Send, self).__init__()
@@ -37,7 +38,7 @@ class Send(MessagingHandler):
def on_sendable(self, event):
while event.sender.credit and self.sent < self.total:
- msg = Message(id=(self.sent+1), body={'sequence':(self.sent+1)})
+ msg = Message(id=(self.sent+1), body={'sequence': (self.sent+1)})
event.sender.send(msg)
self.sent += 1
@@ -50,6 +51,7 @@ class Send(MessagingHandler):
def on_disconnected(self, event):
self.sent = self.confirmed
+
parser = optparse.OptionParser(usage="usage: %prog [options]",
description="Send messages to the supplied address.")
parser.add_option("-a", "--address", default="localhost:5672/examples",
@@ -60,4 +62,5 @@ opts, args = parser.parse_args()
try:
Container(Send(opts.address, opts.messages)).run()
-except KeyboardInterrupt: pass
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/sync_client.py b/python/examples/sync_client.py
index 7b86e29..9a395ae 100755
--- a/python/examples/sync_client.py
+++ b/python/examples/sync_client.py
@@ -43,13 +43,12 @@ url = Url(opts.address)
client = SyncRequestResponse(BlockingConnection(url, timeout=opts.timeout), url.path)
try:
- REQUESTS= ["Twas brillig, and the slithy toves",
- "Did gire and gymble in the wabe.",
- "All mimsy were the borogroves,",
- "And the mome raths outgrabe."]
+ REQUESTS = ["Twas brillig, and the slithy toves",
+ "Did gire and gymble in the wabe.",
+ "All mimsy were the borogroves,",
+ "And the mome raths outgrabe."]
for request in REQUESTS:
response = client.call(Message(body=request))
print("%s => %s" % (request, response.body))
finally:
client.connection.close()
-
diff --git a/python/examples/test_examples.py b/python/examples/test_examples.py
index 8df68ec..d46ab01 100644
--- a/python/examples/test_examples.py
+++ b/python/examples/test_examples.py
@@ -82,7 +82,7 @@ class ExamplesTest(unittest.TestCase):
actual = [remove_unicode_prefix(l.strip()) for l in r.stdout]
expected_py2 = ["{'sequence': int32(%i)}" % (i+1,) for i in range(100)]
expected_py3 = ["{'sequence': %i}" % (i+1,) for i in range(100)]
- self.assertIn(actual,[expected_py2, expected_py3])
+ self.assertIn(actual, [expected_py2, expected_py3])
def test_client_server(self, client=['client.py'], server=['server.py'], sleep=0):
with Popen(server) as s:
@@ -109,10 +109,12 @@ class ExamplesTest(unittest.TestCase):
self.test_client_server(client=['sync_client.py'], server=['server_tx.py'])
def test_client_server_direct(self):
- self.test_client_server(client=['client.py', '-a', 'localhost:8888/examples'], server=['server_direct.py'], sleep=0.5)
+ self.test_client_server(client=['client.py', '-a', 'localhost:8888/examples'],
+ server=['server_direct.py'], sleep=0.5)
def test_sync_client_server_direct(self):
- self.test_client_server(client=['sync_client.py', '-a', 'localhost:8888/examples'], server=['server_direct.py'], sleep=0.5)
+ self.test_client_server(client=['sync_client.py', '-a', 'localhost:8888/examples'],
+ server=['server_direct.py'], sleep=0.5)
def test_db_send_recv(self):
self.maxDiff = None
@@ -154,7 +156,7 @@ class ExamplesTest(unittest.TestCase):
actual = [remove_unicode_prefix(l.strip()) for l in r.stdout]
expected_py2 = ["{'sequence': int32(%i)}" % (i+1,) for i in range(100)]
expected_py3 = ["{'sequence': %i}" % (i+1,) for i in range(100)]
- self.assertIn(actual,[expected_py2, expected_py3])
+ self.assertIn(actual, [expected_py2, expected_py3])
def test_direct_send_simple_recv(self):
with Popen(['direct_send.py', '-a', 'localhost:8888']):
diff --git a/python/examples/tx_recv.py b/python/examples/tx_recv.py
index 4baddcf..bea05ab 100755
--- a/python/examples/tx_recv.py
+++ b/python/examples/tx_recv.py
@@ -24,6 +24,7 @@ from proton import Url
from proton.reactor import Container
from proton.handlers import MessagingHandler, TransactionHandler
+
class TxRecv(MessagingHandler, TransactionHandler):
def __init__(self, url, messages, batch_size):
super(TxRecv, self).__init__(prefetch=0, auto_accept=False)
@@ -63,6 +64,7 @@ class TxRecv(MessagingHandler, TransactionHandler):
def on_disconnected(self, event):
self.current_batch = 0
+
parser = optparse.OptionParser(usage="usage: %prog [options]")
parser.add_option("-a", "--address", default="localhost:5672/examples",
help="address from which messages are received (default %default)")
@@ -74,7 +76,5 @@ opts, args = parser.parse_args()
try:
Container(TxRecv(opts.address, opts.messages, opts.batch_size)).run()
-except KeyboardInterrupt: pass
-
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/tx_recv_interactive.py b/python/examples/tx_recv_interactive.py
index c38f651..63bc76b 100755
--- a/python/examples/tx_recv_interactive.py
+++ b/python/examples/tx_recv_interactive.py
@@ -24,6 +24,7 @@ import threading
from proton.reactor import ApplicationEvent, Container, EventInjector
from proton.handlers import MessagingHandler, TransactionHandler
+
class TxRecv(MessagingHandler, TransactionHandler):
def __init__(self):
super(TxRecv, self).__init__(prefetch=0, auto_accept=False)
@@ -65,12 +66,13 @@ class TxRecv(MessagingHandler, TransactionHandler):
self.receiver.close()
c.close()
+
try:
reactor = Container(TxRecv())
events = EventInjector()
reactor.selectable(events)
thread = threading.Thread(target=reactor.run)
- thread.daemon=True
+ thread.daemon = True
thread.start()
print("Enter 'fetch', 'commit' or 'abort'")
@@ -80,6 +82,5 @@ try:
events.trigger(ApplicationEvent(line.strip()))
else:
break
-except KeyboardInterrupt: pass
-
-
+except KeyboardInterrupt:
+ pass
diff --git a/python/examples/tx_send.py b/python/examples/tx_send.py
index bda6780..3d53be5 100755
--- a/python/examples/tx_send.py
+++ b/python/examples/tx_send.py
@@ -24,6 +24,7 @@ from proton import Message, Url
from proton.reactor import Container
from proton.handlers import MessagingHandler, TransactionHandler
+
class TxSend(MessagingHandler, TransactionHandler):
def __init__(self, url, messages, batch_size):
super(TxSend, self).__init__()
@@ -51,7 +52,7 @@ class TxSend(MessagingHandler, TransactionHandler):
def send(self):
while self.transaction and self.sender.credit and (self.committed + self.current_batch) < self.total:
seq = self.committed + self.current_batch + 1
- msg = Message(id=seq, body={'sequence':seq})
+ msg = Message(id=seq, body={'sequence': seq})
self.transaction.send(self.sender, msg)
self.current_batch += 1
if self.current_batch == self.batch_size:
@@ -74,6 +75,7 @@ class TxSend(MessagingHandler, TransactionHandler):
def on_disconnected(self, event):
self.current_batch = 0
+
parser = optparse.OptionParser(usage="usage: %prog [options]",
description="Send messages transactionally to the supplied address.")
parser.add_option("-a", "--address", default="localhost:5672/examples",
@@ -86,4 +88,5 @@ opts, args = parser.parse_args()
try:
Container(TxSend(opts.address, opts.messages, opts.batch_size)).run()
-except KeyboardInterrupt: pass
+except KeyboardInterrupt:
+ pass
diff --git a/python/proton/_common.py b/python/proton/_common.py
index d64f408..3715c6a 100644
--- a/python/proton/_common.py
+++ b/python/proton/_common.py
@@ -77,6 +77,7 @@ def unicode2utf8(string):
# Anything else illegal - specifically python3 bytes
raise TypeError("Unrecognized string type: %r (%s)" % (string, type(string)))
+
def utf82unicode(string):
"""Convert C strings returned from proton-c into python unicode"""
if string is None:
diff --git a/python/proton/_compat.py b/python/proton/_compat.py
index 7380334..2235d35 100644
--- a/python/proton/_compat.py
+++ b/python/proton/_compat.py
@@ -27,11 +27,11 @@ import sys
try:
import Queue as queue
except ImportError:
- import queue # type: ignore
+ import queue # type: ignore
try:
from urlparse import urlparse, urlunparse
- from urllib import quote, unquote # type: ignore
+ from urllib import quote, unquote # type: ignore
except ImportError:
from urllib.parse import urlparse, urlunparse, quote, unquote
@@ -59,7 +59,7 @@ if PY3:
else:
# the raise syntax will cause a parse error in Py3, so 'sneak' in a
# definition that won't cause the parser to barf
- exec ("""def raise_(t, v=None, tb=None):
+ exec("""def raise_(t, v=None, tb=None):
raise t, v, tb
""")
diff --git a/python/proton/_condition.py b/python/proton/_condition.py
index 6916bee..338c776 100644
--- a/python/proton/_condition.py
+++ b/python/proton/_condition.py
@@ -68,10 +68,11 @@ class Condition:
if x])
def __eq__(self, o):
- if not isinstance(o, Condition): return False
+ if not isinstance(o, Condition):
+ return False
return self.name == o.name and \
- self.description == o.description and \
- self.info == o.info
+ self.description == o.description and \
+ self.info == o.info
def obj2cond(obj, cond):
diff --git a/python/proton/_data.py b/python/proton/_data.py
index e324e64..7cfe0bd 100644
--- a/python/proton/_data.py
+++ b/python/proton/_data.py
@@ -70,7 +70,7 @@ class UnmappedType:
class ulong(long):
"""
The ulong AMQP type.
-
+
An unsigned 64 bit integer in the range :math:`0` to :math:`2^{64} - 1` inclusive.
"""
@@ -86,7 +86,7 @@ class ulong(long):
class timestamp(long):
"""
The timestamp AMQP type.
-
+
An absolute point in time, represented by a signed 64 bit value measuring
milliseconds since the epoch. This value is encoded using the Unix ``time_t``
[IEEE1003] encoding of UTC, but with a precision of milliseconds. For
@@ -100,7 +100,7 @@ class timestamp(long):
class symbol(unicode):
"""
The symbol AMQP type.
-
+
Symbolic values from a constrained domain, represented by a sequence of ASCII characters.
"""
@@ -111,7 +111,7 @@ class symbol(unicode):
class char(unicode):
"""
The char AMQP type.
-
+
A 32 bit UTF-32BE encoded Unicode character.
"""
@@ -122,7 +122,7 @@ class char(unicode):
class byte(int):
"""
The byte AMQP type.
-
+
An 8 bit signed integer in the range :math:`-(2^7)` to :math:`2^7 - 1` inclusive.
"""
@@ -133,7 +133,7 @@ class byte(int):
class short(int):
"""
The short AMQP type.
-
+
A 16 bit signed integer in the range :math:`-(2^{15})` to :math:`2^{15} - 1` inclusive.
"""
@@ -144,7 +144,7 @@ class short(int):
class int32(int):
"""
The signed int AMQP type.
-
+
A 32 bit signed integer in the range :math:`-(2^{31})` to :math:`2^{31} - 1` inclusive.
"""
@@ -155,7 +155,7 @@ class int32(int):
class ubyte(int):
"""
The unsigned byte AMQP type.
-
+
An 8 bit unsigned integer in the range :math:`0` to :math:`2^8 - 1` inclusive.
"""
@@ -171,7 +171,7 @@ class ubyte(int):
class ushort(int):
"""
The unsigned short AMQP type.
-
+
A 16 bit unsigned integer in the range :math:`0` to :math:`2^{16} - 1` inclusive.
"""
@@ -187,7 +187,7 @@ class ushort(int):
class uint(long):
"""
The unsigned int AMQP type.
-
+
A 32 bit unsigned integer in the range :math:`0` to :math:`2^{32} - 1` inclusive.
"""
@@ -203,7 +203,7 @@ class uint(long):
class float32(float):
"""
The float AMQP type.
-
+
A 32 bit floating point number (IEEE 754-2008 binary32).
"""
@@ -214,7 +214,7 @@ class float32(float):
class decimal32(int):
"""
The decimal32 AMQP type.
-
+
A 32 bit decimal floating point number (IEEE 754-2008 decimal32).
"""
@@ -225,7 +225,7 @@ class decimal32(int):
class decimal64(long):
"""
The decimal64 AMQP type.
-
+
A 64 bit decimal floating point number (IEEE 754-2008 decimal64).
"""
@@ -236,7 +236,7 @@ class decimal64(long):
class decimal128(bytes):
"""
The decimal128 AMQP type.
-
+
A 128-bit decimal floating-point number (IEEE 754-2008 decimal128).
"""
@@ -303,7 +303,7 @@ class Array(object):
def __eq__(self, o):
if isinstance(o, Array):
return self.descriptor == o.descriptor and \
- self.type == o.type and self.elements == o.elements
+ self.type == o.type and self.elements == o.elements
else:
return False
@@ -334,6 +334,7 @@ def _check_is_symbol_or_ulong(s, raise_on_error=True):
class RestrictedKeyDict(dict):
"""Parent class for :class:`PropertyDict` and :class:`AnnotationDict`"""
+
def __init__(self, validation_fn, e=None, raise_on_error=True, **kwargs):
super(RestrictedKeyDict, self).__init__()
self.validation_fn = validation_fn
@@ -401,6 +402,7 @@ class PropertyDict(RestrictedKeyDict):
:type raise_on_error: ``bool``
:param kwargs: Keyword args for initializing a ``dict`` of the form key1=val1, key2=val2, ...
"""
+
def __init__(self, e=None, raise_on_error=True, **kwargs):
super(PropertyDict, self).__init__(_check_is_symbol, e, raise_on_error, **kwargs)
@@ -445,6 +447,7 @@ class AnnotationDict(RestrictedKeyDict):
:type raise_on_error: ``bool``
:param kwargs: Keyword args for initializing a ``dict`` of the form key1=val1, key2=val2, ...
"""
+
def __init__(self, e=None, raise_on_error=True, **kwargs):
super(AnnotationDict, self).__init__(_check_is_symbol_or_ulong, e, raise_on_error, **kwargs)
@@ -483,6 +486,7 @@ class SymbolList(list):
an error.
:type raise_on_error: ``bool``
"""
+
def __init__(self, t=None, raise_on_error=True):
super(SymbolList, self).__init__()
self.raise_on_error = raise_on_error
@@ -639,7 +643,7 @@ class Data:
def type_name(amqptype):
"""
Return a string name for an AMQP type.
-
+
:param type: Numeric Proton AMQP type (`enum pn_type_t`)
:type type: integer
:rtype: String describing the AMQP type with numeric value `amqptype`
@@ -1412,7 +1416,7 @@ class Data:
"""
Copy the contents of another pn_data_t object. Any values in the
data object will be lost.
-
+
:param src: The source object from which to copy
:type src: :class:`Data`
:raise: :exc:`DataException` if there is a Proton error.
@@ -1566,7 +1570,8 @@ class Data:
"""
count, described, type = self.get_array()
- if type is None: return None
+ if type is None:
+ return None
if self.enter():
try:
if described:
@@ -1680,7 +1685,8 @@ class Data:
def get_object(self):
type = self.type()
- if type is None: return None
+ if type is None:
+ return None
getter = self.get_mappings.get(type)
if getter:
return getter(self)
diff --git a/python/proton/_delivery.py b/python/proton/_delivery.py
index 0f871cf..8b7a693 100644
--- a/python/proton/_delivery.py
+++ b/python/proton/_delivery.py
@@ -74,7 +74,7 @@ class Disposition(object):
"""
A non terminal state indicating how much (if any) message data
has been received for a delivery.
- """
+ """
ACCEPTED = DispositionType(PN_ACCEPTED, "ACCEPTED")
"""
@@ -107,7 +107,6 @@ class Disposition(object):
delivery being settled.
"""
-
def __init__(self, impl, local):
self._impl = impl
self.local = local
@@ -121,13 +120,13 @@ class Disposition(object):
Get the type of this disposition object.
Defined values are:
-
+
* :const:`RECEIVED`
* :const:`ACCEPTED`
* :const:`REJECTED`
* :const:`RELEASED`
* :const:`MODIFIED`
-
+
:type: ``str``
"""
return DispositionType.get(pn_disposition_type(self._impl))
@@ -269,7 +268,7 @@ class Delivery(Wrapper):
"""
A non terminal state indicating how much (if any) message data
has been received for a delivery.
- """
+ """
ACCEPTED = Disposition.ACCEPTED
"""
@@ -302,7 +301,6 @@ class Delivery(Wrapper):
delivery being settled.
"""
-
@staticmethod
def wrap(impl):
if impl is None:
diff --git a/python/proton/_endpoints.py b/python/proton/_endpoints.py
index c5309ff..acbc745 100644
--- a/python/proton/_endpoints.py
+++ b/python/proton/_endpoints.py
@@ -88,7 +88,7 @@ class Endpoint(object):
but also the last known state of the remote endpoint.
"""
- LOCAL_UNINIT = PN_LOCAL_UNINIT
+ LOCAL_UNINIT = PN_LOCAL_UNINIT
""" The local endpoint state is uninitialized. """
REMOTE_UNINIT = PN_REMOTE_UNINIT
@@ -521,7 +521,7 @@ class Connection(Wrapper, Endpoint):
additional error details can be obtained using this property. The
returned value is the error code defined by Proton in ``pn_error_t``
(see ``error.h``).
-
+
:type: ``int``
"""
return pn_error_code(pn_connection_error(self._impl))
@@ -682,7 +682,7 @@ class Session(Wrapper, Endpoint):
will be set. This may be called without calling
:meth:`open`, in this case it is equivalent to calling
:meth:`open` followed by :meth:`close`.
-
+
"""
self._update_cond()
pn_session_close(self._impl)
@@ -786,7 +786,8 @@ class Link(Wrapper, Endpoint):
@staticmethod
def wrap(impl):
- if impl is None: return None
+ if impl is None:
+ return None
if pn_link_is_sender(impl):
return Sender(impl)
else:
@@ -1243,7 +1244,6 @@ class Link(Wrapper, Endpoint):
"""
return dat2obj(pn_link_remote_properties(self._impl))
-
def _get_properties(self):
return self._properties_dict
@@ -1391,7 +1391,7 @@ class Terminus(object):
A source or target for messages.
"""
UNSPECIFIED = PN_UNSPECIFIED
- """A nonexistent terminus, may used as a source or target."""
+ """A nonexistent terminus, may used as a source or target."""
SOURCE = PN_SOURCE
"""A source of messages."""
TARGET = PN_TARGET
@@ -1549,7 +1549,7 @@ class Terminus(object):
def outcomes(self):
"""
Outcomes of the source or target.
-
+
:type: :class:`Data` containing an array of :class:`symbol`.
"""
return Data(pn_terminus_outcomes(self._impl))
diff --git a/python/proton/_events.py b/python/proton/_events.py
index f1f54e7..df1f664 100644
--- a/python/proton/_events.py
+++ b/python/proton/_events.py
@@ -194,7 +194,6 @@ class Event(EventBase):
TIMER_TASK = _core(PN_TIMER_TASK, "on_timer_task")
"""A timer event has occurred."""
-
CONNECTION_INIT = _core(PN_CONNECTION_INIT, "on_connection_init")
"""
The connection has been created. This is the first event that
@@ -245,7 +244,6 @@ class Event(EventBase):
for a connection.
"""
-
SESSION_INIT = _core(PN_SESSION_INIT, "on_session_init")
"""
The session has been created. This is the first event that will
@@ -283,7 +281,6 @@ class Event(EventBase):
for a session.
"""
-
LINK_INIT = _core(PN_LINK_INIT, "on_link_init")
"""
The link has been created. This is the first event that will ever
@@ -339,14 +336,12 @@ class Event(EventBase):
link. Events of this type point to the relevant link.
"""
-
DELIVERY = _core(PN_DELIVERY, "on_delivery")
"""
A delivery has been created or updated. Events of this type point
to the relevant delivery.
"""
-
TRANSPORT = _core(PN_TRANSPORT, "on_transport")
"""
The transport has new data to read and/or write. Events of this
@@ -379,7 +374,6 @@ class Event(EventBase):
closed. Events of this type point to the relevant transport.
"""
-
# These events are now internal events in the python code
REACTOR_INIT = _internal("reactor_init")
"""
diff --git a/python/proton/_handlers.py b/python/proton/_handlers.py
index baae429..41df67c 100644
--- a/python/proton/_handlers.py
+++ b/python/proton/_handlers.py
@@ -160,6 +160,7 @@ class Acking(object):
"""
A class containing methods for handling received messages.
"""
+
def accept(self, delivery):
"""
Accepts a received message.
@@ -245,7 +246,8 @@ class IncomingMessageHandler(Handler, Acking):
def on_delivery(self, event):
dlv = event.delivery
- if not dlv.link.is_receiver: return
+ if not dlv.link.is_receiver:
+ return
if dlv.aborted:
self.on_aborted(event)
dlv.settle()
@@ -1142,7 +1144,8 @@ class PythonIO:
reactor = event.reactor
# check if we are still quiesced, other handlers of
# on_reactor_quiesced could have produced events to process
- if not reactor.quiesced: return
+ if not reactor.quiesced:
+ return
reading = []
writing = []
@@ -1162,7 +1165,8 @@ class PythonIO:
timeout = deadline - time.time()
else:
timeout = reactor.timeout
- if timeout < 0: timeout = 0
+ if timeout < 0:
+ timeout = 0
timeout = min(timeout, reactor.timeout)
readable, writable, _ = IO.select(reading, writing, [], timeout)
@@ -1346,7 +1350,7 @@ class IOHandler(Handler):
def update(transport, selectable, now):
try:
capacity = transport.capacity()
- selectable.reading = capacity>0
+ selectable.reading = capacity > 0
except:
if transport.closed:
selectable.terminate()
@@ -1354,7 +1358,7 @@ class IOHandler(Handler):
transport._selectable = None
try:
pending = transport.pending()
- selectable.writing = pending>0
+ selectable.writing = pending > 0
except:
if transport.closed:
selectable.terminate()
diff --git a/python/proton/_io.py b/python/proton/_io.py
index bda12db..20a5a44 100644
--- a/python/proton/_io.py
+++ b/python/proton/_io.py
@@ -28,6 +28,7 @@ from ._compat import socket_errno
PN_INVALID_SOCKET = -1
+
class IO(object):
@staticmethod
@@ -144,9 +145,10 @@ class IO(object):
return IO.select(r, w, w, timeout)
t = max(0, min(timeout, self._deadline - now))
- if len(r)==0 and len(w)==0:
- if t > 0: IO.sleep(t)
- return ([],[],[])
+ if len(r) == 0 and len(w) == 0:
+ if t > 0:
+ IO.sleep(t)
+ return ([], [], [])
return IO.select(r, w, w, t)
diff --git a/python/proton/_message.py b/python/proton/_message.py
index ed791c9..c13ac53 100644
--- a/python/proton/_message.py
+++ b/python/proton/_message.py
@@ -548,9 +548,11 @@ class Message(object):
:rtype: :class:`Delivery`
"""
- if link.is_sender: return None
+ if link.is_sender:
+ return None
dlv = link.current
- if not dlv or dlv.partial: return None
+ if not dlv or dlv.partial:
+ return None
dlv.encoded = link.recv(dlv.pending)
link.advance()
# the sender has already forgotten about the delivery, so we might
@@ -568,5 +570,6 @@ class Message(object):
"reply_to_group_id", "instructions", "annotations",
"properties", "body"):
value = getattr(self, attr)
- if value: props.append("%s=%r" % (attr, value))
+ if value:
+ props.append("%s=%r" % (attr, value))
return "Message(%s)" % ", ".join(props)
diff --git a/python/proton/_reactor.py b/python/proton/_reactor.py
index fdffbaf..d11afd4 100644
--- a/python/proton/_reactor.py
+++ b/python/proton/_reactor.py
@@ -31,11 +31,11 @@ import uuid
from cproton import PN_PYREF, PN_ACCEPTED, PN_EVENT_NONE
-from ._delivery import Delivery
+from ._delivery import Delivery
from ._endpoints import Connection, Endpoint, Link, Session, Terminus
from ._exceptions import SSLUnavailable
from ._data import Described, symbol, ulong
-from ._message import Message
+from ._message import Message
from ._transport import Transport, SSL, SSLDomain
from ._url import Url
from ._common import isstring, unicode2utf8, utf82unicode
@@ -100,6 +100,7 @@ class TimerSelectable(Selectable):
self.deadline = self._reactor.timer_deadline
self.update()
+
class Reactor(object):
def __init__(self, *handlers, **kwargs):
@@ -177,7 +178,8 @@ class Reactor(object):
# TODO: Why do we timeout like this?
self.timeout = 3.14159265359
self.start()
- while self.process(): pass
+ while self.process():
+ pass
self.stop()
self.process()
# TODO: This isn't correct if we ever run again
@@ -195,7 +197,7 @@ class Reactor(object):
self._selectable = TimerSelectable(self)
self._selectable.deadline = self.timer_deadline
# TODO set up fd to read for wakeups - but problematic on windows
- #self._selectable.fileno(self._wakeup[0])
+ # self._selectable.fileno(self._wakeup[0])
#self._selectable.reading = True
self.update(self._selectable)
@@ -412,7 +414,7 @@ class EventInjector(object):
def on_selectable_init(self, event):
sel = event.context
- #sel.fileno(self.fileno())
+ # sel.fileno(self.fileno())
sel.reading = True
sel.update()
@@ -492,11 +494,11 @@ class Transaction(object):
a call to :meth:`proton.reactor.Container.declare_transaction`.
To send messages under this transaction, use :meth:`send`.
-
+
To receive messages under this transaction, call :meth:`accept` once the
message is received (typically from the
:meth:`proton.handlers.MessagingHandler.on_message` callback).
-
+
To discharge the transaction, call either :meth:`commit`
(for a successful transaction), or :meth:`abort` (for a failed transaction).
"""
@@ -633,6 +635,7 @@ class AtMostOnce(LinkOption):
setting the sender link settle mode to :const:`proton.Link.SND_SETTLED`
(ie pre-settled).
"""
+
def apply(self, link):
"""
Set the at-most-once delivery semantics on the link.
@@ -650,6 +653,7 @@ class AtLeastOnce(LinkOption):
and the receiver link settle mode to :const:`proton.Link.RCV_FIRST`. This
forces the receiver to settle all messages once they are successfully received.
"""
+
def apply(self, link):
"""
Set the at-least-once delivery semantics on the link.
@@ -665,6 +669,7 @@ class SenderOption(LinkOption):
"""
Abstract class for sender options.
"""
+
def apply(self, sender):
"""
Set the option on the sender.
@@ -681,6 +686,7 @@ class ReceiverOption(LinkOption):
"""
Abstract class for receiver options
"""
+
def apply(self, receiver):
"""
Set the option on the receiver.
@@ -702,6 +708,7 @@ class DynamicNodeProperties(LinkOption):
:param props: A map of link options to be applied to a link.
:type props: ``dict``
"""
+
def __init__(self, props={}):
self.properties = {}
for k in props:
@@ -731,6 +738,7 @@ class Filter(ReceiverOption):
containing the filter name, and the value a filter string.
:type filter_set: ``dict``
"""
+
def __init__(self, filter_set={}):
self.filter_set = filter_set
@@ -755,7 +763,8 @@ class Selector(Filter):
"""
def __init__(self, value, name='selector'):
- super(Selector, self).__init__({symbol(name): Described(symbol('apache.org:selector-filter:string'), utf82unicode(value))})
+ super(Selector, self).__init__({symbol(name): Described(
+ symbol('apache.org:selector-filter:string'), utf82unicode(value))})
class DurableSubscription(ReceiverOption):
@@ -765,6 +774,7 @@ class DurableSubscription(ReceiverOption):
to :const:`proton.Terminus.DELIVERIES` and the source expiry policy to
:const:`proton.Terminus.EXPIRE_NEVER`.
"""
+
def apply(self, receiver):
"""
Set durability on the specified receiver.
@@ -783,6 +793,7 @@ class Move(ReceiverOption):
receivers. This is achieved by setting the receiver source distribution
mode to :const:`proton.Terminus.DIST_MODE_MOVE`.
"""
+
def apply(self, receiver):
"""
Set message move semantics on the specified receiver.
@@ -800,6 +811,7 @@ class Copy(ReceiverOption):
are. This is achieved by setting the receiver source distribution mode to
:const:`proton.Terminus.DIST_MODE_COPY`.
"""
+
def apply(self, receiver):
"""
Set message copy semantics on the specified receiver.
@@ -814,9 +826,11 @@ def _apply_link_options(options, link):
if options:
if isinstance(options, list):
for o in options:
- if o.test(link): o.apply(link)
+ if o.test(link):
+ o.apply(link)
else:
- if options.test(link): options.apply(link)
+ if options.test(link):
+ options.apply(link)
def _create_session(connection, handler=None):
@@ -1030,7 +1044,7 @@ class _Connector(Handler):
self._connect_sequence = ((delay, url) for delay in delay_iter(max_tries=1) for url in self.address)
else:
self._connect_sequence = ((delay, url) for delay in self.reconnect for url in self.address)
- _, url = next(self._connect_sequence) # Ignore delay as we assume first delay must be 0
+ _, url = next(self._connect_sequence) # Ignore delay as we assume first delay must be 0
self._connect(event.connection, url)
def on_connection_remote_open(self, event):
@@ -1040,10 +1054,11 @@ class _Connector(Handler):
elif self.reconnect:
self._connect_sequence = ((delay, url) for delay in self.reconnect for url in self.address)
else:
- self._connect_sequence = None # Help take out the garbage
+ self._connect_sequence = None # Help take out the garbage
def on_transport_closed(self, event):
if self.connection is None:
+
return
if not self.connection.state & Endpoint.LOCAL_ACTIVE:
@@ -1088,6 +1103,7 @@ class SSLConfig(object):
self.client.set_trusted_ca_db(certificate_db)
self.server.set_trusted_ca_db(certificate_db)
+
def _find_config_file():
confname = 'connect.json'
confpath = ['.', os.path.expanduser('~/.config/messaging'), '/etc/messaging']
@@ -1097,6 +1113,7 @@ def _find_config_file():
return f
return None
+
def _get_default_config():
conf = os.environ.get('MESSAGING_CONNECT_FILE') or _find_config_file()
if conf and os.path.isfile(conf):
@@ -1107,24 +1124,27 @@ def _get_default_config():
else:
return {}
+
def _strip_json_comments(json_text):
"""This strips c-style comments from text, taking into account '/*comments*/' and '//comments'
nested inside a string etc."""
def replacer(match):
s = match.group(0)
if s.startswith('/'):
- return " " # note: a space and not an empty string
+ return " " # note: a space and not an empty string
else:
return s
pattern = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE)
return re.sub(pattern, replacer, json_text)
+
def _get_default_port_for_scheme(scheme):
if scheme == 'amqps':
return 5671
else:
return 5672
+
class Container(Reactor):
"""
A representation of the AMQP concept of a 'container', which
@@ -1169,7 +1189,7 @@ class Container(Reactor):
To use SSL/TLS for encryption (when an ``amqps`` URL scheme is used), the above
configuration file must contain a ``tls`` submap containing the following
configuration entries (See :class:`proton.SSLDomain` for details):
-
+
* ``ca``: Path to a database of trusted CAs that the server will advertise.
* ``cert``: Path to a file/database containing the identifying certificate.
* ``key``: An optional key to access the identifying certificate.
@@ -1258,7 +1278,8 @@ class Container(Reactor):
if not url and not urls and not address:
config = _get_default_config()
scheme = config.get('scheme', 'amqps')
- _url = "%s://%s:%s" % (scheme, config.get('host', 'localhost'), config.get('port', _get_default_port_for_scheme(scheme)))
+ _url = "%s://%s:%s" % (scheme, config.get('host', 'localhost'),
+ config.get('port', _get_default_port_for_scheme(scheme)))
_ssl_domain = None
_kwargs = kwargs
if config.get('user'):
diff --git a/python/proton/_tracing.py b/python/proton/_tracing.py
index a663bdf..c398a58 100644
--- a/python/proton/_tracing.py
+++ b/python/proton/_tracing.py
@@ -42,6 +42,7 @@ from proton.handlers import (
_tracer = None
_trace_key = proton.symbol('x-opt-qpid-tracestate')
+
def get_tracer():
global _tracer
if _tracer is not None:
@@ -49,12 +50,14 @@ def get_tracer():
exe = sys.argv[0] if sys.argv[0] else 'interactive-session'
return init_tracer(os.path.basename(exe))
+
def _fini_tracer():
time.sleep(1)
c = opentracing.global_tracer().close()
while not c.done():
time.sleep(0.5)
+
def init_tracer(service_name):
global _tracer
if _tracer is not None:
@@ -95,6 +98,7 @@ class IncomingMessageHandler(ProtonIncomingMessageHandler):
with tracer.start_active_span('amqp-delivery-receive', ignore_active_span=True, tags=span_tags):
proton._events._dispatch(self.delegate, 'on_message', event)
+
class OutgoingMessageHandler(ProtonOutgoingMessageHandler):
def on_settled(self, event):
if self.delegate is not None:
@@ -106,6 +110,7 @@ class OutgoingMessageHandler(ProtonOutgoingMessageHandler):
span.finish()
proton._events._dispatch(self.delegate, 'on_settled', event)
+
class Sender(ProtonSender):
def send(self, msg):
tracer = get_tracer()
@@ -121,7 +126,7 @@ class Sender(ProtonSender):
headers = {}
tracer.inject(span, Format.TEXT_MAP, headers)
if msg.annotations is None:
- msg.annotations = { _trace_key: headers }
+ msg.annotations = {_trace_key: headers}
else:
msg.annotations[_trace_key] = headers
delivery = ProtonSender.send(self, msg)
@@ -129,6 +134,7 @@ class Sender(ProtonSender):
span.set_tag('delivery-tag', delivery.tag)
return delivery
+
# Monkey patch proton for tracing (need to patch both internal and external names)
proton._handlers.IncomingMessageHandler = IncomingMessageHandler
proton._handlers.OutgoingMessageHandler = OutgoingMessageHandler
diff --git a/python/proton/_transport.py b/python/proton/_transport.py
index fa2fe89..1b8272e 100644
--- a/python/proton/_transport.py
+++ b/python/proton/_transport.py
@@ -74,14 +74,12 @@ class Transport(Wrapper):
TRACE_RAW = PN_TRACE_RAW
""" Log raw binary data going in and out of the transport. """
-
CLIENT = 1
""" Transport mode is as a client. """
SERVER = 2
""" Transport mode is as a server. """
-
@staticmethod
def wrap(impl):
if impl is None:
@@ -131,7 +129,7 @@ class Transport(Wrapper):
def log(self, message):
"""
Log a message using a transport's logging mechanism.
-
+
This can be useful in a debugging context as the log message will
be prefixed with the transport's identifier.
@@ -201,7 +199,7 @@ class Transport(Wrapper):
def user(self):
"""
The authenticated user.
-
+
On the client it will return whatever user was passed in to the
:attr:`Connection.user` attribute of the bound connection.
@@ -279,7 +277,7 @@ class Transport(Wrapper):
"""
Get the amount of free space for input following the transport's
tail pointer.
-
+
:return: Available space for input in bytes.
:rtype: ``int``
:raise: :exc:`TransportException` if there is any Proton error.
@@ -639,7 +637,7 @@ class SASL(Wrapper):
The returned value is only reliable after the ``PN_TRANSPORT_AUTHENTICATED``
event has been received.
-
+
:rtype: The authentication mechanism selected by the SASL layer.
"""
return pn_sasl_get_mech(self._sasl)
@@ -648,7 +646,7 @@ class SASL(Wrapper):
def outcome(self):
"""
Retrieve the outcome of SASL negotiation.
-
+
:rtype: * ``None`` if no negotiation has taken place.
* Otherwise the outcome of the negotiation.
"""
@@ -759,7 +757,6 @@ class SSLDomain(object):
ANONYMOUS_PEER = PN_SSL_ANONYMOUS_PEER
"""Do not require a certificate nor cipher authorization."""
-
def __init__(self, mode):
self._domain = pn_ssl_domain(mode)
if self._domain is None:
@@ -1033,7 +1030,7 @@ class SSL(object):
"""
A convenience method to get a string that contains the :const:`CERT_COMMON_NAME`
sub field of the subject field in the ssl certificate.
-
+
:return: A string containing the :const:`CERT_COMMON_NAME` sub field.
:rtype: ``str``
"""
@@ -1043,7 +1040,7 @@ class SSL(object):
"""
A convenience method to get a string that contains the :const:`CERT_ORGANIZATION_NAME`
sub field of the subject field in the ssl certificate.
-
+
:return: A string containing the :const:`CERT_ORGANIZATION_NAME` sub field.
:rtype: ``str``
"""
@@ -1053,7 +1050,7 @@ class SSL(object):
"""
A convenience method to get a string that contains the :const:`CERT_ORGANIZATION_UNIT`
sub field of the subject field in the ssl certificate.
-
+
:return: A string containing the :const:`CERT_ORGANIZATION_UNIT` sub field.
:rtype: ``str``
"""
@@ -1063,7 +1060,7 @@ class SSL(object):
"""
A convenience method to get a string that contains the :const:`CERT_CITY_OR_LOCALITY`
sub field of the subject field in the ssl certificate.
-
+
:return: A string containing the :const:`CERT_CITY_OR_LOCALITY` sub field.
:rtype: ``str``
"""
@@ -1073,7 +1070,7 @@ class SSL(object):
"""
A convenience method to get a string that contains the :const:`CERT_COUNTRY_NAME`
sub field of the subject field in the ssl certificate.
-
+
:return: A string containing the :const:`CERT_COUNTRY_NAME` sub field.
:rtype: ``str``
"""
@@ -1083,7 +1080,7 @@ class SSL(object):
"""
A convenience method to get a string that contains the :const:`CERT_STATE_OR_PROVINCE`
sub field of the subject field in the ssl certificate.
-
+
:return: A string containing the :const:`CERT_STATE_OR_PROVINCE` sub field.
:rtype: ``str``
"""
@@ -1121,7 +1118,7 @@ class SSL(object):
"""
A convenience method to get the :const:`SHA1` fingerprint of the
certificate.
-
+
:return: Hex fingerprint in a string, or ``None`` if an error occurred.
:rtype: ``str`` or ``None``
"""
@@ -1131,7 +1128,7 @@ class SSL(object):
"""
A convenience method to get the :const:`SHA256` fingerprint of the
certificate.
-
+
:return: Hex fingerprint in a string, or ``None`` if an error occurred.
:rtype: ``str`` or ``None``
"""
@@ -1142,7 +1139,7 @@ class SSL(object):
"""
A convenience method to get the :const:`SHA512` fingerprint of the
certificate.
-
+
:return: Hex fingerprint in a string, or ``None`` if an error occurred.
:rtype: ``str`` or ``None``
"""
@@ -1153,7 +1150,7 @@ class SSL(object):
"""
A convenience method to get the :const:`MD5` fingerprint of the
certificate.
-
+
:return: Hex fingerprint in a string, or ``None`` if an error occurred.
:rtype: ``str`` or ``None``
"""
@@ -1239,7 +1236,7 @@ class SSLSessionDetails(object):
def get_session_id(self):
"""
Get the unique identifier for this SSL session
-
+
:return: Session identifier
:rtype: ``str``
"""
diff --git a/python/proton/_url.py b/python/proton/_url.py
index 2388912..2da0001 100644
--- a/python/proton/_url.py
+++ b/python/proton/_url.py
@@ -50,7 +50,7 @@ class Url(object):
:ivar ~.host: Host name, ipv6 literal or ipv4 dotted quad.
:ivar ~.port: Integer port.
:ivar host_port: Returns host:port
-
+
:param url: URL string to parse.
:type url: ``str``
:param defaults: If ``True``, fill in missing default values in the URL.
@@ -66,7 +66,6 @@ class Url(object):
AMQP = "amqp"
"""URL scheme for the AMQP protocol."""
-
class Port(int):
"""An integer port number that can be constructed from a service name string"""
@@ -121,7 +120,8 @@ class Url(object):
if '/' in p[0] or not p[2].startswith('//'):
url = '//' + url
u = urlparse(url)
- if not u: raise ValueError("Invalid URL '%s'" % url)
+ if not u:
+ raise ValueError("Invalid URL '%s'" % url)
self.scheme = None if not u.scheme else u.scheme
self.username = u.username and unquote(u.username)
self.password = u.password and unquote(u.password)
@@ -143,7 +143,8 @@ class Url(object):
for k in kwargs: # Let kwargs override values parsed from url
getattr(self, k) # Check for invalid kwargs
setattr(self, k, kwargs[k])
- if defaults: self.defaults()
+ if defaults:
+ self.defaults()
@staticmethod
def _parse_host_port(nl):
@@ -152,7 +153,7 @@ class Url(object):
beforebrace = hostportsplit[0]
afterbrace = hostportsplit[-1]
- if len(hostportsplit)==1:
+ if len(hostportsplit) == 1:
beforebrace = ''
else:
beforebrace += ']'
diff --git a/python/proton/_utils.py b/python/proton/_utils.py
index 5100f4c..ee7c267 100644
--- a/python/proton/_utils.py
+++ b/python/proton/_utils.py
@@ -90,6 +90,7 @@ class BlockingSender(BlockingLink):
A synchronous sender wrapper. This is typically created by calling
:meth:`BlockingConnection.create_sender`.
"""
+
def __init__(self, connection, sender):
super(BlockingSender, self).__init__(connection, sender)
if self.link.target and self.link.target.address and self.link.target.address != self.link.remote_target.address:
@@ -137,6 +138,7 @@ class Fetcher(MessagingHandler):
:param prefetch:
:type prefetch:
"""
+
def __init__(self, connection, prefetch):
super(Fetcher, self).__init__(prefetch=prefetch, auto_accept=False)
self.connection = connection
@@ -198,6 +200,7 @@ class BlockingReceiver(BlockingLink):
A synchronous receiver wrapper. This is typically created by calling
:meth:`BlockingConnection.create_receiver`.
"""
+
def __init__(self, connection, receiver, fetcher, credit=1):
super(BlockingReceiver, self).__init__(connection, receiver)
if self.link.source and self.link.source.address and self.link.source.address != self.link.remote_source.address:
@@ -206,7 +209,8 @@ class BlockingReceiver(BlockingLink):
# ...but close ourselves if peer does not
self.link.close()
raise LinkException("Failed to open receiver %s, source does not match" % self.link.name)
- if credit: receiver.flow(credit)
+ if credit:
+ receiver.flow(credit)
self.fetcher = fetcher
self.container = connection.container
@@ -287,6 +291,7 @@ class LinkDetached(LinkException):
:param link: The link which closed unexpectedly.
:type link: :class:`proton.Link`
"""
+
def __init__(self, link):
self.link = link
if link.is_sender:
@@ -310,6 +315,7 @@ class ConnectionClosed(ConnectionException):
:param connection: The connection which closed unexpectedly.
:type connection: :class:`proton.Connection`
"""
+
def __init__(self, connection):
self.connection = connection
txt = "Connection %s closed" % connection.hostname
@@ -459,7 +465,8 @@ class BlockingConnection(Handler):
"""
Hand control over to the event loop (e.g. if waiting indefinitely for incoming messages)
"""
- while self.container.process(): pass
+ while self.container.process():
+ pass
self.container.stop()
self.container.process()
@@ -490,7 +497,8 @@ class BlockingConnection(Handler):
self.container.process()
if deadline < time.time():
txt = "Connection %s timed out" % self.url
- if msg: txt += ": " + msg
+ if msg:
+ txt += ": " + msg
raise Timeout(txt)
finally:
self.container.timeout = container_timeout
diff --git a/python/proton/_wrapper.py b/python/proton/_wrapper.py
index 1e7a33a..4703b34 100644
--- a/python/proton/_wrapper.py
+++ b/python/proton/_wrapper.py
@@ -91,7 +91,8 @@ class Wrapper(object):
self.__dict__["_impl"] = impl
self.__dict__["_attrs"] = attrs
self.__dict__["_record"] = record
- if init: self._init()
+ if init:
+ self._init()
def __getattr__(self, name):
attrs = self.__dict__["_attrs"]
diff --git a/python/setuputils/log.py b/python/setuputils/log.py
index f11b255..06b8e50 100644
--- a/python/setuputils/log.py
+++ b/python/setuputils/log.py
@@ -1,19 +1,19 @@
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# Copyright (C) PyZMQ Developers
# Distributed under the terms of the Modified BSD License.
#
# This bundling code is largely adapted from pyzmq-static's get.sh by
# Brandon Craig-Rhodes, which is itself BSD licensed.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# Logging (adapted from h5py:
http://h5py.googlecode.com)
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# This log code is largely adapted from pyzmq's code
# PyZMQ Developers, which is itself Modified BSD licensed.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
import os
diff --git a/python/setuputils/misc.py b/python/setuputils/misc.py
index 1aa5556..009190d 100644
--- a/python/setuputils/misc.py
+++ b/python/setuputils/misc.py
@@ -1,15 +1,15 @@
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# Copyright (C) PyZMQ Developers
# Distributed under the terms of the Modified BSD License.
#
# This bundling code is largely adapted from pyzmq-static's get.sh by
# Brandon Craig-Rhodes, which is itself BSD licensed.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# These functions were largely adapted from pyzmq's code
# PyZMQ Developers, which is itself Modified BSD licensed.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
import errno
@@ -19,6 +19,7 @@ import sys
from . import log
+
def _call_pkg_config(args):
"""Spawn a subprocess running pkg-config with the given args.
@@ -39,7 +40,6 @@ def _call_pkg_config(args):
return None
-
def pkg_config_version_installed(package, version=None, atleast=None):
"""Check if version of a package is is installed
@@ -60,7 +60,7 @@ def pkg_config_version_installed(package, version=None, atleast=None):
version or atleast),
package])
if p:
- out,err = p.communicate()
+ out, err = p.communicate()
if p.returncode:
log.info("Did not find %s via pkg-config: %s" % (package, err))
return False
@@ -78,9 +78,8 @@ def pkg_config_get_var(package, name):
if not p:
log.warn("pkg-config: var %s get failed, package %s", name, package)
return ""
- out,err = p.communicate()
+ out, err = p.communicate()
if p.returncode:
out = ""
log.warn(err)
return out.splitlines()[0]
-
diff --git a/python/tests/proton_tests/__main__.py b/python/tests/proton_tests/__main__.py
index 00697b7..6c1fea5 100644
--- a/python/tests/proton_tests/__main__.py
+++ b/python/tests/proton_tests/__main__.py
@@ -20,4 +20,4 @@
from proton_tests.main import main
if __name__ == '__main__':
- main()
+ main()
diff --git a/python/tests/proton_tests/codec.py b/python/tests/proton_tests/codec.py
index e3bffe5..b63e1d6 100644
--- a/python/tests/proton_tests/codec.py
+++ b/python/tests/proton_tests/codec.py
@@ -27,493 +27,504 @@ from proton._compat import raise_
from . import common
+
class Test(common.Test):
- def setUp(self):
- self.data = Data()
+ def setUp(self):
+ self.data = Data()
+
+ def tearDown(self):
+ self.data = None
- def tearDown(self):
- self.data = None
class DataTest(Test):
- def testTopLevelNext(self):
- assert self.data.next() is None
- self.data.put_null()
- self.data.put_bool(False)
- self.data.put_int(0)
- assert self.data.next() is None
- self.data.rewind()
- assert self.data.next() == Data.NULL
- assert self.data.next() == Data.BOOL
- assert self.data.next() == Data.INT
- assert self.data.next() is None
-
- def testNestedNext(self):
- assert self.data.next() is None
- self.data.put_null()
- assert self.data.next() is None
- self.data.put_list()
- assert self.data.next() is None
- self.data.put_bool(False)
- assert self.data.next() is None
- self.data.rewind()
- assert self.data.next() is Data.NULL
- assert self.data.next() is Data.LIST
- self.data.enter()
- assert self.data.next() is None
- self.data.put_ubyte(0)
- assert self.data.next() is None
- self.data.put_uint(0)
- assert self.data.next() is None
- self.data.put_int(0)
- assert self.data.next() is None
- self.data.exit()
- assert self.data.next() is Data.BOOL
- assert self.data.next() is None
-
- self.data.rewind()
- assert self.data.next() is Data.NULL
- assert self.data.next() is Data.LIST
- assert self.data.enter()
- assert self.data.next() is Data.UBYTE
- assert self.data.next() is Data.UINT
- assert self.data.next() is Data.INT
- assert self.data.next() is None
- assert self.data.exit()
- assert self.data.next() is Data.BOOL
- assert self.data.next() is None
-
- def testEnterExit(self):
- assert self.data.next() is None
- assert not self.data.enter()
- self.data.put_list()
- assert self.data.enter()
- assert self.data.next() is None
- self.data.put_list()
- assert self.data.enter()
- self.data.put_list()
- assert self.data.enter()
- assert self.data.exit()
- assert self.data.get_list() == 0
- assert self.data.exit()
- assert self.data.get_list() == 1
- assert self.data.exit()
- assert self.data.get_list() == 1
- assert not self.data.exit()
- assert self.data.get_list() == 1
- assert self.data.next() is None
-
- self.data.rewind()
- assert self.data.next() is Data.LIST
- assert self.data.get_list() == 1
- assert self.data.enter()
- assert self.data.next() is Data.LIST
- assert self.data.get_list() == 1
- assert self.data.enter()
- assert self.data.next() is Data.LIST
- assert self.data.get_list() == 0
- assert self.data.enter()
- assert self.data.next() is None
- assert self.data.exit()
- assert self.data.get_list() == 0
- assert self.data.exit()
- assert self.data.get_list() == 1
- assert self.data.exit()
- assert self.data.get_list() == 1
- assert not self.data.exit()
-
-
- def put(self, putter, v):
- """More informative exception from putters, include bad value"""
- try:
- putter(v)
- except Exception:
- etype, value, trace = sys.exc_info()
- raise_(etype, etype("%s(%r): %s" % (putter.__name__, v, value)), trace)
- return putter
-
- # (bits, signed) for each integer type
- INT_TYPES = {
- "byte": (8, True),
- "ubyte": (8, False),
- "short": (16, True),
- "ushort": (16, False),
- "int": (32, True),
- "uint": (32, False),
- "long": (64, True),
- "ulong": (64, False)
- }
-
- def int_values(self, dtype):
- """Set of test values for integer type dtype, include extreme and medial values"""
- bits, signed = self.INT_TYPES[dtype]
- values = [0, 1, 2, 5, 42]
- if signed:
- min, max = -2**(bits-1), 2**(bits-1)-1
- values.append(max // 2)
- values += [-i for i in values if i]
- values += [min, max]
- else:
- max = 2**(bits) - 1
- values += [max // 2, max]
- return sorted(values)
-
- def _testArray(self, dtype, descriptor, atype, *values):
- if dtype: dTYPE = getattr(self.data, dtype.upper())
- aTYPE = getattr(self.data, atype.upper())
- self.data.put_array(dtype is not None, aTYPE)
- self.data.enter()
- if dtype is not None:
- putter = getattr(self.data, "put_%s" % dtype)
- self.put(putter, descriptor)
- putter = getattr(self.data, "put_%s" % atype)
- for v in values:
- self.put(putter, v)
- self.data.exit()
- self.data.rewind()
- assert self.data.next() == Data.ARRAY
- count, described, type = self.data.get_array()
- assert count == len(values), count
- if dtype is None:
- assert described == False
- else:
- assert described == True
- assert type == aTYPE, type
- assert self.data.enter()
- if described:
- assert self.data.next() == dTYPE
- getter = getattr(self.data, "get_%s" % dtype)
- gotten = getter()
- assert gotten == descriptor, gotten
- if values:
- getter = getattr(self.data, "get_%s" % atype)
- for v in values:
- assert self.data.next() == aTYPE
- gotten = getter()
- assert gotten == v, gotten
- assert self.data.next() is None
- assert self.data.exit()
-
- def testStringArray(self):
- self._testArray(None, None, "string", "one", "two", "three")
-
- def testDescribedStringArray(self):
- self._testArray("symbol", "url", "string", "one", "two", "three")
-
- def _test_int_array(self, atype):
- self._testArray(None, None, atype, *self.int_values(atype))
-
- def testByteArray(self): self._test_int_array("byte")
- def testUbyteArray(self): self._test_int_array("ubyte")
- def testShortArray(self): self._test_int_array("short")
- def testUshortArray(self): self._test_int_array("ushort")
- def testIntArray(self): self._test_int_array("int")
- def testUintArray(self): self._test_int_array("uint")
- def testLongArray(self): self._test_int_array("long")
- def testUlongArray(self): self._test_int_array("ulong")
-
- def testUUIDArray(self):
- self._testArray(None, None, "uuid", uuid4(), uuid4(), uuid4())
-
- def testEmptyArray(self):
- self._testArray(None, None, "null")
-
- def testDescribedEmptyArray(self):
- self._testArray("long", 0, "null")
-
- def testPropertyDict(self):
- a = PropertyDict(one=1, two=2, three=3)
- b = PropertyDict({'one': 1, 'two': 2, 'three': 3})
- c = PropertyDict(zip(['one', 'two', 'three'], [1, 2, 3]))
- d = PropertyDict([('two', 2), ('one', 1), ('three', 3)])
- e = PropertyDict({symbol('three'): 3, symbol('one'): 1, symbol('two'): 2})
- f = PropertyDict(a)
- g = PropertyDict()
- g['one'] = 1
- g[symbol('two')] = 2
- g['three'] = 3
- assert a == b == c == d == e == f == g
- for k in a.keys():
- assert isinstance(k, symbol)
- self.assertRaises(KeyError, AnnotationDict, {'one': 1, None: 'none'})
- self.assertRaises(KeyError, AnnotationDict, {'one': 1, 1.23: 4})
-
- def testPropertyDictNoRaiseError(self):
- a = PropertyDict(one=1, two=2, three=3, raise_on_error=False)
- a[4] = 'four'
- b = PropertyDict({'one': 1, 'two': 2, 'three': 3, 4: 'four'}, raise_on_error=False)
- c = PropertyDict(zip(['one', 'two', 'three', 4], [1, 2, 3, 'four']), raise_on_error=False)
- d = PropertyDict([('two', 2), ('one', 1), ('three', 3), (4, 'four')], raise_on_error=False)
- e = PropertyDict({4: 'four', symbol('three'): 3, symbol('one'): 1, symbol('two'): 2}, raise_on_error=False)
- f = PropertyDict(a, raise_on_error=False)
- g = PropertyDict(raise_on_error=False)
- g['one'] = 1
- g[4] = 'four'
- g[symbol('two')] = 2
- g['three'] = 3
- assert a == b == c == d == e == f == g
-
- def testAnnotationDict(self):
- # AnnotationMap c'tor calls update(), so this method is also covered
- a = AnnotationDict(one=1, two=2, three=3)
- a[ulong(4)] = 'four'
- b = AnnotationDict({'one': 1, 'two': 2, 'three': 3, ulong(4): 'four'})
- c = AnnotationDict(zip(['one', 'two', 'three', ulong(4)], [1, 2, 3, 'four']))
- d = AnnotationDict([('two', 2), ('one', 1), ('three', 3), (ulong(4), 'four')])
- e = AnnotationDict({symbol('three'): 3, ulong(4): 'four', symbol('one'): 1, symbol('two'): 2})
- f = AnnotationDict(a)
- g = AnnotationDict()
- g[ulong(4)] = 'four'
- g['one'] = 1
- g[symbol('two')] = 2
- g['three'] = 3
- assert a == b == c == d == e == f == g
- for k in a.keys():
- assert isinstance(k, (symbol, ulong))
- self.assertRaises(KeyError, AnnotationDict, {'one': 1, None: 'none'})
- self.assertRaises(KeyError, AnnotationDict, {'one': 1, 1.23: 4})
-
- def testAnnotationDictNoRaiseError(self):
- a = AnnotationDict(one=1, two=2, three=3, raise_on_error=False)
- a[ulong(4)] = 'four'
- a[5] = 'five'
- b = AnnotationDict({'one': 1, 'two': 2, 'three': 3, ulong(4): 'four', 5: 'five'}, raise_on_error=False)
- c = AnnotationDict(zip(['one', 'two', 'three', ulong(4), 5], [1, 2, 3, 'four', 'five']), raise_on_error=False)
- d = AnnotationDict([('two', 2), ('one', 1), ('three', 3), (ulong(4), 'four'), (5, 'five')], raise_on_error=False)
- e = AnnotationDict({5: 'five', symbol('three'): 3, ulong(4): 'four', symbol('one'): 1, symbol('two'): 2}, raise_on_error=False)
- f = AnnotationDict(a, raise_on_error=False)
- g = AnnotationDict(raise_on_error=False)
- g[ulong(4)] = 'four'
- g['one'] = 1
- g[symbol('two')] = 2
- g[5] = 'five'
- g['three'] = 3
- assert a == b == c == d == e == f == g
-
- def testSymbolList(self):
- a = SymbolList(['one', 'two', 'three'])
- b = SymbolList([symbol('one'), symbol('two'), symbol('three')])
- c = SymbolList()
- c.append('one')
- c.extend([symbol('two'), 'three'])
- d1 = SymbolList(['one'])
- d2 = SymbolList(['two', symbol('three')])
- d = d1 + d2
- e = SymbolList(['one'])
- e += SymbolList(['two', symbol('three')])
- f = SymbolList(['one', 'hello', 'goodbye'])
- f[1] = symbol('two')
- f[2] = 'three'
- g = SymbolList(a)
- assert a == b == c == d == e == f == g
- for v in a:
- assert isinstance(v, symbol)
- self.assertRaises(TypeError, SymbolList, ['one', None])
- self.assertRaises(TypeError, SymbolList, ['one', 2])
- self.assertRaises(TypeError, SymbolList, ['one', ['two']])
- self.assertRaises(TypeError, SymbolList, ['one', {'two': 3}])
-
- def testSymbolListNoRaiseError(self):
- a = SymbolList(['one', 'two', 'three', 4], raise_on_error=False)
- b = SymbolList([symbol('one'), symbol('two'), symbol('three'), 4], raise_on_error=False)
- c = SymbolList(raise_on_error=False)
- c.append('one')
- c.extend([symbol('two'), 'three', 4])
- d1 = SymbolList(['one'], raise_on_error=False)
- d2 = SymbolList(['two', symbol('three'), 4], raise_on_error=False)
- d = d1 + d2
- e = SymbolList(['one'], raise_on_error=False)
- e += SymbolList(['two', symbol('three'), 4], raise_on_error=False)
- f = SymbolList(['one', 'hello', 'goodbye', 'what?'], raise_on_error=False)
- f[1] = symbol('two')
- f[2] = 'three'
- f[3] = 4
- g = SymbolList(a, raise_on_error=False)
- assert a == b == c == d == e == f == g
-
- def _test(self, dtype, *values, **kwargs):
- eq=kwargs.get("eq", lambda x, y: x == y)
- ntype = getattr(Data, dtype.upper())
- putter = getattr(self.data, "put_%s" % dtype)
- getter = getattr(self.data, "get_%s" % dtype)
-
- for v in values:
- self.put(putter, v)
- gotten = getter()
- assert eq(gotten, v), (gotten, v)
-
- self.data.rewind()
-
- for v in values:
- vtype = self.data.next()
- assert vtype == ntype, vtype
- gotten = getter()
- assert eq(gotten, v), (gotten, v)
-
- encoded = self.data.encode()
- copy = Data(0)
- while encoded:
- n = copy.decode(encoded)
- encoded = encoded[n:]
- copy.rewind()
-
- cgetter = getattr(copy, "get_%s" % dtype)
-
- for v in values:
- vtype = copy.next()
- assert vtype == ntype, vtype
- gotten = cgetter()
- assert eq(gotten, v), (gotten, v)
-
- def _test_int(self, itype):
- self._test(itype, *self.int_values(itype))
-
- def testByte(self): self._test_int("byte")
- def testUbyte(self):
- self._test_int("ubyte")
- self.assertRaises(AssertionError, ubyte, -1)
- def testShort(self): self._test_int("short")
- def testUshort(self):
- self._test("ushort")
- self.assertRaises(AssertionError, ushort, -1)
- def testInt(self): self._test_int("int")
- def testUint(self):
- self._test_int("uint")
- self.assertRaises(AssertionError, uint, -1)
- def testLong(self): self._test_int("long")
- def testUlong(self):
- self._test_int("ulong")
- self.assertRaises(AssertionError, ulong, -1)
-
- def testString(self):
- self._test("string", "one", "two", "three", "this is a test", "")
-
- def testFloat(self):
- # we have to use a special comparison here because python
- # internally only uses doubles and converting between floats and
- # doubles is imprecise
- self._test("float", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3,
- eq=lambda x, y: x - y < 0.000001)
-
- def testDouble(self):
- self._test("double", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3)
-
- def testBinary(self):
- self._test("binary", b"this", b"is", b"a", b"test",b"of" b"b\x00inary")
-
- def testSymbol(self):
- self._test("symbol", symbol("this is a symbol test"), symbol("bleh"), symbol("blah"))
-
- def testTimestamp(self):
- self._test("timestamp", timestamp(0), timestamp(12345), timestamp(1000000))
-
- def testChar(self):
- self._test("char", char('a'), char('b'), char('c'), char(u'\u20AC'))
-
- def testUUID(self):
- self._test("uuid", uuid4(), uuid4(), uuid4())
-
- def testDecimal32(self):
- self._test("decimal32", decimal32(0), decimal32(1), decimal32(2), decimal32(3), decimal32(4), decimal32(2**30))
-
- def testDecimal64(self):
- self._test("decimal64", decimal64(0), decimal64(1), decimal64(2), decimal64(3), decimal64(4), decimal64(2**60))
-
- def testDecimal128(self):
- self._test("decimal128", decimal128(b"fdsaasdf;lkjjkl;"), decimal128(b"x"*16))
-
- def testCopy(self):
- self.data.put_described()
- self.data.enter()
- self.data.put_ulong(123)
- self.data.put_map()
- self.data.enter()
- self.data.put_string("pi")
- self.data.put_double(3.14159265359)
-
- dst = Data()
- dst.copy(self.data)
-
- copy = dst.format()
- orig = self.data.format()
- assert copy == orig, (copy, orig)
-
- def testCopyNested(self):
- nested = [1, 2, 3, [4, 5, 6], 7, 8, 9]
- self.data.put_object(nested)
- dst = Data()
- dst.copy(self.data)
- assert dst.format() == self.data.format()
-
- def testCopyNestedArray(self):
- nested = [Array(UNDESCRIBED, Data.LIST,
- ["first", [Array(UNDESCRIBED, Data.INT, 1,2,3)]],
- ["second", [Array(UNDESCRIBED, Data.INT, 1,2,3)]],
- ["third", [Array(UNDESCRIBED, Data.INT, 1,2,3)]],
- ),
- "end"]
- self.data.put_object(nested)
- dst = Data()
- dst.copy(self.data)
- assert dst.format() == self.data.format()
-
- def testRoundTrip(self):
- obj = {symbol("key"): timestamp(1234),
- ulong(123): "blah",
- char("c"): "bleh",
- u"desc": Described(symbol("url"), u"
http://example.org"),
- u"array": Array(UNDESCRIBED, Data.INT, 1, 2, 3),
- u"list": [1, 2, 3, None, 4],
- u"boolean": True}
- self.data.put_object(obj)
- enc = self.data.encode()
- data = Data()
- data.decode(enc)
- data.rewind()
- assert data.next()
- copy = data.get_object()
- assert copy == obj, (copy, obj)
-
- def testBuffer(self):
- try:
- self.data.put_object(buffer(b"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() == b"foo"
-
- def testMemoryView(self):
- self.data.put_object(memoryview(b"foo"))
- data = Data()
- data.decode(self.data.encode())
- data.rewind()
- assert data.next()
- assert data.type() == Data.BINARY
- assert data.get_object() == b"foo"
-
- def testLookup(self):
- obj = {symbol("key"): u"value",
- symbol("pi"): 3.14159,
- symbol("list"): [1, 2, 3, 4]}
- self.data.put_object(obj)
- self.data.rewind()
- self.data.next()
- self.data.enter()
- self.data.narrow()
- assert self.data.lookup("pi")
- assert self.data.get_object() == 3.14159
- self.data.rewind()
- assert self.data.lookup("key")
- assert self.data.get_object() == u"value"
- self.data.rewind()
- assert self.data.lookup("list")
- assert self.data.get_object() == [1, 2, 3, 4]
- self.data.widen()
- self.data.rewind()
- assert not self.data.lookup("pi")
+ def testTopLevelNext(self):
+ assert self.data.next() is None
+ self.data.put_null()
+ self.data.put_bool(False)
+ self.data.put_int(0)
+ assert self.data.next() is None
+ self.data.rewind()
+ assert self.data.next() == Data.NULL
+ assert self.data.next() == Data.BOOL
+ assert self.data.next() == Data.INT
+ assert self.data.next() is None
+
+ def testNestedNext(self):
+ assert self.data.next() is None
+ self.data.put_null()
+ assert self.data.next() is None
+ self.data.put_list()
+ assert self.data.next() is None
+ self.data.put_bool(False)
+ assert self.data.next() is None
+ self.data.rewind()
+ assert self.data.next() is Data.NULL
+ assert self.data.next() is Data.LIST
+ self.data.enter()
+ assert self.data.next() is None
+ self.data.put_ubyte(0)
+ assert self.data.next() is None
+ self.data.put_uint(0)
+ assert self.data.next() is None
+ self.data.put_int(0)
+ assert self.data.next() is None
+ self.data.exit()
+ assert self.data.next() is Data.BOOL
+ assert self.data.next() is None
+
+ self.data.rewind()
+ assert self.data.next() is Data.NULL
+ assert self.data.next() is Data.LIST
+ assert self.data.enter()
+ assert self.data.next() is Data.UBYTE
+ assert self.data.next() is Data.UINT
+ assert self.data.next() is Data.INT
+ assert self.data.next() is None
+ assert self.data.exit()
+ assert self.data.next() is Data.BOOL
+ assert self.data.next() is None
+
+ def testEnterExit(self):
+ assert self.data.next() is None
+ assert not self.data.enter()
+ self.data.put_list()
+ assert self.data.enter()
+ assert self.data.next() is None
+ self.data.put_list()
+ assert self.data.enter()
+ self.data.put_list()
+ assert self.data.enter()
+ assert self.data.exit()
+ assert self.data.get_list() == 0
+ assert self.data.exit()
+ assert self.data.get_list() == 1
+ assert self.data.exit()
+ assert self.data.get_list() == 1
+ assert not self.data.exit()
+ assert self.data.get_list() == 1
+ assert self.data.next() is None
+
+ self.data.rewind()
+ assert self.data.next() is Data.LIST
+ assert self.data.get_list() == 1
+ assert self.data.enter()
+ assert self.data.next() is Data.LIST
+ assert self.data.get_list() == 1
+ assert self.data.enter()
+ assert self.data.next() is Data.LIST
+ assert self.data.get_list() == 0
+ assert self.data.enter()
+ assert self.data.next() is None
+ assert self.data.exit()
+ assert self.data.get_list() == 0
+ assert self.data.exit()
+ assert self.data.get_list() == 1
+ assert self.data.exit()
+ assert self.data.get_list() == 1
+ assert not self.data.exit()
+
+ def put(self, putter, v):
+ """More informative exception from putters, include bad value"""
+ try:
+ putter(v)
+ except Exception:
+ etype, value, trace = sys.exc_info()
+ raise_(etype, etype("%s(%r): %s" % (putter.__name__, v, value)), trace)
+ return putter
+
+ # (bits, signed) for each integer type
+ INT_TYPES = {
+ "byte": (8, True),
+ "ubyte": (8, False),
+ "short": (16, True),
+ "ushort": (16, False),
+ "int": (32, True),
+ "uint": (32, False),
+ "long": (64, True),
+ "ulong": (64, False)
+ }
+
+ def int_values(self, dtype):
+ """Set of test values for integer type dtype, include extreme and medial values"""
+ bits, signed = self.INT_TYPES[dtype]
+ values = [0, 1, 2, 5, 42]
+ if signed:
+ min, max = -2**(bits-1), 2**(bits-1)-1
+ values.append(max // 2)
+ values += [-i for i in values if i]
+ values += [min, max]
+ else:
+ max = 2**(bits) - 1
+ values += [max // 2, max]
+ return sorted(values)
+
+ def _testArray(self, dtype, descriptor, atype, *values):
+ if dtype:
+ dTYPE = getattr(self.data, dtype.upper())
+ aTYPE = getattr(self.data, atype.upper())
+ self.data.put_array(dtype is not None, aTYPE)
+ self.data.enter()
+ if dtype is not None:
+ putter = getattr(self.data, "put_%s" % dtype)
+ self.put(putter, descriptor)
+ putter = getattr(self.data, "put_%s" % atype)
+ for v in values:
+ self.put(putter, v)
+ self.data.exit()
+ self.data.rewind()
+ assert self.data.next() == Data.ARRAY
+ count, described, type = self.data.get_array()
+ assert count == len(values), count
+ if dtype is None:
+ assert described == False
+ else:
+ assert described == True
+ assert type == aTYPE, type
+ assert self.data.enter()
+ if described:
+ assert self.data.next() == dTYPE
+ getter = getattr(self.data, "get_%s" % dtype)
+ gotten = getter()
+ assert gotten == descriptor, gotten
+ if values:
+ getter = getattr(self.data, "get_%s" % atype)
+ for v in values:
+ assert self.data.next() == aTYPE
+ gotten = getter()
+ assert gotten == v, gotten
+ assert self.data.next() is None
+ assert self.data.exit()
+
+ def testStringArray(self):
+ self._testArray(None, None, "string", "one", "two", "three")
+
+ def testDescribedStringArray(self):
+ self._testArray("symbol", "url", "string", "one", "two", "three")
+
+ def _test_int_array(self, atype):
+ self._testArray(None, None, atype, *self.int_values(atype))
+
+ def testByteArray(self): self._test_int_array("byte")
+ def testUbyteArray(self): self._test_int_array("ubyte")
+ def testShortArray(self): self._test_int_array("short")
+ def testUshortArray(self): self._test_int_array("ushort")
+ def testIntArray(self): self._test_int_array("int")
+ def testUintArray(self): self._test_int_array("uint")
+ def testLongArray(self): self._test_int_array("long")
+ def testUlongArray(self): self._test_int_array("ulong")
+
+ def testUUIDArray(self):
+ self._testArray(None, None, "uuid", uuid4(), uuid4(), uuid4())
+
+ def testEmptyArray(self):
+ self._testArray(None, None, "null")
+
+ def testDescribedEmptyArray(self):
+ self._testArray("long", 0, "null")
+
+ def testPropertyDict(self):
+ a = PropertyDict(one=1, two=2, three=3)
+ b = PropertyDict({'one': 1, 'two': 2, 'three': 3})
+ c = PropertyDict(zip(['one', 'two', 'three'], [1, 2, 3]))
+ d = PropertyDict([('two', 2), ('one', 1), ('three', 3)])
+ e = PropertyDict({symbol('three'): 3, symbol('one'): 1, symbol('two'): 2})
+ f = PropertyDict(a)
+ g = PropertyDict()
+ g['one'] = 1
+ g[symbol('two')] = 2
+ g['three'] = 3
+ assert a == b == c == d == e == f == g
+ for k in a.keys():
+ assert isinstance(k, symbol)
+ self.assertRaises(KeyError, AnnotationDict, {'one': 1, None: 'none'})
+ self.assertRaises(KeyError, AnnotationDict, {'one': 1, 1.23: 4})
+
+ def testPropertyDictNoRaiseError(self):
+ a = PropertyDict(one=1, two=2, three=3, raise_on_error=False)
+ a[4] = 'four'
+ b = PropertyDict({'one': 1, 'two': 2, 'three': 3, 4: 'four'}, raise_on_error=False)
+ c = PropertyDict(zip(['one', 'two', 'three', 4], [1, 2, 3, 'four']), raise_on_error=False)
+ d = PropertyDict([('two', 2), ('one', 1), ('three', 3), (4, 'four')], raise_on_error=False)
+ e = PropertyDict({4: 'four', symbol('three'): 3, symbol('one'): 1, symbol('two'): 2}, raise_on_error=False)
+ f = PropertyDict(a, raise_on_error=False)
+ g = PropertyDict(raise_on_error=False)
+ g['one'] = 1
+ g[4] = 'four'
+ g[symbol('two')] = 2
+ g['three'] = 3
+ assert a == b == c == d == e == f == g
+
+ def testAnnotationDict(self):
+ # AnnotationMap c'tor calls update(), so this method is also covered
+ a = AnnotationDict(one=1, two=2, three=3)
+ a[ulong(4)] = 'four'
+ b = AnnotationDict({'one': 1, 'two': 2, 'three': 3, ulong(4): 'four'})
+ c = AnnotationDict(zip(['one', 'two', 'three', ulong(4)], [1, 2, 3, 'four']))
+ d = AnnotationDict([('two', 2), ('one', 1), ('three', 3), (ulong(4), 'four')])
+ e = AnnotationDict({symbol('three'): 3, ulong(4): 'four', symbol('one'): 1, symbol('two'): 2})
+ f = AnnotationDict(a)
+ g = AnnotationDict()
+ g[ulong(4)] = 'four'
+ g['one'] = 1
+ g[symbol('two')] = 2
+ g['three'] = 3
+ assert a == b == c == d == e == f == g
+ for k in a.keys():
+ assert isinstance(k, (symbol, ulong))
+ self.assertRaises(KeyError, AnnotationDict, {'one': 1, None: 'none'})
+ self.assertRaises(KeyError, AnnotationDict, {'one': 1, 1.23: 4})
+
+ def testAnnotationDictNoRaiseError(self):
+ a = AnnotationDict(one=1, two=2, three=3, raise_on_error=False)
+ a[ulong(4)] = 'four'
+ a[5] = 'five'
+ b = AnnotationDict({'one': 1, 'two': 2, 'three': 3, ulong(4): 'four', 5: 'five'}, raise_on_error=False)
+ c = AnnotationDict(zip(['one', 'two', 'three', ulong(4), 5], [1, 2, 3, 'four', 'five']), raise_on_error=False)
+ d = AnnotationDict([('two', 2), ('one', 1), ('three', 3),
+ (ulong(4), 'four'), (5, 'five')], raise_on_error=False)
+ e = AnnotationDict({5: 'five', symbol('three'): 3, ulong(4): 'four',
+ symbol('one'): 1, symbol('two'): 2}, raise_on_error=False)
+ f = AnnotationDict(a, raise_on_error=False)
+ g = AnnotationDict(raise_on_error=False)
+ g[ulong(4)] = 'four'
+ g['one'] = 1
+ g[symbol('two')] = 2
+ g[5] = 'five'
+ g['three'] = 3
+ assert a == b == c == d == e == f == g
+
+ def testSymbolList(self):
+ a = SymbolList(['one', 'two', 'three'])
+ b = SymbolList([symbol('one'), symbol('two'), symbol('three')])
+ c = SymbolList()
+ c.append('one')
+ c.extend([symbol('two'), 'three'])
+ d1 = SymbolList(['one'])
+ d2 = SymbolList(['two', symbol('three')])
+ d = d1 + d2
+ e = SymbolList(['one'])
+ e += SymbolList(['two', symbol('three')])
+ f = SymbolList(['one', 'hello', 'goodbye'])
+ f[1] = symbol('two')
+ f[2] = 'three'
+ g = SymbolList(a)
+ assert a == b == c == d == e == f == g
+ for v in a:
+ assert isinstance(v, symbol)
+ self.assertRaises(TypeError, SymbolList, ['one', None])
+ self.assertRaises(TypeError, SymbolList, ['one', 2])
+ self.assertRaises(TypeError, SymbolList, ['one', ['two']])
+ self.assertRaises(TypeError, SymbolList, ['one', {'two': 3}])
+
+ def testSymbolListNoRaiseError(self):
+ a = SymbolList(['one', 'two', 'three', 4], raise_on_error=False)
+ b = SymbolList([symbol('one'), symbol('two'), symbol('three'), 4], raise_on_error=False)
+ c = SymbolList(raise_on_error=False)
+ c.append('one')
+ c.extend([symbol('two'), 'three', 4])
+ d1 = SymbolList(['one'], raise_on_error=False)
+ d2 = SymbolList(['two', symbol('three'), 4], raise_on_error=False)
+ d = d1 + d2
+ e = SymbolList(['one'], raise_on_error=False)
+ e += SymbolList(['two', symbol('three'), 4], raise_on_error=False)
+ f = SymbolList(['one', 'hello', 'goodbye', 'what?'], raise_on_error=False)
+ f[1] = symbol('two')
+ f[2] = 'three'
+ f[3] = 4
+ g = SymbolList(a, raise_on_error=False)
+ assert a == b == c == d == e == f == g
+
+ def _test(self, dtype, *values, **kwargs):
+ eq = kwargs.get("eq", lambda x, y: x == y)
+ ntype = getattr(Data, dtype.upper())
+ putter = getattr(self.data, "put_%s" % dtype)
+ getter = getattr(self.data, "get_%s" % dtype)
+
+ for v in values:
+ self.put(putter, v)
+ gotten = getter()
+ assert eq(gotten, v), (gotten, v)
+
+ self.data.rewind()
+
+ for v in values:
+ vtype = self.data.next()
+ assert vtype == ntype, vtype
+ gotten = getter()
+ assert eq(gotten, v), (gotten, v)
+
+ encoded = self.data.encode()
+ copy = Data(0)
+ while encoded:
+ n = copy.decode(encoded)
+ encoded = encoded[n:]
+ copy.rewind()
+
+ cgetter = getattr(copy, "get_%s" % dtype)
+
+ for v in values:
+ vtype = copy.next()
+ assert vtype == ntype, vtype
+ gotten = cgetter()
+ assert eq(gotten, v), (gotten, v)
+
+ def _test_int(self, itype):
+ self._test(itype, *self.int_values(itype))
+
+ def testByte(self): self._test_int("byte")
+
+ def testUbyte(self):
+ self._test_int("ubyte")
+ self.assertRaises(AssertionError, ubyte, -1)
+
+ def testShort(self): self._test_int("short")
+
+ def testUshort(self):
+ self._test("ushort")
+ self.assertRaises(AssertionError, ushort, -1)
+
+ def testInt(self): self._test_int("int")
+
+ def testUint(self):
+ self._test_int("uint")
+ self.assertRaises(AssertionError, uint, -1)
+
+ def testLong(self): self._test_int("long")
+
+ def testUlong(self):
+ self._test_int("ulong")
+ self.assertRaises(AssertionError, ulong, -1)
+
+ def testString(self):
+ self._test("string", "one", "two", "three", "this is a test", "")
+
+ def testFloat(self):
+ # we have to use a special comparison here because python
+ # internally only uses doubles and converting between floats and
+ # doubles is imprecise
+ self._test("float", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3,
+ eq=lambda x, y: x - y < 0.000001)
+
+ def testDouble(self):
+ self._test("double", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3)
+
+ def testBinary(self):
+ self._test("binary", b"this", b"is", b"a", b"test", b"of" b"b\x00inary")
+
+ def testSymbol(self):
+ self._test("symbol", symbol("this is a symbol test"), symbol("bleh"), symbol("blah"))
+
+ def testTimestamp(self):
+ self._test("timestamp", timestamp(0), timestamp(12345), timestamp(1000000))
+
+ def testChar(self):
+ self._test("char", char('a'), char('b'), char('c'), char(u'\u20AC'))
+
+ def testUUID(self):
+ self._test("uuid", uuid4(), uuid4(), uuid4())
+
+ def testDecimal32(self):
+ self._test("decimal32", decimal32(0), decimal32(1), decimal32(2), decimal32(3), decimal32(4), decimal32(2**30))
+
+ def testDecimal64(self):
+ self._test("decimal64", decimal64(0), decimal64(1), decimal64(2), decimal64(3), decimal64(4), decimal64(2**60))
+
+ def testDecimal128(self):
+ self._test("decimal128", decimal128(b"fdsaasdf;lkjjkl;"), decimal128(b"x"*16))
+
+ def testCopy(self):
+ self.data.put_described()
+ self.data.enter()
+ self.data.put_ulong(123)
+ self.data.put_map()
+ self.data.enter()
+ self.data.put_string("pi")
+ self.data.put_double(3.14159265359)
+
+ dst = Data()
+ dst.copy(self.data)
+
+ copy = dst.format()
+ orig = self.data.format()
+ assert copy == orig, (copy, orig)
+
+ def testCopyNested(self):
+ nested = [1, 2, 3, [4, 5, 6], 7, 8, 9]
+ self.data.put_object(nested)
+ dst = Data()
+ dst.copy(self.data)
+ assert dst.format() == self.data.format()
+
+ def testCopyNestedArray(self):
+ nested = [Array(UNDESCRIBED, Data.LIST,
+ ["first", [Array(UNDESCRIBED, Data.INT, 1, 2, 3)]],
+ ["second", [Array(UNDESCRIBED, Data.INT, 1, 2, 3)]],
+ ["third", [Array(UNDESCRIBED, Data.INT, 1, 2, 3)]],
+ ),
+ "end"]
+ self.data.put_object(nested)
+ dst = Data()
+ dst.copy(self.data)
+ assert dst.format() == self.data.format()
+
+ def testRoundTrip(self):
+ obj = {symbol("key"): timestamp(1234),
+ ulong(123): "blah",
+ char("c"): "bleh",
+ u"desc": Described(symbol("url"), u"
http://example.org"),
+ u"array": Array(UNDESCRIBED, Data.INT, 1, 2, 3),
+ u"list": [1, 2, 3, None, 4],
+ u"boolean": True}
+ self.data.put_object(obj)
+ enc = self.data.encode()
+ data = Data()
+ data.decode(enc)
+ data.rewind()
+ assert data.next()
+ copy = data.get_object()
+ assert copy == obj, (copy, obj)
+
+ def testBuffer(self):
+ try:
+ self.data.put_object(buffer(b"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() == b"foo"
+
+ def testMemoryView(self):
+ self.data.put_object(memoryview(b"foo"))
+ data = Data()
+ data.decode(self.data.encode())
+ data.rewind()
+ assert data.next()
+ assert data.type() == Data.BINARY
+ assert data.get_object() == b"foo"
+
+ def testLookup(self):
+ obj = {symbol("key"): u"value",
+ symbol("pi"): 3.14159,
+ symbol("list"): [1, 2, 3, 4]}
+ self.data.put_object(obj)
+ self.data.rewind()
+ self.data.next()
+ self.data.enter()
+ self.data.narrow()
+ assert self.data.lookup("pi")
+ assert self.data.get_object() == 3.14159
+ self.data.rewind()
+ assert self.data.lookup("key")
+ assert self.data.get_object() == u"value"
+ self.data.rewind()
+ assert self.data.lookup("list")
+ assert self.data.get_object() == [1, 2, 3, 4]
+ self.data.widen()
+ self.data.rewind()
+ assert not self.data.lookup("pi")
diff --git a/python/tests/proton_tests/common.py b/python/tests/proton_tests/common.py
index 89d90bd..1e2e9a9 100644
--- a/python/tests/proton_tests/common.py
+++ b/python/tests/proton_tests/common.py
@@ -22,11 +22,13 @@ from __future__ import absolute_import
from unittest import TestCase
from unittest import SkipTest
-import sys, os, subprocess
+import sys
+import os
+import subprocess
from random import randint
from threading import Thread
from socket import socket, AF_INET, SOCK_STREAM
-from subprocess import Popen,PIPE,STDOUT
+from subprocess import Popen, PIPE, STDOUT
from string import Template
from proton import SASL, SSL
@@ -35,59 +37,63 @@ from proton.handlers import Handshaker, FlowController
def free_tcp_ports(count=1):
- """ return a list of 'count' TCP ports that are free to used (ie. unbound)
- """
- retry = 0
- ports = []
- sockets = []
- while len(ports) != count:
- port = randint(49152, 65535)
- sockets.append( socket( AF_INET, SOCK_STREAM ) )
- try:
- sockets[-1].bind( ("0.0.0.0", port ) )
- ports.append( port )
- retry = 0
- except:
- retry += 1
- assert retry != 100, "No free sockets available for test!"
- for s in sockets:
- s.close()
- return ports
+ """ return a list of 'count' TCP ports that are free to used (ie. unbound)
+ """
+ retry = 0
+ ports = []
+ sockets = []
+ while len(ports) != count:
+ port = randint(49152, 65535)
+ sockets.append(socket(AF_INET, SOCK_STREAM))
+ try:
+ sockets[-1].bind(("0.0.0.0", port))
+ ports.append(port)
+ retry = 0
+ except:
+ retry += 1
+ assert retry != 100, "No free sockets available for test!"
+ for s in sockets:
+ s.close()
+ return ports
+
def free_tcp_port():
- return free_tcp_ports(1)[0]
+ return free_tcp_ports(1)[0]
+
def pump_uni(src, dst, buffer_size=1024):
- p = src.pending()
- c = dst.capacity()
+ p = src.pending()
+ c = dst.capacity()
+
+ if c < 0:
+ if p < 0:
+ return False
+ else:
+ src.close_head()
+ return True
- if c < 0:
if p < 0:
- return False
+ dst.close_tail()
+ elif p == 0 or c == 0:
+ return False
else:
- src.close_head()
- return True
+ binary = src.peek(min(c, buffer_size))
+ dst.push(binary)
+ src.pop(len(binary))
- if p < 0:
- dst.close_tail()
- elif p == 0 or c == 0:
- return False
- else:
- binary = src.peek(min(c, buffer_size))
- dst.push(binary)
- src.pop(len(binary))
+ return True
- return True
def pump(transport1, transport2, buffer_size=1024):
- """ Transfer all pending bytes between two Proton engines
- by repeatedly calling peek/pop and push.
- Asserts that each engine accepts some bytes every time
- (unless it's already closed).
- """
- while (pump_uni(transport1, transport2, buffer_size) or
- pump_uni(transport2, transport1, buffer_size)):
- pass
+ """ Transfer all pending bytes between two Proton engines
+ by repeatedly calling peek/pop and push.
+ Asserts that each engine accepts some bytes every time
+ (unless it's already closed).
+ """
+ while (pump_uni(transport1, transport2, buffer_size) or
+ pump_uni(transport2, transport1, buffer_size)):
+ pass
+
def findfileinpath(filename, searchpath):
"""Find filename in the searchpath
@@ -99,153 +105,163 @@ def findfileinpath(filename, searchpath):
return os.path.abspath(os.path.join(path, filename))
return None
+
def isSSLPresent():
return SSL.present()
+
createdSASLDb = False
+
def _cyrusSetup(conf_dir):
- """Write out simple SASL config.
- """
- saslpasswd = ""
- if 'SASLPASSWD' in os.environ:
- saslpasswd = os.environ['SASLPASSWD']
- else:
- saslpasswd = findfileinpath('saslpasswd2', os.getenv('PATH')) or ""
- if os.path.exists(saslpasswd):
- t = Template("""sasldb_path: ${db}
+ """Write out simple SASL config.
+ """
+ saslpasswd = ""
+ if 'SASLPASSWD' in os.environ:
+ saslpasswd = os.environ['SASLPASSWD']
+ else:
+ saslpasswd = findfileinpath('saslpasswd2', os.getenv('PATH')) or ""
+ if os.path.exists(saslpasswd):
+ t = Template("""sasldb_path: ${db}
mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS
""")
- abs_conf_dir = os.path.abspath(conf_dir)
- subprocess.call(args=['rm','-rf',abs_conf_dir])
- os.mkdir(abs_conf_dir)
- db = os.path.join(abs_conf_dir,'proton.sasldb')
- conf = os.path.join(abs_conf_dir,'proton-server.conf')
- f = open(conf, 'w')
- f.write(t.substitute(db=db))
- f.close()
-
- cmd_template = Template("echo password | ${saslpasswd} -c -p -f ${db} -u proton user")
- cmd = cmd_template.substitute(db=db, saslpasswd=saslpasswd)
- subprocess.call(args=cmd, shell=True)
-
- os.environ['PN_SASL_CONFIG_PATH'] = abs_conf_dir
- global createdSASLDb
- createdSASLDb = True
+ abs_conf_dir = os.path.abspath(conf_dir)
+ subprocess.call(args=['rm', '-rf', abs_conf_dir])
+ os.mkdir(abs_conf_dir)
+ db = os.path.join(abs_conf_dir, 'proton.sasldb')
+ conf = os.path.join(abs_conf_dir, 'proton-server.conf')
+ f = open(conf, 'w')
+ f.write(t.substitute(db=db))
+ f.close()
+
+ cmd_template = Template("echo password | ${saslpasswd} -c -p -f ${db} -u proton user")
+ cmd = cmd_template.substitute(db=db, saslpasswd=saslpasswd)
+ subprocess.call(args=cmd, shell=True)
+
+ os.environ['PN_SASL_CONFIG_PATH'] = abs_conf_dir
+ global createdSASLDb
+ createdSASLDb = True
+
# Globally initialize Cyrus SASL configuration
if SASL.extended():
- _cyrusSetup('sasl-conf')
+ _cyrusSetup('sasl-conf')
+
def ensureCanTestExtendedSASL():
- if not SASL.extended():
- raise Skipped('Extended SASL not supported')
- if not createdSASLDb:
- raise Skipped("Can't Test Extended SASL: Couldn't create auth db")
+ if not SASL.extended():
+ raise Skipped('Extended SASL not supported')
+ if not createdSASLDb:
+ raise Skipped("Can't Test Extended SASL: Couldn't create auth db")
+
class DefaultConfig:
defines = {}
+
class Test(TestCase):
- config = DefaultConfig()
+ config = DefaultConfig()
- def __init__(self, name):
- super(Test, self).__init__(name)
- self.name = name
+ def __init__(self, name):
+ super(Test, self).__init__(name)
+ self.name = name
- def configure(self, config):
- self.config = config
+ def configure(self, config):
+ self.config = config
- def default(self, name, value, **profiles):
- default = value
- profile = self.config.defines.get("profile")
- if profile:
- default = profiles.get(profile, default)
- return self.config.defines.get(name, default)
+ def default(self, name, value, **profiles):
+ default = value
+ profile = self.config.defines.get("profile")
+ if profile:
+ default = profiles.get(profile, default)
+ return self.config.defines.get(name, default)
- @property
- def delay(self):
- return float(self.default("delay", "1", fast="0.1"))
+ @property
+ def delay(self):
+ return float(self.default("delay", "1", fast="0.1"))
- @property
- def timeout(self):
- return float(self.default("timeout", "60", fast="10"))
+ @property
+ def timeout(self):
+ return float(self.default("timeout", "60", fast="10"))
- @property
- def verbose(self):
- return int(self.default("verbose", 0))
+ @property
+ def verbose(self):
+ return int(self.default("verbose", 0))
class Skipped(SkipTest):
- skipped = True
+ skipped = True
class TestServer(object):
- """ Base class for creating test-specific message servers.
- """
- def __init__(self, **kwargs):
- self.args = kwargs
- self.reactor = Container(self)
- self.host = "127.0.0.1"
- self.port = 0
- if "host" in kwargs:
- self.host = kwargs["host"]
- if "port" in kwargs:
- self.port = kwargs["port"]
- self.handlers = [FlowController(10), Handshaker()]
- self.thread = Thread(name="server-thread", target=self.run)
- self.thread.daemon = True
- self.running = True
- self.conditions = []
-
- def start(self):
- self.reactor.start()
- retry = 0
- if self.port == 0:
- self.port = str(randint(49152, 65535))
- retry = 10
- while retry > 0:
- try:
- self.acceptor = self.reactor.acceptor(self.host, self.port)
- break
- except IOError:
- self.port = str(randint(49152, 65535))
- retry -= 1
- assert retry > 0, "No free port for server to listen on!"
- self.thread.start()
-
- def stop(self):
- self.running = False
- self.reactor.wakeup()
- self.thread.join()
-
- # Note: all following methods all run under the thread:
-
- def run(self):
- self.reactor.timeout = 3.14159265359
- while self.reactor.process():
- if not self.running:
- self.acceptor.close()
- self.reactor.stop()
- break
-
- def on_connection_bound(self, event):
- if "idle_timeout" in self.args:
- event.transport.idle_timeout = self.args["idle_timeout"]
-
- def on_connection_local_close(self, event):
- self.conditions.append(event.connection.condition)
-
- def on_delivery(self, event):
- event.delivery.settle()
+ """ Base class for creating test-specific message servers.
+ """
+
+ def __init__(self, **kwargs):
+ self.args = kwargs
+ self.reactor = Container(self)
+ self.host = "127.0.0.1"
+ self.port = 0
+ if "host" in kwargs:
+ self.host = kwargs["host"]
+ if "port" in kwargs:
+ self.port = kwargs["port"]
+ self.handlers = [FlowController(10), Handshaker()]
+ self.thread = Thread(name="server-thread", target=self.run)
+ self.thread.daemon = True
+ self.running = True
+ self.conditions = []
+
+ def start(self):
+ self.reactor.start()
+ retry = 0
+ if self.port == 0:
+ self.port = str(randint(49152, 65535))
+ retry = 10
+ while retry > 0:
+ try:
+ self.acceptor = self.reactor.acceptor(self.host, self.port)
+ break
+ except IOError:
+ self.port = str(randint(49152, 65535))
+ retry -= 1
+ assert retry > 0, "No free port for server to listen on!"
+ self.thread.start()
+
+ def stop(self):
+ self.running = False
+ self.reactor.wakeup()
+ self.thread.join()
+
+ # Note: all following methods all run under the thread:
+
+ def run(self):
+ self.reactor.timeout = 3.14159265359
+ while self.reactor.process():
+ if not self.running:
+ self.acceptor.close()
+ self.reactor.stop()
+ break
+
+ def on_connection_bound(self, event):
+ if "idle_timeout" in self.args:
+ event.transport.idle_timeout = self.args["idle_timeout"]
+
+ def on_connection_local_close(self, event):
+ self.conditions.append(event.connection.condition)
+
+ def on_delivery(self, event):
+ event.delivery.settle()
#
# Classes that wrap the messenger applications msgr-send and msgr-recv.
# These applications reside in the c/tools directory
#
+
class MessengerApp(object):
""" Interface to control a MessengerApp """
+
def __init__(self):
self._cmdline = None
# options common to Receivers and Senders:
@@ -283,7 +299,7 @@ class MessengerApp(object):
# NOTE(flaper87): Skip the test if the command is not found.
if e.errno == 2:
- raise Skipped("Skipping test - %s" % msg)
+ raise Skipped("Skipping test - %s" % msg)
assert False, msg
self._ready() # wait for it to initialize
@@ -303,7 +319,7 @@ class MessengerApp(object):
return self._process.returncode
def stdout(self):
- #self._process.communicate()[0]
+ # self._process.communicate()[0]
if not self._output or not self._output[0]:
return "*** NO STDOUT ***"
return self._output[0]
@@ -342,6 +358,7 @@ class MessengerApp(object):
class MessengerSender(MessengerApp):
""" Interface to configure a sending MessengerApp """
+
def __init__(self):
MessengerApp.__init__(self)
self._command = None
@@ -401,6 +418,7 @@ class MessengerSender(MessengerApp):
class MessengerReceiver(MessengerApp):
""" Interface to configure a receiving MessengerApp """
+
def __init__(self):
MessengerApp.__init__(self)
self._command = None
@@ -457,21 +475,25 @@ class MessengerReceiver(MessengerApp):
r = self._process.stdout.readline()
assert r.strip() == "READY", "Unexpected input while waiting for receiver to initialize: %s" % r
+
class MessengerSenderC(MessengerSender):
def __init__(self):
MessengerSender.__init__(self)
self._command = ["msgr-send"]
+
class MessengerReceiverC(MessengerReceiver):
def __init__(self):
MessengerReceiver.__init__(self)
self._command = ["msgr-recv"]
+
class ReactorSenderC(MessengerSender):
def __init__(self):
MessengerSender.__init__(self)
self._command = ["reactor-send"]
+
class ReactorReceiverC(MessengerReceiver):
def __init__(self):
MessengerReceiver.__init__(self)
diff --git a/python/tests/proton_tests/connect.py b/python/tests/proton_tests/connect.py
index 794e29b..696da6d 100644
--- a/python/tests/proton_tests/connect.py
+++ b/python/tests/proton_tests/connect.py
@@ -27,10 +27,12 @@ from proton.reactor import Container
from proton.handlers import MessagingHandler
from .ssl import _testpath
+
def write_connect_conf(obj):
with open('connect.json', 'w') as outfile:
json.dump(obj, outfile)
+
class Server(MessagingHandler):
def __init__(self, expected_user=None, scheme='amqps'):
super(Server, self).__init__()
@@ -52,6 +54,7 @@ class Server(MessagingHandler):
event.connection.close()
self.listener.close()
+
class Client(MessagingHandler):
def __init__(self):
super(Client, self).__init__()
@@ -61,13 +64,14 @@ class Client(MessagingHandler):
self.opened = True
event.connection.close()
+
class ConnectConfigTest(Test):
def test_port(self):
ensureCanTestExtendedSASL()
server = Server()
container = Container(server)
client = Client()
- write_connect_conf({'port':server.port})
+ write_connect_conf({'port': server.port})
container.connect(handler=client, reconnect=False)
container.run()
assert client.opened == True
@@ -79,7 +83,7 @@ class ConnectConfigTest(Test):
server = Server(user)
container = Container(server)
client = Client()
- write_connect_conf({'port':server.port, 'user':user, 'password':password})
+ write_connect_conf({'port': server.port, 'user': user, 'password': password})
container.connect(handler=client, reconnect=False)
container.run()
assert client.opened == True
@@ -94,11 +98,11 @@ class ConnectConfigTest(Test):
'server-password')
client = Client()
config = {
- 'scheme':'amqps',
- 'port':server.port,
+ 'scheme': 'amqps',
+ 'port': server.port,
'tls': {
'verify': False
- }
+ }
}
write_connect_conf(config)
container.connect(handler=client, reconnect=False)
@@ -113,13 +117,13 @@ class ConnectConfigTest(Test):
_testpath('server-private-key-lh.pem'),
'server-password')
container.ssl.server.set_trusted_ca_db(_testpath('ca-certificate.pem'))
- container.ssl.server.set_peer_authentication( SSLDomain.VERIFY_PEER,
- _testpath('ca-certificate.pem') )
+ container.ssl.server.set_peer_authentication(SSLDomain.VERIFY_PEER,
+ _testpath('ca-certificate.pem'))
client = Client()
config = {
- 'scheme':'amqps',
- 'port':server.port,
+ 'scheme': 'amqps',
+ 'port': server.port,
'sasl': {
'mechanisms': 'EXTERNAL'
},
@@ -145,18 +149,18 @@ class ConnectConfigTest(Test):
_testpath('server-private-key-lh.pem'),
'server-password')
container.ssl.server.set_trusted_ca_db(_testpath('ca-certificate.pem'))
- container.ssl.server.set_peer_authentication( SSLDomain.VERIFY_PEER,
- _testpath('ca-certificate.pem') )
+ container.ssl.server.set_peer_authentication(SSLDomain.VERIFY_PEER,
+ _testpath('ca-certificate.pem'))
client = Client()
config = {
- 'scheme':'amqps',
- 'port':server.port,
- 'user':user,
- 'password':password,
+ 'scheme': 'amqps',
+ 'port': server.port,
+ 'user': user,
+ 'password': password,
'sasl': {
'mechanisms': 'PLAIN'
- },
+ },
'tls': {
'cert': _testpath('client-certificate.pem'),
'key': _testpath('client-private-key-no-password.pem'),
@@ -168,4 +172,3 @@ class ConnectConfigTest(Test):
container.connect(handler=client, reconnect=False)
container.run()
assert client.opened == True
-
diff --git a/python/tests/proton_tests/engine.py b/python/tests/proton_tests/engine.py
index 70d10c8..e20d691 100644
--- a/python/tests/proton_tests/engine.py
+++ b/python/tests/proton_tests/engine.py
@@ -19,7 +19,8 @@
from __future__ import absolute_import
-import os, gc
+import os
+import gc
from time import time, sleep
from proton import *
from proton.reactor import Container
@@ -29,7 +30,7 @@ from .common import pump, Skipped
# older versions of gc do not provide the garbage list
if not hasattr(gc, "garbage"):
- gc.garbage=[]
+ gc.garbage = []
# future test areas
# + different permutations of setup
@@ -53,2803 +54,2822 @@ except:
OUTPUT_SIZE = 10*1024
+
class Test(common.Test):
- def __init__(self, *args):
- common.Test.__init__(self, *args)
- self._wires = []
-
- def connection(self):
- c1 = Connection()
- c2 = Connection()
- t1 = Transport()
- t1.bind(c1)
- t2 = Transport()
- t2.bind(c2)
- self._wires.append((c1, t1, c2, t2))
-
- mask1 = 0
- mask2 = 0
-
- for cat in ("TRACE_FRM", "TRACE_RAW"):
- trc = os.environ.get("PN_%s" % cat)
- if trc and trc.lower() in ("1", "2", "yes", "true"):
- mask1 = mask1 | getattr(Transport, cat)
- if trc == "2":
- mask2 = mask2 | getattr(Transport, cat)
- t1.trace(mask1)
- t2.trace(mask2)
-
- return c1, c2
-
- def link(self, name, max_frame=None, idle_timeout=None):
- c1, c2 = self.connection()
- if max_frame:
- c1.transport.max_frame_size = max_frame[0]
- c2.transport.max_frame_size = max_frame[1]
- if idle_timeout:
- # idle_timeout in seconds expressed as float
- c1.transport.idle_timeout = idle_timeout[0]
- c2.transport.idle_timeout = idle_timeout[1]
- c1.open()
- c2.open()
- ssn1 = c1.session()
- ssn1.open()
- self.pump()
- ssn2 = c2.session_head(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
- ssn2.open()
- self.pump()
- snd = ssn1.sender(name)
- rcv = ssn2.receiver(name)
- return snd, rcv
-
- def cleanup(self):
- self._wires = []
-
- def pump(self, buffer_size=OUTPUT_SIZE):
- for c1, t1, c2, t2 in self._wires:
- pump(t1, t2, buffer_size)
+ def __init__(self, *args):
+ common.Test.__init__(self, *args)
+ self._wires = []
+
+ def connection(self):
+ c1 = Connection()
+ c2 = Connection()
+ t1 = Transport()
+ t1.bind(c1)
+ t2 = Transport()
+ t2.bind(c2)
+ self._wires.append((c1, t1, c2, t2))
+
+ mask1 = 0
+ mask2 = 0
+
+ for cat in ("TRACE_FRM", "TRACE_RAW"):
+ trc = os.environ.get("PN_%s" % cat)
+ if trc and trc.lower() in ("1", "2", "yes", "true"):
+ mask1 = mask1 | getattr(Transport, cat)
+ if trc == "2":
+ mask2 = mask2 | getattr(Transport, cat)
+ t1.trace(mask1)
+ t2.trace(mask2)
+
+ return c1, c2
+
+ def link(self, name, max_frame=None, idle_timeout=None):
+ c1, c2 = self.connection()
+ if max_frame:
+ c1.transport.max_frame_size = max_frame[0]
+ c2.transport.max_frame_size = max_frame[1]
+ if idle_timeout:
+ # idle_timeout in seconds expressed as float
+ c1.transport.idle_timeout = idle_timeout[0]
+ c2.transport.idle_timeout = idle_timeout[1]
+ c1.open()
+ c2.open()
+ ssn1 = c1.session()
+ ssn1.open()
+ self.pump()
+ ssn2 = c2.session_head(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
+ ssn2.open()
+ self.pump()
+ snd = ssn1.sender(name)
+ rcv = ssn2.receiver(name)
+ return snd, rcv
+
+ def cleanup(self):
+ self._wires = []
+
+ def pump(self, buffer_size=OUTPUT_SIZE):
+ for c1, t1, c2, t2 in self._wires:
+ pump(t1, t2, buffer_size)
+
class ConnectionTest(Test):
- def setUp(self):
- gc.enable()
- self.c1, self.c2 = self.connection()
+ def setUp(self):
+ gc.enable()
+ self.c1, self.c2 = self.connection()
+
+ def cleanup(self):
+ # release resources created by this class
+ super(ConnectionTest, self).cleanup()
+ self.c1 = None
+ self.c2 = None
+
+ def tearDown(self):
+ self.cleanup()
+ gc.collect()
+ assert not gc.garbage
+
+ def test_open_close(self):
+ assert self.c1.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ assert self.c2.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+
+ self.c1.open()
+ self.pump()
+
+ assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert self.c2.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE
+
+ self.c2.open()
+ self.pump()
+
+ assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- def cleanup(self):
- # release resources created by this class
- super(ConnectionTest, self).cleanup()
- self.c1 = None
- self.c2 = None
+ self.c1.close()
+ self.pump()
- def tearDown(self):
- self.cleanup()
- gc.collect()
- assert not gc.garbage
+ assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
- def test_open_close(self):
- assert self.c1.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- assert self.c2.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ self.c2.close()
+ self.pump()
- self.c1.open()
- self.pump()
+ assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.c2.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- assert self.c2.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE
+ def test_simultaneous_open_close(self):
+ assert self.c1.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ assert self.c2.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- self.c2.open()
- self.pump()
+ self.c1.open()
+ self.c2.open()
- assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ self.pump()
- self.c1.close()
- self.pump()
+ assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+ self.c1.close()
+ self.c2.close()
- self.c2.close()
- self.pump()
+ self.pump()
- assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert self.c2.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.c2.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- def test_simultaneous_open_close(self):
- assert self.c1.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- assert self.c2.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ def test_capabilities_array(self):
+ self.c1.offered_capabilities = Array(UNDESCRIBED, Data.SYMBOL,
+ symbol("O_one"),
+ symbol("O_two"),
+ symbol("O_three"))
- self.c1.open()
- self.c2.open()
+ self.c1.desired_capabilities = Array(UNDESCRIBED, Data.SYMBOL,
+ symbol("D_one"),
+ symbol("D_two"),
+ symbol("D_three"))
+ self.c1.open()
- self.pump()
+ assert self.c2.remote_offered_capabilities is None
+ assert self.c2.remote_desired_capabilities is None
- assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ self.pump()
- self.c1.close()
- self.c2.close()
+ assert self.c2.remote_offered_capabilities == self.c1.offered_capabilities, \
+ (self.c2.remote_offered_capabilities, self.c1.offered_capabilities)
+ assert self.c2.remote_desired_capabilities == self.c1.desired_capabilities, \
+ (self.c2.remote_desired_capabilities, self.c1.desired_capabilities)
- self.pump()
+ def test_capabilities_symbol_list(self):
+ self.c1.offered_capabilities = SymbolList(['O_one', 'O_two', symbol('O_three')])
+ self.c1.desired_capabilities = SymbolList([symbol('D_one'), 'D_two', 'D_three'])
+ self.c1.open()
- assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert self.c2.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.c2.remote_offered_capabilities is None
+ assert self.c2.remote_desired_capabilities is None
- def test_capabilities_array(self):
- self.c1.offered_capabilities = Array(UNDESCRIBED, Data.SYMBOL,
- symbol("O_one"),
- symbol("O_two"),
- symbol("O_three"))
+ self.pump()
- self.c1.desired_capabilities = Array(UNDESCRIBED, Data.SYMBOL,
- symbol("D_one"),
- symbol("D_two"),
- symbol("D_three"))
- self.c1.open()
+ assert self.c2.remote_offered_capabilities == self.c1.offered_capabilities, \
+ (self.c2.remote_offered_capabilities, self.c1.offered_capabilities)
+ assert self.c2.remote_desired_capabilities == self.c1.desired_capabilities, \
+ (self.c2.remote_desired_capabilities, self.c1.desired_capabilities)
- assert self.c2.remote_offered_capabilities is None
- assert self.c2.remote_desired_capabilities is None
+ def test_condition(self):
+ self.c1.open()
+ self.c2.open()
+ self.pump()
+ assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- self.pump()
+ cond = Condition("blah:bleh", "this is a description", {symbol("foo"): "bar"})
+ self.c1.condition = cond
+ self.c1.close()
+
+ self.pump()
+
+ assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+
+ rcond = self.c2.remote_condition
+ assert rcond == cond, (rcond, cond)
+
+ def test_properties(self, p1=PropertyDict(key=symbol("value")), p2=None):
+ self.c1.properties = p1
+ self.c2.properties = p2
+ self.c1.open()
+ self.c2.open()
+ self.pump()
+
+ assert self.c2.remote_properties == p1, (self.c2.remote_properties, p1)
+ assert self.c1.remote_properties == p2, (self.c1.remote_properties, p2)
+
+ # The proton implementation limits channel_max to 32767.
+ # If I set the application's limit lower than that, I should
+ # get my wish. If I set it higher -- not.
+ def test_channel_max_low(self, value=1234):
+ self.c1.transport.channel_max = value
+ self.c1.open()
+ self.pump()
+ assert self.c1.transport.channel_max == value, (self.c1.transport.channel_max, value)
+
+ def test_channel_max_high(self, value=65535):
+ self.c1.transport.channel_max = value
+ self.c1.open()
+ self.pump()
+ assert self.c1.transport.channel_max == 32767, (self.c1.transport.channel_max, value)
+
+ def test_channel_max_raise_and_lower(self):
+ upper_limit = 32767
+
+ # It's OK to lower the max below upper_limit.
+ self.c1.transport.channel_max = 12345
+ assert self.c1.transport.channel_max == 12345
+
+ # But it won't let us raise the limit above PN_IMPL_CHANNEL_MAX.
+ self.c1.transport.channel_max = 65535
+ assert self.c1.transport.channel_max == upper_limit
+
+ # send the OPEN frame
+ self.c1.open()
+ self.pump()
+
+ # Now it's too late to make any change, because
+ # we have already sent the OPEN frame.
+ try:
+ self.c1.transport.channel_max = 666
+ assert False, "expected session exception"
+ except:
+ pass
+
+ assert self.c1.transport.channel_max == upper_limit
+
+ # TODO: Currently failing test - PROTON-1759 - skip
+
+ def test_channel_max_limits_sessions(self):
+ raise Skipped('Test fails - PROTON-1759')
+ # This is an index -- so max number of channels should be 1.
+ self.c1.transport.channel_max = 0
+ self.c1.open()
+ self.c2.open()
+ ssn_0 = self.c2.session()
+ assert ssn_0 != None
+ ssn_0.open()
+ self.pump()
+ try:
+ ssn_1 = self.c2.session()
+ ssn_1.open()
+ self.pump()
+ assert False, "expected session exception"
+ except SessionException:
+ pass
+
+ def test_cleanup(self):
+ self.c1.open()
+ self.c2.open()
+ self.pump()
+ assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ t1 = self.c1.transport
+ t2 = self.c2.transport
+ c2 = self.c2
+ self.c1.close()
+ # release all references to C1, except that held by the transport
+ self.cleanup()
+ gc.collect()
+ # transport should flush last state from C1:
+ pump(t1, t2)
+ assert c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+
+ def test_user_config(self):
+ self.c1.user = "vindaloo"
+ self.c1.password = "secret"
+ self.c1.open()
+ self.pump()
+
+ self.c2.user = "leela"
+ self.c2.password = "trustno1"
+ self.c2.open()
+ self.pump()
+
+ assert self.c1.user == "vindaloo", self.c1.user
+ assert self.c1.password == None, self.c1.password
+ assert self.c2.user == "leela", self.c2.user
+ assert self.c2.password == None, self.c2.password
- assert self.c2.remote_offered_capabilities == self.c1.offered_capabilities, \
- (self.c2.remote_offered_capabilities, self.c1.offered_capabilities)
- assert self.c2.remote_desired_capabilities == self.c1.desired_capabilities, \
- (self.c2.remote_desired_capabilities, self.c1.desired_capabilities)
-
- def test_capabilities_symbol_list(self):
- self.c1.offered_capabilities = SymbolList(['O_one', 'O_two', symbol('O_three')])
- self.c1.desired_capabilities = SymbolList([symbol('D_one'), 'D_two', 'D_three'])
- self.c1.open()
-
- assert self.c2.remote_offered_capabilities is None
- assert self.c2.remote_desired_capabilities is None
-
- self.pump()
-
- assert self.c2.remote_offered_capabilities == self.c1.offered_capabilities, \
- (self.c2.remote_offered_capabilities, self.c1.offered_capabilities)
- assert self.c2.remote_desired_capabilities == self.c1.desired_capabilities, \
- (self.c2.remote_desired_capabilities, self.c1.desired_capabilities)
-
- def test_condition(self):
- self.c1.open()
- self.c2.open()
- self.pump()
- assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- cond = Condition("blah:bleh", "this is a description", {symbol("foo"): "bar"})
- self.c1.condition = cond
- self.c1.close()
-
- self.pump()
-
- assert self.c1.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
-
- rcond = self.c2.remote_condition
- assert rcond == cond, (rcond, cond)
-
- def test_properties(self, p1=PropertyDict(key=symbol("value")), p2=None):
- self.c1.properties = p1
- self.c2.properties = p2
- self.c1.open()
- self.c2.open()
- self.pump()
-
- assert self.c2.remote_properties == p1, (self.c2.remote_properties, p1)
- assert self.c1.remote_properties == p2, (self.c1.remote_properties, p2)
-
- # The proton implementation limits channel_max to 32767.
- # If I set the application's limit lower than that, I should
- # get my wish. If I set it higher -- not.
- def test_channel_max_low(self, value=1234):
- self.c1.transport.channel_max = value
- self.c1.open()
- self.pump()
- assert self.c1.transport.channel_max == value, (self.c1.transport.channel_max, value)
-
- def test_channel_max_high(self, value=65535):
- self.c1.transport.channel_max = value
- self.c1.open()
- self.pump()
- assert self.c1.transport.channel_max == 32767, (self.c1.transport.channel_max, value)
-
- def test_channel_max_raise_and_lower(self):
- upper_limit = 32767
-
- # It's OK to lower the max below upper_limit.
- self.c1.transport.channel_max = 12345
- assert self.c1.transport.channel_max == 12345
-
- # But it won't let us raise the limit above PN_IMPL_CHANNEL_MAX.
- self.c1.transport.channel_max = 65535
- assert self.c1.transport.channel_max == upper_limit
-
- # send the OPEN frame
- self.c1.open()
- self.pump()
-
- # Now it's too late to make any change, because
- # we have already sent the OPEN frame.
- try:
- self.c1.transport.channel_max = 666
- assert False, "expected session exception"
- except:
- pass
-
- assert self.c1.transport.channel_max == upper_limit
-
-
- # TODO: Currently failing test - PROTON-1759 - skip
- def test_channel_max_limits_sessions(self):
- raise Skipped('Test fails - PROTON-1759')
- # This is an index -- so max number of channels should be 1.
- self.c1.transport.channel_max = 0
- self.c1.open()
- self.c2.open()
- ssn_0 = self.c2.session()
- assert ssn_0 != None
- ssn_0.open()
- self.pump()
- try:
- ssn_1 = self.c2.session()
- ssn_1.open()
- self.pump()
- assert False, "expected session exception"
- except SessionException:
- pass
-
- def test_cleanup(self):
- self.c1.open()
- self.c2.open()
- self.pump()
- assert self.c1.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- t1 = self.c1.transport
- t2 = self.c2.transport
- c2 = self.c2
- self.c1.close()
- # release all references to C1, except that held by the transport
- self.cleanup()
- gc.collect()
- # transport should flush last state from C1:
- pump(t1, t2)
- assert c2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
-
- def test_user_config(self):
- self.c1.user = "vindaloo"
- self.c1.password = "secret"
- self.c1.open()
- self.pump()
-
- self.c2.user = "leela"
- self.c2.password = "trustno1"
- self.c2.open()
- self.pump()
-
- assert self.c1.user == "vindaloo", self.c1.user
- assert self.c1.password == None, self.c1.password
- assert self.c2.user == "leela", self.c2.user
- assert self.c2.password == None, self.c2.password
class SessionTest(Test):
- def setUp(self):
- gc.enable()
- self.c1, self.c2 = self.connection()
- self.ssn = self.c1.session()
- self.c1.open()
- self.c2.open()
+ def setUp(self):
+ gc.enable()
+ self.c1, self.c2 = self.connection()
+ self.ssn = self.c1.session()
+ self.c1.open()
+ self.c2.open()
- def cleanup(self):
- # release resources created by this class
- super(SessionTest, self).cleanup()
- self.c1 = None
- self.c2 = None
- self.ssn = None
+ def cleanup(self):
+ # release resources created by this class
+ super(SessionTest, self).cleanup()
+ self.c1 = None
+ self.c2 = None
+ self.ssn = None
- def tearDown(self):
- self.cleanup()
- gc.collect()
- assert not gc.garbage
+ def tearDown(self):
+ self.cleanup()
+ gc.collect()
+ assert not gc.garbage
- def test_open_close(self):
- assert self.ssn.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ def test_open_close(self):
+ assert self.ssn.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- self.ssn.open()
+ self.ssn.open()
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- self.pump()
+ self.pump()
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- ssn = self.c2.session_head(Endpoint.REMOTE_ACTIVE | Endpoint.LOCAL_UNINIT)
+ ssn = self.c2.session_head(Endpoint.REMOTE_ACTIVE | Endpoint.LOCAL_UNINIT)
- assert ssn != None
- assert ssn.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert ssn != None
+ assert ssn.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- ssn.open()
+ ssn.open()
- assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- self.pump()
+ self.pump()
- assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- ssn.close()
+ ssn.close()
- assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- self.pump()
+ self.pump()
- assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+ assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
- self.ssn.close()
+ self.ssn.close()
- assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- self.pump()
+ self.pump()
- assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- def test_simultaneous_close(self):
- self.ssn.open()
- self.pump()
- ssn = self.c2.session_head(Endpoint.REMOTE_ACTIVE | Endpoint.LOCAL_UNINIT)
- assert ssn != None
- ssn.open()
- self.pump()
+ def test_simultaneous_close(self):
+ self.ssn.open()
+ self.pump()
+ ssn = self.c2.session_head(Endpoint.REMOTE_ACTIVE | Endpoint.LOCAL_UNINIT)
+ assert ssn != None
+ ssn.open()
+ self.pump()
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- self.ssn.close()
- ssn.close()
+ self.ssn.close()
+ ssn.close()
- assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- self.pump()
+ self.pump()
- assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- def test_closing_connection(self):
- self.ssn.open()
- self.pump()
- self.c1.close()
- self.pump()
- self.ssn.close()
- self.pump()
+ def test_closing_connection(self):
+ self.ssn.open()
+ self.pump()
+ self.c1.close()
+ self.pump()
+ self.ssn.close()
+ self.pump()
- def test_condition(self):
- self.ssn.open()
- self.pump()
- ssn = self.c2.session_head(Endpoint.REMOTE_ACTIVE | Endpoint.LOCAL_UNINIT)
- assert ssn != None
- ssn.open()
- self.pump()
+ def test_condition(self):
+ self.ssn.open()
+ self.pump()
+ ssn = self.c2.session_head(Endpoint.REMOTE_ACTIVE | Endpoint.LOCAL_UNINIT)
+ assert ssn != None
+ ssn.open()
+ self.pump()
- assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- cond = Condition("blah:bleh", "this is a description", {symbol("foo"): "bar"})
- self.ssn.condition = cond
- self.ssn.close()
+ cond = Condition("blah:bleh", "this is a description", {symbol("foo"): "bar"})
+ self.ssn.condition = cond
+ self.ssn.close()
- self.pump()
+ self.pump()
- assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+ assert self.ssn.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
- rcond = ssn.remote_condition
- assert rcond == cond, (rcond, cond)
+ rcond = ssn.remote_condition
+ assert rcond == cond, (rcond, cond)
- def test_cleanup(self):
- snd, rcv = self.link("test-link")
- snd.open()
- rcv.open()
- self.pump()
- snd_ssn = snd.session
- rcv_ssn = rcv.session
- assert rcv_ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- self.ssn = None
- snd_ssn.close()
- snd_ssn.free()
- del snd_ssn
- gc.collect()
- self.pump()
- assert rcv_ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+ def test_cleanup(self):
+ snd, rcv = self.link("test-link")
+ snd.open()
+ rcv.open()
+ self.pump()
+ snd_ssn = snd.session
+ rcv_ssn = rcv.session
+ assert rcv_ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ self.ssn = None
+ snd_ssn.close()
+ snd_ssn.free()
+ del snd_ssn
+ gc.collect()
+ self.pump()
+ assert rcv_ssn.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+
+ def test_reopen_on_same_session_without_free(self):
+ """
+ confirm that a link is correctly opened when attaching to a previously
+ closed link *that has not been freed yet* on the same session
+ """
+ self.ssn.open()
+ self.pump()
+
+ ssn2 = self.c2.session_head(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
+ ssn2.open()
+ self.pump()
+ snd = self.ssn.sender("test-link")
+ rcv = ssn2.receiver("test-link")
- def test_reopen_on_same_session_without_free(self):
- """
- confirm that a link is correctly opened when attaching to a previously
- closed link *that has not been freed yet* on the same session
- """
- self.ssn.open()
- self.pump()
+ assert snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ assert rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- ssn2 = self.c2.session_head(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
- ssn2.open()
- self.pump()
- snd = self.ssn.sender("test-link")
- rcv = ssn2.receiver("test-link")
+ snd.open()
+ rcv.open()
+ self.pump()
+
+ assert snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- assert rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ snd.close()
+ rcv.close()
+ self.pump()
- snd.open()
- rcv.open()
- self.pump()
+ assert snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- snd.close()
- rcv.close()
- self.pump()
-
- assert snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
-
- snd = self.ssn.sender("test-link")
- rcv = ssn2.receiver("test-link")
- assert snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- assert rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
-
- snd.open()
- rcv.open()
- self.pump()
-
- assert snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- def test_set_get_outgoing_window(self):
- assert self.ssn.outgoing_window == 2147483647
-
- self.ssn.outgoing_window = 1024
- assert self.ssn.outgoing_window == 1024
+ snd = self.ssn.sender("test-link")
+ rcv = ssn2.receiver("test-link")
+ assert snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ assert rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+
+ snd.open()
+ rcv.open()
+ self.pump()
+
+ assert snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+
+ def test_set_get_outgoing_window(self):
+ assert self.ssn.outgoing_window == 2147483647
+
+ self.ssn.outgoing_window = 1024
+ assert self.ssn.outgoing_window == 1024
class LinkTest(Test):
- def setUp(self):
- gc.enable()
- self.snd, self.rcv = self.link("test-link")
+ def setUp(self):
+ gc.enable()
+ self.snd, self.rcv = self.link("test-link")
+
+ def cleanup(self):
+ # release resources created by this class
+ super(LinkTest, self).cleanup()
+ self.snd = None
+ self.rcv = None
+
+ def tearDown(self):
+ self.cleanup()
+ gc.collect()
+ assert not gc.garbage, gc.garbage
+
+ def test_open_close(self):
+ assert self.snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+
+ self.snd.open()
+
+ assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+
+ self.pump()
+
+ assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE
+
+ self.rcv.open()
+
+ assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+
+ self.pump()
+
+ assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+
+ self.snd.close()
+
+ assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+
+ self.pump()
+
+ assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+
+ self.rcv.close()
+
+ assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+
+ self.pump()
+
+ assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+
+ def test_simultaneous_open_close(self):
+ assert self.snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+
+ self.snd.open()
+ self.rcv.open()
+
+ assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
+
+ self.pump()
+
+ assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+
+ self.snd.close()
+ self.rcv.close()
+
+ assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+
+ self.pump()
+
+ assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+ assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
+
+ def test_multiple(self):
+ rcv = self.snd.session.receiver("second-rcv")
+ assert rcv.name == "second-rcv"
+ self.snd.open()
+ rcv.open()
+ self.pump()
+ c2 = self.rcv.session.connection
+ l = c2.link_head(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
+ while l:
+ l.open()
+ l = l.next(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
+ self.pump()
+
+ assert self.snd
+ assert rcv
+ self.snd.close()
+ rcv.close()
+ ssn = rcv.session
+ conn = ssn.connection
+ ssn.close()
+ conn.close()
+ self.pump()
+
+ def test_closing_session(self):
+ self.snd.open()
+ self.rcv.open()
+ ssn1 = self.snd.session
+ self.pump()
+ ssn1.close()
+ self.pump()
+ self.snd.close()
+ self.pump()
+
+ def test_closing_connection(self):
+ self.snd.open()
+ self.rcv.open()
+ ssn1 = self.snd.session
+ c1 = ssn1.connection
+ self.pump()
+ c1.close()
+ self.pump()
+ self.snd.close()
+ self.pump()
+
+ def assertEqualTermini(self, t1, t2):
+ assert t1.type == t2.type, (t1.type, t2.type)
+ assert t1.address == t2.address, (t1.address, t2.address)
+ assert t1.durability == t2.durability, (t1.durability, t2.durability)
+ assert t1.expiry_policy == t2.expiry_policy, (t1.expiry_policy, t2.expiry_policy)
+ assert t1.timeout == t2.timeout, (t1.timeout, t2.timeout)
+ assert t1.dynamic == t2.dynamic, (t1.dynamic, t2.dynamic)
+ for attr in ["properties", "capabilities", "outcomes", "filter"]:
+ d1 = getattr(t1, attr)
+ d2 = getattr(t2, attr)
+ assert d1.format() == d2.format(), (attr, d1.format(), d2.format())
+
+ def _test_source_target(self, config_source, config_target):
+ if config_source is None:
+ self.snd.source.type = Terminus.UNSPECIFIED
+ else:
+ config_source(self.snd.source)
+ if config_target is None:
+ self.snd.target.type = Terminus.UNSPECIFIED
+ else:
+ config_target(self.snd.target)
+ self.snd.open()
+ self.pump()
+ self.assertEqualTermini(self.rcv.remote_source, self.snd.source)
+ self.assertEqualTermini(self.rcv.remote_target, self.snd.target)
+ self.rcv.target.copy(self.rcv.remote_target)
+ self.rcv.source.copy(self.rcv.remote_source)
+ self.rcv.open()
+ self.pump()
+ self.assertEqualTermini(self.snd.remote_target, self.snd.target)
+ self.assertEqualTermini(self.snd.remote_source, self.snd.source)
+
+ def test_source_target(self):
+ self._test_source_target(TerminusConfig(address="source"),
+ TerminusConfig(address="target"))
+
+ def test_source(self):
+ self._test_source_target(TerminusConfig(address="source"), None)
+
+ def test_target(self):
+ self._test_source_target(None, TerminusConfig(address="target"))
+
+ def test_coordinator(self):
+ caps = Array(UNDESCRIBED, Data.SYMBOL, symbol("amqp:local-transactions"))
+ self._test_source_target(None, TerminusConfig(type=Terminus.COORDINATOR,
+ capabilities=caps))
+
+ def test_source_target_full(self):
+ self._test_source_target(TerminusConfig(address="source",
+ timeout=3,
+ dist_mode=Terminus.DIST_MODE_MOVE,
+ filter=[("int", 1), ("symbol", "two"), ("string", "three")],
+ capabilities=["one", "two", "three"]),
+ TerminusConfig(address="source",
+ timeout=7,
+ capabilities=None))
+
+ def test_distribution_mode(self):
+ self._test_source_target(TerminusConfig(address="source",
+ dist_mode=Terminus.DIST_MODE_COPY),
+ TerminusConfig(address="target"))
+ assert self.rcv.remote_source.distribution_mode == Terminus.DIST_MODE_COPY
+ assert self.rcv.remote_target.distribution_mode == Terminus.DIST_MODE_UNSPECIFIED
+
+ def test_dynamic_link(self):
+ self._test_source_target(TerminusConfig(address=None, dynamic=True), None)
+ assert self.rcv.remote_source.dynamic
+ assert self.rcv.remote_source.address is None
+
+ def test_condition(self):
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
- def cleanup(self):
- # release resources created by this class
- super(LinkTest, self).cleanup()
- self.snd = None
- self.rcv = None
+ assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- def tearDown(self):
- self.cleanup()
- gc.collect()
- assert not gc.garbage, gc.garbage
+ cond = Condition("blah:bleh", "this is a description", {symbol("foo"): "bar"})
+ self.snd.condition = cond
+ self.snd.close()
- def test_open_close(self):
- assert self.snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ self.pump()
- self.snd.open()
+ assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
+ assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
- assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
+ rcond = self.rcv.remote_condition
+ assert rcond == cond, (rcond, cond)
- self.pump()
+ def test_settle_mode(self):
+ self.snd.snd_settle_mode = Link.SND_UNSETTLED
+ assert self.snd.snd_settle_mode == Link.SND_UNSETTLED
+ self.rcv.rcv_settle_mode = Link.RCV_SECOND
+ assert self.rcv.rcv_settle_mode == Link.RCV_SECOND
- assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE
+ assert self.snd.remote_rcv_settle_mode != Link.RCV_SECOND
+ assert self.rcv.remote_snd_settle_mode != Link.SND_UNSETTLED
- self.rcv.open()
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
- assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.snd.remote_rcv_settle_mode == Link.RCV_SECOND
+ assert self.rcv.remote_snd_settle_mode == Link.SND_UNSETTLED
- self.pump()
+ def test_max_message_size(self):
+ assert self.snd.max_message_size == 0
+ assert self.rcv.remote_max_message_size == 0
+ self.snd.max_message_size = 13579
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+ assert self.rcv.remote_max_message_size == 13579
+
+ def test_properties(self):
+ sender_props = {symbol('key1'): 'value1',
+ symbol('key2'): 'value2'}
+ self.snd.properties = sender_props
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
- assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- self.snd.close()
+ assert self.rcv.remote_properties == sender_props, (self.rcv.remote_properties, sender_props)
+ assert self.snd.remote_properties == None, (self.snd.remote_properties, None)
+
+ def test_cleanup(self):
+ snd, rcv = self.link("test-link")
+ snd.open()
+ rcv.open()
+ self.pump()
+ assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ snd.close()
+ snd.free()
+ del snd
+ gc.collect()
+ self.pump()
+ assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
- assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- self.pump()
-
- assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
-
- self.rcv.close()
-
- assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
-
- self.pump()
-
- assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
-
- def test_simultaneous_open_close(self):
- assert self.snd.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
- assert self.rcv.state == Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_UNINIT
-
- self.snd.open()
- self.rcv.open()
-
- assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_UNINIT
-
- self.pump()
-
- assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- self.snd.close()
- self.rcv.close()
-
- assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
-
- self.pump()
-
- assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
- assert self.rcv.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_CLOSED
-
- def test_multiple(self):
- rcv = self.snd.session.receiver("second-rcv")
- assert rcv.name == "second-rcv"
- self.snd.open()
- rcv.open()
- self.pump()
- c2 = self.rcv.session.connection
- l = c2.link_head(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
- while l:
- l.open()
- l = l.next(Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE)
- self.pump()
-
- assert self.snd
- assert rcv
- self.snd.close()
- rcv.close()
- ssn = rcv.session
- conn = ssn.connection
- ssn.close()
- conn.close()
- self.pump()
-
- def test_closing_session(self):
- self.snd.open()
- self.rcv.open()
- ssn1 = self.snd.session
- self.pump()
- ssn1.close()
- self.pump()
- self.snd.close()
- self.pump()
-
- def test_closing_connection(self):
- self.snd.open()
- self.rcv.open()
- ssn1 = self.snd.session
- c1 = ssn1.connection
- self.pump()
- c1.close()
- self.pump()
- self.snd.close()
- self.pump()
-
- def assertEqualTermini(self, t1, t2):
- assert t1.type == t2.type, (t1.type, t2.type)
- assert t1.address == t2.address, (t1.address, t2.address)
- assert t1.durability == t2.durability, (t1.durability, t2.durability)
- assert t1.expiry_policy == t2.expiry_policy, (t1.expiry_policy, t2.expiry_policy)
- assert t1.timeout == t2.timeout, (t1.timeout, t2.timeout)
- assert t1.dynamic == t2.dynamic, (t1.dynamic, t2.dynamic)
- for attr in ["properties", "capabilities", "outcomes", "filter"]:
- d1 = getattr(t1, attr)
- d2 = getattr(t2, attr)
- assert d1.format() == d2.format(), (attr, d1.format(), d2.format())
-
- def _test_source_target(self, config_source, config_target):
- if config_source is None:
- self.snd.source.type = Terminus.UNSPECIFIED
- else:
- config_source(self.snd.source)
- if config_target is None:
- self.snd.target.type = Terminus.UNSPECIFIED
- else:
- config_target(self.snd.target)
- self.snd.open()
- self.pump()
- self.assertEqualTermini(self.rcv.remote_source, self.snd.source)
- self.assertEqualTermini(self.rcv.remote_target, self.snd.target)
- self.rcv.target.copy(self.rcv.remote_target)
- self.rcv.source.copy(self.rcv.remote_source)
- self.rcv.open()
- self.pump()
- self.assertEqualTermini(self.snd.remote_target, self.snd.target)
- self.assertEqualTermini(self.snd.remote_source, self.snd.source)
-
- def test_source_target(self):
- self._test_source_target(TerminusConfig(address="source"),
- TerminusConfig(address="target"))
-
- def test_source(self):
- self._test_source_target(TerminusConfig(address="source"), None)
-
- def test_target(self):
- self._test_source_target(None, TerminusConfig(address="target"))
-
- def test_coordinator(self):
- caps = Array(UNDESCRIBED, Data.SYMBOL, symbol("amqp:local-transactions"))
- self._test_source_target(None, TerminusConfig(type=Terminus.COORDINATOR,
- capabilities=caps))
-
- def test_source_target_full(self):
- self._test_source_target(TerminusConfig(address="source",
- timeout=3,
- dist_mode=Terminus.DIST_MODE_MOVE,
- filter=[("int", 1), ("symbol", "two"), ("string", "three")],
- capabilities=["one", "two", "three"]),
- TerminusConfig(address="source",
- timeout=7,
- capabilities=None))
- def test_distribution_mode(self):
- self._test_source_target(TerminusConfig(address="source",
- dist_mode=Terminus.DIST_MODE_COPY),
- TerminusConfig(address="target"))
- assert self.rcv.remote_source.distribution_mode == Terminus.DIST_MODE_COPY
- assert self.rcv.remote_target.distribution_mode == Terminus.DIST_MODE_UNSPECIFIED
-
- def test_dynamic_link(self):
- self._test_source_target(TerminusConfig(address=None, dynamic=True), None)
- assert self.rcv.remote_source.dynamic
- assert self.rcv.remote_source.address is None
-
- def test_condition(self):
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- assert self.snd.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- cond = Condition("blah:bleh", "this is a description", {symbol("foo"): "bar"})
- self.snd.condition = cond
- self.snd.close()
-
- self.pump()
-
- assert self.snd.state == Endpoint.LOCAL_CLOSED | Endpoint.REMOTE_ACTIVE
- assert self.rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
-
- rcond = self.rcv.remote_condition
- assert rcond == cond, (rcond, cond)
-
- def test_settle_mode(self):
- self.snd.snd_settle_mode = Link.SND_UNSETTLED
- assert self.snd.snd_settle_mode == Link.SND_UNSETTLED
- self.rcv.rcv_settle_mode = Link.RCV_SECOND
- assert self.rcv.rcv_settle_mode == Link.RCV_SECOND
-
- assert self.snd.remote_rcv_settle_mode != Link.RCV_SECOND
- assert self.rcv.remote_snd_settle_mode != Link.SND_UNSETTLED
-
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- assert self.snd.remote_rcv_settle_mode == Link.RCV_SECOND
- assert self.rcv.remote_snd_settle_mode == Link.SND_UNSETTLED
-
- def test_max_message_size(self):
- assert self.snd.max_message_size == 0
- assert self.rcv.remote_max_message_size == 0
- self.snd.max_message_size = 13579
- self.snd.open()
- self.rcv.open()
- self.pump()
- assert self.rcv.remote_max_message_size == 13579
-
- def test_properties(self):
- sender_props = {symbol('key1'): 'value1',
- symbol('key2'): 'value2'}
- self.snd.properties = sender_props
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- assert self.rcv.remote_properties == sender_props, (self.rcv.remote_properties, sender_props)
- assert self.snd.remote_properties == None, (self.snd.remote_properties, None)
-
- def test_cleanup(self):
- snd, rcv = self.link("test-link")
- snd.open()
- rcv.open()
- self.pump()
- assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- snd.close()
- snd.free()
- del snd
- gc.collect()
- self.pump()
- assert rcv.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
class TerminusConfig:
- def __init__(self, type=None, address=None, timeout=None, durability=None,
- filter=None, capabilities=None, dynamic=False, dist_mode=None):
- self.address = address
- self.timeout = timeout
- self.durability = durability
- self.filter = filter
- self.capabilities = capabilities
- self.dynamic = dynamic
- self.dist_mode = dist_mode
- self.type = type
-
- def __call__(self, terminus):
- if self.type is not None:
- terminus.type = self.type
- if self.address is not None:
- terminus.address = self.address
- if self.timeout is not None:
- terminus.timeout = self.timeout
- if self.durability is not None:
- terminus.durability = self.durability
- if self.capabilities is not None:
- terminus.capabilities.put_array(False, Data.SYMBOL)
- terminus.capabilities.enter()
- for c in self.capabilities:
- terminus.capabilities.put_symbol(c)
- if self.filter is not None:
- terminus.filter.put_map()
- terminus.filter.enter()
- for (t, v) in self.filter:
- setter = getattr(terminus.filter, "put_%s" % t)
- setter(v)
- if self.dynamic:
- terminus.dynamic = True
- if self.dist_mode is not None:
- terminus.distribution_mode = self.dist_mode
+ def __init__(self, type=None, address=None, timeout=None, durability=None,
+ filter=None, capabilities=None, dynamic=False, dist_mode=None):
+ self.address = address
+ self.timeout = timeout
+ self.durability = durability
+ self.filter = filter
+ self.capabilities = capabilities
+ self.dynamic = dynamic
+ self.dist_mode = dist_mode
+ self.type = type
+
+ def __call__(self, terminus):
+ if self.type is not None:
+ terminus.type = self.type
+ if self.address is not None:
+ terminus.address = self.address
+ if self.timeout is not None:
+ terminus.timeout = self.timeout
+ if self.durability is not None:
+ terminus.durability = self.durability
+ if self.capabilities is not None:
+ terminus.capabilities.put_array(False, Data.SYMBOL)
+ terminus.capabilities.enter()
+ for c in self.capabilities:
+ terminus.capabilities.put_symbol(c)
+ if self.filter is not None:
+ terminus.filter.put_map()
+ terminus.filter.enter()
+ for (t, v) in self.filter:
+ setter = getattr(terminus.filter, "put_%s" % t)
+ setter(v)
+ if self.dynamic:
+ terminus.dynamic = True
+ if self.dist_mode is not None:
+ terminus.distribution_mode = self.dist_mode
+
class TransferTest(Test):
- def setUp(self):
- gc.enable()
- self.snd, self.rcv = self.link("test-link")
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- def cleanup(self):
- # release resources created by this class
- super(TransferTest, self).cleanup()
- self.c1 = None
- self.c2 = None
- self.snd = None
- self.rcv = None
-
- def tearDown(self):
- self.cleanup()
- gc.collect()
- assert not gc.garbage
-
- def test_work_queue(self):
- assert self.c1.work_head is None
- self.snd.delivery("tag")
- assert self.c1.work_head is None
- self.rcv.flow(1)
- self.pump()
- d = self.c1.work_head
- assert d is not None
- tag = d.tag
- assert tag == "tag", tag
- assert d.writable
-
- n = self.snd.send(b"this is a test")
- assert self.snd.advance()
- assert self.c1.work_head is None
-
- self.pump()
-
- d = self.c2.work_head
- assert d.tag == "tag"
- assert d.readable
-
- def test_multiframe(self):
- self.rcv.flow(1)
- self.snd.delivery("tag")
- msg = b"this is a test"
- n = self.snd.send(msg)
- assert n == len(msg)
-
- self.pump()
-
- d = self.rcv.current
- assert d
- assert d.tag == "tag", repr(d.tag)
- assert d.readable
-
- binary = self.rcv.recv(1024)
- assert binary == msg, (binary, msg)
-
- binary = self.rcv.recv(1024)
- assert binary == b""
-
- msg = b"this is more"
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump()
-
- binary = self.rcv.recv(1024)
- assert binary == msg, (binary, msg)
-
- binary = self.rcv.recv(1024)
- assert binary is None
-
- def test_multiframe_abort(self):
- self.rcv.flow(1)
- sd = self.snd.delivery("tag")
- msg = b"this is a test"
- n = self.snd.send(msg)
- assert n == len(msg)
-
- self.pump()
-
- binary = self.rcv.recv(1024)
- assert binary == msg, (binary, msg)
-
- msg = b"this is more. Error if not discarded."
- n = self.snd.send(msg)
- assert n == len(msg)
- sd.abort()
- assert sd.aborted
-
- # Confirm abort discards the sender's buffered content, i.e. no data in generated transfer frame.
- # We want:
- # @transfer(20) [handle=0, delivery-id=0, delivery-tag=b"tag", message-format=0, settled=true, aborted=true]
- wanted = b"\x00\x00\x00%\x02\x00\x00\x00\x00S\x14\xd0\x00\x00\x00\x15\x00\x00\x00\nR\x00R\x00\xa0\x03tagR\x00A@@@@A"
- t = self.snd.transport
- wire_bytes = t.peek(1024)
- assert wanted == wire_bytes
-
- self.pump()
- assert self.rcv.current.aborted
-
- def test_multiframe_last_empty(self):
- self.rcv.flow(1)
- sd = self.snd.delivery("tag")
- msg_p1 = b"this is a test"
- n = self.snd.send(msg_p1)
- assert n == len(msg_p1)
-
- self.pump()
-
- assert len(msg_p1) == self.rcv.current.pending
- assert self.rcv.current.partial
- msg_p2 = b"this is more."
- n = self.snd.send(msg_p2)
- assert n == len(msg_p2)
-
- self.pump()
-
- msg = msg_p1 + msg_p2
- assert len(msg) == self.rcv.current.pending
- assert self.rcv.current.partial
- # Advance. Should send empty xfer frame with more flag false.
- assert self.snd.advance()
-
- self.pump()
-
- assert len(msg) == self.rcv.current.pending
- assert not self.rcv.current.partial
- binary = self.rcv.recv(self.rcv.current.pending)
- assert binary == msg
-
- def test_disposition(self):
- self.rcv.flow(1)
-
- self.pump()
-
- sd = self.snd.delivery("tag")
- msg = b"this is a test"
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump()
-
- rd = self.rcv.current
- assert rd is not None
- assert rd.tag == sd.tag
- rmsg = self.rcv.recv(1024)
- assert rmsg == msg
- rd.update(Delivery.ACCEPTED)
-
- self.pump()
-
- rdisp = sd.remote_state
- ldisp = rd.local_state
- assert rdisp == ldisp == Delivery.ACCEPTED, (rdisp, ldisp)
- assert sd.updated
-
- sd.update(Delivery.ACCEPTED)
-
- self.pump()
-
- assert sd.local_state == rd.remote_state == Delivery.ACCEPTED
- sd.settle()
-
- def test_delivery_id_ordering(self):
- self.rcv.flow(1024)
- self.pump(buffer_size=64*1024)
-
- #fill up delivery buffer on sender
- for m in range(1024):
- sd = self.snd.delivery("tag%s" % m)
- msg = ("message %s" % m).encode('ascii')
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump(buffer_size=64*1024)
-
- #receive a session-windows worth of messages and accept them
- for m in range(1024):
- rd = self.rcv.current
- assert rd is not None, m
- assert rd.tag == ("tag%s" % m), (rd.tag, m)
- msg = self.rcv.recv(1024)
- assert msg == ("message %s" % m).encode('ascii'), (msg, m)
- rd.update(Delivery.ACCEPTED)
- rd.settle()
-
- self.pump(buffer_size=64*1024)
-
- #add some new deliveries
- for m in range(1024, 1450):
- sd = self.snd.delivery("tag%s" % m)
- msg = ("message %s" % m).encode('ascii')
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- #handle all disposition changes to sent messages
- d = self.c1.work_head
- while d:
- next_d = d.work_next
- if d.updated:
- d.update(Delivery.ACCEPTED)
- d.settle()
- d = next_d
-
- #submit some more deliveries
- for m in range(1450, 1500):
- sd = self.snd.delivery("tag%s" % m)
- msg = ("message %s" % m).encode('ascii')
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump(buffer_size=64*1024)
- self.rcv.flow(1024)
- self.pump(buffer_size=64*1024)
-
- #verify remaining messages can be received and accepted
- for m in range(1024, 1500):
- rd = self.rcv.current
- assert rd is not None, m
- assert rd.tag == ("tag%s" % m), (rd.tag, m)
- msg = self.rcv.recv(1024)
- assert msg == ("message %s" % m).encode('ascii'), (msg, m)
- rd.update(Delivery.ACCEPTED)
- rd.settle()
-
- def test_cleanup(self):
- self.rcv.flow(10)
- self.pump()
-
- for x in range(10):
- self.snd.delivery("tag%d" % x)
+ def setUp(self):
+ gc.enable()
+ self.snd, self.rcv = self.link("test-link")
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+
+ def cleanup(self):
+ # release resources created by this class
+ super(TransferTest, self).cleanup()
+ self.c1 = None
+ self.c2 = None
+ self.snd = None
+ self.rcv = None
+
+ def tearDown(self):
+ self.cleanup()
+ gc.collect()
+ assert not gc.garbage
+
+ def test_work_queue(self):
+ assert self.c1.work_head is None
+ self.snd.delivery("tag")
+ assert self.c1.work_head is None
+ self.rcv.flow(1)
+ self.pump()
+ d = self.c1.work_head
+ assert d is not None
+ tag = d.tag
+ assert tag == "tag", tag
+ assert d.writable
+
+ n = self.snd.send(b"this is a test")
+ assert self.snd.advance()
+ assert self.c1.work_head is None
+
+ self.pump()
+
+ d = self.c2.work_head
+ assert d.tag == "tag"
+ assert d.readable
+
+ def test_multiframe(self):
+ self.rcv.flow(1)
+ self.snd.delivery("tag")
msg = b"this is a test"
n = self.snd.send(msg)
assert n == len(msg)
+
+ self.pump()
+
+ d = self.rcv.current
+ assert d
+ assert d.tag == "tag", repr(d.tag)
+ assert d.readable
+
+ binary = self.rcv.recv(1024)
+ assert binary == msg, (binary, msg)
+
+ binary = self.rcv.recv(1024)
+ assert binary == b""
+
+ msg = b"this is more"
+ n = self.snd.send(msg)
+ assert n == len(msg)
assert self.snd.advance()
- self.snd.close()
- self.snd.free()
- self.snd = None
- gc.collect()
- self.pump()
+ self.pump()
+
+ binary = self.rcv.recv(1024)
+ assert binary == msg, (binary, msg)
+
+ binary = self.rcv.recv(1024)
+ assert binary is None
+
+ def test_multiframe_abort(self):
+ self.rcv.flow(1)
+ sd = self.snd.delivery("tag")
+ msg = b"this is a test"
+ n = self.snd.send(msg)
+ assert n == len(msg)
+
+ self.pump()
+
+ binary = self.rcv.recv(1024)
+ assert binary == msg, (binary, msg)
+
+ msg = b"this is more. Error if not discarded."
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ sd.abort()
+ assert sd.aborted
+
+ # Confirm abort discards the sender's buffered content, i.e. no data in generated transfer frame.
+ # We want:
+ # @transfer(20) [handle=0, delivery-id=0, delivery-tag=b"tag", message-format=0, settled=true, aborted=true]
+ wanted = b"\x00\x00\x00%\x02\x00\x00\x00\x00S\x14\xd0\x00\x00\x00\x15\x00\x00\x00\nR\x00R\x00\xa0\x03tagR\x00A@@@@A"
+ t = self.snd.transport
+ wire_bytes = t.peek(1024)
+ assert wanted == wire_bytes
+
+ self.pump()
+ assert self.rcv.current.aborted
+
+ def test_multiframe_last_empty(self):
+ self.rcv.flow(1)
+ sd = self.snd.delivery("tag")
+ msg_p1 = b"this is a test"
+ n = self.snd.send(msg_p1)
+ assert n == len(msg_p1)
+
+ self.pump()
+
+ assert len(msg_p1) == self.rcv.current.pending
+ assert self.rcv.current.partial
+ msg_p2 = b"this is more."
+ n = self.snd.send(msg_p2)
+ assert n == len(msg_p2)
+
+ self.pump()
+
+ msg = msg_p1 + msg_p2
+ assert len(msg) == self.rcv.current.pending
+ assert self.rcv.current.partial
+ # Advance. Should send empty xfer frame with more flag false.
+ assert self.snd.advance()
+
+ self.pump()
+
+ assert len(msg) == self.rcv.current.pending
+ assert not self.rcv.current.partial
+ binary = self.rcv.recv(self.rcv.current.pending)
+ assert binary == msg
+
+ def test_disposition(self):
+ self.rcv.flow(1)
+
+ self.pump()
+
+ sd = self.snd.delivery("tag")
+ msg = b"this is a test"
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+
+ self.pump()
- for x in range(10):
rd = self.rcv.current
assert rd is not None
- assert rd.tag == "tag%d" % x
+ assert rd.tag == sd.tag
rmsg = self.rcv.recv(1024)
- assert self.rcv.advance()
assert rmsg == msg
- # close of snd should've settled:
- assert rd.settled
- rd.settle()
+ rd.update(Delivery.ACCEPTED)
+
+ self.pump()
+
+ rdisp = sd.remote_state
+ ldisp = rd.local_state
+ assert rdisp == ldisp == Delivery.ACCEPTED, (rdisp, ldisp)
+ assert sd.updated
+
+ sd.update(Delivery.ACCEPTED)
+
+ self.pump()
+
+ assert sd.local_state == rd.remote_state == Delivery.ACCEPTED
+ sd.settle()
+
+ def test_delivery_id_ordering(self):
+ self.rcv.flow(1024)
+ self.pump(buffer_size=64*1024)
+
+ # fill up delivery buffer on sender
+ for m in range(1024):
+ sd = self.snd.delivery("tag%s" % m)
+ msg = ("message %s" % m).encode('ascii')
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+
+ self.pump(buffer_size=64*1024)
+
+ # receive a session-windows worth of messages and accept them
+ for m in range(1024):
+ rd = self.rcv.current
+ assert rd is not None, m
+ assert rd.tag == ("tag%s" % m), (rd.tag, m)
+ msg = self.rcv.recv(1024)
+ assert msg == ("message %s" % m).encode('ascii'), (msg, m)
+ rd.update(Delivery.ACCEPTED)
+ rd.settle()
+
+ self.pump(buffer_size=64*1024)
+
+ # add some new deliveries
+ for m in range(1024, 1450):
+ sd = self.snd.delivery("tag%s" % m)
+ msg = ("message %s" % m).encode('ascii')
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+
+ # handle all disposition changes to sent messages
+ d = self.c1.work_head
+ while d:
+ next_d = d.work_next
+ if d.updated:
+ d.update(Delivery.ACCEPTED)
+ d.settle()
+ d = next_d
+
+ # submit some more deliveries
+ for m in range(1450, 1500):
+ sd = self.snd.delivery("tag%s" % m)
+ msg = ("message %s" % m).encode('ascii')
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+
+ self.pump(buffer_size=64*1024)
+ self.rcv.flow(1024)
+ self.pump(buffer_size=64*1024)
+
+ # verify remaining messages can be received and accepted
+ for m in range(1024, 1500):
+ rd = self.rcv.current
+ assert rd is not None, m
+ assert rd.tag == ("tag%s" % m), (rd.tag, m)
+ msg = self.rcv.recv(1024)
+ assert msg == ("message %s" % m).encode('ascii'), (msg, m)
+ rd.update(Delivery.ACCEPTED)
+ rd.settle()
+
+ def test_cleanup(self):
+ self.rcv.flow(10)
+ self.pump()
+
+ for x in range(10):
+ self.snd.delivery("tag%d" % x)
+ msg = b"this is a test"
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+ self.snd.close()
+ self.snd.free()
+ self.snd = None
+ gc.collect()
+
+ self.pump()
+
+ for x in range(10):
+ rd = self.rcv.current
+ assert rd is not None
+ assert rd.tag == "tag%d" % x
+ rmsg = self.rcv.recv(1024)
+ assert self.rcv.advance()
+ assert rmsg == msg
+ # close of snd should've settled:
+ assert rd.settled
+ rd.settle()
+
class MaxFrameTransferTest(Test):
- def setUp(self):
- pass
-
- def cleanup(self):
- # release resources created by this class
- super(MaxFrameTransferTest, self).cleanup()
- self.c1 = None
- self.c2 = None
- self.snd = None
- self.rcv = None
-
- def tearDown(self):
- self.cleanup()
-
- def message(self, size):
- parts = []
- for i in range(size):
- parts.append(str(i))
- return "/".join(parts)[:size].encode("utf-8")
-
- def testMinFrame(self):
- """
- Configure receiver to support minimum max-frame as defined by AMQP-1.0.
- Verify transfer of messages larger than 512.
- """
- self.snd, self.rcv = self.link("test-link", max_frame=[0,512])
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
- assert self.rcv.session.connection.transport.max_frame_size == 512
- assert self.snd.session.connection.transport.remote_max_frame_size == 512
-
- self.rcv.flow(1)
- self.snd.delivery("tag")
- msg = self.message(513)
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump()
-
- binary = self.rcv.recv(513)
- assert binary == msg
-
- binary = self.rcv.recv(1024)
- assert binary == None
-
- def testOddFrame(self):
- """
- Test an odd sized max limit with data that will require multiple frames to
- be transfered.
- """
- self.snd, self.rcv = self.link("test-link", max_frame=[0,521])
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
- assert self.rcv.session.connection.transport.max_frame_size == 521
- assert self.snd.session.connection.transport.remote_max_frame_size == 521
-
- self.rcv.flow(2)
- self.snd.delivery("tag")
- msg = ("X" * 1699).encode('utf-8')
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump()
-
- binary = self.rcv.recv(1699)
- assert binary == msg
-
- binary = self.rcv.recv(1024)
- assert binary == None
-
- self.rcv.advance()
-
- self.snd.delivery("gat")
- msg = self.message(1426)
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump()
-
- binary = self.rcv.recv(1426)
- assert binary == msg
-
- self.pump()
-
- binary = self.rcv.recv(1024)
- assert binary == None
-
- def testSendQueuedMultiFrameMessages(self, sendSingleFrameMsg = False):
- """
- Test that multiple queued messages on the same link
- with multi-frame content are sent correctly. Use an
- odd max frame size, send enough data to use many.
- """
- self.snd, self.rcv = self.link("test-link", max_frame=[0,517])
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
- assert self.rcv.session.connection.transport.max_frame_size == 517
- assert self.snd.session.connection.transport.remote_max_frame_size == 517
-
- self.rcv.flow(5)
-
- self.pump()
-
- # Send a delivery with 5 frames, all bytes as X1234
- self.snd.delivery("tag")
- msg = ("X1234" * 425).encode('utf-8')
- assert 2125 == len(msg)
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- # Send a delivery with 5 frames, all bytes as Y5678
- self.snd.delivery("tag2")
- msg2 = ("Y5678" * 425).encode('utf-8')
- assert 2125 == len(msg2)
- n = self.snd.send(msg2)
- assert n == len(msg2)
- assert self.snd.advance()
-
- self.pump()
-
- if sendSingleFrameMsg:
- # Send a delivery with 1 frame
- self.snd.delivery("tag3")
- msg3 = ("Z").encode('utf-8')
- assert 1 == len(msg3)
- n = self.snd.send(msg3)
- assert n == len(msg3)
+ def setUp(self):
+ pass
+
+ def cleanup(self):
+ # release resources created by this class
+ super(MaxFrameTransferTest, self).cleanup()
+ self.c1 = None
+ self.c2 = None
+ self.snd = None
+ self.rcv = None
+
+ def tearDown(self):
+ self.cleanup()
+
+ def message(self, size):
+ parts = []
+ for i in range(size):
+ parts.append(str(i))
+ return "/".join(parts)[:size].encode("utf-8")
+
+ def testMinFrame(self):
+ """
+ Configure receiver to support minimum max-frame as defined by AMQP-1.0.
+ Verify transfer of messages larger than 512.
+ """
+ self.snd, self.rcv = self.link("test-link", max_frame=[0, 512])
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+ assert self.rcv.session.connection.transport.max_frame_size == 512
+ assert self.snd.session.connection.transport.remote_max_frame_size == 512
+
+ self.rcv.flow(1)
+ self.snd.delivery("tag")
+ msg = self.message(513)
+ n = self.snd.send(msg)
+ assert n == len(msg)
assert self.snd.advance()
+
self.pump()
- binary = self.rcv.recv(5000)
- self.assertEqual(binary, msg)
+ binary = self.rcv.recv(513)
+ assert binary == msg
+
+ binary = self.rcv.recv(1024)
+ assert binary == None
+
+ def testOddFrame(self):
+ """
+ Test an odd sized max limit with data that will require multiple frames to
+ be transfered.
+ """
+ self.snd, self.rcv = self.link("test-link", max_frame=[0, 521])
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+ assert self.rcv.session.connection.transport.max_frame_size == 521
+ assert self.snd.session.connection.transport.remote_max_frame_size == 521
+
+ self.rcv.flow(2)
+ self.snd.delivery("tag")
+ msg = ("X" * 1699).encode('utf-8')
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
- self.rcv.advance()
+ self.pump()
- binary2 = self.rcv.recv(5000)
- self.assertEqual(binary2, msg2)
+ binary = self.rcv.recv(1699)
+ assert binary == msg
- self.rcv.advance()
+ binary = self.rcv.recv(1024)
+ assert binary == None
- if sendSingleFrameMsg:
- binary3 = self.rcv.recv(5000)
- self.assertEqual(binary3, msg3)
self.rcv.advance()
- self.pump()
-
- def testSendQueuedMultiFrameMessagesThenSingleFrameMessage(self):
- self.testSendQueuedMultiFrameMessages(sendSingleFrameMsg = True)
-
- def testBigMessage(self):
- """
- Test transferring a big message.
- """
- self.snd, self.rcv = self.link("test-link")
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- self.rcv.flow(2)
- self.snd.delivery("tag")
- msg = self.message(1024*256)
- n = self.snd.send(msg)
- assert n == len(msg)
- assert self.snd.advance()
-
- self.pump()
-
- binary = self.rcv.recv(1024*256)
- assert binary == msg
-
- binary = self.rcv.recv(1024)
- assert binary == None
-
- def testMaxFrameAbort(self):
- self.snd, self.rcv = self.link("test-link", max_frame=[0,512])
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.rcv.flow(1)
- sndt = self.snd.transport
- dblfrmbytes = ("0123456789" * 52).encode('utf-8')
- assert 520 == len(dblfrmbytes)
- self.pump()
-
- # Part 1: abort a delivery that would generate two frames - before they are generated.
- # Expect that no output is generated and credit is unaffected.
- assert self.snd.credit == 1
- sd = self.snd.delivery("tag_0")
- n = self.snd.send(dblfrmbytes)
- assert n == len(dblfrmbytes)
- sd.abort()
- generated = sndt.peek(2048)
- assert generated == b""
- assert self.snd.credit == 1
-
- # Part 2: abort a streaming delivery whose last content would generate two frames.
- # First send some un-aborted data across the wire.
- sd = self.snd.delivery("tag_1")
- n = self.snd.send(dblfrmbytes)
- assert n == len(dblfrmbytes)
- self.pump()
- binary = self.rcv.recv(2048)
- assert binary == dblfrmbytes, (binary, dblfrmbytes)
- # Now send more data spanning two frames and immediately abort.
- # Unlike part 1, an abort frame is required to sync with peer.
- n = self.snd.send(dblfrmbytes)
- assert n == len(dblfrmbytes)
- sd.abort()
- assert sd.aborted
- # Expect a single abort transfer frame with no content. One credit is consumed.
- # @transfer(20) [handle=0, delivery-id=0, delivery-tag=b"tag_1", message-format=0, settled=true, aborted=true]
- wanted = b"\x00\x00\x00\x27\x02\x00\x00\x00\x00S\x14\xd0\x00\x00\x00\x17\x00\x00\x00\nR\x00R\x00\xa0\x05tag_1R\x00A@@@@A"
- t = self.snd.transport
- wire_bytes = t.peek(2048)
- assert wanted == wire_bytes
- assert self.snd.credit == 0
- self.pump()
- assert self.rcv.current.aborted
- # Confirm no lingering transfers by closing the link.
- self.snd.close()
- # Expect just the detach frame.
- # @detach(22) [handle=0, closed=true]
- wanted = b"\x00\x00\x00\x17\x02\x00\x00\x00\x00S\x16\xd0\x00\x00\x00\x07\x00\x00\x00\x02R\x00A"
- wire_bytes = t.peek(2048)
- assert wanted == wire_bytes
+ self.snd.delivery("gat")
+ msg = self.message(1426)
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+
+ self.pump()
+
+ binary = self.rcv.recv(1426)
+ assert binary == msg
+
+ self.pump()
+
+ binary = self.rcv.recv(1024)
+ assert binary == None
+
+ def testSendQueuedMultiFrameMessages(self, sendSingleFrameMsg=False):
+ """
+ Test that multiple queued messages on the same link
+ with multi-frame content are sent correctly. Use an
+ odd max frame size, send enough data to use many.
+ """
+ self.snd, self.rcv = self.link("test-link", max_frame=[0, 517])
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+ assert self.rcv.session.connection.transport.max_frame_size == 517
+ assert self.snd.session.connection.transport.remote_max_frame_size == 517
+
+ self.rcv.flow(5)
+
+ self.pump()
+
+ # Send a delivery with 5 frames, all bytes as X1234
+ self.snd.delivery("tag")
+ msg = ("X1234" * 425).encode('utf-8')
+ assert 2125 == len(msg)
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+
+ # Send a delivery with 5 frames, all bytes as Y5678
+ self.snd.delivery("tag2")
+ msg2 = ("Y5678" * 425).encode('utf-8')
+ assert 2125 == len(msg2)
+ n = self.snd.send(msg2)
+ assert n == len(msg2)
+ assert self.snd.advance()
+
+ self.pump()
+
+ if sendSingleFrameMsg:
+ # Send a delivery with 1 frame
+ self.snd.delivery("tag3")
+ msg3 = ("Z").encode('utf-8')
+ assert 1 == len(msg3)
+ n = self.snd.send(msg3)
+ assert n == len(msg3)
+ assert self.snd.advance()
+ self.pump()
+
+ binary = self.rcv.recv(5000)
+ self.assertEqual(binary, msg)
+
+ self.rcv.advance()
+
+ binary2 = self.rcv.recv(5000)
+ self.assertEqual(binary2, msg2)
+
+ self.rcv.advance()
+
+ if sendSingleFrameMsg:
+ binary3 = self.rcv.recv(5000)
+ self.assertEqual(binary3, msg3)
+ self.rcv.advance()
+
+ self.pump()
+
+ def testSendQueuedMultiFrameMessagesThenSingleFrameMessage(self):
+ self.testSendQueuedMultiFrameMessages(sendSingleFrameMsg=True)
+
+ def testBigMessage(self):
+ """
+ Test transferring a big message.
+ """
+ self.snd, self.rcv = self.link("test-link")
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+
+ self.rcv.flow(2)
+ self.snd.delivery("tag")
+ msg = self.message(1024*256)
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ assert self.snd.advance()
+
+ self.pump()
+
+ binary = self.rcv.recv(1024*256)
+ assert binary == msg
+
+ binary = self.rcv.recv(1024)
+ assert binary == None
+
+ def testMaxFrameAbort(self):
+ self.snd, self.rcv = self.link("test-link", max_frame=[0, 512])
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.rcv.flow(1)
+ sndt = self.snd.transport
+ dblfrmbytes = ("0123456789" * 52).encode('utf-8')
+ assert 520 == len(dblfrmbytes)
+ self.pump()
+
+ # Part 1: abort a delivery that would generate two frames - before they are generated.
+ # Expect that no output is generated and credit is unaffected.
+ assert self.snd.credit == 1
+ sd = self.snd.delivery("tag_0")
+ n = self.snd.send(dblfrmbytes)
+ assert n == len(dblfrmbytes)
+ sd.abort()
+ generated = sndt.peek(2048)
+ assert generated == b""
+ assert self.snd.credit == 1
+
+ # Part 2: abort a streaming delivery whose last content would generate two frames.
+ # First send some un-aborted data across the wire.
+ sd = self.snd.delivery("tag_1")
+ n = self.snd.send(dblfrmbytes)
+ assert n == len(dblfrmbytes)
+ self.pump()
+ binary = self.rcv.recv(2048)
+ assert binary == dblfrmbytes, (binary, dblfrmbytes)
+ # Now send more data spanning two frames and immediately abort.
+ # Unlike part 1, an abort frame is required to sync with peer.
+ n = self.snd.send(dblfrmbytes)
+ assert n == len(dblfrmbytes)
+ sd.abort()
+ assert sd.aborted
+ # Expect a single abort transfer frame with no content. One credit is consumed.
+ # @transfer(20) [handle=0, delivery-id=0, delivery-tag=b"tag_1", message-format=0, settled=true, aborted=true]
+ wanted = b"\x00\x00\x00\x27\x02\x00\x00\x00\x00S\x14\xd0\x00\x00\x00\x17\x00\x00\x00\nR\x00R\x00\xa0\x05tag_1R\x00A@@@@A"
+ t = self.snd.transport
+ wire_bytes = t.peek(2048)
+ assert wanted == wire_bytes
+ assert self.snd.credit == 0
+ self.pump()
+ assert self.rcv.current.aborted
+ # Confirm no lingering transfers by closing the link.
+ self.snd.close()
+ # Expect just the detach frame.
+ # @detach(22) [handle=0, closed=true]
+ wanted = b"\x00\x00\x00\x17\x02\x00\x00\x00\x00S\x16\xd0\x00\x00\x00\x07\x00\x00\x00\x02R\x00A"
+ wire_bytes = t.peek(2048)
+ assert wanted == wire_bytes
class IdleTimeoutTest(Test):
- def setUp(self):
- pass
-
- def cleanup(self):
- # release resources created by this class
- super(IdleTimeoutTest, self).cleanup()
- self.snd = None
- self.rcv = None
- self.c1 = None
- self.c2 = None
-
- def tearDown(self):
- self.cleanup()
-
- def message(self, size):
- parts = []
- for i in range(size):
- parts.append(str(i))
- return "/".join(parts)[:size]
-
- def testGetSet(self):
- """
- Verify the configuration and negotiation of the idle timeout.
- """
-
- self.snd, self.rcv = self.link("test-link", idle_timeout=[1.0,2.0])
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
- # proton advertises 1/2 the configured timeout to the peer:
- assert self.rcv.session.connection.transport.idle_timeout == 2.0
- assert self.rcv.session.connection.transport.remote_idle_timeout == 0.5
- assert self.snd.session.connection.transport.idle_timeout == 1.0
- assert self.snd.session.connection.transport.remote_idle_timeout == 1.0
-
- def testTimeout(self):
- """
- Verify the AMQP Connection idle timeout.
- """
-
- # snd will timeout the Connection if no frame is received within 1000 ticks
- self.snd, self.rcv = self.link("test-link", idle_timeout=[1.0,0])
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- t_snd = self.snd.session.connection.transport
- t_rcv = self.rcv.session.connection.transport
- assert t_rcv.idle_timeout == 0.0
- # proton advertises 1/2 the timeout (see spec)
- assert t_rcv.remote_idle_timeout == 0.5
- assert t_snd.idle_timeout == 1.0
- assert t_snd.remote_idle_timeout == 0.0
-
- sndr_frames_in = t_snd.frames_input
- rcvr_frames_out = t_rcv.frames_output
-
- # at t+1msec, nothing should happen:
- clock = 0.001
- assert t_snd.tick(clock) == 1.001, "deadline for remote timeout"
- assert t_rcv.tick(clock) == 0.251, "deadline to send keepalive"
- self.pump()
- assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
-
- # at one tick from expected idle frame send, nothing should happen:
- clock = 0.250
- assert t_snd.tick(clock) == 1.001, "deadline for remote timeout"
- assert t_rcv.tick(clock) == 0.251, "deadline to send keepalive"
- self.pump()
- assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
-
- # this should cause rcvr to expire and send a keepalive
- clock = 0.251
- assert t_snd.tick(clock) == 1.001, "deadline for remote timeout"
- assert t_rcv.tick(clock) == 0.501, "deadline to send keepalive"
- self.pump()
- sndr_frames_in += 1
- rcvr_frames_out += 1
- assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
- assert rcvr_frames_out == t_rcv.frames_output, "unexpected frame"
-
- # since a keepalive was received, sndr will rebase its clock against this tick:
- # and the receiver should not change its deadline
- clock = 0.498
- assert t_snd.tick(clock) == 1.498, "deadline for remote timeout"
- assert t_rcv.tick(clock) == 0.501, "deadline to send keepalive"
- self.pump()
- assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
-
- # now expire sndr
- clock = 1.499
- t_snd.tick(clock)
- self.pump()
- assert self.c2.state & Endpoint.REMOTE_CLOSED
- assert self.c2.remote_condition.name == "amqp:resource-limit-exceeded"
+ def setUp(self):
+ pass
+
+ def cleanup(self):
+ # release resources created by this class
+ super(IdleTimeoutTest, self).cleanup()
+ self.snd = None
+ self.rcv = None
+ self.c1 = None
+ self.c2 = None
+
+ def tearDown(self):
+ self.cleanup()
+
+ def message(self, size):
+ parts = []
+ for i in range(size):
+ parts.append(str(i))
+ return "/".join(parts)[:size]
+
+ def testGetSet(self):
+ """
+ Verify the configuration and negotiation of the idle timeout.
+ """
+
+ self.snd, self.rcv = self.link("test-link", idle_timeout=[1.0, 2.0])
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+ # proton advertises 1/2 the configured timeout to the peer:
+ assert self.rcv.session.connection.transport.idle_timeout == 2.0
+ assert self.rcv.session.connection.transport.remote_idle_timeout == 0.5
+ assert self.snd.session.connection.transport.idle_timeout == 1.0
+ assert self.snd.session.connection.transport.remote_idle_timeout == 1.0
+
+ def testTimeout(self):
+ """
+ Verify the AMQP Connection idle timeout.
+ """
+
+ # snd will timeout the Connection if no frame is received within 1000 ticks
+ self.snd, self.rcv = self.link("test-link", idle_timeout=[1.0, 0])
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+
+ t_snd = self.snd.session.connection.transport
+ t_rcv = self.rcv.session.connection.transport
+ assert t_rcv.idle_timeout == 0.0
+ # proton advertises 1/2 the timeout (see spec)
+ assert t_rcv.remote_idle_timeout == 0.5
+ assert t_snd.idle_timeout == 1.0
+ assert t_snd.remote_idle_timeout == 0.0
+
+ sndr_frames_in = t_snd.frames_input
+ rcvr_frames_out = t_rcv.frames_output
+
+ # at t+1msec, nothing should happen:
+ clock = 0.001
+ assert t_snd.tick(clock) == 1.001, "deadline for remote timeout"
+ assert t_rcv.tick(clock) == 0.251, "deadline to send keepalive"
+ self.pump()
+ assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
+
+ # at one tick from expected idle frame send, nothing should happen:
+ clock = 0.250
+ assert t_snd.tick(clock) == 1.001, "deadline for remote timeout"
+ assert t_rcv.tick(clock) == 0.251, "deadline to send keepalive"
+ self.pump()
+ assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
+
+ # this should cause rcvr to expire and send a keepalive
+ clock = 0.251
+ assert t_snd.tick(clock) == 1.001, "deadline for remote timeout"
+ assert t_rcv.tick(clock) == 0.501, "deadline to send keepalive"
+ self.pump()
+ sndr_frames_in += 1
+ rcvr_frames_out += 1
+ assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
+ assert rcvr_frames_out == t_rcv.frames_output, "unexpected frame"
+
+ # since a keepalive was received, sndr will rebase its clock against this tick:
+ # and the receiver should not change its deadline
+ clock = 0.498
+ assert t_snd.tick(clock) == 1.498, "deadline for remote timeout"
+ assert t_rcv.tick(clock) == 0.501, "deadline to send keepalive"
+ self.pump()
+ assert sndr_frames_in == t_snd.frames_input, "unexpected received frame"
+
+ # now expire sndr
+ clock = 1.499
+ t_snd.tick(clock)
+ self.pump()
+ assert self.c2.state & Endpoint.REMOTE_CLOSED
+ assert self.c2.remote_condition.name == "amqp:resource-limit-exceeded"
+
class CreditTest(Test):
- def setUp(self):
- self.snd, self.rcv = self.link("test-link", max_frame=(16*1024, 16*1024))
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- def cleanup(self):
- # release resources created by this class
- super(CreditTest, self).cleanup()
- self.c1 = None
- self.snd = None
- self.c2 = None
- self.rcv2 = None
- self.snd2 = None
-
- def tearDown(self):
- self.cleanup()
-
- def testCreditSender(self, count=1024):
- credit = self.snd.credit
- assert credit == 0, credit
- self.rcv.flow(10)
- self.pump()
- credit = self.snd.credit
- assert credit == 10, credit
-
- self.rcv.flow(count)
- self.pump()
- credit = self.snd.credit
- assert credit == 10 + count, credit
-
- def testCreditReceiver(self):
- self.rcv.flow(10)
- self.pump()
- assert self.rcv.credit == 10, self.rcv.credit
-
- d = self.snd.delivery("tag")
- assert d
- assert self.snd.advance()
- self.pump()
- assert self.rcv.credit == 10, self.rcv.credit
- assert self.rcv.queued == 1, self.rcv.queued
- c = self.rcv.current
- assert c.tag == "tag", c.tag
- assert self.rcv.advance()
- assert self.rcv.credit == 9, self.rcv.credit
- assert self.rcv.queued == 0, self.rcv.queued
-
- def _testBufferingOnClose(self, a, b):
- for i in range(10):
- d = self.snd.delivery("tag-%s" % i)
- assert d
- d.settle()
- self.pump()
- assert self.snd.queued == 10
-
- endpoints = {"connection": (self.c1, self.c2),
- "session": (self.snd.session, self.rcv.session),
- "link": (self.snd, self.rcv)}
-
- local_a, remote_a = endpoints[a]
- local_b, remote_b = endpoints[b]
-
- remote_b.close()
- self.pump()
- assert local_b.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
- local_a.close()
- self.pump()
- assert remote_a.state & Endpoint.REMOTE_CLOSED
- assert self.snd.queued == 10
-
- def testBufferingOnCloseLinkLink(self):
- self._testBufferingOnClose("link", "link")
-
- def testBufferingOnCloseLinkSession(self):
- self._testBufferingOnClose("link", "session")
-
- def testBufferingOnCloseLinkConnection(self):
- self._testBufferingOnClose("link", "connection")
-
- def testBufferingOnCloseSessionLink(self):
- self._testBufferingOnClose("session", "link")
-
- def testBufferingOnCloseSessionSession(self):
- self._testBufferingOnClose("session", "session")
-
- def testBufferingOnCloseSessionConnection(self):
- self._testBufferingOnClose("session", "connection")
-
- def testBufferingOnCloseConnectionLink(self):
- self._testBufferingOnClose("connection", "link")
-
- def testBufferingOnCloseConnectionSession(self):
- self._testBufferingOnClose("connection", "session")
-
- def testBufferingOnCloseConnectionConnection(self):
- self._testBufferingOnClose("connection", "connection")
-
- def testFullDrain(self):
- assert self.rcv.credit == 0
- assert self.snd.credit == 0
- self.rcv.drain(10)
- assert self.rcv.draining()
- assert self.rcv.credit == 10
- assert self.snd.credit == 0
- self.pump()
- assert self.rcv.credit == 10
- assert self.snd.credit == 10
- assert self.rcv.draining()
- self.snd.drained()
- assert self.rcv.credit == 10
- assert self.snd.credit == 0
- assert self.rcv.draining()
- self.pump()
- assert self.rcv.credit == 0
- assert self.snd.credit == 0
- assert not self.rcv.draining()
- drained = self.rcv.drained()
- assert drained == 10, drained
-
- def testPartialDrain(self):
- self.rcv.drain(2)
- assert self.rcv.draining()
- self.pump()
-
- d = self.snd.delivery("tag")
- assert d
- assert self.snd.advance()
- self.snd.drained()
- assert self.rcv.draining()
- self.pump()
- assert not self.rcv.draining()
-
- c = self.rcv.current
- assert self.rcv.queued == 1, self.rcv.queued
- assert c.tag == d.tag, c.tag
- assert self.rcv.advance()
- assert not self.rcv.current
- assert self.rcv.credit == 0, self.rcv.credit
- assert not self.rcv.draining()
- drained = self.rcv.drained()
- assert drained == 1, drained
-
- def testDrainFlow(self):
- assert self.rcv.credit == 0
- assert self.snd.credit == 0
- self.rcv.drain(10)
- assert self.rcv.credit == 10
- assert self.snd.credit == 0
- self.pump()
- assert self.rcv.credit == 10
- assert self.snd.credit == 10
- self.snd.drained()
- assert self.rcv.credit == 10
- assert self.snd.credit == 0
- self.pump()
- assert self.rcv.credit == 0
- assert self.snd.credit == 0
- self.rcv.flow(10)
- assert self.rcv.credit == 10
- assert self.snd.credit == 0
- self.pump()
- assert self.rcv.credit == 10
- assert self.snd.credit == 10
- self.snd.drained()
- assert self.rcv.credit == 10
- assert self.snd.credit == 10
- self.pump()
- assert self.rcv.credit == 10
- assert self.snd.credit == 10
- drained = self.rcv.drained()
- assert drained == 10, drained
-
- def testNegative(self):
- assert self.snd.credit == 0
- d = self.snd.delivery("tag")
- assert d
- assert self.snd.advance()
- self.pump()
-
- assert self.rcv.credit == 0
- assert self.rcv.queued == 0
-
- self.rcv.flow(1)
- assert self.rcv.credit == 1
- assert self.rcv.queued == 0
- self.pump()
- assert self.rcv.credit == 1
- assert self.rcv.queued == 1, self.rcv.queued
-
- c = self.rcv.current
- assert c
- assert c.tag == "tag"
- assert self.rcv.advance()
- assert self.rcv.credit == 0
- assert self.rcv.queued == 0
-
- def testDrainZero(self):
- assert self.snd.credit == 0
- assert self.rcv.credit == 0
- assert self.rcv.queued == 0
- drained = self.rcv.drained()
- assert drained == 0
-
- self.rcv.flow(10)
- self.pump()
- assert self.snd.credit == 10
- assert self.rcv.credit == 10
- assert self.rcv.queued == 0
-
- self.snd.drained()
- self.pump()
- assert self.snd.credit == 10
- assert self.rcv.credit == 10
- assert self.rcv.queued == 0
- drained = self.rcv.drained()
- assert drained == 0
-
- self.rcv.drain(0)
- assert self.snd.credit == 10
- assert self.rcv.credit == 10
- assert self.rcv.queued == 0
-
- self.pump()
-
- assert self.snd.credit == 10
- assert self.rcv.credit == 10
- assert self.rcv.queued == 0
-
- self.snd.drained()
- assert self.snd.credit == 0
- assert self.rcv.credit == 10
- assert self.rcv.queued == 0
- drained = self.rcv.drained()
- assert drained == 0
- self.pump()
-
- assert self.snd.credit == 0
- assert self.rcv.credit == 0
- assert self.rcv.queued == 0
- drained = self.rcv.drained()
- assert drained == 10
-
-
- def testDrainOrder(self):
- """ Verify drain/drained works regardless of ordering. See PROTON-401
- """
- assert self.snd.credit == 0
- assert self.rcv.credit == 0
- assert self.rcv.queued == 0
-
- #self.rcv.session.connection.transport.trace(Transport.TRACE_FRM)
- #self.snd.session.connection.transport.trace(Transport.TRACE_FRM)
-
- ## verify that a sender that has reached the drain state will respond
- ## promptly to a drain issued by the peer.
- self.rcv.flow(10)
- self.pump()
- assert self.snd.credit == 10, self.snd.credit
- assert self.rcv.credit == 10, self.rcv.credit
-
- sd = self.snd.delivery("tagA")
- assert sd
- n = self.snd.send(b"A")
- assert n == 1
- self.pump()
- self.snd.advance()
-
- # done sending, so signal that we are drained:
- self.snd.drained()
- self.pump()
- assert self.snd.credit == 9, self.snd.credit
- assert self.rcv.credit == 10, self.rcv.credit
-
- self.rcv.drain(0)
- self.pump()
- assert self.snd.credit == 9, self.snd.credit
- assert self.rcv.credit == 10, self.rcv.credit
-
- data = self.rcv.recv(10)
- assert data == b"A", data
- self.rcv.advance()
- self.pump()
- assert self.snd.credit == 9, self.snd.credit
- assert self.rcv.credit == 9, self.rcv.credit
-
- self.snd.drained()
- self.pump()
- assert self.snd.credit == 0, self.snd.credit
- assert self.rcv.credit == 0, self.rcv.credit
-
- # verify that a drain requested by the peer is not "acknowledged" until
- # after the sender has completed sending its pending messages
-
- self.rcv.flow(10)
- self.pump()
- assert self.snd.credit == 10, self.snd.credit
- assert self.rcv.credit == 10, self.rcv.credit
-
- sd = self.snd.delivery("tagB")
- assert sd
- n = self.snd.send(b"B")
- assert n == 1
- self.snd.advance()
- self.pump()
- assert self.snd.credit == 9, self.snd.credit
- assert self.rcv.credit == 10, self.rcv.credit
-
- self.rcv.drain(0)
- self.pump()
- assert self.snd.credit == 9, self.snd.credit
- assert self.rcv.credit == 10, self.rcv.credit
-
- sd = self.snd.delivery("tagC")
- assert sd
- n = self.snd.send(b"C")
- assert n == 1
- self.snd.advance()
- self.pump()
- assert self.snd.credit == 8, self.snd.credit
- assert self.rcv.credit == 10, self.rcv.credit
-
- # now that the sender has finished sending everything, it can signal
- # drained
- self.snd.drained()
- self.pump()
- assert self.snd.credit == 0, self.snd.credit
- assert self.rcv.credit == 2, self.rcv.credit
-
- data = self.rcv.recv(10)
- assert data == b"B", data
- self.rcv.advance()
- data = self.rcv.recv(10)
- assert data == b"C", data
- self.rcv.advance()
- self.pump()
- assert self.snd.credit == 0, self.snd.credit
- assert self.rcv.credit == 0, self.rcv.credit
-
-
- def testPushback(self, count=10):
- assert self.snd.credit == 0
- assert self.rcv.credit == 0
-
- self.rcv.flow(count)
- self.pump()
-
- for i in range(count):
- d = self.snd.delivery("tag%s" % i)
- assert d
- self.snd.advance()
-
- assert self.snd.queued == count
- assert self.rcv.queued == 0
- self.pump()
- assert self.snd.queued == 0
- assert self.rcv.queued == count
-
- d = self.snd.delivery("extra")
- self.snd.advance()
-
- assert self.snd.queued == 1
- assert self.rcv.queued == count
- self.pump()
- assert self.snd.queued == 1
- assert self.rcv.queued == count
-
- def testHeadOfLineBlocking(self):
- self.snd2 = self.snd.session.sender("link-2")
- self.rcv2 = self.rcv.session.receiver("link-2")
- self.snd2.open()
- self.rcv2.open()
- self.pump()
- assert self.snd2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
- assert self.rcv2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
-
- self.rcv.flow(5)
- self.rcv2.flow(10)
- self.pump()
-
- assert self.snd.credit == 5
- assert self.snd2.credit == 10
-
- for i in range(10):
- tag = "test %d" % i
- self.snd.delivery( tag )
- self.snd.send( tag.encode("ascii") )
- assert self.snd.advance()
- self.snd2.delivery( tag )
- self.snd2.send( tag.encode("ascii") )
- assert self.snd2.advance()
-
- self.pump()
-
- for i in range(5):
- b = self.rcv.recv( 512 )
- assert self.rcv.advance()
- b = self.rcv2.recv( 512 )
- assert self.rcv2.advance()
-
- for i in range(5):
- b = self.rcv2.recv( 512 )
- assert self.rcv2.advance()
+ def setUp(self):
+ self.snd, self.rcv = self.link("test-link", max_frame=(16*1024, 16*1024))
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+
+ def cleanup(self):
+ # release resources created by this class
+ super(CreditTest, self).cleanup()
+ self.c1 = None
+ self.snd = None
+ self.c2 = None
+ self.rcv2 = None
+ self.snd2 = None
+
+ def tearDown(self):
+ self.cleanup()
+
+ def testCreditSender(self, count=1024):
+ credit = self.snd.credit
+ assert credit == 0, credit
+ self.rcv.flow(10)
+ self.pump()
+ credit = self.snd.credit
+ assert credit == 10, credit
+
+ self.rcv.flow(count)
+ self.pump()
+ credit = self.snd.credit
+ assert credit == 10 + count, credit
+
+ def testCreditReceiver(self):
+ self.rcv.flow(10)
+ self.pump()
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ d = self.snd.delivery("tag")
+ assert d
+ assert self.snd.advance()
+ self.pump()
+ assert self.rcv.credit == 10, self.rcv.credit
+ assert self.rcv.queued == 1, self.rcv.queued
+ c = self.rcv.current
+ assert c.tag == "tag", c.tag
+ assert self.rcv.advance()
+ assert self.rcv.credit == 9, self.rcv.credit
+ assert self.rcv.queued == 0, self.rcv.queued
+
+ def _testBufferingOnClose(self, a, b):
+ for i in range(10):
+ d = self.snd.delivery("tag-%s" % i)
+ assert d
+ d.settle()
+ self.pump()
+ assert self.snd.queued == 10
+ endpoints = {"connection": (self.c1, self.c2),
+ "session": (self.snd.session, self.rcv.session),
+ "link": (self.snd, self.rcv)}
+
+ local_a, remote_a = endpoints[a]
+ local_b, remote_b = endpoints[b]
+
+ remote_b.close()
+ self.pump()
+ assert local_b.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED
+ local_a.close()
+ self.pump()
+ assert remote_a.state & Endpoint.REMOTE_CLOSED
+ assert self.snd.queued == 10
+
+ def testBufferingOnCloseLinkLink(self):
+ self._testBufferingOnClose("link", "link")
+
+ def testBufferingOnCloseLinkSession(self):
+ self._testBufferingOnClose("link", "session")
+
+ def testBufferingOnCloseLinkConnection(self):
+ self._testBufferingOnClose("link", "connection")
+
+ def testBufferingOnCloseSessionLink(self):
+ self._testBufferingOnClose("session", "link")
+
+ def testBufferingOnCloseSessionSession(self):
+ self._testBufferingOnClose("session", "session")
+
+ def testBufferingOnCloseSessionConnection(self):
+ self._testBufferingOnClose("session", "connection")
+
+ def testBufferingOnCloseConnectionLink(self):
+ self._testBufferingOnClose("connection", "link")
+
+ def testBufferingOnCloseConnectionSession(self):
+ self._testBufferingOnClose("connection", "session")
+
+ def testBufferingOnCloseConnectionConnection(self):
+ self._testBufferingOnClose("connection", "connection")
+
+ def testFullDrain(self):
+ assert self.rcv.credit == 0
+ assert self.snd.credit == 0
+ self.rcv.drain(10)
+ assert self.rcv.draining()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 0
+ self.pump()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 10
+ assert self.rcv.draining()
+ self.snd.drained()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 0
+ assert self.rcv.draining()
+ self.pump()
+ assert self.rcv.credit == 0
+ assert self.snd.credit == 0
+ assert not self.rcv.draining()
+ drained = self.rcv.drained()
+ assert drained == 10, drained
+
+ def testPartialDrain(self):
+ self.rcv.drain(2)
+ assert self.rcv.draining()
+ self.pump()
+
+ d = self.snd.delivery("tag")
+ assert d
+ assert self.snd.advance()
+ self.snd.drained()
+ assert self.rcv.draining()
+ self.pump()
+ assert not self.rcv.draining()
+
+ c = self.rcv.current
+ assert self.rcv.queued == 1, self.rcv.queued
+ assert c.tag == d.tag, c.tag
+ assert self.rcv.advance()
+ assert not self.rcv.current
+ assert self.rcv.credit == 0, self.rcv.credit
+ assert not self.rcv.draining()
+ drained = self.rcv.drained()
+ assert drained == 1, drained
+
+ def testDrainFlow(self):
+ assert self.rcv.credit == 0
+ assert self.snd.credit == 0
+ self.rcv.drain(10)
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 0
+ self.pump()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 10
+ self.snd.drained()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 0
+ self.pump()
+ assert self.rcv.credit == 0
+ assert self.snd.credit == 0
+ self.rcv.flow(10)
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 0
+ self.pump()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 10
+ self.snd.drained()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 10
+ self.pump()
+ assert self.rcv.credit == 10
+ assert self.snd.credit == 10
+ drained = self.rcv.drained()
+ assert drained == 10, drained
+
+ def testNegative(self):
+ assert self.snd.credit == 0
+ d = self.snd.delivery("tag")
+ assert d
+ assert self.snd.advance()
+ self.pump()
+
+ assert self.rcv.credit == 0
+ assert self.rcv.queued == 0
+
+ self.rcv.flow(1)
+ assert self.rcv.credit == 1
+ assert self.rcv.queued == 0
+ self.pump()
+ assert self.rcv.credit == 1
+ assert self.rcv.queued == 1, self.rcv.queued
+
+ c = self.rcv.current
+ assert c
+ assert c.tag == "tag"
+ assert self.rcv.advance()
+ assert self.rcv.credit == 0
+ assert self.rcv.queued == 0
+
+ def testDrainZero(self):
+ assert self.snd.credit == 0
+ assert self.rcv.credit == 0
+ assert self.rcv.queued == 0
+ drained = self.rcv.drained()
+ assert drained == 0
+
+ self.rcv.flow(10)
+ self.pump()
+ assert self.snd.credit == 10
+ assert self.rcv.credit == 10
+ assert self.rcv.queued == 0
+
+ self.snd.drained()
+ self.pump()
+ assert self.snd.credit == 10
+ assert self.rcv.credit == 10
+ assert self.rcv.queued == 0
+ drained = self.rcv.drained()
+ assert drained == 0
+
+ self.rcv.drain(0)
+ assert self.snd.credit == 10
+ assert self.rcv.credit == 10
+ assert self.rcv.queued == 0
+
+ self.pump()
+
+ assert self.snd.credit == 10
+ assert self.rcv.credit == 10
+ assert self.rcv.queued == 0
+
+ self.snd.drained()
+ assert self.snd.credit == 0
+ assert self.rcv.credit == 10
+ assert self.rcv.queued == 0
+ drained = self.rcv.drained()
+ assert drained == 0
+ self.pump()
+
+ assert self.snd.credit == 0
+ assert self.rcv.credit == 0
+ assert self.rcv.queued == 0
+ drained = self.rcv.drained()
+ assert drained == 10
+
+ def testDrainOrder(self):
+ """ Verify drain/drained works regardless of ordering. See PROTON-401
+ """
+ assert self.snd.credit == 0
+ assert self.rcv.credit == 0
+ assert self.rcv.queued == 0
+
+ # self.rcv.session.connection.transport.trace(Transport.TRACE_FRM)
+ # self.snd.session.connection.transport.trace(Transport.TRACE_FRM)
+
+ # verify that a sender that has reached the drain state will respond
+ # promptly to a drain issued by the peer.
+ self.rcv.flow(10)
+ self.pump()
+ assert self.snd.credit == 10, self.snd.credit
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ sd = self.snd.delivery("tagA")
+ assert sd
+ n = self.snd.send(b"A")
+ assert n == 1
+ self.pump()
+ self.snd.advance()
+
+ # done sending, so signal that we are drained:
+ self.snd.drained()
+ self.pump()
+ assert self.snd.credit == 9, self.snd.credit
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ self.rcv.drain(0)
+ self.pump()
+ assert self.snd.credit == 9, self.snd.credit
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ data = self.rcv.recv(10)
+ assert data == b"A", data
+ self.rcv.advance()
+ self.pump()
+ assert self.snd.credit == 9, self.snd.credit
+ assert self.rcv.credit == 9, self.rcv.credit
+
+ self.snd.drained()
+ self.pump()
+ assert self.snd.credit == 0, self.snd.credit
+ assert self.rcv.credit == 0, self.rcv.credit
+
+ # verify that a drain requested by the peer is not "acknowledged" until
+ # after the sender has completed sending its pending messages
+
+ self.rcv.flow(10)
+ self.pump()
+ assert self.snd.credit == 10, self.snd.credit
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ sd = self.snd.delivery("tagB")
+ assert sd
+ n = self.snd.send(b"B")
+ assert n == 1
+ self.snd.advance()
+ self.pump()
+ assert self.snd.credit == 9, self.snd.credit
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ self.rcv.drain(0)
+ self.pump()
+ assert self.snd.credit == 9, self.snd.credit
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ sd = self.snd.delivery("tagC")
+ assert sd
+ n = self.snd.send(b"C")
+ assert n == 1
+ self.snd.advance()
+ self.pump()
+ assert self.snd.credit == 8, self.snd.credit
+ assert self.rcv.credit == 10, self.rcv.credit
+
+ # now that the sender has finished sending everything, it can signal
+ # drained
+ self.snd.drained()
+ self.pump()
+ assert self.snd.credit == 0, self.snd.credit
+ assert self.rcv.credit == 2, self.rcv.credit
+
+ data = self.rcv.recv(10)
+ assert data == b"B", data
+ self.rcv.advance()
+ data = self.rcv.recv(10)
+ assert data == b"C", data
+ self.rcv.advance()
+ self.pump()
+ assert self.snd.credit == 0, self.snd.credit
+ assert self.rcv.credit == 0, self.rcv.credit
+
+ def testPushback(self, count=10):
+ assert self.snd.credit == 0
+ assert self.rcv.credit == 0
+
+ self.rcv.flow(count)
+ self.pump()
+
+ for i in range(count):
+ d = self.snd.delivery("tag%s" % i)
+ assert d
+ self.snd.advance()
+
+ assert self.snd.queued == count
+ assert self.rcv.queued == 0
+ self.pump()
+ assert self.snd.queued == 0
+ assert self.rcv.queued == count
+
+ d = self.snd.delivery("extra")
+ self.snd.advance()
+
+ assert self.snd.queued == 1
+ assert self.rcv.queued == count
+ self.pump()
+ assert self.snd.queued == 1
+ assert self.rcv.queued == count
+
+ def testHeadOfLineBlocking(self):
+ self.snd2 = self.snd.session.sender("link-2")
+ self.rcv2 = self.rcv.session.receiver("link-2")
+ self.snd2.open()
+ self.rcv2.open()
+ self.pump()
+ assert self.snd2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+ assert self.rcv2.state == Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE
+
+ self.rcv.flow(5)
+ self.rcv2.flow(10)
+ self.pump()
+
+ assert self.snd.credit == 5
+ assert self.snd2.credit == 10
+
+ for i in range(10):
+ tag = "test %d" % i
+ self.snd.delivery(tag)
+ self.snd.send(tag.encode("ascii"))
+ assert self.snd.advance()
+ self.snd2.delivery(tag)
+ self.snd2.send(tag.encode("ascii"))
+ assert self.snd2.advance()
+
+ self.pump()
+
+ for i in range(5):
+ b = self.rcv.recv(512)
+ assert self.rcv.advance()
+ b = self.rcv2.recv(512)
+ assert self.rcv2.advance()
+
+ for i in range(5):
+ b = self.rcv2.recv(512)
+ assert self.rcv2.advance()
class SessionCreditTest(Test):
- def tearDown(self):
- self.cleanup()
-
- def testBuffering(self, count=32, size=1024, capacity=16*1024, max_frame=1024):
- snd, rcv = self.link("test-link", max_frame=(max_frame, max_frame))
- rcv.session.incoming_capacity = capacity
- snd.open()
- rcv.open()
- rcv.flow(count)
- self.pump()
-
- assert count > 0
-
- total_bytes = count * size
-
- assert snd.session.outgoing_bytes == 0, snd.session.outgoing_bytes
- assert rcv.session.incoming_bytes == 0, rcv.session.incoming_bytes
- assert snd.queued == 0, snd.queued
- assert rcv.queued == 0, rcv.queued
-
- data = bytes(bytearray(size))
- idx = 0
- while snd.credit:
- d = snd.delivery("tag%s" % idx)
- assert d
- n = snd.send(data)
- assert n == size, (n, size)
- assert snd.advance()
- self.pump()
- idx += 1
-
- assert idx == count, (idx, count)
-
- assert snd.session.outgoing_bytes < total_bytes, (snd.session.outgoing_bytes, total_bytes)
- assert rcv.session.incoming_bytes < capacity, (rcv.session.incoming_bytes, capacity)
- assert snd.session.outgoing_bytes + rcv.session.incoming_bytes == total_bytes, \
- (snd.session.outgoing_bytes, rcv.session.incoming_bytes, total_bytes)
- if snd.session.outgoing_bytes > 0:
- available = rcv.session.incoming_capacity - rcv.session.incoming_bytes
- assert available < max_frame, (available, max_frame)
-
- for i in range(count):
- d = rcv.current
- assert d, i
- pending = d.pending
- before = rcv.session.incoming_bytes
- assert rcv.advance()
- after = rcv.session.incoming_bytes
- assert before - after == pending, (before, after, pending)
- snd_before = snd.session.incoming_bytes
- self.pump()
- snd_after = snd.session.incoming_bytes
-
- assert rcv.session.incoming_bytes < capacity
- if snd_before > 0:
- assert capacity - after <= max_frame
- assert snd_before > snd_after
- if snd_after > 0:
- available = rcv.session.incoming_capacity - rcv.session.incoming_bytes
- assert available < max_frame, available
-
- def testBufferingSize16(self):
- self.testBuffering(size=16)
-
- def testBufferingSize256(self):
- self.testBuffering(size=256)
-
- def testBufferingSize512(self):
- self.testBuffering(size=512)
-
- def testBufferingSize2048(self):
- self.testBuffering(size=2048)
-
- def testBufferingSize1025(self):
- self.testBuffering(size=1025)
-
- def testBufferingSize1023(self):
- self.testBuffering(size=1023)
-
- def testBufferingSize989(self):
- self.testBuffering(size=989)
-
- def testBufferingSize1059(self):
- self.testBuffering(size=1059)
-
- def testCreditWithBuffering(self):
- snd, rcv = self.link("test-link", max_frame=(1024, 1024))
- rcv.session.incoming_capacity = 64*1024
- snd.open()
- rcv.open()
- rcv.flow(128)
- self.pump()
-
- assert snd.credit == 128, snd.credit
- assert rcv.queued == 0, rcv.queued
-
- idx = 0
- while snd.credit:
- d = snd.delivery("tag%s" % idx)
- snd.send(("x"*1024).encode('ascii'))
- assert d
- assert snd.advance()
- self.pump()
- idx += 1
-
- assert idx == 128, idx
- assert rcv.queued < 128, rcv.queued
-
- rcv.flow(1)
- self.pump()
- assert snd.credit == 1, snd.credit
+ def tearDown(self):
+ self.cleanup()
+
+ def testBuffering(self, count=32, size=1024, capacity=16*1024, max_frame=1024):
+ snd, rcv = self.link("test-link", max_frame=(max_frame, max_frame))
+ rcv.session.incoming_capacity = capacity
+ snd.open()
+ rcv.open()
+ rcv.flow(count)
+ self.pump()
+
+ assert count > 0
+
+ total_bytes = count * size
+
+ assert snd.session.outgoing_bytes == 0, snd.session.outgoing_bytes
+ assert rcv.session.incoming_bytes == 0, rcv.session.incoming_bytes
+ assert snd.queued == 0, snd.queued
+ assert rcv.queued == 0, rcv.queued
+
+ data = bytes(bytearray(size))
+ idx = 0
+ while snd.credit:
+ d = snd.delivery("tag%s" % idx)
+ assert d
+ n = snd.send(data)
+ assert n == size, (n, size)
+ assert snd.advance()
+ self.pump()
+ idx += 1
+
+ assert idx == count, (idx, count)
+
+ assert snd.session.outgoing_bytes < total_bytes, (snd.session.outgoing_bytes, total_bytes)
+ assert rcv.session.incoming_bytes < capacity, (rcv.session.incoming_bytes, capacity)
+ assert snd.session.outgoing_bytes + rcv.session.incoming_bytes == total_bytes, \
+ (snd.session.outgoing_bytes, rcv.session.incoming_bytes, total_bytes)
+ if snd.session.outgoing_bytes > 0:
+ available = rcv.session.incoming_capacity - rcv.session.incoming_bytes
+ assert available < max_frame, (available, max_frame)
+
+ for i in range(count):
+ d = rcv.current
+ assert d, i
+ pending = d.pending
+ before = rcv.session.incoming_bytes
+ assert rcv.advance()
+ after = rcv.session.incoming_bytes
+ assert before - after == pending, (before, after, pending)
+ snd_before = snd.session.incoming_bytes
+ self.pump()
+ snd_after = snd.session.incoming_bytes
+
+ assert rcv.session.incoming_bytes < capacity
+ if snd_before > 0:
+ assert capacity - after <= max_frame
+ assert snd_before > snd_after
+ if snd_after > 0:
+ available = rcv.session.incoming_capacity - rcv.session.incoming_bytes
+ assert available < max_frame, available
+
+ def testBufferingSize16(self):
+ self.testBuffering(size=16)
+
+ def testBufferingSize256(self):
+ self.testBuffering(size=256)
+
+ def testBufferingSize512(self):
+ self.testBuffering(size=512)
+
+ def testBufferingSize2048(self):
+ self.testBuffering(size=2048)
+
+ def testBufferingSize1025(self):
+ self.testBuffering(size=1025)
+
+ def testBufferingSize1023(self):
+ self.testBuffering(size=1023)
+
+ def testBufferingSize989(self):
+ self.testBuffering(size=989)
+
+ def testBufferingSize1059(self):
+ self.testBuffering(size=1059)
+
+ def testCreditWithBuffering(self):
+ snd, rcv = self.link("test-link", max_frame=(1024, 1024))
+ rcv.session.incoming_capacity = 64*1024
+ snd.open()
+ rcv.open()
+ rcv.flow(128)
+ self.pump()
+
+ assert snd.credit == 128, snd.credit
+ assert rcv.queued == 0, rcv.queued
+
+ idx = 0
+ while snd.credit:
+ d = snd.delivery("tag%s" % idx)
+ snd.send(("x"*1024).encode('ascii'))
+ assert d
+ assert snd.advance()
+ self.pump()
+ idx += 1
+
+ assert idx == 128, idx
+ assert rcv.queued < 128, rcv.queued
+
+ rcv.flow(1)
+ self.pump()
+ assert snd.credit == 1, snd.credit
+
class SettlementTest(Test):
- def setUp(self):
- self.snd, self.rcv = self.link("test-link")
- self.c1 = self.snd.session.connection
- self.c2 = self.rcv.session.connection
- self.snd.open()
- self.rcv.open()
- self.pump()
-
- def cleanup(self):
- # release resources created by this class
- super(SettlementTest, self).cleanup()
- self.c1 = None
- self.snd = None
- self.c2 = None
- self.rcv2 = None
- self.snd2 = None
-
- def tearDown(self):
- self.cleanup()
-
- def testSettleCurrent(self):
- self.rcv.flow(10)
- self.pump()
-
- assert self.snd.credit == 10, self.snd.credit
- d = self.snd.delivery("tag")
- e = self.snd.delivery("tag2")
- assert d
- assert e
- c = self.snd.current
- assert c.tag == "tag", c.tag
- c.settle()
- c = self.snd.current
- assert c.tag == "tag2", c.tag
- c.settle()
- c = self.snd.current
- assert not c
- self.pump()
-
- c = self.rcv.current
- assert c
- assert c.tag == "tag", c.tag
- assert c.settled
- c.settle()
- c = self.rcv.current
- assert c
- assert c.tag == "tag2", c.tag
- assert c.settled
- c.settle()
- c = self.rcv.current
- assert not c
-
- def testUnsettled(self):
- self.rcv.flow(10)
- self.pump()
-
- assert self.snd.unsettled == 0, self.snd.unsettled
- assert self.rcv.unsettled == 0, self.rcv.unsettled
-
- d = self.snd.delivery("tag")
- assert d
- assert self.snd.unsettled == 1, self.snd.unsettled
- assert self.rcv.unsettled == 0, self.rcv.unsettled
- assert self.snd.advance()
- self.pump()
-
- assert self.snd.unsettled == 1, self.snd.unsettled
- assert self.rcv.unsettled == 1, self.rcv.unsettled
-
- c = self.rcv.current
- assert c
- c.settle()
-
- assert self.snd.unsettled == 1, self.snd.unsettled
- assert self.rcv.unsettled == 0, self.rcv.unsettled
-
- def testMultipleUnsettled(self, count=1024, size=1024):
- self.rcv.flow(count)
- self.pump()
-
- assert self.snd.unsettled == 0, self.snd.unsettled
- assert self.rcv.unsettled == 0, self.rcv.unsettled
-
- unsettled = []
-
- for i in range(count):
- sd = self.snd.delivery("tag%s" % i)
- assert sd
- n = self.snd.send(("x"*size).encode('ascii'))
- assert n == size, n
- assert self.snd.advance()
- self.pump()
-
- rd = self.rcv.current
- assert rd, "did not receive delivery %s" % i
- n = rd.pending
- b = self.rcv.recv(n)
- assert len(b) == n, (b, n)
- rd.update(Delivery.ACCEPTED)
- assert self.rcv.advance()
- self.pump()
- unsettled.append(rd)
-
- assert self.rcv.unsettled == count
-
- for rd in unsettled:
- rd.settle()
-
- def testMultipleUnsettled2K1K(self):
- self.testMultipleUnsettled(2048, 1024)
-
- def testMultipleUnsettled4K1K(self):
- self.testMultipleUnsettled(4096, 1024)
-
- def testMultipleUnsettled1K2K(self):
- self.testMultipleUnsettled(1024, 2048)
-
- def testMultipleUnsettled2K2K(self):
- self.testMultipleUnsettled(2048, 2048)
-
- def testMultipleUnsettled4K2K(self):
- self.testMultipleUnsettled(4096, 2048)
+ def setUp(self):
+ self.snd, self.rcv = self.link("test-link")
+ self.c1 = self.snd.session.connection
+ self.c2 = self.rcv.session.connection
+ self.snd.open()
+ self.rcv.open()
+ self.pump()
+
+ def cleanup(self):
+ # release resources created by this class
+ super(SettlementTest, self).cleanup()
+ self.c1 = None
+ self.snd = None
+ self.c2 = None
+ self.rcv2 = None
+ self.snd2 = None
+
+ def tearDown(self):
+ self.cleanup()
+
+ def testSettleCurrent(self):
+ self.rcv.flow(10)
+ self.pump()
+
+ assert self.snd.credit == 10, self.snd.credit
+ d = self.snd.delivery("tag")
+ e = self.snd.delivery("tag2")
+ assert d
+ assert e
+ c = self.snd.current
+ assert c.tag == "tag", c.tag
+ c.settle()
+ c = self.snd.current
+ assert c.tag == "tag2", c.tag
+ c.settle()
+ c = self.snd.current
+ assert not c
+ self.pump()
+
+ c = self.rcv.current
+ assert c
+ assert c.tag == "tag", c.tag
+ assert c.settled
+ c.settle()
+ c = self.rcv.current
+ assert c
+ assert c.tag == "tag2", c.tag
+ assert c.settled
+ c.settle()
+ c = self.rcv.current
+ assert not c
+
+ def testUnsettled(self):
+ self.rcv.flow(10)
+ self.pump()
+
+ assert self.snd.unsettled == 0, self.snd.unsettled
+ assert self.rcv.unsettled == 0, self.rcv.unsettled
+
+ d = self.snd.delivery("tag")
+ assert d
+ assert self.snd.unsettled == 1, self.snd.unsettled
+ assert self.rcv.unsettled == 0, self.rcv.unsettled
+ assert self.snd.advance()
+ self.pump()
+
+ assert self.snd.unsettled == 1, self.snd.unsettled
+ assert self.rcv.unsettled == 1, self.rcv.unsettled
+
+ c = self.rcv.current
+ assert c
+ c.settle()
+
+ assert self.snd.unsettled == 1, self.snd.unsettled
+ assert self.rcv.unsettled == 0, self.rcv.unsettled
+
+ def testMultipleUnsettled(self, count=1024, size=1024):
+ self.rcv.flow(count)
+ self.pump()
+
+ assert self.snd.unsettled == 0, self.snd.unsettled
+ assert self.rcv.unsettled == 0, self.rcv.unsettled
+
+ unsettled = []
+
+ for i in range(count):
+ sd = self.snd.delivery("tag%s" % i)
+ assert sd
+ n = self.snd.send(("x"*size).encode('ascii'))
+ assert n == size, n
+ assert self.snd.advance()
+ self.pump()
+
+ rd = self.rcv.current
+ assert rd, "did not receive delivery %s" % i
+ n = rd.pending
+ b = self.rcv.recv(n)
+ assert len(b) == n, (b, n)
+ rd.update(Delivery.ACCEPTED)
+ assert self.rcv.advance()
+ self.pump()
+ unsettled.append(rd)
+
+ assert self.rcv.unsettled == count
+
+ for rd in unsettled:
+ rd.settle()
+
+ def testMultipleUnsettled2K1K(self):
+ self.testMultipleUnsettled(2048, 1024)
+
+ def testMultipleUnsettled4K1K(self):
+ self.testMultipleUnsettled(4096, 1024)
+
+ def testMultipleUnsettled1K2K(self):
+ self.testMultipleUnsettled(1024, 2048)
+
+ def testMultipleUnsettled2K2K(self):
+ self.testMultipleUnsettled(2048, 2048)
+
+ def testMultipleUnsettled4K2K(self):
+ self.testMultipleUnsettled(4096, 2048)
+
class PipelineTest(Test):
- def setUp(self):
- self.c1, self.c2 = self.connection()
-
- def cleanup(self):
- # release resources created by this class
- super(PipelineTest, self).cleanup()
- self.c1 = None
- self.c2 = None
-
- def tearDown(self):
- self.cleanup()
-
- def test(self):
- ssn = self.c1.session()
- snd = ssn.sender("sender")
- self.c1.open()
- ssn.open()
- snd.open()
-
- for i in range(10):
- t = "delivery-%s" % i
- d = snd.delivery(t)
- snd.send(t.encode('ascii'))
- d.settle()
-
- snd.close()
- ssn.close()
- self.c1.close()
-
- self.pump()
-
- state = self.c2.state
- assert state == (Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE), "%x" % state
- ssn2 = self.c2.session_head(Endpoint.LOCAL_UNINIT)
- assert ssn2
- state == ssn2.state
- assert state == (Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE), "%x" % state
- rcv = self.c2.link_head(Endpoint.LOCAL_UNINIT)
- assert rcv
- state = rcv.state
- assert state == (Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE), "%x" % state
-
- self.c2.open()
- ssn2.open()
- rcv.open()
- rcv.flow(10)
- assert rcv.queued == 0, rcv.queued
-
- self.pump()
-
- assert rcv.queued == 10, rcv.queued
- state = rcv.state
- assert state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED), "%x" % state
- state = ssn2.state
- assert state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED), "%x" % state
- state = self.c2.state
- assert state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED), "%x" % state
-
- for i in range(rcv.queued):
- d = rcv.current
- assert d
- assert d.tag == "delivery-%s" % i
- d.settle()
-
- assert rcv.queued == 0, rcv.queued
+ def setUp(self):
+ self.c1, self.c2 = self.connection()
+
+ def cleanup(self):
+ # release resources created by this class
+ super(PipelineTest, self).cleanup()
+ self.c1 = None
+ self.c2 = None
+
+ def tearDown(self):
+ self.cleanup()
+
+ def test(self):
+ ssn = self.c1.session()
+ snd = ssn.sender("sender")
+ self.c1.open()
+ ssn.open()
+ snd.open()
+
+ for i in range(10):
+ t = "delivery-%s" % i
+ d = snd.delivery(t)
+ snd.send(t.encode('ascii'))
+ d.settle()
+
+ snd.close()
+ ssn.close()
+ self.c1.close()
+
+ self.pump()
+
+ state = self.c2.state
+ assert state == (Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE), "%x" % state
+ ssn2 = self.c2.session_head(Endpoint.LOCAL_UNINIT)
+ assert ssn2
+ state == ssn2.state
+ assert state == (Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE), "%x" % state
+ rcv = self.c2.link_head(Endpoint.LOCAL_UNINIT)
+ assert rcv
+ state = rcv.state
+ assert state == (Endpoint.LOCAL_UNINIT | Endpoint.REMOTE_ACTIVE), "%x" % state
+
+ self.c2.open()
+ ssn2.open()
+ rcv.open()
+ rcv.flow(10)
+ assert rcv.queued == 0, rcv.queued
+
+ self.pump()
+
+ assert rcv.queued == 10, rcv.queued
+ state = rcv.state
+ assert state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED), "%x" % state
+ state = ssn2.state
+ assert state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED), "%x" % state
+ state = self.c2.state
+ assert state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_CLOSED), "%x" % state
+
+ for i in range(rcv.queued):
+ d = rcv.current
+ assert d
+ assert d.tag == "delivery-%s" % i
+ d.settle()
+
+ assert rcv.queued == 0, rcv.queued
class ServerTest(Test):
- def testKeepalive(self):
- """ Verify that idle frames are sent to keep a Connection alive
- """
- idle_timeout = self.delay
- server = common.TestServer()
- server.start()
-
- class Program:
-
- def on_reactor_init(self, event):
- self.conn = event.reactor.connection()
- self.conn.hostname = "%s:%s" % (server.host, server.port)
- self.conn.open()
- self.old_count = None
- event.reactor.schedule(3 * idle_timeout, self)
-
- def on_connection_bound(self, event):
- event.transport.idle_timeout = idle_timeout
-
- def on_connection_remote_open(self, event):
- self.old_count = event.transport.frames_input
-
- def on_timer_task(self, event):
- assert self.conn.state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE), "Connection terminated"
- assert self.conn.transport.frames_input > self.old_count, "No idle frames received"
- self.conn.close()
-
- Container(Program()).run()
- server.stop()
-
- def testIdleTimeout(self):
- """ Verify that a Connection is terminated properly when Idle frames do not
- arrive in a timely manner.
- """
- idle_timeout = self.delay
- server = common.TestServer(idle_timeout=idle_timeout)
- server.start()
-
- class Program:
-
- def on_reactor_init(self, event):
- self.conn = event.reactor.connection()
- self.conn.hostname = "%s:%s" % (server.host, server.port)
- self.conn.open()
- self.remote_condition = None
- self.old_count = None
- # verify the connection stays up even if we don't explicitly send stuff
- # wait up to 3x the idle timeout
- event.reactor.schedule(3 * idle_timeout, self)
-
- def on_connection_bound(self, event):
- self.transport = event.transport
-
- def on_connection_remote_open(self, event):
- self.old_count = event.transport.frames_output
-
- def on_connection_remote_close(self, event):
- assert self.conn.remote_condition
- assert self.conn.remote_condition.name == "amqp:resource-limit-exceeded"
- self.remote_condition = self.conn.remote_condition
-
- def on_timer_task(self, event):
- assert self.conn.state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE), "Connection terminated"
- assert self.conn.transport.frames_output > self.old_count, "No idle frames sent"
-
- # now wait to explicitly cause the other side to expire:
- suspend_time = 3 * idle_timeout
- if os.name=="nt":
- # On windows, the full delay gets too close to the graceful/hard close tipping point
- suspend_time = 2.5 * idle_timeout
- sleep(suspend_time)
-
- p = Program()
- Container(p).run()
- assert p.remote_condition
- assert p.remote_condition.name == "amqp:resource-limit-exceeded"
- server.stop()
+ def testKeepalive(self):
+ """ Verify that idle frames are sent to keep a Connection alive
+ """
+ idle_timeout = self.delay
+ server = common.TestServer()
+ server.start()
+
+ class Program:
+
+ def on_reactor_init(self, event):
+ self.conn = event.reactor.connection()
+ self.conn.hostname = "%s:%s" % (server.host, server.port)
+ self.conn.open()
+ self.old_count = None
+ event.reactor.schedule(3 * idle_timeout, self)
+
+ def on_connection_bound(self, event):
+ event.transport.idle_timeout = idle_timeout
+
+ def on_connection_remote_open(self, event):
+ self.old_count = event.transport.frames_input
+
+ def on_timer_task(self, event):
+ assert self.conn.state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE), "Connection terminated"
+ assert self.conn.transport.frames_input > self.old_count, "No idle frames received"
+ self.conn.close()
+
+ Container(Program()).run()
+ server.stop()
+
+ def testIdleTimeout(self):
+ """ Verify that a Connection is terminated properly when Idle frames do not
+ arrive in a timely manner.
+ """
+ idle_timeout = self.delay
+ server = common.TestServer(idle_timeout=idle_timeout)
+ server.start()
+
+ class Program:
+
+ def on_reactor_init(self, event):
+ self.conn = event.reactor.connection()
+ self.conn.hostname = "%s:%s" % (server.host, server.port)
+ self.conn.open()
+ self.remote_condition = None
+ self.old_count = None
+ # verify the connection stays up even if we don't explicitly send stuff
+ # wait up to 3x the idle timeout
+ event.reactor.schedule(3 * idle_timeout, self)
+
+ def on_connection_bound(self, event):
+ self.transport = event.transport
+
+ def on_connection_remote_open(self, event):
+ self.old_count = event.transport.frames_output
+
+ def on_connection_remote_close(self, event):
+ assert self.conn.remote_condition
+ assert self.conn.remote_condition.name == "amqp:resource-limit-exceeded"
+ self.remote_condition = self.conn.remote_condition
+
+ def on_timer_task(self, event):
+ assert self.conn.state == (Endpoint.LOCAL_ACTIVE | Endpoint.REMOTE_ACTIVE), "Connection terminated"
+ assert self.conn.transport.frames_output > self.old_count, "No idle frames sent"
+
+ # now wait to explicitly cause the other side to expire:
+ suspend_time = 3 * idle_timeout
+ if os.name == "nt":
+ # On windows, the full delay gets too close to the graceful/hard close tipping point
+ suspend_time = 2.5 * idle_timeout
+ sleep(suspend_time)
+
+ p = Program()
+ Container(p).run()
+ assert p.remote_condition
+ assert p.remote_condition.name == "amqp:resource-limit-exceeded"
+ server.stop()
+
class NoValue:
- def __init__(self):
- pass
+ def __init__(self):
+ pass
- def apply(self, dlv):
- pass
+ def apply(self, dlv):
+ pass
+
+ def check(self, dlv):
+ assert dlv.data == None
+ assert dlv.section_number == 0
+ assert dlv.section_offset == 0
+ assert dlv.condition == None
+ assert dlv.failed == False
+ assert dlv.undeliverable == False
+ assert dlv.annotations == None
- def check(self, dlv):
- assert dlv.data == None
- assert dlv.section_number == 0
- assert dlv.section_offset == 0
- assert dlv.condition == None
- assert dlv.failed == False
- assert dlv.undeliverable == False
- assert dlv.annotations == None
class RejectValue:
- def __init__(self, condition):
- self.condition = condition
+ def __init__(self, condition):
+ self.condition = condition
+
+ def apply(self, dlv):
+ dlv.condition = self.condition
- def apply(self, dlv):
- dlv.condition = self.condition
+ def check(self, dlv):
+ assert dlv.data == None, dlv.data
+ assert dlv.section_number == 0
+ assert dlv.section_offset == 0
+ assert dlv.condition == self.condition, (dlv.condition, self.condition)
+ assert dlv.failed == False
+ assert dlv.undeliverable == False
+ assert dlv.annotations == None
- def check(self, dlv):
- assert dlv.data == None, dlv.data
- assert dlv.section_number == 0
- assert dlv.section_offset == 0
- assert dlv.condition == self.condition, (dlv.condition, self.condition)
- assert dlv.failed == False
- assert dlv.undeliverable == False
- assert dlv.annotations == None
class ReceivedValue:
- def __init__(self, section_number, section_offset):
- self.section_number = section_number
- self.section_offset = section_offset
-
- def apply(self, dlv):
- dlv.section_number = self.section_number
- dlv.section_offset = self.section_offset
-
- def check(self, dlv):
- assert dlv.data == None, dlv.data
- assert dlv.section_number == self.section_number, (dlv.section_number, self.section_number)
- assert dlv.section_offset == self.section_offset
- assert dlv.condition == None
- assert dlv.failed == False
- assert dlv.undeliverable == False
- assert dlv.annotations == None
+ def __init__(self, section_number, section_offset):
+ self.section_number = section_number
+ self.section_offset = section_offset
+
+ def apply(self, dlv):
+ dlv.section_number = self.section_number
+ dlv.section_offset = self.section_offset
+
+ def check(self, dlv):
+ assert dlv.data == None, dlv.data
+ assert dlv.section_number == self.section_number, (dlv.section_number, self.section_number)
+ assert dlv.section_offset == self.section_offset
+ assert dlv.condition == None
+ assert dlv.failed == False
+ assert dlv.undeliverable == False
+ assert dlv.annotations == None
+
class ModifiedValue:
- def __init__(self, failed, undeliverable, annotations):
- self.failed = failed
- self.undeliverable = undeliverable
- self.annotations = annotations
-
- def apply(self, dlv):
- dlv.failed = self.failed
- dlv.undeliverable = self.undeliverable
- dlv.annotations = self.annotations
-
- def check(self, dlv):
- assert dlv.data == None, dlv.data
- assert dlv.section_number == 0
- assert dlv.section_offset == 0
- assert dlv.condition == None
- assert dlv.failed == self.failed
- assert dlv.undeliverable == self.undeliverable
- assert dlv.annotations == self.annotations, (dlv.annotations, self.annotations)
+ def __init__(self, failed, undeliverable, annotations):
+ self.failed = failed
+ self.undeliverable = undeliverable
+ self.annotations = annotations
+
+ def apply(self, dlv):
+ dlv.failed = self.failed
+ dlv.undeliverable = self.undeliverable
+ dlv.annotations = self.annotations
+
+ def check(self, dlv):
+ assert dlv.data == None, dlv.data
+ assert dlv.section_number == 0
+ assert dlv.section_offset == 0
+ assert dlv.condition == None
+ assert dlv.failed == self.failed
+ assert dlv.undeliverable == self.undeliverable
+ assert dlv.annotations == self.annotations, (dlv.annotations, self.annotations)
+
class CustomValue:
- def __init__(self, data):
- self.data = data
+ def __init__(self, data):
+ self.data = data
+
+ def apply(self, dlv):
+ dlv.data = self.data
- def apply(self, dlv):
- dlv.data = self.data
+ def check(self, dlv):
+ assert dlv.data == self.data, (dlv.data, self.data)
+ assert dlv.section_number == 0
+ assert dlv.section_offset == 0
+ assert dlv.condition == None
+ assert dlv.failed == False
+ assert dlv.undeliverable == False
+ assert dlv.annotations == None
- def check(self, dlv):
- assert dlv.data == self.data, (dlv.data, self.data)
- assert dlv.section_number == 0
- assert dlv.section_offset == 0
- assert dlv.condition == None
- assert dlv.failed == False
- assert dlv.undeliverable == False
- assert dlv.annotations == None
class DeliveryTest(Test):
- def tearDown(self):
- self.cleanup()
+ def tearDown(self):
+ self.cleanup()
- def testDisposition(self, count=1, tag="tag%i", type=Delivery.ACCEPTED, value=NoValue()):
- snd, rcv = self.link("test-link")
- snd.open()
- rcv.open()
+ def testDisposition(self, count=1, tag="tag%i", type=Delivery.ACCEPTED, value=NoValue()):
+ snd, rcv = self.link("test-link")
+ snd.open()
+ rcv.open()
- snd_deliveries = []
- for i in range(count):
- d = snd.delivery(tag % i)
- snd_deliveries.append(d)
- snd.advance()
+ snd_deliveries = []
+ for i in range(count):
+ d = snd.delivery(tag % i)
+ snd_deliveries.append(d)
+ snd.advance()
- rcv.flow(count)
- self.pump()
+ rcv.flow(count)
+ self.pump()
+
+ rcv_deliveries = []
+ for i in range(count):
+ d = rcv.current
+ assert d.tag == (tag % i)
+ rcv_deliveries.append(d)
+ rcv.advance()
- rcv_deliveries = []
- for i in range(count):
- d = rcv.current
- assert d.tag == (tag % i)
- rcv_deliveries.append(d)
- rcv.advance()
+ for d in rcv_deliveries:
+ value.apply(d.local)
+ d.update(type)
- for d in rcv_deliveries:
- value.apply(d.local)
- d.update(type)
+ self.pump()
- self.pump()
+ for d in snd_deliveries:
+ assert d.remote_state == type
+ assert d.remote.type == type
+ value.check(d.remote)
+ value.apply(d.local)
+ d.update(type)
- for d in snd_deliveries:
- assert d.remote_state == type
- assert d.remote.type == type
- value.check(d.remote)
- value.apply(d.local)
- d.update(type)
+ self.pump()
- self.pump()
+ for d in rcv_deliveries:
+ assert d.remote_state == type
+ assert d.remote.type == type
+ value.check(d.remote)
- for d in rcv_deliveries:
- assert d.remote_state == type
- assert d.remote.type == type
- value.check(d.remote)
+ for d in snd_deliveries:
+ d.settle()
- for d in snd_deliveries:
- d.settle()
+ self.pump()
- self.pump()
+ for d in rcv_deliveries:
+ assert d.settled, d.settled
+ d.settle()
- for d in rcv_deliveries:
- assert d.settled, d.settled
- d.settle()
+ def testReceived(self):
+ self.testDisposition(type=Disposition.RECEIVED, value=ReceivedValue(1, 2))
- def testReceived(self):
- self.testDisposition(type=Disposition.RECEIVED, value=ReceivedValue(1, 2))
+ def testRejected(self):
+ self.testDisposition(type=Disposition.REJECTED, value=RejectValue(Condition(symbol("foo"))))
- def testRejected(self):
- self.testDisposition(type=Disposition.REJECTED, value=RejectValue(Condition(symbol("foo"))))
+ def testReleased(self):
+ self.testDisposition(type=Disposition.RELEASED)
- def testReleased(self):
- self.testDisposition(type=Disposition.RELEASED)
+ def testModified(self):
+ self.testDisposition(type=Disposition.MODIFIED,
+ value=ModifiedValue(failed=True, undeliverable=True,
+ annotations={"key": "value"}))
- def testModified(self):
- self.testDisposition(type=Disposition.MODIFIED,
- value=ModifiedValue(failed=True, undeliverable=True,
- annotations={"key": "value"}))
+ def testCustom(self):
+ self.testDisposition(type=0x12345, value=CustomValue([1, 2, 3]))
- def testCustom(self):
- self.testDisposition(type=0x12345, value=CustomValue([1, 2, 3]))
class CollectorTest(Test):
- def setUp(self):
- self.collector = Collector()
-
- def drain(self):
- result = []
- while True:
- e = self.collector.peek()
- if e:
- result.append(e)
- self.collector.pop()
- else:
- break
- return result
-
- def expect(self, *types):
- return self.expect_oneof(types)
-
- def expect_oneof(self, *sequences):
- events = self.drain()
- types = tuple([e.type for e in events])
-
- for alternative in sequences:
- if types == alternative:
- if len(events) == 1:
- return events[0]
- elif len(events) > 1:
- return events
- else:
- return
+ def setUp(self):
+ self.collector = Collector()
+
+ def drain(self):
+ result = []
+ while True:
+ e = self.collector.peek()
+ if e:
+ result.append(e)
+ self.collector.pop()
+ else:
+ break
+ return result
+
+ def expect(self, *types):
+ return self.expect_oneof(types)
+
+ def expect_oneof(self, *sequences):
+ events = self.drain()
+ types = tuple([e.type for e in events])
+
+ for alternative in sequences:
+ if types == alternative:
+ if len(events) == 1:
+ return events[0]
+ elif len(events) > 1:
+ return events
+ else:
+ return
- assert False, "actual events %s did not match any of the expected sequences: %s" % (events, sequences)
+ assert False, "actual events %s did not match any of the expected sequences: %s" % (events, sequences)
+
+ def expect_until(self, *types):
+ events = self.drain()
+ etypes = tuple([e.type for e in events[-len(types):]])
+ assert etypes == types, "actual events %s did not end in expect sequence: %s" % (events, types)
- def expect_until(self, *types):
- events = self.drain()
- etypes = tuple([e.type for e in events[-len(types):]])
- assert etypes == types, "actual events %s did not end in expect sequence: %s" % (events, types)
class EventTest(CollectorTest):
- def tearDown(self):
- self.cleanup()
-
- def testEndpointEvents(self):
- c1, c2 = self.connection()
- c1.collect(self.collector)
- self.expect(Event.CONNECTION_INIT)
- self.pump()
- self.expect()
- c2.open()
- self.pump()
- self.expect(Event.CONNECTION_REMOTE_OPEN)
- self.pump()
- self.expect()
-
- ssn = c2.session()
- snd = ssn.sender("sender")
- ssn.open()
- snd.open()
-
- self.expect()
- self.pump()
- self.expect(Event.SESSION_INIT, Event.SESSION_REMOTE_OPEN,
- Event.LINK_INIT, Event.LINK_REMOTE_OPEN)
-
- c1.open()
- ssn2 = c1.session()
- ssn2.open()
- rcv = ssn2.receiver("receiver")
- rcv.open()
- self.pump()
- self.expect(Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT,
- Event.SESSION_INIT, Event.SESSION_LOCAL_OPEN,
- Event.TRANSPORT, Event.LINK_INIT, Event.LINK_LOCAL_OPEN,
- Event.TRANSPORT)
-
- rcv.close()
- self.expect(Event.LINK_LOCAL_CLOSE, Event.TRANSPORT)
- self.pump()
- rcv.free()
- del rcv
- self.expect(Event.LINK_FINAL)
- ssn2.free()
- del ssn2
- self.pump()
- c1.free()
- c1.transport.unbind()
- self.expect_oneof((Event.SESSION_FINAL, Event.LINK_FINAL, Event.SESSION_FINAL,
- Event.CONNECTION_UNBOUND, Event.CONNECTION_FINAL),
- (Event.CONNECTION_UNBOUND, Event.SESSION_FINAL, Event.LINK_FINAL,
- Event.SESSION_FINAL, Event.CONNECTION_FINAL))
-
- def testConnectionINIT_FINAL(self):
- c = Connection()
- c.collect(self.collector)
- self.expect(Event.CONNECTION_INIT)
- c.free()
- self.expect(Event.CONNECTION_FINAL)
-
- def testSessionINIT_FINAL(self):
- c = Connection()
- c.collect(self.collector)
- self.expect(Event.CONNECTION_INIT)
- s = c.session()
- self.expect(Event.SESSION_INIT)
- s.free()
- self.expect(Event.SESSION_FINAL)
- c.free()
- self.expect(Event.CONNECTION_FINAL)
-
- def testLinkINIT_FINAL(self):
- c = Connection()
- c.collect(self.collector)
- self.expect(Event.CONNECTION_INIT)
- s = c.session()
- self.expect(Event.SESSION_INIT)
- r = s.receiver("asdf")
- self.expect(Event.LINK_INIT)
- r.free()
- self.expect(Event.LINK_FINAL)
- c.free()
- self.expect(Event.SESSION_FINAL, Event.CONNECTION_FINAL)
-
- def testFlowEvents(self):
- snd, rcv = self.link("test-link")
- snd.session.connection.collect(self.collector)
- rcv.open()
- rcv.flow(10)
- self.pump()
- self.expect(Event.CONNECTION_INIT, Event.SESSION_INIT,
- Event.LINK_INIT, Event.LINK_REMOTE_OPEN, Event.LINK_FLOW)
- rcv.flow(10)
- self.pump()
- self.expect(Event.LINK_FLOW)
- return snd, rcv
-
- def testDeliveryEvents(self):
- snd, rcv = self.link("test-link")
- rcv.session.connection.collect(self.collector)
- rcv.open()
- rcv.flow(10)
- self.pump()
- self.expect(Event.CONNECTION_INIT, Event.SESSION_INIT,
- Event.LINK_INIT, Event.LINK_LOCAL_OPEN, Event.TRANSPORT)
- snd.delivery("delivery")
- snd.send(b"Hello World!")
- snd.advance()
- self.pump()
- self.expect()
- snd.open()
- self.pump()
- self.expect(Event.LINK_REMOTE_OPEN, Event.DELIVERY)
- rcv.session.connection.transport.unbind()
- rcv.session.connection.free()
- self.expect(Event.CONNECTION_UNBOUND, Event.TRANSPORT, Event.LINK_FINAL,
- Event.SESSION_FINAL, Event.CONNECTION_FINAL)
-
- def testDeliveryEventsDisp(self):
- snd, rcv = self.testFlowEvents()
- snd.open()
- dlv = snd.delivery("delivery")
- snd.send(b"Hello World!")
- assert snd.advance()
- self.expect(Event.LINK_LOCAL_OPEN, Event.TRANSPORT)
- self.pump()
- self.expect(Event.LINK_FLOW)
- rdlv = rcv.current
- assert rdlv != None
- assert rdlv.tag == "delivery"
- rdlv.update(Delivery.ACCEPTED)
- self.pump()
- event = self.expect(Event.DELIVERY)
- assert event.context == dlv, (dlv, event.context)
-
- def testConnectionBOUND_UNBOUND(self):
- c = Connection()
- c.collect(self.collector)
- self.expect(Event.CONNECTION_INIT)
- t = Transport()
- t.bind(c)
- self.expect(Event.CONNECTION_BOUND)
- t.unbind()
- self.expect(Event.CONNECTION_UNBOUND, Event.TRANSPORT)
-
- def testTransportERROR_CLOSE(self):
- c = Connection()
- c.collect(self.collector)
- self.expect(Event.CONNECTION_INIT)
- t = Transport()
- t.bind(c)
- self.expect(Event.CONNECTION_BOUND)
- assert t.condition is None
- t.push(b"asdf")
- self.expect(Event.TRANSPORT_ERROR, Event.TRANSPORT_TAIL_CLOSED)
- assert t.condition is not None
- assert t.condition.name == "amqp:connection:framing-error"
- assert "AMQP protocol header" in t.condition.description
- p = t.pending()
- assert p > 0
- t.pop(p)
- self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.TRANSPORT_CLOSED)
-
- def testTransportCLOSED(self):
- c = Connection()
- c.collect(self.collector)
- self.expect(Event.CONNECTION_INIT)
- t = Transport()
- t.bind(c)
- c.open()
-
- self.expect(Event.CONNECTION_BOUND, Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT)
-
- c2 = Connection()
- t2 = Transport()
- t2.bind(c2)
- c2.open()
- c2.close()
-
- pump(t, t2)
-
- self.expect(Event.CONNECTION_REMOTE_OPEN, Event.CONNECTION_REMOTE_CLOSE,
- Event.TRANSPORT_TAIL_CLOSED)
-
- c.close()
-
- pump(t, t2)
-
- self.expect(Event.CONNECTION_LOCAL_CLOSE, Event.TRANSPORT,
- Event.TRANSPORT_HEAD_CLOSED, Event.TRANSPORT_CLOSED)
-
- def testLinkDetach(self):
- c1 = Connection()
- c1.collect(self.collector)
- t1 = Transport()
- t1.bind(c1)
- c1.open()
- s1 = c1.session()
- s1.open()
- l1 = s1.sender("asdf")
- l1.open()
- l1.detach()
- self.expect_until(Event.LINK_LOCAL_DETACH, Event.TRANSPORT)
-
- c2 = Connection()
- c2.collect(self.collector)
- t2 = Transport()
- t2.bind(c2)
-
- pump(t1, t2)
-
- self.expect_until(Event.LINK_REMOTE_DETACH)
+ def tearDown(self):
+ self.cleanup()
-class PeerTest(CollectorTest):
+ def testEndpointEvents(self):
+ c1, c2 = self.connection()
+ c1.collect(self.collector)
+ self.expect(Event.CONNECTION_INIT)
+ self.pump()
+ self.expect()
+ c2.open()
+ self.pump()
+ self.expect(Event.CONNECTION_REMOTE_OPEN)
+ self.pump()
+ self.expect()
- def setUp(self):
- CollectorTest.setUp(self)
- self.connection = Connection()
- self.connection.collect(self.collector)
- self.transport = Transport()
- self.transport.bind(self.connection)
- self.peer = Connection()
- self.peer_transport = Transport()
- self.peer_transport.bind(self.peer)
- self.peer_transport.trace(Transport.TRACE_OFF)
+ ssn = c2.session()
+ snd = ssn.sender("sender")
+ ssn.open()
+ snd.open()
- def pump(self):
- pump(self.transport, self.peer_transport)
+ self.expect()
+ self.pump()
+ self.expect(Event.SESSION_INIT, Event.SESSION_REMOTE_OPEN,
+ Event.LINK_INIT, Event.LINK_REMOTE_OPEN)
+
+ c1.open()
+ ssn2 = c1.session()
+ ssn2.open()
+ rcv = ssn2.receiver("receiver")
+ rcv.open()
+ self.pump()
+ self.expect(Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT,
+ Event.SESSION_INIT, Event.SESSION_LOCAL_OPEN,
+ Event.TRANSPORT, Event.LINK_INIT, Event.LINK_LOCAL_OPEN,
+ Event.TRANSPORT)
-class TeardownLeakTest(PeerTest):
+ rcv.close()
+ self.expect(Event.LINK_LOCAL_CLOSE, Event.TRANSPORT)
+ self.pump()
+ rcv.free()
+ del rcv
+ self.expect(Event.LINK_FINAL)
+ ssn2.free()
+ del ssn2
+ self.pump()
+ c1.free()
+ c1.transport.unbind()
+ self.expect_oneof((Event.SESSION_FINAL, Event.LINK_FINAL, Event.SESSION_FINAL,
+ Event.CONNECTION_UNBOUND, Event.CONNECTION_FINAL),
+ (Event.CONNECTION_UNBOUND, Event.SESSION_FINAL, Event.LINK_FINAL,
+ Event.SESSION_FINAL, Event.CONNECTION_FINAL))
+
+ def testConnectionINIT_FINAL(self):
+ c = Connection()
+ c.collect(self.collector)
+ self.expect(Event.CONNECTION_INIT)
+ c.free()
+ self.expect(Event.CONNECTION_FINAL)
+
+ def testSessionINIT_FINAL(self):
+ c = Connection()
+ c.collect(self.collector)
+ self.expect(Event.CONNECTION_INIT)
+ s = c.session()
+ self.expect(Event.SESSION_INIT)
+ s.free()
+ self.expect(Event.SESSION_FINAL)
+ c.free()
+ self.expect(Event.CONNECTION_FINAL)
+
+ def testLinkINIT_FINAL(self):
+ c = Connection()
+ c.collect(self.collector)
+ self.expect(Event.CONNECTION_INIT)
+ s = c.session()
+ self.expect(Event.SESSION_INIT)
+ r = s.receiver("asdf")
+ self.expect(Event.LINK_INIT)
+ r.free()
+ self.expect(Event.LINK_FINAL)
+ c.free()
+ self.expect(Event.SESSION_FINAL, Event.CONNECTION_FINAL)
+
+ def testFlowEvents(self):
+ snd, rcv = self.link("test-link")
+ snd.session.connection.collect(self.collector)
+ rcv.open()
+ rcv.flow(10)
+ self.pump()
+ self.expect(Event.CONNECTION_INIT, Event.SESSION_INIT,
+ Event.LINK_INIT, Event.LINK_REMOTE_OPEN, Event.LINK_FLOW)
+ rcv.flow(10)
+ self.pump()
+ self.expect(Event.LINK_FLOW)
+ return snd, rcv
+
+ def testDeliveryEvents(self):
+ snd, rcv = self.link("test-link")
+ rcv.session.connection.collect(self.collector)
+ rcv.open()
+ rcv.flow(10)
+ self.pump()
+ self.expect(Event.CONNECTION_INIT, Event.SESSION_INIT,
+ Event.LINK_INIT, Event.LINK_LOCAL_OPEN, Event.TRANSPORT)
+ snd.delivery("delivery")
+ snd.send(b"Hello World!")
+ snd.advance()
+ self.pump()
+ self.expect()
+ snd.open()
+ self.pump()
+ self.expect(Event.LINK_REMOTE_OPEN, Event.DELIVERY)
+ rcv.session.connection.transport.unbind()
+ rcv.session.connection.free()
+ self.expect(Event.CONNECTION_UNBOUND, Event.TRANSPORT, Event.LINK_FINAL,
+ Event.SESSION_FINAL, Event.CONNECTION_FINAL)
+
+ def testDeliveryEventsDisp(self):
+ snd, rcv = self.testFlowEvents()
+ snd.open()
+ dlv = snd.delivery("delivery")
+ snd.send(b"Hello World!")
+ assert snd.advance()
+ self.expect(Event.LINK_LOCAL_OPEN, Event.TRANSPORT)
+ self.pump()
+ self.expect(Event.LINK_FLOW)
+ rdlv = rcv.current
+ assert rdlv != None
+ assert rdlv.tag == "delivery"
+ rdlv.update(Delivery.ACCEPTED)
+ self.pump()
+ event = self.expect(Event.DELIVERY)
+ assert event.context == dlv, (dlv, event.context)
+
+ def testConnectionBOUND_UNBOUND(self):
+ c = Connection()
+ c.collect(self.collector)
+ self.expect(Event.CONNECTION_INIT)
+ t = Transport()
+ t.bind(c)
+ self.expect(Event.CONNECTION_BOUND)
+ t.unbind()
+ self.expect(Event.CONNECTION_UNBOUND, Event.TRANSPORT)
+
+ def testTransportERROR_CLOSE(self):
+ c = Connection()
+ c.collect(self.collector)
+ self.expect(Event.CONNECTION_INIT)
+ t = Transport()
+ t.bind(c)
+ self.expect(Event.CONNECTION_BOUND)
+ assert t.condition is None
+ t.push(b"asdf")
+ self.expect(Event.TRANSPORT_ERROR, Event.TRANSPORT_TAIL_CLOSED)
+ assert t.condition is not None
+ assert t.condition.name == "amqp:connection:framing-error"
+ assert "AMQP protocol header" in t.condition.description
+ p = t.pending()
+ assert p > 0
+ t.pop(p)
+ self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.TRANSPORT_CLOSED)
+
+ def testTransportCLOSED(self):
+ c = Connection()
+ c.collect(self.collector)
+ self.expect(Event.CONNECTION_INIT)
+ t = Transport()
+ t.bind(c)
+ c.open()
+
+ self.expect(Event.CONNECTION_BOUND, Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT)
+
+ c2 = Connection()
+ t2 = Transport()
+ t2.bind(c2)
+ c2.open()
+ c2.close()
+
+ pump(t, t2)
+
+ self.expect(Event.CONNECTION_REMOTE_OPEN, Event.CONNECTION_REMOTE_CLOSE,
+ Event.TRANSPORT_TAIL_CLOSED)
+
+ c.close()
+
+ pump(t, t2)
+
+ self.expect(Event.CONNECTION_LOCAL_CLOSE, Event.TRANSPORT,
+ Event.TRANSPORT_HEAD_CLOSED, Event.TRANSPORT_CLOSED)
+
+ def testLinkDetach(self):
+ c1 = Connection()
+ c1.collect(self.collector)
+ t1 = Transport()
+ t1.bind(c1)
+ c1.open()
+ s1 = c1.session()
+ s1.open()
+ l1 = s1.sender("asdf")
+ l1.open()
+ l1.detach()
+ self.expect_until(Event.LINK_LOCAL_DETACH, Event.TRANSPORT)
+
+ c2 = Connection()
+ c2.collect(self.collector)
+ t2 = Transport()
+ t2.bind(c2)
+
+ pump(t1, t2)
+
+ self.expect_until(Event.LINK_REMOTE_DETACH)
+
+
+class PeerTest(CollectorTest):
+
+ def setUp(self):
+ CollectorTest.setUp(self)
+ self.connection = Connection()
+ self.connection.collect(self.collector)
+ self.transport = Transport()
+ self.transport.bind(self.connection)
+ self.peer = Connection()
+ self.peer_transport = Transport()
+ self.peer_transport.bind(self.peer)
+ self.peer_transport.trace(Transport.TRACE_OFF)
+
+ def pump(self):
+ pump(self.transport, self.peer_transport)
- def doLeak(self, local, remote):
- self.connection.open()
- self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND,
- Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT)
- ssn = self.connection.session()
- ssn.open()
- self.expect(Event.SESSION_INIT, Event.SESSION_LOCAL_OPEN, Event.TRANSPORT)
+class TeardownLeakTest(PeerTest):
- snd = ssn.sender("sender")
- snd.open()
- self.expect(Event.LINK_INIT, Event.LINK_LOCAL_OPEN, Event.TRANSPORT)
+ def doLeak(self, local, remote):
+ self.connection.open()
+ self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND,
+ Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT)
+ ssn = self.connection.session()
+ ssn.open()
+ self.expect(Event.SESSION_INIT, Event.SESSION_LOCAL_OPEN, Event.TRANSPORT)
- self.pump()
+ snd = ssn.sender("sender")
+ snd.open()
+ self.expect(Event.LINK_INIT, Event.LINK_LOCAL_OPEN, Event.TRANSPORT)
- self.peer.open()
- self.peer.session_head(0).open()
- self.peer.link_head(0).open()
+ self.pump()
- self.pump()
- self.expect_oneof((Event.CONNECTION_REMOTE_OPEN, Event.SESSION_REMOTE_OPEN,
- Event.LINK_REMOTE_OPEN, Event.LINK_FLOW),
- (Event.CONNECTION_REMOTE_OPEN, Event.SESSION_REMOTE_OPEN,
- Event.LINK_REMOTE_OPEN))
+ self.peer.open()
+ self.peer.session_head(0).open()
+ self.peer.link_head(0).open()
- if local:
- snd.close() # ha!!
- self.expect(Event.LINK_LOCAL_CLOSE, Event.TRANSPORT)
- ssn.close()
- self.expect(Event.SESSION_LOCAL_CLOSE, Event.TRANSPORT)
- self.connection.close()
- self.expect(Event.CONNECTION_LOCAL_CLOSE, Event.TRANSPORT)
+ self.pump()
+ self.expect_oneof((Event.CONNECTION_REMOTE_OPEN, Event.SESSION_REMOTE_OPEN,
+ Event.LINK_REMOTE_OPEN, Event.LINK_FLOW),
+ (Event.CONNECTION_REMOTE_OPEN, Event.SESSION_REMOTE_OPEN,
+ Event.LINK_REMOTE_OPEN))
+
+ if local:
+ snd.close() # ha!!
+ self.expect(Event.LINK_LOCAL_CLOSE, Event.TRANSPORT)
+ ssn.close()
+ self.expect(Event.SESSION_LOCAL_CLOSE, Event.TRANSPORT)
+ self.connection.close()
+ self.expect(Event.CONNECTION_LOCAL_CLOSE, Event.TRANSPORT)
+
+ if remote:
+ self.peer.link_head(0).close() # ha!!
+ self.peer.session_head(0).close()
+ self.peer.close()
- if remote:
- self.peer.link_head(0).close() # ha!!
- self.peer.session_head(0).close()
- self.peer.close()
+ self.pump()
- self.pump()
+ if remote:
+ self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.LINK_REMOTE_CLOSE,
+ Event.SESSION_REMOTE_CLOSE, Event.CONNECTION_REMOTE_CLOSE,
+ Event.TRANSPORT_TAIL_CLOSED, Event.TRANSPORT_CLOSED)
+ else:
+ self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.SESSION_REMOTE_CLOSE,
+ Event.CONNECTION_REMOTE_CLOSE, Event.TRANSPORT_TAIL_CLOSED,
+ Event.TRANSPORT_CLOSED)
- if remote:
- self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.LINK_REMOTE_CLOSE,
- Event.SESSION_REMOTE_CLOSE, Event.CONNECTION_REMOTE_CLOSE,
- Event.TRANSPORT_TAIL_CLOSED, Event.TRANSPORT_CLOSED)
- else:
- self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.SESSION_REMOTE_CLOSE,
- Event.CONNECTION_REMOTE_CLOSE, Event.TRANSPORT_TAIL_CLOSED,
- Event.TRANSPORT_CLOSED)
+ self.connection.free()
+ self.expect(Event.LINK_FINAL, Event.SESSION_FINAL)
+ self.transport.unbind()
- self.connection.free()
- self.expect(Event.LINK_FINAL, Event.SESSION_FINAL)
- self.transport.unbind()
+ self.expect(Event.CONNECTION_UNBOUND, Event.CONNECTION_FINAL)
- self.expect(Event.CONNECTION_UNBOUND, Event.CONNECTION_FINAL)
+ def testLocalRemoteLeak(self):
+ self.doLeak(True, True)
- def testLocalRemoteLeak(self):
- self.doLeak(True, True)
+ def testLocalLeak(self):
+ self.doLeak(True, False)
- def testLocalLeak(self):
- self.doLeak(True, False)
+ def testRemoteLeak(self):
+ self.doLeak(False, True)
- def testRemoteLeak(self):
- self.doLeak(False, True)
+ def testLeak(self):
+ self.doLeak(False, False)
- def testLeak(self):
- self.doLeak(False, False)
class IdleTimeoutEventTest(PeerTest):
- def half_pump(self):
- p = self.transport.pending()
- if p>0:
- self.transport.pop(p)
-
- def testTimeoutWithZombieServer(self, expectOpenCloseFrames=True):
- self.transport.idle_timeout = self.delay
- self.connection.open()
- self.half_pump()
- t = time()
- self.transport.tick(t)
- self.transport.tick(t + self.delay*4)
- self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND,
- Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT,
- Event.TRANSPORT_ERROR, Event.TRANSPORT_TAIL_CLOSED)
- assert self.transport.capacity() < 0
- if expectOpenCloseFrames:
- assert self.transport.pending() > 0
- self.half_pump()
- self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.TRANSPORT_CLOSED)
- assert self.transport.pending() < 0
-
- def testTimeoutWithZombieServerAndSASL(self):
- sasl = self.transport.sasl()
- self.testTimeoutWithZombieServer(expectOpenCloseFrames=False)
+ def half_pump(self):
+ p = self.transport.pending()
+ if p > 0:
+ self.transport.pop(p)
+
+ def testTimeoutWithZombieServer(self, expectOpenCloseFrames=True):
+ self.transport.idle_timeout = self.delay
+ self.connection.open()
+ self.half_pump()
+ t = time()
+ self.transport.tick(t)
+ self.transport.tick(t + self.delay*4)
+ self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND,
+ Event.CONNECTION_LOCAL_OPEN, Event.TRANSPORT,
+ Event.TRANSPORT_ERROR, Event.TRANSPORT_TAIL_CLOSED)
+ assert self.transport.capacity() < 0
+ if expectOpenCloseFrames:
+ assert self.transport.pending() > 0
+ self.half_pump()
+ self.expect(Event.TRANSPORT_HEAD_CLOSED, Event.TRANSPORT_CLOSED)
+ assert self.transport.pending() < 0
+
+ def testTimeoutWithZombieServerAndSASL(self):
+ sasl = self.transport.sasl()
+ self.testTimeoutWithZombieServer(expectOpenCloseFrames=False)
+
class DeliverySegFaultTest(Test):
- def testDeliveryAfterUnbind(self):
- conn = Connection()
- t = Transport()
- ssn = conn.session()
- snd = ssn.sender("sender")
- dlv = snd.delivery("tag")
- dlv.settle()
- del dlv
- t.bind(conn)
- t.unbind()
- dlv = snd.delivery("tag")
+ def testDeliveryAfterUnbind(self):
+ conn = Connection()
+ t = Transport()
+ ssn = conn.session()
+ snd = ssn.sender("sender")
+ dlv = snd.delivery("tag")
+ dlv.settle()
+ del dlv
+ t.bind(conn)
+ t.unbind()
+ dlv = snd.delivery("tag")
+
class SaslEventTest(CollectorTest):
- def testAnonymousNoInitialResponse(self):
- conn = Connection()
- conn.collect(self.collector)
- transport = Transport(Transport.SERVER)
- transport.bind(conn)
- self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND)
-
- transport.push(b'AMQP\x03\x01\x00\x00\x00\x00\x00 \x02\x01\x00\x00\x00SA'
- b'\xd0\x00\x00\x00\x10\x00\x00\x00\x02\xa3\tANONYMOUS@'
- b'AMQP\x00\x01\x00\x00')
- self.expect(Event.TRANSPORT)
- for i in range(1024):
- p = transport.pending()
- self.drain()
- p = transport.pending()
- self.expect()
-
- def testPipelinedServerReadFirst(self):
- conn = Connection()
- conn.collect(self.collector)
- transport = Transport(Transport.CLIENT)
- s = transport.sasl()
- s.allowed_mechs("ANONYMOUS PLAIN")
- transport.bind(conn)
- self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND)
- transport.push(
- # SASL
- b'AMQP\x03\x01\x00\x00'
- # @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:ANONYMOUS]]
- b'\x00\x00\x00\x1c\x02\x01\x00\x00\x00S@\xc0\x0f\x01\xe0\x0c\x01\xa3\tANONYMOUS'
- # @sasl-outcome(68) [code=0]
- b'\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00'
- # AMQP
- b'AMQP\x00\x01\x00\x00'
+ def testAnonymousNoInitialResponse(self):
+ conn = Connection()
+ conn.collect(self.collector)
+ transport = Transport(Transport.SERVER)
+ transport.bind(conn)
+ self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND)
+
+ transport.push(b'AMQP\x03\x01\x00\x00\x00\x00\x00 \x02\x01\x00\x00\x00SA'
+ b'\xd0\x00\x00\x00\x10\x00\x00\x00\x02\xa3\tANONYMOUS@'
+ b'AMQP\x00\x01\x00\x00')
+ self.expect(Event.TRANSPORT)
+ for i in range(1024):
+ p = transport.pending()
+ self.drain()
+ p = transport.pending()
+ self.expect()
+
+ def testPipelinedServerReadFirst(self):
+ conn = Connection()
+ conn.collect(self.collector)
+ transport = Transport(Transport.CLIENT)
+ s = transport.sasl()
+ s.allowed_mechs("ANONYMOUS PLAIN")
+ transport.bind(conn)
+ self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND)
+ transport.push(
+ # SASL
+ b'AMQP\x03\x01\x00\x00'
+ # @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:ANONYMOUS]]
+ b'\x00\x00\x00\x1c\x02\x01\x00\x00\x00S@\xc0\x0f\x01\xe0\x0c\x01\xa3\tANONYMOUS'
+ # @sasl-outcome(68) [code=0]
+ b'\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00'
+ # AMQP
+ b'AMQP\x00\x01\x00\x00'
)
- self.expect(Event.TRANSPORT)
- p = transport.pending()
- bytes = transport.peek(p)
- transport.pop(p)
-
- server = Transport(Transport.SERVER)
- server.push(bytes)
- assert s.outcome == SASL.OK
- assert server.sasl().outcome == SASL.OK
-
- def testPipelinedServerWriteFirst(self):
- conn = Connection()
- conn.collect(self.collector)
- transport = Transport(Transport.CLIENT)
- s = transport.sasl()
- s.allowed_mechs("ANONYMOUS")
- transport.bind(conn)
- p = transport.pending()
- bytes = transport.peek(p)
- transport.pop(p)
- self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND)
- transport.push(
- # SASL
- b'AMQP\x03\x01\x00\x00'
- # @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:ANONYMOUS]]
- b'\x00\x00\x00\x1c\x02\x01\x00\x00\x00S@\xc0\x0f\x01\xe0\x0c\x01\xa3\tANONYMOUS'
- # @sasl-outcome(68) [code=0]
- b'\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00'
- # AMQP
- b'AMQP\x00\x01\x00\x00'
+ self.expect(Event.TRANSPORT)
+ p = transport.pending()
+ bytes = transport.peek(p)
+ transport.pop(p)
+
+ server = Transport(Transport.SERVER)
+ server.push(bytes)
+ assert s.outcome == SASL.OK
+ assert server.sasl().outcome == SASL.OK
+
+ def testPipelinedServerWriteFirst(self):
+ conn = Connection()
+ conn.collect(self.collector)
+ transport = Transport(Transport.CLIENT)
+ s = transport.sasl()
+ s.allowed_mechs("ANONYMOUS")
+ transport.bind(conn)
+ p = transport.pending()
+ bytes = transport.peek(p)
+ transport.pop(p)
+ self.expect(Event.CONNECTION_INIT, Event.CONNECTION_BOUND)
+ transport.push(
+ # SASL
+ b'AMQP\x03\x01\x00\x00'
+ # @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:ANONYMOUS]]
+ b'\x00\x00\x00\x1c\x02\x01\x00\x00\x00S@\xc0\x0f\x01\xe0\x0c\x01\xa3\tANONYMOUS'
+ # @sasl-outcome(68) [code=0]
+ b'\x00\x00\x00\x10\x02\x01\x00\x00\x00SD\xc0\x03\x01P\x00'
+ # AMQP
+ b'AMQP\x00\x01\x00\x00'
)
- self.expect(Event.TRANSPORT)
- p = transport.pending()
- bytes = transport.peek(p)
- transport.pop(p)
- assert s.outcome == SASL.OK
- # XXX: the bytes above appear to be correct, but we don't get any
- # sort of event indicating that the transport is authenticated
+ self.expect(Event.TRANSPORT)
+ p = transport.pending()
+ bytes = transport.peek(p)
+ transport.pop(p)
+ assert s.outcome == SASL.OK
+ # XXX: the bytes above appear to be correct, but we don't get any
+ # sort of event indicating that the transport is authenticated
diff --git a/python/tests/proton_tests/handler.py b/python/tests/proton_tests/handler.py
index 2324073..e8fdebd 100644
--- a/python/tests/proton_tests/handler.py
+++ b/python/tests/proton_tests/handler.py
@@ -19,7 +19,9 @@
from __future__ import absolute_import
-import os, gc, traceback
+import os
+import gc
+import traceback
from proton import *
from proton.reactor import Container
@@ -28,95 +30,105 @@ from . import common
CUSTOM = EventType("custom")
+
class HandlerTest(common.Test):
- def test_reactorHandlerCycling(self, n=0):
-
- class CustomHandler(Handler):
- UNSET = 999999999
- def __init__(self):
- self.offset = len(traceback.extract_stack())
- def on_reactor_init(self, event):
- self.depth = len(traceback.extract_stack())
- def reset(self):
- self.depth = self.UNSET
- @property
- def init_depth(self):
- d = self.depth - self.offset
- return d
- custom = CustomHandler()
-
- container = Container()
- container.handler = custom
- for i in range(n):
- h = container.handler
- container.handler = h
- custom.reset()
- container.run()
- assert custom.init_depth < 50, "Unexpectedly long traceback for a simple handler"
-
- def test_reactorHandlerCycling10k(self):
- self.test_reactorHandlerCycling(10000)
-
- def test_reactorHandlerCycling100(self):
- self.test_reactorHandlerCycling(100)
-
- def do_customEvent(self, reactor_handler, event_root):
-
- class CustomHandler:
- did_custom = False
- did_init = False
- def __init__(self, *handlers):
- self.handlers = handlers
- def on_reactor_init(self, event):
- self.did_init = True
- def on_custom(self, event):
- self.did_custom = True
-
- class CustomInvoker(CustomHandler):
- def on_reactor_init(self, event):
- h = event_root(event)
- event.dispatch(h, CUSTOM)
- self.did_init = True
-
- child = CustomInvoker()
- root = CustomHandler(child)
-
- container = Container()
-
- reactor_handler(container, root)
- container.run()
- assert root.did_init
- assert child.did_init
- assert root.did_custom
- assert child.did_custom
-
- def set_root(self, reactor, root):
- reactor.handler = root
- def add_root(self, reactor, root):
- reactor.handler.add(root)
- def append_root(self, reactor, root):
- reactor.handler.handlers.append(root)
-
- def event_root(self, event):
- return event.handler
-
- def event_reactor_handler(self, event):
- return event.reactor.handler
-
- def test_set_handler(self):
- self.do_customEvent(self.set_root, self.event_reactor_handler)
-
- def test_add_handler(self):
- self.do_customEvent(self.add_root, self.event_reactor_handler)
-
- def test_append_handler(self):
- self.do_customEvent(self.append_root, self.event_reactor_handler)
-
- def test_set_root(self):
- self.do_customEvent(self.set_root, self.event_root)
-
- def test_add_root(self):
- self.do_customEvent(self.add_root, self.event_root)
-
- def test_append_root(self):
- self.do_customEvent(self.append_root, self.event_root)
+ def test_reactorHandlerCycling(self, n=0):
+
+ class CustomHandler(Handler):
+ UNSET = 999999999
+
+ def __init__(self):
+ self.offset = len(traceback.extract_stack())
+
+ def on_reactor_init(self, event):
+ self.depth = len(traceback.extract_stack())
+
+ def reset(self):
+ self.depth = self.UNSET
+
+ @property
+ def init_depth(self):
+ d = self.depth - self.offset
+ return d
+ custom = CustomHandler()
+
+ container = Container()
+ container.handler = custom
+ for i in range(n):
+ h = container.handler
+ container.handler = h
+ custom.reset()
+ container.run()
+ assert custom.init_depth < 50, "Unexpectedly long traceback for a simple handler"
+
+ def test_reactorHandlerCycling10k(self):
+ self.test_reactorHandlerCycling(10000)
+
+ def test_reactorHandlerCycling100(self):
+ self.test_reactorHandlerCycling(100)
+
+ def do_customEvent(self, reactor_handler, event_root):
+
+ class CustomHandler:
+ did_custom = False
+ did_init = False
+
+ def __init__(self, *handlers):
+ self.handlers = handlers
+
+ def on_reactor_init(self, event):
+ self.did_init = True
+
+ def on_custom(self, event):
+ self.did_custom = True
+
+ class CustomInvoker(CustomHandler):
+ def on_reactor_init(self, event):
+ h = event_root(event)
+ event.dispatch(h, CUSTOM)
+ self.did_init = True
+
+ child = CustomInvoker()
+ root = CustomHandler(child)
+
+ container = Container()
+
+ reactor_handler(container, root)
+ container.run()
+ assert root.did_init
+ assert child.did_init
+ assert root.did_custom
+ assert child.did_custom
+
+ def set_root(self, reactor, root):
+ reactor.handler = root
+
+ def add_root(self, reactor, root):
+ reactor.handler.add(root)
+
+ def append_root(self, reactor, root):
+ reactor.handler.handlers.append(root)
+
+ def event_root(self, event):
+ return event.handler
+
+ def event_reactor_handler(self, event):
+ return event.reactor.handler
+
+ def test_set_handler(self):
+ self.do_customEvent(self.set_root, self.event_reactor_handler)
+
+ def test_add_handler(self):
+ self.do_customEvent(self.add_root, self.event_reactor_handler)
+
+ def test_append_handler(self):
+ self.do_customEvent(self.append_root, self.event_reactor_handler)
+
+ def test_set_root(self):
+ self.do_customEvent(self.set_root, self.event_root)
+
+ def test_add_root(self):
+ self.do_customEvent(self.add_root, self.event_root)
+
+ def test_append_root(self):
+ self.do_customEvent(self.append_root, self.event_root)
diff --git a/python/tests/proton_tests/interop.py b/python/tests/proton_tests/interop.py
index 5ccbd2b..f57327b 100644
--- a/python/tests/proton_tests/interop.py
+++ b/python/tests/proton_tests/interop.py
@@ -35,7 +35,9 @@ def find_test_interop_dir():
raise Exception("Cannot find tests/interop directory from "+__file__)
return f
-test_interop_dir=find_test_interop_dir()
+
+test_interop_dir = find_test_interop_dir()
+
class InteropTest(common.Test):
@@ -48,9 +50,11 @@ class InteropTest(common.Test):
def get_data(self, name):
filename = os.path.join(test_interop_dir, name+".amqp")
- f = open(filename,"rb")
- try: return f.read()
- finally: f.close()
+ f = open(filename, "rb")
+ try:
+ return f.read()
+ finally:
+ f.close()
def decode_data(self, encoded):
buffer = encoded
@@ -78,10 +82,10 @@ class InteropTest(common.Test):
def assert_next(self, type, value):
next_type = self.data.next()
- assert next_type == type, "Type mismatch: %s != %s"%(
+ assert next_type == type, "Type mismatch: %s != %s" % (
Data.type_names[next_type], Data.type_names[type])
next_value = self.data.get_object()
- assert next_value == value, "Value mismatch: %s != %s"%(next_value, value)
+ assert next_value == value, "Value mismatch: %s != %s" % (next_value, value)
def test_message(self):
self.decode_message_file("message")
@@ -128,11 +132,11 @@ class InteropTest(common.Test):
def test_described_array(self):
self.decode_data_file("described_array")
- self.assert_next(Data.ARRAY, Array("int-array", Data.INT, *range(0,10)))
+ self.assert_next(Data.ARRAY, Array("int-array", Data.INT, *range(0, 10)))
def test_arrays(self):
self.decode_data_file("arrays")
- self.assert_next(Data.ARRAY, Array(UNDESCRIBED, Data.INT, *range(0,100)))
+ self.assert_next(Data.ARRAY, Array(UNDESCRIBED, Data.INT, *range(0, 100)))
self.assert_next(Data.ARRAY, Array(UNDESCRIBED, Data.STRING, *["a", "b", "c"]))
self.assert_next(Data.ARRAY, Array(UNDESCRIBED, Data.INT))
assert self.data.next() is None
@@ -145,7 +149,7 @@ class InteropTest(common.Test):
def test_maps(self):
self.decode_data_file("maps")
- self.assert_next(Data.MAP, {"one":1, "two":2, "three":3 })
- self.assert_next(Data.MAP, {1:"one", 2:"two", 3:"three"})
+ self.assert_next(Data.MAP, {"one": 1, "two": 2, "three": 3})
+ self.assert_next(Data.MAP, {1: "one", 2: "two", 3: "three"})
self.assert_next(Data.MAP, {})
assert self.data.next() is None
diff --git a/python/tests/proton_tests/main.py b/python/tests/proton_tests/main.py
index e560cf1..c30f282 100644
--- a/python/tests/proton_tests/main.py
+++ b/python/tests/proton_tests/main.py
@@ -19,7 +19,14 @@
# TODO: summarize, test harness preconditions (e.g. broker is alive)
-import optparse, os, struct, sys, time, traceback, types, cgi
+import optparse
+import os
+import struct
+import sys
+import time
+import traceback
+import types
+import cgi
from fnmatch import fnmatchcase as match
from logging import getLogger, StreamHandler, Formatter, Filter, \
WARN, DEBUG, ERROR, INFO
@@ -32,11 +39,11 @@ else:
CLASS_TYPES = (type, types.ClassType)
levels = {
- "DEBUG": DEBUG,
- "INFO": INFO,
- "WARN": WARN,
- "ERROR": ERROR
- }
+ "DEBUG": DEBUG,
+ "INFO": INFO,
+ "WARN": WARN,
+ "ERROR": ERROR
+}
sorted_levels = [(v, k) for k, v in list(levels.items())]
sorted_levels.sort()
@@ -80,13 +87,15 @@ parser.add_option("-j", "--javatrace", action="store_true", default=False,
help="Show the full java stack trace. This disables heuristics to eliminate the " +
"jython portion of java stack traces.")
+
class Config:
- def __init__(self):
- self.defines = {}
- self.log_file = None
- self.log_level = WARN
- self.log_categories = []
+ def __init__(self):
+ self.defines = {}
+ self.log_file = None
+ self.log_level = WARN
+ self.log_categories = []
+
opts, args = parser.parse_args()
@@ -98,79 +107,86 @@ excludes = ["*__*__"]
config = Config()
list_only = opts.list
for d in opts.defines:
- try:
- idx = d.index("=")
- name = d[:idx]
- value = d[idx+1:]
- config.defines[name] = value
- except ValueError:
- config.defines[d] = None
+ try:
+ idx = d.index("=")
+ name = d[:idx]
+ value = d[idx+1:]
+ config.defines[name] = value
+ except ValueError:
+ config.defines[d] = None
config.log_file = opts.log_file
config.log_level = levels[opts.log_level.upper()]
config.log_categories = opts.log_categories
excludes.extend([v.strip() for v in opts.ignore])
for v in opts.ignore_file:
- f = open(v)
- for line in f:
- line = line.strip()
- if line.startswith("#"):
- continue
- excludes.append(line)
- f.close()
+ f = open(v)
+ for line in f:
+ line = line.strip()
+ if line.startswith("#"):
+ continue
+ excludes.append(line)
+ f.close()
for a in args:
- includes.append(a.strip())
+ includes.append(a.strip())
+
def is_ignored(path):
- for p in excludes:
- if match(path, p):
- return True
- return False
+ for p in excludes:
+ if match(path, p):
+ return True
+ return False
+
def is_included(path):
- if is_ignored(path):
... 5953 lines suppressed ...
---------------------------------------------------------------------
To unsubscribe, e-mail:
[hidden email]
For additional commands, e-mail:
[hidden email]