TESTS: add a new helper check_result to validate the result of SCSI helpers

Many/most all SCSI helpers do pretty much the same checking for the SCSI
result and status. Break this out into a separate helper that we can use
to reduce code duplication.

Signed-off-by: Ronnie Sahlberg <sahlberg@localhost>
This commit is contained in:
Ronnie Sahlberg
2014-09-17 07:15:52 -07:00
committed by Ronnie Sahlberg
parent 97177ec0e4
commit 905695575f
2 changed files with 107 additions and 0 deletions

View File

@@ -2,6 +2,7 @@
iscsi-test tool support
Copyright (C) 2012 by Lee Duncan <leeman.duncan@gmail.com>
Copyright (C) 2014 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
@@ -63,8 +64,102 @@ int readonly;
int sbc3_support;
int maximum_transfer_length;
int no_medium_ascqs[3] = {
SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT,
SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN,
SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED
};
int lba_oob_ascqs[1] = {
SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE
};
int invalid_cdb_ascqs[1] = {
SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB
};
int write_protect_ascqs[1] = {
SCSI_SENSE_ASCQ_WRITE_PROTECTED
};
int (*real_iscsi_queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
static const char *scsi_status_str(int status)
{
switch(status) {
case SCSI_STATUS_GOOD: return "SUCCESS";
case SCSI_STATUS_CHECK_CONDITION: return "CHECK_CONDITION";
case SCSI_STATUS_CONDITION_MET: return "CONDITIONS_MET";
case SCSI_STATUS_BUSY: return "BUSY";
case SCSI_STATUS_RESERVATION_CONFLICT: return "RESERVATION_CONFLICT";
case SCSI_STATUS_TASK_SET_FULL: return "TASK_SET_FULL";
case SCSI_STATUS_ACA_ACTIVE: return "ACA_ACTIVE";
case SCSI_STATUS_TASK_ABORTED: return "TASK_ABORTED";
}
return "UNKNOWN";
}
static int check_result(const char *opcode, struct iscsi_context *iscsi,
struct scsi_task *task,
int status, enum scsi_sense_key key,
int *ascq, int num_ascq)
{
int ascq_ok;
if (task == NULL) {
logging(LOG_NORMAL, "[FAILED] Failed to send %s command: "
"%s", opcode, 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] %s is not implemented.",
opcode);
return -2;
}
if (status == SCSI_STATUS_GOOD && task->status != SCSI_STATUS_GOOD) {
logging(LOG_NORMAL, "[FAILED] %s command failed with "
"sense. %s", opcode, iscsi_get_error(iscsi));
return -1;
}
if (status != SCSI_STATUS_GOOD && task->status == SCSI_STATUS_GOOD) {
logging(LOG_NORMAL, "[FAILED] %s successful but should "
"have failed with %s(0x%02x)/%s(0x%04x)",
opcode,
scsi_sense_key_str(key), key,
scsi_sense_ascq_str(ascq[0]), ascq[0]);
return -1;
}
/* did we get any of the expected ASCQs ?*/
if (status == SCSI_STATUS_CHECK_CONDITION) {
int i;
for (i = 0; i < num_ascq; i++) {
if (ascq[i] == task->sense.ascq) {
ascq_ok = 1;
}
}
if (num_ascq == 0) {
ascq_ok = 1;
}
}
if (status == SCSI_STATUS_CHECK_CONDITION &&
(task->status != status
|| task->sense.key != key
|| !ascq_ok)) {
logging(LOG_NORMAL, "[FAILED] %s failed with wrong sense. "
"Should have failed with %s(0x%02x)/%s(0x%04x)"
"but failed with Sense:%s\n",
opcode,
scsi_sense_key_str(key), key,
scsi_sense_ascq_str(ascq[0]), ascq[0],
iscsi_get_error(iscsi));
return -1;
}
logging(LOG_VERBOSE, "[OK] %s returned %s %s(0x%02x) %s(0x%04x)",
opcode, scsi_status_str(status),
scsi_sense_key_str(task->sense.key), task->sense.key,
scsi_sense_ascq_str(task->sense.ascq), task->sense.ascq);
return 0;
}
void logging(int level, const char *format, ...)
{
va_list ap;

View File

@@ -29,6 +29,18 @@ extern const char *initiatorname1;
extern const char *initiatorname2;
extern const char *tgt_url;
#define EXPECT_STATUS_GOOD SCSI_STATUS_GOOD, SCSI_SENSE_NO_SENSE, NULL, 0
#define EXPECT_NO_MEDIUM SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_NOT_READY, no_medium_ascqs, 3
#define EXPECT_LBA_OOB SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, lba_oob_ascqs, 1
#define EXPECT_INVALID_FIELD_IN_CDB SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, invalid_cdb_ascqs, 1
#define EXPECT_MISCOMPARE SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_MISCOMPARE, 0, 0
#define EXPECT_WRITE_PROTECTED SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_DATA_PROTECTION, write_protect_ascqs, 1
int no_medium_ascqs[3];
int lba_oob_ascqs[1];
int invalid_cdb_ascqs[1];
int write_protect_ascqs[1];
extern int loglevel;
#define LOG_SILENT 0
#define LOG_NORMAL 1