예제 #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["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
예제 #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["payload"] == pay
    assert summary["payload length"] == 3

    # test transid (note we cant test payload because it's randomly gen)
    assert summary["transaction id"] == b""
    assert len(summary["transaction 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

    # test meid
    assert rmr.rmr_get_meid(sbuf) == summary["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
예제 #3
0
def test_send_rcv_subid_bad_mtype():
    """
    test send and receive where subid is used for routing but nobody recieves 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"
예제 #4
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["message state"] != 10:  # 10 is retry
                break
            max_retries -= 1
            time.sleep(0.75)

        assert ms["message state"] == 0
        assert max_retries > 0
예제 #5
0
def rmr_rcvall_msgs_raw(mrc, pass_filter=[]):
    """
    Same as rmr_rcvall_msgs, but the raw sbuf is also returned.
    Useful, for example, if rts is to be used.

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

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

    Returns
    -------
    list of tuple:$
       List of tuples [(S, sbuf),...] where S is a message summary and sbuf is the raw message$
       the caller is responsible for calling rmr.rmr_free_msg(sbuf) for each sbuf afterwards to prevent memory leaks.
    """

    new_messages = []

    while True:
        mbuf = rmr.rmr_alloc_msg(mrc, 4096)  # allocate buffer to have something for a return status
        mbuf = rmr.rmr_torcv_msg(mrc, mbuf, 0)  # set the timeout to 0 so this doesn't block!!
        summary = rmr.message_summary(mbuf)
        if summary["message status"] != "RMR_OK":
            break

        if len(pass_filter) == 0 or mbuf.contents.mtype in pass_filter:  # no filter, or passes; capture it
            new_messages.append((summary, mbuf))
        else:
            rmr.rmr_free_msg(mbuf)

    return new_messages
예제 #6
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["transaction id"] == b"66666666666666666666666666666666"
예제 #7
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[
        "message state"] == 0  # if send fails don't attempt receive
    assert send_summary["message 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

    # 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["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
예제 #8
0
def test_send_mock(monkeypatch):
    """
    tests the send mock
    """
    monkeypatch.setattr("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 = {
        "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,
    }
    _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 = {
        "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,
    }
    _partial_dict_comparison(expected, rmr.message_summary(sbuf))
예제 #9
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)
    sbuf_rcv = rmr.rmr_torcv_msg(MRC_RCV, sbuf_rcv,
                                 50)  # should time out after 50ms
    summary = rmr.message_summary(sbuf_rcv)
    assert summary["message state"] == 12
    assert summary["message status"] == "RMR_ERR_TIMEOUT"
예제 #10
0
 def _assert_good_send(self, sbuf, pre_send_summary):
     """
     common helper function for _send_msg and _rts_msg
     """
     post_send_summary = rmr.message_summary(sbuf)
     if post_send_summary["message state"] == 0 and post_send_summary[
             "message status"] == "RMR_OK":
         return True
     mdc_logger.debug("Message NOT sent!")
     mdc_logger.debug(
         "Pre-send summary: {0}, Post-send summary: {1}".format(
             pre_send_summary, post_send_summary))
     return False
예제 #11
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["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
예제 #12
0
 def _rts_msg(self, pay, sbuf_rts, mtype):
     """
     sends a message using rts
     we do not call free here because we may rts many times; it is called after the rts loop
     """
     for _ in range(0, RETRY_TIMES):
         pre_send_summary = rmr.message_summary(sbuf_rts)
         sbuf_rts = rmr.rmr_rts_msg(self.mrc,
                                    sbuf_rts,
                                    payload=pay,
                                    mtype=mtype)
         if self._assert_good_send(sbuf_rts, pre_send_summary):
             break
     return sbuf_rts  # in some cases rts may return a new sbuf
예제 #13
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)["meid"] == b"\x01\x02"
    assert len(rmr.rmr_get_meid(sbuf)) == 2

    rmr.rmr_set_meid(sbuf, b"\x00" * 32)
    assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(
        sbuf)["meid"] == b""  # NULL bytes get truncated

    rmr.rmr_set_meid(sbuf, b"6" * 32)
    assert rmr.rmr_get_meid(sbuf) == rmr.message_summary(
        sbuf)["meid"] == b"6" * 32  # 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" + b"6" * 30)  # bytes in string out, 6s left over
    assert len(rmr.rmr_get_meid(sbuf)) == 32
예제 #14
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["message state"] == 0
        expected_pay = bytes(pay_fmt % i, "UTF-8")
        assert 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 second 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["message state"] == 0  # all should be OK
        assert ms["message 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
        rmr.rmr_free_msg(sbuf)
예제 #15
0
 def _send_msg(self, pay, mtype, subid):
     """
     sends a msg
     """
     for _ in range(0, RETRY_TIMES):
         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)
         sbuf = rmr.rmr_send_msg(self.mrc, sbuf)  # send
         if self._assert_good_send(sbuf, pre_send_summary):
             rmr.rmr_free_msg(sbuf)  # free
             break
예제 #16
0
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
예제 #17
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["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
예제 #18
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["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
예제 #19
0
def rmr_rcvall_msgs(mrc, pass_filter=[]):
    """
    Assemble an array of all messages which can be received without
    blocking.  Effectively draining 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 messages with any type being captured.

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

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

    Returns
    -------
        list of dict
        List of message summaries, one for each message captured.
    """

    new_messages = []
    mbuf = rmr.rmr_alloc_msg(mrc, 4096)  # allocate buffer to have something for a return status

    while True:
        mbuf = rmr.rmr_torcv_msg(mrc, mbuf, 0)  # set the timeout to 0 so this doesn't block!!

        summary = rmr.message_summary(mbuf)
        if summary["message 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
            new_messages.append(summary)

    rmr.rmr_free_msg(mbuf)  # must free message to avoid leak
    return new_messages
예제 #20
0
test_type = 1006001

while rmr.rmr_ready(mrc) == 0:
    time.sleep(1)
    print("not yet ready")

print("listening ON {}".format(PORT))

# loop
while True:

    # do query
    pay = {"policy_type_id": test_type}
    sbuf_send = rmr.rmr_alloc_msg(mrc, 4096, payload=json.dumps(pay).encode("utf-8"), gen_transaction_id=True, mtype=20012)
    sbuf_send = rmr.rmr_send_msg(mrc, sbuf_send)
    post_send_summary = rmr.message_summary(sbuf_send)

    if not (post_send_summary["message state"] == 0 and post_send_summary["message status"] == "RMR_OK"):
        print("was unable to send query to a1!")
        time.sleep(1)
    else:
        # query worked, wait 2 seconds, then receive everything we have
        time.sleep(1)
        print("reading messages")

        # this is a hacked up version of rmr_rcvall_msgs in the rmr package
        # we need the actual messages, not the summaries, to use rts
        sbuf_rcv = rmr.rmr_alloc_msg(mrc, 4096)  # allocate buffer to have something for a return status
        while True:
            sbuf_rcv = rmr.rmr_torcv_msg(mrc, sbuf_rcv, 0)  # set the timeout to 0 so this doesn't block!!
예제 #21
0
PORT = os.environ.get("TEST_RCV_PORT", "4560")
DELAY = int(os.environ.get("TEST_RCV_SEC_DELAY", 0))
HANDLER_ID = os.environ.get("HANDLER_ID", "test_receiver")

mrc = rmr.rmr_init(PORT.encode("utf-8"), rmr.RMR_MAX_RCV_BYTES,
                   rmr.RMRFL_MTCALL)

while rmr.rmr_ready(mrc) == 0:
    time.sleep(1)
    print("not yet ready")

print("listening ON {}".format(PORT))
while True:
    sbuf = rmr.rmr_alloc_msg(mrc, 10)
    sbuf = rmr.rmr_torcv_msg(mrc, sbuf, 1000)
    summary = rmr.message_summary(sbuf)
    if summary["message state"] == 12 and summary[
            "message status"] == "RMR_ERR_TIMEOUT":
        # print("Nothing received yet")
        time.sleep(1)
    else:
        print("Message received!: {}".format(summary))

        received_payload = json.loads(summary["payload"])

        op = received_payload["operation"]
        send_payload_status = "ERROR"
        if op == "CREATE":
            send_payload_status = "OK"
        elif op == "DELETE":
            send_payload_status = "DELETED"
예제 #22
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['message state'] == 12:
            print("Nothing received yet")
        else:
            print("Ack Message received!: {}".format(summary))

    time.sleep(1)
예제 #23
0
    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['message 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)