Exemplo n.º 1
0
def test_send_rcv_subid_good():
    """
    test send and receive where subid is used for routing
    """
    pay = b"\x01\x00\x80"
    test_mtype = 46656
    test_subid = 777

    # send a message
    sbuf_send = rmr.rmr_alloc_msg(MRC_SEND,
                                  3,
                                  pay,
                                  mtype=test_mtype,
                                  sub_id=test_subid)
    pre_send_summary = rmr.message_summary(sbuf_send)
    sbuf_send = rmr.rmr_send_msg(MRC_SEND, sbuf_send)
    send_summary = rmr.message_summary(sbuf_send)

    # receive it in other context
    time.sleep(0.5)
    sbuf_rcv = rmr.rmr_alloc_msg(MRC_RCV, 3)
    sbuf_rcv = rmr.rmr_torcv_msg(MRC_RCV, sbuf_rcv, 2000)
    rcv_summary = rmr.message_summary(sbuf_rcv)

    # asserts
    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
Exemplo n.º 2
0
def test_rmr_set_get():
    """
    test set functions
    """
    sbuf = rmr.rmr_alloc_msg(MRC_SEND, SIZE)
    _assert_new_sbuf(sbuf)

    # test payload
    pay = b"\x01\x00\x80"
    rmr.set_payload_and_length(pay, sbuf)
    summary = rmr.message_summary(sbuf)
    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[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[rmr.RMR_MS_TRN_ID] != b""
    assert len(summary[rmr.RMR_MS_TRN_ID]) == 32

    # test meid
    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[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)
Exemplo n.º 3
0
def test_meid():
    """
    test meid stringification
    """
    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)[
        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)[
        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)[
        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)[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

    # test that an exception is raised for buffers which are too long
    with pytest.raises(exceptions.MeidSizeOutOfRange):
        rmr.rmr_set_meid(sbuf, b"8" * 32)
Exemplo n.º 4
0
def test_wh():
    """test the ability to send a message directly, without routing, via a wormhole"""
    state = rmr.rmr_wh_state(MRC_SEND, 1)
    assert state != rmr.RMR_OK
    whid = rmr.rmr_wh_open(MRC_SEND, b"127.0.0.1:3563")
    assert whid >= 0
    state = rmr.rmr_wh_state(MRC_SEND, whid)
    assert state == rmr.RMR_OK

    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_summary = rmr.message_summary(sbuf_send)

    # send via call, but don't wait long for a response
    rmr.rmr_wh_call(MRC_SEND, whid, sbuf_send, 1, 100)

    # receive message in other context
    time.sleep(0.5)
    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)

    # asserts
    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_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)

    # receive message in other context
    time.sleep(0.5)
    sbuf_rcv = rmr.rmr_torcv_msg(MRC_RCV, sbuf_rcv, 2000)
    rcv_summary = rmr.message_summary(sbuf_rcv)

    # asserts
    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_TYPE] == rcv_summary[
        rmr.RMR_MS_MSG_TYPE] == mtype
    assert send_summary[rmr.RMR_MS_PAYLOAD] == rcv_summary[
        rmr.RMR_MS_PAYLOAD] == payload

    rmr.rmr_wh_close(MRC_SEND, whid)
Exemplo n.º 5
0
def test_send_rcv_subid_bad_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)[
        rmr.RMR_MS_MSG_STATE] == rmr.RMR_ERR_NOENDPT
    assert rmr.message_summary(sbuf_send)[
        rmr.RMR_MS_MSG_STATUS] == "RMR_ERR_NOENDPT"
