Пример #1
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)
def test_rcv_mock(monkeypatch):
    """
    tests the rmr recieve mocking generator
    """
    rmr_mocks.patch_rmr(monkeypatch)
    sbuf = rmr.rmr_alloc_msg(MRC, SIZE)

    # test rcv
    monkeypatch.setattr(
        "ricxappframe.rmr.rmr.rmr_rcv_msg",
        rmr_mocks.rcv_mock_generator({"foo": "bar"}, 666, 0, True))
    sbuf = rmr.rmr_rcv_msg(MRC, sbuf)
    assert rmr.get_payload(sbuf) == b'{"foo": "bar"}'
    assert sbuf.contents.mtype == 666
    assert sbuf.contents.state == rmr.RMR_OK
    assert sbuf.contents.len == 14

    # test torcv, although the timeout portion is not currently mocked or tested
    monkeypatch.setattr(
        "ricxappframe.rmr.rmr.rmr_torcv_msg",
        rmr_mocks.rcv_mock_generator({"foo": "bar"}, 666, 0, True, 50))
    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 == rmr.RMR_OK
    assert sbuf.contents.len == 14
Пример #3
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
Пример #4
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
Пример #5
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
Пример #6
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
Пример #7
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
Пример #8
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
Пример #9
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
Пример #10
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)