TESTS: Add some REPORT SUPPORTED OPCODES tests
Add a simple test that it works or is not implemented. Add a RCTD test to verify that with this flag clear we get command descriptors without CTDP set and with it set we get command descriptors with CTDP set and a timeout descriptor
This commit is contained in:
@@ -31,7 +31,7 @@ int T0430_report_all_supported_ops(const char *initiator, const char *url)
|
||||
struct scsi_command_descriptor *desc;
|
||||
int ret, lun;
|
||||
int full_size, desc_size;
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
printf("0430_report_all_supported_ops:\n");
|
||||
printf("===================\n");
|
||||
@@ -108,9 +108,9 @@ int T0430_report_all_supported_ops(const char *initiator, const char *url)
|
||||
printf("=======================\n");
|
||||
for (i = 0; i < rsoc->num_descriptors; i++) {
|
||||
printf("op:%x\tsa:%x\tcdb length:%d\n",
|
||||
rsoc->descriptors[i].op_code,
|
||||
rsoc->descriptors[i].service_action,
|
||||
rsoc->descriptors[i].cdb_length);
|
||||
rsoc->descriptors[i].opcode,
|
||||
rsoc->descriptors[i].sa,
|
||||
rsoc->descriptors[i].cdb_len);
|
||||
}
|
||||
|
||||
printf("\n[OK]\n");
|
||||
@@ -179,13 +179,13 @@ int T0430_report_all_supported_ops(const char *initiator, const char *url)
|
||||
desc = &rsoc->descriptors[0];
|
||||
for (i = 0; i < rsoc->num_descriptors; i++) {
|
||||
printf("op:%x\tsa:%x\tcdb_length:%d\ttimeout info: length:%d\tcommand specific:%x\tnominal processing%d\trecommended%d\n",
|
||||
desc->op_code,
|
||||
desc->service_action,
|
||||
desc->cdb_length,
|
||||
desc->to[0].descriptor_length,
|
||||
desc->to[0].command_specific,
|
||||
desc->to[0].nominal_processing_timeout,
|
||||
desc->to[0].recommended_timeout);
|
||||
desc->opcode,
|
||||
desc->sa,
|
||||
desc->cdb_len,
|
||||
desc->to.descriptor_length,
|
||||
desc->to.command_specific,
|
||||
desc->to.nominal_processing_timeout,
|
||||
desc->to.recommended_timeout);
|
||||
desc = (struct scsi_command_descriptor *)((char *)desc +
|
||||
desc_size);
|
||||
}
|
||||
|
||||
@@ -2759,6 +2759,48 @@ release6(struct iscsi_context *iscsi, int lun)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int report_supported_opcodes(struct iscsi_context *iscsi, int lun, int rctd, int options, int opcode, int sa, int alloc_len, struct scsi_task **save_task)
|
||||
{
|
||||
struct scsi_task *task;
|
||||
|
||||
logging(LOG_VERBOSE, "Send REPORT_SUPPORTED_OPCODE RCTD:%d OPTIONS:%d "
|
||||
"OPCODE:%d SA:%d ALLOC_LEN:%d",
|
||||
rctd, options, opcode, sa, alloc_len);
|
||||
|
||||
task = iscsi_report_supported_opcodes_sync(iscsi, lun,
|
||||
rctd, options, opcode, sa, alloc_len);
|
||||
if (task == NULL) {
|
||||
logging(LOG_NORMAL, "[FAILED] Failed to send "
|
||||
"REPORT_SUPPORTED_OPCODES 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] REPORT_SUPPORTED_OPCODES is not "
|
||||
"implemented on target");
|
||||
scsi_free_scsi_task(task);
|
||||
return -2;
|
||||
}
|
||||
if (task->status != SCSI_STATUS_GOOD) {
|
||||
logging(LOG_NORMAL, "[FAILED] REPORT_SUPPORTED_OPCODES "
|
||||
"command: failed with sense. %s",
|
||||
iscsi_get_error(iscsi));
|
||||
scsi_free_scsi_task(task);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (save_task != NULL) {
|
||||
*save_task = task;
|
||||
} else {
|
||||
scsi_free_scsi_task(task);
|
||||
}
|
||||
|
||||
logging(LOG_VERBOSE, "[OK] REPORT_SUPPORTED_OPCODES returned SUCCESS.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
reserve6(struct iscsi_context *iscsi, int lun)
|
||||
{
|
||||
|
||||
@@ -243,6 +243,7 @@ int readcapacity10(struct iscsi_context *iscsi, int lun, uint32_t lba, int pmi);
|
||||
int readcapacity10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int pmi);
|
||||
int readcapacity16(struct iscsi_context *iscsi, int lun, int alloc_len);
|
||||
int readcapacity16_nomedium(struct iscsi_context *iscsi, int lun, int alloc_len);
|
||||
int report_supported_opcodes(struct iscsi_context *iscsi, int lun, int rctd, int options, int opcode, int sa, int alloc_len, struct scsi_task **save_task);
|
||||
int release6(struct iscsi_context *iscsi, int lun);
|
||||
int reserve6(struct iscsi_context *iscsi, int lun);
|
||||
int reserve6_conflict(struct iscsi_context *iscsi, int lun);
|
||||
|
||||
@@ -221,6 +221,12 @@ static CU_TestInfo tests_readonly[] = {
|
||||
CU_TEST_INFO_NULL
|
||||
};
|
||||
|
||||
static CU_TestInfo tests_report_supported_opcodes[] = {
|
||||
{ (char *)"ReportSupportedOpcodesSimple", test_report_supported_opcodes_simple },
|
||||
{ (char *)"ReportSupportedOpcodesRCTD", test_report_supported_opcodes_rctd },
|
||||
CU_TEST_INFO_NULL
|
||||
};
|
||||
|
||||
static CU_TestInfo tests_reserve6[] = {
|
||||
{ (char *)"Reserve6Simple", test_reserve6_simple },
|
||||
{ (char *)"Reserve6_2Initiators", test_reserve6_2initiators },
|
||||
@@ -403,6 +409,8 @@ static CU_SuiteInfo scsi_suites[] = {
|
||||
tests_readcapacity16 },
|
||||
{ (char *)"ReadOnly", test_setup, test_teardown,
|
||||
tests_readonly },
|
||||
{ (char *)"ReportSupportedOpcodes", test_setup, test_teardown,
|
||||
tests_report_supported_opcodes },
|
||||
{ (char *)"Reserve6", test_setup, test_teardown,
|
||||
tests_reserve6 },
|
||||
{ (char *)"StartStopUnit", test_setup, test_teardown,
|
||||
@@ -505,6 +513,8 @@ static CU_SuiteInfo all_suites[] = {
|
||||
tests_readcapacity16 },
|
||||
{ (char *)"ReadOnly", test_setup, test_teardown,
|
||||
tests_readonly },
|
||||
{ (char *)"ReportSupportedOpcodes", test_setup, test_teardown,
|
||||
tests_report_supported_opcodes },
|
||||
{ (char *)"Reserve6", test_setup, test_teardown,
|
||||
tests_reserve6 },
|
||||
{ (char *)"StartStopUnit", test_setup, test_teardown,
|
||||
@@ -577,6 +587,8 @@ static CU_SuiteInfo scsi_usb_sbc_suites[] = {
|
||||
tests_readcapacity16 },
|
||||
{ (char *)"ReadOnly", test_setup, test_teardown,
|
||||
tests_readonly },
|
||||
{ (char *)"ReportSupportedOpcodes", test_setup, test_teardown,
|
||||
tests_report_supported_opcodes },
|
||||
{ (char *)"Reserve6", test_setup, test_teardown,
|
||||
tests_reserve6 },
|
||||
{ (char *)"TestUnitReady", test_setup, test_teardown,
|
||||
|
||||
@@ -138,6 +138,9 @@ void test_readcapacity16_simple(void);
|
||||
|
||||
void test_readonly_sbc(void);
|
||||
|
||||
void test_report_supported_opcodes_simple(void);
|
||||
void test_report_supported_opcodes_rctd(void);
|
||||
|
||||
void test_reserve6_simple(void);
|
||||
void test_reserve6_2initiators(void);
|
||||
void test_reserve6_logout(void);
|
||||
|
||||
99
test-tool/test_report_supported_opcodes_rctd.c
Normal file
99
test-tool/test_report_supported_opcodes_rctd.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright (C) 2013 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
#include "iscsi.h"
|
||||
#include "scsi-lowlevel.h"
|
||||
#include "iscsi-support.h"
|
||||
#include "iscsi-test-cu.h"
|
||||
|
||||
|
||||
void
|
||||
test_report_supported_opcodes_rctd(void)
|
||||
{
|
||||
int i, ret;
|
||||
struct scsi_task *rso_task;
|
||||
struct scsi_report_supported_op_codes *rsoc;
|
||||
|
||||
logging(LOG_VERBOSE, LOG_BLANK_LINE);
|
||||
logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES RCTD flag");
|
||||
|
||||
|
||||
logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES report ALL opcodes "
|
||||
"without timeout descriptors");
|
||||
ret = report_supported_opcodes(iscsic, tgt_lun,
|
||||
0, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0,
|
||||
65535, &rso_task);
|
||||
if (ret == -2) {
|
||||
logging(LOG_NORMAL, "[SKIPPED] READ_SUPPORTED_OPCODES is not "
|
||||
"implemented.");
|
||||
CU_PASS("READ_SUPPORTED_OPCODES is not implemented.");
|
||||
return;
|
||||
}
|
||||
CU_ASSERT_EQUAL(ret, 0);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
|
||||
rsoc = scsi_datain_unmarshall(rso_task);
|
||||
CU_ASSERT_NOT_EQUAL(rsoc, NULL);
|
||||
|
||||
|
||||
logging(LOG_VERBOSE, "Verify that all returned command descriptors "
|
||||
"lack timeout description");
|
||||
for (i = 0; i < rsoc->num_descriptors; i++) {
|
||||
if (rsoc->descriptors[i].ctdp) {
|
||||
logging(LOG_NORMAL, "[FAILED] Command descriptor with "
|
||||
"CTDP set");
|
||||
CU_FAIL("[FAILED] Command descriptor with "
|
||||
"CTDP set");
|
||||
}
|
||||
}
|
||||
scsi_free_scsi_task(rso_task);
|
||||
|
||||
|
||||
logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES report ALL opcodes "
|
||||
"with timeout descriptors");
|
||||
ret = report_supported_opcodes(iscsic, tgt_lun,
|
||||
1, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0,
|
||||
65535, &rso_task);
|
||||
CU_ASSERT_EQUAL(ret, 0);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
|
||||
rsoc = scsi_datain_unmarshall(rso_task);
|
||||
CU_ASSERT_NOT_EQUAL(rsoc, NULL);
|
||||
|
||||
logging(LOG_VERBOSE, "Verify that all returned command descriptors "
|
||||
"have a timeout description");
|
||||
for (i = 0; i < rsoc->num_descriptors; i++) {
|
||||
if (!rsoc->descriptors[i].ctdp) {
|
||||
logging(LOG_NORMAL, "[FAILED] Command descriptor "
|
||||
"without CTDP set");
|
||||
CU_FAIL("[FAILED] Command descriptor without "
|
||||
"CTDP set");
|
||||
}
|
||||
}
|
||||
|
||||
scsi_free_scsi_task(rso_task);
|
||||
}
|
||||
46
test-tool/test_report_supported_opcodes_simple.c
Normal file
46
test-tool/test_report_supported_opcodes_simple.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright (C) 2013 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
#include "iscsi.h"
|
||||
#include "scsi-lowlevel.h"
|
||||
#include "iscsi-support.h"
|
||||
#include "iscsi-test-cu.h"
|
||||
|
||||
|
||||
void
|
||||
test_report_supported_opcodes_simple(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
logging(LOG_VERBOSE, LOG_BLANK_LINE);
|
||||
logging(LOG_VERBOSE, "Test basic READ_SUPPORTED_OPCODES");
|
||||
|
||||
ret = report_supported_opcodes(iscsic, tgt_lun,
|
||||
0, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0,
|
||||
1024, NULL);
|
||||
if (ret == -2) {
|
||||
logging(LOG_NORMAL, "[SKIPPED] READ_SUPPORTED_OPCODES is not "
|
||||
"implemented.");
|
||||
CU_PASS("READ_SUPPORTED_OPCODES is not implemented.");
|
||||
return;
|
||||
}
|
||||
CU_ASSERT_EQUAL(ret, 0);
|
||||
}
|
||||
Reference in New Issue
Block a user