diff --git a/test-tool/Makefile.am b/test-tool/Makefile.am index ece16dd..513c387 100644 --- a/test-tool/Makefile.am +++ b/test-tool/Makefile.am @@ -19,6 +19,7 @@ iscsi_test_cu_SOURCES = iscsi-test-cu.c \ test_compareandwrite_simple.c \ test_compareandwrite_dpofua.c \ test_compareandwrite_miscompare.c \ + test_compareandwrite_unwritten.c \ test_extendedcopy_simple.c \ test_extendedcopy_param.c \ test_extendedcopy_descr_limits.c \ diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index f918250..764ec9d 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -75,6 +75,7 @@ static CU_TestInfo tests_compareandwrite[] = { { (char *)"Simple", test_compareandwrite_simple }, { (char *)"DpoFua", test_compareandwrite_dpofua }, { (char *)"Miscompare", test_compareandwrite_miscompare }, + { (char *)"Unwritten", test_compareandwrite_unwritten }, CU_TEST_INFO_NULL }; diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index 4ff8860..e2a8927 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -51,6 +51,7 @@ void test_teardown(void); void test_compareandwrite_simple(void); void test_compareandwrite_dpofua(void); void test_compareandwrite_miscompare(void); +void test_compareandwrite_unwritten(void); void test_extendedcopy_simple(void); void test_extendedcopy_param(void); diff --git a/test-tool/test_async_abort_simple.c b/test-tool/test_async_abort_simple.c index c7a991d..b7ed825 100644 --- a/test-tool/test_async_abort_simple.c +++ b/test-tool/test_async_abort_simple.c @@ -60,9 +60,13 @@ test_async_abort_cb(struct iscsi_context *iscsi __attribute__((unused)), int status, void *command_data, void *private_data) { - uint32_t tmf_response = *(uint32_t *)command_data; + uint32_t tmf_response; struct tests_async_abort_state *state = private_data; + /* command_data NULL if a reconnect occured. see iscsi_reconnect_cb() */ + CU_ASSERT_PTR_NOT_NULL_FATAL(command_data); + tmf_response = *(uint32_t *)command_data; + logging(LOG_VERBOSE, "ABORT TASK: TMF response %d for" " RefCmdSN=0x%x, RefITT=0x%x", tmf_response, state->wtask->cmdsn, state->wtask->itt); diff --git a/test-tool/test_compareandwrite_unwritten.c b/test-tool/test_compareandwrite_unwritten.c new file mode 100644 index 0000000..6bd6a2c --- /dev/null +++ b/test-tool/test_compareandwrite_unwritten.c @@ -0,0 +1,78 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) SUSE LINUX GmbH 2016 + Copyright (C) 2013 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 "scsi-lowlevel.h" +#include "iscsi-support.h" +#include "iscsi-test-cu.h" + + +void +test_compareandwrite_unwritten(void) +{ + int i; + + CHECK_FOR_DATALOSS; + CHECK_FOR_SBC; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the " + "start of the LUN, 1 block at a time"); + for (i = 1; i < 256; i++) { + int caw_ret; + unsigned char read_buf[block_size]; + + /* semi-unique 'compare' buffer to trigger miscompare */ + memset(scratch, '%', block_size); + memset(scratch + block_size, 'B', block_size); + + caw_ret = compareandwrite(sd, i, scratch, 2 * block_size, + block_size, + 0, 0, 0, 0, + EXPECT_MISCOMPARE); + if (caw_ret == -2) { + CU_PASS("[SKIPPED] COMPARE AND WRITE not supported"); + return; + } + READ16(sd, NULL, i, block_size, + block_size, 0, 0, 0, 0, 0, read_buf, + EXPECT_STATUS_GOOD); + + if (caw_ret == 0) { + /* miscompare - confirm unwritten block doesn't match compare buf */ + CU_ASSERT_NOT_EQUAL(memcmp(read_buf, scratch, + block_size), 0); + } else { + /* + * unexpected CAW success, or failure with an ASCQ that + * doesn't indicate miscompare - tolerate only the + * former, by checking that the range now carries data + * matching the CAW write buffer. + */ + CU_ASSERT_EQUAL(memcmp(read_buf, scratch + block_size, + block_size), 0); + } + } +}