Add ability to set xaction deterministically, bug fixes 47/1947/1
authorTommy Carpenter <tc677g@att.com>
Thu, 5 Dec 2019 15:27:21 +0000 (10:27 -0500)
committerTommy Carpenter <tc677g@att.com>
Thu, 5 Dec 2019 15:28:11 +0000 (10:28 -0500)
Change-Id: I0a3aa99f1a793b7f16fe0a5314a2529715690c01
Signed-off-by: Tommy Carpenter <tc677g@att.com>
src/bindings/rmr-python/docs/release-notes.rst
src/bindings/rmr-python/rmr/rmr.py
src/bindings/rmr-python/rmr/rmr_mocks/rmr_mocks.py
src/bindings/rmr-python/setup.py
src/bindings/rmr-python/tests/test_rmr.py
src/bindings/rmr-python/tests/test_rmr_mocks.py

index b4ed2dc..010cb50 100644 (file)
@@ -7,6 +7,17 @@ The format is based on `Keep a Changelog <http://keepachangelog.com/>`__
 and this project adheres to `Semantic
 Versioning <http://semver.org/>`__.
 
+
+[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
 --------------------
 
index 45515c8..336dca3 100644 (file)
@@ -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):
index 32cc575..b498511 100644 (file)
@@ -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
index ef31241..4d666c4 100644 (file)
@@ -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",
index c7e872a..b0e43ee 100644 (file)
@@ -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!
index e3b0fea..7d0cbf0 100644 (file)
@@ -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