From 6ae0e8cdd56f93d3f290538da9331eedcc8a644d Mon Sep 17 00:00:00 2001 From: Agrant Date: Mon, 2 Jun 2025 19:58:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Agrant --- test/BUILD.gn | 19 + test/unittest/BUILD.gn | 144 + .../coap_discover/coap_app_ut.cpp | 235 ++ .../coap_discover/coap_client_ut.cpp | 208 ++ .../coap_discover/coap_discover_ut.cpp | 410 +++ .../dfinder_gtest/json_payload_ut.cpp | 230 ++ .../dfinder_gtest/nstackx_common_ut.cpp | 1424 ++++++++++ .../dfinder_gtest/nstackx_device_local_ut.cpp | 349 +++ .../nstackx_device_remote_ut.cpp | 240 ++ .../nstackx_dfinder_hidump_ut.cpp | 156 ++ .../nstackx_dfinder_hievent_ut.cpp | 74 + test/unittest/dfinder_gtest/util/ut_utils.cpp | 71 + test/unittest/dfinder_gtest/util/ut_utils.h | 56 + test/unittest/test_dfile_gtest.cpp | 2405 +++++++++++++++++ test/unittest/test_dstream_gtest.cpp | 347 +++ 15 files changed, 6368 insertions(+) create mode 100644 test/BUILD.gn create mode 100644 test/unittest/BUILD.gn create mode 100644 test/unittest/dfinder_gtest/coap_discover/coap_app_ut.cpp create mode 100644 test/unittest/dfinder_gtest/coap_discover/coap_client_ut.cpp create mode 100644 test/unittest/dfinder_gtest/coap_discover/coap_discover_ut.cpp create mode 100644 test/unittest/dfinder_gtest/json_payload_ut.cpp create mode 100644 test/unittest/dfinder_gtest/nstackx_common_ut.cpp create mode 100644 test/unittest/dfinder_gtest/nstackx_device_local_ut.cpp create mode 100644 test/unittest/dfinder_gtest/nstackx_device_remote_ut.cpp create mode 100644 test/unittest/dfinder_gtest/nstackx_dfinder_hidump_ut.cpp create mode 100644 test/unittest/dfinder_gtest/nstackx_dfinder_hievent_ut.cpp create mode 100644 test/unittest/dfinder_gtest/util/ut_utils.cpp create mode 100644 test/unittest/dfinder_gtest/util/ut_utils.h create mode 100644 test/unittest/test_dfile_gtest.cpp create mode 100644 test/unittest/test_dstream_gtest.cpp diff --git a/test/BUILD.gn b/test/BUILD.gn new file mode 100644 index 0000000..6970d89 --- /dev/null +++ b/test/BUILD.gn @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# 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. + +import("//build/test.gni") + +group("unittest") { + testonly = true + deps = [ "unittest:unittest" ] +} \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn new file mode 100644 index 0000000..f5edb0f --- /dev/null +++ b/test/unittest/BUILD.gn @@ -0,0 +1,144 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# 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. + +import("//build/test.gni") + +module_output_path = "developer_test/calculator" + +ohos_unittest("DfileTest") { + module_out_path = module_output_path + + cflags = [ + "-Wall", + "-fstack-protector-all", + "-D_FORTIFY_SOURCE=2", + "-DMBEDTLS_INCLUDED", + "-DNSTACKX_DEVICE_L2", + "-DNSTACKX_WITH_HMOS_LINUX", + "-DENABLE_USER_LOG", + "-DOPENSSL_ARM_PLATFORM", + "-DBUILD_FOR_OHOS", + ] + cflags_cc = cflags + include_dirs = [ + "$NSTACKX_ROOT/nstackx_core/dfile/include", + "$NSTACKX_ROOT/nstackx_core/dfile/interface", + "$NSTACKX_ROOT/nstackx_core/platform/unix", + "$NSTACKX_ROOT/nstackx_util/interface", + "$NSTACKX_ROOT/nstackx_util/platform/unix", + ] + sources = [ "test_dfile_test.cpp" ] + deps = [ + "$NSTACKX_ROOT/nstackx_congestion:nstackx_congestion.open", + "$NSTACKX_ROOT/nstackx_core/dfile:nstackx_dfile.open", + "$NSTACKX_ROOT/nstackx_util:nstackx_util.open", + ] + external_deps = [ + "bounds_checking_function:libsec_shared", + "hilog:libhilog", + "mbedtls:mbedtls_shared", + "openssl:libcrypto_shared", + ] + + deps += [ "//third_party/googletest:gtest_main" ] +} + +ohos_unittest("DstreamTest") { + module_out_path = module_output_path + + cflags = [ + "-Wall", + "-fstack-protector-all", + "-D_FORTIFY_SOURCE=2", + "-DMBEDTLS_INCLUDED", + "-DNSTACKX_DEVICE_L2", + "-DNSTACKX_WITH_HMOS_LINUX", + "-DENABLE_USER_LOG", + "-DOPENSSL_ARM_PLATFORM", + "-DBUILD_FOR_OHOS", + ] + cflags_cc = cflags + include_dirs = [ + "$NSTACKX_ROOT/fillp/include", + "$NSTACKX_ROOT/fillp/src/public/include", + "$NSTACKX_ROOT/fillp/src/app_lib/include", + "$NSTACKX_ROOT/fillp/src/fillp_lib/include", + "$NSTACKX_ROOT/fillp/src/fillp_lib/include/fillp", + "$NSTACKX_ROOT/fillp/src/fillp_lib/include/wifi_info", + ] + sources = [ "test_dstream_test.cpp" ] + deps = [ + "$NSTACKX_ROOT/nstackx_congestion:nstackx_congestion.open", + "$NSTACKX_ROOT/fillp:FillpSo.open", + "$NSTACKX_ROOT/nstackx_util:nstackx_util.open", + ] + external_deps = [ + "bounds_checking_function:libsec_shared", + "hilog:libhilog", + "mbedtls:mbedtls_shared", + "openssl:libcrypto_shared", + ] + + deps += [ "//third_party/googletest:gtest_main" ] +} + +ohos_unittest("DfinderTest") { + module_out_path = module_output_path + + cflags = [ + "-Wall", + "-fstack-protector-all", + "-D_FORTIFY_SOURCE=2", + "-DMBEDTLS_INCLUDED", + "-DNSTACKX_DEVICE_L2", + "-DNSTACKX_WITH_HMOS_LINUX", + "-DENABLE_USER_LOG", + "-DOPENSSL_ARM_PLATFORM", + "-DBUILD_FOR_OHOS", + ] + cflags_cc = cflags + include_dirs = [ + "$NSTACKX_ROOT/nstackx_ctrl/include", + "$NSTACKX_ROOT/nstackx_ctrl/interface", + ] + sources = [ + "dfinder_gtest/json_payload_ut.cpp", + "dfinder_gtest/nstackx_common_ut.cpp", + "dfinder_gtest/nstackx_device_local_ut.cpp", + "dfinder_gtest/nstackx_device_remote_ut.cpp", + "dfinder_gtest/nstackx_dfinder_hidump_ut.cpp", + "dfinder_gtest/nstackx_dfinder_hievent_ut.cpp", + ] + deps = [ + "$NSTACKX_ROOT/nstackx_congestion:nstackx_congestion.open", + "$NSTACKX_ROOT/nstackx_ctrl:nstackx_ctrl", + "$NSTACKX_ROOT/nstackx_util:nstackx_util.open", + ] + external_deps = [ + "bounds_checking_function:libsec_shared", + "hilog:libhilog", + "mbedtls:mbedtls_shared", + "openssl:libcrypto_shared", + ] + + deps += [ "//third_party/googletest:gtest_main" ] +} + +group("unittest") { + testonly = true + deps = [ + ":DfileTest", + ":DstreamTest", + ":DfinderTest", + ] +} \ No newline at end of file diff --git a/test/unittest/dfinder_gtest/coap_discover/coap_app_ut.cpp b/test/unittest/dfinder_gtest/coap_discover/coap_app_ut.cpp new file mode 100644 index 0000000..7aceb37 --- /dev/null +++ b/test/unittest/dfinder_gtest/coap_discover/coap_app_ut.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "coap_app.h" +#ifndef _WIN32 +#include +#endif +#include "coap_client.h" +#include "nstackx_device_local.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" +#include "ut_utils.h" + +TEST(Dfinder, TestGetCoapContextList) +{ + List *list = GetCoapContextList(); + ASSERT_NE(list, nullptr); +} + +void Invoke_coap_register_response_handler(coap_context_t *context, coap_response_handler_t handler) +{ + (void)context; + (void)handler; +} +TEST(Dfinder, TestCoapServerInit) +{ + coap_context_t *ctx = CreateCoapContext(); + LocalIface *localIface = CreateLocalIface(); + union InetAddr ipAddr; + ipAddr.in = localIface->addr.in; + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + CoapCtxType *coapCtxType = CoapServerInit(AF_INET, &ipAddr, localIface); + ASSERT_EQ(coapCtxType, nullptr); + GlobalMockObject::verify(); + + // CoapGetContext == NULL + MOCKER(CoapGetContext).stubs().will(returnValue((coap_context_t *)NULL)); + coapCtxType = CoapServerInit(AF_INET, &ipAddr, localIface); + ASSERT_EQ(coapCtxType, nullptr); + GlobalMockObject::verify(); + + // CoapInitResources(ctx->ctx) != NSTACKX_EOK, {@link ctx} is free + MOCKER(CoapGetContext).stubs().will(returnValue(ctx)); + MOCKER(CoapInitResources).stubs().will(returnValue(NSTACKX_EFAILED)); + coapCtxType = CoapServerInit(AF_INET, &ipAddr, localIface); + ASSERT_EQ(coapCtxType, nullptr); + GlobalMockObject::verify(); + + // all is ok + MOCKER(CoapGetContext).stubs().will(returnValue(ctx)); + MOCKER(CoapInitResources).stubs().will(returnValue(NSTACKX_EOK)); + MOCKER(coap_register_response_handler).stubs().will(invoke(Invoke_coap_register_response_handler)); + coapCtxType = CoapServerInit(AF_INET, &ipAddr, localIface); + ASSERT_NE(coapCtxType, nullptr); + GlobalMockObject::verify(); + + FreeLocalIface(localIface); + ListRemoveNode(&coapCtxType->node); + free(coapCtxType); +} + +TEST(Dfinder, TestCoapGetCoapCtxType) +{ + CoapCtxType *ctx = InsertDevice(); + + CoapCtxType *coapCtxType = CoapGetCoapCtxType(NULL); + ASSERT_EQ(coapCtxType, nullptr); + + coapCtxType = CoapGetCoapCtxType(ctx->ctx); + ASSERT_EQ(coapCtxType, ctx); + + RemoveDevice(ctx); +} + +TEST(Dfinder, TestIsCoapContextReady) +{ + bool ret = IsCoapContextReady(); + ASSERT_EQ(ret, false); +} + +static coap_socket_t *g_socket; +#define PREPARE_IO_RETURN_VALUE 1000 +unsigned int Invoke_coap_io_prepare_io(coap_context_t *ctx, coap_socket_t *sockets[], unsigned int max_sockets, + unsigned int *numSockets, coap_tick_t now) +{ + *numSockets = 1; + g_socket = (coap_socket_t *)malloc(1*sizeof(coap_socket_t)); + g_socket->fd = 1; + g_socket->flags = COAP_SOCKET_WANT_CONNECT; + sockets[0] = g_socket; + return PREPARE_IO_RETURN_VALUE; +} +TEST(Dfinder, TestRegisterCoAPEpollTask) +{ + CoapCtxType *ctx = InsertDevice(); + // all is ok + ctx->socketNum = 1; + EpollDesc epollfd = CreateEpollDesc(); + MOCKER(coap_io_prepare_io).stubs().will(invoke(Invoke_coap_io_prepare_io)); + uint32_t ret = RegisterCoAPEpollTask(epollfd); + ASSERT_EQ(ret, (uint32_t)1000); + GlobalMockObject::verify(); + + free(g_socket); + RemoveDevice(ctx); +} + +TEST(Dfinder, TestCoAPEpollReadHandle) +{ + CoapCtxType *ctx = InsertDevice(); + // all is ok + ctx->socketNum = 1; + EpollDesc epollfd = CreateEpollDesc(); + MOCKER(coap_io_prepare_io).stubs().will(invoke(Invoke_coap_io_prepare_io)); + uint32_t ret = RegisterCoAPEpollTask(epollfd); + ASSERT_EQ(ret, (uint32_t)1000); + GlobalMockObject::verify(); + + // data == null + ctx->taskList[0].readHandle(NULL); + + EpollTask task = {0}; + // task->taskfd < 0 + task.taskfd = -1; + ctx->taskList[0].readHandle(&task); + + // task->ptr == NULL + task.taskfd = 0; + task.ptr = (void *)NULL; + ctx->taskList[0].readHandle(&task); + + coap_socket_t socket = {0}; + task.ptr = &socket; + // socket->flags & COAP_SOCKET_WANT_READ + socket.flags = COAP_SOCKET_WANT_READ; + ctx->taskList[0].readHandle(&task); + + // socket->flags & COAP_SOCKET_WANT_ACCEPT + socket.flags = COAP_SOCKET_WANT_ACCEPT; + ctx->taskList[0].readHandle(&task); + + free(g_socket); + RemoveDevice(ctx); +} + +TEST(Dfinder, TestCoAPEpollWriteHandle) +{ + CoapCtxType *ctx = InsertDevice(); + // all is ok + ctx->socketNum = 1; + EpollDesc epollfd = CreateEpollDesc(); + MOCKER(coap_io_prepare_io).stubs().will(invoke(Invoke_coap_io_prepare_io)); + uint32_t ret = RegisterCoAPEpollTask(epollfd); + ASSERT_EQ(ret, (uint32_t)1000); + GlobalMockObject::verify(); + + // data == null + ctx->taskList[0].writeHandle(NULL); + + EpollTask task = {0}; + // task->taskfd < 0 + task.taskfd = -1; + ctx->taskList[0].writeHandle(&task); + + // task->ptr == NULL + task.taskfd = 0; + task.ptr = (void *)NULL; + ctx->taskList[0].writeHandle(&task); + + coap_socket_t socket = {0}; + task.ptr = &socket; + // socket->flags & COAP_SOCKET_WANT_WRITE + socket.flags = COAP_SOCKET_WANT_WRITE; + ctx->taskList[0].writeHandle(&task); + + // socket->flags & COAP_SOCKET_WANT_CONNECT + socket.flags = COAP_SOCKET_WANT_CONNECT; + ctx->taskList[0].writeHandle(&task); + + free(g_socket); + RemoveDevice(ctx); +} + +TEST(Dfinder, TestCoAPEpollErrorHandle) +{ + CoapCtxType *ctx = InsertDevice(); + // all is ok + ctx->socketNum = 1; + EpollDesc epollfd = CreateEpollDesc(); + MOCKER(coap_io_prepare_io).stubs().will(invoke(Invoke_coap_io_prepare_io)); + uint32_t ret = RegisterCoAPEpollTask(epollfd); + ASSERT_EQ(ret, (uint32_t)1000); + GlobalMockObject::verify(); + + EpollTask task = {0}; + // task->taskfd < 0 + task.taskfd = -1; + ctx->taskList[0].errorHandle(&task); + + // task->ptr == NULL + task.taskfd = 0; + task.ptr = (void *)NULL; + ctx->taskList[0].errorHandle(&task); + + coap_socket_t socket = {0}; + task.ptr = &socket; + + // IsCoapCtxEndpointSocket is ok + MOCKER(IsCoapCtxEndpointSocket).stubs().will(returnValue(1)); + ctx->taskList[0].errorHandle(&task); + GlobalMockObject::verify(); + + // IsCoapCtxEndpointSocket is error + MOCKER(IsCoapCtxEndpointSocket).stubs().will(returnValue(0)); + ctx->taskList[0].errorHandle(&task); + GlobalMockObject::verify(); + + free(g_socket); + RemoveDevice(ctx); +} diff --git a/test/unittest/dfinder_gtest/coap_discover/coap_client_ut.cpp b/test/unittest/dfinder_gtest/coap_discover/coap_client_ut.cpp new file mode 100644 index 0000000..c7bc57f --- /dev/null +++ b/test/unittest/dfinder_gtest/coap_discover/coap_client_ut.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "coap_client.h" +#ifndef _WIN32 +#include +#endif + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" +#include "ut_utils.h" + +TEST(Dfinder, TestCoapResolveAddress) +{ + // all is ok + coap_str_const_t *server = coap_make_str_const("server"); + struct sockaddr_in inetAddr = {0}; + inetAddr.sin_family = AF_INET; + inetAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + inetAddr.sin_port = htons(0); + struct sockaddr *dst = (struct sockaddr*)&inetAddr; + int32_t ret = CoapResolveAddress(server, dst); + ASSERT_NE(ret, -1); + + // dst == NULL + ret = CoapResolveAddress(server, NULL); + ASSERT_EQ(ret, -2); + + // server->length > 0 and then memcpy_s is error + MOCKER(memcpy_s).stubs().will(returnValue(-1)); + ret = CoapResolveAddress(server, dst); + ASSERT_EQ(ret, -1); + GlobalMockObject::verify(); + + // server->length == 0 and then memcpy_s is error + MOCKER(memcpy_s).stubs().will(returnValue(-1)); + int temp = server->length; + server->length = 0; + ret = CoapResolveAddress(server, dst); + ASSERT_EQ(ret, -1); + server->length = temp; + GlobalMockObject::verify(); + + // getaddrinfo return -2 + MOCKER(getaddrinfo).stubs().will(returnValue(-2)); + ret = CoapResolveAddress(server, dst); + ASSERT_EQ(ret, -2); + GlobalMockObject::verify(); +} + +namespace MessageHandlerNs { + static coap_session_t *session = NULL; + static coap_pdu_t sent; + static coap_pdu_t recv; + static coap_opt_t opt = {0}; +} + +TEST(Dfinder, TestCoapMessageHandler_NullReceivedPdu) +{ + coap_response_t ret = CoapMessageHandler(MessageHandlerNs::session, &MessageHandlerNs::sent, NULL, 1); + ASSERT_EQ(ret, COAP_RESPONSE_FAIL); +} + +TEST(Dfinder, TestCoapMessageHandler_ReceiveRstMsg) +{ + MOCKER(coap_pdu_get_type).stubs().will(returnValue(COAP_MESSAGE_RST)); + int32_t ret = CoapMessageHandler(MessageHandlerNs::session, &MessageHandlerNs::sent, &MessageHandlerNs::recv, 1); + GlobalMockObject::verify(); + ASSERT_EQ(ret, COAP_RESPONSE_FAIL); +} + +TEST(Dfinder, TestCoapMessageHandler_OptNotNull) +{ + MOCKER(coap_check_option).stubs().will(returnValue(&MessageHandlerNs::opt)); + MOCKER(coap_pdu_get_type).stubs().will(returnValue(COAP_MESSAGE_ACK)); + int32_t ret = CoapMessageHandler(MessageHandlerNs::session, &MessageHandlerNs::sent, &MessageHandlerNs::recv, 1); + GlobalMockObject::verify(); + ASSERT_EQ(ret, COAP_RESPONSE_FAIL); +} + +TEST(Dfinder, TestCoapMessageHandler_NullOptThenNotNullOpt) +{ + MOCKER(coap_check_option).stubs().will(returnValue((coap_opt_t *)NULL)).then(returnValue(&MessageHandlerNs::opt)); + MOCKER(coap_pdu_get_type).stubs().will(returnValue(COAP_MESSAGE_ACK)); + int32_t ret = CoapMessageHandler(MessageHandlerNs::session, &MessageHandlerNs::sent, &MessageHandlerNs::recv, 1); + GlobalMockObject::verify(); + ASSERT_EQ(ret, COAP_RESPONSE_FAIL); +} + +TEST(Dfinder, TestCoapMessageHandler_AllOk) +{ + // all is ok + MOCKER(coap_check_option).stubs().will(returnValue((coap_opt_t *)NULL)); + MOCKER(coap_pdu_get_type).stubs().will(returnValue(COAP_MESSAGE_ACK)); + int32_t ret = CoapMessageHandler(MessageHandlerNs::session, &MessageHandlerNs::sent, &MessageHandlerNs::recv, 1); + ASSERT_EQ(ret, COAP_RESPONSE_OK); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestCoapGetContext) +{ + char addrStr[NI_MAXHOST] = COAP_SRV_DEFAULT_ADDR; + char portStr[NI_MAXSERV] = COAP_SRV_DEFAULT_PORT; + LocalIface *localIface = CreateLocalIface(); + union InetAddr ipAddr; + ipAddr.in = localIface->addr.in; + + // getaddrinfo != 0 + MOCKER(getaddrinfo).stubs().will(returnValue(-1)); + coap_context_t *ctx = CoapGetContext(addrStr, portStr, AF_INET, &ipAddr); + ASSERT_EQ(ctx, nullptr); + GlobalMockObject::verify(); + + // coap_new_endpoint == NULL + MOCKER(coap_new_endpoint).stubs().will(returnValue((coap_endpoint_t *)NULL)); + ctx = CoapGetContext(addrStr, portStr, AF_INET, &ipAddr); + ASSERT_EQ(ctx, nullptr); + GlobalMockObject::verify(); + + // BindToDevice(ep->sock.fd, sockIpPtr) != NSTACKX_EOK + ctx = CoapGetContext(addrStr, portStr, AF_INET, &ipAddr); + ASSERT_EQ(ctx, nullptr); + + FreeLocalIface(localIface); + free(ctx); +} + +TEST(Dfinder, TestCoapGetSession) +{ + coap_address_t dst = {0}; + struct sockaddr_in inetAddr; + inetAddr.sin_family = AF_INET; + inetAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + inetAddr.sin_port = htons(0); + memcpy_s(&dst.addr.sa, sizeof(struct sockaddr), (struct sockaddr*)&inetAddr, 10); + dst.size = (uint32_t)10; + dst.addr.sin.sin_port = htons(COAP_DEFAULT_PORT); + dst.addr.sa.sa_family = AF_INET; + CoapServerParameter coapServerParameter = { + .proto = COAP_PROTO_UDP, + .dst = &dst + }; + coap_context_t *ctx = CreateCoapContext(); + coap_session_t *session1 = (coap_session_t *)malloc(1*sizeof(coap_session_t *)); + // all is ok + MOCKER(coap_new_client_session).stubs().will(returnValue(session1)); + coap_session_t *session = CoapGetSession(ctx, "127.0.0.1", COAP_SRV_DEFAULT_PORT, &coapServerParameter); + ASSERT_EQ(session, session1); + GlobalMockObject::verify(); + + // localAddr == NULL + session = CoapGetSession(ctx, NULL, COAP_SRV_DEFAULT_PORT, &coapServerParameter); + ASSERT_EQ(session, nullptr); + + // getaddrinfo != 0 + MOCKER(getaddrinfo).stubs().will(returnValue(-1)); + session = CoapGetSession(ctx, "127.0.0.1", COAP_SRV_DEFAULT_PORT, &coapServerParameter); + ASSERT_EQ(session, nullptr); + GlobalMockObject::verify(); + + // coap_session_get_by_peer != NULL + MOCKER(coap_session_get_by_peer).stubs().will(returnValue(session1)); + session = CoapGetSession(ctx, "127.0.0.1", COAP_SRV_DEFAULT_PORT, &coapServerParameter); + ASSERT_EQ(session, session1); + GlobalMockObject::verify(); + + // dst == NULL + coapServerParameter.dst = NULL; + session = CoapGetSession(ctx, "127.0.0.1", COAP_SRV_DEFAULT_PORT, &coapServerParameter); + ASSERT_EQ(session, nullptr); + + // proto != COAP_PROTO_UDP + coapServerParameter.proto = COAP_PROTO_NONE; + session = CoapGetSession(ctx, "127.0.0.1", COAP_SRV_DEFAULT_PORT, &coapServerParameter); + ASSERT_EQ(session, nullptr); + + // coapServerParameter == NULL + session = CoapGetSession(ctx, "127.0.0.1", COAP_SRV_DEFAULT_PORT, NULL); + ASSERT_EQ(session, nullptr); + + FreeCoapContext(ctx); + free(session1); +} + +TEST(Dfinder, TestIsCoapCtxEndpointSocket) +{ + coap_context_t *coapContext = CreateCoapContext(); + uint8_t ret = IsCoapCtxEndpointSocket(coapContext, 1); + ASSERT_EQ(ret, NSTACKX_FALSE); + + // ctx == NULL + ret = IsCoapCtxEndpointSocket(NULL, 1); + ASSERT_EQ(ret, NSTACKX_FALSE); + + FreeCoapContext(coapContext); +} diff --git a/test/unittest/dfinder_gtest/coap_discover/coap_discover_ut.cpp b/test/unittest/dfinder_gtest/coap_discover/coap_discover_ut.cpp new file mode 100644 index 0000000..fcd94d3 --- /dev/null +++ b/test/unittest/dfinder_gtest/coap_discover/coap_discover_ut.cpp @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "coap_discover.h" +#include "coap_client.h" +#include "nstackx_dfinder_log.h" +#include "nstackx_util.h" +#include "json_payload.h" +#include "nstackx_device_local.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" +#include "ut_utils.h" + +#define BODY_LENGTH 331 + +void MockSetDefaultCoapDiscoverTargetCount() +{ + // IsCoapContextReady is ok + MOCKER(IsCoapContextReady).stubs().will(returnValue(true)); + // g_coapDiscoverType = COAP_BROADCAST_TYPE_DEFAULT + SetCoapDiscoverType(COAP_BROADCAST_TYPE_DEFAULT); + CoapServiceDiscoverInnerConfigurable(1); +} + +#define LOCAL_IP_LENGTH 9 + +void MockCoapGetSession(coap_context_t *ctx) +{ + // setsockopt is ok + MOCKER(setsockopt).stubs().will(returnValue(0)); + // coap_session_get_by_peer is ok + coap_address_t dst = {0}; + struct sockaddr_in inetAddr; + inetAddr.sin_family = AF_INET; + inetAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + inetAddr.sin_port = htons(COAP_DEFAULT_PORT); + memcpy_s(&dst.addr.sa, sizeof(struct sockaddr), (struct sockaddr*)&inetAddr, LOCAL_IP_LENGTH); + dst.size = (uint32_t)LOCAL_IP_LENGTH; + dst.addr.sin.sin_port = htons(COAP_DEFAULT_PORT); + dst.addr.sa.sa_family = AF_INET; + coap_session_t *session = coap_new_client_session(ctx, NULL, &dst, COAP_PROTO_UDP); + MOCKER(coap_session_get_by_peer).stubs().will(returnValue(session)); +} + +TEST(Dfinder, TestSetCoapDiscConfig) +{ + uint32_t bcastInterval[1] = {0}; + DFinderDiscConfig config; + config.bcastInterval = bcastInterval; + config.intervalArrLen = 1; + + // malloc is error, and g_coapIntervalArr == NULL + MOCKER(malloc).stubs().will(returnValue((void *)NULL)); + int32_t ret = SetCoapDiscConfig(&config); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // all is ok + ret = SetCoapDiscConfig(&config); + ASSERT_EQ(ret, NSTACKX_EOK); + + // g_coapIntervalArr != NULL + ret = SetCoapDiscConfig(&config); + ASSERT_EQ(ret, NSTACKX_EOK); + + // malloc is error, and g_coapIntervalArr != NULL + MOCKER(malloc).stubs().will(returnValue((void *)NULL)); + ret = SetCoapDiscConfig(&config); + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); + + // free g_coapIntervalArr + CoapDiscoverDeinit(); +} + +static Timer *InvokeTimerStart(EpollDesc epollfd, uint32_t ms, uint8_t repeated, TimeoutHandle handle, void *data) +{ + handle(data); + return (Timer *)malloc(1 * sizeof(Timer)); +} +static void TimerHandle(void *argument) +{ + (void)argument; +} +TEST(Dfinder, TestCoapDiscoverInit) +{ + EpollDesc epollfd = CreateEpollDesc(); + + // g_recvRecountTimer == NULL + MOCKER(TimerStart).stubs().will(returnValue((Timer *)NULL)); + int32_t ret = CoapDiscoverInit(epollfd); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // g_discoverTimer == NULL + Timer *timer = TimerStart(epollfd, 1000, NSTACKX_TRUE, TimerHandle, NULL); + MOCKER(TimerStart).stubs().will(returnValue(timer)).then(returnValue((Timer *)NULL)); + ret = CoapDiscoverInit(epollfd); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // g_notificationTimer == NULL + Timer *tmpRecvTimer = TimerStart(epollfd, 1000, NSTACKX_TRUE, TimerHandle, NULL); + EXPECT_NE(tmpRecvTimer, (Timer *)NULL) << "recv timer, case g_notificationTimer == NULL fail"; + Timer *tmpDiscTimer = TimerStart(epollfd, 1000, NSTACKX_TRUE, TimerHandle, NULL); + EXPECT_NE(tmpDiscTimer, (Timer *)NULL) << "disc timer, case g_notificationTimer == NULL fail"; + MOCKER(TimerStart).stubs().will(returnValue(tmpRecvTimer)). + then(returnValue(tmpDiscTimer)).then(returnValue((Timer *)NULL)); + ret = CoapDiscoverInit(epollfd); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case g_notificationTimer == NULL fail"; + CoapDiscoverDeinit(); + GlobalMockObject::verify(); + + // calloc is error + MOCKER(TimerStart).stubs().will(invoke(InvokeTimerStart)); + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = CoapDiscoverInit(epollfd); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // all is ok + MOCKER(TimerStart).stubs().will(invoke(InvokeTimerStart)); + ret = CoapDiscoverInit(epollfd); + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); + CoapDiscoverDeinit(); + + // g_discoverCount < g_coapDiscoverTargetCount && IsCoapContextReady is true + MOCKER(IsCoapContextReady).stubs().will(returnValue(true)); + MOCKER(TimerStart).stubs().will(invoke(InvokeTimerStart)); + SetCoapDiscoverType(COAP_BROADCAST_TYPE_DEFAULT); + CoapServiceDiscoverInnerAn(1); + // CoapPostServiceDiscover + CoapCtxType *ctx = InsertDevice(); + + char serviceData[] = "service\0"; + NSTACKX_RegisterServiceData(serviceData); + // GetBroadcastIp != NSTACKX_EOK + ret = CoapDiscoverInit(epollfd); + ASSERT_EQ(ret, NSTACKX_EOK); + CoapDiscoverDeinit(); + + // GetBroadcastIp == NSTACKX_EOK + MOCKER(GetBroadcastIp).stubs().will(returnValue(NSTACKX_EOK)); + // CoapGetSession != NULL + coap_session_t *session = (coap_session_t *)malloc(1 * sizeof(coap_session_t)); + MOCKER(CoapGetSession).stubs().will(returnValue(session)); + // coap_split_uri >= 0 + MOCKER(coap_split_uri).stubs().will(returnValue(0)); + // CoapResolveAddress >= 0 + MOCKER(CoapResolveAddress).stubs().will(returnValue(0)); + // coap_new_pdu != NULL + coap_pdu_t *pdu = (coap_pdu_t *)malloc(1 * sizeof(coap_pdu_t)); + MOCKER(coap_new_pdu).stubs().will(returnValue(pdu)); + // coap_send != COAP_INVALID_TID(-1) + MOCKER(coap_send).stubs().will(returnValue(1)); + + ret = CoapDiscoverInit(epollfd); + ASSERT_EQ(ret, NSTACKX_EOK); + CoapDiscoverDeinit(); + GlobalMockObject::verify(); + + CoapDiscoverDeinit(); + RemoveDevice(ctx); + free(session); + free(pdu); +} + +TEST(Dfinder, TestCoapDiscoverRequestOngoing) +{ + // 调用 CoapSubscribeModuleInner,假设它会触发 CoapDiscoverRequestOngoing 返回 1 + CoapSubscribeModuleInner(1); + uint8_t ret = CoapDiscoverRequestOngoing(); + ASSERT_EQ(ret, 1); +} + +namespace ServiceMsgNs { + static const uint8_t data[] = {0}; + static MsgCtx ctx = { + .deviceId = "deviceId", + .moduleName = "moduleName", + .data = data, + .len = 1, + .type = SERVER_TYPE_WLANORETH, + .err = NSTACKX_EOK + }; + const char addr[INET_ADDRSTRLEN] = "127.0.0.1:8080"; + struct in_addr remoteIp; +} + +TEST(Dfinder, TestCoapSendServiceMsg_NullCtx) +{ + (void)inet_pton(AF_INET, ServiceMsgNs::addr, &ServiceMsgNs::remoteIp); + MOCKER(LocalIfaceGetCoapCtxByRemoteIp).stubs().will(returnValue((CoapCtxType *)NULL)); + int32_t ret = CoapSendServiceMsg(&ServiceMsgNs::ctx, ServiceMsgNs::addr, &ServiceMsgNs::remoteIp); + GlobalMockObject::verify(); + ASSERT_EQ(ret, NSTACKX_EFAILED); +} + +TEST(Dfinder, TestCoapSendServiceMsg_NullSession) +{ + CoapCtxType *coapCtxType = CreateCoapCtxType(); + MOCKER(LocalIfaceGetCoapCtxByRemoteIp).stubs().will(returnValue(coapCtxType)); + MOCKER(CoapGetSession).stubs().will(returnValue((coap_session_t *)NULL)); + int32_t ret = CoapSendServiceMsg(&ServiceMsgNs::ctx, ServiceMsgNs::addr, &ServiceMsgNs::remoteIp); + GlobalMockObject::verify(); + FreeCoapCtxType(coapCtxType); + ASSERT_EQ(ret, NSTACKX_EFAILED); +} + +TEST(Dfinder, TestCoapSendServiceMsg_MemcpysFail) +{ + MOCKER(memcpy_s).stubs().will(returnValue(EINVAL)); + int32_t ret = CoapSendServiceMsg(&ServiceMsgNs::ctx, ServiceMsgNs::addr, &ServiceMsgNs::remoteIp); + ASSERT_EQ(ret, NSTACKX_EFAILED); +} + +TEST(Dfinder, TestCoapSendServiceMsg_CallocFail) +{ + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + int32_t ret = CoapSendServiceMsg(&ServiceMsgNs::ctx, ServiceMsgNs::addr, &ServiceMsgNs::remoteIp); + GlobalMockObject::verify(); + ASSERT_EQ(ret, NSTACKX_EFAILED); +} + +static bool g_IsDiscoverMode = true; +static void Invoke_coap_register_handler(coap_resource_t *resource, coap_request_t method, + coap_method_handler_t handler) +{ + coap_session_t *session = NULL; + coap_pdu_t *request = (coap_pdu_t *)malloc(1 * sizeof(coap_pdu_t)); + coap_pdu_t *response = (coap_pdu_t *)malloc(1 * sizeof(coap_pdu_t)); + request->mid = 1; // Valid message ids are 0 to 2^16. Negative values are error codes. + if (g_IsDiscoverMode) { + request->body_data = (const uint8_t *) + "{\"deviceId\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE623283EAE5CEDD\\\"}\"," + "\"devicename\":\"Mate 50\",\"type\":14,\"mode\":1,\"deviceHash\":\"0\"," + "\"serviceData\":\"\",\"extendServiceData\":\"\",\"wlanIp\":\"127.0.0.1\",\"capabilityBitmap\":[71]," + "\"bType\":0,\"bData\":\"\", \"coapUri\":\"coap://127.0.0.1/device_discover\"}"; + } else { + request->body_data = (const uint8_t *) + "{\"deviceId\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE623283EAE5CEDD\\\"}\"," + "\"devicename\":\"Mate 50\",\"type\":14,\"mode\":2,\"deviceHash\":\"0\"," + "\"serviceData\":\"\",\"extendServiceData\":\"\",\"wlanIp\":\"127.0.0.1\",\"capabilityBitmap\":[71]," + "\"bType\":0,\"bData\":\"\", \"coapUri\":\"coap://127.0.0.1/device_discover\"}"; + } + request->body_length = (size_t)BODY_LENGTH; + handler(resource, session, request, coap_get_query(request), response); + + free(request); + free(response); +} +static void Invoke_coap_resource_set_get_observable(coap_resource_t *resource, int mode) +{ + return; +} +static void Invoke_coap_add_resource(coap_context_t *context, coap_resource_t *resource) +{ + return; +} +static int Invoke_coap_delete_resource(coap_context_t *context, coap_resource_t *resource) +{ + return 0; +} +static void Invoke_coap_pdu_set_code(coap_pdu_t *pdu, coap_pdu_code_t code) +{ + return; +} +TEST(Dfinder, TestCoapInitResources) +{ + // InsertDevice and CoapDiscoverInit + CoapCtxType *ctx = InsertDevice(); + + // r == NULL + MOCKER(coap_resource_init).stubs().will(returnValue((coap_resource_t *)NULL)); + int32_t ret = CoapInitResources(ctx->ctx); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // msg == NULL + MOCKER(coap_register_request_handler).stubs().will(invoke(Invoke_coap_register_handler)); + MOCKER(coap_resource_set_get_observable).stubs().will(invoke(Invoke_coap_resource_set_get_observable)); + MOCKER(coap_add_resource).stubs().will(invoke(Invoke_coap_add_resource)); + MOCKER(coap_delete_resource).stubs().will(invoke(Invoke_coap_delete_resource)); + coap_resource_t *res = (coap_resource_t *)malloc(1 * sizeof(coap_resource_t)); + MOCKER(coap_resource_init).stubs().will(returnValue(res)).then(returnValue((coap_resource_t *)NULL)); + ret = CoapInitResources(ctx->ctx); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // notification == NULL + MOCKER(coap_register_request_handler).stubs().will(invoke(Invoke_coap_register_handler)); + MOCKER(coap_resource_set_get_observable).stubs().will(invoke(Invoke_coap_resource_set_get_observable)); + MOCKER(coap_add_resource).stubs().will(invoke(Invoke_coap_add_resource)); + MOCKER(coap_delete_resource).stubs().will(invoke(Invoke_coap_delete_resource)); + coap_resource_t *resDisc = (coap_resource_t *)malloc(1 * sizeof(coap_resource_t)); + EXPECT_NE(resDisc, (coap_resource_t *)NULL) << "malloc for disc testcase notification == NULL fail"; + coap_resource_t *resMsg = (coap_resource_t *)malloc(1 * sizeof(coap_resource_t)); + EXPECT_NE(resMsg, (coap_resource_t *)NULL) << "malloc for msg testcase notification == NULL fail"; + MOCKER(coap_resource_init).stubs().will(returnValue(resDisc)). + then(returnValue(resMsg)).then(returnValue((coap_resource_t *)NULL)); + ret = CoapInitResources(ctx->ctx); + if (resDisc) free(resDisc); + if (resMsg) free(resMsg); + EXPECT_EQ(ret, NSTACKX_ENOMEM) << "case notification == NULL fail"; + GlobalMockObject::verify(); + + // all is ok + MOCKER(coap_register_request_handler).stubs().will(invoke(Invoke_coap_register_handler)); + MOCKER(coap_resource_set_get_observable).stubs().will(invoke(Invoke_coap_resource_set_get_observable)); + MOCKER(coap_add_resource).stubs().will(invoke(Invoke_coap_add_resource)); + MOCKER(coap_delete_resource).stubs().will(invoke(Invoke_coap_delete_resource)); + MOCKER(coap_resource_init).stubs().will(returnValue(res)); + coap_context_t *context = CreateCoapContext(); + MOCKER(coap_session_get_context).stubs().will(returnValue(context)); + MOCKER(CoapGetCoapCtxType).stubs().will(returnValue(ctx)); + MOCKER(GetServiceDiscoverInfo).stubs().will(returnValue(NSTACKX_EOK)); + MOCKER(ReportDiscoveredDevice).stubs().will(returnValue(NSTACKX_EOK)); + MOCKER(coap_pdu_set_code).stubs().will(invoke(Invoke_coap_pdu_set_code)); + MOCKER(ntohs).stubs().will(returnValue(BODY_LENGTH)); + + ret = CoapInitResources(ctx->ctx); + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); + + CoapDiscoverDeinit(); + RemoveDevice(ctx); + free(res); + FreeCoapContext(context); +} + +TEST(Dfinder, TestCoapServiceNotification) +{ + // coap context not ready + CoapServiceNotification(); + + // coap context ready, init, already running, run again: g_notificationRunCnt != 0 + MOCKER(IsCoapContextReady).stubs().will(returnValue(true)); + NSTACKX_Parameter params = {0}; + int32_t ret = NSTACKX_Init(¶ms); + EXPECT_EQ(ret, NSTACKX_EOK) << "dfinder init fail"; + uint16_t tmpIntervals[3] = {0, 2000, 2000}; + std::string tmpMsg("hello"); + NSTACKX_NotificationConfig config = { + msg : const_cast(tmpMsg.c_str()), + msgLen : 5, + intervalsMs : tmpIntervals, + intervalLen : 3, + businessType : NSTACKX_BUSINESS_TYPE_NULL + }; + // ThreadInit + ret = NSTACKX_ThreadInit(); + ASSERT_EQ(ret, NSTACKX_EOK) << "thread init fail"; + + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EOK) << "send notification fail"; + CoapServiceNotification(); + NSTACKX_Deinit(); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestLocalizeNotificationInterval) +{ + const uint16_t tmpIntervals[3] = {0, 2000, 2000}; + const uint8_t intervalLen = 3; + + MOCKER(calloc) + .stubs() + .will(returnValue(static_cast(NULL))); + int32_t ret = LocalizeNotificationInterval(tmpIntervals, intervalLen); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "malloc for notification interval fail"; + GlobalMockObject::verify(); + + // all ok, first call to make g_notificationIntervals not NULL + ret = LocalizeNotificationInterval(tmpIntervals, intervalLen); + EXPECT_EQ(ret, NSTACKX_EOK) << "first localize interval fail"; + + MOCKER(calloc) + .stubs() + .will(returnValue(static_cast(NULL))); + ret = LocalizeNotificationInterval(tmpIntervals, intervalLen); + EXPECT_EQ(ret, NSTACKX_EOK) << "second localize interval fail"; + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestCoapServiceNotificationStop) +{ + // g_notificationIntervals == NULL + CoapServiceNotificationStop(); + + // g_notificationIntervals != NULL + const uint16_t tmpIntervals[5] = {0, 1000, 2000, 3000, 4000}; + const uint8_t intervalLen = 5; + int32_t ret = LocalizeNotificationInterval(tmpIntervals, intervalLen); + EXPECT_EQ(ret, NSTACKX_EOK) << "first localize interval fail"; + CoapServiceNotificationStop(); +} diff --git a/test/unittest/dfinder_gtest/json_payload_ut.cpp b/test/unittest/dfinder_gtest/json_payload_ut.cpp new file mode 100644 index 0000000..96f6803 --- /dev/null +++ b/test/unittest/dfinder_gtest/json_payload_ut.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "json_payload.h" +#include + +#include "cJSON.h" +#ifndef DFINDER_USE_MINI_NSTACKX +#include "coap_client.h" +#endif /* END OF DFINDER_USE_MINI_NSTACKX */ +#include "nstackx_dfinder_log.h" +#include "nstackx_dfinder_mgt_msg_log.h" +#include "nstackx_error.h" +#include "nstackx_device.h" +#include "nstackx_statistics.h" +#include "nstackx_device_local.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" + +class Dfinder : public testing::Test { +public: + void SetUp() + { + Dfinderinit(); + } + void TearDown() + { + DfinderDestroy(); + } +}; + +TEST(Dfinder, TestPrepareServiceDiscover) +{ + DeviceInfo *deviceInfo = (DeviceInfo *)calloc(1, sizeof(DeviceInfo)); + char deviceName[11] = "deviceName"; + strcpy_s(deviceInfo->deviceName, sizeof(deviceInfo->deviceName), deviceName); + deviceInfo->deviceType = UINT8_MAX + 1; + uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM] = {1}; + memcpy_s(deviceInfo->capabilityBitmap, sizeof(deviceInfo->capabilityBitmap), capabilityBitmap, + sizeof(deviceInfo->capabilityBitmap)); + MOCKER(GetLocalDeviceInfo).stubs().will(returnValue(deviceInfo)); + char localIpStr[NSTACKX_MAX_IP_STRING_LEN] = "127.1.1.1"; + char serviceData[512] = + "{" + "\"deviceId\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE623283EAE5CEDD\\\"}\"," + "\"devicename\":\"Mate 50\",\"type\":0,\"seqNo\":1,\"mode\":1," + "\"deviceHash\":\"0\",\"serviceData\":\"\",\"extendServiceData\":\"\",\"wlanIp\":\"127.0.0.1\"," + "\"capabilityBitmap\":[71]," + "\"bType\":0,\"bData\":\"\", \"coapUri\":\"coap://127.0.0.1/device_discover\"" + "}"; + char *ret = PrepareServiceDiscover(AF_INET, localIpStr, NSTACKX_TRUE, NSTACKX_BUSINESS_TYPE_SOFTBUS, serviceData); + ASSERT_NE(ret, (char *)NULL); + cJSON_free(ret); + + // deviceInfo->deviceType <= UINT8_MAX + deviceInfo->deviceType = UINT8_MAX; + ret = PrepareServiceDiscover(AF_INET, localIpStr, NSTACKX_TRUE, NSTACKX_BUSINESS_TYPE_SOFTBUS, serviceData); + ASSERT_NE(ret, (char *)NULL); + cJSON_free(ret); + + GlobalMockObject::verify(); + + // cJSON_CreateString == NULL + MOCKER(GetLocalDeviceInfo).stubs().will(returnValue(deviceInfo)); + MOCKER(cJSON_CreateString).stubs().will(returnValue((cJSON *)NULL)); + ret = PrepareServiceDiscover(AF_INET, localIpStr, NSTACKX_TRUE, NSTACKX_BUSINESS_TYPE_SOFTBUS, serviceData); + ASSERT_EQ(ret, (char *)NULL); + GlobalMockObject::verify(); + + // cJSON_CreateNumber == NULL + MOCKER(GetLocalDeviceInfo).stubs().will(returnValue(deviceInfo)); + MOCKER(cJSON_CreateNumber).stubs().will(returnValue((cJSON *)NULL)); + ret = PrepareServiceDiscover(AF_INET, localIpStr, NSTACKX_TRUE, NSTACKX_BUSINESS_TYPE_SOFTBUS, serviceData); + ASSERT_EQ(ret, (char *)NULL); + GlobalMockObject::verify(); + + // cJSON_CreateObject == NULL + MOCKER(cJSON_CreateObject).stubs().will(returnValue((cJSON *)NULL)); + ret = PrepareServiceDiscover(AF_INET, localIpStr, NSTACKX_TRUE, NSTACKX_BUSINESS_TYPE_SOFTBUS, serviceData); + ASSERT_EQ(ret, (char *)NULL); + GlobalMockObject::verify(); + + free(deviceInfo); +} + +TEST(Dfinder, TestParseServiceDiscover) +{ + char buf[512] = + "{" + "\"deviceId\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE623283EAE5CEDD\\\"}\"," + "\"devicename\":\"Mate 50\",\"type\":0,\"seqNo\":1,\"mode\":1," + "\"deviceHash\":\"0\",\"serviceData\":\"\",\"extendServiceData\":\"\",\"wlanIp\":\"127.0.0.1\"," + "\"capabilityBitmap\":[71]," + "\"bType\":0,\"bData\":\"\", \"coapUri\":\"coap://127.0.0.1/device_discover\"" + "}"; + DeviceInfo *deviceInfo = (DeviceInfo *)calloc(1, sizeof(DeviceInfo)); + char *remoteUrl = NULL; + int32_t ret = ParseServiceDiscover((uint8_t *)buf, deviceInfo, &remoteUrl); + free(remoteUrl); + ASSERT_EQ(ret, NSTACKX_EOK); + + // strdup is error + MOCKER(strdup).stubs().will(returnValue((char *)NULL)); + ret = ParseServiceDiscover((uint8_t *)buf, deviceInfo, &remoteUrl); + GlobalMockObject::verify(); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + + // cJSON_IsString is false, 0 is false + MOCKER(cJSON_IsString).stubs().will(returnValue(0)); + ret = ParseServiceDiscover((uint8_t *)buf, deviceInfo, &remoteUrl); + GlobalMockObject::verify(); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // strcpy_s != EOK + MOCKER(strcpy_s).stubs().will(returnValue(-1)); + ret = ParseServiceDiscover((uint8_t *)buf, deviceInfo, &remoteUrl); + GlobalMockObject::verify(); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // cJSON_IsNumber is false, 0 is false + MOCKER(cJSON_IsNumber).stubs().will(returnValue(0)); + ret = ParseServiceDiscover((uint8_t *)buf, deviceInfo, &remoteUrl); + GlobalMockObject::verify(); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + free(deviceInfo); +} + +TEST(Dfinder, TestParseServiceDiscover_RecvMsgWithHicomVersion) +{ + char recvedMsg[512] = + "{" + "\"deviceId\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE623283EAE5CEDD\\\"}\"," + "\"devicename\":\"Mate 50\",\"type\":0,\"seqNo\":1,\"hicomversion\":\"3.1.0.0\",\"mode\":1," + "\"deviceHash\":\"0\",\"serviceData\":\"\",\"extendServiceData\":\"\",\"wlanIp\":\"127.0.0.1\"," + "\"capabilityBitmap\":[71]," + "\"bType\":0,\"bData\":\"\", \"coapUri\":\"coap://127.0.0.1/device_discover\"" + "}"; + + DeviceInfo *deviceInfo = (DeviceInfo *)calloc(1, sizeof(DeviceInfo)); + ASSERT_NE(deviceInfo, nullptr); + + char *remoteUrl = NULL; + int32_t ret = ParseServiceDiscover((uint8_t *)recvedMsg, deviceInfo, &remoteUrl); + free(deviceInfo); + free(remoteUrl); + ASSERT_EQ(ret, NSTACKX_EOK); +} + +TEST(Dfinder, TestParseServiceNotification) +{ + char buf[] = + "{\"notify\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE623283EAE5CEDD\\\"}\"}"; + // buf NULL + int32_t ret = ParseServiceNotification(NULL, NULL); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "input buf null"; + + char tmpMsg[NSTACKX_MAX_NOTIFICATION_DATA_LEN] = {0}; + NSTACKX_NotificationConfig config = { + msg : tmpMsg, + msgLen : 0, + intervalsMs : NULL, + intervalLen : 0, + businessType : NSTACKX_BUSINESS_TYPE_NULL + }; + + // cJSON_Parse fail + MOCKER(cJSON_Parse).stubs().will(returnValue((cJSON *)NULL)); + ret = ParseServiceNotification((const uint8_t *)buf, &config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case cJSON_Parse fail"; + GlobalMockObject::verify(); + + // cJSON_GetObjectItemCaseSensitive fail + MOCKER(cJSON_GetObjectItemCaseSensitive).stubs().will(returnValue((cJSON *)NULL)); + ret = ParseServiceNotification((const uint8_t *)buf, &config); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case cJSON_GetObjectItemCaseSensitive fail"; + GlobalMockObject::verify(); + + // cJSON_IsString fail + MOCKER(cJSON_IsString).stubs().will(returnValue((cJSON_bool)false)); + ret = ParseServiceNotification((const uint8_t *)buf, &config); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case cJSON_IsString fail"; + GlobalMockObject::verify(); + + // strcpy_s fail + MOCKER(strcpy_s).stubs().will(returnValue(EINVAL)); + ret = ParseServiceNotification((const uint8_t *)buf, &config); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case strcpy_s fail"; + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestPrepareServiceNotification) +{ + // cJSON_CreateObject fail + MOCKER(cJSON_CreateObject).stubs().will(returnValue((cJSON *)NULL)); + char *ret = PrepareServiceNotification(); + EXPECT_EQ(ret, (char *)NULL) << "case cJSON_CreateObject fail"; + GlobalMockObject::verify(); + + // JsonAddStr fail + DeviceInfo tmpDeviceInfo = {0}; + MOCKER(GetLocalDeviceInfo).stubs().will(returnValue(&tmpDeviceInfo)); + MOCKER(cJSON_CreateString).stubs().will(returnValue((cJSON *)NULL)); + ret = PrepareServiceNotification(); + EXPECT_EQ(ret, (char *)NULL) << "JsonAddStr fail"; + GlobalMockObject::verify(); + + // all ok + tmpDeviceInfo = {0}; + MOCKER(GetLocalDeviceInfo).stubs().will(returnValue(&tmpDeviceInfo)); + ret = PrepareServiceNotification(); + EXPECT_NE(ret, (char *)NULL) << "case cJSON_PrintUnformatted fail"; + if (ret != NULL) { + free(ret); + } + GlobalMockObject::verify(); +} \ No newline at end of file diff --git a/test/unittest/dfinder_gtest/nstackx_common_ut.cpp b/test/unittest/dfinder_gtest/nstackx_common_ut.cpp new file mode 100644 index 0000000..885879b --- /dev/null +++ b/test/unittest/dfinder_gtest/nstackx_common_ut.cpp @@ -0,0 +1,1424 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "nstackx_common.h" +#include "nstackx_error.h" +#include "nstackx_event.h" +#include "nstackx_timer.h" +#include "nstackx_util.h" +#include "json_payload.h" +#include "nstackx_device_remote.h" +#include "nstackx_dfinder_hievent.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" + +static void DeviceListChanged(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount) +{ +} + +static void DeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount) +{ +} + +static void MsgReceived(const char *moduleName, const char *deviceId, + const uint8_t *data, uint32_t len, const char *srcIp) +{ +} + +static DFinderMsgType mType = DFINDER_ON_INNER_ERROR; + +static void DFinderMsgReceived(DFinderMsgType msgType) +{ + mType = msgType; +} + +void DFinderOnNotificationReceived(const NSTACKX_NotificationConfig *notification) +{ + (void)notification; +} + +class Dfinder : public testing::Test { +public: + void SetUp() + { + Dfinderinit(); + } + void TearDown() + { + DfinderDestroy(); + } +}; + +TEST(Dfinder, TestGetIsNotifyPerDevice) +{ + bool ret = GetIsNotifyPerDevice(); + ASSERT_EQ(ret, false); +} + +TEST(Dfinder, TestGetEventNodeChain) +{ + List *ret = GetEventNodeChain(); + ASSERT_NE(ret, nullptr); +} + +TEST(Dfinder, TestGetEpollFD) +{ + EpollDesc ret = GetEpollFD(); + ASSERT_EQ(ret, INVALID_EPOLL_DESC); +} + +TEST(Dfinder, TestNotifyDFinderMsgRecver) +{ + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + NotifyDFinderMsgRecver(DFINDER_ON_TOO_BUSY); + ASSERT_EQ(mType, DFINDER_ON_TOO_BUSY); + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestShouldAutoReplyUnicast) +{ + int32_t ret = ShouldAutoReplyUnicast(NSTACKX_BUSINESS_TYPE_NULL); + ASSERT_EQ(ret, NSTACKX_TRUE); + ret = ShouldAutoReplyUnicast(NSTACKX_BUSINESS_TYPE_HICOM); + ASSERT_EQ(ret, NSTACKX_TRUE); + ret = ShouldAutoReplyUnicast(NSTACKX_BUSINESS_TYPE_SOFTBUS); + ASSERT_EQ(ret, NSTACKX_FALSE); + ret = ShouldAutoReplyUnicast(NSTACKX_BUSINESS_TYPE_NEARBY); + ASSERT_EQ(ret, NSTACKX_TRUE); + ret = ShouldAutoReplyUnicast(-1); + ASSERT_EQ(ret, NSTACKX_TRUE); +} + +TEST(Dfinder, TestGetDefaultDiscoverInterval) +{ + uint32_t ret = GetDefaultDiscoverInterval(0); + ASSERT_EQ(ret, (uint32_t)COAP_FIRST_DISCOVER_INTERVAL); + ret = GetDefaultDiscoverInterval(COAP_FIRST_DISCOVER_COUNT_RANGE); + ASSERT_EQ(ret, (uint32_t)COAP_SECOND_DISCOVER_INTERVAL); + ret = GetDefaultDiscoverInterval(COAP_SECOND_DISCOVER_COUNT_RANGE); + ASSERT_EQ(ret, (uint32_t)COAP_LAST_DISCOVER_INTERVAL); +} + +TEST(Dfinder, TestGetServiceDiscoverInfo) +{ + const uint8_t *buf =(uint8_t *) + "{\"deviceId\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE623283EAE5CEDD\\\"}\"," + "\"devicename\":\"Mate 50\",\"type\":14,\"mode\":1,\"deviceHash\":\"0\"," + "\"serviceData\":\"\",\"extendServiceData\":\"\",\"wlanIp\":\"127.0.0.1\",\"capabilityBitmap\":[71]," + "\"bType\":0,\"bData\":\"\", \"coapUri\":\"coap://127.0.0.1/device_discover\"}"; + DeviceInfo deviceInfo = {0}; + char *remoteUrl = NULL; + //deviceInfo->discoveryType = (*remoteUrl != NULL) ? NSTACKX_DISCOVERY_TYPE_PASSIVE : NSTACKX_DISCOVERY_TYPE_ACTIVE; + deviceInfo.discoveryType = NSTACKX_DISCOVERY_TYPE_ACTIVE; + + // size <= 0 + int32_t ret = GetServiceDiscoverInfo(buf, 0, &deviceInfo, &remoteUrl); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + ret = GetServiceDiscoverInfo(buf, sizeof(buf)-1, &deviceInfo, &remoteUrl); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + // memcpy_s is error + MOCKER(memcpy_s).stubs().will(returnValue(-1)); + ret = GetServiceDiscoverInfo(buf, sizeof(buf)-1, &deviceInfo, &remoteUrl); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = GetServiceDiscoverInfo(buf, sizeof(buf)-1, &deviceInfo, &remoteUrl); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // ParseServiceDiscover == NSTACKX_EOK + MOCKER(ParseServiceDiscover).stubs().will(returnValue(NSTACKX_EOK)); + ret = GetServiceDiscoverInfo(buf, sizeof(buf)-1, &deviceInfo, &remoteUrl); + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestGetMainLoopEpollFd) +{ + EpollDesc ret = GetMainLoopEpollFd(); + ASSERT_EQ(ret, INVALID_EPOLL_DESC); +} + +TEST(Dfinder, TestGetMainLoopEvendChain) +{ + List *ret = GetMainLoopEvendChain(); + ASSERT_NE(ret, nullptr); +} + +TEST(Dfinder, TestNSTACKX_InitAndDeinit) +{ + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + // GetTimeDiffMs > EVENT_COUNT_RATE_INTERVAL + MOCKER(GetTimeDiffMs).stubs().will(returnValue(2001)); + int32_t ret = NSTACKX_Init(¶meter); + ASSERT_EQ(ret, NSTACKX_EOK); + // init again + ret = NSTACKX_InitV2(¶meter, true); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(1100000); // 因为每隔1秒,主线程会轮询执行一遍,所以睡眠1.1s,保证主线程轮询的时候mock还生效 + GlobalMockObject::verify(); + NSTACKX_Deinit(); + // deInit again + NSTACKX_Deinit(); + + // CoapDiscoverInit error + MOCKER(CoapDiscoverInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_Init(¶meter); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // DeviceModuleInit error + MOCKER(DeviceModuleInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_Init(¶meter); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // EventModuleInit error + MOCKER(EventModuleInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_Init(¶meter); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // IsEpollDescValid error + MOCKER(CreateEpollDesc).stubs().will(returnValue(-1)); + ret = NSTACKX_Init(¶meter); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_StartDeviceFind) +{ + // not init + int32_t ret = NSTACKX_StartDeviceFind(); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDeviceFound = DeviceFound; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // all is ok + MOCKER(IsCoapContextReady).stubs().will(returnValue(true)); + ret = NSTACKX_StartDeviceFind(); + ASSERT_EQ(ret, NSTACKX_EOK); + NSTACKX_Deinit(); + usleep(50000); // post event is async operation + GlobalMockObject::verify(); + + // onDeviceFound == NULL + parameter.onDeviceFound = NULL; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + ret = NSTACKX_StartDeviceFind(); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // PostEvent error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StartDeviceFind(); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_StartDeviceFindAn) +{ + // not init + int32_t ret = NSTACKX_StartDeviceFindAn(DISCOVER_MODE); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // all is ok + ret = NSTACKX_StartDeviceFindAn(DISCOVER_MODE); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // PostEvent error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StartDeviceFindAn(DISCOVER_MODE); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_StopDeviceFind) +{ + // not init + int32_t ret = NSTACKX_StopDeviceFind(); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // all is ok + ret = NSTACKX_StopDeviceFind(); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // PostEvent error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StopDeviceFind(); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_StartDeviceDiscovery) +{ + // not init + NSTACKX_DiscoverySettings settings = {0}; + int32_t ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // *settings * is null + NSTACKX_DiscoverySettings *setting = nullptr; + ret = NSTACKX_StartDeviceDiscovery(setting); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // businessData == null and length != 0 + settings.businessData = nullptr; + settings.length = 1; + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // length is NSTACKX_MAX_BUSINESS_DATA_LEN + settings.businessData = (char *)"businessData"; + settings.length = NSTACKX_MAX_BUSINESS_DATA_LEN; + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // advertiseCount is 0 and advertiseDuration is 0 + settings.length = NSTACKX_MAX_BUSINESS_DATA_LEN - 1; + settings.advertiseCount = 0; + settings.advertiseDuration = 0; + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EOK); + + // advertiseCount is NSTACKX_MIN_ADVERTISE_COUNT and advertiseDuration is NSTACKX_MAX_ADVERTISE_DURATION + 1 + settings.advertiseCount = NSTACKX_MIN_ADVERTISE_COUNT; + settings.advertiseDuration = NSTACKX_MAX_ADVERTISE_DURATION + 1; + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // all is ok + settings.advertiseDuration = NSTACKX_MAX_ADVERTISE_DURATION; + settings.businessType = 0; + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // businessType != businessTypeLocal + settings.businessType = 1; + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EOK); + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // strncpy_s is error + MOCKER(strncpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StartDeviceDiscovery(&settings); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_StartDeviceDiscoveryWithConfig) +{ + DFinderDiscConfig config = {0}; + uint32_t array[] = {NSTACKX_MAX_ADVERTISE_INTERVAL}; + config.bcastInterval = array; + config.intervalArrLen = 1; + config.businessData = (char *)"businessData"; + config.businessDataLen = NSTACKX_MAX_BUSINESS_DATA_LEN - 1; + // not init + int32_t ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // param is NULL + ret = NSTACKX_StartDeviceDiscoveryWithConfig(NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // intervalArrLen is 0 + config.intervalArrLen = 0; + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EINVAL); + config.intervalArrLen = 1; + + // bcastInterval is illegal + uint32_t array1[] = {NSTACKX_MAX_ADVERTISE_INTERVAL + 1}; + config.bcastInterval = array1; + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EINVAL); + uint32_t array2[] = {NSTACKX_MAX_ADVERTISE_INTERVAL}; + config.bcastInterval = array2; + + // businessData is NULL and businessDataLen != 0 + config.businessData = (char *)NULL; + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EINVAL); + config.businessData = (char *)"businessData"; + + // businessDataLen is NSTACKX_MAX_BUSINESS_DATA_LEN + config.businessDataLen = NSTACKX_MAX_BUSINESS_DATA_LEN; + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EINVAL); + config.businessDataLen = NSTACKX_MAX_BUSINESS_DATA_LEN - 1; + + // all is ok + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + // businessType != businessTypeLocal + config.businessType = 1; + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // strncpy_s is error + MOCKER(strncpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StartDeviceDiscoveryWithConfig(&config); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); +} + +TEST(Dfinder, TestNSTACKX_SubscribeModule) +{ + // not init + int32_t ret = NSTACKX_SubscribeModule(); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + + // all is ok + ret = NSTACKX_SubscribeModule(); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_UnsubscribeModule) +{ + // not init + int32_t ret = NSTACKX_UnsubscribeModule(); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + + // all is ok + ret = NSTACKX_UnsubscribeModule(); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + GlobalMockObject::verify(); + + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_RegisterDevice) +{ + NSTACKX_LocalDeviceInfo *deviceInfo = (NSTACKX_LocalDeviceInfo *)calloc(1, sizeof(NSTACKX_LocalDeviceInfo)); + // not init + int32_t ret = NSTACKX_RegisterDevice(deviceInfo); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + + // param is NULL + ret = NSTACKX_RegisterDevice(NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // ifNums is error + memset_s(deviceInfo, sizeof(deviceInfo), 0, sizeof(deviceInfo)); + deviceInfo->ifNums = NSTACKX_MAX_LISTENED_NIF_NUM + 1; + ret = NSTACKX_RegisterDevice(deviceInfo); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // StringHasEOF(networkIpAddr) is error or invalid ip addr + // StringHasEOF(networkIpAddr) is error + deviceInfo->ifNums = 0; + for (int i = 0; i < NSTACKX_MAX_IP_STRING_LEN; i++) { + deviceInfo->networkIpAddr[i] = 'a'; + } + ret = NSTACKX_RegisterDevice(deviceInfo); + ASSERT_EQ(ret, NSTACKX_EINVAL); + // invalid ip addr + deviceInfo->networkIpAddr[NSTACKX_MAX_IP_STRING_LEN - 1] = '\0'; + ret = NSTACKX_RegisterDevice(deviceInfo); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // StringHasEOF(networkName) is error + memset_s(deviceInfo, sizeof(deviceInfo), 0, sizeof(deviceInfo)); + for (int i = 0; i < NSTACKX_MAX_INTERFACE_NAME_LEN; i++) { + deviceInfo->networkName[i] = 'a'; + } + ret = NSTACKX_RegisterDevice(deviceInfo); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // all is ok + memset_s(deviceInfo, sizeof(deviceInfo), 0, sizeof(deviceInfo)); + memset_s(deviceInfo->networkIpAddr, sizeof(deviceInfo->networkIpAddr), 0, sizeof(deviceInfo->networkIpAddr)); + memset_s(deviceInfo->networkName, sizeof(deviceInfo->networkName), 0, sizeof(deviceInfo->networkName)); + deviceInfo->ifNums = 0; + deviceInfo->deviceId[NSTACKX_MAX_DEVICE_ID_LEN - 1] = '\0'; + deviceInfo->name[NSTACKX_MAX_DEVICE_NAME_LEN] = '\0'; + deviceInfo->networkName[NSTACKX_MAX_INTERFACE_NAME_LEN - 1] = '\0'; + deviceInfo->networkIpAddr[0] = '1'; + deviceInfo->networkIpAddr[1] = '2'; + deviceInfo->networkIpAddr[2] = '7'; + deviceInfo->networkIpAddr[3] = '.'; + deviceInfo->networkIpAddr[4] = '1'; + deviceInfo->networkIpAddr[5] = '0'; + deviceInfo->networkIpAddr[6] = '0'; + deviceInfo->networkIpAddr[7] = '.'; + deviceInfo->networkIpAddr[8] = '1'; + deviceInfo->networkIpAddr[9] = '0'; + deviceInfo->networkIpAddr[10] = '0'; + deviceInfo->networkIpAddr[11] = '.'; + deviceInfo->networkIpAddr[12] = '1'; + deviceInfo->networkIpAddr[13] = '0'; + deviceInfo->networkIpAddr[14] = '0'; + ret = NSTACKX_RegisterDevice(deviceInfo); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // strcpy_s is error + deviceInfo->ifNums = 0; + MOCKER(strcpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterDevice(deviceInfo); + ASSERT_EQ(ret, NSTACKX_EINVAL); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); + free(deviceInfo); +} + +// 其他分支在TestNSTACKX_RegisterDevice里已全部覆盖 +TEST(Dfinder, TestNSTACKX_RegisterDeviceAn) +{ + NSTACKX_LocalDeviceInfo deviceInfo = {0}; + // not init + int32_t ret = NSTACKX_RegisterDeviceAn(&deviceInfo, 0); + ASSERT_EQ(ret, NSTACKX_EFAILED); +} + +// 其他分支在TestNSTACKX_RegisterDevice里已全部覆盖 +TEST(Dfinder, TestNSTACKX_RegisterDeviceV2) +{ + NSTACKX_LocalDeviceInfoV2 deviceInfo = {0}; + // not init + int32_t ret = NSTACKX_RegisterDeviceV2(&deviceInfo); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + ret = NSTACKX_RegisterDeviceV2(&deviceInfo); + ASSERT_EQ(ret, NSTACKX_EINVAL); + usleep(50000); // post event is async operation + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_RegisterDeviceName) +{ + char devName[NSTACKX_MAX_DEVICE_NAME_LEN - 1] = "A"; + // not init + int32_t ret = NSTACKX_RegisterDeviceName(devName); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + ret = NSTACKX_RegisterDeviceName(NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // strlen(devName) > NSTACKX_MAX_DEVICE_NAME_LEN - 1 + char devName1[NSTACKX_MAX_DEVICE_NAME_LEN + 1] = + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + ret = NSTACKX_RegisterDeviceName(devName1); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + (void)NSTACKX_ThreadInit(); + // PostEvent != NSTACKX_EOK + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterDeviceName(devName); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + ret = NSTACKX_RegisterDeviceName(devName); + ASSERT_EQ(ret, NSTACKX_EOK); + + NSTACKX_ThreadDeinit(); + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_RegisterCapability) +{ + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // capabilityBitmapNum != 0 && capabilityBitmap == NULL + int32_t ret = NSTACKX_RegisterCapability(1, NULL); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + // capabilityBitmapNum > NSTACKX_MAX_CAPABILITY_NUM + uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM]; + ret = NSTACKX_RegisterCapability(NSTACKX_MAX_CAPABILITY_NUM + 1, capabilityBitmap); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // all is ok + ret = NSTACKX_RegisterCapability(NSTACKX_MAX_CAPABILITY_NUM, capabilityBitmap); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_RegisterCapability(NSTACKX_MAX_CAPABILITY_NUM, capabilityBitmap); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // memcpy_s is error + MOCKER(memcpy_s).stubs().will(returnValue(-1)); + ret = NSTACKX_RegisterCapability(NSTACKX_MAX_CAPABILITY_NUM, capabilityBitmap); + ASSERT_EQ(ret, NSTACKX_EINVAL); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterCapability(NSTACKX_MAX_CAPABILITY_NUM, capabilityBitmap); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); +} + +// 其他分支在TestNSTACKX_RegisterCapability里已全部覆盖 +TEST(Dfinder, TestNSTACKX_SetFilterCapability) +{ + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + int32_t ret = NSTACKX_SetFilterCapability(0, NULL); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_SetMaxDeviceNum) +{ + // not init + int32_t ret = NSTACKX_SetMaxDeviceNum(0); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // SemInit is error + MOCKER(SemInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SetMaxDeviceNum(0); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SetMaxDeviceNum(0); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); +} + +TEST(Dfinder, TestNSTACKX_SetDeviceListAgingTime) +{ + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + + // all is ok + int32_t ret = NSTACKX_SetDeviceListAgingTime(0); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_ScreenStatusChange) +{ + // not init + int32_t ret = NSTACKX_ScreenStatusChange(false); + ASSERT_EQ(ret, NSTACKX_EOK); +} + +TEST(Dfinder, TestNSTACKX_RegisterServiceData) +{ + // param is NULL + int32_t ret = NSTACKX_RegisterServiceData(NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + const char serviceData[] = "serviceData,serviceData,serviceData,serviceData,serviceData,serviceData,"; + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + // strlen(serviceData) >= NSTACKX_MAX_SERVICE_DATA_LEN + ret = NSTACKX_RegisterServiceData(serviceData); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + ret = NSTACKX_RegisterServiceData("data"); + ASSERT_EQ(ret, NSTACKX_EOK); + + (void)NSTACKX_ThreadInit(); + const char serviceData1[] = "serviceData"; + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_RegisterServiceData(serviceData1); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // strncpy_s is error + MOCKER(strncpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterServiceData(serviceData1); + ASSERT_EQ(ret, NSTACKX_EINVAL); + GlobalMockObject::verify(); + + + // all is ok + ret = NSTACKX_RegisterServiceData(serviceData1); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterServiceData(serviceData1); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_ThreadDeinit(); + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNNSTACKX_RegisterBusinessData) +{ + // param is NULL + int32_t ret = NSTACKX_RegisterBusinessData(NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // not init + const char businessData[] = "A"; + ret = NSTACKX_RegisterBusinessData(businessData); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + char businessData1[NSTACKX_MAX_BUSINESS_DATA_LEN + 1] = + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"\ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"\ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + // strlen(businessData) >= NSTACKX_MAX_BUSINESS_DATA_LEN + ret = NSTACKX_RegisterBusinessData(businessData1); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_RegisterBusinessData(businessData); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // strncpy_s is error + MOCKER(strncpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterBusinessData(businessData); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterBusinessData(businessData); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); +} + +TEST(Dfinder, TestNSTACKX_RegisterExtendServiceData) +{ + // param is NULL + int32_t ret = NSTACKX_RegisterExtendServiceData(NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + const char extendServiceData[] = "extendServiceData"; + + // not init + ret = NSTACKX_RegisterExtendServiceData(extendServiceData); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // strlen(extendServiceData) >= NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN + const char extendServiceData1[] = "extendServiceData,extendServiceData,extendServiceData,extendServiceData," + "extendServiceData,extendServiceData,extendServiceData,extendServiceData,"; + ret = NSTACKX_RegisterExtendServiceData(extendServiceData1); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_RegisterExtendServiceData(extendServiceData); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // strncpy_s is error + MOCKER(strncpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterExtendServiceData(extendServiceData); + ASSERT_EQ(ret, NSTACKX_EINVAL); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterExtendServiceData(extendServiceData); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_ThreadDeinit(); + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_SendMsgDirect) +{ + // not init + const char moduleName[] = ""; + const char deviceId[] = ""; + const uint8_t data[] = {0}; + const char ipaddr[] = ""; + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // ipaddr == NULL + int32_t ret = NSTACKX_SendMsgDirect(moduleName, deviceId, data, 1, NULL, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // type > SERVER_TYPE_USB + ret = NSTACKX_SendMsgDirect(moduleName, deviceId, data, 1, ipaddr, SERVER_TYPE_USB + 1); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // moduleName == NULL + ret = NSTACKX_SendMsgDirect(NULL, deviceId, data, 1, ipaddr, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // deviceId == NULL + ret = NSTACKX_SendMsgDirect(moduleName, NULL, data, 1, ipaddr, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // data == NULL + ret = NSTACKX_SendMsgDirect(moduleName, deviceId, NULL, 1, ipaddr, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // invalid ip addr + ret = NSTACKX_SendMsgDirect(moduleName, deviceId, data, 1, ipaddr, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // all is ok + MOCKER(inet_pton).stubs().will(returnValue(1)); // inet_pton is ok, == 1 + ret = NSTACKX_SendMsgDirect(moduleName, deviceId, data, 1, ipaddr, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EFAILED); + usleep(50000); // post event is async operation + GlobalMockObject::verify(); + + // SemInit is error + MOCKER(inet_pton).stubs().will(returnValue(1)); // inet_pton is ok, == 1 + MOCKER(SemInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendMsgDirect(moduleName, deviceId, data, 1, ipaddr, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(inet_pton).stubs().will(returnValue(1)); // inet_pton is ok, == 1 + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendMsgDirect(moduleName, deviceId, data, 1, ipaddr, SERVER_TYPE_WLANORETH); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + NSTACKX_ThreadDeinit(); + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_SendMsg) +{ + // not init + const char moduleName[] = ""; + const char deviceId[] = ""; + const uint8_t data[] = {0}; + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // moduleName == NULL + int32_t ret = NSTACKX_SendMsg(NULL, deviceId, data, 1); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // SemInit is error + MOCKER(SemInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendMsg(moduleName, deviceId, data, 1); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendMsg(moduleName, deviceId, data, 1); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // remoteIp == NULL + ret = NSTACKX_SendMsg(moduleName, deviceId, data, 1); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // remoteIp != NULL && inet_ntop != NULL + const struct in_addr remoteIp = {0}; + MOCKER(GetRemoteDeviceIp).stubs().will(returnValue(&remoteIp)); + ret = NSTACKX_SendMsg(moduleName, deviceId, data, 1); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // remoteIp != NULL && inet_ntop == NULL + MOCKER(GetRemoteDeviceIp).stubs().will(returnValue(&remoteIp)); + MOCKER(inet_ntop).stubs().will(returnValue((char const*)NULL)); + ret = NSTACKX_SendMsg(moduleName, deviceId, data, 1); + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); + + // all is ok + MOCKER(GetRemoteDeviceIp).stubs().will(returnValue(&remoteIp)); + MOCKER(CoapSendServiceMsg).stubs().will(returnValue(NSTACKX_EOK)); + ret = NSTACKX_SendMsg(moduleName, deviceId, data, 1); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + GlobalMockObject::verify(); + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); +} + +TEST(Dfinder, TestNSTACKX_SendDiscoveryRsp) +{ + NSTACKX_ResponseSettings settings = {0}; + // not init + int32_t ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // responseSettings == NULL + ret = NSTACKX_SendDiscoveryRsp(NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // (responseSettings->businessData == NULL) && (responseSettings->length != 0) + settings.businessData = NULL; + settings.length = NSTACKX_MAX_BUSINESS_DATA_LEN - 1; + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // responseSettings->length >= NSTACKX_MAX_BUSINESS_DATA_LEN + settings.businessData = (char *)"businessData"; + settings.length = NSTACKX_MAX_BUSINESS_DATA_LEN; + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + settings.length = NSTACKX_MAX_BUSINESS_DATA_LEN - 1; + + // calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_ENOMEM); + GlobalMockObject::verify(); + + // businessData != NULL && strncpy_s is error + MOCKER(strncpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + GlobalMockObject::verify(); + + // businessData == NULL && strncpy_s is error + settings.businessData = NULL; + settings.length = 0; + MOCKER(strncpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EINVAL); + settings.businessData = (char *)"businessData"; + settings.length = NSTACKX_MAX_BUSINESS_DATA_LEN - 1; + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // all is ok + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EOK); + // businessType != localBusinessType + settings.businessType = 2; + ret = NSTACKX_SendDiscoveryRsp(&settings); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); + // because PostEvent is async, so lastly execute GlobalMockObject::verify() + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestNSTACKX_GetDeviceList) +{ + // not init + NSTACKX_DeviceInfo deviceList = {0}; + uint32_t deviceCountPtr = 1; + int32_t ret = NSTACKX_GetDeviceList(&deviceList, &deviceCountPtr); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // deviceCountPtr == NULL + ret = NSTACKX_GetDeviceList(&deviceList, NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // SemInit is error + MOCKER(SemInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_GetDeviceList(&deviceList, &deviceCountPtr); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_GetDeviceList(&deviceList, &deviceCountPtr); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // all is ok + ret = NSTACKX_GetDeviceList(&deviceList, &deviceCountPtr); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(50000); // post event is async operation + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); +} + +TEST(Dfinder, TestNSTACKX_InitRestart) +{ + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + int32_t ret = NSTACKX_InitRestart(¶meter); + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); + NSTACKX_Deinit(); +} + +void DFinderLogCb(const char *moduleName, uint32_t logLevel, const char *format, ...) +{ + (void)logLevel; +} + +TEST(Dfinder, TestNSTACKX_DFinderRegisterLog) +{ + // userLogCallback == NULL + int32_t ret = NSTACKX_DFinderRegisterLog(NULL); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + // all is ok + ret = NSTACKX_DFinderRegisterLog(DFinderLogCb); + ASSERT_EQ(ret, NSTACKX_EOK); + + // logCb == g_nstackxLogCallBack + ret = NSTACKX_DFinderRegisterLog(DFinderLogCb); + ASSERT_EQ(ret, NSTACKX_EOK); +} + +void DFinderDumpFuncCb(void *softObj, const char *data, uint32_t len) +{ + (void)softObj; + (void)len; + printf("[%s][%d] %s\n", __FUNCTION__, __LINE__, data); +} +TEST(Dfinder, TestNSTACKX_DFinderDump) +{ + const char* argv = (const char*)"argv"; + uint32_t argc = 1; + int32_t softObj = 0; + // not init + int32_t ret = NSTACKX_DFinderDump((const char**)&argv, argc, (void *)&softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + + // dump == NULL + ret = NSTACKX_DFinderDump((const char**)&argv, argc, (void *)&softObj, NULL); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // argc > MAX_DUMP_ARGC + argc = 10 + 1; + ret = NSTACKX_DFinderDump((const char**)&argv, argc, (void *)&softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EINVAL); + argc = 1; + + // argv == NULL + ret = NSTACKX_DFinderDump(NULL, argc, (void *)&softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // argv[0] == NULL + char *argv1 = (char *)"argv1"; + (&argv1)[0] = NULL; + ret = NSTACKX_DFinderDump((const char**)&argv1, argc, (void *)&softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EINVAL); + + // all is ok + ret = NSTACKX_DFinderDump((const char**)&argv, argc, (void *)&softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EOK); + + NSTACKX_Deinit(); +} + +static void DFinderEventFunCb(void *softObj, const DFinderEvent *info) +{ + (void)info; +} +TEST(Dfinder, TestNSTACKX_DFinderSetEventFunc) +{ + int32_t softObj = 0; + // not init + int ret = NSTACKX_DFinderSetEventFunc((void *)&softObj, DFinderEventFunCb); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + MOCKER(SetEventFunc).stubs().will(returnValue(NSTACKX_EOK)); + ret = NSTACKX_DFinderSetEventFunc((void *)&softObj, DFinderEventFunCb); + ASSERT_EQ(ret, NSTACKX_EOK); + NSTACKX_Deinit(); + + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestGetServiceNotificationInfo) +{ + const char *buf = "{\"notify\":\"{\\\"UDID\\\":\\\"FE73EE0BA926F5A5B149B1567AD2D32BC5443A9FE05FE812CE62\\\"}\"}"; + NSTACKX_NotificationConfig config = {0}; + + // calloc fail + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + int32_t ret = GetServiceNotificationInfo((const uint8_t *)buf, strlen(buf), &config); + EXPECT_EQ(ret, NSTACKX_ENOMEM) << "case calloc fail"; + GlobalMockObject::verify(); + + // memcpy_s fail + MOCKER(memcpy_s).stubs().will(returnValue(EINVAL)); + ret = GetServiceNotificationInfo((const uint8_t *)buf, strlen(buf), &config); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case memcpy_s fail"; + GlobalMockObject::verify(); + + // ParseServiceNotification fail + MOCKER(ParseServiceNotification).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = GetServiceNotificationInfo((const uint8_t *)buf, strlen(buf), &config); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case ParseServiceNotification fail"; + GlobalMockObject::verify(); + + // all ok + MOCKER(ParseServiceNotification).stubs().will(returnValue(NSTACKX_EOK)); + ret = GetServiceNotificationInfo((const uint8_t *)buf, strlen(buf), &config); + EXPECT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestNotificationReceived) +{ + NSTACKX_Parameter param = {0}; + param.onNotificationReceived = DFinderOnNotificationReceived; + int32_t ret = NSTACKX_Init(¶m); + ASSERT_EQ(ret, NSTACKX_EOK) << "case NULL init fail"; + + // param NULL + NotificationReceived(NULL); + + // param not NULL + NSTACKX_NotificationConfig tmpConfig = {0}; + NotificationReceived(&tmpConfig); + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_StopSendNotification) +{ + uint8_t businessType = NSTACKX_BUSINESS_TYPE_NULL; + + // dfinder not inited + int32_t ret = NSTACKX_StopSendNotification(businessType); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case dfinder not inited fail"; + + NSTACKX_Parameter param = {0}; + param.onNotificationReceived = DFinderOnNotificationReceived; + ret = NSTACKX_Init(¶m); + ASSERT_EQ(ret, NSTACKX_EOK) << "init fail"; + + ret = NSTACKX_ThreadInit(); + ASSERT_EQ(ret, NSTACKX_EOK) << "threadinit fail"; + + // invalid business type + ret = NSTACKX_StopSendNotification(NSTACKX_BUSINESS_TYPE_MAX); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case invalid business type fail"; + + // PostEvent fail + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_StopSendNotification(businessType); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case PostEvent fail"; + GlobalMockObject::verify(); + + // ThreadInit + ret = NSTACKX_ThreadInit(); + ASSERT_EQ(ret, NSTACKX_EOK) << "thread init fail"; + + // all ok + ret = NSTACKX_StopSendNotification(businessType); + EXPECT_EQ(ret, NSTACKX_EOK) << "case all ok fail"; + GlobalMockObject::verify(); + + NSTACKX_Deinit(); + NSTACKX_ThreadDeinit(); +} + +TEST(Dfinder, TestNSTACKX_SendNotification) +{ + // dfinder not inited + int32_t ret = NSTACKX_SendNotification(NULL); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case dfinder not inited fail"; + + NSTACKX_Parameter param = {0}; + param.onNotificationReceived = DFinderOnNotificationReceived; + ret = NSTACKX_Init(¶m); + ASSERT_EQ(ret, NSTACKX_EOK) << "init fail"; + + ret = NSTACKX_ThreadInit(); + ASSERT_EQ(ret, NSTACKX_EOK) << "thread init fail"; + + // config NULL + ret = NSTACKX_SendNotification(NULL); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case config NULL fail"; + + // invalid business type + NSTACKX_NotificationConfig config = {0}; + config.businessType = NSTACKX_BUSINESS_TYPE_MAX; + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case invalid business type fail"; + + // msg NULL + config.businessType = NSTACKX_BUSINESS_TYPE_NULL; + config.msg = NULL; + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case msg NULL fail"; + + // invalid msg len + std::string tmpMsg("hello"); + config.msg = const_cast(tmpMsg.c_str()); + config.msgLen = 0; + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case invalid msg len fail"; + + // invalid interval len + config.intervalLen = 0; + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case invalid interval len fail"; + + // interval ms NULL + config.intervalLen = 3; + config.intervalsMs = NULL; + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case interval ms fail"; + + // first interval not zero + uint16_t intervalFirstNotZero[] = {100, 200, 300}; + config.intervalsMs = intervalFirstNotZero; + config.intervalLen = 3; + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case first interval not zero fail"; + + // interval too big + uint16_t intervalTooBig[] = {0, NSTACKX_MAX_ADVERTISE_INTERVAL + 1}; + config.intervalsMs = intervalTooBig; + config.intervalLen = 2; + ret = NSTACKX_SendNotification(&config); + EXPECT_EQ(ret, NSTACKX_EINVAL) << "case interval too big fail"; + + std::string legalMsg("auv"); + uint16_t legalInterval[] = {0, 200, 200}; + NSTACKX_NotificationConfig legalConfig = { + msg : const_cast(legalMsg.c_str()), + msgLen : 3, + intervalsMs : legalInterval, + intervalLen : 3, + businessType : NSTACKX_BUSINESS_TYPE_NULL + }; + + // calloc fail + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = NSTACKX_SendNotification(&legalConfig); + EXPECT_EQ(ret, NSTACKX_ENOMEM) << "case calloc fail"; + GlobalMockObject::verify(); + + // PostEvent fail + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_SendNotification(&legalConfig); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case PostEvent fail"; + GlobalMockObject::verify(); + + // all ok + ret = NSTACKX_SendNotification(&legalConfig); + EXPECT_EQ(ret, NSTACKX_EOK) << "case all ok fail"; + + NSTACKX_Deinit(); +} + +TEST(Dfinder, TestNSTACKX_RegisterServiceDataV2) +{ + NSTACKX_ServiceData testData = {0}; + strcpy_s(testData.ip, sizeof(testData.ip), "127.0.0.1"); + strcpy_s(testData.serviceData, sizeof(testData.serviceData), "testdata"); + const struct NSTACKX_ServiceData *param = &testData; + + // not inited + int32_t ret = NSTACKX_RegisterServiceDataV2(param, 1); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case dfinder not inited fail"; + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // SemInit is error + MOCKER(SemInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterServiceDataV2(param, 1); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent fail + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterServiceDataV2(param, 1); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case PostEvent fail"; + GlobalMockObject::verify(); + + NSTACKX_Deinit(); +} + + +TEST(Dfinder, TestNSTACKX_RegisterDeviceHash) +{ + // dfinder not inited + int32_t ret = NSTACKX_RegisterDeviceHash(0); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case dfinder not inited fail"; + + NSTACKX_Parameter parameter; + parameter.onDFinderMsgReceived = DFinderMsgReceived; + (void)NSTACKX_Init(¶meter); + (void)NSTACKX_ThreadInit(); + + // PostEvent fail + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = NSTACKX_RegisterDeviceHash(0); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case PostEvent fail"; + GlobalMockObject::verify(); + + NSTACKX_Deinit(); +} diff --git a/test/unittest/dfinder_gtest/nstackx_device_local_ut.cpp b/test/unittest/dfinder_gtest/nstackx_device_local_ut.cpp new file mode 100644 index 0000000..ddb6943 --- /dev/null +++ b/test/unittest/dfinder_gtest/nstackx_device_local_ut.cpp @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "nstackx_device_local.h" +#include "nstackx_device_remote.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" +#include "ut_utils.h" + +TEST(Dfinder, TestLocalDeviceInit) +{ + EpollDesc epollDesc = CreateEpollDesc(); + + // g_localDevice.timer == NULL + MOCKER(TimerStart).stubs().will(returnValue((Timer *)NULL)); + int ret = LocalDeviceInit(epollDesc); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // all is ok + ret = LocalDeviceInit(epollDesc); + ASSERT_EQ(ret, NSTACKX_EOK); + + LocalDeviceDeinit(); +} + +static Timer *g_timer; +static Timer *InvokeTimerStart(EpollDesc epollfd, uint32_t ms, uint8_t repeated, TimeoutHandle handle, void *data) +{ + handle(data); + g_timer = (Timer *)malloc(1*sizeof(Timer)); + return g_timer; +} + +class Dfinder : public testing::Test { +public: + void SetUp() + { + Dfinderinit(); + } + void TearDown() + { + DfinderDestroy(); + } +}; + +TEST(Dfinder, TestAddLocalIface) +{ + (void)LocalDeviceInit(CreateEpollDesc()); + + // iface->ctx == NULL + union InetAddr addr; + union InetAddr addr1; + struct in_addr ipv4Addr; + struct in_addr ipv4Addr1; + inet_pton(AF_INET, "127.0.0.1", &ipv4Addr); + addr.in = ipv4Addr; + char serviceData[NSTACKX_MAX_SERVICE_DATA_LEN] = "data"; + int ret = AddLocalIface("eth0", serviceData, AF_INET, &addr); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + CoapCtxType *ctx = (CoapCtxType *)malloc(1 * sizeof(CoapCtxType)); + ctx->ctx = CreateCoapContext(); + MOCKER(CoapServerInit).stubs().will(returnValue(ctx)); + + ret = AddLocalIface("eth", serviceData, AF_INET, &addr); // eth 127.0.0.1 添加到g_localDevice.readyList里 + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = AddLocalIface("wlan", serviceData, AF_INET, &addr); /** wlan 127.0.0.1 添加到g_localDevice.readyList里 */ + ASSERT_EQ(ret, NSTACKX_EOK); + + // iface == NULL and then iface != NULL + RemoveLocalIface(AF_INET, "eth"); // // eth 127.0.0.1 添加到g_localDevice.destroyList里 + ret = AddLocalIface("eth", serviceData, AF_INET, &addr); // eth 127.0.0.1 添加到g_localDevice.readyList里 + ASSERT_EQ(ret, NSTACKX_EOK); + + // ip.s_addr == ip->s_addr + ret = AddLocalIface("eth", serviceData, AF_INET, &addr); // 没有添加到任何list里 + ASSERT_EQ(ret, NSTACKX_EOK); + + // ip.s_addr != ip->s_addr + inet_pton(AF_INET, "127.0.0.2", &ipv4Addr1); + addr1.in = ipv4Addr1; + ret = AddLocalIface("eth", serviceData, AF_INET, &addr1); /** eth 127.0.0.2 添加到g_localDevice.destroyList里 */ + ASSERT_EQ(ret, NSTACKX_EOK); + + // inet_ntop(AF_INET, ip, ipStr, sizeof(ipStr)) == NULL + MOCKER(inet_ntop).stubs().will(returnValue((char const*)NULL)); + ret = AddLocalIface("eth", serviceData, AF_INET, &addr); /** eth 127.0.0.1 添加到g_localDevice.destroyList里 */ + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // !NeedCreateSynchronously(iface->type), 即GetIfaceType >= IFACE_TYPE_P2P + MOCKER(GetIfaceType).stubs().will(returnValue(2)); + ret = AddLocalIface("p2p", serviceData, AF_INET, &addr); // 没有添加到任何list里 + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // !NeedCreateSynchronously(iface->type), 即GetIfaceType >= IFACE_TYPE_P2P + MOCKER(TimerStart).stubs().will(invoke(InvokeTimerStart)); + ret = AddLocalIface("p2p", serviceData, AF_INET, &addr);/** p2p 127.0.0.1 添加到g_localDevice.creatingList里 */ + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); + + free(g_timer); + FreeCoapContext(ctx->ctx); + free(ctx); +} + +TEST(Dfinder, TestLocalIfaceDump) +{ + char buf[2048]; + // 与TestAddLocalIface方法挂钩,遍历g_localDevice3个列表:creatingList、readyList、destroyList + int ret = LocalIfaceDump(buf, 2048); + ASSERT_EQ(ret, 181); +} + +TEST(Dfinder, TestLocalIfaceGetCoapCtx) +{ + // 与TestAddLocalIface方法挂钩,遍历g_localDevice.readyList列表 + CoapCtxType *coapCtxType = LocalIfaceGetCoapCtx(AF_INET, "eth"); + ASSERT_EQ(coapCtxType, nullptr); +} + +bool mHasLocalIface = true; +int32_t InvokeGetTargetInterface(const struct sockaddr_in *dstAddr, struct ifreq *localDev) +{ + // 与TestAddLocalIface方法挂钩,LocalIfaceGetCoapCtxByRemoteIp会从g_localDevice.readyList里查找 + if (mHasLocalIface) { + (void)strcpy_s(localDev->ifr_ifrn.ifrn_name, IFNAMSIZ, "wlan"); + } else { + (void)strcpy_s(localDev->ifr_ifrn.ifrn_name, IFNAMSIZ, "eth"); + } + return NSTACKX_EOK; +} +TEST(Dfinder, TestLocalIfaceGetCoapCtxByRemoteIp) +{ + char ipStr[INET_ADDRSTRLEN] = "127.0.0.1"; // host:port + struct in_addr remoteIp; + inet_pton(AF_INET, ipStr, &remoteIp); + + // GetTargetInterface != NSTACKX_EOK + CoapCtxType *coapCtxType = LocalIfaceGetCoapCtxByRemoteIp(&remoteIp, SERVER_TYPE_WLANORETH); + ASSERT_EQ(coapCtxType, nullptr); + + // all is ok + MOCKER(GetTargetInterface).stubs().will(invoke(InvokeGetTargetInterface)); + coapCtxType = LocalIfaceGetCoapCtxByRemoteIp(&remoteIp, SERVER_TYPE_WLANORETH); + ASSERT_NE(coapCtxType, nullptr); + + // !IfaceTypeIsMatch + coapCtxType = LocalIfaceGetCoapCtxByRemoteIp(&remoteIp, SERVER_TYPE_USB + 1); + ASSERT_EQ(coapCtxType, nullptr); + + // iface == NULL + mHasLocalIface = false; + MOCKER(GetTargetInterface).stubs().will(invoke(InvokeGetTargetInterface)); + coapCtxType = LocalIfaceGetCoapCtxByRemoteIp(&remoteIp, SERVER_TYPE_WLANORETH); + ASSERT_EQ(coapCtxType, nullptr); + GlobalMockObject::verify(); +} + +uint8_t mBusinessType = 10; +const char mDeviceId[] = "deviceId"; +char mNetworkName[NSTACKX_MAX_INTERFACE_NAME_LEN] = "eth"; +TEST(Dfinder, TestRegisterLocalDeviceV2) +{ + NSTACKX_LocalDeviceInfoV2 devInfo = {0}; + // strcpy_s(devInfo->deviceId) != EOK + int ret = RegisterLocalDeviceV2(&devInfo, REGISTER_TYPE_UPDATE_ALL); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + // name[0] == '\0' + devInfo.deviceId = mDeviceId; + devInfo.name = ""; + ret = RegisterLocalDeviceV2(&devInfo, REGISTER_TYPE_UPDATE_ALL); + ASSERT_EQ(ret, NSTACKX_EOK); + + devInfo.name = "name"; + devInfo.ifNums = 1; + devInfo.hasDeviceHash = true; + devInfo.deviceHash = 1; + devInfo.businessType = mBusinessType; + NSTACKX_InterfaceInfo info = {0}; + devInfo.localIfInfo = &info; + + // ifInfo->networkName[0] == '\0' + (void)strcpy_s(info.networkName, NSTACKX_MAX_INTERFACE_NAME_LEN, ""); + ret = RegisterLocalDeviceV2(&devInfo, REGISTER_TYPE_UPDATE_ALL); + ASSERT_EQ(ret, NSTACKX_EOK); + + // inet_pton(AF_INET, ifInfo[i].networkIpAddr, &ip) != 1 + (void)strcpy_s(info.networkName, NSTACKX_MAX_INTERFACE_NAME_LEN, mNetworkName); + (void)strcpy_s(info.networkIpAddr, NSTACKX_MAX_IP_STRING_LEN, "127"); + ret = RegisterLocalDeviceV2(&devInfo, REGISTER_TYPE_UPDATE_ALL); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + // ip.s_addr == 0 + (void)strcpy_s(info.networkIpAddr, NSTACKX_MAX_IP_STRING_LEN, "0.0.0.0"); + ret = RegisterLocalDeviceV2(&devInfo, REGISTER_TYPE_UPDATE_ALL); + ASSERT_EQ(ret, NSTACKX_EOK); + + // all is ok + (void)strcpy_s(info.networkName, NSTACKX_MAX_INTERFACE_NAME_LEN, mNetworkName); + (void)strcpy_s(info.networkIpAddr, NSTACKX_MAX_IP_STRING_LEN, "127.0.0.1"); + ret = RegisterLocalDeviceV2(&devInfo, REGISTER_TYPE_UPDATE_ALL); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = RegisterLocalDeviceV2(&devInfo, REGISTER_TYPE_UPDATE_SPECIFIED); + ASSERT_EQ(ret, NSTACKX_EOK); +} + +TEST(Dfinder, TestGetLocalDeviceBusinessType) +{ + uint8_t ret = GetLocalDeviceBusinessType(); + ASSERT_EQ(ret, mBusinessType); +} + +TEST(Dfinder, TestGetLocalDeviceId) +{ + const char *ret = GetLocalDeviceId(); + ASSERT_EQ(*ret, *mDeviceId); +} + +TEST(Dfinder, TestGetLocalDeviceInfo) +{ + DeviceInfo *deviceInfo = GetLocalDeviceInfo(); + ASSERT_EQ(*(deviceInfo->deviceId), *mDeviceId); +} + +TEST(Dfinder, TestSetLocalDeviceCapability) +{ + // all is ok + uint32_t bitmapNum=1; + uint32_t bitmap[]={0}; + int ret = SetLocalDeviceCapability(bitmapNum, bitmap); + ASSERT_EQ(ret, NSTACKX_EOK); + + // memcpy_s is error + MOCKER(memcpy_s).stubs().will(returnValue(-1)); + ret = SetLocalDeviceCapability(bitmapNum, bitmap); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestSetLocalDeviceServiceData) +{ + // all is ok + int32_t ret = SetLocalDeviceServiceData("serviceData"); + ASSERT_EQ(ret, NSTACKX_EOK); + + // strcpy_s is error + MOCKER(strcpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = SetLocalDeviceServiceData("serviceData"); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestSetLocalDeviceBusinessData) +{ + // all is ok + int ret = SetLocalDeviceBusinessData("data", false); + ASSERT_EQ(ret, NSTACKX_EOK); + + // strcpy_s is error + MOCKER(strcpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = SetLocalDeviceBusinessData("data", true); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestLocalDeviceMode) +{ + uint8_t mode = 1; + SetLocalDeviceMode(mode); + uint8_t ret = GetLocalDeviceMode(); + ASSERT_EQ(ret, mode); +} + +TEST(Dfinder, TestSetLocalDeviceExtendServiceData) +{ + // all is ok + int32_t ret = SetLocalDeviceExtendServiceData("extendServiceData"); + ASSERT_EQ(ret, NSTACKX_EOK); + + // strcpy_s is error + MOCKER(strcpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = SetLocalDeviceExtendServiceData("extendServiceData"); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestGetLocalIfaceIpStr) +{ + LocalIface *localIface = CreateLocalIface(); + const char *ipStr = GetLocalIfaceIpStr(localIface); + ASSERT_EQ(localIface->ipStr, ipStr); + + FreeLocalIface(localIface); +} + +TEST(Dfinder, TestGetLocalIfaceName) +{ + LocalIface *localIface = CreateLocalIface(); + const char *name = GetLocalIfaceName(localIface); + ASSERT_EQ(*localIface->ifname, *name); + + FreeLocalIface(localIface); +} + +void InvokeDestroyRxIfaceByIfname(const char *ifName) +{ + return; +} + +void InvokeCoapServerDestroy(CoapCtxType *ctx, bool moduleDeinit) +{ + return; +} + +TEST(Dfinder, TestLocalizeNotificationMsg) +{ + const char *msg = "auv"; + + // strcpy_s fail + MOCKER(strcpy_s).stubs().will(returnValue(EINVAL)); + int32_t ret = LocalizeNotificationMsg(msg); + EXPECT_EQ(ret, NSTACKX_EFAILED) << "case strcpy_s fail"; + GlobalMockObject::verify(); + + // all ok + MOCKER(strcpy_s).stubs().will(returnValue(EOK)); + ret = LocalizeNotificationMsg(msg); + EXPECT_EQ(ret, NSTACKX_EOK) << "case all ok fail"; + GlobalMockObject::verify(); +} diff --git a/test/unittest/dfinder_gtest/nstackx_device_remote_ut.cpp b/test/unittest/dfinder_gtest/nstackx_device_remote_ut.cpp new file mode 100644 index 0000000..f2aeedc --- /dev/null +++ b/test/unittest/dfinder_gtest/nstackx_device_remote_ut.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "nstackx_device_remote.h" +#include "nstackx_error.h" +#include "nstackx_timer.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" + +class Dfinder : public testing::Test { +public: + void SetUp() + { + Dfinderinit(); + } + void TearDown() + { + DfinderDestroy(); + } +}; + +TEST(Dfinder, TestRemoteDeviceListInit) +{ + // all is ok + int32_t ret = RemoteDeviceListInit(); + ASSERT_EQ(ret, NSTACKX_EOK); +} + +TEST(Dfinder, TestGetRemoteNodeCount) +{ + uint32_t count = GetRemoteNodeCount(); + ASSERT_EQ(count, 0); +} + +TEST(Dfinder, TestUpdateRemoteNodeByDeviceInfo) +{ + NSTACKX_InterfaceInfo ifaceInfo = {0}; + strcpy_s(ifaceInfo.networkName, sizeof(ifaceInfo.networkName), "eth"); + strcpy_s(ifaceInfo.networkIpAddr, sizeof(ifaceInfo.networkIpAddr), "127.0.0.1"); + + NSTACKX_InterfaceInfo ifaceInfo1 = {0}; + strcpy_s(ifaceInfo1.networkName, sizeof(ifaceInfo1.networkName), "eth"); + strcpy_s(ifaceInfo1.networkIpAddr, sizeof(ifaceInfo1.networkIpAddr), "127.0.0.2"); + + NSTACKX_InterfaceInfo ifaceInfo2 = {0}; + strcpy_s(ifaceInfo2.networkName, sizeof(ifaceInfo2.networkName), "eth"); + strcpy_s(ifaceInfo2.networkIpAddr, sizeof(ifaceInfo2.networkIpAddr), "127.0.0.3"); + + NSTACKX_InterfaceInfo ifaceInfo3 = {0}; + strcpy_s(ifaceInfo3.networkName, sizeof(ifaceInfo3.networkName), "eth"); + strcpy_s(ifaceInfo3.networkIpAddr, sizeof(ifaceInfo3.networkIpAddr), "127.0.0.4"); + + NSTACKX_InterfaceInfo ifaceInfo4 = {0}; + strcpy_s(ifaceInfo4.networkName, sizeof(ifaceInfo4.networkName), "eth"); + strcpy_s(ifaceInfo4.networkIpAddr, sizeof(ifaceInfo4.networkIpAddr), "127.0.0.5"); + + BusinessDataAll businessData = { 0 }; + businessData.isBroadcast = NSTACKX_FALSE; + strcpy_s(businessData.businessDataBroadcast, sizeof(businessData.businessDataBroadcast), "Broadcast"); + strcpy_s(businessData.businessDataUnicast, sizeof(businessData.businessDataUnicast), "Unicast"); + DeviceInfo deviceInfo = { 0 }; + + deviceInfo.businessData = businessData; + deviceInfo.netChannelInfo.wifiApInfo.af = AF_INET; + deviceInfo.deviceType = NSTACKX_DISCOVERY_TYPE_PASSIVE; + deviceInfo.capabilityBitmapNum = 1; + uint8_t updated = NSTACKX_FALSE; + + // CreateRemoteDevice == NULL, (1)calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + int32_t ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // CreateRemoteDevice == NULL, (2)strcpy_s is error + MOCKER(strcpy_s).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // g_remoteNodeCount == GetMaxDeviceNum() && CheckAndRemoveAgingNode() != NSTACKX_EOK + MOCKER(GetMaxDeviceNum).stubs().will(returnValue(GetRemoteNodeCount())); + SetDeviceListAgingTime(2); + MOCKER(GetTimeDiffMs).stubs().will(returnValue(1001)); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // all is ok, add list node + SetDeviceListAgingTime(1); + SetMaxDeviceNum(10); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + usleep(2000); + + // UpdateRemoteNode, isBroadcast == NSTACKX_TRUE + BusinessDataAll businessData1 = {0}; + businessData1.isBroadcast = NSTACKX_TRUE; + strcpy_s(businessData1.businessDataBroadcast, sizeof(businessData1.businessDataBroadcast), "Broadcast1"); + strcpy_s(businessData1.businessDataUnicast, sizeof(businessData1.businessDataUnicast), "Unicast1"); + DeviceInfo deviceInfo1 = {0}; + strcpy_s(deviceInfo1.deviceId, sizeof(deviceInfo1.deviceId), "deviceId"); + deviceInfo.netChannelInfo.wifiApInfo.af = AF_INET; + deviceInfo.netChannelInfo.wifiApInfo.addr.in.s_addr = 778; + deviceInfo1.businessData = businessData1; + deviceInfo1.deviceType = NSTACKX_DISCOVERY_TYPE_PASSIVE; + deviceInfo1.netChannelInfo.wifiApInfo.af = AF_INET; + deviceInfo1.capabilityBitmapNum = 1; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo1, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, isBroadcast != NSTACKX_TRUE + BusinessDataAll businessData2 = { 0 }; + businessData2.isBroadcast = NSTACKX_FALSE; + strcpy_s(businessData2.businessDataBroadcast, sizeof(businessData2.businessDataBroadcast), "Broadcast2"); + strcpy_s(businessData2.businessDataUnicast, sizeof(businessData2.businessDataUnicast), "Unicast2"); + DeviceInfo deviceInfo2 = { 0 }; + strcpy_s(deviceInfo2.deviceId, sizeof(deviceInfo2.deviceId), "deviceId"); + deviceInfo2.deviceType = NSTACKX_DISCOVERY_TYPE_PASSIVE; + deviceInfo2.businessData = businessData2; + deviceInfo2.netChannelInfo.wifiApInfo.af = AF_INET; + deviceInfo2.capabilityBitmapNum = 1; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo2, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, businessType != newInfo->businessType + deviceInfo.businessType = 1; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, serviceData != newInfo->serviceData + strcpy_s(deviceInfo.serviceData, sizeof(deviceInfo.serviceData), "serviceData"); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, mode != newInfo->mode + deviceInfo.mode = 1; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, deviceHash != newInfo->deviceHash + strcpy_s(deviceInfo.deviceHash, sizeof(deviceInfo.deviceHash), "deviceHash"); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, capabilityBitmapNum > 0 + deviceInfo.capabilityBitmapNum = 1; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, capabilityBitmapNum > 0, memcpy_s is error + MOCKER(memcpy_s).stubs().will(returnValue(-1)); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // UpdateRemoteNode, deviceName != newInfo->deviceName + strcpy_s(deviceInfo.deviceName, sizeof(deviceInfo.deviceName), "deviceName"); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // CheckAndUpdateRemoteNodeChangeState, discoveryType == NSTACKX_DISCOVERY_TYPE_PASSIVE + deviceInfo.discoveryType = NSTACKX_DISCOVERY_TYPE_PASSIVE; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // UpdateRemoteNode, deviceType != newInfo->deviceType + deviceInfo.deviceType = NSTACKX_DISCOVERY_TYPE_ACTIVE; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + // rxIface->remoteNodeCnt >= RX_IFACE_REMOTE_NODE_COUNT, 调用5次UpdateRemoteNodeByDeviceInfo,每次传的remoteIp不同 + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + deviceInfo.deviceType = NSTACKX_DISCOVERY_TYPE_PASSIVE; + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo1, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo2, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo3, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo4, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + // insert node into list + /** eth */ + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo1, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo2, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + /** wlan */ + NSTACKX_InterfaceInfo ifaceInfo5 = {0}; + strcpy_s(ifaceInfo5.networkName, sizeof(ifaceInfo5.networkName), "wlan"); + strcpy_s(ifaceInfo5.networkIpAddr, sizeof(ifaceInfo5.networkIpAddr), "127.0.0.1"); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo5, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); + + NSTACKX_InterfaceInfo ifaceInfo6 = {0}; + strcpy_s(ifaceInfo6.networkName, sizeof(ifaceInfo6.networkName), "wlan"); + strcpy_s(ifaceInfo6.networkIpAddr, sizeof(ifaceInfo6.networkIpAddr), "127.0.0.2"); + ret = UpdateRemoteNodeByDeviceInfo("deviceId", &ifaceInfo, &deviceInfo, &updated); + ASSERT_EQ(ret, NSTACKX_EOK); +} + +TEST(Dfinder, TestGetRemoteDeviceIp) +{ + const struct in_addr *remoteIp = GetRemoteDeviceIp("deviceId"); + ASSERT_NE(remoteIp, nullptr); + + remoteIp = GetRemoteDeviceIp("deviceId1"); + ASSERT_EQ(remoteIp, nullptr); +} + +TEST(Dfinder, TestDumpRemoteDevice) +{ + char buf[2048]; + (void)memset_s(buf, 2048, 0, 2048); + int32_t ret = DumpRemoteDevice(buf, 2048); + ASSERT_EQ(ret, 571); + ret = DumpRemoteDevice(buf, 0); + ASSERT_EQ(ret, NSTACKX_EFAILED); +} diff --git a/test/unittest/dfinder_gtest/nstackx_dfinder_hidump_ut.cpp b/test/unittest/dfinder_gtest/nstackx_dfinder_hidump_ut.cpp new file mode 100644 index 0000000..b077375 --- /dev/null +++ b/test/unittest/dfinder_gtest/nstackx_dfinder_hidump_ut.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "nstackx_dfinder_hidump.h" +#include "nstackx_util.h" +#include "nstackx_getopt.h" +#include "nstackx_event.h" +#include "nstackx_device_local.h" +#include "nstackx_device_remote.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" +#include "ut_utils.h" + +class Dfinder : public testing::Test { +public: + void SetUp() + { + Dfinderinit(); + } + void TearDown() + { + DfinderDestroy(); + } +}; + +TEST(Dfinder, TestDumpDeviceInfo) +{ + DeviceInfo deviceInfo = {0}; + (void)strcpy_s(deviceInfo.deviceId, NSTACKX_MAX_DEVICE_ID_LEN, "deviceId"); + char buf[2048]; + + // all is ok + int ret = DumpDeviceInfo(&deviceInfo, buf, 2048, 1); + ASSERT_EQ(ret, 99); + + // memcpy_s is error + MOCKER(memcpy_s).stubs().will(returnValue(-1)); + ret = DumpDeviceInfo(&deviceInfo, buf, 2048, 1); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestDFinderDumpIface) +{ + char buf[2048]; + char ifname[] = "eth"; + LocalIface *localIface = CreateLocalIface(); + union InetAddr ipAddr; + ipAddr.in = localIface->addr.in; + struct DumpIfaceInfo info = { + .ifname = "eth", + .state = 1, + .af = AF_INET, + .addr = &ipAddr + }; + + + // all is ok + int ret = DFinderDumpIface(&info, buf, sizeof(buf)); + ASSERT_GT(ret, 0); + + // IpAddrAnonymousFormat < 0 + MOCKER(IpAddrAnonymousFormat).stubs().will(returnValue(-10)); + ret = DFinderDumpIface(&info, buf, sizeof(buf)); + ASSERT_EQ(ret, -10); + GlobalMockObject::verify(); + + // Test IPv6 + union InetAddr ipv6Addr; + ipv6Addr.in6 = in6addr_any; + struct DumpIfaceInfo ipv6Info = { + .ifname = "eth6", + .state = 1, + .af = AF_INET6, + .addr = &ipv6Addr + }; + ret = DFinderDumpIface(&ipv6Info, buf, sizeof(buf)); + ASSERT_NE(ret, NSTACKX_EFAILED); + + FreeLocalIface(localIface); +} + +static void DFinderDumpFuncCb(void *softObj, const char *data, uint32_t len) +{ + (void)softObj; + (void)len; +} +int32_t InvokePostEvent(const List *eventNodeChain, EpollDesc epollfd, EventHandle handle, void *arg) +{ + handle(arg); + return NSTACKX_EOK; +} +TEST(Dfinder, TestDFinderDump) +{ + const char *argv[] = {"", "-f", "-h", "-l", "-r", "-s", "-m", "0", ""}; + char softObj[2048]; + + MOCKER(PostEvent).stubs().will(invoke(InvokePostEvent)); + MOCKER(LocalIfaceDump).stubs().will(returnValue(NSTACKX_EOK)); + MOCKER(DumpRemoteDevice).stubs().will(returnValue(NSTACKX_EOK)); + + // EnableMgtMsgLog enable == 0 + int ret = DFinderDump(argv, sizeof(argv)/sizeof(argv[0]), (void *)softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EOK); + + // EnableMgtMsgLog enable == 1 + const char *argv1[] = {"", "-f", "-h", "-l", "-r", "-s", "-m", "1", ""}; + ret = DFinderDump(argv1, sizeof(argv1)/sizeof(argv1[0]), (void *)softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EOK); + + // EnableMgtMsgLog strlen(optMsg) != 1 + const char *argv2[] = {"", "-f", "-h", "-l", "-r", "-s", "-m", ""}; + ret = DFinderDump(argv2, sizeof(argv2)/sizeof(argv2[0]), (void *)softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EFAILED); + + // NstackGetOpt is default + MOCKER(NstackGetOpt).stubs().will(returnValue(0)); + ret = DFinderDump(argv, sizeof(argv)/sizeof(argv[0]), (void *)softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // CreateDumpMsg == NULL, that is SemInit error + MOCKER(SemInit).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = DFinderDump(argv, sizeof(argv)/sizeof(argv[0]), (void *)softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // PostEvent is error + MOCKER(PostEvent).stubs().will(returnValue(NSTACKX_EFAILED)); + ret = DFinderDump(argv, sizeof(argv)/sizeof(argv[0]), (void *)softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EFAILED); + GlobalMockObject::verify(); + + // argc = 1 + ret = DFinderDump(nullptr, 1, (void *)&softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EOK); + + // argc = 1 and calloc is error + MOCKER(calloc).stubs().will(returnValue((void *)NULL)); + ret = DFinderDump(nullptr, 1, (void *)&softObj, DFinderDumpFuncCb); + ASSERT_EQ(ret, NSTACKX_EOK); + GlobalMockObject::verify(); +} \ No newline at end of file diff --git a/test/unittest/dfinder_gtest/nstackx_dfinder_hievent_ut.cpp b/test/unittest/dfinder_gtest/nstackx_dfinder_hievent_ut.cpp new file mode 100644 index 0000000..a5087dc --- /dev/null +++ b/test/unittest/dfinder_gtest/nstackx_dfinder_hievent_ut.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * 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 "nstackx_dfinder_hievent.h" +#include "nstackx_getopt.h" +#include "nstackx_event.h" + +#include "gtest/gtest.h" +#include "mockcpp/mokc.h" + +static int g_eventCnt = 0; +static void TestDFinderEventFuncCb(void *softObj, const DFinderEvent *info) +{ + (void)softObj; + (void)info; + g_eventCnt++; +} + +static int32_t InvokePostEvent(const List *eventNodeChain, + EpollDesc epollfd, EventHandle handle, void *arg) +{ + handle(arg); + return 0; +} + +class Dfinder : public testing::Test { +public: + void SetUp() + { + Dfinderinit(); + } + void TearDown() + { + DfinderDestroy(); + } +}; + +TEST(Dfinder, TestSetEventFunc) +{ + MOCKER(PostEvent).stubs().will(invoke(InvokePostEvent)); + ASSERT_EQ(SetEventFunc(NULL, TestDFinderEventFuncCb), 0); + ASSERT_EQ(SetEventFunc(NULL, NULL), 0); + GlobalMockObject::verify(); + + MOCKER(PostEvent).stubs().will(returnValue(-1)); + ASSERT_NE(SetEventFunc(NULL, TestDFinderEventFuncCb), 0); + GlobalMockObject::verify(); +} + +TEST(Dfinder, TestNotifyStatisticsEvent) +{ + MOCKER(PostEvent).stubs().will(invoke(InvokePostEvent)); + NotifyStatisticsEvent(); + ASSERT_EQ(g_eventCnt, 0); + ASSERT_EQ(SetEventFunc(NULL, TestDFinderEventFuncCb), 0); + GlobalMockObject::verify(); + NotifyStatisticsEvent(); + ASSERT_EQ(g_eventCnt, 1); + ResetEventFunc(); + NotifyStatisticsEvent(); + ASSERT_EQ(g_eventCnt, 1); +} diff --git a/test/unittest/dfinder_gtest/util/ut_utils.cpp b/test/unittest/dfinder_gtest/util/ut_utils.cpp new file mode 100644 index 0000000..19097ba --- /dev/null +++ b/test/unittest/dfinder_gtest/util/ut_utils.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "ut_utils.h" + +LocalIface *CreateLocalIface() +{ + struct LocalIface *iface = (struct LocalIface *)calloc(1, sizeof(struct LocalIface)); + strcpy_s(iface->ifname, sizeof(iface->ifname), "eth"); + strcpy_s(iface->ipStr, sizeof(iface->ipStr), "127.0.0.1"); + iface->type = IFACE_TYPE_ETH; + return iface; +} + +void FreeLocalIface(LocalIface *localInterface) +{ + free(localInterface); +} + +coap_context_t *CreateCoapContext() +{ + return coap_new_context(NULL); +} + +void FreeCoapContext(coap_context_t *context) +{ + coap_free_context(context); +} + +CoapCtxType *CreateCoapCtxType() +{ + CoapCtxType *ctx = (CoapCtxType *)malloc(1 * sizeof(CoapCtxType)); + ctx->ctx = CreateCoapContext(); + ctx->iface = (void *)CreateLocalIface(); + return ctx; +} + +void FreeCoapCtxType(CoapCtxType *coapCtxType) +{ + if (coapCtxType != NULL) { + FreeCoapContext(coapCtxType->ctx); + FreeLocalIface((LocalIface *)coapCtxType->iface); + } + free(coapCtxType); +} + +CoapCtxType *InsertDevice(void) +{ + CoapCtxType *ctx = CreateCoapCtxType(); + List *list = GetCoapContextList(); + ListInsertTail(list, &ctx->node); + return ctx; +} + +void RemoveDevice(CoapCtxType *ctx) +{ + ListRemoveNode(&ctx->node); + FreeCoapCtxType(ctx); +} \ No newline at end of file diff --git a/test/unittest/dfinder_gtest/util/ut_utils.h b/test/unittest/dfinder_gtest/util/ut_utils.h new file mode 100644 index 0000000..8f69d7f --- /dev/null +++ b/test/unittest/dfinder_gtest/util/ut_utils.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 UT_UTILS_H +#define UT_UTILS_H + +#include "nstackx_timer.h" +#include "nstackx_device.h" +#include "nstackx_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct LocalIface { + List node; + + uint8_t type; + uint8_t state; + uint8_t createCount; + uint8_t af; + char ifname[NSTACKX_MAX_INTERFACE_NAME_LEN]; + char ipStr[NSTACKX_MAX_IP_STRING_LEN]; + union InetAddr addr; + char serviceData[NSTACKX_MAX_SERVICE_DATA_LEN]; + struct timespec updateTime; + + Timer *timer; + CoapCtxType *ctx; +}; + +LocalIface *CreateLocalIface(); +void FreeLocalIface(LocalIface *localInterface); +coap_context_t *CreateCoapContext(); +void FreeCoapContext(coap_context_t *context); +CoapCtxType *CreateCoapCtxType(); +void FreeCoapCtxType(CoapCtxType *coapCtxType); +CoapCtxType *InsertDevice(void); +void RemoveDevice(CoapCtxType *ctx); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif // UT_UTILS_H diff --git a/test/unittest/test_dfile_gtest.cpp b/test/unittest/test_dfile_gtest.cpp new file mode 100644 index 0000000..ed53286 --- /dev/null +++ b/test/unittest/test_dfile_gtest.cpp @@ -0,0 +1,2405 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "nstackx_dfile.h" +#include "nstackx_dfile_session.h" +#include "nstackx_dfile_dfx.h" +#include "nstackx_dfile_retransmission.h" +#include "nstackx_dfile_private.h" +#include "nstackx_file_manager_client.h" +#include "rbtree.h" +#include "gtest/gtest.h" +#include "securec.h" + +using namespace std; + +#define DFILE_SEND_FILE_NAME "dfile.1M" +#define DFILE_SEND_FILE_RENAME_BAK "-BAK" +#define DFILE_SEND_FILE_SIZE (1024 * 1024) +#define DFILE_SEND_FILE_NAME_100M "dfile.100M" +#define DFILE_SEND_FILE_SIZE_100M (100 * 1024 * 1024) +#define DFILE_RECV_REMOTE_PATH "/sdcard/" +#define DFILE_DEFAULT_STORAGE_PATH "./recv/" +#define DFILE_DEFAULT_SEND_PATH "./send/" +#define DFILE_SESSION_ID_OFFEST 2 +#define DFILE_DEFAULT_PATH_LEN 100 +#define DFILE_MD5_ARRAY_SIZE 16 +#define DFILE_MD5_STR_SIZE 100 +#define DFLIE_MD5_BLOCK_LENGTH 1024 +#define DFILE_MP_PARA_NUM 2 +#define RBTREE_NUM_NODES 1000000 +#define DFILE_DUMP_CMD_NUM_MAX 20 +#define DFILE_UT_BUF_LEN 1000 +#define DEFAULT_DFILE_SERVER_PORT 8197 +#define FILE_PATH_LEN 4100 +#define SLEEP_SECOND_LOW 2 +#define SLEEP_SECOND_HIGH 10 +#define SET_CAPABILITIES_VALUE_FOUR 4 +#define CMD_COUNT 2 +#define FILE_AUTHOPITY_LOW 0600 +#define FILE_AUTHOPITY_HIGH 0755 + +const string g_default_ip("127.0.0.1"); +const string g_default_second_ip("192.168.10.1"); +const unsigned short g_default_port = 8097; +const char *g_files[FILE_PATH_LEN] = { nullptr }; +struct sockaddr_in g_defaultAddr; +NSTACKX_ServerParaMp g_mp_serverPara[DFILE_MP_PARA_NUM]; +NSTACKX_SessionParaMp g_mp_clinetPara[DFILE_MP_PARA_NUM]; +DFileDirCallback g_set; +static int g_recvSucc = NSTACKX_FALSE; +static int g_sendFileNums = 10; +static int g_restFileNums = 0; +static int g_sid = 0; +static int g_cid = 0; +static sem_t g_sem; + +using pii = std::pair; + +static void InitDefaultAddr(unsigned short port) +{ + (void)memset_s(&g_defaultAddr, sizeof(g_defaultAddr), 0, sizeof(g_defaultAddr)); + g_defaultAddr.sin_family = AF_INET; + if (port) { + g_defaultAddr.sin_port = port; + } else { + g_defaultAddr.sin_port = g_default_port; + } + g_defaultAddr.sin_addr.s_addr = ntohl(inet_addr(g_default_ip.c_str())); +} + +static int CreateFileWithSize(const char *fileName, int fileSize) +{ + FILE *fp = fopen(fileName, "wb"); + if (!fp) { + return NSTACKX_EFAILED; + } + + (void)fseek(fp, fileSize - 1, SEEK_SET); + int ret = fwrite(" ", 1, 1, fp); + if (ret <= 0) { + return NSTACKX_EFAILED; + } + (void)fclose(fp); + return NSTACKX_EOK; +} + +static int CreateFolder(const char *path) +{ +#ifdef BUILD_FOR_UNIX + return (mkdir(path, FILE_AUTHOPITY_HIGH) == 0); +#else + return (mkdir(path, FILE_AUTHOPITY_LOW) == 0); +#endif +} + +static int UTIsExistingFile(const char *fileName) +{ + return (access(fileName, F_OK) == 0); +} + +static int RemoveDir(const char *dir) +{ + char cur_dir[] = "."; + char up_dir[] = ".."; + char dir_name[PATH_MAX] = {0}; + DIR *dirp; + struct dirent *dp; + struct stat dirStat; + if ((access(dir, F_OK) != 0)) { + return NSTACKX_EOK; + } + if (stat(dir, &dirStat) < 0) { + return NSTACKX_EFAILED; + } + if (S_ISREG(dirStat.st_mode)) { + (void)remove(dir); + } else if (S_ISDIR(dirStat.st_mode)) { + dirp = opendir(dir); + while ((dp = readdir(dirp)) != nullptr) { + if ((strcmp(cur_dir, dp->d_name) == 0) || (strcmp(up_dir, dp->d_name) == 0)) { + continue; + } + (void)sprintf_s(dir_name, sizeof(dir_name), "%s/%s", dir, dp->d_name); + RemoveDir(dir_name); + } + closedir(dirp); + rmdir(dir); + } else { + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +static void RenameFileCalbak(DFileRenamePara *renamePara) +{ + (void)sprintf_s(renamePara->newFileName, NSTACKX_MAX_REMOTE_PATH_LEN, "%s%s", + renamePara->initFileName, DFILE_SEND_FILE_RENAME_BAK); + return; +} + +static int GetFileMD5(const char *filepath, char *md5Str, int length) +{ + struct stat fileStat; + unsigned char md5[DFILE_MD5_ARRAY_SIZE]; + int fd; + + if ((fd = open(filepath, O_RDONLY)) <= 0) { + return NSTACKX_EFAILED; + } + + if (stat(filepath, &fileStat) < 0) { + close(fd); + return NSTACKX_EFAILED; + } + + int fileSize = fileStat.st_size; + unsigned char *p = (unsigned char*)mmap(nullptr, fileSize, + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_POPULATE, fd, 0); + if (p == MAP_FAILED) { + close(fd); + return NSTACKX_EFAILED; + } + + MD5((unsigned char *)p, fileSize, md5); + + (void)memset_s(md5Str, length, 0, length); + for (int i = 0; i < DFILE_MD5_ARRAY_SIZE; i++) { + (void)sprintf_s(md5Str + strlen(md5Str), DFILE_MD5_STR_SIZE - strlen(md5Str), "%02X", md5[i]); + } + + munmap(p, fileSize); + close(fd); + return NSTACKX_EOK; +} + +int FileMd5Equal(char *file1, char *file2) +{ + char sendFileMD5[DFILE_MD5_STR_SIZE]; + char recvFileMD5[DFILE_MD5_STR_SIZE]; + + if (!UTIsExistingFile(file1) || !UTIsExistingFile(file2)) { + return NSTACKX_EFAILED; + } + + if (GetFileMD5(file1, sendFileMD5, DFILE_MD5_STR_SIZE) != NSTACKX_EOK || + GetFileMD5(file2, recvFileMD5, DFILE_MD5_STR_SIZE) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + + int ret = (strcmp(sendFileMD5, recvFileMD5) == 0) ? NSTACKX_TRUE : NSTACKX_FALSE; + return ret; +} + +static void MsgReceiver(int32_t sid, DFileMsgType msgType, const DFileMsg *msg) +{ + (void)msg; + printf("MsgReceiver: session %d, msgtype: %d\n", sid, msgType); + + if (msgType == DFILE_ON_FILE_RECEIVE_SUCCESS) { + for (uint32_t i = 0; i < msg->fileList.fileNum; i++) { + printf("MsgReceiver: recv success, %s\n", msg->fileList.files[i]); + } + g_recvSucc += msg->fileList.fileNum; + } + if (msgType == DFILE_ON_FILE_SEND_FAIL || msgType == DFILE_ON_FATAL_ERROR) { + for (uint32_t i = 0; i < msg->fileList.fileNum; i++) { + printf("MsgReceiver: rest files, %s\n", msg->fileList.files[i]); + } + if (msg->fileList.fileNum) { + int ret = NSTACKX_DFileSendFiles(g_cid, msg->fileList.files, msg->fileList.fileNum, nullptr); + EXPECT_EQ(ret, 0); + g_restFileNums = msg->fileList.fileNum; + } + } + return; +} + +static void NewLogImpl(const char *tag, uint32_t level, const char *format, va_list args) +{ + time_t now; + + (void)time(&now); + struct tm *tm_now = localtime(&now); + + printf("%02d-%02d %02d:%02d:%02d %d %d %s: ", + tm_now->tm_mon, tm_now->tm_mday, tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec, + getpid(), level, tag); + vprintf(format, args); +} + +#ifdef ENABLE_USER_LOG +__attribute__((format(printf, 3, 4))) static void Printflog(const char *moduleName, + uint32_t logLevel, const char *format, ...) +{ + const char *tag = moduleName; + va_list args; + va_start(args, format); + time_t now; + (void)time(&now); + struct tm *tm_now = localtime(&now); + + printf("PLOG %02d-%02d %02d:%02d:%02d %d %d %s: ", + tm_now->tm_mon, tm_now->tm_mday, tm_now->tm_hour, + tm_now->tm_min, tm_now->tm_sec, getpid(), logLevel, tag); + vprintf(format, args); + va_end(args); +} +#endif + +static int32_t InitDFileServerParaMp(NSTACKX_ServerParaMp *para, uint8_t paraNum, int port) +{ + if (para == nullptr || paraNum <= 0) { + return NSTACKX_EFAILED; + } + + for (int32_t i = 0; i < paraNum; i++) { + para[i].addr = (struct sockaddr_in *)calloc(1, sizeof(struct sockaddr_in)); + if (para[i].addr == nullptr) { + goto MALLOC_FAIL; + } + para[i].addr->sin_family = AF_INET; + if (port) { + para[i].addr->sin_port = port + i; + } else { + para[i].addr->sin_port = g_default_port + i; + } + para[i].addr->sin_addr.s_addr = ntohl(inet_addr(g_default_ip.c_str())); + para[i].addrLen = sizeof(struct sockaddr_in); + } + return NSTACKX_EOK; + +MALLOC_FAIL: + for (int32_t i = 0; i < paraNum; i++) { + if (para[i].addr != nullptr) { + free(para[i].addr); + para[i].addr = nullptr; + } + } + return NSTACKX_EFAILED; +} + +static int32_t InitDFileServerParaMpEscape(NSTACKX_ServerParaMp *para, uint8_t paraNum) +{ + if (para == nullptr || paraNum <= 0) { + return NSTACKX_EFAILED; + } + + for (int32_t i = 0; i < paraNum; i++) { + para[i].addr = (struct sockaddr_in *)calloc(1, sizeof(struct sockaddr_in)); + if (para[i].addr == nullptr) { + goto MALLOC_FAIL; + } + para[i].addr->sin_family = AF_INET; + para[i].addr->sin_port = g_default_port + i; + para[i].addrLen = sizeof(struct sockaddr_in); + } + para[0].addr->sin_addr.s_addr = ntohl(inet_addr(g_default_ip.c_str())); + para[1].addr->sin_addr.s_addr = ntohl(inet_addr(g_default_second_ip.c_str())); + return NSTACKX_EOK; + +MALLOC_FAIL: + for (int32_t i = 0; i < paraNum; i++) { + if (para[i].addr != nullptr) { + free(para[i].addr); + para[i].addr = nullptr; + } + } + return NSTACKX_EFAILED; +} + +static uint32_t InitDFileClientParaMp(NSTACKX_SessionParaMp *clientPara, + NSTACKX_ServerParaMp *serverPara, uint8_t paraNum) +{ + if (clientPara == nullptr || serverPara == nullptr || paraNum <= 0) { + return NSTACKX_EFAILED; + } + + for (int32_t i = 0; i < paraNum; i++) { + clientPara[i].addr = serverPara[i].addr; + clientPara[i].addrLen = serverPara[i].addrLen; + clientPara[i].localInterfaceName = nullptr; + } + return NSTACKX_EOK; +} + +static void FreeDFileServerAddrMp(NSTACKX_ServerParaMp *para, uint8_t paraNum) +{ + if (para == nullptr || paraNum <= 0) { + return; + } + + for (int32_t i = 0; i < paraNum; i++) { + if (para[i].addr != nullptr) { + free(para[i].addr); + para[i].addr = nullptr; + } + } +} + +class NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN : public ::testing::Test { +public: + void SetUp() + { + g_recvSucc = NSTACKX_FALSE; + InitDefaultAddr(0); + int ret = CreateFileWithSize(DFILE_SEND_FILE_NAME, DFILE_SEND_FILE_SIZE); + ASSERT_EQ(ret, NSTACKX_EOK); + ret = CreateFileWithSize(DFILE_SEND_FILE_NAME_100M, DFILE_SEND_FILE_SIZE_100M); + ASSERT_EQ(ret, NSTACKX_EOK); + if (!UTIsExistingFile(DFILE_DEFAULT_STORAGE_PATH)) { + ret = CreateFolder(DFILE_DEFAULT_STORAGE_PATH); + ASSERT_GT(ret, 0); + } + } + void TearDown() + { + (void)remove(DFILE_SEND_FILE_NAME); + (void)remove(DFILE_SEND_FILE_NAME_100M); + RemoveDir(DFILE_DEFAULT_STORAGE_PATH); + } +}; + +class BREAKPOINT_RESUME_SETUP_AND_TEARDOWN : public ::testing::Test { +public: + char fileName[DFILE_DEFAULT_PATH_LEN] = {0}; + void SetUp() + { + g_recvSucc = NSTACKX_FALSE; + InitDefaultAddr(0); + int ret = InitDFileServerParaMp(g_mp_serverPara, DFILE_MP_PARA_NUM, 0); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = InitDFileClientParaMp(g_mp_clinetPara, g_mp_serverPara, DFILE_MP_PARA_NUM); + ASSERT_EQ(ret, NSTACKX_EOK); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)memset_s(fileName, sizeof(fileName), 0, sizeof(fileName)); + (void)sprintf_s(fileName, sizeof(fileName), "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ret = CreateFileWithSize(fileName, DFILE_SEND_FILE_SIZE_100M); + ASSERT_EQ(ret, NSTACKX_EOK); + } + + if (!UTIsExistingFile(DFILE_DEFAULT_STORAGE_PATH)) { + ret = CreateFolder(DFILE_DEFAULT_STORAGE_PATH); + ASSERT_GT(ret, 0); + } + system("iptables -D INPUT -p tcp --dport 8097 -j REJECT"); + system("iptables -D OUTPUT -p tcp --sport 8097 -j REJECT"); + system("iptables -D INPUT -p udp --dport 8097 -j REJECT"); + system("iptables -D OUTPUT -p udp --sport 8097 -j REJECT"); + } + void TearDown() + { + for (int i = 0; i < g_sendFileNums; i++) { + (void)memset_s(fileName, sizeof(fileName), 0, sizeof(fileName)); + (void)sprintf_s(fileName, sizeof(fileName), "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + printf("delete file %s\n", fileName); + (void)remove(fileName); + } + RemoveDir(DFILE_DEFAULT_STORAGE_PATH); + FreeDFileServerAddrMp(g_mp_serverPara, DFILE_MP_PARA_NUM); + system("iptables -D INPUT -p tcp --dport 8097 -j REJECT"); + system("iptables -D OUTPUT -p tcp --sport 8097 -j REJECT"); + system("iptables -D INPUT -p udp --dport 8097 -j REJECT"); + system("iptables -D OUTPUT -p udp --sport 8097 -j REJECT"); + } +}; + +class MpEscape_SETUP_AND_TEARDOWN : public ::testing::Test { +public: + char fileName[DFILE_DEFAULT_PATH_LEN] = {0}; + void SetUp() + { + g_recvSucc = NSTACKX_FALSE; + InitDefaultAddr(0); + int ret = InitDFileServerParaMpEscape(g_mp_serverPara, DFILE_MP_PARA_NUM); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = InitDFileClientParaMp(g_mp_clinetPara, g_mp_serverPara, DFILE_MP_PARA_NUM); + ASSERT_EQ(ret, NSTACKX_EOK); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)memset_s(fileName, sizeof(fileName), 0, sizeof(fileName)); + (void)sprintf_s(fileName, sizeof(fileName), "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ret = CreateFileWithSize(fileName, DFILE_SEND_FILE_SIZE_100M); + ASSERT_EQ(ret, NSTACKX_EOK); + } + + if (!UTIsExistingFile(DFILE_DEFAULT_STORAGE_PATH)) { + ret = CreateFolder(DFILE_DEFAULT_STORAGE_PATH); + ASSERT_GT(ret, 0); + } + system("mkdir -p /dev/net && ln -s /dev/tun /dev/net/tun"); + system("ip tuntap add dev tap0 mod tap"); + system("ifconfig tap0 192.168.10.1"); + } + void TearDown() + { + for (int i = 0; i < g_sendFileNums; i++) { + (void)memset_s(fileName, sizeof(fileName), 0, sizeof(fileName)); + (void)sprintf_s(fileName, sizeof(fileName), "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + printf("delete file %s\n", fileName); + (void)remove(fileName); + } + RemoveDir(DFILE_DEFAULT_STORAGE_PATH); + FreeDFileServerAddrMp(g_mp_serverPara, DFILE_MP_PARA_NUM); + system("ip tuntap del dev tap0 mod tap"); + } +}; + +class NSTACKX_DFILE_MP : public ::testing::Test { +public: + void SetUp() + { + g_recvSucc = NSTACKX_FALSE; + int ret = InitDFileServerParaMp(g_mp_serverPara, DFILE_MP_PARA_NUM, 0); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = InitDFileClientParaMp(g_mp_clinetPara, g_mp_serverPara, DFILE_MP_PARA_NUM); + ASSERT_EQ(ret, NSTACKX_EOK); + + ret = CreateFileWithSize(DFILE_SEND_FILE_NAME_100M, DFILE_SEND_FILE_SIZE_100M); + ASSERT_EQ(ret, NSTACKX_EOK); + + if (!UTIsExistingFile(DFILE_DEFAULT_STORAGE_PATH)) { + ret = CreateFolder(DFILE_DEFAULT_STORAGE_PATH); + ASSERT_GT(ret, 0); + } + } + void TearDown() + { + (void)remove(DFILE_SEND_FILE_NAME_100M); + RemoveDir(DFILE_DEFAULT_STORAGE_PATH); + FreeDFileServerAddrMp(g_mp_serverPara, DFILE_MP_PARA_NUM); + } +}; + +TEST(NSTACKX_DFILE, CreateServerEncrypt) +{ + const string key("aaaaaaaaaaaaaaaa"); + + InitDefaultAddr(0); + int sid = NSTACKX_DFileServer(nullptr, 0, nullptr, 0, nullptr); + ASSERT_LT(sid, 0); + + sid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), + (const uint8_t *)key.c_str(), key.length(), nullptr); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateServerNonEncrypt) +{ + InitDefaultAddr(0); + int sid = NSTACKX_DFileServer(nullptr, 0, nullptr, 0, nullptr); + ASSERT_LT(sid, 0); + + sid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateClientEncrypt) +{ + const string key("aaaaaaaaaaaaaaaa"); + + InitDefaultAddr(0); + int sid = NSTACKX_DFileClient(nullptr, 0, nullptr, 0, nullptr); + ASSERT_LT(sid, 0); + + sid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), + (const uint8_t *)key.c_str(), key.length(), nullptr); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateClientNonEncrypt) +{ + InitDefaultAddr(0); + int sid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateServerV2Encrypt) +{ + const string key("aaaaaaaaaaaaaaaa"); + + uint32_t abmStatus = 0; + + InitDefaultAddr(0); + int sid = NSTACKX_DFileServerV2(nullptr, 0, nullptr, 0, nullptr, abmStatus); + ASSERT_LT(sid, 0); + + sid = NSTACKX_DFileServerV2(&g_defaultAddr, sizeof(g_defaultAddr), + (const uint8_t *)key.c_str(), key.length(), nullptr, abmStatus); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateServerV2NonEncrypt) +{ + uint32_t abmStatus = 0; + + InitDefaultAddr(0); + int sid = NSTACKX_DFileServerV2(nullptr, 0, nullptr, 0, nullptr, abmStatus); + ASSERT_LT(sid, 0); + + sid = NSTACKX_DFileServerV2(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr, abmStatus); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateClientV2Encrypt) +{ + const string key("aaaaaaaaaaaaaaaa"); + + uint32_t abmStatus = 0; + + InitDefaultAddr(0); + int sid = NSTACKX_DFileClientV2(nullptr, 0, nullptr, 0, nullptr, abmStatus); + ASSERT_LT(sid, 0); + + sid = NSTACKX_DFileClientV2(&g_defaultAddr, sizeof(g_defaultAddr), + (const uint8_t *)key.c_str(), key.length(), nullptr, abmStatus); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateClientV2NonEncrypt) +{ + uint32_t abmStatus = 0; + + InitDefaultAddr(0); + int sid = NSTACKX_DFileClientV2(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr, abmStatus); + ASSERT_GT(sid, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, SetStoragePath) +{ + InitDefaultAddr(0); + int sid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr); + ASSERT_GT(sid, 0); + + int err = NSTACKX_DFileSetStoragePath(sid, "/qqqqqqqq"); + EXPECT_LT(err, 0); + +#ifdef BUILD_FOR_UNIX + if (!UTIsExistingFile(DFILE_DEFAULT_STORAGE_PATH)) { + err = CreateFolder(DFILE_DEFAULT_STORAGE_PATH); + ASSERT_GT(err, 0); + } + err = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); // diff path + EXPECT_EQ(err, 0); + RemoveDir(DFILE_DEFAULT_STORAGE_PATH); +#else + err = NSTACKX_DFileSetStoragePath(sid, DFILE_RECV_REMOTE_PATH); // diff path + EXPECT_EQ(err, 0); +#endif + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateClientWithTargetDev) +{ + NSTACKX_SessionPara sessionPara; + + InitDefaultAddr(0); + sessionPara.addr = &g_defaultAddr; + sessionPara.addrLen = sizeof(g_defaultAddr); + sessionPara.key = nullptr; + sessionPara.keyLen = 0; + sessionPara.msgReceiver = nullptr; + sessionPara.localInterfaceName = nullptr; + + int sid = NSTACKX_DFileClientWithTargetDev(nullptr); + ASSERT_LT(sid, 0); + sid = NSTACKX_DFileClientWithTargetDev(&sessionPara); + ASSERT_GT(sid, 0); + NSTACKX_DFileClose(sid); + + const string key("aaaaaaaaaaaaaaaa"); + sessionPara.key = (const uint8_t *)key.c_str(); + sessionPara.keyLen = key.length(); + + /* Encrypt */ + sid = NSTACKX_DFileClientWithTargetDev(&sessionPara); + ASSERT_GT(sid, 0); + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CreateClientWithTargetDevV2) +{ + NSTACKX_SessionPara sessionPara; + uint32_t abmStatus = 0; + + InitDefaultAddr(0); + sessionPara.addr = &g_defaultAddr; + sessionPara.addrLen = sizeof(g_defaultAddr); + sessionPara.key = nullptr; + sessionPara.keyLen = 0; + sessionPara.msgReceiver = nullptr; + sessionPara.localInterfaceName = nullptr; + + int sid = NSTACKX_DFileClientWithTargetDevV2(nullptr, abmStatus); + ASSERT_LT(sid, 0); + sid = NSTACKX_DFileClientWithTargetDevV2(&sessionPara, abmStatus); + ASSERT_GT(sid, 0); + NSTACKX_DFileClose(sid); + + const string key("aaaaaaaaaaaaaaaa"); + sessionPara.key = (const uint8_t *)key.c_str(); + sessionPara.keyLen = key.length(); + + /* Encrypt */ + sid = NSTACKX_DFileClientWithTargetDevV2(&sessionPara, abmStatus); + ASSERT_GT(sid, 0); + NSTACKX_DFileClose(sid); + sleep(1); +} + +#ifdef DFILE_ENABLE_HIDUMP +static void DFileDumpFuncUT(void *softObj, const char *data, uint32_t len) +{ + (void)softObj; + (void)data; + (void)len; + printf("--------------------------------\n"); +} + +static DFileDump_UT(const char *argv1, int expectVal) +{ + const char *argv[DFILE_DUMP_CMD_NUM_MAX] = {nullptr}; + uint32_t argc = 0; + argv[argc++] = "dfile"; + argv[argc++] = argv1; + if (argv2) { + argv[argc++] = argv2; + } + int ret = NSTACKX_DFileDump(argc, argv, nullptr, dump); + ASSERT_EQ(ret, expectVal); +} + +TEST(NSTACKX_DFILE, DFileDump) +{ + const char *argv[DFILE_DUMP_CMD_NUM_MAX] = {nullptr}; + char sidBuf[DFILE_UT_BUF_LEN]; + DFileDumpFunc dump = DFileDumpFuncUT; + + int ret = NSTACKX_DFileDump(0, nullptr, nullptr, dump); + ASSERT_LT(ret, 0); + + ret = NSTACKX_DFileDump(argc, argv, nullptr, dump); + ASSERT_LT(ret, 0); + + uint32_t argc = 0; + argv[argc++] = "-h"; + argv[argc++] = nullptr; + ret = NSTACKX_DFileDump(argc, argv, nullptr, dump); + ASSERT_LT(ret, 0); + + argc = 0; + argv[argc++] = "dfile"; + argv[argc++] = "-h"; + argv[argc++] = nullptr; + ret = NSTACKX_DFileDump(argc, argv, nullptr, dump); + ASSERT_LT(ret, 0); + + DFileDump_UT("h", nullptr, -1); + + DFileDump_UT("-h", nullptr, 0); + + DFileDump_UT("-l", nullptr, 0); + + DFileDump_UT("-m", nullptr, -1); + + DFileDump_UT("-m", "a", 0); + + DFileDump_UT("-m", "1", 0); + + DFileDump_UT("-m", "0", 0); + + DFileDump_UT("-m", "0a", 0); + + DFileDump_UT("-m", "1a", 0); + + DFileDump_UT("-m", "11", 0); + + DFileDump_UT("-m", "00", 0); + + DFileDump_UT("-s", "-1", 0); + + DFileDump_UT("-s", "0", 0); + + InitDefaultAddr(0); + int sid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr); + ASSERT_GT(sid, 0); + (void)sprintf_s(sidBuf, DFILE_UT_BUF_LEN - 1, "%d", sid); + printf("dfile -s %d (server id), expect success\n", sid); + DFileDump_UT("-s", (const char *)sidBuf, 0); + NSTACKX_DFileClose(sid); + + InitDefaultAddr(0); + sid = NSTACKX_DFileClientV2(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr, 0); + ASSERT_GT(sid, 0); + (void)sprintf_s(sidBuf, DFILE_UT_BUF_LEN - 1, "%d", sid); + printf("dfile -s %d (client id), expect success\n", sid); + DFileDump_UT("-s", (const char *)sidBuf, 0); + NSTACKX_DFileClose(sid); + sleep(1); + + DFileDump_UT("-s", "a", 0); + + DFileDump_UT("x", nullptr, -1); +} +#endif + +TEST(NSTACKX_DFILE, DFileSetEventFunc) +{ + NSTACKX_DFileSetEventFunc(nullptr, nullptr); +} + +static int32_t OpenFuncRegister(const char *fileName, int32_t flag, int32_t mode) +{ + return open(fileName, flag, mode); +} + +TEST(NSTACKX_DFILE, DFileSetOpenFdCallback) +{ + int ret = NSTACKX_DFileSetOpenFdCallback(nullptr); + ASSERT_EQ(ret, -1); + + ret = NSTACKX_DFileSetOpenFdCallback(OpenFuncRegister); + ASSERT_EQ(ret, 0); +} + +TEST(NSTACKX_DFILE, DFileSetCloseFdCallback) +{ + int ret; + + ret = NSTACKX_DFileSetCloseFdCallback(nullptr); + ASSERT_EQ(ret, -1); + + ret = NSTACKX_DFileSetCloseFdCallback(close); + ASSERT_EQ(ret, 0); +} + +TEST(NSTACKX_DFILE, AckLossEvent) +{ + AckLossEvent(0); + AckLossEvent(1); +} + +TEST(NSTACKX_DFILE, WaitFileHeaderTimeoutEvent) +{ + WaitFileHeaderTimeoutEvent(DFILE_TRANS_NO_ERROR); + WaitFileHeaderTimeoutEvent(DFILE_TRANS_SOCKET_ERROR); +} + +TEST(NSTACKX_DFILE, ReceiverIdleTimeoutEvent) +{ + ReceiverIdleTimeoutEvent(0); + ReceiverIdleTimeoutEvent(1); +} + +static DFileSessionNode *GTestGetDFileSessionNodeById(uint16_t sessionId) +{ + List *pos = nullptr; + DFileSessionNode *node = nullptr; + uint8_t isFound = NSTACKX_FALSE; + LIST_FOR_EACH(pos, &g_dFileSessionChain) { + node = (DFileSessionNode *)pos; + if (node->sessionId == sessionId) { + isFound = NSTACKX_TRUE; + break; + } + } + return isFound ? node : nullptr; +} + +pii gtest_parse_address(const char *s) +{ + struct in_addr ip; + int port; + std::string str(s); + size_t pos = str.find(':'); + if (pos != std::string::npos) { + std::string sp = str.substr(pos + 1); + if (sp.length() == 0) { + port = DEFAULT_DFILE_SERVER_PORT; + } else { + port = std::stoi(sp); + } + str.erase(pos); + if (str.length() == 0) { + s = "192.168.49.1"; + inet_pton(AF_INET, s, &ip); + } else { + inet_pton(AF_INET, str.c_str(), &ip); + } + } else { + port = DEFAULT_DFILE_SERVER_PORT; + } + return std::make_pair(ntohl(ip.s_addr), port); +} + +static int GTestGetSockAddr(const char *s, struct sockaddr_in *addr) +{ + if (s == nullptr || addr == nullptr) { + return NSTACKX_EFAILED; + } + pii pair = gtest_parse_address(s); + (void)memset_s(addr, sizeof(*addr), 0, sizeof(*addr)); + addr->sin_family = AF_INET; + addr->sin_port = pair.second; + addr->sin_addr.s_addr = pair.first; + return NSTACKX_EOK; +} + +TEST(NSTACKX_DFILE, DISABLED_NotifyTransAddRetryNodeZS) +{ + DFileSession *sessionServer; + uint16_t sessionServerId, sessionClientId; + struct sockaddr_in addr; + char address[64] = "127.0.0.1:8097"; + int32_t ret = NSTACKX_EOK; + uint8_t socketIndex = 0; + FileDataFrameZS tmp; + FileDataFrameZS *fileDataFrame = &tmp; + + ret = GTestGetSockAddr(address, &addr); + ASSERT_EQ(ret, NSTACKX_EOK); + sessionServerId = NSTACKX_DFileServer(&addr, sizeof(addr), nullptr, 0, MsgReceiver); + sessionClientId = NSTACKX_DFileClient(&addr, sizeof(addr), nullptr, 0, MsgReceiver); + sessionServer = GTestGetDFileSessionNodeById(sessionServerId)->session; + fileDataFrame->header.type = NSTACKX_DFILE_FILE_DATA_FRAME; + fileDataFrame->header.transId = 0; + fileDataFrame->fileId = 0; + fileDataFrame->linkSequence = 1; + + DFileTrans ttmp; + DFileTrans *transtmp = &ttmp; + transtmp->transId = 0; + sessionServer->dFileTransChain.next = &transtmp->list; + transtmp->list.next = &sessionServer->dFileTransChain; + transtmp->receivedDataFrameCnt = 1; + + NotifyTransAddRetryNodeZS(sessionServer, (const DFileFrame *)fileDataFrame, socketIndex); + sleep(1); + ASSERT_EQ(transtmp->receivedDataFrameCnt, (uint64_t)0); + + sessionServer->dFileTransChain.next = &sessionServer->dFileTransChain; + sessionServer->peerInfoChain.next = &sessionServer->peerInfoChain; + NSTACKX_DFileClose(sessionServerId); + NSTACKX_DFileClose(sessionClientId); + sleep(1); +} + +TEST(NSTACKX_DFILE, DFilePrintControlFrame) +{ + char opt[DFILE_UT_BUF_LEN] = {'1', '\0'}; + char message[DUMP_INFO_MAX]; + size_t size; + char frame[DFILE_UT_BUF_LEN] = {0}; + DFileFrame *dFileFrame = (DFileFrame *)frame; + + // open hidump + printf("call HidumpMessage, opt %s\n", opt); + int ret = HidumpMessage(message, &size, opt); + printf("call HidumpMessage, result: %s\n", message); + ASSERT_EQ(ret, 0); + + dFileFrame->header.type = NSTACKX_DFILE_SETTING_FRAME; + DFilePrintControlFrame((const DFileFrame *)frame, 1); + + dFileFrame->header.type = NSTACKX_DFILE_FILE_HEADER_FRAME; + DFilePrintControlFrame((const DFileFrame *)frame, 1); + + dFileFrame->header.type = NSTACKX_DFILE_FILE_HEADER_CONFIRM_FRAME; + DFilePrintControlFrame((const DFileFrame *)frame, 1); + + dFileFrame->header.type = NSTACKX_DFILE_FILE_DATA_ACK_FRAME; + DFilePrintControlFrame((const DFileFrame *)frame, 1); + + dFileFrame->header.type = NSTACKX_DFILE_FILE_BACK_PRESSURE_FRAME; + DFilePrintControlFrame((const DFileFrame *)frame, 1); + + dFileFrame->header.type = NSTACKX_DFILE_FILE_TRANSFER_DONE_FRAME; + DFilePrintControlFrame((const DFileFrame *)frame, 1); +} + +TEST(NSTACKX_DFILE, CheckDFileRealPath) +{ + OpenCloseFdSwtich(false); + char *ret = DFileRealPath(nullptr, "test", nullptr); + printf("DFileRealPath(test, nullptr) return %08lx\n", (unsigned long)ret); + if (ret != nullptr) { + free(ret); + } + + OpenCloseFdSwtich(true); + ret = DFileRealPath(nullptr, "test", nullptr); + printf("DFileRealPath(test, nullptr) return %08lx\n", (unsigned long)ret); + if (ret != nullptr) { + free(ret); + } + OpenCloseFdSwtich(false); +} + +struct TestNode { + struct RbNode rb; + uint32_t key; + + TestNode() + { + rb.parentColor = 0; + rb.left = nullptr; + rb.right = nullptr; + + key = 0; + } +}; + +static void TestInsert(TestNode *node, RbRoot *root) +{ + RbNode **next = &root->node; + RbNode *parent = nullptr; + uint32_t key = node->key; + TestNode *current = nullptr; + + while (*next) { + parent = *next; + current = container_of(parent, TestNode, rb); + if (key < current->key) { + next = &parent->left; + } else { + next = &parent->right; + } + } + + RbLinkNode(&node->rb, parent, next); + RbInsertColor(&node->rb, root); +} + +static inline void TestErase(TestNode *node, RbRoot *root) +{ + RbErase(&node->rb, root); +} + +TEST(NSTACKX_DFILE, UtilRBTree) +{ + RbRoot root nullptr}; + RbNode *node = nullptr; + TestNode *nodes = nullptr; + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution distrib(0, UINT32_MAX); + int k = 0; + uint32_t *keys = nullptr; + + nodes = new TestNode[RBTREE_NUM_NODES]; + ASSERT_TRUE(nodes); + + keys = new uint32_t[RBTREE_NUM_NODES]; + ASSERT_TRUE(keys); + + for (int i = 0; i < RBTREE_NUM_NODES; i++) { + nodes[i].key = distrib(gen); + TestInsert(&nodes[i], &root); + ASSERT_TRUE(RB_IS_BLACK(root.node)); + } + + for (node = RbFirst(&root); node; node = RbNext(node)) { + TestNode *tmp = container_of(node, TestNode, rb); + keys[k++] = tmp->key; + } + + ASSERT_EQ(k, RBTREE_NUM_NODES); + ASSERT_TRUE(std::is_sorted(keys, keys + k)); + + for (node = RbLast(&root); node; node = RbPrev(node)) { + TestNode *tmp = container_of(node, TestNode, rb); + keys[--k] -= tmp->key; + ASSERT_EQ(keys[k], 0U); + } + + ASSERT_EQ(k, 0); + + for (int i = RBTREE_NUM_NODES - 1; i > 0; i--) { + TestErase(&nodes[i], &root); + ASSERT_FALSE(RB_IS_RED(root.node)); + } + + ASSERT_EQ(root.node, &nodes[0].rb); + + TestErase(&nodes[0], &root); + + ASSERT_TRUE(root.node == nullptr); + + delete[] nodes; + delete[] keys; +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSendFiles) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 10; + DFileOpt opt; + uint8_t tos = 0xBC; + opt.optType = OPT_TYPE_SOCK_PRIO; + opt.value = (uint64_t)(uintptr_t)&tos; + opt.valLen = sizeof(tos); + + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + int ret = NSTACKX_DFileSetSessionOpt(ssid, &opt); + EXPECT_EQ(ret, 0); + + ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + ret = NSTACKX_DFileSetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + + /* para is nullptr, return vaule shuold be less than 0 */ + ret = NSTACKX_DFileSendFiles(csid, nullptr, 0, nullptr); + EXPECT_LT(ret, 0); + + files[0] = DFILE_SEND_FILE_NAME; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + tos = ~tos; + ret = NSTACKX_DFileSetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + second--; + } + + ret = NSTACKX_DFileGetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(csid); + NSTACKX_DFileClose(ssid); + + sleep(1); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSendFilesWithAlgNoRate) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 10; + + int ret = NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_ALG_NORATE, 0); + EXPECT_EQ(ret, 0); + + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + + ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + + files[0] = DFILE_SEND_FILE_NAME; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(csid); + NSTACKX_DFileClose(ssid); + + sleep(1); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, MemLog) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 10; + + NSTACKX_DFileSetInternalCapabilities(NSTACKX_INTERNAL_CAPS_MEMLOG); + + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + + int ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + + files[0] = DFILE_SEND_FILE_NAME; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(csid); + NSTACKX_DFileClose(ssid); + sleep(1); + NSTACKX_DFileSetInternalCapabilities(0); + ret = NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_UDP_GSO, 0); + EXPECT_EQ(ret, 0); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSendFilesV2) +{ + uint32_t abmStatus = 1; + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 10; + + int ssid = NSTACKX_DFileServerV2(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver, abmStatus); + ASSERT_GT(ssid, 0); + + int ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClientV2(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver, abmStatus); + EXPECT_GT(csid, 0); + + /* para is nullptr, return vaule shuold be less than 0 */ + ret = NSTACKX_DFileSendFiles(csid, nullptr, 0, nullptr); + EXPECT_LT(ret, 0); + + files[0] = DFILE_SEND_FILE_NAME; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(csid); + NSTACKX_DFileClose(ssid); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSendFilesV3) +{ + int filenum = 2; + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + uint8_t tos = 0xBC; + DFileOpt opt; + opt.optType = OPT_TYPE_SOCK_PRIO; + opt.value = (uint64_t)(uintptr_t)&tos; + opt.valLen = sizeof(tos); + if (!UTIsExistingFile(DFILE_DEFAULT_SEND_PATH)) { + ret = CreateFolder(DFILE_DEFAULT_SEND_PATH); + ASSERT_GT(ret, 0); + } + int ret = NSTACKX_DFileConfigSet(DFILE_CONF_DIR_CALLBACK, &g_set, sizeof(DFileDirCallback)); + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + ret = NSTACKX_DFileSetSessionOpt(ssid, &opt); + EXPECT_EQ(ret, 0); + + ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + ret = NSTACKX_DFileSetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + + sleep(SLEEP_SECOND_LOW); + /* para is nullptr, return vaule shuold be less than 0 */ + ret = NSTACKX_DFileSendFiles(csid, nullptr, 0, nullptr); + EXPECT_LT(ret, 0); + + files[0] = DFILE_SEND_FILE_NAME; + files[1] = DFILE_DEFAULT_SEND_PATH; + ret = NSTACKX_DFileSendFiles(csid + DFILE_SESSION_ID_OFFEST, files, 1, nullptr); + ret = NSTACKX_DFileSendFiles(csid, files, filenum, nullptr); + EXPECT_EQ(ret, 0); + + for (int second = 1; second <= SLEEP_SECOND_HIGH; second++) { + if (g_recvSucc) { + break; + } + sleep(1); + tos = ~tos; + ret = NSTACKX_DFileSetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + } + + ret = NSTACKX_DFileGetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(csid); + NSTACKX_DFileClose(ssid); + RemoveDir(DFILE_DEFAULT_SEND_PATH); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSendFilesWithRemotePath) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + const char *remotePath[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + + int sid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr); + ASSERT_GT(sid, 0); + + /* para is nullptr, return vaule shuold be less than 0 */ + int ret = NSTACKX_DFileSendFilesWithRemotePath(sid, nullptr, nullptr, 0, nullptr); + EXPECT_LT(ret, 0); + + files[0] = DFILE_SEND_FILE_NAME; + remotePath[0] = DFILE_DEFAULT_STORAGE_PATH; + ret = NSTACKX_DFileSendFilesWithRemotePath(sid, files, remotePath, 1, nullptr); + EXPECT_EQ(ret, 0); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSendFilesWithRemotePathAndType) +{ + NSTACKX_FilesInfo fileInfo; + + (void)memset_s(&fileInfo, sizeof(fileInfo), 0, sizeof(fileInfo)); + fileInfo.files[0] = DFILE_SEND_FILE_NAME; + fileInfo.fileNum = 1; + fileInfo.remotePath[0] = DFILE_DEFAULT_STORAGE_PATH; + fileInfo.smallFlag = 1; + fileInfo.pathType = 1; + fileInfo.tarFlag = 0; + fileInfo.unuse = 0; + fileInfo.userData = nullptr; + + int sid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr); + ASSERT_GT(sid, 0); + + int ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid, nullptr); + EXPECT_LT(ret, 0); + + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid, &fileInfo); + EXPECT_EQ(ret, 0); + + fileInfo.tarFlag = 1; + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid, &fileInfo); + + fileInfo.pathType = NSTACKX_RESERVED_PATH_TYPE; + fileInfo.remotePath[0] = nullptr; + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid, &fileInfo); + + fileInfo.tarFlag = 0; + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid, &fileInfo); + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid + DFILE_SESSION_ID_OFFEST, &fileInfo); + + fileInfo.pathType = 1; + fileInfo.remotePath[0] = DFILE_DEFAULT_STORAGE_PATH; + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid + DFILE_SESSION_ID_OFFEST, &fileInfo); + fileInfo.files[0] = nullptr; + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid, &fileInfo); + + fileInfo.files[0] = "\0"; + ret = NSTACKX_DFileSendFilesWithRemotePathAndType(sid, &fileInfo); + + ret = NSTACKX_DFileSetRenameHook(sid + DFILE_SESSION_ID_OFFEST, RenameFileCalbak); + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSetRenameHook) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 10; + + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + + int ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + + files[0] = DFILE_SEND_FILE_NAME; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + char recvFile[] = DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME; + ret = UTIsExistingFile(recvFile); + EXPECT_EQ(ret, NSTACKX_TRUE); + + /* para is nullptr, return vaule shuold be less than 0 */ + ret = NSTACKX_DFileSetRenameHook(ssid, nullptr); + EXPECT_LT(ret, 0); + + ret = NSTACKX_DFileSetRenameHook(ssid, RenameFileCalbak); + EXPECT_GE(ret, 0); + + g_recvSucc = 0; + second = SLEEP_SECOND_HIGH; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + char recvFileRename[] = DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME DFILE_SEND_FILE_RENAME_BAK; + char sendFile[] = DFILE_SEND_FILE_NAME; + ret = FileMd5Equal(sendFile, recvFile); + ASSERT_EQ(ret, NSTACKX_TRUE); + ret = FileMd5Equal(recvFileRename, recvFile); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(ssid); + NSTACKX_DFileClose(csid); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileSendRecvLinkSeq) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 10; + + int cap = NSTACKX_DFileGetCapabilities(); + EXPECT_GT(cap, 0); + + int ret = NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_LINK_SEQUENCE | NSTACKX_CAPS_UDP_GSO, 0); + EXPECT_EQ(ret, 0); + + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + + ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + + files[0] = DFILE_SEND_FILE_NAME; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME); + ASSERT_EQ(ret, NSTACKX_TRUE); + + ret = NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_UDP_GSO, 0); + EXPECT_EQ(ret, 0); + + NSTACKX_DFileClose(ssid); + NSTACKX_DFileClose(csid); + sleep(1); +} + +TEST(NSTACKX_DFILE, DFileSetStoragePathList) +{ + InitDefaultAddr(0); + int sid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, nullptr); + ASSERT_GT(sid, 0); + + int ret = NSTACKX_DFileSetStoragePathList(sid, nullptr, nullptr, 0); + EXPECT_LT(ret, 0); + + char path[DFILE_DEFAULT_PATH_LEN] = DFILE_DEFAULT_STORAGE_PATH; + char *spath[1] = {nullptr}; + spath[0] = path; + uint16_t pathType = 1; +#ifdef BUILD_FOR_UNIX + if (!UTIsExistingFile(DFILE_DEFAULT_STORAGE_PATH)) { + ret = CreateFolder(DFILE_DEFAULT_STORAGE_PATH); + ASSERT_GT(ret, 0); + } + ret = NSTACKX_DFileSetStoragePathList(sid, (const char**)spath, &pathType, 1); + EXPECT_EQ(ret, 0); + RemoveDir(DFILE_DEFAULT_STORAGE_PATH); +#else + ret = NSTACKX_DFileSetStoragePathList(sid, (const char**)spath, &pathType, 1); + EXPECT_EQ(ret, 0); +#endif + + NSTACKX_DFileClose(sid); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_MP, NSTACKX_DFileMP) +{ + const string key("OW~zx9+rfTt'8yvn"); + int keyLen = 16; + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 60; + + int32_t sid = NSTACKX_DFileServerMp(nullptr, 0, nullptr, 0, nullptr); + ASSERT_EQ(sid, NSTACKX_EFAILED); + + sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, (uint8_t *)key.c_str(), keyLen, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(nullptr, 0, nullptr, 0, nullptr); + ASSERT_EQ(cid, NSTACKX_EFAILED); + + cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, (uint8_t *)key.c_str(), keyLen, MsgReceiver); + ASSERT_GT(cid, 0); + + files[0] = DFILE_SEND_FILE_NAME_100M; + ret = NSTACKX_DFileSendFiles(cid, files, 1, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + /* Expect to receive file within 60 seconds */ + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME_100M, + (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_MP, NSTACKX_DFileRegisterLog) +{ + int ret; + + ret = NSTACKX_DFileRegisterLog(nullptr); + EXPECT_EQ(ret, NSTACKX_EFAILED); + + ret = NSTACKX_DFileRegisterLog(NewLogImpl); + EXPECT_EQ(ret, NSTACKX_EOK); +#ifdef ENABLE_USER_LOG + ret = NSTACKX_DFileRegisterLogCallback(nullptr); + EXPECT_EQ(ret, NSTACKX_EFAILED); + + ret = NSTACKX_DFileRegisterLogCallback(Printflog); + EXPECT_EQ(ret, NSTACKX_EOK); + + NSTACKX_DFileRegisterDefaultLog(); +#endif +} + +TEST_F(NSTACKX_DFILE_MP, NSTACKX_DFileGetCapabilities) +{ + int ret; + + ret = NSTACKX_DFileGetCapabilities(); + EXPECT_GT(ret, 0); +} + +TEST_F(NSTACKX_DFILE_MP, NSTACKX_DFileSetCapabilities) +{ + int ret; + int cap; + + cap = NSTACKX_DFileGetCapabilities(); + EXPECT_GT(cap, 0); + + ret = NSTACKX_DFileSetCapabilities(0, 0); + EXPECT_EQ(ret, 0); + + /* set itself, must be success */ + ret = NSTACKX_DFileSetCapabilities(cap, 0); + EXPECT_EQ(ret, 0); + + /* link sequence and tcp is not coexist */ + if (cap & NSTACKX_CAPS_LINK_SEQUENCE) { + ret = NSTACKX_DFileSetCapabilities(cap, SET_CAPABILITIES_VALUE_FOUR); + EXPECT_EQ(ret, 1); + } + + if (cap & NSTACKX_CAPS_LINK_SEQUENCE) { + ret = NSTACKX_DFileSetCapabilities(cap, 1); + EXPECT_EQ(ret, 0); + } +} + +TEST_F(NSTACKX_DFILE_MP, MpLinkSeq) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 60; + + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_UDP_GSO | NSTACKX_CAPS_LINK_SEQUENCE | NSTACKX_CAPS_WLAN_CATEGORY, + SET_CAPABILITIES_VALUE_FOUR); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(cid, 0); + + files[0] = DFILE_SEND_FILE_NAME_100M; + ret = NSTACKX_DFileSendFiles(cid, files, 1, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME_100M, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(NSTACKX_DFILE_MP, DISABLED_MpLinkSeqEncrypted) +{ + const string key("OW~zx9+rfTt'8yvn"); + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 60; + + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_UDP_GSO | NSTACKX_CAPS_LINK_SEQUENCE | NSTACKX_CAPS_WLAN_CATEGORY, + SET_CAPABILITIES_VALUE_FOUR); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, + (const uint8_t *)key.c_str(), key.length(), MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, + (const uint8_t *)key.c_str(), key.length(), MsgReceiver); + ASSERT_GT(cid, 0); + + files[0] = DFILE_SEND_FILE_NAME_100M; + ret = NSTACKX_DFileSendFiles(cid, files, 1, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + /* Expect to receive file within 60 seconds */ + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, 1); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME_100M, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(BREAKPOINT_RESUME_SETUP_AND_TEARDOWN, DISABLED_SP_BreakPoint) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + char sendFile[g_sendFileNums][DFILE_DEFAULT_PATH_LEN]; + char recvFile[g_sendFileNums][DFILE_DEFAULT_PATH_LEN]; + + int ret = NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_RESUMABLE_TRANS, 0); + EXPECT_EQ(ret, 0); + + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + + ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)memset_s(sendFile[i], sizeof(sendFile[i]), 0, sizeof(sendFile[i])); + (void)sprintf_s(sendFile[i], sizeof(sendFile[i]), "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + files[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(csid, files, g_sendFileNums, nullptr); + EXPECT_EQ(ret, 0); + + sleep(rand() % SLEEP_SECOND_HIGH); + if (g_recvSucc != g_sendFileNums) { + InitDefaultAddr(g_default_port + 1); + g_sid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(g_sid, 0); + + ret = NSTACKX_DFileSetStoragePath(g_sid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + g_cid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(g_cid, 0); + + // close server to trigger breakPoint resume + NSTACKX_DFileClose(ssid); + } + + int second = 120; + while (second) { + if (g_recvSucc && g_recvSucc >= g_restFileNums) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, g_restFileNums); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)sprintf_s(recvFile[i], sizeof(recvFile[i]), "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(g_sid); + NSTACKX_DFileClose(g_cid); + NSTACKX_DFileClose(csid); + sleep(1); +} + +TEST_F(BREAKPOINT_RESUME_SETUP_AND_TEARDOWN, DISABLED_TCP_BreakPoint) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + char sendFile[g_sendFileNums][DFILE_DEFAULT_PATH_LEN]; + char recvFile[g_sendFileNums][DFILE_DEFAULT_PATH_LEN]; + + (void)signal(SIGPIPE, SIG_IGN); + // set tcp caps + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_WLAN_CATEGORY | NSTACKX_CAPS_RESUMABLE_TRANS, NSTACKX_WLAN_CAT_TCP); + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + + int ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)memset_s(sendFile[i], sizeof(sendFile[i]), 0, sizeof(sendFile[i])); + (void)sprintf_s(sendFile[i], sizeof(sendFile[i]), "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + files[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(csid, files, g_sendFileNums, nullptr); + EXPECT_EQ(ret, 0); + + sleep(1); + if (g_recvSucc != g_sendFileNums) { + InitDefaultAddr(g_default_port + 1); + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_WLAN_CATEGORY | NSTACKX_CAPS_RESUMABLE_TRANS, NSTACKX_WLAN_CAT_TCP); + g_sid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(g_sid, 0); + + ret = NSTACKX_DFileSetStoragePath(g_sid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + g_cid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(g_cid, 0); + + // close server to trigger breakPoint resume + NSTACKX_DFileClose(ssid); + } + + int second = 120; + while (second--) { + if (g_recvSucc && g_recvSucc >= g_restFileNums) { + break; + } + sleep(1); + } + ASSERT_GE(g_recvSucc, g_restFileNums); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)sprintf_s(recvFile[i], sizeof(recvFile[i]), "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(g_sid); + NSTACKX_DFileClose(g_cid); + NSTACKX_DFileClose(csid); + sleep(1); +} + +TEST_F(BREAKPOINT_RESUME_SETUP_AND_TEARDOWN, DISABLED_TCP_ZEROCOPY) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + char sendFile[g_sendFileNums][DFILE_DEFAULT_PATH_LEN]; + char recvFile[g_sendFileNums][DFILE_DEFAULT_PATH_LEN]; + + // set tcp caps + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_WLAN_CATEGORY | NSTACKX_CAPS_ZEROCOPY | NSTACKX_CAPS_NO_RTT, + NSTACKX_WLAN_CAT_TCP); + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + ASSERT_GT(ssid, 0); + + int ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiver); + EXPECT_GT(csid, 0); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)memset_s(sendFile[i], sizeof(sendFile[i]), 0, sizeof(sendFile[i])); + (void)sprintf_s(sendFile[i], sizeof(sendFile[i]), "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + files[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(csid, files, g_sendFileNums, nullptr); + EXPECT_EQ(ret, 0); + + int second = 120; + while (second) { + if (g_recvSucc && g_recvSucc >= g_restFileNums) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, g_restFileNums); + + for (int i = 0; i < g_sendFileNums; i++) { + (void)sprintf_s(recvFile[i], sizeof(recvFile[i]), "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(csid); + NSTACKX_DFileClose(ssid); + sleep(1); +} + +TEST_F(BREAKPOINT_RESUME_SETUP_AND_TEARDOWN, DISABLED_NSTACKX_DFileMPTcp) +{ + const string key("OW~zx9+rfTt'8yvn"); + int32_t keyLen = 16; + char sendFile[NSTACKX_MAX_FILE_NAME_LEN]; + char recvFile[NSTACKX_MAX_FILE_NAME_LEN]; + const char *p[1]; + + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_WLAN_CATEGORY | NSTACKX_CAPS_NO_RTT, NSTACKX_WLAN_CAT_TCP); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, + (uint8_t *)key.c_str(), keyLen, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, + (uint8_t *)key.c_str(), keyLen, MsgReceiver); + ASSERT_GT(cid, 0); + + ret = sprintf_s(sendFile, sizeof(sendFile), "%s-0", DFILE_SEND_FILE_NAME_100M); + ASSERT_GE(ret, 0); + p[0] = sendFile; + ret = NSTACKX_DFileSendFiles(cid, p, 1, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + int second = 120; + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ASSERT_GE(g_recvSucc, 1); + ret = sprintf_s(recvFile, sizeof(recvFile), "%s-0", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M); + ASSERT_GE(ret, 0); + + ret = FileMd5Equal(sendFile, recvFile); + ASSERT_EQ(ret, NSTACKX_TRUE); + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(BREAKPOINT_RESUME_SETUP_AND_TEARDOWN, DISABLED_NSTACKX_DFileMPTcpEscapeTimeout) +{ + int sendNums = 5; + int second = 120; + char sendFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + char recvFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + const char *p[sendNums]; + + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_WLAN_CATEGORY | NSTACKX_CAPS_NO_RTT, NSTACKX_WLAN_CAT_TCP); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(cid, 0); + + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(sendFile[i], NSTACKX_MAX_FILE_NAME_LEN, + "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + p[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(cid, p, sendNums, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + sleep(1); + const char *cmd[2] = { + "iptables -A INPUT -p tcp --dport 8097 -j REJECT", + "iptables -A OUTPUT -p tcp --sport 8097 -j REJECT", + }; + + for (int i = 0; i < CMD_COUNT; i++) { + ret = system(cmd[i]); + ASSERT_GE(ret, NSTACKX_EOK); + } + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + ASSERT_GE(g_recvSucc, sendNums); + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(recvFile[i], NSTACKX_MAX_FILE_NAME_LEN, "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(BREAKPOINT_RESUME_SETUP_AND_TEARDOWN, DISABLED_NSTACKX_DFileMPUdpEscapeTimeout) +{ + int sendNums = 5; + int second = 120; + char sendFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + char recvFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + const char *p[sendNums]; + + NSTACKX_DFileSetCapabilities(0, 0); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(cid, 0); + + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(sendFile[i], NSTACKX_MAX_FILE_NAME_LEN, + "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + p[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(cid, p, sendNums, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + sleep(1); + const char *cmd[2] = { + "iptables -A INPUT -p udp --dport 8097 -j REJECT", + "iptables -A OUTPUT -p udp --sport 8097 -j REJECT", + }; + + for (int i = 0; i < CMD_COUNT; i++) { + ret = system(cmd[i]); + ASSERT_GE(ret, NSTACKX_EOK); + } + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ASSERT_GE(g_recvSucc, sendNums); + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(recvFile[i], NSTACKX_MAX_FILE_NAME_LEN, "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(BREAKPOINT_RESUME_SETUP_AND_TEARDOWN, DISABLED_NSTACKX_DFileMPLinkSeqEscapeTimeout) +{ + int sendNums = 5; + int second = 120; + char sendFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + char recvFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + const char *p[sendNums]; + + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_LINK_SEQUENCE | NSTACKX_CAPS_WLAN_CATEGORY, + SET_CAPABILITIES_VALUE_FOUR); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(cid, 0); + + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(sendFile[i], NSTACKX_MAX_FILE_NAME_LEN, + "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + p[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(cid, p, sendNums, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + sleep(1); + const char *cmd[2] = { + "iptables -A INPUT -p udp --dport 8097 -j REJECT", + "iptables -A OUTPUT -p udp --sport 8097 -j REJECT", + }; + + for (int i = 0; i < CMD_COUNT; i++) { + ret = system(cmd[i]); + ASSERT_GE(ret, NSTACKX_EOK); + } + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ASSERT_GE(g_recvSucc, sendNums); + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(recvFile[i], NSTACKX_MAX_FILE_NAME_LEN, "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(MpEscape_SETUP_AND_TEARDOWN, DISABLED_NstackxDFileMPTcpEscapeDisconnect) +{ + int sendNums = 5; + int second = 120; + char sendFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + char recvFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + const char *p[sendNums]; + + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_WLAN_CATEGORY, NSTACKX_WLAN_CAT_TCP); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(cid, 0); + + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(sendFile[i], NSTACKX_MAX_FILE_NAME_LEN, + "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + p[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(cid, p, sendNums, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + sleep(1); + system("ip tuntap del dev tap0 mod tap"); + ASSERT_GE(ret, NSTACKX_EOK); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ASSERT_GE(g_recvSucc, sendNums); + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(recvFile[i], NSTACKX_MAX_FILE_NAME_LEN, "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(MpEscape_SETUP_AND_TEARDOWN, DISABLED_NstackxDFileMPUdpEscapeDisconnect) +{ + int sendNums = 5; + int second = 120; + char sendFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + char recvFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + const char *p[sendNums]; + + NSTACKX_DFileSetCapabilities(0, 0); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(cid, 0); + + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(sendFile[i], NSTACKX_MAX_FILE_NAME_LEN, + "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + p[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(cid, p, sendNums, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + sleep(1); + system("ip tuntap del dev tap0 mod tap"); + ASSERT_GE(ret, NSTACKX_EOK); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ASSERT_GE(g_recvSucc, sendNums); + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(recvFile[i], NSTACKX_MAX_FILE_NAME_LEN, "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST_F(MpEscape_SETUP_AND_TEARDOWN, DISABLED_NstackxDFileMPLinkSeqEscapeDisconnect) +{ + int sendNums = 5; + int second = 120; + char sendFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + char recvFile[sendNums][NSTACKX_MAX_FILE_NAME_LEN]; + const char *p[sendNums]; + + NSTACKX_DFileSetCapabilities(NSTACKX_CAPS_LINK_SEQUENCE | NSTACKX_CAPS_WLAN_CATEGORY, SET_CAPABILITIES_VALUE_FOUR); + int32_t sid = NSTACKX_DFileServerMp(g_mp_serverPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(sid, 0); + + int32_t ret = NSTACKX_DFileSetStoragePath(sid, DFILE_DEFAULT_STORAGE_PATH); + ASSERT_EQ(ret, 0); + + int32_t cid = NSTACKX_DFileClientMp(g_mp_clinetPara, DFILE_MP_PARA_NUM, nullptr, 0, MsgReceiver); + ASSERT_GT(cid, 0); + + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(sendFile[i], NSTACKX_MAX_FILE_NAME_LEN, + "%s-%d", DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + p[i] = sendFile[i]; + } + ret = NSTACKX_DFileSendFiles(cid, p, sendNums, nullptr); + ASSERT_EQ(ret, NSTACKX_EOK); + + sleep(1); + system("ip tuntap del dev tap0 mod tap"); + ASSERT_GE(ret, NSTACKX_EOK); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ASSERT_GE(g_recvSucc, sendNums); + for (int i = 0; i < sendNums; i++) { + ret = sprintf_s(recvFile[i], NSTACKX_MAX_FILE_NAME_LEN, "%s-%d", + DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME_100M, i); + ASSERT_GE(ret, 0); + ret = FileMd5Equal(sendFile[i], recvFile[i]); + ASSERT_EQ(ret, NSTACKX_TRUE); + } + + NSTACKX_DFileClose(sid); + NSTACKX_DFileClose(cid); + sleep(1); +} + +TEST(NSTACKX_DFILE, CheckDecodeSettingFrameDfxPayload) +{ + int32_t ret = NSTACKX_EOK; + uint8_t *buf = (uint8_t *)calloc(14720, sizeof(uint8_t)); + if (buf == nullptr) { + return; + } + SettingFrame hostSettingFrame; + (void)memset_s(&hostSettingFrame, sizeof(SettingFrame), 0, sizeof(SettingFrame)); + + (void)memset_s(buf, 14720, 0x01, 14720); + SettingFrame *settingFrame = (SettingFrame *)buf; + settingFrame->header.type = NSTACKX_DFILE_SETTING_FRAME; + settingFrame->header.flag = 0; + settingFrame->header.sessionId = 0; + settingFrame->header.transId = 0; + settingFrame->header.length = htons(14720 - DFILE_FRAME_HEADER_LEN); + settingFrame->connType = htons(CONNECT_TYPE_P2P); + settingFrame->mtu = htons(14720); + + ret = DecodeSettingFrame((SettingFrame *)buf, &hostSettingFrame); + ASSERT_EQ(ret, NSTACKX_EOK); + ASSERT_EQ(strlen(hostSettingFrame.productVersion), (size_t)0); + + settingFrame->header.length = htons(sizeof(SettingFrame) - DFILE_FRAME_HEADER_LEN); + ret = DecodeSettingFrame((SettingFrame *)buf, &hostSettingFrame); + ASSERT_EQ(ret, NSTACKX_EOK); + ASSERT_EQ(strlen(hostSettingFrame.productVersion), (size_t)0); + + if (strcpy_s(settingFrame->productVersion, VERSION_STR_LEN, "123456") != EOK) { + printf("strcpy productVersion failed!\n"); + free(buf); + return; + } + ret = DecodeSettingFrame((SettingFrame *)buf, &hostSettingFrame); + ASSERT_EQ(ret, NSTACKX_EOK); + ASSERT_EQ(strlen(hostSettingFrame.productVersion), (size_t)6); + printf("productVersion:%s\n", hostSettingFrame.productVersion); + + (void)memset_s(settingFrame->productVersion, VERSION_STR_LEN, 0, VERSION_STR_LEN); + ret = DecodeSettingFrame((SettingFrame *)buf, &hostSettingFrame); + ASSERT_EQ(ret, NSTACKX_EOK); + ASSERT_EQ(strlen(hostSettingFrame.productVersion), (size_t)0); + + free(buf); +} + +static void MsgReceiverWithSem(int32_t sid, DFileMsgType msgType, const DFileMsg *msg) +{ + (void)msg; + printf("MsgReceiver: session %d, msgtype: %d\n", sid, msgType); + if (msgType == DFILE_ON_CONNECT_SUCCESS) { + printf("Callback:connect success\n"); + SemPost(&g_sem); + } + if (msgType == DFILE_ON_FILE_RECEIVE_SUCCESS) { + for (uint32_t i = 0; i < msg->fileList.fileNum; i++) { + printf("MsgReceiver: recv success, %s\n", msg->fileList.files[i]); + } + g_recvSucc += msg->fileList.fileNum; + } + if (msgType == DFILE_ON_FILE_SEND_FAIL || msgType == DFILE_ON_FATAL_ERROR) { + for (uint32_t i = 0; i < msg->fileList.fileNum; i++) { + printf("MsgReceiver: rest files, %s\n", msg->fileList.files[i]); + } + if (msg->fileList.fileNum) { + int ret = NSTACKX_DFileSendFiles(g_cid, msg->fileList.files, msg->fileList.fileNum, nullptr); + EXPECT_EQ(ret, 0); + g_restFileNums = msg->fileList.fileNum; + } + } + return; +} + +TEST_F(NSTACKX_DFILE_WITH_SETUP_AND_TEARDOWN, DFileGetFileList) +{ + const char *files[NSTACKX_DFILE_MAX_FILE_NUM] = { nullptr }; + int second = 10; + SemInit(&g_sem, 0, 0); + int ssid = NSTACKX_DFileServer(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiverWithSem); + ASSERT_GT(ssid, 0); + + int ret = NSTACKX_DFileSetStoragePath(ssid, DFILE_DEFAULT_STORAGE_PATH); + EXPECT_EQ(ret, 0); + + int csid = NSTACKX_DFileClient(&g_defaultAddr, sizeof(g_defaultAddr), nullptr, 0, MsgReceiverWithSem); + EXPECT_GT(csid, 0); + + struct timespec expire; + expire.tv_sec = SLEEP_SECOND_LOW; + expire.tv_nsec = 0; + ret = SemTimedWait(&g_sem, expire); + EXPECT_EQ(ret, 0); + + DFileOpt opt; + opt.optType = OPT_TYPE_CLEAR_POLICY; + opt.value = CLEAR_POLICY_NOTHING; + opt.valLen = sizeof(DFileOptValueClearPolicy); + ret = NSTACKX_DFileSetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + + files[0] = DFILE_SEND_FILE_NAME; + ret = NSTACKX_DFileSendFiles(csid, files, 1, nullptr); + EXPECT_EQ(ret, 0); + + while (second) { + if (g_recvSucc) { + break; + } + sleep(1); + second--; + } + + ret = NSTACKX_DFileGetSessionOpt(csid, &opt); + EXPECT_EQ(ret, 0); + ASSERT_GE(g_recvSucc, 1); + + ret = NSTACKX_DFileSessionGetFileList(csid); + EXPECT_EQ(ret, 0); + ret = NSTACKX_DFileSessionGetFileList(ssid); + EXPECT_EQ(ret, 0); + + ret = FileMd5Equal((char *)DFILE_SEND_FILE_NAME, (char *)DFILE_DEFAULT_STORAGE_PATH DFILE_SEND_FILE_NAME); + ASSERT_EQ(ret, NSTACKX_TRUE); + + SemDestroy(&g_sem); + NSTACKX_DFileClose(csid); + NSTACKX_DFileClose(ssid); + + sleep(1); +} \ No newline at end of file diff --git a/test/unittest/test_dstream_gtest.cpp b/test/unittest/test_dstream_gtest.cpp new file mode 100644 index 0000000..ff50203 --- /dev/null +++ b/test/unittest/test_dstream_gtest.cpp @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 "fillpadapt.h" +#include "fillpinc.h" +#include "socket_common.h" +#ifdef FILLP_LINUX +#include +#include +#endif + +using namespace testing::ext; + +class NSTACK_DSTREAM_WITH_SETUP_AND : public testing::Test { +public: + void SetUp() + { + Ftinit(); + } + void TearDown() + { + FtDestroy(); + } +}; + +#ifndef DTFUZZ_TEST_TIMES +#define DTFUZZ_TEST_TIMES 30000000 +#endif +#ifndef DTFUZZ_TEST_TIME_OUT +#define DTFUZZ_TEST_TIME_OUT 10800 // second, 3 hours max +#endif + +#define LOOPBACK_IP "127.0.0.1" +char g_addr[32] = LOOPBACK_IP; +bool g_isServer = false; +bool g_isIpv6 = false; + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, create_socket_001, TestSize.Level1) +{ + int ret = 0; + ret = FtSocket(*(int *)DT_SetGetS32(&g_Element[0], 0x01), *(int *)DT_SetGetS32(&g_Element[1], 0x01), + *(int *)DT_SetGetS32(&g_Element[2], 0x01)); + EXPECT_EQ(0, ret); + ret = FtClose(ret); + + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_bind_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + int ret = FtBind(fd, g_addr, len); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_listen_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + int ret = FtBind(fd, g_addr, len); + EXPECT_EQ(0, ret); + + FtListen(fd, 10); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_accept_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + int ret = FtBind(fd, g_addr, len); + EXPECT_EQ(0, ret); + + FtListen(fd, 10); + + ret = FtAccept(fd, g_addr, &len); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_connect_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + ret = FtConnect(fd, g_addr, len); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftsend_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + ret = FtConnect(fd, g_addr, len); + EXPECT_EQ(0, ret); + + char data[256]; + int datalen = 255; + ret = FtSend(fd, data, datalen, 0); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftsendframe_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + ret = FtConnect(fd, g_addr, len); + EXPECT_EQ(0, ret); + + char data[256]; + int datalen = 255; + ret = FtSendFrame(fd, data, datalen, 0); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftsendframeext_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + ret = FtConnect(fd, g_addr, len); + EXPECT_EQ(0, ret); + + char data[256]; + int datalen = 255; + ret = FtSendFrameExt(fd, data, datalen, 0); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftsendframeext_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + FtEventCbkInfo evtInfo = {0}; + int ret = FtApiEventInfoGet(fd, &evtInfo); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftrecv_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + + int ret = FtBind(fd, g_addr, len); + EXPECT_EQ(0, ret); + + FtListen(fd, 10); + + ret = FtAccept(fd, g_addr, &len); + EXPECT_EQ(0, ret); + + char data[255] = 0; + int datalen = 255; + ret = FtRecv(fd, data, datalen, 0); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftwritev_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + int iovCount = 10; + struct iovec *iov = (struct iovec *)malloc(iovCount * sizeof(struct iovec)); + for (int i = 0; i < iovCount; i++) { + iov[i].iov_len = *(int *)DT_SetGetNumberRange(&g_Element[2 + i], 0, 0, 100); + if (iov[i].iov_len == 0) { + iov[i].iov_base = NULL; + } else { + iov[i].iov_base = malloc(iov[i].iov_len); + } + } + int ret = FtWritev(fd, iov, iovCount); + EXPECT_EQ(0, ret); + free(iov); + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftgetsockname_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + char *addr = (char *)malloc(len); + + int ret = FtGetSockName(fd, addr, &len); + EXPECT_EQ(0, ret); + free(addr); + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftgetpeerkname_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = sizeof(struct sockaddr_in); + if (sizeof(struct sockaddr_in6) > len) { + len = sizeof(struct sockaddr_in6); + } + char *addr = (char *)malloc(len); + int ret = FtGetPeerName(fd, addr, &len); + EXPECT_EQ(0, ret); + + free(addr); + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftgetsockopt_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = 255; + char *addr = (char *)malloc(len); + int ret = FtGetSockOpt(fd, 0, 0, addr, &len); + EXPECT_EQ(0, ret); + free(addr); + ret = FtClose(fd); + EXPECT_EQ(0, ret); +} + +HWTEST_F(NSTACK_DSTREAM_WITH_SETUP_AND, socket_ftsetsockopt_001, TestSize.Level1) +{ + int fd = FtSocket(AF_INET, SOCK_STREAM, IPPROTO_FILLP); + int flags = 1; + FtIoctl(fd, FILLP_FIONBIO, &flags); + + size_t len = 255; + char *addr = (char *)malloc(len); + int ret = FtSetSockOpt(fd, 0, 0, addr, &len); + EXPECT_EQ(0, ret); + + ret = FtClose(fd); + EXPECT_EQ(0, ret); +}