From a152c68e17b6ad1ae48a126e0b80c05cb44188b8 Mon Sep 17 00:00:00 2001 From: Daniel Mrzyglod Date: Sat, 6 Aug 2016 20:38:27 +0100 Subject: tldk_test: Add TLDK unit tests Unit tests for TLDK libtle_udp & libtle_dring libraries Change-Id: I6818c72ca0260f1af784e758bfe21118c395afcf Signed-off-by: Karol Latecki Signed-off-by: Daniel Mrzyglod --- test/Makefile | 1 + test/gtest/Makefile | 115 ++++++++++ test/gtest/README | 41 ++++ test/gtest/main.cpp | 35 +++ test/gtest/test_tle_dring.cpp | 63 ++++++ test/gtest/test_tle_dring.h | 426 ++++++++++++++++++++++++++++++++++++ test/gtest/test_tle_udp_ctx.cpp | 42 ++++ test/gtest/test_tle_udp_ctx.h | 23 ++ test/gtest/test_tle_udp_destroy.cpp | 29 +++ test/gtest/test_tle_udp_destroy.h | 47 ++++ test/gtest/test_tle_udp_dev.cpp | 92 ++++++++ test/gtest/test_tle_udp_dev.h | 63 ++++++ test/gtest/test_tle_udp_event.cpp | 194 ++++++++++++++++ test/gtest/test_tle_udp_event.h | 110 ++++++++++ test/gtest/test_tle_udp_stream.cpp | 134 ++++++++++++ test/gtest/test_tle_udp_stream.h | 136 ++++++++++++ 16 files changed, 1551 insertions(+) create mode 100644 test/gtest/Makefile create mode 100644 test/gtest/README create mode 100644 test/gtest/main.cpp create mode 100644 test/gtest/test_tle_dring.cpp create mode 100644 test/gtest/test_tle_dring.h create mode 100644 test/gtest/test_tle_udp_ctx.cpp create mode 100644 test/gtest/test_tle_udp_ctx.h create mode 100644 test/gtest/test_tle_udp_destroy.cpp create mode 100644 test/gtest/test_tle_udp_destroy.h create mode 100644 test/gtest/test_tle_udp_dev.cpp create mode 100644 test/gtest/test_tle_udp_dev.h create mode 100644 test/gtest/test_tle_udp_event.cpp create mode 100644 test/gtest/test_tle_udp_event.h create mode 100644 test/gtest/test_tle_udp_stream.cpp create mode 100644 test/gtest/test_tle_udp_stream.h (limited to 'test') diff --git a/test/Makefile b/test/Makefile index fb446b4..665396f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -22,5 +22,6 @@ endif include $(RTE_SDK)/mk/rte.vars.mk DIRS-y += dring +DIRS-y += gtest include $(TLDK_ROOT)/mk/tle.subdir.mk diff --git a/test/gtest/Makefile b/test/gtest/Makefile new file mode 100644 index 0000000..5f47cc4 --- /dev/null +++ b/test/gtest/Makefile @@ -0,0 +1,115 @@ +# Copyright (c) 2016 Intel Corporation. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(RTE_SDK),) +$(error "Please define RTE_SDK environment variable") +endif + +ifeq ($(GTEST_DIR),) +all: + @echo "GTEST_DIR is not setup properly. Skipping gtest" + +%:: + @echo "GTEST_DIR is not setup properly. Skipping gtest" + +else + +# Default target, can be overridden by command line or environment +RTE_TARGET ?= x86_64-native-linuxapp-gcc + +include $(RTE_SDK)/mk/rte.vars.mk + +CUR_SUBDIR ?= . + +# we must create the output dir first and recall the same Makefile +# from this directory +ifeq ($(NOT_FIRST_CALL),) + +NOT_FIRST_CALL = 1 +export NOT_FIRST_CALL + + +BDIR := $(RTE_OUTPUT)/build/$(CUR_SUBDIR) + +all: + $(Q)mkdir -p $(BDIR) + $(Q)$(MAKE) -C $(BDIR) -f $(RTE_EXTMK) \ + S=$(RTE_SRCDIR) O=$(RTE_OUTPUT) SRCDIR=$(RTE_SRCDIR) X=obj + $(Q)$(MAKE) -C $(BDIR) -f $(RTE_EXTMK) \ + S=$(RTE_SRCDIR) O=$(RTE_OUTPUT) SRCDIR=$(RTE_SRCDIR) X=app + +%:: + $(Q)mkdir -p $(BDIR) + $(Q)$(MAKE) -C $(BDIR) -f $(RTE_EXTMK) $@ \ + S=$(RTE_SRCDIR) O=$(RTE_OUTPUT) SRCDIR=$(RTE_SRCDIR) X=obj + $(Q)$(MAKE) -C $(BDIR) -f $(RTE_EXTMK) $@ \ + S=$(RTE_SRCDIR) O=$(RTE_OUTPUT) SRCDIR=$(RTE_SRCDIR) X=app +else + +# +# building object +# + +ifeq ($(X),obj) +include $(TLDK_ROOT)/mk/tle.cpp-vars.mk + +# binary name +OBJ = gtest-rfc.o + +# all source are stored in SRCS-y +SRCS-y += main.cpp +SRCS-y += test_tle_dring.cpp +SRCS-y += test_tle_udp_ctx.cpp +SRCS-y += test_tle_udp_dev.cpp +SRCS-y += test_tle_udp_destroy.cpp +SRCS-y += test_tle_udp_event.cpp +SRCS-y += test_tle_udp_stream.cpp + +CXXFLAGS += -std=c++11 +CXXFLAGS += -I$(GTEST_DIR)/include +CXXFLAGS += -I$(GMOCK_DIR)/include +CXXFLAGS += -I$(TLDK_ROOT)/$(RTE_TARGET)/include + +LDFLAGS += -lstdc++ +LDFLAGS += -L$(GMOCK_DIR) -lgmock +LDLIBS += -ltle_udp -ltle_dring + +include $(TLDK_ROOT)/mk/tle.cpp-obj.mk +endif + +# +# building app +# + +ifeq ($(X),app) + +# binary name +APP = gtest-rfc + +# all source are stored in SRCS-y + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +LDLIBS += gtest-rfc.o + +LDFLAGS += -lstdc++ +LDFLAGS += -L$(GMOCK_DIR) -lgmock +LDLIBS += -L$(TLDK_ROOT)/$(RTE_TARGET)/lib +LDLIBS += -ltle_udp -ltle_dring + +include $(TLDK_ROOT)/mk/tle.app.mk +endif + +endif +endif diff --git a/test/gtest/README b/test/gtest/README new file mode 100644 index 0000000..8d39b6b --- /dev/null +++ b/test/gtest/README @@ -0,0 +1,41 @@ +OVERVIEW +======== + +This application is a set of API unit tests for libtle_dring and libtle_udp +libraries, plus a small set of functional tests for RX/TX functions in +libtle_udp library. +UT application needs GoogleTest C++ testing framework to compile, please +follow installation steps below to enable them. + +INSTALLATION GUIDE +================== +Assumes that user had finished initial installation from TLDK root +directory README. + +1. TLDK unit tests require pcap PMD to be available, enable it in DPDK and + rebuild it. + (http://dpdk.org/doc/quick-start has information how to do it) +2. Obtain GoogleTest and build it. Some additional dependencies might be + needed. + (refer to https://github.com/google/googletest for information how to + download and build it) +3. Make sure that GTEST_DIR and GMOCK_DIR environment variables are set. +4. Rebuild TLDK. + +Example: +cd dpdk +make config T=x86_64-native-linuxapp-gcc +sed -ri 's,(PMD_PCAP=).*,\1y,' build/.config +make install + +git clone https://github.com/google/googletest.git +cd ../googletest +export GTEST_DIR=`pwd`/googletest +export GMOCK_DIR=`pwd`/googlemock +cmake CMakeLists.txt +make + +cd ../tldk +make clean +make all +./x86_64-native-linuxapp-gcc/app/gtest-rfc --lcores=0 diff --git a/test/gtest/main.cpp b/test/gtest/main.cpp new file mode 100644 index 0000000..8c4e2dc --- /dev/null +++ b/test/gtest/main.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + /* Initialize GoogleTest&Mock and parse any args */ + testing::InitGoogleMock(&argc, argv); + + /* Initialize EAL */ + int ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); + argc -= ret; + argv += ret; + + return RUN_ALL_TESTS(); +} diff --git a/test/gtest/test_tle_dring.cpp b/test/gtest/test_tle_dring.cpp new file mode 100644 index 0000000..6ab4905 --- /dev/null +++ b/test/gtest/test_tle_dring.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_tle_dring.h" + +TEST_F(dring, test_dring_st) +{ + printf("%s started;\n", __func__); + + tle_dring_reset(&dr); + r = init_drb_ring(OBJ_NUM); + + ASSERT_NE(r, (void *) NULL) << "Out of memory"; + + tle_dring_dump(stdout, 1, &dr); + + memset(&arg, 0, sizeof(arg)); + arg[0].dr = &dr; + arg[0].r = r; + arg[0].iter = ITER_NUM; + arg[0].enq_type = SINGLE; + arg[0].deq_type = SINGLE; + rc = test_dring_enq_deq(&arg[0]); + + rc = (rc != 0) ? rc : (arg[0].enq != arg[0].deq); + printf("%s finished with status: %s(%d);\n", + __func__, strerror(-rc), rc); + + tle_dring_dump(stdout, rc != 0, &dr); + fini_drb_ring(r); + EXPECT_EQ(rc, 0); +} + + +TEST_F(dring ,test_dring_mp_mc) +{ + rc = test_dring_mt(MULTI, MULTI, MULTI, MULTI); + EXPECT_EQ(rc, 0); +} + +TEST_F(dring, test_dring_mp_sc) +{ + rc = test_dring_mt(MULTI, SINGLE, MULTI, NONE); + EXPECT_EQ(rc, 0); +} + +TEST_F(dring, test_dring_sp_mc) +{ + rc = test_dring_mt(SINGLE, MULTI, NONE, MULTI); + EXPECT_EQ(rc, 0); +} diff --git a/test/gtest/test_tle_dring.h b/test/gtest/test_tle_dring.h new file mode 100644 index 0000000..a978bae --- /dev/null +++ b/test/gtest/test_tle_dring.h @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TEST_TLE_DRING_H_ +#define TEST_TLE_DRING_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct dring_arg { + struct tle_dring *dr; + struct rte_ring *r; + uint32_t iter; + int32_t enq_type; + int32_t deq_type; + uint32_t enq; + uint32_t deq; +}; + +class dring: public ::testing::Test { +protected: + + virtual void SetUp(void) {}; + virtual void TearDown(void) {}; + + int32_t rc; + struct rte_ring *r; + struct tle_dring dr; + struct dring_arg arg[RTE_MAX_LCORE]; + +}; + +#define OBJ_NUM UINT16_MAX +#define ITER_NUM (4 * OBJ_NUM) + +enum { + NONE, + SINGLE, + MULTI, +}; + +/* + * Each enqueued object will contain: + * [2-3]B: it's own sequence number. + * [0-1]B: next object sequence number, or UINT16_MAX. + */ +static void +test_fill_obj(uintptr_t obj[], uint32_t num) +{ + uint32_t i; + + for (i = 0; i != num - 1; i++) + obj[i] = i << 16 | (i + 1); + + obj[i] = i << 16 | UINT16_MAX; +} + +static uint32_t +test_check_obj(uintptr_t obj[], uint32_t num) +{ + uint32_t i, h, l, oh, ol; + + h = obj[0] >> 16; + l = obj[0] & UINT16_MAX; + + if (h + 1 != l && l != UINT16_MAX) + return 0; + + if (l == UINT16_MAX) + l = 0; + + for (i = 1; i != num; i++) { + + oh = obj[i] >> 16; + ol = obj[i] & UINT16_MAX; + + if (l != oh || (oh + 1 != ol && ol != UINT16_MAX)) + return i; + + l = ol; + if (l == UINT16_MAX) + l = 0; + } + + return num; +} + +/* + * free memory allocated for drbs and for the ring itself. + */ +static void +fini_drb_ring(struct rte_ring *r) +{ + struct tle_drb *drb; + + /* free drbs. */ + while (rte_ring_dequeue(r, (void **)&drb) == 0) + free(drb); + + /* free ring. */ + free(r); +} + +static struct rte_ring * +init_drb_ring(uint32_t num) +{ + uint32_t i, k, n; + size_t sz, tsz; + struct rte_ring *r; + struct tle_drb *drb; + + /* allocate and initialise rte_ring. */ + + n = rte_align32pow2(num); + sz = sizeof(*r) + n * sizeof(r->ring[0]); + + r = (struct rte_ring *)calloc(1, sz); + if (r == NULL) { + printf("%s:%d(%u) failed to allocate %zu bytes;\n", + __func__, __LINE__, num, sz); + return NULL; + } + + rte_ring_init(r, __func__, n, 0); + + /* allocate drbs and put them into the ring. */ + + tsz = sz; + for (i = 0; i != num; i += k) { + k = rte_rand() % (UINT8_MAX + 1) + 1; + k = RTE_MIN(k, num - i); + sz = tle_drb_calc_size(k); + drb = (struct tle_drb *)calloc(1, sz); + if (drb == NULL) { + printf("%s:%d(%u) %u-th iteration: " + "failed to allocate %zu bytes;\n", + __func__, __LINE__, num, i, sz); + fini_drb_ring(r); + return NULL; + } + drb->size = k; + rte_ring_enqueue(r, drb); + tsz += sz; + } + + printf("%s(%u) total %zu bytes allocated, number of drbs: %u;\n", + __func__, num, tsz, rte_ring_count(r)); + return r; +} + +static int +test_dring_enqueue(struct tle_dring *dr, struct rte_ring *r, uint32_t num, + int32_t type) +{ + uint32_t i, j, k, lc, nb; + struct tle_drb *drb[num]; + uintptr_t obj[num]; + + lc = rte_lcore_id(); + + /* prepare drbs to enqueue up to *num* objects. */ + for (i = 0, j = 0; i != num; i += k, j++) { + + if (rte_ring_dequeue(r, (void **)&drb[j]) != 0) + break; + + /* udata value for unused drb should be zero. */ + if (drb[j]->udata != NULL) { + printf("error @ %s:%d(%p, %u) at lcore %u: " + "erroneous drb@%p={udata=%p, size=%u,};\n", + __func__, __LINE__, dr, num, lc, drb[j], + drb[j]->udata, drb[j]->size); + return -EFAULT; + } + + /* update udata value with current lcore id. */ + drb[j]->udata = (void *)(uintptr_t)(lc + 1); + k = drb[j]->size; + k = RTE_MIN(k, num - i); + } + + /* no free drbs left. */ + if (i == 0) + return 0; + + /* fill objects to enqueue. */ + test_fill_obj(obj, i); + + /* enqueue into the dring. */ + nb = j; + if (type == SINGLE) + k = tle_dring_sp_enqueue(dr, (const void **)obj, i, drb, &nb); + else if (type == MULTI) + k = tle_dring_mp_enqueue(dr, (const void **)obj, i, drb, &nb); + else + return -EINVAL; + + if (k != i) { + printf("%s:%d(%p, %p, %u): failed to enqueue %u objects;\n", + __func__, __LINE__, dr, r, num, i); + } + + /* free unused drbs */ + for (i = j - nb; i != j; i++) { + if ((uintptr_t)drb[i]->udata != lc + 1) { + printf("error @ %s:%d(%p, %u) at lcore %u: " + "erroneous drb@%p={udata=%p, size=%u,};\n", + __func__, __LINE__, dr, num, lc, drb[i], + drb[i]->udata, drb[i]->size); + return -EFAULT; + } + drb[i]->udata = NULL; + rte_ring_enqueue(r, drb[i]); + } + + return k; +} + +static int +test_dring_dequeue(struct tle_dring *dr, struct rte_ring *r, uint32_t num, + int32_t type) +{ + uint32_t i, k, lc, n, t; + struct tle_drb *drb[num]; + uintptr_t obj[num]; + + lc = rte_lcore_id(); + k = num; + + /* dequeue objects. */ + if (type == SINGLE) + n = tle_dring_sc_dequeue(dr, (const void **)obj, num, drb, &k); + else if (type == MULTI) + n = tle_dring_mc_dequeue(dr, (const void **)obj, num, drb, &k); + else + return -EINVAL; + + if (n == 0) + return 0; + + /* check the data returned. */ + t = test_check_obj(obj, n); + if (t != n) { + printf("%s:%d(%p, %u) at lcore %u: invalid dequeued object, " + "n=%u, idx=%u, obj=%#x, prev obj=%#x;\n", + __func__, __LINE__, dr, num, lc, n, t, + (uint32_t)obj[t], (t == 0) ? 0 : (uint32_t)obj[t - 1]); + return -EFAULT; + } + + /* check and free drbs. */ + for (i = 0; i != k; i++) { + /* udata value for drb in use shouldn't be zero. */ + if (drb[i]->udata == NULL) { + printf("error @ %s:%d(%p, %u) at lcore %u: " + "erroneous drb@%p={udata=%p, size=%u,};\n", + __func__, __LINE__, dr, num, lc, drb[i], + drb[i]->udata, drb[i]->size); + return -EFAULT; + } + drb[i]->udata = NULL; + rte_ring_enqueue(r, drb[i]); + } + + return n; +} + +static int +test_dring_enq_deq(struct dring_arg *arg) +{ + int32_t rc; + uint32_t i, lc, n; + + rc = 0; + arg->enq = 0; + arg->deq = 0; + lc = rte_lcore_id(); + + for (i = 0; i != arg->iter; i++) { + + /* try to enqueue random number of objects. */ + if (arg->enq_type != NONE) { + n = rte_rand() % (UINT8_MAX + 1); + rc = test_dring_enqueue(arg->dr, arg->r, n, + arg->enq_type); + if (rc < 0) + break; + arg->enq += rc; + } + + /* try to dequeue random number of objects. */ + if (arg->deq_type != NONE) { + n = rte_rand() % (UINT8_MAX + 1); + rc = test_dring_dequeue(arg->dr, arg->r, n, + arg->deq_type); + if (rc < 0) + break; + arg->deq += rc; + } + } + + if (rc < 0) + return rc; + + /* dequeue remaining objects. */ + while (arg->deq_type != NONE && arg->enq != arg->deq) { + + /* try to dequeue random number of objects. */ + n = rte_rand() % (UINT8_MAX + 1) + 1; + rc = test_dring_dequeue(arg->dr, arg->r, n, arg->deq_type); + if (rc <= 0) + break; + arg->deq += rc; + } + + printf("%s:%d(lcore=%u, enq_type=%d, deq_type=%d): " + "%u objects enqueued, %u objects dequeued\n", + __func__, __LINE__, lc, arg->enq_type, arg->deq_type, + arg->enq, arg->deq); + return 0; +} + +static int +test_dring_worker(void *arg) +{ + struct dring_arg *p; + + p = (struct dring_arg *)arg; + return test_dring_enq_deq(p); +} + +/* + * enqueue/dequeue by multiple threads. + */ +static int +test_dring_mt(int32_t master_enq_type, int32_t master_deq_type, + int32_t slave_enq_type, int32_t slave_deq_type) +{ + int32_t rc; + uint32_t lc; + uint64_t deq, enq; + struct rte_ring *r; + struct tle_dring dr; + struct dring_arg arg[RTE_MAX_LCORE]; + + tle_dring_reset(&dr); + r = init_drb_ring(OBJ_NUM); + if (r == NULL) + return -ENOMEM; + + memset(arg, 0, sizeof(arg)); + + /* launch on all slaves */ + RTE_LCORE_FOREACH_SLAVE(lc) { + arg[lc].dr = &dr; + arg[lc].r = r; + arg[lc].iter = ITER_NUM; + arg[lc].enq_type = slave_enq_type; + arg[lc].deq_type = slave_deq_type; + rte_eal_remote_launch(test_dring_worker, &arg[lc], lc); + } + + /* launch on master */ + lc = rte_lcore_id(); + arg[lc].dr = &dr; + arg[lc].r = r; + arg[lc].iter = ITER_NUM; + arg[lc].enq_type = master_enq_type; + arg[lc].deq_type = master_deq_type; + rc = test_dring_worker(&arg[lc]); + enq = arg[lc].enq; + deq = arg[lc].deq; + + /* wait for slaves. */ + RTE_LCORE_FOREACH_SLAVE(lc) { + rc |= rte_eal_wait_lcore(lc); + enq += arg[lc].enq; + deq += arg[lc].deq; + } + + printf("%s:%d: total %" PRIu64 " objects enqueued, %" + PRIu64 " objects dequeued\n", + __func__, __LINE__, enq, deq); + + rc = (rc != 0) ? rc : (enq != deq); + if (rc != 0) + tle_dring_dump(stdout, 1, &dr); + + fini_drb_ring(r); + return rc; +} + +#endif /* TEST_TLE_DRING_H_ */ diff --git a/test/gtest/test_tle_udp_ctx.cpp b/test/gtest/test_tle_udp_ctx.cpp new file mode 100644 index 0000000..0bad39f --- /dev/null +++ b/test/gtest/test_tle_udp_ctx.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_tle_udp_ctx.h" + +TEST(udp_ctx, udp_create_null) +{ + struct tle_udp_ctx *ctx; + + ctx = tle_udp_create(NULL); + ASSERT_EQ(ctx, (struct tle_udp_ctx *) NULL); + ASSERT_EQ(rte_errno, EINVAL); +} + +TEST(udp_ctx, udp_create) +{ + struct tle_udp_ctx *ctx; + struct tle_udp_ctx_param prm; + + memset(&prm, 0, sizeof(prm)); + prm.socket_id = SOCKET_ID_ANY; + prm.max_streams = 0x10; + prm.max_stream_rbufs = 0x100; + prm.max_stream_sbufs = 0x100; + + ctx = tle_udp_create(&prm); + ASSERT_NE(ctx, (void *)NULL); + + tle_udp_destroy(ctx); +} diff --git a/test/gtest/test_tle_udp_ctx.h b/test/gtest/test_tle_udp_ctx.h new file mode 100644 index 0000000..af02440 --- /dev/null +++ b/test/gtest/test_tle_udp_ctx.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TEST_TLE_UDP_CTX_H_ +#define TEST_TLE_UDP_CTX_H_ + +#include +#include +#include + +#endif /* TEST_TLE_UDP_CTX_H_ */ diff --git a/test/gtest/test_tle_udp_destroy.cpp b/test/gtest/test_tle_udp_destroy.cpp new file mode 100644 index 0000000..2244b18 --- /dev/null +++ b/test/gtest/test_tle_udp_destroy.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_tle_udp_destroy.h" + +TEST(udp_destroy_null, udp_destroy_null) +{ + tle_udp_destroy(NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_destroy, udp_destroy_positive) +{ + int rc; + tle_udp_destroy(ctx); + ASSERT_EQ(rte_errno, 0); +} diff --git a/test/gtest/test_tle_udp_destroy.h b/test/gtest/test_tle_udp_destroy.h new file mode 100644 index 0000000..d52376e --- /dev/null +++ b/test/gtest/test_tle_udp_destroy.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TEST_TLE_UDP_DESTROY_H_ +#define TEST_TLE_UDP_DESTROY_H_ + +#include +#include +#include + +class udp_destroy : public ::testing::Test { + +protected: + struct tle_udp_ctx *ctx; + struct tle_udp_ctx_param prm; + + virtual void SetUp(void) + { + rte_errno = 0; + memset(&prm, 0, sizeof(prm)); + prm.socket_id = SOCKET_ID_ANY; + prm.max_streams = 0x10; + prm.max_stream_rbufs = 0x100; + prm.max_stream_sbufs = 0x100; + + ctx = tle_udp_create(&prm); + ASSERT_NE(ctx, (void *) NULL); + } + + virtual void TearDown(void) + { + } +}; + +#endif /* TEST_TLE_UDP_DESTROY_H_ */ diff --git a/test/gtest/test_tle_udp_dev.cpp b/test/gtest/test_tle_udp_dev.cpp new file mode 100644 index 0000000..8efb866 --- /dev/null +++ b/test/gtest/test_tle_udp_dev.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_tle_udp_dev.h" + +TEST_F(udp_dev, udp_dev_add_null_ctx) +{ + dev = tle_udp_add_dev(NULL, &dev_prm); + EXPECT_EQ(dev, (void *) NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_dev, udp_dev_add_null_dev_prm) +{ + dev = tle_udp_add_dev(ctx, NULL); + EXPECT_EQ(dev, (void *) NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_dev, udp_dev_add_no_addr) +{ + memset(&(dev_prm).local_addr4, 0, sizeof(struct in_addr)); + memset(&(dev_prm).local_addr6, 0, sizeof(struct in6_addr)); + dev = tle_udp_add_dev(ctx, &dev_prm); + EXPECT_EQ(dev, (void *) NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_dev, udp_dev_add_anyaddr) +{ + inet_pton(AF_INET, "0.0.0.0", &(dev_prm).local_addr4); + inet_pton(AF_INET6, "::0", &(dev_prm).local_addr6); + dev = tle_udp_add_dev(ctx, &dev_prm); + EXPECT_EQ(dev, (void *) NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_dev, udp_dev_add_only_ipv4) +{ + memset(&(dev_prm).local_addr6, 0, sizeof(struct in6_addr)); + dev = tle_udp_add_dev(ctx, &dev_prm); + ASSERT_NE(dev, (void *) NULL); + EXPECT_EQ(rte_errno, 0); +} + +TEST_F(udp_dev, udp_dev_add_only_ipv6) +{ + memset(&(dev_prm).local_addr4, 0, sizeof(struct in_addr)); + dev = tle_udp_add_dev(ctx, &dev_prm); + ASSERT_NE(dev, (void *) NULL); + EXPECT_EQ(rte_errno, 0); +} + +TEST_F(udp_dev, udp_dev_add_nonexist_ipv4) +{ + memset(&(dev_prm).local_addr4, 0, sizeof(struct in_addr)); + inet_pton(AF_INET, "10.0.0.1", &(dev_prm).local_addr4); + dev = tle_udp_add_dev(ctx, &dev_prm); + ASSERT_NE(dev, (void *) NULL); + EXPECT_EQ(rte_errno, 0); +} + +TEST_F(udp_dev, udp_dev_add_positive) +{ + dev = tle_udp_add_dev(ctx, &dev_prm); + ASSERT_NE(dev, (void *) NULL); + EXPECT_EQ(rte_errno, 0); + dev = tle_udp_add_dev(ctx, &dev_prm); + ASSERT_NE(dev, (void *) NULL); + EXPECT_EQ(rte_errno, 0); +} + +TEST_F(udp_dev, udp_dev_del_positive) +{ + dev = tle_udp_add_dev(ctx, &dev_prm); + ASSERT_NE(dev, (void *) NULL); + EXPECT_EQ(rte_errno, 0); + ASSERT_EQ(tle_udp_del_dev(dev), 0); + EXPECT_EQ(rte_errno, 0); +} diff --git a/test/gtest/test_tle_udp_dev.h b/test/gtest/test_tle_udp_dev.h new file mode 100644 index 0000000..3ecc5c7 --- /dev/null +++ b/test/gtest/test_tle_udp_dev.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TEST_TLE_UDP_DEV_H_ +#define TEST_TLE_UDP_DEV_H_ + +#include +#include +#include +#include + +#define RX_NO_OFFLOAD 0 +#define TX_NO_OFFLOAD 0 + +class udp_dev : public ::testing::Test { + +public: + struct tle_udp_ctx *ctx; + struct tle_udp_dev *dev; + struct tle_udp_ctx_param prm; + struct tle_udp_dev_param dev_prm; + + virtual void SetUp(void) + { + rte_errno = 0; + memset(&prm, 0, sizeof(prm)); + prm.socket_id = SOCKET_ID_ANY; + prm.max_streams = 0x1; + prm.max_stream_rbufs = 0x1; + prm.max_stream_sbufs = 0x1; + + memset(&dev_prm, 0, sizeof(dev_prm)); + + /* Offload irrelevant in these tests, set to 0 */ + dev_prm.rx_offload = RX_NO_OFFLOAD; + dev_prm.tx_offload = TX_NO_OFFLOAD; + inet_pton(AF_INET, "192.168.2.1", &(dev_prm).local_addr4); + inet_pton(AF_INET6, "fe80::21e:67ff:fec2:2568", + &(dev_prm).local_addr6); + + ctx = tle_udp_create(&prm); + ASSERT_NE(ctx, (void *) NULL); + } + + virtual void TearDown(void) + { + tle_udp_destroy(ctx); + } +}; + +#endif /* TEST_TLE_UDP_DEV_H_ */ diff --git a/test/gtest/test_tle_udp_event.cpp b/test/gtest/test_tle_udp_event.cpp new file mode 100644 index 0000000..6d5c548 --- /dev/null +++ b/test/gtest/test_tle_udp_event.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_tle_udp_event.h" + +TEST_F(udp_evq, udp_evq_create_null) +{ + evq = tle_evq_create(NULL); + EXPECT_EQ(evq, (struct tle_evq *) NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_evq, udp_evq_create_invalid_socket) +{ + evq_params.socket_id = 999; + evq = tle_evq_create(&evq_params); + ASSERT_EQ(evq, (struct tle_evq *) NULL); +} + +TEST_F(udp_evq, udp_evq_create_destroy_positive) +{ + evq = tle_evq_create(&evq_params); + ASSERT_NE(evq, (struct tle_evq *) NULL); + EXPECT_EQ(rte_errno, 0); + EXPECT_EQ(evq->nb_events, max_events); + EXPECT_EQ(evq->nb_free, max_events); + tle_evq_destroy(evq); + EXPECT_EQ(rte_errno, 0); +} + +TEST_F(udp_event, udp_event_alloc_null) +{ + event = tle_event_alloc(NULL, (void *) &fake_data); + EXPECT_EQ(event, (struct tle_event *) NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_event, udp_event_free_null) +{ + tle_event_free(NULL); + EXPECT_EQ(rte_errno, EINVAL); +} + +TEST_F(udp_event, udp_event_alloc_free_positive) +{ + event = tle_event_alloc(evq, (void *) &fake_data); + ASSERT_NE(event, (struct tle_event *) NULL); + EXPECT_EQ(rte_errno, 0); + EXPECT_EQ(evq->nb_free, max_events - 1); + tle_event_free(event); + EXPECT_EQ(rte_errno, 0); + EXPECT_EQ(evq->nb_free, max_events); +} + +TEST_F(udp_event, udp_event_alloc_free_max_reached) +{ + uint32_t i; + struct tle_event *last_event; + + for (i = 1; i <= max_events; i++) { + event = tle_event_alloc(evq, (void *) &fake_data); + ASSERT_NE(event, (struct tle_event *) NULL); + EXPECT_EQ(rte_errno, 0); + EXPECT_EQ(evq->nb_free, max_events - i); + } + + last_event = tle_event_alloc(evq, (void *) &fake_data); + ASSERT_EQ(last_event, (struct tle_event *) NULL); + ASSERT_EQ(rte_errno, -ENOMEM); + + for (i = 1; i <= max_events; i++) { + tle_event_free(event); + } + EXPECT_EQ(evq->nb_free, max_events); +} + +TEST_F(udp_event_state, udp_state_default) +{ + ASSERT_EQ(event->state, TLE_SEV_IDLE); +} + +TEST_P(udp_event_state_active, udp_state_active) +{ + auto states = GetParam(); + + tle_event_active(event, states.event_state); + ASSERT_EQ(event->state, states.event_state); + EXPECT_EQ(rte_errno, 0); +} + +INSTANTIATE_TEST_CASE_P(Default, udp_event_state_active, + testing::Values( + event_state_active{TLE_SEV_IDLE}, + event_state_active{TLE_SEV_UP}, + event_state_active{TLE_SEV_DOWN} +)); + +TEST_P(udp_event_state_active_twice, udp_state_active_twice) +{ + auto states = GetParam(); + + tle_event_active(event, states.first_state); + ASSERT_EQ(event->state, states.first_state); + EXPECT_EQ(rte_errno, 0); + tle_event_active(event, states.second_state); + ASSERT_EQ(event->state, states.result_state); + EXPECT_EQ(rte_errno, 0); +} + +INSTANTIATE_TEST_CASE_P(Default, udp_event_state_active_twice, + testing::Values( + event_state_active_twice{TLE_SEV_IDLE, TLE_SEV_IDLE, TLE_SEV_IDLE}, + event_state_active_twice{TLE_SEV_IDLE, TLE_SEV_DOWN, TLE_SEV_DOWN}, + event_state_active_twice{TLE_SEV_IDLE, TLE_SEV_UP, TLE_SEV_UP}, + event_state_active_twice{TLE_SEV_DOWN, TLE_SEV_IDLE, TLE_SEV_DOWN}, + event_state_active_twice{TLE_SEV_DOWN, TLE_SEV_DOWN, TLE_SEV_DOWN}, + event_state_active_twice{TLE_SEV_UP, TLE_SEV_IDLE, TLE_SEV_UP}, + event_state_active_twice{TLE_SEV_UP, TLE_SEV_DOWN, TLE_SEV_UP}, + event_state_active_twice{TLE_SEV_UP, TLE_SEV_UP, TLE_SEV_UP} +)); + +TEST_F(udp_event_state, udp_state_raise) +{ + tle_event_raise(event); + ASSERT_EQ(event->state, TLE_SEV_IDLE); + EXPECT_EQ(rte_errno, 0); + tle_event_active(event, TLE_SEV_DOWN); + ASSERT_EQ(event->state, TLE_SEV_DOWN); + EXPECT_EQ(rte_errno, 0); + tle_event_raise(event); + ASSERT_EQ(event->state, TLE_SEV_UP); + EXPECT_EQ(rte_errno, 0); +} + +TEST_F(udp_event_state, udp_state_down) +{ + tle_event_down(event); + ASSERT_EQ(event->state, TLE_SEV_IDLE); + EXPECT_EQ(rte_errno, 0); + tle_event_active(event, TLE_SEV_UP); + ASSERT_EQ(event->state, TLE_SEV_UP); + EXPECT_EQ(rte_errno, 0); + tle_event_down(event); + ASSERT_EQ(event->state, TLE_SEV_DOWN); + EXPECT_EQ(rte_errno, 0); +} + +TEST_P(udp_event_state_idle, udp_state_idle) +{ + auto states = GetParam(); + + tle_event_active(event, states.event_state); + ASSERT_EQ(event->state, states.event_state); + EXPECT_EQ(rte_errno, 0); + tle_event_idle(event); + ASSERT_EQ(event->state, TLE_SEV_IDLE); + EXPECT_EQ(rte_errno, 0); +} + +INSTANTIATE_TEST_CASE_P(Default, udp_event_state_idle, + testing::Values( + event_state_active{TLE_SEV_IDLE}, + event_state_active{TLE_SEV_UP}, + event_state_active{TLE_SEV_DOWN} +)); + +TEST_F(udp_event, udp_event_get) +{ + uint32_t i; + const void **evd; + + evd = (const void **) malloc(max_events * sizeof(void *)); + for (i = 1; i <= max_events; i++) { + event = tle_event_alloc(evq, (void *) &fake_data); + EXPECT_NE(event, (struct tle_event *) NULL); + tle_event_active(event, TLE_SEV_UP); + EXPECT_EQ(event->state, TLE_SEV_UP); + } + EXPECT_EQ(evq->nb_free, 0); + EXPECT_EQ(tle_evq_get(evq, evd, max_events), max_events); + free(evd); +} diff --git a/test/gtest/test_tle_udp_event.h b/test/gtest/test_tle_udp_event.h new file mode 100644 index 0000000..4d66fb6 --- /dev/null +++ b/test/gtest/test_tle_udp_event.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TEST_TLE_UDP_EVENT_H_ +#define TEST_TLE_UDP_EVENT_H_ + +#include +#include +#include +#include + +struct event_state_active { + enum tle_ev_state event_state; +}; + +struct event_state_active_twice { + enum tle_ev_state first_state; + enum tle_ev_state second_state; + enum tle_ev_state result_state; +}; + +class udp_evq : public ::testing::Test { +protected: + + /* Can parameterize here for + * different socket_id and max_events values + */ + int32_t socket_id; + uint32_t max_events; + struct tle_evq_param evq_params; + struct tle_evq *evq; + + virtual void SetUp(void) + { + socket_id = SOCKET_ID_ANY; + max_events = 10; + rte_errno = 0; + memset(&evq_params, 0, sizeof(struct tle_evq_param)); + evq_params.socket_id = socket_id; + evq_params.max_events = max_events; + } + + virtual void TearDown(void) + { + } +}; + +class udp_event : public ::udp_evq { +protected: + + int fake_data; + struct tle_event *event; + + virtual void SetUp(void) + { + udp_evq::SetUp(); + evq = tle_evq_create(&evq_params); + ASSERT_NE(evq, (struct tle_evq *) NULL); + EXPECT_EQ(rte_errno, 0); + } + + virtual void TearDown(void) + { + tle_evq_destroy(evq); + } +}; + +class udp_event_state : public ::udp_event { +protected: + + virtual void SetUp(void) + { + udp_event::SetUp(); + event = tle_event_alloc(evq, (void *) &fake_data); + ASSERT_NE(event, (struct tle_event *) NULL); + } + + virtual void TearDown(void) + { + tle_event_free(event); + udp_event::TearDown(); + } +}; + +struct udp_event_state_active : ::udp_event_state, +testing::WithParamInterface < event_state_active > { + udp_event_state_active() {} +}; + +struct udp_event_state_active_twice : ::udp_event_state, +testing::WithParamInterface < event_state_active_twice > { + udp_event_state_active_twice() {} +}; + +struct udp_event_state_idle : ::udp_event_state_active { +}; + +#endif /* TEST_TLE_UDP_EVENT_H_ */ diff --git a/test/gtest/test_tle_udp_stream.cpp b/test/gtest/test_tle_udp_stream.cpp new file mode 100644 index 0000000..9356288 --- /dev/null +++ b/test/gtest/test_tle_udp_stream.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_tle_udp_stream.h" + +TEST_F(test_tle_udp_stream, stream_test_open) +{ + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_NE(stream, nullptr); + ret = tle_udp_stream_close(stream); + + EXPECT_EQ(ret, 0); +} + +TEST_F(test_tle_udp_stream, stream_test_open_nullctx) +{ + stream = tle_udp_stream_open(nullptr, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_EQ(stream, nullptr); + EXPECT_EQ(rte_errno, EINVAL); + + ret = tle_udp_stream_close(stream); + EXPECT_EQ(ret, EINVAL); +} + +TEST_F(test_tle_udp_stream, stream_test_open_null_stream_prm) +{ + stream = tle_udp_stream_open(ctx, nullptr); + EXPECT_EQ(stream, nullptr); + EXPECT_EQ(rte_errno, EINVAL); + + ret = tle_udp_stream_close(stream); + EXPECT_EQ(ret, EINVAL); +} + + +TEST_F(test_tle_udp_stream, stream_test_open_close_open_close) +{ + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_NE(stream, nullptr); + + ret = tle_udp_stream_close(stream); + EXPECT_EQ(ret, 0); + + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param*)&stream_prm); + EXPECT_NE(stream, nullptr); + + ret = tle_udp_stream_close(stream); + EXPECT_EQ(ret, 0); +} + +TEST_F(test_tle_udp_stream, stream_test_close) +{ + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_NE(stream, nullptr); + + ret = tle_udp_stream_close(stream); + EXPECT_EQ(ret, 0); +} + +TEST_F(test_tle_udp_stream, stream_test_close_null) +{ + ret = tle_udp_stream_close(nullptr); + EXPECT_EQ(ret, EINVAL); +} + + +TEST_F(test_tle_udp_stream, stream_test_close_already) +{ + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_NE(stream, nullptr); + + ret = tle_udp_stream_close(stream); + EXPECT_EQ(ret, 0); + + ret = tle_udp_stream_close(stream); + EXPECT_NE(ret, 0); +} + +TEST_F(test_tle_udp_stream, stream_get_param) +{ + struct tle_udp_stream_param prm; + + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_NE(stream, nullptr); + + ret = tle_udp_stream_get_param(stream,&prm); + EXPECT_EQ(ret, 0); +} + +TEST_F(test_tle_udp_stream, stream_get_param_streamnull) +{ + struct tle_udp_stream_param prm; + + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_NE(stream, nullptr); + + ret = tle_udp_stream_get_param(nullptr, &prm); + EXPECT_EQ(ret, EINVAL); +} + +TEST_F(test_tle_udp_stream, stream_get_param_prmnull) +{ + struct tle_udp_stream_param prm; + + stream = tle_udp_stream_open(ctx, + (const struct tle_udp_stream_param *)&stream_prm); + EXPECT_NE(stream, nullptr); + + ret = tle_udp_stream_get_param(stream, nullptr); + EXPECT_EQ(ret, EINVAL); +} + + + diff --git a/test/gtest/test_tle_udp_stream.h b/test/gtest/test_tle_udp_stream.h new file mode 100644 index 0000000..a5d166b --- /dev/null +++ b/test/gtest/test_tle_udp_stream.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TEST_TLE_UDP_STREAM_H_ +#define TEST_TLE_UDP_STREAM_H_ +#include +#include +#include +#include +#include + +#include +#include + +struct tle_udp_ctx_param ctx_prm_tmpl = { + .socket_id = SOCKET_ID_ANY, + .max_streams = 0x10, + .max_stream_rbufs = 0x100, + .max_stream_sbufs = 0x100 +}; + +struct tle_udp_dev_param dev_prm_tmpl = { + .rx_offload = 0x100, + .tx_offload = 0x100 +}; + +class test_tle_udp_stream: public ::testing::Test { +public: + void setup_dev_prm(struct tle_udp_dev_param *, + char const *, char const *); + struct tle_udp_ctx *setup_ctx(struct tle_udp_ctx_param *prm); + struct tle_udp_dev *setup_dev(struct tle_udp_ctx *ctx, + struct tle_udp_dev_param *dev_prm); + struct tle_evq *setup_event(); + + virtual void SetUp(void) + { + char const *ipv4_laddr = "192.168.0.1"; + char const *ipv4_raddr = "192.168.0.2"; + char const *ipv6 = "fe80::21e:67ff:fec2:2568"; + + ctx = nullptr; + dev = nullptr; + stream = nullptr; + /* Setup Context */ + ctx = setup_ctx(&ctx_prm_tmpl); + /* Setup Dev */ + memset(&dev_prm, 0, sizeof(dev_prm)); + setup_dev_prm(&dev_prm, ipv4_laddr, ipv6); + dev = setup_dev(ctx, &dev_prm); + + /* Stream Param & Event param */ + memset(&stream_prm, 0, sizeof(struct tle_udp_stream_param)); + inet_pton(AF_INET, ipv4_laddr, &stream_prm.local_addr); + inet_pton(AF_INET, ipv4_raddr, &stream_prm.remote_addr); + stream_prm.local_addr.ss_family = AF_INET; + stream_prm.remote_addr.ss_family = AF_INET; + stream_prm.recv_ev = tle_event_alloc(setup_event(), nullptr); + stream_prm.send_ev = tle_event_alloc(setup_event(), nullptr); + } + + virtual void TearDown(void) + { + ret = 0; + tle_udp_stream_close(stream); + tle_udp_del_dev(dev); + tle_udp_destroy(ctx); + } + + int ret; + struct tle_udp_ctx *ctx; + struct tle_udp_dev *dev; + struct tle_udp_stream *stream; + + struct tle_udp_ctx_param ctx_prm; + struct tle_udp_dev_param dev_prm; + struct tle_udp_stream_param stream_prm; +}; + +struct tle_evq *test_tle_udp_stream::setup_event() { + int32_t socket_id; + uint32_t max_events; + struct tle_evq_param evq_params; + struct tle_evq *evq; + + socket_id = SOCKET_ID_ANY; + max_events = 10; + rte_errno = 0; + memset(&evq_params, 0, sizeof(struct tle_evq_param)); + evq_params.socket_id = socket_id; + evq_params.max_events = max_events; + evq = tle_evq_create(&evq_params); + return evq; +} + +struct tle_udp_ctx +*test_tle_udp_stream::setup_ctx(struct tle_udp_ctx_param *prm) { + struct tle_udp_ctx *ctx; + + ctx = tle_udp_create(prm); + + return ctx; +} + +struct tle_udp_dev +*test_tle_udp_stream::setup_dev(struct tle_udp_ctx *ctx, + struct tle_udp_dev_param *dev_prm) { + + struct tle_udp_dev *dev; + + dev = tle_udp_add_dev(ctx, dev_prm); + + return dev; +} + +void test_tle_udp_stream::setup_dev_prm(struct tle_udp_dev_param *dev_prm, + char const *ipv4, char const *ipv6) { + + inet_pton(AF_INET, ipv4, &dev_prm->local_addr4); + inet_pton(AF_INET6, ipv6, &dev_prm->local_addr6); + +} + +#endif /* TEST_TLE_UDP_STREAM_H_ */ -- cgit 1.2.3-korg