From b04cd08cc8607b499583008b2351de5f522c8481 Mon Sep 17 00:00:00 2001 From: William Jordan Date: Tue, 1 Dec 2020 17:00:23 -0500 Subject: [PATCH] Add netlink and gen netlink library loader. Netlink and generic netlink are standard linux interfaces to allow management traffic between user space and kernel subsystems over sockets. This patch adds a loader for the generic netlink library to allow Level 0 Sysman to manage linux hardware that implements the generic netlink interface. ULTs updated. Signed-off-by: William Jordan --- level_zero/CMakeLists.txt | 11 +- .../source/sysman/linux/nl_api/CMakeLists.txt | 22 ++ .../source/sysman/linux/nl_api/nl_api.cpp | 253 +++++++++++++++++ .../tools/source/sysman/linux/nl_api/nl_api.h | 136 +++++++++ .../sysman/linux/nl_api/CMakeLists.txt | 16 ++ .../sysman/linux/nl_api/mock_nl_api.cpp | 261 ++++++++++++++++++ .../sources/sysman/linux/nl_api/mock_nl_api.h | 65 +++++ .../linux/nl_api/test_sysman_nl_api.cpp | 213 ++++++++++++++ 8 files changed, 976 insertions(+), 1 deletion(-) create mode 100644 level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt create mode 100644 level_zero/tools/source/sysman/linux/nl_api/nl_api.cpp create mode 100644 level_zero/tools/source/sysman/linux/nl_api/nl_api.h create mode 100644 level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt create mode 100644 level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.cpp create mode 100644 level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.h create mode 100644 level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp diff --git a/level_zero/CMakeLists.txt b/level_zero/CMakeLists.txt index 008b05a61a..78477dfc29 100644 --- a/level_zero/CMakeLists.txt +++ b/level_zero/CMakeLists.txt @@ -61,7 +61,7 @@ if(BUILD_WITH_L0) endif() if(UNIX) - # Xml Library + # Xml Package find_package(LibXml2) if(PC_LIBXML_FOUND) include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR}) @@ -69,6 +69,15 @@ if(BUILD_WITH_L0) else() message(STATUS "LibXml2 Library headers not available. Building without.") endif() + # Netlink and Generic Netlink + find_path(LIBGENL_INCLUDE_DIR netlink/genl/genl.h PATH_SUFFIXES libnl3) + if(LIBGENL_INCLUDE_DIR) + message(STATUS "LibGenl headers directory: ${LIBGENL_INCLUDE_DIR}") + include_directories(SYSTEM ${LIBGENL_INCLUDE_DIR}) + set(LIBGENL_FOUND TRUE) + else() + message(STATUS "LibGenl headers not available. Building without") + endif() endif() if(UNIX) diff --git a/level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt b/level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt new file mode 100644 index 0000000000..75f26f0c8f --- /dev/null +++ b/level_zero/tools/source/sysman/linux/nl_api/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(LIBGENL_FOUND) + set(L0_SRCS_TOOLS_SYSMAN_LINUX_NL_API + ${CMAKE_CURRENT_SOURCE_DIR}/nl_api.h + ${CMAKE_CURRENT_SOURCE_DIR}/nl_api.cpp + ) +endif() + +if(UNIX) + target_sources(${L0_STATIC_LIB_NAME} + PRIVATE + ${L0_SRCS_TOOLS_SYSMAN_LINUX_NL_API} + ) +endif() + +# Make our source files visible to parent +set_property(GLOBAL PROPERTY L0_SRCS_TOOLS_SYSMAN_LINUX_NL_API ${L0_SRCS_TOOLS_SYSMAN_LINUX_NL_API}) diff --git a/level_zero/tools/source/sysman/linux/nl_api/nl_api.cpp b/level_zero/tools/source/sysman/linux/nl_api/nl_api.cpp new file mode 100644 index 0000000000..dc04eb8668 --- /dev/null +++ b/level_zero/tools/source/sysman/linux/nl_api/nl_api.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "nl_api.h" + +namespace L0 { + +static constexpr std::string_view libgenlFile = "libnl-genl-3.so.200"; +static constexpr std::string_view genlConnectRoutine = "genl_connect"; +static constexpr std::string_view genlCtrlResolveRoutine = "genl_ctrl_resolve"; +static constexpr std::string_view genlHandleMsgRoutine = "genl_handle_msg"; +static constexpr std::string_view genlmsgPutRoutine = "genlmsg_put"; +static constexpr std::string_view genlOpsResolveRoutine = "genl_ops_resolve"; +static constexpr std::string_view genlRegisterFamilyRoutine = "genl_register_family"; +static constexpr std::string_view genlUnregisterFamilyRoutine = "genl_unregister_family"; +static constexpr std::string_view nlRecvmsgsDefaultRoutine = "nl_recvmsgs_default"; +static constexpr std::string_view nlSendAutoRoutine = "nl_send_auto"; +static constexpr std::string_view nlSocketAllocRoutine = "nl_socket_alloc"; +static constexpr std::string_view nlSocketDisableSeqCheckRoutine = "nl_socket_disable_seq_check"; +static constexpr std::string_view nlSocketFreeRoutine = "nl_socket_free"; +static constexpr std::string_view nlSocketModifyCbRoutine = "nl_socket_modify_cb"; +static constexpr std::string_view nlaDataRoutine = "nla_data"; +static constexpr std::string_view nlaGetU32Routine = "nla_get_u32"; +static constexpr std::string_view nlaGetU64Routine = "nla_get_u64"; +static constexpr std::string_view nlaGetU8Routine = "nla_get_u8"; +static constexpr std::string_view nlaIsNestedRoutine = "nla_is_nested"; +static constexpr std::string_view nlaLenRoutine = "nla_len"; +static constexpr std::string_view nlaNextRoutine = "nla_next"; +static constexpr std::string_view nlaOkRoutine = "nla_ok"; +static constexpr std::string_view nlaPutU16Routine = "nla_put_u16"; +static constexpr std::string_view nlaPutU32Routine = "nla_put_u32"; +static constexpr std::string_view nlaPutU64Routine = "nla_put_u64"; +static constexpr std::string_view nlaPutU8Routine = "nla_put_u8"; +static constexpr std::string_view nlaTypeRoutine = "nla_type"; +static constexpr std::string_view nlmsgAllocRoutine = "nlmsg_alloc"; +static constexpr std::string_view nlmsgAttrdataRoutine = "nlmsg_attrdata"; +static constexpr std::string_view nlmsgAttrlenRoutine = "nlmsg_attrlen"; +static constexpr std::string_view nlmsgFreeRoutine = "nlmsg_free"; +static constexpr std::string_view nlmsgHdrRoutine = "nlmsg_hdr"; + +template +bool NlApi::getSymbolAddr(const std::string_view &name, T &sym) { + sym = reinterpret_cast(genlLibraryHandle->getProcAddress(std::string(name))); + return nullptr != sym; +} + +bool NlApi::loadEntryPoints() { + if (!isAvailable()) + return false; + + bool ok = true; + ok = getSymbolAddr(genlConnectRoutine, genlConnectEntry); + ok = ok && getSymbolAddr(genlCtrlResolveRoutine, genlCtrlResolveEntry); + ok = ok && getSymbolAddr(genlHandleMsgRoutine, genlHandleMsgEntry); + ok = ok && getSymbolAddr(genlmsgPutRoutine, genlmsgPutEntry); + ok = ok && getSymbolAddr(genlOpsResolveRoutine, genlOpsResolveEntry); + ok = ok && getSymbolAddr(genlRegisterFamilyRoutine, genlRegisterFamilyEntry); + ok = ok && getSymbolAddr(genlUnregisterFamilyRoutine, genlUnregisterFamilyEntry); + ok = ok && getSymbolAddr(nlRecvmsgsDefaultRoutine, nlRecvmsgsDefaultEntry); + ok = ok && getSymbolAddr(nlSendAutoRoutine, nlSendAutoEntry); + ok = ok && getSymbolAddr(nlSocketAllocRoutine, nlSocketAllocEntry); + ok = ok && getSymbolAddr(nlSocketDisableSeqCheckRoutine, nlSocketDisableSeqCheckEntry); + ok = ok && getSymbolAddr(nlSocketFreeRoutine, nlSocketFreeEntry); + ok = ok && getSymbolAddr(nlSocketModifyCbRoutine, nlSocketModifyCbEntry); + ok = ok && getSymbolAddr(nlaDataRoutine, nlaDataEntry); + ok = ok && getSymbolAddr(nlaGetU32Routine, nlaGetU32Entry); + ok = ok && getSymbolAddr(nlaGetU64Routine, nlaGetU64Entry); + ok = ok && getSymbolAddr(nlaGetU8Routine, nlaGetU8Entry); + ok = ok && getSymbolAddr(nlaIsNestedRoutine, nlaIsNestedEntry); + ok = ok && getSymbolAddr(nlaLenRoutine, nlaLenEntry); + ok = ok && getSymbolAddr(nlaNextRoutine, nlaNextEntry); + ok = ok && getSymbolAddr(nlaOkRoutine, nlaOkEntry); + ok = ok && getSymbolAddr(nlaPutU16Routine, nlaPutU16Entry); + ok = ok && getSymbolAddr(nlaPutU32Routine, nlaPutU32Entry); + ok = ok && getSymbolAddr(nlaPutU64Routine, nlaPutU64Entry); + ok = ok && getSymbolAddr(nlaPutU8Routine, nlaPutU8Entry); + ok = ok && getSymbolAddr(nlaTypeRoutine, nlaTypeEntry); + ok = ok && getSymbolAddr(nlmsgAllocRoutine, nlmsgAllocEntry); + ok = ok && getSymbolAddr(nlmsgAttrdataRoutine, nlmsgAttrdataEntry); + ok = ok && getSymbolAddr(nlmsgAttrlenRoutine, nlmsgAttrlenEntry); + ok = ok && getSymbolAddr(nlmsgFreeRoutine, nlmsgFreeEntry); + ok = ok && getSymbolAddr(nlmsgHdrRoutine, nlmsgHdrEntry); + + return ok; +} + +int NlApi::genlConnect(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == genlConnectEntry); + return (*genlConnectEntry)(sock); +} + +int NlApi::genlCtrlResolve(struct nl_sock *sock, const char *name) { + UNRECOVERABLE_IF(nullptr == genlCtrlResolveEntry); + return (*genlCtrlResolveEntry)(sock, name); +} + +int NlApi::genlHandleMsg(struct nl_msg *msg, void *arg) { + UNRECOVERABLE_IF(nullptr == genlHandleMsgEntry); + return (*genlHandleMsgEntry)(msg, arg); +} + +void *NlApi::genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) { + UNRECOVERABLE_IF(nullptr == genlmsgPutEntry); + return (*genlmsgPutEntry)(msg, port, seq, family, hdrlen, flags, cmd, version); +} + +int NlApi::genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops) { + UNRECOVERABLE_IF(nullptr == genlOpsResolveEntry); + return (*genlOpsResolveEntry)(sock, ops); +} + +int NlApi::genlRegisterFamily(struct genl_ops *ops) { + UNRECOVERABLE_IF(nullptr == genlRegisterFamilyEntry); + return (*genlRegisterFamilyEntry)(ops); +} + +int NlApi::genlUnregisterFamily(struct genl_ops *ops) { + UNRECOVERABLE_IF(nullptr == genlUnregisterFamilyEntry); + return (*genlUnregisterFamilyEntry)(ops); +} + +int NlApi::nlRecvmsgsDefault(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == nlRecvmsgsDefaultEntry); + return (*nlRecvmsgsDefaultEntry)(sock); +} + +int NlApi::nlSendAuto(struct nl_sock *sock, struct nl_msg *msg) { + UNRECOVERABLE_IF(nullptr == nlSendAutoEntry); + return (*nlSendAutoEntry)(sock, msg); +} + +struct nl_sock *NlApi::nlSocketAlloc() { + UNRECOVERABLE_IF(nullptr == nlSocketAllocEntry); + return (*nlSocketAllocEntry)(); +} + +void NlApi::nlSocketDisableSeqCheck(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == nlSocketDisableSeqCheckEntry); + (*nlSocketDisableSeqCheckEntry)(sock); + return; +} + +void NlApi::nlSocketFree(struct nl_sock *sock) { + UNRECOVERABLE_IF(nullptr == nlSocketFreeEntry); + (*nlSocketFreeEntry)(sock); + return; +} + +int NlApi::nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg) { + UNRECOVERABLE_IF(nullptr == nlSocketModifyCbEntry); + return (*nlSocketModifyCbEntry)(sock, type, kind, cb, arg); +} + +void *NlApi::nlaData(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaDataEntry); + return (*nlaDataEntry)(attr); +} + +uint32_t NlApi::nlaGetU32(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaGetU32Entry); + return (*nlaGetU32Entry)(attr); +} + +uint64_t NlApi::nlaGetU64(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaGetU64Entry); + return (*nlaGetU64Entry)(attr); +} + +uint8_t NlApi::nlaGetU8(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaGetU8Entry); + return (*nlaGetU8Entry)(attr); +} + +int NlApi::nlaIsNested(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaIsNestedEntry); + return (*nlaIsNestedEntry)(attr); +} + +int NlApi::nlaLen(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaLenEntry); + return (*nlaLenEntry)(attr); +} + +struct nlattr *NlApi::nlaNext(const struct nlattr *attr, int *remaining) { + UNRECOVERABLE_IF(nullptr == nlaNextEntry); + return (*nlaNextEntry)(attr, remaining); +} + +int NlApi::nlaOk(const struct nlattr *attr, int remaining) { + UNRECOVERABLE_IF(nullptr == nlaOkEntry); + return (*nlaOkEntry)(attr, remaining); +} + +int NlApi::nlaPutU16(struct nl_msg *msg, int id, uint16_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU16Entry); + return (*nlaPutU16Entry)(msg, id, data); +} + +int NlApi::nlaPutU32(struct nl_msg *msg, int id, uint32_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU32Entry); + return (*nlaPutU32Entry)(msg, id, data); +} + +int NlApi::nlaPutU64(struct nl_msg *msg, int id, uint64_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU64Entry); + return (*nlaPutU64Entry)(msg, id, data); +} + +int NlApi::nlaPutU8(struct nl_msg *msg, int id, uint8_t data) { + UNRECOVERABLE_IF(nullptr == nlaPutU8Entry); + return (*nlaPutU8Entry)(msg, id, data); +} + +int NlApi::nlaType(const struct nlattr *attr) { + UNRECOVERABLE_IF(nullptr == nlaTypeEntry); + return (*nlaTypeEntry)(attr); +} + +struct nl_msg *NlApi::nlmsgAlloc() { + UNRECOVERABLE_IF(nullptr == nlmsgAllocEntry); + return (*nlmsgAllocEntry)(); +} + +struct nlattr *NlApi::nlmsgAttrdata(const struct nlmsghdr *hdr, int attr) { + UNRECOVERABLE_IF(nullptr == nlmsgAttrdataEntry); + return (*nlmsgAttrdataEntry)(hdr, attr); +} + +int NlApi::nlmsgAttrlen(const struct nlmsghdr *hdr, int attr) { + UNRECOVERABLE_IF(nullptr == nlmsgAttrlenEntry); + return (*nlmsgAttrlenEntry)(hdr, attr); +} + +void NlApi::nlmsgFree(struct nl_msg *msg) { + UNRECOVERABLE_IF(nullptr == nlmsgFreeEntry); + (*nlmsgFreeEntry)(msg); + return; +} + +struct nlmsghdr *NlApi::nlmsgHdr(struct nl_msg *msg) { + UNRECOVERABLE_IF(nullptr == nlmsgHdrEntry); + return (*nlmsgHdrEntry)(msg); +} + +NlApi::NlApi() { + genlLibraryHandle.reset(NEO::OsLibrary::load(std::string(libgenlFile))); +} + +} // namespace L0 diff --git a/level_zero/tools/source/sysman/linux/nl_api/nl_api.h b/level_zero/tools/source/sysman/linux/nl_api/nl_api.h new file mode 100644 index 0000000000..8c184ed0e8 --- /dev/null +++ b/level_zero/tools/source/sysman/linux/nl_api/nl_api.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/core/source/device/device.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace L0 { + +typedef int (*pGenlConnect)(struct nl_sock *); +typedef int (*pGenlCtrlResolve)(struct nl_sock *, const char *); +typedef int (*pGenlHandleMsg)(struct nl_msg *, void *); +typedef int (*pGenlOpsResolve)(struct nl_sock *, struct genl_ops *); +typedef int (*pGenlRegisterFamily)(struct genl_ops *); +typedef int (*pGenlUnregisterFamily)(struct genl_ops *); +typedef void *(*pGenlmsgPut)(struct nl_msg *, uint32_t, uint32_t, int, int, int, uint8_t, uint8_t); +typedef int (*pNlRecvmsgsDefault)(struct nl_sock *); +typedef int (*pNlSendAuto)(struct nl_sock *, struct nl_msg *); +typedef struct nl_sock *(*pNlSocketAlloc)(); +typedef void (*pNlSocketDisableSeqCheck)(struct nl_sock *); +typedef void (*pNlSocketFree)(struct nl_sock *); +typedef int (*pNlSocketModifyCb)(struct nl_sock *, enum nl_cb_type, enum nl_cb_kind, nl_recvmsg_msg_cb_t, void *); +typedef void *(*pNlaData)(const struct nlattr *); +typedef uint32_t (*pNlaGetU32)(const struct nlattr *); +typedef uint64_t (*pNlaGetU64)(const struct nlattr *); +typedef uint8_t (*pNlaGetU8)(const struct nlattr *); +typedef int (*pNlaIsNested)(const struct nlattr *); +typedef int (*pNlaLen)(const struct nlattr *); +typedef struct nlattr *(*pNlaNext)(const struct nlattr *, int *); +typedef int (*pNlaOk)(const struct nlattr *, int); +typedef int (*pNlaPutU16)(struct nl_msg *, int, uint16_t); +typedef int (*pNlaPutU32)(struct nl_msg *, int, uint32_t); +typedef int (*pNlaPutU64)(struct nl_msg *, int, uint64_t); +typedef int (*pNlaPutU8)(struct nl_msg *, int, uint8_t); +typedef int (*pNlaType)(const struct nlattr *); +typedef struct nl_msg *(*pNlmsgAlloc)(); +typedef struct nlattr *(*pNlmsgAttrdata)(const struct nlmsghdr *, int); +typedef int (*pNlmsgAttrlen)(const struct nlmsghdr *, int); +typedef void (*pNlmsgFree)(struct nl_msg *); +typedef struct nlmsghdr *(*pNlmsgHdr)(struct nl_msg *); + +class NlApi : public NEO::NonCopyableOrMovableClass { + public: + MOCKABLE_VIRTUAL int genlConnect(struct nl_sock *sock); + MOCKABLE_VIRTUAL int genlCtrlResolve(struct nl_sock *sock, const char *name); + MOCKABLE_VIRTUAL int genlHandleMsg(struct nl_msg *msg, void *arg); + MOCKABLE_VIRTUAL int genlOpsResolve(struct nl_sock *sock, struct genl_ops *ops); + MOCKABLE_VIRTUAL int genlRegisterFamily(struct genl_ops *ops); + MOCKABLE_VIRTUAL int genlUnregisterFamily(struct genl_ops *ops); + MOCKABLE_VIRTUAL void *genlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version); + MOCKABLE_VIRTUAL int nlRecvmsgsDefault(struct nl_sock *sock); + MOCKABLE_VIRTUAL int nlSendAuto(struct nl_sock *sock, struct nl_msg *msg); + MOCKABLE_VIRTUAL struct nl_sock *nlSocketAlloc(); + MOCKABLE_VIRTUAL void nlSocketDisableSeqCheck(struct nl_sock *sock); + MOCKABLE_VIRTUAL void nlSocketFree(struct nl_sock *sock); + MOCKABLE_VIRTUAL int nlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg); + MOCKABLE_VIRTUAL void *nlaData(const struct nlattr *attr); + MOCKABLE_VIRTUAL uint32_t nlaGetU32(const struct nlattr *attr); + MOCKABLE_VIRTUAL uint64_t nlaGetU64(const struct nlattr *attr); + MOCKABLE_VIRTUAL uint8_t nlaGetU8(const struct nlattr *attr); + MOCKABLE_VIRTUAL int nlaIsNested(const struct nlattr *attr); + MOCKABLE_VIRTUAL int nlaLen(const struct nlattr *attr); + MOCKABLE_VIRTUAL struct nlattr *nlaNext(const struct nlattr *attr, int *remaining); + MOCKABLE_VIRTUAL int nlaOk(const struct nlattr *attr, int remaining); + MOCKABLE_VIRTUAL int nlaPutU16(struct nl_msg *msg, int id, uint16_t data); + MOCKABLE_VIRTUAL int nlaPutU32(struct nl_msg *msg, int id, uint32_t data); + MOCKABLE_VIRTUAL int nlaPutU64(struct nl_msg *msg, int id, uint64_t data); + MOCKABLE_VIRTUAL int nlaPutU8(struct nl_msg *msg, int id, uint8_t data); + MOCKABLE_VIRTUAL int nlaType(const struct nlattr *attr); + MOCKABLE_VIRTUAL struct nl_msg *nlmsgAlloc(); + MOCKABLE_VIRTUAL struct nlattr *nlmsgAttrdata(const struct nlmsghdr *hdr, int attr); + MOCKABLE_VIRTUAL int nlmsgAttrlen(const struct nlmsghdr *hdr, int attr); + MOCKABLE_VIRTUAL void nlmsgFree(struct nl_msg *msg); + MOCKABLE_VIRTUAL struct nlmsghdr *nlmsgHdr(struct nl_msg *msg); + + bool isAvailable() { return nullptr != genlLibraryHandle.get(); } + + MOCKABLE_VIRTUAL bool loadEntryPoints(); + + NlApi(); + MOCKABLE_VIRTUAL ~NlApi() = default; + + protected: + template + bool getSymbolAddr(const std::string_view &name, T &sym); + + std::unique_ptr genlLibraryHandle; + + pGenlConnect genlConnectEntry = nullptr; + pGenlCtrlResolve genlCtrlResolveEntry = nullptr; + pGenlHandleMsg genlHandleMsgEntry = nullptr; + pGenlOpsResolve genlOpsResolveEntry = nullptr; + pGenlRegisterFamily genlRegisterFamilyEntry = nullptr; + pGenlUnregisterFamily genlUnregisterFamilyEntry = nullptr; + pGenlmsgPut genlmsgPutEntry = nullptr; + pNlRecvmsgsDefault nlRecvmsgsDefaultEntry = nullptr; + pNlSendAuto nlSendAutoEntry = nullptr; + pNlSocketAlloc nlSocketAllocEntry = nullptr; + pNlSocketDisableSeqCheck nlSocketDisableSeqCheckEntry = nullptr; + pNlSocketFree nlSocketFreeEntry = nullptr; + pNlSocketModifyCb nlSocketModifyCbEntry = nullptr; + pNlaData nlaDataEntry = nullptr; + pNlaGetU32 nlaGetU32Entry = nullptr; + pNlaGetU64 nlaGetU64Entry = nullptr; + pNlaGetU8 nlaGetU8Entry = nullptr; + pNlaIsNested nlaIsNestedEntry = nullptr; + pNlaLen nlaLenEntry = nullptr; + pNlaNext nlaNextEntry = nullptr; + pNlaOk nlaOkEntry = nullptr; + pNlaPutU16 nlaPutU16Entry = nullptr; + pNlaPutU32 nlaPutU32Entry = nullptr; + pNlaPutU64 nlaPutU64Entry = nullptr; + pNlaPutU8 nlaPutU8Entry = nullptr; + pNlaType nlaTypeEntry = nullptr; + pNlmsgAlloc nlmsgAllocEntry = nullptr; + pNlmsgAttrdata nlmsgAttrdataEntry = nullptr; + pNlmsgAttrlen nlmsgAttrlenEntry = nullptr; + pNlmsgFree nlmsgFreeEntry = nullptr; + pNlmsgHdr nlmsgHdrEntry = nullptr; +}; + +} // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt new file mode 100644 index 0000000000..311b7a236a --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(UNIX) + if(LIBGENL_FOUND) + target_sources(${TARGET_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_nl_api.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_nl_api.cpp + ) + endif() +endif() diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.cpp b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.cpp new file mode 100644 index 0000000000..17e21fe1b4 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "mock_nl_api.h" + +namespace L0 { +namespace ult { + +extern "C" { +static int mockCallback(struct nl_msg *msg, void *arg) { + return NL_OK; +} +} + +struct nl_sock MockNlDll::mockNlSock; +struct nl_msg MockNlDll::mockNlMsg; +struct nlmsghdr MockNlDll::mockNlmsghdr; +struct nlattr MockNlDll::mockNlattr; +struct nlattr MockNlDll::mockNextNlattr; +struct genl_ops MockNlDll::mockGenlOps; +nl_recvmsg_msg_cb_t MockNlDll::mockCb = mockCallback; + +extern "C" { +int mockGenlConnect(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return 0; +} + +int mockGenlCtrlResolve(struct nl_sock *sock, const char *name) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_FALSE(strcmp(MockNlDll::mockFamilyName, name)); + return 0; +} + +int mockGenlHandleMsg(struct nl_msg *msg, void *arg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockArgP, arg); + return 0; +} + +void *mockGenlmsgPut(struct nl_msg *msg, uint32_t port, uint32_t seq, int family, int hdrlen, int flags, uint8_t cmd, uint8_t version) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockFamilyId, family); + EXPECT_EQ(MockNlDll::mockPort, port); + EXPECT_EQ(MockNlDll::mockSeq, seq); + EXPECT_EQ(MockNlDll::mockCmd, cmd); + EXPECT_EQ(MockNlDll::mockHdrlen, hdrlen); + EXPECT_EQ(MockNlDll::mockFlags, flags); + EXPECT_EQ(MockNlDll::mockVersion, version); + return msg; +} + +int mockGenlOpsResolve(struct nl_sock *sock, struct genl_ops *ops) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_EQ(&MockNlDll::mockGenlOps, ops); + return 0; +} + +int mockGenlRegisterFamily(struct genl_ops *ops) { + EXPECT_EQ(&MockNlDll::mockGenlOps, ops); + return 0; +} + +int mockGenlUnregisterFamily(struct genl_ops *ops) { + EXPECT_EQ(&MockNlDll::mockGenlOps, ops); + return 0; +} + +struct nl_sock *mockNlSocketAlloc() { + return &MockNlDll::mockNlSock; +} + +void mockNlSocketDisableSeqCheck(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return; +} + +void mockNlSocketFree(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return; +} + +int mockNlSocketModifyCb(struct nl_sock *sock, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t cb, void *arg) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_EQ(MockNlDll::mockCbType, type); + EXPECT_EQ(MockNlDll::mockCbKind, kind); + EXPECT_EQ(MockNlDll::mockCb, cb); + EXPECT_EQ(MockNlDll::mockArgP, arg); + return 0; +} + +int mockNlRecvmsgsDefault(struct nl_sock *sock) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + return 0; +} + +int mockNlSendAuto(struct nl_sock *sock, struct nl_msg *msg) { + EXPECT_EQ(&MockNlDll::mockNlSock, sock); + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + return 0; +} + +void *mockNlaData(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return &MockNlDll::mockNlattr; +} + +uint32_t mockNlaGetU32(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockU32Val; +} + +uint64_t mockNlaGetU64(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockU64Val; +} + +uint8_t mockNlaGetU8(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockU8Val; +} + +int mockNlaIsNested(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return 0; +} + +int mockNlaLen(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockAttrLen; +} + +struct nlattr *mockNlaNext(const struct nlattr *attr, int *remaining) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + EXPECT_EQ(MockNlDll::mockRemainBefore, *remaining); + *remaining = MockNlDll::mockRemainAfter; + return &MockNlDll::mockNextNlattr; +} + +int mockNlaOk(const struct nlattr *attr, int remaining) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + EXPECT_EQ(MockNlDll::mockRemainBefore, remaining); + return 0; +} + +int mockNlaPutU16(struct nl_msg *msg, int type, uint16_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU16Val, data); + return 0; +} + +int mockNlaPutU32(struct nl_msg *msg, int type, uint32_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU32Val, data); + return 0; +} + +int mockNlaPutU64(struct nl_msg *msg, int type, uint64_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU64Val, data); + return 0; +} + +int mockNlaPutU8(struct nl_msg *msg, int type, uint8_t data) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + EXPECT_EQ(MockNlDll::mockType, type); + EXPECT_EQ(MockNlDll::mockU8Val, data); + return 0; +} + +int mockNlaType(const struct nlattr *attr) { + EXPECT_EQ(&MockNlDll::mockNlattr, attr); + return MockNlDll::mockType; +} + +struct nl_msg *mockNlmsgAlloc() { + return &MockNlDll::mockNlMsg; +} + +void mockNlmsgFree(struct nl_msg *msg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + return; +} + +struct nlattr *mockNlmsgAttrdata(const struct nlmsghdr *hdr, int attr) { + EXPECT_EQ(&MockNlDll::mockNlmsghdr, hdr); + EXPECT_EQ(MockNlDll::mockAttr, attr); + return &MockNlDll::mockNlattr; +} + +int mockNlmsgAttrlen(const struct nlmsghdr *hdr, int attr) { + EXPECT_EQ(&MockNlDll::mockNlmsghdr, hdr); + EXPECT_EQ(MockNlDll::mockAttr, attr); + return MockNlDll::mockAttrLen; +} + +struct nlmsghdr *mockNlmsgHdr(struct nl_msg *msg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, msg); + return &MockNlDll::mockNlmsghdr; +} +} + +MockNlDll::MockNlDll() { + funcMap["genl_connect"] = reinterpret_cast(&mockGenlConnect); + funcMap["genl_ctrl_resolve"] = reinterpret_cast(&mockGenlCtrlResolve); + funcMap["genl_handle_msg"] = reinterpret_cast(&mockGenlHandleMsg); + funcMap["genlmsg_put"] = reinterpret_cast(&mockGenlmsgPut); + funcMap["genl_ops_resolve"] = reinterpret_cast(&mockGenlOpsResolve); + funcMap["genl_register_family"] = reinterpret_cast(&mockGenlRegisterFamily); + funcMap["genl_unregister_family"] = reinterpret_cast(&mockGenlUnregisterFamily); + funcMap["nl_recvmsgs_default"] = reinterpret_cast(&mockNlRecvmsgsDefault); + funcMap["nl_send_auto"] = reinterpret_cast(&mockNlSendAuto); + funcMap["nl_socket_alloc"] = reinterpret_cast(&mockNlSocketAlloc); + funcMap["nl_socket_disable_seq_check"] = reinterpret_cast(&mockNlSocketDisableSeqCheck); + funcMap["nl_socket_free"] = reinterpret_cast(&mockNlSocketFree); + funcMap["nl_socket_modify_cb"] = reinterpret_cast(&mockNlSocketModifyCb); + funcMap["nla_data"] = reinterpret_cast(&mockNlaData); + funcMap["nla_get_u32"] = reinterpret_cast(&mockNlaGetU32); + funcMap["nla_get_u64"] = reinterpret_cast(&mockNlaGetU64); + funcMap["nla_get_u8"] = reinterpret_cast(&mockNlaGetU8); + funcMap["nla_is_nested"] = reinterpret_cast(&mockNlaIsNested); + funcMap["nla_len"] = reinterpret_cast(&mockNlaLen); + funcMap["nla_next"] = reinterpret_cast(&mockNlaNext); + funcMap["nla_ok"] = reinterpret_cast(&mockNlaOk); + funcMap["nla_put_u16"] = reinterpret_cast(&mockNlaPutU16); + funcMap["nla_put_u32"] = reinterpret_cast(&mockNlaPutU32); + funcMap["nla_put_u64"] = reinterpret_cast(&mockNlaPutU64); + funcMap["nla_put_u8"] = reinterpret_cast(&mockNlaPutU8); + funcMap["nla_type"] = reinterpret_cast(&mockNlaType); + funcMap["nlmsg_alloc"] = reinterpret_cast(&mockNlmsgAlloc); + funcMap["nlmsg_attrdata"] = reinterpret_cast(&mockNlmsgAttrdata); + funcMap["nlmsg_attrlen"] = reinterpret_cast(&mockNlmsgAttrlen); + funcMap["nlmsg_free"] = reinterpret_cast(&mockNlmsgFree); + funcMap["nlmsg_hdr"] = reinterpret_cast(&mockNlmsgHdr); +} + +void *MockNlDll::getProcAddress(const std::string &procName) { + auto it = funcMap.find(procName); + if (funcMap.end() == it) { + return nullptr; + } else { + return it->second; + } +} + +void MockNlDll::deleteEntryPoint(const std::string &procName) { + auto it = funcMap.find(procName); + if (funcMap.end() != it) { + funcMap.erase(it); + } +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.h b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.h new file mode 100644 index 0000000000..4bfb76f12e --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_api.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h" +#include "level_zero/tools/source/sysman/linux/nl_api/nl_api.h" + +// Define opaque types so variables can be allocated +struct nl_sock { +}; + +struct nl_msg { +}; + +namespace L0 { +namespace ult { + +class MockNlDll : public NEO::OsLibrary { + public: + MOCK_METHOD(bool, isLoaded, (), (override)); + void *getProcAddress(const std::string &procName) override; + + void deleteEntryPoint(const std::string &procName); + + MockNlDll(); + + static struct nl_sock mockNlSock; + static struct nl_msg mockNlMsg; + static struct nlmsghdr mockNlmsghdr; + static struct nlattr mockNlattr; + static struct nlattr mockNextNlattr; + static struct genl_ops mockGenlOps; + static nl_recvmsg_msg_cb_t mockCb; + + constexpr static int mockFamilyId = 0x2020; + constexpr static char mockFamilyName[] = "TestName"; + constexpr static void *mockArgP = nullptr; + constexpr static uint32_t mockPort = NL_AUTO_PID; + constexpr static uint32_t mockSeq = NL_AUTO_SEQ; + constexpr static int mockHdrlen = NLMSG_HDRLEN; + constexpr static int mockFlags = 0; + constexpr static uint8_t mockCmd = 1; + constexpr static uint8_t mockVersion = 2; + constexpr static int mockType = 3; + constexpr static uint8_t mockU8Val = 0x7fU; + constexpr static uint16_t mockU16Val = 0x7fffU; + constexpr static uint32_t mockU32Val = 0x7fffffffU; + constexpr static uint64_t mockU64Val = 0x7fffffffffffffffUL; + constexpr static int mockAttr = 4; + constexpr static int mockAttrLen = 8; + constexpr static int mockRemainBefore = 20; + constexpr static int mockRemainAfter = 16; + constexpr static enum nl_cb_type mockCbType = NL_CB_VALID; + constexpr static enum nl_cb_kind mockCbKind = NL_CB_CUSTOM; + + private: + std::map funcMap; +}; + +} // namespace ult +} // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp new file mode 100644 index 0000000000..37c74c1d67 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/test_sysman_nl_api.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "mock_nl_api.h" + +using ::testing::Invoke; +using ::testing::Return; + +namespace L0 { +namespace ult { + +class PublicNlApi : public NlApi { + public: + using NlApi::genlLibraryHandle; +}; + +class SysmanNlApiFixture : public ::testing::Test { + protected: + PublicNlApi testNlApi; + + void SetUp() override { + auto mockNlDll = std::make_unique(); + + testNlApi.genlLibraryHandle = std::move(mockNlDll); + EXPECT_TRUE(testNlApi.loadEntryPoints()); + } + void TearDown() override { + } + bool testLoadEntryPointsWithMissingFunction(const std::string &procName) { + PublicNlApi localNlApi; + auto mockNlDll = std::make_unique(); + mockNlDll->deleteEntryPoint(procName); + localNlApi.genlLibraryHandle = std::move(mockNlDll); + + return localNlApi.loadEntryPoints(); + } + + public: + static const int testAttr; +}; +const int SysmanNlApiFixture::testAttr = 1; + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenMissingDllEntryPointVerifyLoadEntryPointsFails) { + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_connect")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_ctrl_resolve")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_handle_msg")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genlmsg_put")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_ops_resolve")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_register_family")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("genl_unregister_family")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_recvmsgs_default")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_send_auto")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_alloc")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_disable_seq_check")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_free")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nl_socket_modify_cb")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_data")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_get_u32")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_get_u64")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_get_u8")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_is_nested")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_len")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_next")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_ok")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u16")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u32")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u64")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_put_u8")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nla_type")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_alloc")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_attrdata")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_attrlen")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_free")); + EXPECT_FALSE(testLoadEntryPointsWithMissingFunction("nlmsg_hdr")); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenMissingDllHandleThenVerifyLoadEntryPointsFails) { + testNlApi.genlLibraryHandle.reset(); + EXPECT_FALSE(testNlApi.loadEntryPoints()); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlConnectReturnsZero) { + EXPECT_EQ(0, testNlApi.genlConnect(&MockNlDll::mockNlSock)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlCtrlReturnsZero) { + EXPECT_EQ(0, testNlApi.genlCtrlResolve(&MockNlDll::mockNlSock, const_cast(MockNlDll::mockFamilyName))); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlHandleMsgReturnsZero) { + EXPECT_EQ(0, testNlApi.genlHandleMsg(&MockNlDll::mockNlMsg, MockNlDll::mockArgP)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlmsgPutReturnsValidPointer) { + EXPECT_NE(nullptr, testNlApi.genlmsgPut(&MockNlDll::mockNlMsg, MockNlDll::mockPort, MockNlDll::mockSeq, MockNlDll::mockFamilyId, MockNlDll::mockHdrlen, MockNlDll::mockFlags, MockNlDll::mockCmd, MockNlDll::mockVersion)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlOpsResolveReturnsZero) { + EXPECT_EQ(0, testNlApi.genlOpsResolve(&MockNlDll::mockNlSock, &MockNlDll::mockGenlOps)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlRegisterFamilyReturnsZero) { + EXPECT_EQ(0, testNlApi.genlRegisterFamily(&MockNlDll::mockGenlOps)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyGenlUnregisterFamilyReturnsZero) { + EXPECT_EQ(0, testNlApi.genlUnregisterFamily(&MockNlDll::mockGenlOps)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSocketAllocReturnsValidPointer) { + EXPECT_EQ(&MockNlDll::mockNlSock, testNlApi.nlSocketAlloc()); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSocketDisableSeqCheckCompletesSuccessfully) { + testNlApi.nlSocketDisableSeqCheck(&MockNlDll::mockNlSock); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSocketFreeCompletesSuccessfully) { + testNlApi.nlSocketFree(&MockNlDll::mockNlSock); +} + +TEST_F(SysmanNlApiFixture, GivenValidNlSockWhenCallingNlSocketModifyCbThenVerifyNlSocketModifyCbReturnsZero) { + EXPECT_EQ(0, testNlApi.nlSocketModifyCb(&MockNlDll::mockNlSock, MockNlDll::mockCbType, MockNlDll::mockCbKind, MockNlDll::mockCb, MockNlDll::mockArgP)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlRecvmsgsDefaultReturnsZero) { + EXPECT_EQ(0, testNlApi.nlRecvmsgsDefault(&MockNlDll::mockNlSock)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlSendAutoReturnsZero) { + EXPECT_EQ(0, testNlApi.nlSendAuto(&MockNlDll::mockNlSock, &MockNlDll::mockNlMsg)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaDataReturnsValidPointer) { + EXPECT_NE(nullptr, testNlApi.nlaData(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaGetU32ReturnsValue) { + EXPECT_EQ(MockNlDll::mockU32Val, testNlApi.nlaGetU32(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaGetU64ReturnsValue) { + EXPECT_EQ(MockNlDll::mockU64Val, testNlApi.nlaGetU64(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaGetU8ReturnsValue) { + EXPECT_EQ(MockNlDll::mockU8Val, testNlApi.nlaGetU8(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaIsNestedReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaIsNested(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaLenReturnsValue) { + EXPECT_EQ(MockNlDll::mockAttrLen, testNlApi.nlaLen(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaNextReturnsZero) { + int remaining = MockNlDll::mockRemainBefore; + + EXPECT_EQ(&MockNlDll::mockNextNlattr, testNlApi.nlaNext(&MockNlDll::mockNlattr, &remaining)); + EXPECT_EQ(MockNlDll::mockRemainAfter, remaining); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaOkReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaOk(&MockNlDll::mockNlattr, MockNlDll::mockRemainBefore)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU16ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU16(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU16Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU32ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU32(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU32Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU64ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU64(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU64Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaPutU8ReturnsZero) { + EXPECT_EQ(0, testNlApi.nlaPutU8(&MockNlDll::mockNlMsg, MockNlDll::mockType, MockNlDll::mockU8Val)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlaTypeReturnsType) { + EXPECT_EQ(MockNlDll::mockType, testNlApi.nlaType(&MockNlDll::mockNlattr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgAllocReturnsNlMsg) { + EXPECT_EQ(&MockNlDll::mockNlMsg, testNlApi.nlmsgAlloc()); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgFreeReturnsSuccessfully) { + testNlApi.nlmsgFree(&MockNlDll::mockNlMsg); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgAttrdataReturnsNlattr) { + EXPECT_EQ(&MockNlDll::mockNlattr, testNlApi.nlmsgAttrdata(&MockNlDll::mockNlmsghdr, MockNlDll::mockAttr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgAttrlenReturnsLength) { + EXPECT_EQ(MockNlDll::mockAttrLen, testNlApi.nlmsgAttrlen(&MockNlDll::mockNlmsghdr, MockNlDll::mockAttr)); +} + +TEST_F(SysmanNlApiFixture, GivenNlApiWhenCompleteMockNlDllThenVerifyNlmsgHdrReturnsNlmsghdr) { + EXPECT_EQ(&MockNlDll::mockNlmsghdr, testNlApi.nlmsgHdr(&MockNlDll::mockNlMsg)); +} +} // namespace ult +} // namespace L0