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:
Ronnie Sahlberg
2013-05-18 13:56:02 -07:00
parent ce4623b2fb
commit 709410b1d7
10 changed files with 286 additions and 76 deletions

View File

@@ -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);
}

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);

View 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);
}

View 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);
}