Commit 58d2c00a authored by Federico Vaga's avatar Federico Vaga

tst:hmq:sync: check multiprocess access

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent eb9a3048
......@@ -15,6 +15,7 @@ TRTL_CONFIG_ROM_MAX_CPU = 8
TRTL_CONFIG_ROM_MAX_HMQ = 8
TRTL_CONFIG_ROM_MAX_RMQ = 8
ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT = 83638
class TrtlConfigMq(Structure):
"""
......@@ -578,6 +579,7 @@ class TrtlHmq(object):
:rtype: TrtlMessage
:raises OSError: from C library errors
"""
set_errno(0)
msg_r = TrtlMessage()
self.libtrtl.trtl_msg_sync(self.trtl_dev.tkn,
self.idx_cpu, self.idx_hmq,
......
......@@ -13,7 +13,8 @@ from .PyMockTurtle import TrtlHmqHeader, TrtlMessage, TrtlConfig, \
TrtlFirmwareVariable, \
TRTL_CONFIG_ROM_MAX_CPU, \
TRTL_CONFIG_ROM_MAX_HMQ, \
TRTL_CONFIG_ROM_MAX_RMQ
TRTL_CONFIG_ROM_MAX_RMQ, \
ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT
__all__ = (
"TrtlDevice",
......@@ -29,4 +30,5 @@ __all__ = (
"TRTL_CONFIG_ROM_MAX_CPU",
"TRTL_CONFIG_ROM_MAX_HMQ",
"TRTL_CONFIG_ROM_MAX_RMQ",
"ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT",
)
......@@ -7,6 +7,7 @@ DIRS += config_rom
DIRS += sim-verif
DIRS += hmq-async-recv
DIRS += hmq-async-send
DIRS += hmq-sync
DIRS += hmq-purge
DIRS += rmq-udp-send
DIRS += rt-frm
......
mainmenu "hmq_async_send test configuration"
comment "Project specific configuration"
config FPGA_APPLICATION_ID
int "FPGA application ID"
default 0
help
Help text
config RT_APPLICATION_ID
int "RT application ID"
default 0
help
Help text
# include Mock Turtle's Kconfig
source "Kconfig.mt"
TRTL ?= ../../../
TRTL_FW = $(TRTL)/software/firmware
all clean:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = hmq-sync.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-sync
#
# Automatically generated file; DO NOT EDIT.
# hmq_async_send test configuration
#
#
# Project specific configuration
#
CONFIG_FPGA_APPLICATION_ID=0
CONFIG_RT_APPLICATION_ID=0
#
# Mock Turtle configuration
#
CONFIG_CFLAGS_OPT="-O0"
CONFIG_CFLAGS_EXTRA="-ggdb"
# CONFIG_MOCKTURTLE_SIMULATION is not set
#
# Mock Turtle framework configuration
#
# CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE is not set
CONFIG_MOCKTURTLE_FRAMEWORK_ACTION_ENABLE=y
# CONFIG_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE is not set
# CONFIG_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE is not set
CONFIG_MOCKTURTLE_FRAMEWORK_PING_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_VERSION_ENABLE=y
#
# Mock Turtle library configuration
#
CONFIG_MOCKTURTLE_LIBRARY_PRINT_ENABLE=y
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE is not set
CONFIG_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE=y
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_MESSAGE_ENABLE is not set
#include <mockturtle-rt.h>
int main()
{
int cpu, hmq;
const struct trtl_config_rom *cfgrom = trtl_config_rom_get();
struct trtl_fw_msg msg, msg_s;
struct payload *p;
uint32_t status;
pr_debug("TEST for: async send, sync\r\n");
cpu = trtl_get_core_id();
while (1) {
for (hmq = 0; hmq < cfgrom->n_hmq[cpu]; ++hmq) {
mq_map_in_message(TRTL_HMQ, hmq, &msg);
mq_map_out_message(TRTL_HMQ, hmq, &msg_s);
status = mq_poll_in_wait(TRTL_HMQ, 1 << hmq, 1);
if (!status)
continue;
if (!(msg.header->flags & TRTL_HMQ_HEADER_FLAG_SYNC))
continue;
/* For sync answer test */
pr_debug("SEND MESSAGES SYNC ANSWER\r\n");
mq_claim(TRTL_HMQ, hmq);
memcpy(msg_s.header, msg.header,
sizeof(struct trtl_hmq_header));
msg_s.header->flags &= ~TRTL_HMQ_HEADER_FLAG_SYNC;
msg_s.header->flags |= TRTL_HMQ_HEADER_FLAG_ACK;
memcpy(msg_s.payload, msg.payload, msg.header->len * 4);
mq_send(TRTL_HMQ, hmq);
mq_discard(TRTL_HMQ, hmq);
}
}
pp_printf("OK\r\n");
return 0;
}
......@@ -3,6 +3,8 @@ import PyMockTurtle
import pytest
import serial
import time
import multiprocessing
import errno
@pytest.fixture
def trtl_binary_hmq_purge(trtl_firmware_dir):
......@@ -25,6 +27,25 @@ def trtl_binary_hmq_sync(trtl_firmware_dir):
"firmware/hmq-sync/fw-hmq-sync.bin")
def do_sync_mult(q, hmq_orig, msg):
try:
dev = PyMockTurtle.TrtlDevice(hmq_orig.trtl_dev.device_id)
hmq = dev.cpu[hmq_orig.idx_cpu].hmq[hmq_orig.idx_hmq]
q.put(hmq.sync_msg(msg))
except Exception as e:
print(e)
q.put(None)
def do_sync_no_multone(q, hmq):
try:
msg_r = hmq.sync_msg(PyMockTurtle.TrtlMessage())
q.put(0)
except OSError as err:
q.put(err.errno)
except Exception as e:
print(e)
q.put(None)
class TestHmq(object):
confirm = 'OK\r\n'
......@@ -113,6 +134,86 @@ class TestHmq(object):
sa = hmq.get_stats()
assert sb[hmq]["message_received"] + tot == sa["message_received"]
def __do_sync_msg(self, hmq, trtl_msg):
msg_r_a = []
# I do not understand why I can't make Pool() working.
# it complains about hmq
# with multiprocessing.Pool(processes=len(trtl_msg)) as p:
# msg_r_a = p.starmap(do_sync_msg,
# [(hmq, msg) for msg in trtl_msg])
proc = []
for msg in trtl_msg:
q = multiprocessing.Queue()
proc.append((q, multiprocessing.Process(target=do_sync_msg,
args=(q, hmq, msg))))
for q, p in proc:
p.start()
for q, p in proc:
msg_r_a.append(q.get())
p.join()
return msg_r_a
@pytest.mark.parametrize("nproc", range(1, 5))
def test_sync_no_multone(self, trtl_cpu, nproc):
"""The driver should not accept more than 1 sync message at time
from the same user. The test is successful when the driver refused
a second message"""
trtl_cpu.disable();
for hmq in trtl_cpu.hmq:
proc = []
for n in range(nproc):
q = multiprocessing.Queue()
p = multiprocessing.Process(target=do_sync_no_multone,
args=(q, hmq))
proc.append((q, p))
p.start()
count_busy = 0
count_timeout = 0
for q, p in proc:
err = q.get()
p.join()
assert err != 0
if err == errno.EBUSY:
count_busy = count_busy + 1
if err == PyMockTurtle.ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT:
count_timeout = count_timeout + 1
assert count_timeout == 1
assert count_busy == nproc - 1
assert count_timeout + count_busy == nproc
def test_sync_mult(self, trtl_cpu, trtl_msg, trtl_binary_hmq_sync):
"""Test Multiprocess sync messages. The firmware will copy back
the message as answer"""
trtl_cpu.load_application_file(trtl_binary_hmq_sync)
trtl_cpu.enable()
for hmq in trtl_cpu.hmq:
proc = []
sb = hmq.get_stats()
for msg in trtl_msg:
q = multiprocessing.Queue()
p = multiprocessing.Process(target=do_sync_mult,
args=(q, hmq, msg))
proc.append((q, p, msg))
p.start()
for q, p, msg in proc:
msg_r = q.get()
p.join()
assert msg_r is not None
assert msg_r.header.rt_app_id == msg.header.rt_app_id
assert msg_r.header.msg_id == msg.header.msg_id
assert msg_r.header.len == msg.header.len
assert msg_r.header.flags == PyMockTurtle.TrtlHmqHeader.TRTL_HMQ_HEADER_FLAG_ACK
for v1, v2 in zip(msg.payload, msg_r.payload):
assert v1 == v2
sa = hmq.get_stats()
assert sb["message_sent"] + len(trtl_msg) == sa["message_sent"]
assert sb["message_received"] + len(trtl_msg) == sa["message_received"]
def test_sync(self, trtl_cpu, trtl_msg, trtl_binary_hmq_async_send):
"""It sends the test messages on all available HMQ.
The test is successful when what we read back is the same we sent
......@@ -131,8 +232,6 @@ class TestHmq(object):
assert msg_r.header.rt_app_id == msg.header.rt_app_id
assert msg_r.header.msg_id == msg.header.msg_id
assert msg_r.header.len == msg.header.len
assert msg_r.header.sync_id == msg.header.sync_id
assert msg.header.flags == PyMockTurtle.TrtlHmqHeader.TRTL_HMQ_HEADER_FLAG_SYNC
assert msg_r.header.flags == PyMockTurtle.TrtlHmqHeader.TRTL_HMQ_HEADER_FLAG_ACK
for v1, v2 in zip(msg.payload, msg_r.payload):
assert v1 == v2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment