diff --git a/test-tool/Makefile.am b/test-tool/Makefile.am index c73c754..6f18de5 100644 --- a/test-tool/Makefile.am +++ b/test-tool/Makefile.am @@ -201,7 +201,8 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_writeverify16_wrprotect.c \ test_writeverify16_flags.c \ test_writeverify16_dpo.c \ - test_writeverify16_residuals.c + test_writeverify16_residuals.c \ + test_multipathio_simple.c endif diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index 66a1dd3..11dd7a7 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -417,6 +417,11 @@ static CU_TestInfo tests_writeverify16[] = { CU_TEST_INFO_NULL }; +static CU_TestInfo tests_multipathio[] = { + { (char *)"Simple", test_multipathio_simple }, + CU_TEST_INFO_NULL +}; + typedef struct libiscsi_suite_info { const char *pName; /**< Suite name. */ CU_InitializeFunc pInitFunc; /**< Suite initialization function. */ @@ -469,6 +474,7 @@ static libiscsi_suite_info scsi_suites[] = { { "WriteVerify10", NON_PGR_FUNCS, tests_writeverify10 }, { "WriteVerify12", NON_PGR_FUNCS, tests_writeverify12 }, { "WriteVerify16", NON_PGR_FUNCS, tests_writeverify16 }, + { "MultipathIO", NON_PGR_FUNCS, tests_multipathio }, { NULL, NULL, NULL, NULL, NULL, NULL } }; @@ -553,6 +559,7 @@ static libiscsi_suite_info all_suites[] = { { "iSCSIcmdsn", NON_PGR_FUNCS, tests_iscsi_cmdsn }, { "iSCSIdatasn", NON_PGR_FUNCS, tests_iscsi_datasn }, { "iSCSIResiduals", NON_PGR_FUNCS, tests_iscsi_residuals }, + { "MultipathIO", NON_PGR_FUNCS, tests_multipathio }, { NULL, NULL, NULL, NULL, NULL, NULL }, }; @@ -586,6 +593,7 @@ static libiscsi_suite_info linux_suites[] = { { "WriteVerify10", NON_PGR_FUNCS, tests_writeverify10 }, { "WriteVerify12", NON_PGR_FUNCS, tests_writeverify12 }, { "WriteVerify16", NON_PGR_FUNCS, tests_writeverify16 }, + { "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 b3455fc..c82a6e9 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -283,4 +283,6 @@ void test_writeverify16_flags(void); void test_writeverify16_dpo(void); void test_writeverify16_residuals(void); +void test_multipathio_simple(void); + #endif /* _ISCSI_TEST_CU_H_ */ diff --git a/test-tool/test_multipathio_simple.c b/test-tool/test_multipathio_simple.c new file mode 100644 index 0000000..7092ab9 --- /dev/null +++ b/test-tool/test_multipathio_simple.c @@ -0,0 +1,82 @@ +/* + Copyright (C) 2013 Ronnie Sahlberg + Copyright (C) 2015 David Disseldorp + + 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 "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-support.h" +#include "iscsi-test-cu.h" +#include "iscsi-multipath.h" + +void +test_multipathio_simple(void) +{ + int write_path; + unsigned char *write_buf = alloca(256 * block_size); + unsigned char *read_buf = alloca(256 * block_size); + + CHECK_FOR_DATALOSS; + CHECK_FOR_SBC; + MPATH_SKIP_IF_UNAVAILABLE(mp_sds, mp_num_sds); + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + memset(write_buf, 0xa6, 256 * block_size); + + for (write_path = 0; write_path < mp_num_sds; write_path++) { + int i, ret; + int read_path; + + /* read back written data using a different path */ + read_path = (write_path + 1) % mp_num_sds; + + logging(LOG_VERBOSE, + "Test multipath WRITE16/READ16 of 1-256 blocks using " + "path %d", write_path); + + for (i = 1; i <= 256; i++) { + if (maximum_transfer_length + && maximum_transfer_length < i) { + break; + } + ret = write16(mp_sds[write_path], 0, i * block_size, + block_size, 0, 0, 0, 0, 0, write_buf, + EXPECT_STATUS_GOOD); + if (ret == -2) { + logging(LOG_NORMAL, + "[SKIPPED] WRITE16 not implemented."); + CU_PASS("WRITE16 is not implemented."); + return; + } + CU_ASSERT_EQUAL(ret, 0); + + ret = read16(mp_sds[read_path], NULL, 0, i * block_size, + block_size, 0, 0, 0, 0, 0, read_buf, + EXPECT_STATUS_GOOD); + CU_ASSERT_EQUAL(ret, 0); + + /* compare written and read data */ + CU_ASSERT_EQUAL(0, + memcmp(write_buf, read_buf, i * block_size)); + } + + } +}