From d288d5a8b69e721eb2f63db2266ec118662131f2 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 3 Mar 2013 10:05:57 -0800 Subject: [PATCH] TESTS: Add tests for prevent/allow medium removal --- Makefile.am | 2 + test-tool/iscsi-support.c | 67 +++++++++++++++++++++++ test-tool/iscsi-support.h | 13 +++++ test-tool/iscsi-test-cu.c | 8 +++ test-tool/iscsi-test-cu.h | 3 ++ test-tool/test_preventallow_eject.c | 78 +++++++++++++++++++++++++++ test-tool/test_preventallow_simple.c | 45 ++++++++++++++++ test-tool/test_startstopunit_simple.c | 2 +- 8 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 test-tool/test_preventallow_eject.c create mode 100644 test-tool/test_preventallow_simple.c diff --git a/Makefile.am b/Makefile.am index 305a313..538b946 100644 --- a/Makefile.am +++ b/Makefile.am @@ -203,6 +203,8 @@ bin_iscsi_test_cu_SOURCES = test-tool/iscsi-test-cu.c \ test-tool/test_prefetch16_beyond_eol.c \ test-tool/test_prefetch16_0blocks.c \ test-tool/test_prefetch16_flags.c \ + test-tool/test_preventallow_simple.c \ + test-tool/test_preventallow_eject.c \ test-tool/test_prin_read_keys_simple.c \ test-tool/test_prin_serviceaction_range.c \ test-tool/test_prout_register_simple.c \ diff --git a/test-tool/iscsi-support.c b/test-tool/iscsi-support.c index cea6d53..78eb924 100644 --- a/test-tool/iscsi-support.c +++ b/test-tool/iscsi-support.c @@ -1262,6 +1262,42 @@ int startstopunit(struct iscsi_context *iscsi, int lun, int immed, int pcm, int return 0; } +int startstopunit_preventremoval(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send STARTSTOPUNIT (Expecting MEDIUM_REMOVAL_PREVENTED) " + "IMMED:%d PCM:%d PC:%d NO_FLUSH:%d LOEJ:%d START:%d", + immed, pcm, pc, no_flush, loej, start); + + task = iscsi_startstopunit_sync(iscsi, lun, immed, pcm, pc, no_flush, + loej, start); + if (task == NULL) { + logging(LOG_NORMAL, + "[FAILED] Failed to send STARTSTOPUNIT command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, + "[FAILED] STARTSTOPUNIT successful but should have failed with ILLEGAL_REQUEST/MEDIUM_REMOVAL_PREVENTED"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_ILLEGAL_REQUEST + || task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_REMOVAL_PREVENTED) { + logging(LOG_NORMAL, "[FAILED] STARTSTOPUNIT Should have failed " + "with ILLEGAL_REQUEST/MEDIUM_REMOVAL_PREVENTED But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] STARTSTOPUNIT returned MEDIUM_REMOVAL_PREVENTED."); + return 0; +} + int testunitready(struct iscsi_context *iscsi, int lun) { @@ -1722,6 +1758,37 @@ prefetch16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, return 0; } +int +preventallow(struct iscsi_context *iscsi, int lun, int prevent) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send PREVENTALLOW prevent:%d", prevent); + task = iscsi_preventallow_sync(iscsi, lun, prevent); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send PREVENTALLOW " + "command: %s", iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] PREVENTALLOW is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status != SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] PREVENTALLOW command: " + "failed with sense. %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] PREVENTALLOW returned SUCCESS."); + return 0; +} + int read6(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, diff --git a/test-tool/iscsi-support.h b/test-tool/iscsi-support.h index fea3c13..472274c 100644 --- a/test-tool/iscsi-support.h +++ b/test-tool/iscsi-support.h @@ -64,6 +64,17 @@ do { \ } \ } while (0); +#define CHECK_FOR_REMOVABLE \ +do { \ + if (!removable) { \ + logging(LOG_VERBOSE, "[SKIPPED] Logical unit is not " \ + "removable. Skipping test."); \ + CU_PASS("[SKIPPED] Logical unit is not removable" \ + " Skipping test"); \ + return; \ + } \ +} while (0); + #define CHECK_FOR_THIN_PROVISIONING \ do { \ if (lbpme == 0) { \ @@ -214,6 +225,7 @@ int prefetch10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int int prefetch16(struct iscsi_context *iscsi, int lun, uint64_t lba, int num_blocks, int immed, int group); int prefetch16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, int num_blocks, int immed, int group); int prefetch16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, int num_blocks, int immed, int group); +int preventallow(struct iscsi_context *iscsi, int lun, int prevent); int read6(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, unsigned char *data); int read6_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, unsigned char *data); int read10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); @@ -233,6 +245,7 @@ int readcapacity10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int readcapacity16(struct iscsi_context *iscsi, int lun, int alloc_len); int readcapacity16_nomedium(struct iscsi_context *iscsi, int lun, int alloc_len); int startstopunit(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start); +int startstopunit_preventremoval(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start); int synchronizecache10(struct iscsi_context *iscsi, int lun, uint32_t lba, int num_blocks, int sync_nv, int immed); int synchronizecache10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int num_blocks, int sync_nv, int immed); int synchronizecache16(struct iscsi_context *iscsi, int lun, uint64_t lba, int num_blocks, int sync_nv, int immed); diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index a17c5fb..9006a35 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -97,6 +97,12 @@ static CU_TestInfo tests_prefetch16[] = { CU_TEST_INFO_NULL }; +static CU_TestInfo tests_preventallow[] = { + { (char *)"testPreventAllowSimple", test_preventallow_simple }, + { (char *)"testPreventAllowEject", test_preventallow_eject }, + CU_TEST_INFO_NULL +}; + static CU_TestInfo tests_prin_read_keys[] = { { (char *)"testPrinReadKeysSimple", test_prin_read_keys_simple }, CU_TEST_INFO_NULL @@ -331,6 +337,8 @@ static CU_SuiteInfo suites[] = { tests_prefetch10 }, { (char *)"TestPrefetch16", test_setup, test_teardown, tests_prefetch16 }, + { (char *)"TestPreventAllow", test_setup, test_teardown, + tests_preventallow }, { (char *)"TestPrinReadKeys", test_setup, test_teardown, tests_prin_read_keys }, { (char *)"TestPrinServiceactionRange", test_setup, test_teardown, diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index 8702f96..63dc8eb 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -62,6 +62,9 @@ void test_prefetch16_beyond_eol(void); void test_prefetch16_0blocks(void); void test_prefetch16_flags(void); +void test_preventallow_simple(void); +void test_preventallow_eject(void); + void test_prin_read_keys_simple(void); void test_prin_serviceaction_range(void); diff --git a/test-tool/test_preventallow_eject.c b/test-tool/test_preventallow_eject.c new file mode 100644 index 0000000..26da530 --- /dev/null +++ b/test-tool/test_preventallow_eject.c @@ -0,0 +1,78 @@ +/* + 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 "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-support.h" +#include "iscsi-test-cu.h" + +void +test_preventallow_eject(void) +{ + int ret; + + CHECK_FOR_SBC; + CHECK_FOR_REMOVABLE; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test that we can not eject medium when PREVENT is active"); + + logging(LOG_VERBOSE, "Set the PREVENT flag"); + ret = preventallow(iscsic, tgt_lun, 1); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Try to eject the medium"); + ret = startstopunit_preventremoval(iscsic, tgt_lun, 0, 0, 0, 0, 1, 0); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Verify we can still access the media."); + ret = testunitready(iscsic, tgt_lun); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); + ret = preventallow(iscsic, tgt_lun, 0); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Try to eject the medium"); + ret = startstopunit(iscsic, tgt_lun, 0, 0, 0, 0, 1, 0); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Verify we can not access the media."); + ret = testunitready_nomedium(iscsic, tgt_lun); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Set the PREVENT flag"); + ret = preventallow(iscsic, tgt_lun, 1); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Try to load the medium"); + ret = startstopunit_preventremoval(iscsic, tgt_lun, 0, 0, 0, 0, 1, 1); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Clear PREVENT flag"); + ret = preventallow(iscsic, tgt_lun, 0); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Load the medium again"); + ret = startstopunit(iscsic, tgt_lun, 0, 0, 0, 0, 1, 1); + CU_ASSERT_EQUAL(ret, 0); + +} diff --git a/test-tool/test_preventallow_simple.c b/test-tool/test_preventallow_simple.c new file mode 100644 index 0000000..eb2324d --- /dev/null +++ b/test-tool/test_preventallow_simple.c @@ -0,0 +1,45 @@ +/* + 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 "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-support.h" +#include "iscsi-test-cu.h" + +void +test_preventallow_simple(void) +{ + int ret; + + CHECK_FOR_SBC; + CHECK_FOR_REMOVABLE; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test PREVENTALLOW basics"); + + logging(LOG_VERBOSE, "Test we can set PREVENT flag"); + ret = preventallow(iscsic, tgt_lun, 1); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); + ret = preventallow(iscsic, tgt_lun, 0); + CU_ASSERT_EQUAL(ret, 0); +} diff --git a/test-tool/test_startstopunit_simple.c b/test-tool/test_startstopunit_simple.c index 2216ac6..7f819dc 100644 --- a/test-tool/test_startstopunit_simple.c +++ b/test-tool/test_startstopunit_simple.c @@ -82,7 +82,7 @@ test_startstopunit_simple(void) 0, 0, 0, 0, 1, 1); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Verify we can read from the media."); + logging(LOG_VERBOSE, "Verify we can access the media again."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); }