From 04c3a6eab6289751feb358c4d3ebe451992d80cf Mon Sep 17 00:00:00 2001 From: Tommy Carpenter Date: Thu, 5 Dec 2019 10:27:21 -0500 Subject: [PATCH] Add ability to set xaction deterministically, bug fixes Change-Id: I0a3aa99f1a793b7f16fe0a5314a2529715690c01 Signed-off-by: Tommy Carpenter --- src/bindings/rmr-python/docs/release-notes.rst | 11 +++++++ src/bindings/rmr-python/rmr/rmr.py | 34 +++++++++++++++++----- src/bindings/rmr-python/rmr/rmr_mocks/rmr_mocks.py | 30 ++++++++++++++++--- src/bindings/rmr-python/setup.py | 2 +- src/bindings/rmr-python/tests/test_rmr.py | 7 +++++ src/bindings/rmr-python/tests/test_rmr_mocks.py | 18 +++++++++++- 6 files changed, 89 insertions(+), 13 deletions(-) diff --git a/src/bindings/rmr-python/docs/release-notes.rst b/src/bindings/rmr-python/docs/release-notes.rst index b4ed2dc..010cb50 100644 --- a/src/bindings/rmr-python/docs/release-notes.rst +++ b/src/bindings/rmr-python/docs/release-notes.rst @@ -7,6 +7,17 @@ The format is based on `Keep a Changelog `__ and this project adheres to `Semantic Versioning `__. + +[2.2.0] - 12/5/2019 +-------------------- + +:: + + * add ability to set a deterministic transaction id in alloc, and in the mock of alloc + * add ability to set meid in fake alloc; before None was always returned erroneously + * Fix a bug where fake_alloc was way out of date with alloc, and add a test for it + + [2.1.0] - 12/4/2019 -------------------- diff --git a/src/bindings/rmr-python/rmr/rmr.py b/src/bindings/rmr-python/rmr/rmr.py index 45515c8..336dca3 100644 --- a/src/bindings/rmr-python/rmr/rmr.py +++ b/src/bindings/rmr-python/rmr/rmr.py @@ -216,15 +216,20 @@ _rmr_alloc_msg.argtypes = [c_void_p, c_int] _rmr_alloc_msg.restype = POINTER(rmr_mbuf_t) -def rmr_alloc_msg(vctx, size, payload=None, gen_transaction_id=False, mtype=None, meid=None, sub_id=None): +def rmr_alloc_msg( + vctx, size, payload=None, gen_transaction_id=False, mtype=None, meid=None, sub_id=None, fixed_transaction_id=None +): """ Refer to the rmr C documentation for rmr_alloc_msg extern rmr_mbuf_t* rmr_alloc_msg(void* vctx, int size) + TODO: on next API break, clean up transaction_id ugliness. Kept for now to preserve API. if payload is not None, attempts to set the payload - if gen_transaction_id is True, it generates and sets a transaction id + if gen_transaction_id is True, it generates and sets a transaction id. Note, fixed_transaction_id supersedes this option if mtype is not None, sets the sbuf's message type if meid is not None, sets the sbuf's meid + if sub_id is not None, sets the sbud's subscription id + if fixed_transaction_id is set, it deterministically sets the transaction_id. This overrides the option gen_transation_id """ sbuf = _rmr_alloc_msg(vctx, size) @@ -236,7 +241,9 @@ def rmr_alloc_msg(vctx, size, payload=None, gen_transaction_id=False, mtype=None if payload: set_payload_and_length(payload, sbuf) - if gen_transaction_id: + if fixed_transaction_id: + set_transaction_id(sbuf, fixed_transaction_id) + elif gen_transaction_id: generate_and_set_transaction_id(sbuf) if mtype: @@ -526,17 +533,30 @@ def set_payload_and_length(byte_str, ptr_mbuf): def generate_and_set_transaction_id(ptr_mbuf): """ - | Generate a UUID and Set an rmr transaction id to it - | In place method, no return + Generate a UUID and Set an rmr transaction id to it + + Parameters + ---------- + ptr_mbuf: ctypes c_void_p + Pointer to an rmr message buffer + """ + set_transaction_id(ptr_mbuf, uuid.uuid1().hex.encode("utf-8")) + + +def set_transaction_id(ptr_mbuf, tid_bytes): + """ + Set an rmr transaction id + TODO: on next API break, merge these two functions. Not done now to preserve API. Parameters ---------- ptr_mbuf: ctypes c_void_p Pointer to an rmr message buffer + tid_bytes: bytes + bytes of the desired transaction id """ - uu_id = uuid.uuid1().hex.encode("utf-8") sz = _get_constants().get("RMR_MAX_XID", 0) - memmove(ptr_mbuf.contents.xaction, uu_id, sz) + memmove(ptr_mbuf.contents.xaction, tid_bytes, sz) def get_src(ptr_mbuf): diff --git a/src/bindings/rmr-python/rmr/rmr_mocks/rmr_mocks.py b/src/bindings/rmr-python/rmr/rmr_mocks/rmr_mocks.py index 32cc575..b498511 100644 --- a/src/bindings/rmr-python/rmr/rmr_mocks/rmr_mocks.py +++ b/src/bindings/rmr-python/rmr/rmr_mocks/rmr_mocks.py @@ -72,6 +72,7 @@ class _Sbuf_Contents: self.xaction = uuid.uuid1().hex.encode("utf-8") self.sub_id = 0 self.tp_state = 0 + self.meid = None def __str__(self): return str( @@ -83,6 +84,7 @@ class _Sbuf_Contents: "xaction": self.xaction, "sub_id": self.sub_id, "tp_state": self.tp_state, + "meid": self.meid, } ) @@ -99,8 +101,28 @@ def patch_rmr(monkeypatch): Patch rmr; requires a monkeypatch (pytest) object to be passed in """ - def fake_alloc(_unused, _alsounused): - return Rmr_mbuf_t() + def fake_alloc( + _vctx, _sz, payload=None, gen_transaction_id=False, mtype=None, meid=None, sub_id=None, fixed_transaction_id=None + ): + sbuf = Rmr_mbuf_t() + if payload: + sbuf.contents.payload = payload + + if fixed_transaction_id: + sbuf.contents.xaction = fixed_transaction_id + elif gen_transaction_id: + sbuf.contents.xaction = uuid.uuid1().hex.encode("utf-8") + + if mtype: + sbuf.contents.mtype = mtype + + if meid: + sbuf.contents.meid = meid + + if sub_id: + sbuf.contents.sub_id = sub_id + + return sbuf def fake_set_payload_and_length(payload, sbuf): sbuf.contents.payload = payload @@ -112,8 +134,8 @@ def patch_rmr(monkeypatch): def fake_get_payload(sbuf): return sbuf.contents.payload - def fake_get_meid(_sbuf): - return None # this is not a part of rmr_mbuf_t + def fake_get_meid(sbuf): + return sbuf.contents.meid def fake_get_src(_sbuf): return "localtest:80" # this is not a part of rmr_mbuf_t diff --git a/src/bindings/rmr-python/setup.py b/src/bindings/rmr-python/setup.py index ef31241..4d666c4 100644 --- a/src/bindings/rmr-python/setup.py +++ b/src/bindings/rmr-python/setup.py @@ -32,7 +32,7 @@ def _long_descr(): setup( name="rmr", - version="2.1.0", + version="2.2.0", packages=find_packages(), author="Tommy Carpenter, E. Scott Daniels", description="Python wrapper for RIC RMR", diff --git a/src/bindings/rmr-python/tests/test_rmr.py b/src/bindings/rmr-python/tests/test_rmr.py index c7e872a..b0e43ee 100644 --- a/src/bindings/rmr-python/tests/test_rmr.py +++ b/src/bindings/rmr-python/tests/test_rmr.py @@ -168,6 +168,13 @@ def test_alloc_fancy(): assert sbuf.contents.sub_id == summary["subscription id"] == 654321 +def test_alloc_overlapping_flags(): + """test allocation with setting the transaction id""" + sbuf = rmr.rmr_alloc_msg(MRC_SEND, SIZE, gen_transaction_id=True, fixed_transaction_id=b"6" * 32) + summary = rmr.message_summary(sbuf) + assert summary["transaction id"] == b"66666666666666666666666666666666" + + def test_rcv_timeout(): """ test torcv; this is a scary test because if it fails... it doesn't fail, it will run forever! diff --git a/src/bindings/rmr-python/tests/test_rmr_mocks.py b/src/bindings/rmr-python/tests/test_rmr_mocks.py index e3b0fea..7d0cbf0 100644 --- a/src/bindings/rmr-python/tests/test_rmr_mocks.py +++ b/src/bindings/rmr-python/tests/test_rmr_mocks.py @@ -91,8 +91,24 @@ def test_rcv_mock(monkeypatch): # test torcv, although the timeout portion is not currently mocked or tested monkeypatch.setattr("rmr.rmr.rmr_torcv_msg", rmr_mocks.rcv_mock_generator({"foo": "bar"}, 666, 0, True, 50)) - sbuf = rmr.rmr_torcv_msg(MRC, sbuf) + sbuf = rmr.rmr_torcv_msg(MRC, sbuf, 5) assert rmr.get_payload(sbuf) == b'{"foo": "bar"}' assert sbuf.contents.mtype == 666 assert sbuf.contents.state == 0 assert sbuf.contents.len == 14 + + +def test_alloc(monkeypatch): + """ + test alloc with all fields set + """ + rmr_mocks.patch_rmr(monkeypatch) + sbuf = rmr.rmr_alloc_msg( + MRC, SIZE, payload=b"foo", gen_transaction_id=True, mtype=5, meid=b"mee", sub_id=234, fixed_transaction_id=b"t" * 32 + ) + summary = rmr.message_summary(sbuf) + assert summary["payload"] == b"foo" + assert summary["transaction id"] == b"t" * 32 + assert summary["message type"] == 5 + assert summary["meid"] == b"mee" + assert summary["subscription id"] == 234 -- 2.16.6