Exemplo n.º 6
0
def send_burst(mrc, fmt, mtype=1, num=13, counter=0):
    """
        Internal function to support test_rcv_all.
        Send a burst of messages optionally giving the type, payload
        and number to send.
    """
    sbuf_send = rmr.rmr_alloc_msg(MRC_SEND, SIZE)  # seed message buffer

    for i in range(num):
        payload = bytes(fmt % counter, "UTF-8")
        counter += 1

        rmr.set_payload_and_length(payload, sbuf_send)
        sbuf_send.contents.mtype = mtype

        max_retries = 5
        while max_retries > 0:
            sbuf_send = rmr.rmr_send_msg(mrc, sbuf_send)
            ms = rmr.message_summary(sbuf_send)
            if ms[rmr.RMR_MS_MSG_STATE] != rmr.RMR_ERR_RETRY:
                break
            max_retries -= 1
            time.sleep(0.75)

        assert ms[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK
        assert max_retries > 0
Exemplo n.º 7
0
    def rmr_rts(self, sbuf, new_payload=None, new_mtype=None, retries=100):
        """
        Allows the xapp to return to sender, possibly adjusting the
        payload and message type before doing so.  This does NOT free
        the sbuf for the caller as the caller may wish to perform
        multiple rts per buffer. The client needs to free.

        Parameters
        ----------
        sbuf: ctypes c_void_p
             Pointer to an rmr message buffer
        new_payload: bytes (optional)
            New payload to set
        new_mtype: int (optional)
            New message type (replaces the received message)
        retries: int (optional, default 100)
            Number of times to retry at the application level

        Returns
        -------
        bool
            whether or not the send worked after retries attempts
        """
        for _ in range(retries):
            sbuf = rmr.rmr_rts_msg(self._mrc,
                                   sbuf,
                                   payload=new_payload,
                                   mtype=new_mtype)
            if sbuf.contents.state == 0:
                return True

        self.logger.warning("RTS Failed! Summary: {}".format(
            rmr.message_summary(sbuf)))
        return False
Exemplo n.º 8
0
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[rmr.RMR_MS_TRN_ID] == b"66666666666666666666666666666666"
Exemplo n.º 9
0
 def _assert_good_send(self, sbuf, pre_send_summary):
     """
     Extracts the send result and logs a detailed warning if the send failed.
     Returns the message state, an integer that indicates the result.
     """
     post_send_summary = rmr.message_summary(sbuf)
     if post_send_summary[rmr.RMR_MS_MSG_STATE] != rmr.RMR_OK:
         mdc_logger.warning("RMR send failed; pre-send summary: {0}, post-send summary: {1}".format(pre_send_summary, post_send_summary))
     return post_send_summary[rmr.RMR_MS_MSG_STATE]
Exemplo n.º 10
0
def test_send_rcv():
    """
    test send and receive
    """
    pay = b"\x01\x00\x80"

    # send a message
    sbuf_send = rmr.rmr_alloc_msg(MRC_SEND, SIZE)
    _assert_new_sbuf(sbuf_send)
    rmr.set_payload_and_length(pay, sbuf_send)
    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[
        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[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"
    sbuf_rcv = rmr.rmr_rts_msg(MRC_RCV, sbuf_rcv, payload=ack_pay, mtype=6666)
    rcv_ack_summary = rmr.message_summary(sbuf_rcv)

    # have the sender receive it
    sbuf_send = rmr.rmr_torcv_msg(MRC_SEND, sbuf_send, 2000)
    send_ack_summary = rmr.message_summary(sbuf_send)

    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_mock(monkeypatch):
    """
    tests the send mock
    """
    monkeypatch.setattr("ricxappframe.rmr.rmr.rmr_send_msg",
                        rmr_mocks.send_mock_generator(12))
    rmr_mocks.patch_rmr(monkeypatch)
    sbuf = rmr.rmr_alloc_msg(MRC, SIZE)
    rmr.set_payload_and_length("testttt".encode("utf8"), sbuf)

    expected = {
        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))

    # set the mtype
    sbuf.contents.mtype = 666

    # send it (the fake send sets the state, and touches nothing else)
    sbuf = rmr.rmr_send_msg(MRC, sbuf)

    expected = {
        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))
Exemplo n.º 12
0
def _assert_new_sbuf(sbuf):
    """
    verify the initial state of an alloced message is what we expect
    """
    summary = rmr.message_summary(sbuf)
    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
Exemplo n.º 13
0
def _receive_alarm_msg(action: AlarmAction):
    """
    delays briefly, receives a message, checks the message type and action
    """
    time.sleep(0.5)
    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[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK
    assert rcv_summary[rmr.RMR_MS_MSG_TYPE] == alarm.RIC_ALARM_UPDATE
    # parse JSON
    data = json.loads(rcv_summary[rmr.RMR_MS_PAYLOAD].decode())
    assert data[alarm.KEY_ALARM_ACTION] == action.name
Exemplo n.º 14
0
def rmr_rcvall_msgs(mrc, pass_filter=None, timeout=0):
    """
    Assembles an array of all messages which can be received without blocking
    (but see the timeout parameter).  Effectively drains the message queue if
    RMR is started in mt-call mode, or draining any waiting TCP buffers.  If
    the pass_filter parameter is supplied, it is treated as one or more
    message types to accept (pass through). Using the default, an empty list,
    results in capturing all messages. If the timeout parameter is supplied
    and is not zero, this call may block up to that number of milliseconds
    waiting for a message to arrive. Using the default, zero, results in
    non-blocking no-wait behavior.

    Parameters
    ----------
        mrc: ctypes c_void_p
            Pointer to the RMR context

        pass_filter: list (optional)
            The message type(s) to capture.

        timeout: int (optional)
            The number of milliseconds to wait for a message to arrive.

    Returns
    -------
        List of message summaries (dict), one for each message received; may be empty.
    """

    new_messages = []
    mbuf = rmr.rmr_alloc_msg(
        mrc, 4096)  # allocate and reuse a single buffer for RMR

    while True:
        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[
                rmr.
                RMR_MS_MSG_STATUS] != "RMR_OK":  # ok indicates msg received, stop on all other states
            break

        if pass_filter is None or 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
    return new_messages
Exemplo n.º 15
0
def test_rcv_timeout():
    """
    test torcv; this is a scary test because if it fails... it doesn't fail, it will run forever!
    We receive a message (though nothing has been sent) and make sure the function doesn't block forever.

    There is no unit test for rmr_rcv_msg; too dangerous, that is a blocking call that may never return.
    """
    sbuf_rcv = rmr.rmr_alloc_msg(MRC_RCV, SIZE)
    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[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
Exemplo n.º 16
0
def _receive_metric_rpt(rptr: str):
    """
    delays briefly, receives a message, checks the message type and reporter
    """
    time.sleep(0.5)
    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)
    mdc_logger.debug("Receive result is {}".format(
        rcv_summary[rmr.RMR_MS_MSG_STATE]))
    assert rcv_summary[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK
    assert rcv_summary[rmr.RMR_MS_MSG_TYPE] == metric.RIC_METRICS
    # parse JSON
    data = json.loads(rcv_summary[rmr.RMR_MS_PAYLOAD].decode())
    mdc_logger.debug("Received reporter {}".format(data[metric.KEY_REPORTER]))
    assert data[metric.KEY_REPORTER] == rptr
Exemplo n.º 17
0
def rmr_rcvall_msgs_raw(mrc, pass_filter=None, timeout=0):
    """
    Same as rmr_rcvall_msgs, but answers tuples with the raw sbuf.
    Useful if return-to-sender (rts) functions are required.

    Parameters
    ----------
        mrc: ctypes c_void_p
            Pointer to the RMR context

        pass_filter: list (optional)
            The message type(s) to capture.

        timeout: int (optional)
            The number of milliseconds to wait for a message to arrive.

    Returns
    -------
    list of tuple:
        List of tuples [(S, sbuf),...] where S is a message summary (dict), and sbuf is the raw message; may be empty.
        The caller MUST call rmr.rmr_free_msg(sbuf) when finished with each sbuf to prevent memory leaks!
    """

    new_messages = []

    while True:
        mbuf = rmr.rmr_alloc_msg(
            mrc, 4096)  # allocate a new buffer for every message
        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[rmr.RMR_MS_MSG_STATUS] != "RMR_OK":
            rmr.rmr_free_msg(mbuf)  # free the failed-to-receive buffer
            break

        if pass_filter is None or len(
                pass_filter
        ) == 0 or mbuf.contents.mtype in pass_filter:  # no filter, or passes; capture it
            new_messages.append(
                (summary,
                 mbuf))  # caller is responsible for freeing the buffer
        else:
            rmr.rmr_free_msg(mbuf)  # free the filtered-out message buffer

    return new_messages
Exemplo n.º 18
0
    def _rts_msg(self, pay, sbuf_rts, mtype):
        """
        Sends a message via RMR's return-to-sender feature.
        This neither allocates nor frees a message buffer because we may rts many times.
        Returns the message buffer from the RTS function, which may reallocate it.
        """
        pre_send_summary = rmr.message_summary(sbuf_rts)
        for _ in range(0, RETRY_TIMES):
            mdc_logger.debug("_rts_msg: sending: {}".format(pre_send_summary))
            sbuf_rts = rmr.rmr_rts_msg(self.mrc, sbuf_rts, payload=pay, mtype=mtype)
            msg_state = self._assert_good_send(sbuf_rts, pre_send_summary)
            mdc_logger.debug("_rts_msg: result message state: {}".format(msg_state))
            if msg_state != rmr.RMR_ERR_RETRY:
                break

        if msg_state != rmr.RMR_OK:
            mdc_logger.warning("_rts_msg: failed after {} retries".format(RETRY_TIMES))
        return sbuf_rts  # in some cases rts may return a new sbuf
Exemplo n.º 19
0
    def _send_msg(self, pay, mtype, subid):
        """
        Creates and sends a message via RMR's send-message feature with the specified payload
        using the specified message type and subscription ID.
        """
        sbuf = rmr.rmr_alloc_msg(self.mrc, len(pay), payload=pay, gen_transaction_id=True, mtype=mtype, sub_id=subid)
        sbuf.contents.sub_id = subid
        pre_send_summary = rmr.message_summary(sbuf)
        for _ in range(0, RETRY_TIMES):
            mdc_logger.debug("_send_msg: sending: {}".format(pre_send_summary))
            sbuf = rmr.rmr_send_msg(self.mrc, sbuf)
            msg_state = self._assert_good_send(sbuf, pre_send_summary)
            mdc_logger.debug("_send_msg: result message state: {}".format(msg_state))
            if msg_state != rmr.RMR_ERR_RETRY:
                break

        rmr.rmr_free_msg(sbuf)
        if msg_state != rmr.RMR_OK:
            mdc_logger.warning("_send_msg: failed after {} retries".format(RETRY_TIMES))
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[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
Exemplo n.º 21
0
    def send_report(self, msg: MetricsReport):
        """
        Serializes the MetricsReport dict to JSON and sends the result via RMR.
        Raises an exception if the report has no MetricsData items.

        Parameters
        ----------
        msg: MetricsReport (required)
            Dictionary with measurement data to encode and send

        Returns
        -------
        bool
            True if the send succeeded (possibly with retries), False otherwise
        """
        if KEY_DATA not in msg or len(msg[KEY_DATA]) == 0:
            raise EmptyReport
        payload = json.dumps(msg).encode()
        mdc_logger.debug("send_report: payload is {}".format(payload))
        sbuf = rmr.rmr_alloc_msg(vctx=self.vctx,
                                 size=len(payload),
                                 payload=payload,
                                 mtype=RIC_METRICS,
                                 gen_transaction_id=True)

        for _ in range(0, RETRIES):
            sbuf = rmr.rmr_send_msg(self.vctx, sbuf)
            post_send_summary = rmr.message_summary(sbuf)
            mdc_logger.debug("send_report: try {0} result is {1}".format(
                _, post_send_summary[rmr.RMR_MS_MSG_STATE]))
            # stop trying if RMR does not indicate retry
            if post_send_summary[rmr.RMR_MS_MSG_STATE] != rmr.RMR_ERR_RETRY:
                break

        rmr.rmr_free_msg(sbuf)
        if post_send_summary[rmr.RMR_MS_MSG_STATE] != rmr.RMR_OK:
            mdc_logger.warning(
                "send_report: failed after {} retries".format(RETRIES))
            return False

        return True
Exemplo n.º 22
0
def test_resize_payload():
    """test the ability to insert a larger payload into an existing message"""
    mtype = 99
    subid = 100

    mbuf = rmr.rmr_alloc_msg(MRC_SEND,
                             25)  # allocate buffer with small payload
    mbuf.contents.mtype = mtype  # type and sub-id should not change
    mbuf.contents.sub_id = subid

    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[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
Exemplo n.º 23
0
def test_alloc_fancy():
    """test allocation with setting payload, trans, mtype, subid"""
    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[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
Exemplo n.º 24
0
    def _rmr_send_alarm(self, msg: dict):
        """
        Serializes the dict and sends the result via RMR using a predefined message
        type to the wormhole initialized at start.

        Parameters
        ----------
        msg: dict
            Dictionary with alarm message to encode and send

        Returns
        -------
        bool
            True if the send succeeded (possibly with retries), False otherwise
        """
        payload = json.dumps(msg).encode()
        mdc_logger.debug("_rmr_send_alarm: payload is {}".format(payload))
        sbuf = rmr.rmr_alloc_msg(vctx=self.vctx,
                                 size=len(payload),
                                 payload=payload,
                                 mtype=RIC_ALARM_UPDATE,
                                 gen_transaction_id=True)

        for _ in range(0, RETRIES):
            sbuf = rmr.rmr_wh_send_msg(self.vctx, self._wormhole_id, sbuf)
            post_send_summary = rmr.message_summary(sbuf)
            mdc_logger.debug("_rmr_send_alarm: try {0} result is {1}".format(
                _, post_send_summary[rmr.RMR_MS_MSG_STATE]))
            # stop trying if RMR does not indicate retry
            if post_send_summary[rmr.RMR_MS_MSG_STATE] != rmr.RMR_ERR_RETRY:
                break

        rmr.rmr_free_msg(sbuf)
        if post_send_summary[rmr.RMR_MS_MSG_STATE] != rmr.RMR_OK:
            mdc_logger.warning(
                "_rmr_send_alarm: failed after {} retries".format(RETRIES))
            return False

        return True
Exemplo n.º 25
0
def signal_handler(sig, frame):
    print("SIGINT received! Cleaning up RMR")
    rmr.rmr_close(mrc)
    print("Byeee")
    sys.exit(0)


# init rmr
mrc = rmr.rmr_init("4560".encode("utf-8"), rmr.RMR_MAX_RCV_BYTES, 0x00)
while rmr.rmr_ready(mrc) == 0:
    time.sleep(1)
    print("not yet ready")
rmr.rmr_set_stimeout(mrc, 2)

# capture ctrl-c
signal.signal(signal.SIGINT, signal_handler)

sbuf = None
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[rmr.RMR_MS_MSG_STATE] == 12:
        print("Nothing received =(")
    else:
        print("Message received!: {}".format(summary))
        val = b"message recieved OK yall!"
        rmr.set_payload_and_length(val, sbuf)
        sbuf = rmr.rmr_rts_msg(mrc, sbuf)
    time.sleep(1)
Exemplo n.º 26
0
sbuf = rmr.rmr_alloc_msg(mrc, 256)

# capture ctrl-c
signal.signal(signal.SIGINT, signal_handler)

while True:
    # generate a random value between 1 and 256 bytes, then gen some random  bytes with several nulls thrown in
    for val in [
            "".join([
                random.choice(string.ascii_letters + string.digits)
                for n in range(random.randint(1, 256))
            ]).encode("utf8"),
            b"\x00" + os.urandom(4) + b"\x00" + os.urandom(4) + b"\x00",
    ]:
        rmr.set_payload_and_length(val, sbuf)
        rmr.generate_and_set_transaction_id(sbuf)
        sbuf.contents.state = 0
        sbuf.contents.mtype = 0
        print("Pre send summary: {}".format(rmr.message_summary(sbuf)))
        sbuf = rmr.rmr_send_msg(mrc, sbuf)
        print("Post send summary: {}".format(rmr.message_summary(sbuf)))
        print("Waiting for return, will timeout after 2000ms")
        sbuf = rmr.rmr_torcv_msg(mrc, sbuf, 2000)
        summary = rmr.message_summary(sbuf)
        if summary[rmr.RMR_MS_MSG_STATE] == 12:
            print("Nothing received yet")
        else:
            print("Ack Message received!: {}".format(summary))

    time.sleep(1)
Exemplo n.º 27
0
def test_rcv_all():
    """
    test the ability to receive a batch of queued messages.
    """
    pay_fmt = "send to ring msg: %d"  # dynamic message format with counter

    send_burst(MRC_SEND,
               pay_fmt)  # send a bunch of 13 messages that should queue
    time.sleep(1)  # ensure underlying transport gets cycles to send/receive

    bundle = helpers.rmr_rcvall_msgs(
        MRC_BUF_RCV
    )  # use the buffered receiver to read all with a single call
    assert len(bundle) == 13

    for i, ms in enumerate(bundle):
        ms = bundle[
            i]  # validate each summary returned, and ordering preserved
        assert ms[rmr.RMR_MS_MSG_STATE] == rmr.RMR_OK
        expected_pay = bytes(pay_fmt % i, "UTF-8")
        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)
    send_burst(MRC_SEND, pay_fmt, mtype=1, num=5)
    send_burst(MRC_SEND, pay_fmt, mtype=2, num=4,
               counter=8)  # total of 12 messages with type 2 should be queued
    time.sleep(1)  # ensure underlying transport gets cycles to send/receive

    bundle = helpers.rmr_rcvall_msgs_raw(
        MRC_BUF_RCV, [2])  # receive only message type 2 messages
    assert len(
        bundle) == 12  # we should only get the type 2 batch of 12 messages

    for i, (ms, sbuf) in enumerate(bundle):  # test the raw version
        test_summary = rmr.message_summary(sbuf)
        assert test_summary == ms
        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[rmr.RMR_MS_PAYLOAD] == expected_pay
        rmr.rmr_free_msg(sbuf)

    # check the timeout scenarios
    start_rcv_sec = time.time()
    bundle = helpers.rmr_rcvall_msgs(
        MRC_RCV, timeout=1001)  # non-zero timeout means wait
    assert len(bundle) == 0  # we should get none
    assert (time.time() - start_rcv_sec > 1
            )  # test duration should be longer than 1 second

    start_rcv_sec = time.time()
    bundle = helpers.rmr_rcvall_msgs_raw(
        MRC_RCV, timeout=1002)  # non-zero timeout means wait
    assert len(bundle) == 0  # we should get none
    assert (time.time() - start_rcv_sec > 1
            )  # test duration should be longer than 1 second