From 1511ddcbe4b5b00dcbc98009d6227000c81e6dc9 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Mon, 16 Sep 2019 11:19:12 +0200 Subject: [PATCH] test-tool: add simple iSCSI NOP-Out test Send a ping with/without data and expect a valid response. Signed-off-by: David Disseldorp --- test-tool/Makefile.am | 1 + test-tool/iscsi-test-cu.c | 8 +++ test-tool/iscsi-test-cu.h | 1 + test-tool/test_iscsi_nop_simple.c | 115 ++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 test-tool/test_iscsi_nop_simple.c diff --git a/test-tool/Makefile.am b/test-tool/Makefile.am index 45acf27..f9faa90 100644 --- a/test-tool/Makefile.am +++ b/test-tool/Makefile.am @@ -41,6 +41,7 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_iscsi_cmdsn_toolow.c \ test_iscsi_datasn_invalid.c \ test_iscsi_sendtargets.c \ + test_iscsi_nop_simple.c \ test_mandatory_sbc.c \ test_modesense6_all_pages.c \ test_modesense6_control.c \ diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index 865e668..670a705 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -564,6 +564,11 @@ static CU_TestInfo tests_iscsi_sendtargets[] = { CU_TEST_INFO_NULL }; +static CU_TestInfo tests_iscsi_nop[] = { + { (char *)"Simple", test_iscsi_nop_simple }, + CU_TEST_INFO_NULL +}; + static CU_TestInfo tests_iscsi_residuals[] = { { (char *)"Read10Invalid", test_read10_invalid }, { (char *)"Read10Residuals", test_read10_residuals }, @@ -596,6 +601,8 @@ static libiscsi_suite_info iscsi_suites[] = { tests_iscsi_tmf }, { "iSCSISendTargets", NON_PGR_FUNCS, tests_iscsi_sendtargets }, + { "iSCSINop", NON_PGR_FUNCS, + tests_iscsi_nop }, { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -654,6 +661,7 @@ static libiscsi_suite_info all_suites[] = { { "iSCSIResiduals", NON_PGR_FUNCS, tests_iscsi_residuals }, { "iSCSITMF", NON_PGR_FUNCS, tests_iscsi_tmf }, { "iSCSISendTargets", NON_PGR_FUNCS, tests_iscsi_sendtargets }, + { "iSCSINop", NON_PGR_FUNCS, tests_iscsi_nop }, { "MultipathIO", NON_PGR_FUNCS, tests_multipathio }, { NULL, NULL, NULL, NULL, NULL, NULL }, }; diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index b19a12f..b05bbe2 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -80,6 +80,7 @@ void test_iscsi_cmdsn_toolow(void); void test_iscsi_datasn_invalid(void); void test_iscsi_sendtargets_simple(void); void test_iscsi_sendtargets_invalid(void); +void test_iscsi_nop_simple(void); void test_mandatory_sbc(void); diff --git a/test-tool/test_iscsi_nop_simple.c b/test-tool/test_iscsi_nop_simple.c new file mode 100644 index 0000000..3a5c9bc --- /dev/null +++ b/test-tool/test_iscsi_nop_simple.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2019 SUSE LLC + Copyright (C) 2013 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi-private.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +struct test_iscsi_nop_state { + int dispatched; + int completed; + char nop_buf[1024]; + size_t nop_datalen; +}; + +static int +test_iscsi_nop_txrx(struct test_iscsi_nop_state *state) +{ + while (state->completed < state->dispatched) { + struct pollfd pfd; + int ret; + + pfd.fd = iscsi_get_fd(sd->iscsi_ctx); + pfd.events = iscsi_which_events(sd->iscsi_ctx); + + ret = poll(&pfd, 1, -1); + if (ret < 0) { + return ret; + } + + ret = iscsi_service(sd->iscsi_ctx, pfd.revents); + if (ret != 0) { + return ret; + } + } + return 0; +} + +static void +test_iscsi_nop_cb(struct iscsi_context *iscsi _U_, int status, + void *command_data, void *private_data) +{ + struct test_iscsi_nop_state *state = private_data; + struct iscsi_data *data = command_data; + + CU_ASSERT_EQUAL(status, 0); + CU_ASSERT_PTR_NOT_NULL(data); + CU_ASSERT_EQUAL_FATAL(state->nop_datalen, data->size); + if (state->nop_datalen > 0) { + CU_ASSERT_EQUAL(0, memcmp(state->nop_buf, data->data, + state->nop_datalen)); + } + + state->completed++; +} + +void +test_iscsi_nop_simple(void) +{ + struct test_iscsi_nop_state state; + int ret; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test Nop Out Pings"); + + if (sd->iscsi_ctx == NULL) { + const char *err = "[SKIPPED] This test is " + "only supported for iSCSI backends"; + logging(LOG_NORMAL, "%s", err); + CU_PASS(err); + return; + } + + memset(&state, 0, sizeof(state)); + strncpy(state.nop_buf, "nopping", sizeof(state.nop_buf)); + state.nop_datalen = strlen(state.nop_buf) + 1; + ret = iscsi_nop_out_async(sd->iscsi_ctx, test_iscsi_nop_cb, + (unsigned char *)state.nop_buf, + state.nop_datalen, &state); + CU_ASSERT_EQUAL(ret, 0); + state.dispatched++; + + ret = test_iscsi_nop_txrx(&state); + CU_ASSERT_EQUAL(ret, 0); + + /* no data */ + state.nop_datalen = 0; + ret = iscsi_nop_out_async(sd->iscsi_ctx, test_iscsi_nop_cb, + NULL, state.nop_datalen, &state); + CU_ASSERT_EQUAL(ret, 0); + state.dispatched++; + + ret = test_iscsi_nop_txrx(&state); + CU_ASSERT_EQUAL(ret, 0); +}