The format is based on `Keep a Changelog <http://keepachangelog.com/>`__
and this project adheres to `Semantic Versioning <http://semver.org/>`__.
+[3.0.1] - 2021-12-07
+--------------------
+* Take configuration and rmr unit tests back into use after fixing the tests (`RIC-865 <https://jira.o-ran-sc.org/browse/RIC-865>`_)
+* Improve memory leak fix done in the version 3.0.0 to free memory also if python exception has been thrown.
+
[3.0.0] - 2021-12-03
--------------------
* Upgrade to RMR version 4.8.0 to fix memory leak in get_constants() function (`RIC-858 <https://jira.o-ran-sc.org/browse/RIC-858>`_)
return _rmr_wh_call(vctx, whid, ptr_mbuf, call_id, max_wait)
-_rmr_wh_close = _wrap_rmr_function('rmr_close', None, [c_void_p, c_int])
+_rmr_wh_close = _wrap_rmr_function('rmr_wh_close', None, [c_void_p, c_int])
def rmr_wh_close(vctx: c_void_p, whid: c_int):
# ==================================================================================
import ctypes
import json
+from contextlib import contextmanager
# Subpackage that creates and publishes a reference to the C shared library.
# Intended to be private; RMR-python and xapp-frame-py users should not need this.
_rmr_free_consts.restype = None
+@contextmanager
+def _rmr_get_consts_decorator():
+ ptr = _rmr_get_consts()
+ try:
+ yield ptr
+ finally:
+ _rmr_free_consts(ptr)
+
+
def get_constants(cache={}):
"""
Gets constants published by RMR and caches for subsequent calls.
if cache:
return cache
- ptr = _rmr_get_consts() # read char pointer
- js = ctypes.cast(ptr, ctypes.c_char_p).value # cast to json string
- cache = json.loads(str(js.decode())) # create constants value object as a hash
- _rmr_free_consts(ptr)
+ # read pointer to json data
+ with _rmr_get_consts_decorator() as ptr:
+ js = ctypes.cast(ptr, ctypes.c_char_p).value # cast it to python string
+ cache = json.loads(str(js.decode())) # create constants value object as a hash
+
return cache
setup(
name="ricxappframe",
- version="3.0.0",
+ version="3.0.1",
packages=find_packages(exclude=["tests.*", "tests"]),
author="O-RAN Software Community",
description="Xapp and RMR framework for Python",
time.sleep(3)
assert not config_event_seen
rmr_xapp_noconfig.stop()
+ rmr_xapp_noconfig = None
def test_default_config_handler(monkeypatch):
# give the work loop a chance to timeout on RMR and process the config event
time.sleep(3)
rmr_xapp_defconfig.stop()
+ rmr_xapp_defconfig = None
def test_custom_config_handler(monkeypatch):
time.sleep(3)
assert change_config_event
rmr_xapp_config.stop()
+ rmr_xapp_config = None
def teardown_module():
"""
os.remove(config_file_path)
with suppress(Exception):
- rmr_xapp_config.stop()
- with suppress(Exception):
- rmr_xapp_defconfig.stop()
- with suppress(Exception):
- rmr_xapp_noconfig.stop()
+ if rmr_xapp_config:
+ rmr_xapp_config.stop()
+ if rmr_xapp_defconfig:
+ rmr_xapp_defconfig.stop()
+ if rmr_xapp_noconfig:
+ rmr_xapp_noconfig.stop()
assert send_summary[rmr.RMR_MS_MSG_TYPE] == rcv_summary[rmr.RMR_MS_MSG_TYPE] == mtype
assert send_summary[rmr.RMR_MS_PAYLOAD] == rcv_summary[rmr.RMR_MS_PAYLOAD] == payload
+ sbuf_send = rmr.rmr_alloc_msg(MRC_SEND, SIZE)
+ _assert_new_sbuf(sbuf_send)
+ mtype = 1
+ sbuf_send.contents.mtype = mtype
+ payload = b"Birds like worms"
+ rmr.set_payload_and_length(payload, sbuf_send)
+
# send without waiting for a response
rmr.rmr_wh_send_msg(MRC_SEND, whid, sbuf_send)
commands =
# add -s flag after pytest to show logs immediately instead of delaying
- pytest --ignore=tests/test_config.py --ignore=tests/test_rmr.py --cov ricxappframe --cov-report xml --cov-report term-missing --cov-report html --cov-fail-under=70 --junitxml=/tmp/tests.xml
+ pytest --cov ricxappframe --cov-report xml --cov-report term-missing --cov-report html --cov-fail-under=70 --junitxml=/tmp/tests.xml
coverage xml -i
[testenv:flake8]