Skip to content

Commit

Permalink
prov/efa: Add unit tests for efa_msg
Browse files Browse the repository at this point in the history
Use FI_EP_RDM as ep type and override efa_msg_ops.

Signed-off-by: Jessie Yang <jiaxiyan@amazon.com>
  • Loading branch information
jiaxiyan authored and shijin-aws committed Dec 13, 2024
1 parent c312085 commit de520c2
Show file tree
Hide file tree
Showing 6 changed files with 304 additions and 1 deletion.
3 changes: 2 additions & 1 deletion prov/efa/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ nodist_prov_efa_test_efa_unit_test_SOURCES = \
prov/efa/test/efa_unit_test_runt.c \
prov/efa/test/efa_unit_test_mr.c \
prov/efa/test/efa_unit_test_rdm_peer.c \
prov/efa/test/efa_unit_test_pke.c
prov/efa/test/efa_unit_test_pke.c \
prov/efa/test/efa_unit_test_msg.c


efa_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/prov/efa/test $(cmocka_CPPFLAGS)
Expand Down
12 changes: 12 additions & 0 deletions prov/efa/test/efa_unit_test_mocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ void efa_mock_ibv_wr_send_verify_handshake_pkt_local_host_id_and_save_wr(struct
return efa_mock_ibv_wr_send_save_wr(qp);
}

void efa_mock_ibv_wr_send_imm_save_wr(struct ibv_qp_ex *qp, __be32 imm_data)
{
g_ibv_submitted_wr_id_vec[g_ibv_submitted_wr_id_cnt] = (void *)qp->wr_id;
g_ibv_submitted_wr_id_cnt++;
}

void efa_mock_ibv_wr_set_inline_data_list_no_op(struct ibv_qp_ex *qp,
size_t num_buf,
const struct ibv_data_buf *buf_list)
Expand Down Expand Up @@ -207,6 +213,12 @@ bool efa_mock_efa_device_support_unsolicited_write_recv()
return mock();
}

int efa_mock_ibv_post_recv(struct ibv_qp *qp, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr)
{
return mock();
}

struct efa_unit_test_mocks g_efa_unit_test_mocks = {
.local_host_id = 0,
.peer_host_id = 0,
Expand Down
5 changes: 5 additions & 0 deletions prov/efa/test/efa_unit_test_mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ uint32_t efa_mock_ibv_read_wc_flags_return_mock(struct ibv_cq_ex *current);

bool efa_mock_efadv_wc_is_unsolicited(struct efadv_cq *efadv_cq);

void efa_mock_ibv_wr_send_imm_save_wr(struct ibv_qp_ex *qp, __be32 imm_data);

ssize_t __real_ofi_copy_from_hmem_iov(void *dest, size_t size,
enum fi_hmem_iface hmem_iface, uint64_t device,
const struct iovec *hmem_iov,
Expand All @@ -93,6 +95,9 @@ int efa_mock_efa_rdm_pke_read_return_mock(struct efa_rdm_ope *ope);

bool efa_mock_efa_device_support_unsolicited_write_recv(void);

int efa_mock_ibv_post_recv(struct ibv_qp *qp, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr);

struct efa_unit_test_mocks
{
uint64_t local_host_id;
Expand Down
267 changes: 267 additions & 0 deletions prov/efa/test/efa_unit_test_msg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
/* SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0-only */
/* SPDX-FileCopyrightText: Copyright Amazon.com, Inc. or its affiliates. All
* rights reserved. */

#include "efa_unit_tests.h"
#include "ofi_util.h"

extern struct fi_ops_msg efa_msg_ops;

static void test_efa_msg_recv_prep(struct efa_resource *resource,
fi_addr_t *addr)
{
struct ibv_qp *ibv_qp;
struct efa_ep_addr raw_addr;
struct efa_base_ep *base_ep;
size_t raw_addr_len = sizeof(raw_addr);
int ret;

efa_unit_test_resource_construct(resource, FI_EP_RDM);
resource->ep->msg = &efa_msg_ops;

base_ep = container_of(resource->ep, struct efa_base_ep, util_ep.ep_fid);
ibv_qp = base_ep->qp->ibv_qp;
ibv_qp->context->ops.post_recv = &efa_mock_ibv_post_recv;
will_return(efa_mock_ibv_post_recv, 0);

ret = fi_getname(&resource->ep->fid, &raw_addr, &raw_addr_len);
assert_int_equal(ret, 0);
raw_addr.qpn = 1;
raw_addr.qkey = 0x1234;
ret = fi_av_insert(resource->av, &raw_addr, 1, addr, 0 /* flags */,
NULL /* context */);
assert_int_equal(ret, 1);
}

void test_efa_msg_fi_recv(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
int ret;
void *desc;

test_efa_msg_recv_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 4096 /* buff_size */);

desc = fi_mr_desc(send_buff.mr);

ret = fi_recv(resource->ep, send_buff.buff, send_buff.size, desc, addr,
NULL /* context */);
assert_int_equal(ret, 0);

efa_unit_test_buff_destruct(&send_buff);
}

void test_efa_msg_fi_recvv(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
struct iovec iov;
fi_addr_t addr;
int ret;
void *desc;

test_efa_msg_recv_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 4096 /* buff_size */);

iov.iov_base = send_buff.buff;
iov.iov_len = send_buff.size;
desc = fi_mr_desc(send_buff.mr);

ret = fi_recvv(resource->ep, &iov, &desc, 1, addr, NULL /* context */);
assert_int_equal(ret, 0);

efa_unit_test_buff_destruct(&send_buff);
}

void test_efa_msg_fi_recvmsg(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
int ret;
void *desc;
struct iovec iov;
struct fi_msg msg = {0};

test_efa_msg_recv_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 4096 /* buff_size */);

iov.iov_base = send_buff.buff;
iov.iov_len = send_buff.size;
desc = fi_mr_desc(send_buff.mr);
efa_unit_test_construct_msg(&msg, &iov, 1, addr, NULL, 0, &desc);

ret = fi_recvmsg(resource->ep, &msg, 0);
assert_int_equal(ret, 0);

efa_unit_test_buff_destruct(&send_buff);
}

