From 61270901cda095afdd3ce147bf0dfd628c84cf99 Mon Sep 17 00:00:00 2001 From: "Lott, Christopher (cl778h)" Date: Wed, 6 May 2020 09:23:55 -0400 Subject: [PATCH] Define message-summary dict keys as constants Refactor code to eliminate hardcoded strings like "message state". Add wrapper method and test for method rmr_set_vlevel. Unpin xappframepy version in Ping/Pong Dockerfiles. Use constants for message-state values instead of integers. Drop all mentions of NNG. Bump version to 1.1.0. Signed-off-by: Lott, Christopher (cl778h) Change-Id: I27c0bcb4ae6d6a85b518510fd1a4c651d3445313 --- docs/release-notes.rst | 10 +-- examples/Dockerfile-Ping | 2 +- examples/Dockerfile-Pong | 2 +- examples/pong_xapp.py | 4 +- examples/rmr/rcv_all.py | 7 +- examples/rmr/receive.py | 6 +- examples/rmr/send.py | 6 +- ricxappframe/rmr/helpers.py | 9 +-- ricxappframe/rmr/rmr.py | 79 +++++++++++++++---- ricxappframe/rmr/rmr_mocks/rmr_mocks.py | 19 ++--- ricxappframe/xapp_frame.py | 13 ++-- ricxappframe/xapp_rmr.py | 8 +- ricxappframe/xapp_sdl.py | 6 +- setup.py | 2 +- tests/conftest.py | 1 - tests/test_rmr.py | 132 ++++++++++++++++---------------- tests/test_rmr_mocks.py | 50 ++++++------ tests/test_rmrclib.py | 2 + tests/test_sdl.py | 7 +- 19 files changed, 204 insertions(+), 161 deletions(-) diff --git a/docs/release-notes.rst b/docs/release-notes.rst index b28a846..8a5001f 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -10,13 +10,12 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog `__ and this project adheres to `Semantic Versioning `__. -.. contents:: - :depth: 3 - :local: -[1.0.4] - 2020-05-05 +[1.1.0] - 2020-05-06 -------------------- * Use RMR timeout on receive to avoid 100% CPU usage (`RIC-354 `_) +* Publish message-summary dict keys as constants to avoid hardcoding strings +* Add wrapper and test for RMR method rmr_set_vlevel(int) [1.0.3] - 2020-04-29 @@ -70,7 +69,6 @@ and this project adheres to `Semantic Versioning `__. * Switch to SI95 for rmr - [0.5.0] - 3/18/2020 ------------------- @@ -110,6 +108,7 @@ and this project adheres to `Semantic Versioning `__. and call stop() when they want. * Raises tox coverage minimum to 70 from 50 (currently at 86) + [0.2.0] - 3/3/2020 ------------------ @@ -129,6 +128,7 @@ and this project adheres to `Semantic Versioning `__. page looks nicer * Removes a bad release file (will be added back in subseq. commit) + [0.1.0] - 2/27/2020 ------------------- diff --git a/examples/Dockerfile-Ping b/examples/Dockerfile-Ping index acb32b8..66e3f0a 100644 --- a/examples/Dockerfile-Ping +++ b/examples/Dockerfile-Ping @@ -28,7 +28,7 @@ ENV RMR_SEED_RT /opt/route/test_route.rt RUN apk update && apk add gcc musl-dev bash # Install -RUN pip install ricxappframe==0.6.0 +RUN pip install ricxappframe COPY ping_xapp.py . # Run diff --git a/examples/Dockerfile-Pong b/examples/Dockerfile-Pong index 03d768a..5d09213 100644 --- a/examples/Dockerfile-Pong +++ b/examples/Dockerfile-Pong @@ -28,7 +28,7 @@ ENV RMR_SEED_RT /opt/route/test_route.rt RUN apk update && apk add gcc musl-dev bash # Install -RUN pip install ricxappframe==0.6.0 +RUN pip install ricxappframe COPY pong_xapp.py . # Run diff --git a/examples/pong_xapp.py b/examples/pong_xapp.py index 5c90685..863f635 100644 --- a/examples/pong_xapp.py +++ b/examples/pong_xapp.py @@ -18,7 +18,7 @@ Test xapp 2 that works with 1 # limitations under the License. # ================================================================================== import json -from ricxappframe.xapp_frame import RMRXapp +from ricxappframe.xapp_frame import RMRXapp, rmr def post_init(_self): @@ -31,7 +31,7 @@ def sixtyh(self, summary, sbuf): self.logger.info("registered 60000 handler called!") # see comment in ping about this; bytes does not work with the ric mdc logger currently print(summary) - jpay = json.loads(summary["payload"]) + jpay = json.loads(summary[rmr.RMR_MS_MSG_PAYLOAD]) self.rmr_rts(sbuf, new_payload=json.dumps({"ACK": jpay["test_send"]}).encode(), new_mtype=60001, retries=100) self.rmr_free(sbuf) diff --git a/examples/rmr/rcv_all.py b/examples/rmr/rcv_all.py index 1db982f..8a33435 100644 --- a/examples/rmr/rcv_all.py +++ b/examples/rmr/rcv_all.py @@ -1,4 +1,3 @@ -# vim: ts=4 sw=4 expandtab: # ================================================================================== # Copyright (c) 2019 Nokia # Copyright (c) 2018-2019 AT&T Intellectual Property. @@ -27,10 +26,6 @@ # Because this programme does not send messages, there is no reason # to wait for RMR to initialise a route table (no call to rmr_ready # is needed. -# -# Date: 26 September 2019 -# -# --------------------------------------------------------------------------------- from rmr import rmr from rmr import helpers @@ -64,7 +59,7 @@ while True: else: print( "got %d messages" % len( mbunch ) ) for mb in mbunch: - print( "type=%d payload=%s" % (mb["message type"], mb["payload"] ) ) + print( "type=%d payload=%s" % (mb[rmr.RMR_MS_MSG_TYPE], mb[rmr.RMR_MS_PAYLOAD] ) ) time.sleep( 1 ) # sleep to allow some to accumulate diff --git a/examples/rmr/receive.py b/examples/rmr/receive.py index ae31309..ac00878 100644 --- a/examples/rmr/receive.py +++ b/examples/rmr/receive.py @@ -20,9 +20,9 @@ import sys import signal -# Demonstrate NNG cleanup +# Demonstrate RMR cleanup def signal_handler(sig, frame): - print("SIGINT received! Cleaning up rmr") + print("SIGINT received! Cleaning up RMR") rmr.rmr_close(mrc) print("Byeee") sys.exit(0) @@ -44,7 +44,7 @@ while True: print("Waiting for a message, will timeout after 2000ms") sbuf = rmr.rmr_torcv_msg(mrc, sbuf, 2000) summary = rmr.message_summary(sbuf) - if summary["message state"] == 12: + if summary[rmr.RMR_MS_MSG_STATE] == 12: print("Nothing received =(") else: print("Message received!: {}".format(summary)) diff --git a/examples/rmr/send.py b/examples/rmr/send.py index 270d893..4801649 100644 --- a/examples/rmr/send.py +++ b/examples/rmr/send.py @@ -23,9 +23,9 @@ import sys from ricxappframe.rmr import rmr -# Demonstrate NNG cleanup +# Demonstrate RMR cleanup def signal_handler(sig, frame): - print("SIGINT received! Cleaning up rmr") + print("SIGINT received! Cleaning up RMR") rmr.rmr_close(mrc) print("Byeee") sys.exit(0) @@ -58,7 +58,7 @@ while True: print("Waiting for return, will timeout after 2000ms") sbuf = rmr.rmr_torcv_msg(mrc, sbuf, 2000) summary = rmr.message_summary(sbuf) - if summary["message state"] == 12: + if summary[rmr.RMR_MS_MSG_STATE] == 12: print("Nothing received yet") else: print("Ack Message received!: {}".format(summary)) diff --git a/ricxappframe/rmr/helpers.py b/ricxappframe/rmr/helpers.py index 339526a..bc7a4fb 100644 --- a/ricxappframe/rmr/helpers.py +++ b/ricxappframe/rmr/helpers.py @@ -1,4 +1,3 @@ -# vim: ts=4 sw=4 expandtab: # ================================================================================== # Copyright (c) 2019 Nokia # Copyright (c) 2018-2019 AT&T Intellectual Property. @@ -19,8 +18,6 @@ # Mnemonic: helpers.py # Abstract: This is a collection of extensions to the RMR base package # which are likely to be convenient for Python programs. -# Date: 26 September 2019 -# --------------------------------------------------------------------------- from ricxappframe.rmr import rmr @@ -60,10 +57,10 @@ def rmr_rcvall_msgs(mrc, pass_filter=[], timeout=0): mbuf = rmr.rmr_torcv_msg(mrc, mbuf, timeout) # first call may have non-zero timeout timeout = 0 # reset so subsequent calls do not wait summary = rmr.message_summary(mbuf) - if summary["message status"] != "RMR_OK": # ok indicates msg received, stop on all other states; e.g., RMR_ERR_TIMEOUT + if summary[rmr.RMR_MS_MSG_STATUS] != "RMR_OK": # ok indicates msg received, stop on all other states break - if len(pass_filter) == 0 or summary["message type"] in pass_filter: # no filter, or passes; capture it + if len(pass_filter) == 0 or summary[rmr.RMR_MS_MSG_TYPE] in pass_filter: # no filter, or passes; capture it new_messages.append(summary) rmr.rmr_free_msg(mbuf) # free the single buffer to avoid leak @@ -100,7 +97,7 @@ def rmr_rcvall_msgs_raw(mrc, pass_filter=[], timeout=0): mbuf = rmr.rmr_torcv_msg(mrc, mbuf, timeout) # first call may have non-zero timeout timeout = 0 # reset so subsequent calls do not wait summary = rmr.message_summary(mbuf) - if summary["message status"] != "RMR_OK": # e.g., RMR_ERR_TIMEOUT + if summary[rmr.RMR_MS_MSG_STATUS] != "RMR_OK": rmr.rmr_free_msg(mbuf) # free the failed-to-receive buffer break diff --git a/ricxappframe/rmr/rmr.py b/ricxappframe/rmr/rmr.py index 59885ed..00c4b25 100644 --- a/ricxappframe/rmr/rmr.py +++ b/ricxappframe/rmr/rmr.py @@ -80,10 +80,37 @@ RMRFL_MTCALL = _get_rmr_constant('RMRFL_MTCALL', 0x02) # initialization flags RMRFL_NONE = _get_rmr_constant('RMRFL_NONE', 0x0) #: State constant for OK RMR_OK = _get_rmr_constant('RMR_OK', 0x00) -#: State constant for timeout -RMR_ERR_TIMEOUT = _get_rmr_constant('RMR_ERR_TIMEOUT') +#: State constant for no endpoint based on msg type +RMR_ERR_NOENDPT = _get_rmr_constant('RMR_ERR_NOENDPT') #: State constant for retry RMR_ERR_RETRY = _get_rmr_constant('RMR_ERR_RETRY') +#: State constant for timeout +RMR_ERR_TIMEOUT = _get_rmr_constant('RMR_ERR_TIMEOUT') + +# Publish keys used in the message summary dict as constants + +# message payload, bytes +RMR_MS_PAYLOAD = "payload" +# payload length, integer +RMR_MS_PAYLOAD_LEN = "payload length" +# message type, integer +RMR_MS_MSG_TYPE = "message type" +# subscription ID, integer +RMR_MS_SUB_ID = "subscription id" +# transaction ID, bytes +RMR_MS_TRN_ID = "transaction id" +# state of message processing, integer; e.g., 0 +RMR_MS_MSG_STATE = "message state" +# state of message processing converted to string; e.g., RMR_OK +RMR_MS_MSG_STATUS = "message status" +# number of bytes usable in the payload, integer +RMR_MS_PAYLOAD_MAX = "payload max size" +# managed entity ID, bytes +RMR_MS_MEID = "meid" +# message source, string; e.g., host:port +RMR_MS_MSG_SOURCE = "message source" +# transport state, integer +RMR_MS_ERRNO = "errno" class rmr_mbuf_t(Structure): @@ -101,7 +128,7 @@ class rmr_mbuf_t(Structure): | | these things are off limits to the user application | - | void* tp_buf; // underlying transport allocated pointer (e.g. nng message) + | void* tp_buf; // underlying transport allocated pointer | void* header; // internal message header (whole buffer: header+payload) | unsigned char* id; // if we need an ID in the message separate from the xaction id | int flags; // various MFL (private) flags as needed @@ -610,6 +637,24 @@ def rmr_get_src(ptr_mbuf: POINTER(rmr_mbuf_t), dest: c_char_p) -> c_char_p: return _rmr_get_src(ptr_mbuf, dest) +_rmr_set_vlevel = _wrap_rmr_function('rmr_set_vlevel', None, [c_int]) + + +def rmr_set_vlevel(new_level: c_int): + """ + Sets the verbosity level which determines the messages RMR writes to standard error. + Refer to RMR C documentation for method:: + + void rmr_set_vlevel( int new_level ) + + Parameters + ---------- + new_level: int + New logging verbosity level, an integer in the range 0 (none) to 5 (debug). + """ + _rmr_set_vlevel(new_level) + + # Methods that exist ONLY in rmr-python, and are not wrapped methods # In hindsight, I wish i put these in a separate module, but leaving this here to prevent api breakage. @@ -655,30 +700,30 @@ def get_xaction(ptr_mbuf: c_void_p) -> bytes: def message_summary(ptr_mbuf: c_void_p) -> dict: """ - Returns a dict with the fields of an RMR message. + Builds a dict with the contents of an RMR message. Parameters ---------- ptr_mbuf: ctypes c_void_p - Pointer to an rmr message buffer + Pointer to an RMR message buffer Returns ------- dict: - dict message summary + Message content as key-value pairs; keys are defined as RMR_MS_* constants. """ return { - "payload": get_payload(ptr_mbuf) if ptr_mbuf.contents.state == RMR_OK else None, - "payload length": ptr_mbuf.contents.len, - "message type": ptr_mbuf.contents.mtype, - "subscription id": ptr_mbuf.contents.sub_id, - "transaction id": get_xaction(ptr_mbuf), - "message state": ptr_mbuf.contents.state, - "message status": state_to_status(ptr_mbuf.contents.state), - "payload max size": rmr_payload_size(ptr_mbuf), - "meid": rmr_get_meid(ptr_mbuf), - "message source": get_src(ptr_mbuf), - "errno": ptr_mbuf.contents.tp_state, + RMR_MS_PAYLOAD: get_payload(ptr_mbuf) if ptr_mbuf.contents.state == RMR_OK else None, + RMR_MS_PAYLOAD_LEN: ptr_mbuf.contents.len, + RMR_MS_MSG_TYPE: ptr_mbuf.contents.mtype, + RMR_MS_SUB_ID: ptr_mbuf.contents.sub_id, + RMR_MS_TRN_ID: get_xaction(ptr_mbuf), + RMR_MS_MSG_STATE: ptr_mbuf.contents.state, + RMR_MS_MSG_STATUS: state_to_status(ptr_mbuf.contents.state), + RMR_MS_PAYLOAD_MAX: rmr_payload_size(ptr_mbuf), + RMR_MS_MEID: rmr_get_meid(ptr_mbuf), + RMR_MS_MSG_SOURCE: get_src(ptr_mbuf), + RMR_MS_ERRNO: ptr_mbuf.contents.tp_state, } diff --git a/ricxappframe/rmr/rmr_mocks/rmr_mocks.py b/ricxappframe/rmr/rmr_mocks/rmr_mocks.py index 2c188d4..99ac406 100644 --- a/ricxappframe/rmr/rmr_mocks/rmr_mocks.py +++ b/ricxappframe/rmr/rmr_mocks/rmr_mocks.py @@ -21,6 +21,7 @@ Provides mocks that are useful for end applications unit testing import json import uuid +from ricxappframe.rmr import rmr def rcv_mock_generator(msg_payload, msg_type, msg_state, jsonb, timeout=0): @@ -62,7 +63,7 @@ def send_mock_generator(msg_state): class _Sbuf_Contents: - """fake version of how pointers work (ctype pointer access is done by accessing a magical attrivute called "contents""" + """fake version of how pointers work (ctype pointer access is done by accessing a magical attribute called "contents""" def __init__(self): self.state = 0 @@ -77,14 +78,14 @@ class _Sbuf_Contents: def __str__(self): return str( { - "state": self.state, - "mtype": self.mtype, - "len": self.len, - "payload": self.payload, - "xaction": self.xaction, - "sub_id": self.sub_id, - "tp_state": self.tp_state, - "meid": self.meid, + rmr.RMR_MS_MSG_STATE: self.state, + rmr.RMR_MS_MSG_TYPE: self.mtype, + rmr.RMR_MS_PAYLOAD_LEN: self.len, + rmr.RMR_MS_PAYLOAD: self.payload, + rmr.RMR_MS_TRN_ID: self.xaction, + rmr.RMR_MS_SUB_ID: self.sub_id, + rmr.RMR_MS_ERRNO: self.tp_state, + rmr.RMR_MS_MEID: self.meid, } ) diff --git a/ricxappframe/xapp_frame.py b/ricxappframe/xapp_frame.py index 58596b8..b81804e 100644 --- a/ricxappframe/xapp_frame.py +++ b/ricxappframe/xapp_frame.py @@ -1,7 +1,3 @@ -""" -Framework for python xapps -Framework here means Xapp classes that can be subclassed -""" # ================================================================================== # Copyright (c) 2020 Nokia # Copyright (c) 2020 AT&T Intellectual Property. @@ -18,10 +14,15 @@ Framework here means Xapp classes that can be subclassed # See the License for the specific language governing permissions and # limitations under the License. # ================================================================================== +""" +Framework for python xapps +Framework here means Xapp classes that can be subclassed +""" + from threading import Thread from ricxappframe import xapp_rmr -from ricxappframe.xapp_sdl import SDLWrapper from ricxappframe.rmr import rmr +from ricxappframe.xapp_sdl import SDLWrapper from mdclogpy import Logger # constants @@ -337,7 +338,7 @@ class RMRXapp(_BaseXapp): if not self._rmr_loop.rcv_queue.empty(): (summary, sbuf) = self._rmr_loop.rcv_queue.get() # dispatch - func = self._dispatch.get(summary["message type"], None) + func = self._dispatch.get(summary[rmr.RMR_MS_MSG_TYPE], None) if not func: func = self._default_handler func(self, summary, sbuf) diff --git a/ricxappframe/xapp_rmr.py b/ricxappframe/xapp_rmr.py index 6092e14..93eaeeb 100644 --- a/ricxappframe/xapp_rmr.py +++ b/ricxappframe/xapp_rmr.py @@ -1,7 +1,3 @@ -""" -Contains rmr functionality specific to the xapp -The general rmr API is via "rmr" -""" # ================================================================================== # Copyright (c) 2020 Nokia # Copyright (c) 2020 AT&T Intellectual Property. @@ -19,6 +15,10 @@ The general rmr API is via "rmr" # limitations under the License. # ================================================================================== +""" +Contains RMR functionality specific to the xapp. +The general rmr API is via "rmr" +""" import time import queue diff --git a/ricxappframe/xapp_sdl.py b/ricxappframe/xapp_sdl.py index af41aab..e39c711 100644 --- a/ricxappframe/xapp_sdl.py +++ b/ricxappframe/xapp_sdl.py @@ -1,6 +1,3 @@ -""" -sdl functionality -""" # ================================================================================== # Copyright (c) 2020 Nokia # Copyright (c) 2020 AT&T Intellectual Property. @@ -18,6 +15,9 @@ sdl functionality # limitations under the License. # ================================================================================== +""" +sdl functionality +""" import msgpack from ricsdl.syncstorage import SyncStorage diff --git a/setup.py b/setup.py index 332fde9..3d2e96f 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ def _long_descr(): setup( name="ricxappframe", - version="1.0.4", + version="1.1.0", packages=find_packages(exclude=["tests.*", "tests"]), author="Tommy Carpenter, E. Scott Daniels", description="Xapp and RMR framework for python", diff --git a/tests/conftest.py b/tests/conftest.py index e29c779..eead2c4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,3 @@ -# vim: ts=4 sw=4 expandtab: # ================================================================================== # Copyright (c) 2019 Nokia # Copyright (c) 2018-2019 AT&T Intellectual Property. diff --git a/tests/test_rmr.py b/tests/test_rmr.py index 72cdf4b..4d0d439 100644 --- a/tests/test_rmr.py +++ b/tests/test_rmr.py @@ -1,4 +1,3 @@ -# vim: ts=4 sw=4 expandtab: # =================================================================================2 # Copyright (c) 2019-2020 Nokia # Copyright (c) 2018-2020 AT&T Intellectual Property. @@ -60,14 +59,14 @@ def _assert_new_sbuf(sbuf): verify the initial state of an alloced message is what we expect """ summary = rmr.message_summary(sbuf) - assert summary["payload"] == b"" - assert summary["payload length"] == 0 - assert summary["subscription id"] == -1 - assert summary["transaction id"] == b"" - assert summary["message state"] == 0 - assert summary["message status"] == "RMR_OK" - assert summary["meid"] == b"" - assert summary["errno"] == 0 + assert summary[rmr.RMR_MS_PAYLOAD] == b"" + assert summary[rmr.RMR_MS_PAYLOAD_LEN] == 0 + assert summary[rmr.RMR_MS_SUB_ID] == -1 + assert summary[rmr.RMR_MS_TRN_ID] == b"" + assert summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK + assert summary[rmr.RMR_MS_MSG_STATUS] == "RMR_OK" + assert summary[rmr.RMR_MS_MEID] == b"" + assert summary[rmr.RMR_MS_ERRNO] == 0 def test_meid(): @@ -77,18 +76,18 @@ def test_meid(): sbuf = rmr.rmr_alloc_msg(MRC_SEND, SIZE) rmr.rmr_set_meid(sbuf, b"\x01\x02") - assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)["meid"] == b"\x01\x02" + assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)[rmr.RMR_MS_MEID] == b"\x01\x02" assert len(rmr.rmr_get_meid(sbuf)) == 2 rmr.rmr_set_meid(sbuf, b"\x00" * 31) - assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)["meid"] == b"" # NULL bytes get truncated + assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)[rmr.RMR_MS_MEID] == b"" # NULL bytes get truncated rmr.rmr_set_meid(sbuf, b"6" * 31) - assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)["meid"] == b"6" * 31 # string in string out + assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)[rmr.RMR_MS_MEID] == b"6" * 31 # string in string out rmr.rmr_set_meid(sbuf, b"\x01\x02") assert ( - rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)["meid"] == b"\x01\x02" + rmr.rmr_get_meid(sbuf) == rmr.message_summary(sbuf)[rmr.RMR_MS_MEID] == b"\x01\x02" ) # Ctypes will chop at first nil, so expect only 2 bytes back assert len(rmr.rmr_get_meid(sbuf)) == 2 @@ -109,23 +108,26 @@ def test_rmr_set_get(): pay = b"\x01\x00\x80" rmr.set_payload_and_length(pay, sbuf) summary = rmr.message_summary(sbuf) - assert summary["payload"] == pay - assert summary["payload length"] == 3 + assert summary[rmr.RMR_MS_PAYLOAD] == pay + assert summary[rmr.RMR_MS_PAYLOAD_LEN] == 3 # test transid (note we cant test payload because it's randomly gen) - assert summary["transaction id"] == b"" - assert len(summary["transaction id"]) == 0 + assert summary[rmr.RMR_MS_TRN_ID] == b"" + assert len(summary[rmr.RMR_MS_TRN_ID]) == 0 rmr.generate_and_set_transaction_id(sbuf) summary = rmr.message_summary(sbuf) - assert summary["transaction id"] != b"" - assert len(summary["transaction id"]) == 32 + assert summary[rmr.RMR_MS_TRN_ID] != b"" + assert len(summary[rmr.RMR_MS_TRN_ID]) == 32 # test meid - assert rmr.rmr_get_meid(sbuf) == summary["meid"] == b"" + assert rmr.rmr_get_meid(sbuf) == summary[rmr.RMR_MS_MEID] == b"" rmr.rmr_set_meid(sbuf, b"666\x01\x00\x01") summary = rmr.message_summary(sbuf) - assert rmr.rmr_get_meid(sbuf) == summary["meid"] == b"666\x01" - assert (len(summary["meid"])) == 4 + assert rmr.rmr_get_meid(sbuf) == summary[rmr.RMR_MS_MEID] == b"666\x01" + assert (len(summary[rmr.RMR_MS_MEID])) == 4 + + # exercise the logging setter; cannot test the result + rmr.rmr_set_vlevel(0) def test_alloc_fancy(): @@ -133,21 +135,21 @@ def test_alloc_fancy(): pay = b"yoo\x01\x00\x80" sbuf = rmr.rmr_alloc_msg(MRC_SEND, SIZE, payload=pay, gen_transaction_id=True, mtype=14, meid=b"asdf", sub_id=654321) summary = rmr.message_summary(sbuf) - assert summary["payload"] == pay - assert summary["payload length"] == 6 - assert summary["transaction id"] != b"" # hard to test what it will be, but make sure not empty - assert len(summary["transaction id"]) == 32 - assert summary["message state"] == 0 - assert summary["message type"] == sbuf.contents.mtype == 14 - assert rmr.rmr_get_meid(sbuf) == summary["meid"] == b"asdf" - assert sbuf.contents.sub_id == summary["subscription id"] == 654321 + assert summary[rmr.RMR_MS_PAYLOAD] == pay + assert summary[rmr.RMR_MS_PAYLOAD_LEN] == 6 + assert summary[rmr.RMR_MS_TRN_ID] != b"" # hard to test what it will be, but make sure not empty + assert len(summary[rmr.RMR_MS_TRN_ID]) == 32 + assert summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK + assert summary[rmr.RMR_MS_MSG_TYPE] == sbuf.contents.mtype == 14 + assert rmr.rmr_get_meid(sbuf) == summary[rmr.RMR_MS_MEID] == b"asdf" + assert sbuf.contents.sub_id == summary[rmr.RMR_MS_SUB_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" + assert summary[rmr.RMR_MS_TRN_ID] == b"66666666666666666666666666666666" def test_rcv_timeout(): @@ -161,8 +163,8 @@ def test_rcv_timeout(): start_rcv_sec = time.time() sbuf_rcv = rmr.rmr_torcv_msg(MRC_RCV, sbuf_rcv, 500) # should wait a bit before returning summary = rmr.message_summary(sbuf_rcv) - assert summary["message state"] == 12 - assert summary["message status"] == "RMR_ERR_TIMEOUT" + assert summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_ERR_TIMEOUT + assert summary[rmr.RMR_MS_MSG_STATUS] == "RMR_ERR_TIMEOUT" assert(time.time() - start_rcv_sec > 0.5) # test duration should be longer than the timeout @@ -179,18 +181,18 @@ def test_send_rcv(): sbuf_send.contents.mtype = 0 sbuf_send = rmr.rmr_send_msg(MRC_SEND, sbuf_send) send_summary = rmr.message_summary(sbuf_send) - assert send_summary["message state"] == 0 # if send fails don't attempt receive - assert send_summary["message status"] == "RMR_OK" + assert send_summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK # if send fails don't attempt receive + assert send_summary[rmr.RMR_MS_MSG_STATUS] == "RMR_OK" time.sleep(0.5) # receive it in other context sbuf_rcv = rmr.rmr_alloc_msg(MRC_RCV, SIZE) sbuf_rcv = rmr.rmr_torcv_msg(MRC_RCV, sbuf_rcv, 2000) rcv_summary = rmr.message_summary(sbuf_rcv) - assert rcv_summary["message state"] == 0 - assert rcv_summary["message status"] == "RMR_OK" - assert rcv_summary["message type"] == 0 - assert rcv_summary["payload"] == pay + assert rcv_summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK + assert rcv_summary[rmr.RMR_MS_MSG_STATUS] == "RMR_OK" + assert rcv_summary[rmr.RMR_MS_MSG_TYPE] == 0 + assert rcv_summary[rmr.RMR_MS_PAYLOAD] == pay # send an ACK back ack_pay = b"message received" @@ -201,10 +203,10 @@ def test_send_rcv(): sbuf_send = rmr.rmr_torcv_msg(MRC_SEND, sbuf_send, 2000) send_ack_summary = rmr.message_summary(sbuf_send) - assert send_ack_summary["message state"] == rcv_ack_summary["message state"] == 0 - assert send_ack_summary["message status"] == rcv_ack_summary["message status"] == "RMR_OK" - assert send_ack_summary["payload"] == ack_pay - assert send_ack_summary["message type"] == 6666 + assert send_ack_summary[rmr.RMR_MS_MSG_STATE] == rcv_ack_summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK + assert send_ack_summary[rmr.RMR_MS_MSG_STATUS] == rcv_ack_summary[rmr.RMR_MS_MSG_STATUS] == "RMR_OK" + assert send_ack_summary[rmr.RMR_MS_PAYLOAD] == ack_pay + assert send_ack_summary[rmr.RMR_MS_MSG_TYPE] == 6666 def test_send_rcv_subid_good(): @@ -228,31 +230,31 @@ def test_send_rcv_subid_good(): rcv_summary = rmr.message_summary(sbuf_rcv) # asserts - assert send_summary["message state"] == rcv_summary["message state"] == 0 - assert send_summary["message status"] == rcv_summary["message status"] == "RMR_OK" - assert pre_send_summary["payload"] == rcv_summary["payload"] == pay - assert pre_send_summary["message type"] == rcv_summary["message type"] == test_mtype - assert pre_send_summary["subscription id"] == rcv_summary["subscription id"] == test_subid + assert send_summary[rmr.RMR_MS_MSG_STATE] == rcv_summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK + assert send_summary[rmr.RMR_MS_MSG_STATUS] == rcv_summary[rmr.RMR_MS_MSG_STATUS] == "RMR_OK" + assert pre_send_summary[rmr.RMR_MS_PAYLOAD] == rcv_summary[rmr.RMR_MS_PAYLOAD] == pay + assert pre_send_summary[rmr.RMR_MS_MSG_TYPE] == rcv_summary[rmr.RMR_MS_MSG_TYPE] == test_mtype + assert pre_send_summary[rmr.RMR_MS_SUB_ID] == rcv_summary[rmr.RMR_MS_SUB_ID] == test_subid def test_send_rcv_subid_bad_subid(): """ - test send and receive where subid is used for routing but nobody recieves this subid + test send and receive where subid is used for routing but nobody receives this subid """ sbuf_send = rmr.rmr_alloc_msg(MRC_SEND, 3, b"\x01\x00\x80", mtype=46656, sub_id=778) sbuf_send = rmr.rmr_send_msg(MRC_SEND, sbuf_send) - assert rmr.message_summary(sbuf_send)["message state"] == 2 - assert rmr.message_summary(sbuf_send)["message status"] == "RMR_ERR_NOENDPT" + assert rmr.message_summary(sbuf_send)[rmr.RMR_MS_MSG_STATE] == rmr.RMR_ERR_NOENDPT + assert rmr.message_summary(sbuf_send)[rmr.RMR_MS_MSG_STATUS] == "RMR_ERR_NOENDPT" def test_send_rcv_subid_bad_mtype(): """ - test send and receive where subid is used for routing but nobody recieves this mtype + test send and receive where subid is used for routing but nobody receives this mtype """ sbuf_send = rmr.rmr_alloc_msg(MRC_SEND, 3, b"\x01\x00\x80", mtype=46657, sub_id=777) sbuf_send = rmr.rmr_send_msg(MRC_SEND, sbuf_send) - assert rmr.message_summary(sbuf_send)["message state"] == 2 - assert rmr.message_summary(sbuf_send)["message status"] == "RMR_ERR_NOENDPT" + assert rmr.message_summary(sbuf_send)[rmr.RMR_MS_MSG_STATE] == rmr.RMR_ERR_NOENDPT + assert rmr.message_summary(sbuf_send)[rmr.RMR_MS_MSG_STATUS] == "RMR_ERR_NOENDPT" def send_burst(mrc, fmt, mtype=1, num=13, counter=0): @@ -274,12 +276,12 @@ def send_burst(mrc, fmt, mtype=1, num=13, counter=0): while max_retries > 0: sbuf_send = rmr.rmr_send_msg(mrc, sbuf_send) ms = rmr.message_summary(sbuf_send) - if ms["message state"] != 10: # 10 is retry + if ms[rmr.RMR_MS_MSG_STATE] != rmr.RMR_ERR_RETRY: break max_retries -= 1 time.sleep(0.75) - assert ms["message state"] == 0 + assert ms[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK assert max_retries > 0 @@ -297,9 +299,9 @@ def test_rcv_all(): for i, ms in enumerate(bundle): ms = bundle[i] # validate each summary returned, and ordering preserved - assert ms["message state"] == 0 + assert ms[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK expected_pay = bytes(pay_fmt % i, "UTF-8") - assert ms["payload"] == expected_pay + assert ms[rmr.RMR_MS_PAYLOAD] == expected_pay send_burst(MRC_SEND, pay_fmt, mtype=1, num=10) # send a second round with msg types 1 and 2 to test filter send_burst(MRC_SEND, pay_fmt, mtype=2, num=8) @@ -313,10 +315,10 @@ def test_rcv_all(): for i, (ms, sbuf) in enumerate(bundle): # test the raw version test_summary = rmr.message_summary(sbuf) assert test_summary == ms - assert ms["message state"] == 0 # all should be OK - assert ms["message type"] == 2 # only mtype 2 should have been received + assert ms[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK # all should be OK + assert ms[rmr.RMR_MS_MSG_TYPE] == 2 # only mtype 2 should have been received expected_pay = bytes(pay_fmt % i, "UTF-8") # ordering should still jive with the counter - assert ms["payload"] == expected_pay + assert ms[rmr.RMR_MS_PAYLOAD] == expected_pay rmr.rmr_free_msg(sbuf) # check the timeout scenarios @@ -349,7 +351,7 @@ def test_resize_payload(): long_payload = b"This is a long payload that should force the message buffer to be reallocated" rmr.set_payload_and_length(long_payload, mbuf) summary = rmr.message_summary(mbuf) - assert summary["payload max size"] >= len(long_payload) # RMR may allocate a larger payload space - assert summary["payload length"] == len(long_payload) # however, the length must be exactly the same - assert summary["message type"] == mtype # both mtype and sub-id should be preserved in new - assert summary["subscription id"] == subid + assert summary[rmr.RMR_MS_PAYLOAD_MAX] >= len(long_payload) # RMR may allocate a larger payload space + assert summary[rmr.RMR_MS_PAYLOAD_LEN] == len(long_payload) # however, the length must be exactly the same + assert summary[rmr.RMR_MS_MSG_TYPE] == mtype # both mtype and sub-id should be preserved in new + assert summary[rmr.RMR_MS_SUB_ID] == subid diff --git a/tests/test_rmr_mocks.py b/tests/test_rmr_mocks.py index 7479e1a..6d34a3b 100644 --- a/tests/test_rmr_mocks.py +++ b/tests/test_rmr_mocks.py @@ -41,15 +41,15 @@ def test_send_mock(monkeypatch): rmr.set_payload_and_length("testttt".encode("utf8"), sbuf) expected = { - "meid": None, - "message source": "localtest:80", - "message state": 0, - "message type": 0, - "message status": "RMR_OK", - "payload": b"testttt", - "payload length": 7, - "payload max size": 4096, - "subscription id": 0, + rmr.RMR_MS_MEID: None, + rmr.RMR_MS_MSG_SOURCE: "localtest:80", + rmr.RMR_MS_MSG_STATE: rmr.RMR_OK, + rmr.RMR_MS_MSG_STATUS: "RMR_OK", + rmr.RMR_MS_MSG_TYPE: 0, + rmr.RMR_MS_PAYLOAD: b"testttt", + rmr.RMR_MS_PAYLOAD_LEN: 7, + rmr.RMR_MS_PAYLOAD_MAX: 4096, + rmr.RMR_MS_SUB_ID: 0, } _partial_dict_comparison(expected, rmr.message_summary(sbuf)) @@ -60,15 +60,15 @@ def test_send_mock(monkeypatch): sbuf = rmr.rmr_send_msg(MRC, sbuf) expected = { - "meid": None, - "message source": "localtest:80", - "message state": 12, - "message type": 666, - "message status": "RMR_ERR_TIMEOUT", - "payload": None, - "payload length": 7, - "payload max size": 4096, - "subscription id": 0, + rmr.RMR_MS_MEID: None, + rmr.RMR_MS_MSG_SOURCE: "localtest:80", + rmr.RMR_MS_MSG_STATE: rmr.RMR_ERR_TIMEOUT, + rmr.RMR_MS_MSG_STATUS: "RMR_ERR_TIMEOUT", + rmr.RMR_MS_MSG_TYPE: 666, + rmr.RMR_MS_PAYLOAD: None, + rmr.RMR_MS_PAYLOAD_LEN: 7, + rmr.RMR_MS_PAYLOAD_MAX: 4096, + rmr.RMR_MS_SUB_ID: 0, } _partial_dict_comparison(expected, rmr.message_summary(sbuf)) @@ -85,7 +85,7 @@ def test_rcv_mock(monkeypatch): sbuf = rmr.rmr_rcv_msg(MRC, sbuf) assert rmr.get_payload(sbuf) == b'{"foo": "bar"}' assert sbuf.contents.mtype == 666 - assert sbuf.contents.state == 0 + assert sbuf.contents.state == rmr.RMR_OK assert sbuf.contents.len == 14 # test torcv, although the timeout portion is not currently mocked or tested @@ -93,7 +93,7 @@ def test_rcv_mock(monkeypatch): 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.state == rmr.RMR_OK assert sbuf.contents.len == 14 @@ -106,8 +106,8 @@ def test_alloc(monkeypatch): 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 + assert summary[rmr.RMR_MS_PAYLOAD] == b"foo" + assert summary[rmr.RMR_MS_TRN_ID] == b"t" * 32 + assert summary[rmr.RMR_MS_MSG_TYPE] == 5 + assert summary[rmr.RMR_MS_MEID] == b"mee" + assert summary[rmr.RMR_MS_SUB_ID] == 234 diff --git a/tests/test_rmrclib.py b/tests/test_rmrclib.py index eba4436..e62281a 100644 --- a/tests/test_rmrclib.py +++ b/tests/test_rmrclib.py @@ -45,5 +45,7 @@ def test_get_mapping_dict(expected_states): """ assert rmrclib.get_mapping_dict() == expected_states assert rmrclib.state_to_status(0) == "RMR_OK" + assert rmrclib.state_to_status(2) == "RMR_ERR_NOENDPT" + assert rmrclib.state_to_status(10) == "RMR_ERR_RETRY" assert rmrclib.state_to_status(12) == "RMR_ERR_TIMEOUT" assert rmrclib.state_to_status(666) == "UNKNOWN STATE" diff --git a/tests/test_sdl.py b/tests/test_sdl.py index 92edcb0..c40960a 100644 --- a/tests/test_sdl.py +++ b/tests/test_sdl.py @@ -1,6 +1,3 @@ -""" -tests data functions -""" # ================================================================================== # Copyright (c) 2019-2020 Nokia # Copyright (c) 2018-2020 AT&T Intellectual Property. @@ -17,6 +14,10 @@ tests data functions # See the License for the specific language governing permissions and # limitations under the License. # ================================================================================== +""" +tests data functions +""" + from ricxappframe.xapp_sdl import SDLWrapper -- 2.16.6