iscsi/ut: Test for read task splitting
Splitting an iSCSI task into primary and sub tasks is complex operation and a degradation was caused for it. Hence adding test codes is required but there is no UT code for it yet. primary->bytes_completed is for read completion from bdev and it is tested by this patch. Additional test codes will follow: - primary->bytes_completed is tested when read tasks do not complete in order. - primary->task.data_transferred is for write completion to initiator through network. - primary->task.data_transferred is tested by another patch because primary->bytes_completed is used in iscsi/conn.c but primary->task.data_transferred is used in iscsi/iscsi.c. Change-Id: I94b47048111a3d3b249b84d5c54941b0a89ccd40 Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/394143 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
0e48ef40df
commit
c3e890e92b
@ -34,7 +34,7 @@
|
||||
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../..)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
|
||||
DIRS-y = init_grp.c iscsi.c param.c tgt_node.c
|
||||
DIRS-y = conn.c init_grp.c iscsi.c param.c tgt_node.c
|
||||
|
||||
.PHONY: all clean $(DIRS-y)
|
||||
|
||||
|
1
test/unit/lib/iscsi/conn.c/.gitignore
vendored
Normal file
1
test/unit/lib/iscsi/conn.c/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
conn_ut
|
56
test/unit/lib/iscsi/conn.c/Makefile
Normal file
56
test/unit/lib/iscsi/conn.c/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
#
|
||||
# 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 cunit trace conf util
|
||||
|
||||
CFLAGS += -I$(SPDK_ROOT_DIR)/test
|
||||
CFLAGS += -I$(SPDK_ROOT_DIR)/lib
|
||||
LIBS += $(SPDK_LIB_LINKER_ARGS)
|
||||
LIBS += -lcunit
|
||||
|
||||
APP = conn_ut
|
||||
C_SRCS = conn_ut.c
|
||||
|
||||
all: $(APP)
|
||||
|
||||
$(APP): $(OBJS) $(SPDK_LIB_FILES)
|
||||
$(LINK_C)
|
||||
|
||||
clean:
|
||||
$(CLEAN_C) $(APP)
|
||||
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.deps.mk
|
367
test/unit/lib/iscsi/conn.c/conn_ut.c
Normal file
367
test/unit/lib/iscsi/conn.c/conn_ut.c
Normal file
@ -0,0 +1,367 @@
|
||||
/*-
|
||||
* 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_cunit.h"
|
||||
#include "CUnit/Basic.h"
|
||||
|
||||
#include "iscsi/conn.c"
|
||||
#include "net/net_framework_default.c"
|
||||
|
||||
SPDK_LOG_REGISTER_COMPONENT("iscsi", SPDK_LOG_ISCSI)
|
||||
|
||||
#define DMIN32(A,B) ((uint32_t) ((uint32_t)(A) > (uint32_t)(B) ? (uint32_t)(B) : (uint32_t)(A)))
|
||||
|
||||
struct spdk_iscsi_globals g_spdk_iscsi;
|
||||
static TAILQ_HEAD(, spdk_iscsi_task) g_ut_read_tasks = TAILQ_HEAD_INITIALIZER(g_ut_read_tasks);
|
||||
|
||||
int
|
||||
spdk_app_get_shm_id(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
spdk_env_get_current_core(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
spdk_env_get_first_core(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
spdk_env_get_last_core(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
spdk_env_get_next_core(uint32_t prev_core)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t spdk_get_ticks(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t spdk_get_ticks_hz(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct spdk_event *
|
||||
spdk_event_allocate(uint32_t lcore, spdk_event_fn fn, void *arg1, void *arg2)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_event_call(struct spdk_event *event)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
spdk_sock_getaddr(int sock, char *saddr, int slen, char *caddr, int clen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_sock_close(int sock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
spdk_sock_recv(int sock, void *buf, size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
spdk_sock_writev(int sock, struct iovec *iov, int iovcnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_sock_set_recvlowat(int s, int nbytes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_sock_set_recvbuf(int sock, int sz)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_sock_set_sendbuf(int sock, int sz)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_scsi_task_put(struct spdk_scsi_task *task)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
spdk_scsi_dev_free_io_channels(struct spdk_scsi_dev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
spdk_scsi_dev_allocate_io_channels(struct spdk_scsi_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
spdk_scsi_port_get_name(const struct spdk_scsi_port *port)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_put_pdu(struct spdk_iscsi_pdu *pdu)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
spdk_iscsi_param_free(struct iscsi_param *params)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_conn_params_init(struct iscsi_param **params)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spdk_clear_all_transfer_task(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_scsi_lun *lun)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_build_iovecs(struct spdk_iscsi_conn *conn, struct iovec *iovec,
|
||||
struct spdk_iscsi_pdu *pdu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool spdk_iscsi_is_deferred_free_pdu(struct spdk_iscsi_pdu *pdu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_task *task)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_task *task)
|
||||
{
|
||||
}
|
||||
|
||||
int spdk_iscsi_send_nopin(struct spdk_iscsi_conn *conn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_execute(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spdk_del_transfer_task(struct spdk_iscsi_conn *conn, uint32_t task_tag)
|
||||
{
|
||||
}
|
||||
|
||||
int spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_read_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu **_pdu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spdk_free_sess(struct spdk_iscsi_sess *sess)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_tgt_node_cleanup_luns(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_tgt_node *target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_iscsi_fini_done(void)
|
||||
{
|
||||
}
|
||||
|
||||
static struct spdk_iscsi_task *
|
||||
ut_conn_task_get(struct spdk_iscsi_task *parent)
|
||||
{
|
||||
struct spdk_iscsi_task *task;
|
||||
|
||||
task = calloc(1, sizeof(*task));
|
||||
SPDK_CU_ASSERT_FATAL(task != NULL);
|
||||
|
||||
if (parent) {
|
||||
task->parent = parent;
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
static void
|
||||
ut_conn_create_read_tasks(int transfer_len)
|
||||
{
|
||||
struct spdk_iscsi_task *task, *subtask;
|
||||
int32_t remaining_size = 0;
|
||||
|
||||
task = ut_conn_task_get(NULL);
|
||||
|
||||
task->scsi.transfer_len = transfer_len;
|
||||
task->scsi.offset = 0;
|
||||
task->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, task->scsi.transfer_len);
|
||||
task->scsi.status = SPDK_SCSI_STATUS_GOOD;
|
||||
|
||||
remaining_size = task->scsi.transfer_len - task->scsi.length;
|
||||
task->current_datain_offset = 0;
|
||||
|
||||
if (remaining_size == 0) {
|
||||
TAILQ_INSERT_TAIL(&g_ut_read_tasks, task, link);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (task->current_datain_offset == 0) {
|
||||
task->current_datain_offset = task->scsi.length;
|
||||
TAILQ_INSERT_TAIL(&g_ut_read_tasks, task, link);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (task->current_datain_offset < task->scsi.transfer_len) {
|
||||
remaining_size = task->scsi.transfer_len - task->current_datain_offset;
|
||||
|
||||
subtask = ut_conn_task_get(task);
|
||||
|
||||
subtask->scsi.offset = task->current_datain_offset;
|
||||
subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size);
|
||||
subtask->scsi.status = SPDK_SCSI_STATUS_GOOD;
|
||||
|
||||
task->current_datain_offset += subtask->scsi.length;
|
||||
|
||||
TAILQ_INSERT_TAIL(&g_ut_read_tasks, subtask, link);
|
||||
}
|
||||
|
||||
if (task->current_datain_offset == task->scsi.transfer_len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
read_task_split_in_order_case(void)
|
||||
{
|
||||
struct spdk_iscsi_task *primary, *task, *tmp;
|
||||
|
||||
ut_conn_create_read_tasks(SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8);
|
||||
|
||||
TAILQ_FOREACH(task, &g_ut_read_tasks, link) {
|
||||
primary = spdk_iscsi_task_get_primary(task);
|
||||
process_read_task_completion(NULL, task, primary);
|
||||
}
|
||||
|
||||
primary = TAILQ_FIRST(&g_ut_read_tasks);
|
||||
SPDK_CU_ASSERT_FATAL(primary != NULL);
|
||||
|
||||
if (primary != NULL) {
|
||||
CU_ASSERT(primary->bytes_completed == primary->scsi.transfer_len);
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_SAFE(task, &g_ut_read_tasks, link, tmp) {
|
||||
TAILQ_REMOVE(&g_ut_read_tasks, task, link);
|
||||
free(task);
|
||||
}
|
||||
|
||||
CU_ASSERT(TAILQ_EMPTY(&g_ut_read_tasks));
|
||||
}
|
||||
|
||||
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("conn_suite", NULL, NULL);
|
||||
if (suite == NULL) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (
|
||||
CU_add_test(suite, "read task split in order", read_task_split_in_order_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;
|
||||
}
|
@ -95,6 +95,7 @@ $valgrind test/unit/lib/scsi/scsi_bdev.c/scsi_bdev_ut
|
||||
|
||||
$valgrind test/unit/lib/lvol/lvol.c/lvol_ut
|
||||
|
||||
$valgrind test/unit/lib/iscsi/conn.c/conn_ut
|
||||
$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
|
||||
|
Loading…
Reference in New Issue
Block a user