static void test_efa_msg_send_prep(struct efa_resource *resource,
fi_addr_t *addr)
{
struct ibv_qp_ex *ibv_qpx;
struct efa_ep_addr raw_addr;
struct efa_base_ep *base_ep;
size_t raw_addr_len = sizeof(raw_addr);
int ret;

efa_unit_test_resource_construct(resource, FI_EP_RDM);
resource->ep->msg = &efa_msg_ops;

base_ep = container_of(resource->ep, struct efa_base_ep, util_ep.ep_fid);
ibv_qpx = base_ep->qp->ibv_qp_ex;

ret = fi_getname(&resource->ep->fid, &raw_addr, &raw_addr_len);
assert_int_equal(ret, 0);
raw_addr.qpn = 1;
raw_addr.qkey = 0x1234;
ret = fi_av_insert(resource->av, &raw_addr, 1, addr, 0 /* flags */,
NULL /* context */);
assert_int_equal(ret, 1);

ibv_qpx->wr_start = &efa_mock_ibv_wr_start_no_op;
/* this mock will save the send work request (wr) in a global list */
ibv_qpx->wr_send = &efa_mock_ibv_wr_send_save_wr;
ibv_qpx->wr_send_imm = &efa_mock_ibv_wr_send_imm_save_wr;
ibv_qpx->wr_set_inline_data_list = &efa_mock_ibv_wr_set_inline_data_list_no_op;
ibv_qpx->wr_set_sge_list = &efa_mock_ibv_wr_set_sge_list_no_op;
ibv_qpx->wr_set_ud_addr = &efa_mock_ibv_wr_set_ud_addr_no_op;
ibv_qpx->wr_complete = &efa_mock_ibv_wr_complete_no_op;
}

void test_efa_msg_fi_send(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
void *desc;
int ret;

test_efa_msg_send_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 4096 /* buff_size */);

desc = fi_mr_desc(send_buff.mr);

assert_int_equal(g_ibv_submitted_wr_id_cnt, 0);
ret = fi_send(resource->ep, send_buff.buff, send_buff.size, desc, addr,
NULL /* context */);
assert_int_equal(ret, 0);
assert_int_equal(g_ibv_submitted_wr_id_cnt, 1);

efa_unit_test_buff_destruct(&send_buff);
}

void test_efa_msg_fi_sendv(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
struct iovec iov;
void *desc;
int ret;

test_efa_msg_send_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 4096 /* buff_size */);

iov.iov_base = send_buff.buff;
iov.iov_len = send_buff.size;
desc = fi_mr_desc(send_buff.mr);

