diff --git a/lib/iscsi/iscsi_rpc.c b/lib/iscsi/iscsi_rpc.c index 8167517c0..b6d246317 100644 --- a/lib/iscsi/iscsi_rpc.c +++ b/lib/iscsi/iscsi_rpc.c @@ -825,7 +825,6 @@ spdk_rpc_add_portal_group(struct spdk_jsonrpc_request *request, struct rpc_portal_group req = {}; struct spdk_iscsi_portal *portal_list[MAX_PORTAL] = {}; struct spdk_json_write_ctx *w; - uint64_t cpumask; size_t i = 0; int rc = -1; @@ -836,11 +835,10 @@ spdk_rpc_add_portal_group(struct spdk_jsonrpc_request *request, goto out; } - cpumask = spdk_app_get_core_mask(); for (i = 0; i < req.portal_list.num_portals; i++) { portal_list[i] = spdk_iscsi_portal_create(req.portal_list.portals[i].host, - req.portal_list.portals[i].port, cpumask); + req.portal_list.portals[i].port, NULL); if (portal_list[i] == NULL) { SPDK_ERRLOG("portal_list allocation failed\n"); goto out; diff --git a/lib/iscsi/portal_grp.c b/lib/iscsi/portal_grp.c index fceed3949..039efdbcd 100644 --- a/lib/iscsi/portal_grp.c +++ b/lib/iscsi/portal_grp.c @@ -67,9 +67,11 @@ spdk_iscsi_portal_find_by_addr(const char *host, const char *port) /* Assumes caller allocated host and port strings on the heap */ struct spdk_iscsi_portal * -spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask) +spdk_iscsi_portal_create(const char *host, const char *port, const char *cpumask) { struct spdk_iscsi_portal *p = NULL; + uint64_t core_mask; + int rc; assert(host != NULL); assert(port != NULL); @@ -80,9 +82,9 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask) return NULL; } - p = malloc(sizeof(*p)); + p = calloc(1, sizeof(*p)); if (!p) { - SPDK_ERRLOG("malloc() failed for portal\n"); + SPDK_ERRLOG("calloc() failed for portal\n"); return NULL; } @@ -100,9 +102,34 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask) } else { p->host = strdup(host); } + if (!p->host) { + SPDK_ERRLOG("strdup() failed for host\n"); + goto error_out; + } p->port = strdup(port); - p->cpumask = cpumask; + if (!p->port) { + SPDK_ERRLOG("strdup() failed for host\n"); + goto error_out; + } + + core_mask = spdk_app_get_core_mask(); + + if (cpumask != NULL) { + rc = spdk_app_parse_core_mask(cpumask, &p->cpumask); + if (rc < 0) { + SPDK_ERRLOG("cpumask (%s) is invalid\n", cpumask); + goto error_out; + } + if (p->cpumask == 0) { + SPDK_ERRLOG("cpumask (%s) does not contain core mask (0x%" PRIx64 ")\n", + cpumask, core_mask); + goto error_out; + } + } else { + p->cpumask = core_mask; + } + p->sock = -1; p->group = NULL; /* set at a later time by caller */ p->acceptor_poller = NULL; @@ -110,6 +137,13 @@ spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask) TAILQ_INSERT_TAIL(&g_spdk_iscsi.portal_head, p, g_tailq); return p; + +error_out: + free(p->port); + free(p->host); + free(p); + + return NULL; } void @@ -166,10 +200,8 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring, struct spdk_iscsi_portal **ip, int dry_run) { - char *host = NULL, *port = NULL; - const char *cpumask_str; - uint64_t cpumask = 0; - int n, len, rc = -1; + char *host = NULL, *port = NULL, *cpumask = NULL; + int len, rc = -1; const char *p, *q; if (portalstring == NULL) { @@ -177,6 +209,7 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring, goto error_out; } + /* IP address */ if (portalstring[0] == '[') { /* IPv6 */ p = strchr(portalstring + 1, ']'); @@ -185,114 +218,79 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring, goto error_out; } p++; - n = p - portalstring; - if (!dry_run) { - host = malloc(n + 1); - if (!host) { - SPDK_ERRLOG("malloc() failed for host\n"); - goto error_out; - } - memcpy(host, portalstring, n); - host[n] = '\0'; - } - if (p[0] == '\0') { - if (!dry_run) { - port = malloc(PORTNUMSTRLEN); - if (!port) { - SPDK_ERRLOG("malloc() failed for port\n"); - goto error_out; - } - snprintf(port, PORTNUMSTRLEN, "%d", DEFAULT_PORT); - } - } else { - if (p[0] != ':') { - SPDK_ERRLOG("portal error\n"); - goto error_out; - } - if (!dry_run) { - q = strchr(portalstring, '@'); - if (q == NULL) { - q = portalstring + strlen(portalstring); - } - len = q - p - 1; - - port = malloc(len + 1); - if (!port) { - SPDK_ERRLOG("malloc() failed for port\n"); - goto error_out; - } - memset(port, 0, len + 1); - memcpy(port, p + 1, len); - } - } } else { /* IPv4 */ p = strchr(portalstring, ':'); if (p == NULL) { p = portalstring + strlen(portalstring); } - n = p - portalstring; - if (!dry_run) { - host = malloc(n + 1); - if (!host) { - SPDK_ERRLOG("malloc() failed for host\n"); - goto error_out; - } - memcpy(host, portalstring, n); - host[n] = '\0'; + } + + if (!dry_run) { + len = p - portalstring; + host = malloc(len + 1); + if (host == NULL) { + SPDK_ERRLOG("malloc() failed for host\n"); + goto error_out; } - if (p[0] == '\0') { - if (!dry_run) { - port = malloc(PORTNUMSTRLEN); - if (!port) { - SPDK_ERRLOG("malloc() failed for port\n"); - goto error_out; - } - snprintf(port, PORTNUMSTRLEN, "%d", DEFAULT_PORT); - } - } else { - if (p[0] != ':') { - SPDK_ERRLOG("portal error\n"); + strncpy(host, portalstring, len); + host[len] = '\0'; + } + + /* Port number (IPv4 and IPv6 are the same) */ + if (p[0] == '\0') { + if (!dry_run) { + port = malloc(PORTNUMSTRLEN); + if (!port) { + SPDK_ERRLOG("malloc() failed for port\n"); goto error_out; } - if (!dry_run) { - q = strchr(portalstring, '@'); - if (q == NULL) { - q = portalstring + strlen(portalstring); - } + snprintf(port, PORTNUMSTRLEN, "%d", DEFAULT_PORT); + } + } else { + if (p[0] != ':') { + SPDK_ERRLOG("portal error\n"); + goto error_out; + } + q = strchr(portalstring, '@'); + if (q == NULL) { + q = portalstring + strlen(portalstring); + } + if (q == p) { + SPDK_ERRLOG("no port specified\n"); + goto error_out; + } - if (q == p) { - SPDK_ERRLOG("no port specified\n"); - goto error_out; - } - - len = q - p - 1; - port = malloc(len + 1); - if (!port) { - SPDK_ERRLOG("malloc() failed for port\n"); - goto error_out; - } - memset(port, 0, len + 1); - memcpy(port, p + 1, len); + if (!dry_run) { + len = q - p - 1; + port = malloc(len + 1); + if (port == NULL) { + SPDK_ERRLOG("malloc() failed for port\n"); + goto error_out; } - + strncpy(port, p + 1, len); + port[len] = '\0'; } } + /* Cpumask (IPv4 and IPv6 are the same) */ p = strchr(portalstring, '@'); if (p != NULL) { - cpumask_str = p + 1; - if (spdk_app_parse_core_mask(cpumask_str, &cpumask)) { - SPDK_ERRLOG("invalid portal cpumask %s\n", cpumask_str); + q = portalstring + strlen(portalstring); + if (q == p) { + SPDK_ERRLOG("no cpumask specified\n"); goto error_out; } - if (cpumask == 0) { - SPDK_ERRLOG("no cpu is selected among reactor mask(=%jx)\n", - spdk_app_get_core_mask()); - goto error_out; + if (!dry_run) { + len = q - p - 1; + cpumask = malloc(len + 1); + if (cpumask == NULL) { + SPDK_ERRLOG("malloc() failed for cpumask\n"); + goto error_out; + } + strncpy(cpumask, p + 1, len); + cpumask[len] = '\0'; } - } else { - cpumask = spdk_app_get_core_mask(); } if (!dry_run) { @@ -304,12 +302,9 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring, rc = 0; error_out: - if (host) { - free(host); - } - if (port) { - free(port); - } + free(host); + free(port); + free(cpumask); return rc; } diff --git a/lib/iscsi/portal_grp.h b/lib/iscsi/portal_grp.h index 0f8c5ef08..5f03f3bb4 100644 --- a/lib/iscsi/portal_grp.h +++ b/lib/iscsi/portal_grp.h @@ -58,7 +58,7 @@ struct spdk_iscsi_portal_grp { /* SPDK iSCSI Portal Group management API */ struct spdk_iscsi_portal *spdk_iscsi_portal_create(const char *host, const char *port, - uint64_t cpumask); + const char *cpumask); void spdk_iscsi_portal_destroy(struct spdk_iscsi_portal *p); int spdk_iscsi_portal_grp_create_from_portal_list(int tag, diff --git a/test/unit/lib/iscsi/Makefile b/test/unit/lib/iscsi/Makefile index 99fe1ac3f..396c5a055 100644 --- a/test/unit/lib/iscsi/Makefile +++ b/test/unit/lib/iscsi/Makefile @@ -34,7 +34,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -DIRS-y = conn.c init_grp.c iscsi.c param.c tgt_node.c +DIRS-y = conn.c init_grp.c iscsi.c param.c portal_grp.c tgt_node.c .PHONY: all clean $(DIRS-y) diff --git a/test/unit/lib/iscsi/common.c b/test/unit/lib/iscsi/common.c index 15c0c43f0..def18d783 100644 --- a/test/unit/lib/iscsi/common.c +++ b/test/unit/lib/iscsi/common.c @@ -1,9 +1,11 @@ #include "iscsi/task.h" #include "iscsi/iscsi.h" #include "iscsi/conn.h" +#include "iscsi/acceptor.h" #include "spdk/env.h" #include "spdk/event.h" +#include "spdk/net.h" #include "spdk_internal/log.h" @@ -100,6 +102,51 @@ spdk_scsi_dev_get_name(const struct spdk_scsi_dev *dev) return NULL; } +void +spdk_iscsi_acceptor_start(struct spdk_iscsi_portal *p) +{ +} + +void +spdk_iscsi_acceptor_stop(struct spdk_iscsi_portal *p) +{ +} + +int +spdk_sock_listen(const char *ip, int port) +{ + return 0; +} + +int +spdk_sock_close(int sock) +{ + return 0; +} + +uint64_t +spdk_app_get_core_mask(void) +{ + return 0xFFFFFFFFFFFFFFFF; +} + +int +spdk_app_parse_core_mask(const char *mask, uint64_t *cpumask) +{ + char *end; + + if (mask == NULL || cpumask == NULL) { + return -1; + } + + *cpumask = strtoull(mask, &end, 16); + if (*end != '\0' || errno) { + return -1; + } + + return 0; +} + uint32_t spdk_env_get_current_core(void) { diff --git a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c index 3168d782c..c17b2dc1b 100644 --- a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c +++ b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c @@ -80,11 +80,6 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn, return 0; } -void -spdk_iscsi_acceptor_stop(struct spdk_iscsi_portal *p) -{ -} - void spdk_iscsi_portal_grp_close_all(void) { diff --git a/test/unit/lib/iscsi/portal_grp.c/.gitignore b/test/unit/lib/iscsi/portal_grp.c/.gitignore new file mode 100644 index 000000000..106ffebc2 --- /dev/null +++ b/test/unit/lib/iscsi/portal_grp.c/.gitignore @@ -0,0 +1 @@ +portal_grp_ut diff --git a/test/unit/lib/iscsi/portal_grp.c/Makefile b/test/unit/lib/iscsi/portal_grp.c/Makefile new file mode 100644 index 000000000..2e8088ded --- /dev/null +++ b/test/unit/lib/iscsi/portal_grp.c/Makefile @@ -0,0 +1,57 @@ +# +## BSD LICENSE +# +## Copyright (c) Intel Corporation. +# All rights reserved. +# # +# Redistribution and use in source and binary forms, with or without +# # modification, are permitted provided that the following conditions +# are met: +# # +# * Redistributions of source code must retain the above copyright +# # notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# # notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# # distribution. +# * Neither the name of Intel Corporation nor the names of its +# # contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# # + +SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../../..) +include $(SPDK_ROOT_DIR)/mk/spdk.common.mk +include $(SPDK_ROOT_DIR)/mk/spdk.app.mk + +SPDK_LIB_LIST = log conf util cunit + +CFLAGS += $(ENV_CFLAGS) +CFLAGS += -I$(SPDK_ROOT_DIR)/test +CFLAGS += -I$(SPDK_ROOT_DIR)/lib +LIBS += $(SPDK_LIB_LINKER_ARGS) +LIBS += -lcunit + +APP = portal_grp_ut +C_SRCS = portal_grp_ut.c + +all: $(APP) + +$(APP): $(OBJS) $(SPDK_LIB_FILES) + $(LINK_C) + +clean: + $(CLEAN_C) $(APP) + +include $(SPDK_ROOT_DIR)/mk/spdk.deps.mk diff --git a/test/unit/lib/iscsi/portal_grp.c/portal_grp_ut.c b/test/unit/lib/iscsi/portal_grp.c/portal_grp_ut.c new file mode 100644 index 000000000..13066b9cc --- /dev/null +++ b/test/unit/lib/iscsi/portal_grp.c/portal_grp_ut.c @@ -0,0 +1,336 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "spdk/stdinc.h" +#include "spdk/event.h" + +#include "CUnit/Basic.h" + +#include "../common.c" +#include "iscsi/portal_grp.c" + +struct spdk_iscsi_globals g_spdk_iscsi; + +static int +test_setup(void) +{ + TAILQ_INIT(&g_spdk_iscsi.portal_head); + return 0; +} + +static void +portal_create_ipv4_normal_case(void) +{ + struct spdk_iscsi_portal *p; + + const char *host = "192.168.2.0"; + const char *port = "3260"; + const char *cpumask = "1"; + + p = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p != NULL); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_ipv6_normal_case(void) +{ + struct spdk_iscsi_portal *p; + + const char *host = "[2001:ad6:1234::]"; + const char *port = "3260"; + const char *cpumask = "1"; + + p = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p != NULL); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_ipv4_wildcard_case(void) +{ + struct spdk_iscsi_portal *p; + + const char *host = "*"; + const char *port = "3260"; + const char *cpumask = "1"; + + p = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p != NULL); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_ipv6_wildcard_case(void) +{ + struct spdk_iscsi_portal *p; + + const char *host = "[*]"; + const char *port = "3260"; + const char *cpumask = "1"; + + p = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p != NULL); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_cpumask_null_case(void) +{ + struct spdk_iscsi_portal *p; + + const char *host = "192.168.2.0"; + const char *port = "3260"; + const char *cpumask = NULL; + + p = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p != NULL); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_cpumask_no_bit_on_case(void) +{ + struct spdk_iscsi_portal *p; + + const char *host = "192.168.2.0"; + const char *port = "3260"; + const char *cpumask = "0"; + + p = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p == NULL); +} + +static void +portal_create_twice_case(void) +{ + struct spdk_iscsi_portal *p1, *p2; + + const char *host = "192.168.2.0"; + const char *port = "3260"; + const char *cpumask = "1"; + + p1 = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p1 != NULL); + + p2 = spdk_iscsi_portal_create(host, port, cpumask); + CU_ASSERT(p2 == NULL); + + spdk_iscsi_portal_destroy(p1); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_from_configline_ipv4_normal_case(void) +{ + const char *string = "192.168.2.0:3260@1"; + const char *host_str = "192.168.2.0"; + const char *port_str = "3260"; + uint64_t cpumask_val = 1; + struct spdk_iscsi_portal *p; + int rc; + + rc = spdk_iscsi_portal_create_from_configline(string, &p, 0); + CU_ASSERT(rc == 0); + CU_ASSERT(strcmp(p->host, host_str) == 0); + CU_ASSERT(strcmp(p->port, port_str) == 0); + CU_ASSERT(p->cpumask == cpumask_val); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_from_configline_ipv6_normal_case(void) +{ + const char *string = "[2001:ad6:1234::]:3260@1"; + const char *host_str = "[2001:ad6:1234::]"; + const char *port_str = "3260"; + uint64_t cpumask_val = 1; + struct spdk_iscsi_portal *p; + int rc; + + rc = spdk_iscsi_portal_create_from_configline(string, &p, 0); + CU_ASSERT(rc == 0); + CU_ASSERT(strcmp(p->host, host_str) == 0); + CU_ASSERT(strcmp(p->port, port_str) == 0); + CU_ASSERT(p->cpumask == cpumask_val); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_from_configline_ipv4_skip_cpumask_case(void) +{ + const char *string = "192.168.2.0:3260"; + const char *host_str = "192.168.2.0"; + const char *port_str = "3260"; + uint64_t cpumask_val = 0xFFFFFFFFFFFFFFFF; + struct spdk_iscsi_portal *p; + int rc; + + rc = spdk_iscsi_portal_create_from_configline(string, &p, 0); + CU_ASSERT(rc == 0); + CU_ASSERT(strcmp(p->host, host_str) == 0); + CU_ASSERT(strcmp(p->port, port_str) == 0); + CU_ASSERT(p->cpumask == cpumask_val); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_from_configline_ipv6_skip_cpumask_case(void) +{ + const char *string = "[2001:ad6:1234::]:3260"; + const char *host_str = "[2001:ad6:1234::]"; + const char *port_str = "3260"; + uint64_t cpumask_val = 0xFFFFFFFFFFFFFFFF; + struct spdk_iscsi_portal *p; + int rc; + + rc = spdk_iscsi_portal_create_from_configline(string, &p, 0); + CU_ASSERT(rc == 0); + CU_ASSERT(strcmp(p->host, host_str) == 0); + CU_ASSERT(strcmp(p->port, port_str) == 0); + CU_ASSERT(p->cpumask == cpumask_val); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_from_configline_ipv4_skip_port_and_cpumask_case(void) +{ + const char *string = "192.168.2.0"; + const char *host_str = "192.168.2.0"; + const char *port_str = "3260"; + uint64_t cpumask_val = 0xFFFFFFFFFFFFFFFF; + struct spdk_iscsi_portal *p; + int rc; + + rc = spdk_iscsi_portal_create_from_configline(string, &p, 0); + CU_ASSERT(rc == 0); + CU_ASSERT(strcmp(p->host, host_str) == 0); + CU_ASSERT(strcmp(p->port, port_str) == 0); + CU_ASSERT(p->cpumask == cpumask_val); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +static void +portal_create_from_configline_ipv6_skip_port_and_cpumask_case(void) +{ + const char *string = "[2001:ad6:1234::]"; + const char *host_str = "[2001:ad6:1234::]"; + const char *port_str = "3260"; + uint64_t cpumask_val = 0xFFFFFFFFFFFFFFFF; + struct spdk_iscsi_portal *p; + int rc; + + rc = spdk_iscsi_portal_create_from_configline(string, &p, 0); + CU_ASSERT(rc == 0); + CU_ASSERT(strcmp(p->host, host_str) == 0); + CU_ASSERT(strcmp(p->port, port_str) == 0); + CU_ASSERT(p->cpumask == cpumask_val); + + spdk_iscsi_portal_destroy(p); + CU_ASSERT(TAILQ_EMPTY(&g_spdk_iscsi.portal_head)); +} + +int +main(int argc, char **argv) +{ + CU_pSuite suite = NULL; + unsigned int num_failures; + + if (CU_initialize_registry() != CUE_SUCCESS) { + return CU_get_error(); + } + + suite = CU_add_suite("portal_grp_suite", test_setup, NULL); + if (suite == NULL) { + CU_cleanup_registry(); + return CU_get_error(); + } + + if ( + CU_add_test(suite, "portal create ipv4 normal case", + portal_create_ipv4_normal_case) == NULL + || CU_add_test(suite, "portal create ipv6 normal case", + portal_create_ipv6_normal_case) == NULL + || CU_add_test(suite, "portal create ipv4 wildcard case", + portal_create_ipv4_wildcard_case) == NULL + || CU_add_test(suite, "portal create ipv6 wildcard case", + portal_create_ipv6_wildcard_case) == NULL + || CU_add_test(suite, "portal create cpumask NULL case", + portal_create_cpumask_null_case) == NULL + || CU_add_test(suite, "portal create cpumask no bit on case", + portal_create_cpumask_no_bit_on_case) == NULL + || CU_add_test(suite, "portal create twice case", + portal_create_twice_case) == NULL + || CU_add_test(suite, "portal create from configline ipv4 normal case", + portal_create_from_configline_ipv4_normal_case) == NULL + || CU_add_test(suite, "portal create from configline ipv6 normal case", + portal_create_from_configline_ipv6_normal_case) == NULL + || CU_add_test(suite, "portal create from configline ipv4 skip cpumask case", + portal_create_from_configline_ipv4_skip_cpumask_case) == NULL + || CU_add_test(suite, "portal create from configline ipv6 skip cpumask case", + portal_create_from_configline_ipv6_skip_cpumask_case) == NULL + || CU_add_test(suite, "portal create from configline ipv4 skip port and cpumask case", + portal_create_from_configline_ipv4_skip_port_and_cpumask_case) == NULL + || CU_add_test(suite, "portal create from configline ipv6 skip port and cpumask case", + portal_create_from_configline_ipv6_skip_port_and_cpumask_case) == NULL + ) { + CU_cleanup_registry(); + return CU_get_error(); + } + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + num_failures = CU_get_number_of_failures(); + CU_cleanup_registry(); + return num_failures; +} diff --git a/unittest.sh b/unittest.sh index 9b8cead88..f2d1f6b03 100755 --- a/unittest.sh +++ b/unittest.sh @@ -100,6 +100,7 @@ $valgrind test/unit/lib/iscsi/param.c/param_ut $valgrind test/unit/lib/iscsi/tgt_node.c/tgt_node_ut test/unit/lib/iscsi/tgt_node.c/tgt_node.conf $valgrind test/unit/lib/iscsi/iscsi.c/iscsi_ut $valgrind test/unit/lib/iscsi/init_grp.c/init_grp_ut test/unit/lib/iscsi/init_grp.c/init_grp.conf +$valgrind test/unit/lib/iscsi/portal_grp.c/portal_grp_ut test/unit/lib/iscsi/portal_grp.c/portal_grp.conf $valgrind test/unit/lib/util/bit_array.c/bit_array_ut $valgrind test/unit/lib/util/crc16.c/crc16_ut