assert_int_equal(g_ibv_submitted_wr_id_cnt, 0);
ret = fi_sendv(resource->ep, &iov, &desc, 1, addr, NULL);
assert_int_equal(ret, 0);
assert_int_equal(g_ibv_submitted_wr_id_cnt, 1);

efa_unit_test_buff_destruct(&send_buff);
}

void test_efa_msg_fi_sendmsg(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
struct iovec iov;
void *desc;
int ret;
struct fi_msg msg = {0};

test_efa_msg_send_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 4096 /* buff_size */);

iov.iov_base = send_buff.buff;
iov.iov_len = send_buff.size;
desc = fi_mr_desc(send_buff.mr);

efa_unit_test_construct_msg(&msg, &iov, 1, addr, NULL, 0, &desc);

assert_int_equal(g_ibv_submitted_wr_id_cnt, 0);
ret = fi_sendmsg(resource->ep, &msg, 0);
assert_int_equal(ret, 0);
assert_int_equal(g_ibv_submitted_wr_id_cnt, 1);

efa_unit_test_buff_destruct(&send_buff);
}

void test_efa_msg_fi_senddata(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
void *desc;
int ret;
uint64_t data = 0x1234567890ABCDEF;

test_efa_msg_send_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 4096 /* buff_size */);

desc = fi_mr_desc(send_buff.mr);

assert_int_equal(g_ibv_submitted_wr_id_cnt, 0);
ret = fi_senddata(resource->ep, send_buff.buff, send_buff.size, desc,
data, addr, NULL);
assert_int_equal(ret, 0);
assert_int_equal(g_ibv_submitted_wr_id_cnt, 1);

efa_unit_test_buff_destruct(&send_buff);
}

void test_efa_msg_fi_inject(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
int ret;

test_efa_msg_send_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 32);

assert_int_equal(g_ibv_submitted_wr_id_cnt, 0);
ret = fi_inject(resource->ep, send_buff.buff, send_buff.size, addr);
assert_int_equal(ret, 0);
assert_int_equal(g_ibv_submitted_wr_id_cnt, 1);

efa_unit_test_buff_destruct(&send_buff);
}

void test_efa_msg_fi_injectdata(struct efa_resource **state)
{
struct efa_resource *resource = *state;
struct efa_unit_test_buff send_buff;
fi_addr_t addr;
int ret;
uint64_t data = 0x1234567890ABCDEF;

test_efa_msg_send_prep(resource, &addr);
efa_unit_test_buff_construct(&send_buff, resource, 32);

assert_int_equal(g_ibv_submitted_wr_id_cnt, 0);
ret = fi_injectdata(resource->ep, send_buff.buff, send_buff.size, data,
addr);
assert_int_equal(ret, 0);
assert_int_equal(g_ibv_submitted_wr_id_cnt, 1);

efa_unit_test_buff_destruct(&send_buff);
}
9 changes: 9 additions & 0 deletions prov/efa/test/efa_unit_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ int main(void)
cmocka_unit_test_setup_teardown(test_efa_rdm_peer_keep_pke_in_overflow_list, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_peer_append_overflow_pke_to_recvwin, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_rdm_pke_handle_longcts_rtm_send_completion, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_recv, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_recvv, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_recvmsg, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_send, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_sendv, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_sendmsg, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_senddata, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_inject, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
cmocka_unit_test_setup_teardown(test_efa_msg_fi_injectdata, efa_unit_test_mocks_setup, efa_unit_test_mocks_teardown),
};

cmocka_set_message_output(CM_OUTPUT_XML);
Expand Down
9 changes: 9 additions & 0 deletions prov/efa/test/efa_unit_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ void test_efa_rdm_peer_move_overflow_pke_to_recvwin();
void test_efa_rdm_peer_keep_pke_in_overflow_list();
void test_efa_rdm_peer_append_overflow_pke_to_recvwin();
void test_efa_rdm_pke_handle_longcts_rtm_send_completion();
void test_efa_msg_fi_recv();
void test_efa_msg_fi_recvv();
void test_efa_msg_fi_recvmsg();
void test_efa_msg_fi_send();
void test_efa_msg_fi_sendv();
void test_efa_msg_fi_sendmsg();
void test_efa_msg_fi_senddata();
void test_efa_msg_fi_inject();
void test_efa_msg_fi_injectdata();

static inline
int efa_unit_test_get_dlist_length(struct dlist_entry *head)
Expand Down

0 comments on commit de520c2

Please sign in to comment.