2022-09-25 21:49:24 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// SCSI Target Emulator RaSCSI Reloaded
|
|
|
|
// for Raspberry Pi
|
|
|
|
//
|
|
|
|
// Copyright (C) 2022 Uwe Seimet
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
#include "mocks.h"
|
|
|
|
#include "scsi.h"
|
|
|
|
#include "devices/disk.h"
|
2022-09-25 21:49:24 +00:00
|
|
|
#include "rascsi_exceptions.h"
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
using namespace scsi_defs;
|
|
|
|
|
|
|
|
TEST(DiskTest, Dispatch)
|
|
|
|
{
|
|
|
|
MockAbstractController controller(0);
|
|
|
|
const unordered_set<uint32_t> sector_sizes;
|
|
|
|
auto disk = make_shared<MockDisk>();
|
|
|
|
|
|
|
|
controller.AddDevice(disk);
|
|
|
|
|
|
|
|
disk->MediumChanged();
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdTestUnitReady), scsi_exception);
|
2022-10-04 15:23:42 +00:00
|
|
|
}
|
|
|
|
|
2022-09-25 21:49:24 +00:00
|
|
|
TEST(DiskTest, Rezero)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdRezero), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "REZERO must fail because drive is not ready";
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetReady(true);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdRezero));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, FormatUnit)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
vector<int>& cmd = controller.InitCmd(6);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdFormat), scsi_exception);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetReady(true);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdFormat));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x10;
|
|
|
|
cmd[4] = 1;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdFormat), scsi_exception);
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, ReassignBlocks)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReassign), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "REASSIGN must fail because drive is not ready";
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetReady(true);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReassign));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, Seek)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
vector<int>& cmd = controller.InitCmd(10);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek6), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "SEEK(6) must fail for a medium with 0 blocks";
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "SEEK(10) must fail for a medium with 0 blocks";
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetBlockCount(1);
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek6), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "SEEK(6) must fail because drive is not ready";
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSeek10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "SEEK(10) must fail because drive is not ready";
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetReady(true);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
// Block count for SEEK(6)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[4] = 1;
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdSeek6));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[4] = 0;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
// Block count for SEEK(10)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[5] = 1;
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdSeek10));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, ReadCapacity)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
vector<int>& cmd = controller.InitCmd(16);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "Neithed READ CAPACITY(16) nor READ LONG(16)";
|
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ CAPACITY(10) must fail because drive is not ready";
|
|
|
|
// READ CAPACITY(16), not READ LONG(16)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x10;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ CAPACITY(16) must fail because drive is not ready";
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x00;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetReady(true);
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ CAPACITY(10) must fail because the medium has no capacity";
|
|
|
|
// READ CAPACITY(16), not READ LONG(16)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x10;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ CAPACITY(16) must fail because the medium has no capacity";
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x00;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetBlockCount(0x12345678);
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, DataIn()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity10));
|
2022-10-01 15:56:06 +00:00
|
|
|
EXPECT_EQ(0x12, controller.GetBuffer()[0]);
|
|
|
|
EXPECT_EQ(0x34, controller.GetBuffer()[1]);
|
|
|
|
EXPECT_EQ(0x56, controller.GetBuffer()[2]);
|
|
|
|
EXPECT_EQ(0x77, controller.GetBuffer()[3]);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetBlockCount(0x1234567887654321);
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, DataIn()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity10));
|
2022-10-01 15:56:06 +00:00
|
|
|
EXPECT_EQ(0xff, controller.GetBuffer()[0]);
|
|
|
|
EXPECT_EQ(0xff, controller.GetBuffer()[1]);
|
|
|
|
EXPECT_EQ(0xff, controller.GetBuffer()[2]);
|
|
|
|
EXPECT_EQ(0xff, controller.GetBuffer()[3]);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetSectorSizeInBytes(1024);
|
2022-09-25 21:49:24 +00:00
|
|
|
// READ CAPACITY(16), not READ LONG(16)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x10;
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, DataIn()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16));
|
2022-10-01 15:56:06 +00:00
|
|
|
EXPECT_EQ(0x12, controller.GetBuffer()[0]);
|
|
|
|
EXPECT_EQ(0x34, controller.GetBuffer()[1]);
|
|
|
|
EXPECT_EQ(0x56, controller.GetBuffer()[2]);
|
|
|
|
EXPECT_EQ(0x78, controller.GetBuffer()[3]);
|
|
|
|
EXPECT_EQ(0x87, controller.GetBuffer()[4]);
|
|
|
|
EXPECT_EQ(0x65, controller.GetBuffer()[5]);
|
|
|
|
EXPECT_EQ(0x43, controller.GetBuffer()[6]);
|
|
|
|
EXPECT_EQ(0x20, controller.GetBuffer()[7]);
|
|
|
|
EXPECT_EQ(0x00, controller.GetBuffer()[8]);
|
|
|
|
EXPECT_EQ(0x00, controller.GetBuffer()[9]);
|
|
|
|
EXPECT_EQ(0x04, controller.GetBuffer()[10]);
|
|
|
|
EXPECT_EQ(0x00, controller.GetBuffer()[11]);
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, ReadWriteLong)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
vector<int>& cmd = controller.InitCmd(16);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadLong10));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdWriteLong10));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[2] = 1;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadLong10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ LONG(10) must fail because the capacity is exceeded";
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "WRITE LONG(10) must fail because the capacity is exceeded";
|
|
|
|
// READ LONG(16), not READ CAPACITY(16)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x11;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ LONG(16) must fail because the capacity is exceeded";
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong16), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "WRITE LONG(16) must fail because the capacity is exceeded";
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[2] = 0;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[7] = 1;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadLong10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ LONG(10) must fail because it currently only supports 0 bytes transfer length";
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong10), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "WRITE LONG(10) must fail because it currently only supports 0 bytes transfer length";
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[7] = 0;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
// READ LONG(16), not READ CAPACITY(16)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x11;
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x00;
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdWriteLong16));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[13] = 1;
|
2022-09-25 21:49:24 +00:00
|
|
|
// READ LONG(16), not READ CAPACITY(16)
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x11;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "READ LONG(16) must fail because it currently only supports 0 bytes transfer length";
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x00;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdWriteLong16), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "WRITE LONG(16) must fail because it currently only supports 0 bytes transfer length";
|
|
|
|
}
|
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
TEST(DiskTest, Reserve)
|
2022-09-25 21:49:24 +00:00
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReserve6));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-10-08 17:26:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, Release)
|
|
|
|
{
|
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
|
|
|
|
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdRelease6));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, SendDiagnostic)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
vector<int>& cmd = controller.InitCmd(6);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdSendDiag));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0x10;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSendDiag), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "SEND DIAGNOSTIC must fail because PF bit is not supported";
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[1] = 0;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[3] = 1;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSendDiag), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "SEND DIAGNOSTIC must fail because parameter list is not supported";
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[3] = 0;
|
|
|
|
cmd[4] = 1;
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdSendDiag), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "SEND DIAGNOSTIC must fail because parameter list is not supported";
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, PreventAllowMediumRemoval)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
vector<int>& cmd = controller.InitCmd(6);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-08 17:26:04 +00:00
|
|
|
EXPECT_THROW(disk->Dispatch(scsi_command::eCmdRemoval), scsi_exception)
|
2022-09-25 21:49:24 +00:00
|
|
|
<< "REMOVAL must fail because drive is not ready";
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
disk->SetReady(true);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdRemoval));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
|
|
|
EXPECT_FALSE(disk->IsLocked());
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
cmd[4] = 1;
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdRemoval));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
|
|
|
EXPECT_TRUE(disk->IsLocked());
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, SynchronizeCache)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_CALL(*disk, FlushCache()).Times(1);
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdSynchronizeCache10));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_CALL(*disk, FlushCache()).Times(1);
|
2022-09-25 21:49:24 +00:00
|
|
|
EXPECT_CALL(controller, Status()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdSynchronizeCache16));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, ReadDefectData)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockAbstractController controller(0);
|
|
|
|
auto disk = make_shared<MockDisk>();
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
controller.AddDevice(disk);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-01 15:56:06 +00:00
|
|
|
controller.InitCmd(10);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(controller, DataIn()).Times(1);
|
2022-10-04 15:23:42 +00:00
|
|
|
EXPECT_TRUE(disk->Dispatch(scsi_command::eCmdReadDefectData10));
|
|
|
|
EXPECT_EQ(status::GOOD, controller.GetStatus());
|
2022-09-25 21:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, SectorSize)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockDisk disk;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
unordered_set<uint32_t> sizes = { 512, 1024 };
|
2022-09-25 21:49:24 +00:00
|
|
|
disk.SetSectorSizes(sizes);
|
|
|
|
EXPECT_TRUE(disk.IsSectorSizeConfigurable());
|
|
|
|
|
|
|
|
sizes.clear();
|
|
|
|
disk.SetSectorSizes(sizes);
|
|
|
|
EXPECT_FALSE(disk.IsSectorSizeConfigurable());
|
|
|
|
|
|
|
|
disk.SetSectorSizeShiftCount(9);
|
|
|
|
EXPECT_EQ(9, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(512, disk.GetSectorSizeInBytes());
|
|
|
|
disk.SetSectorSizeInBytes(512);
|
|
|
|
EXPECT_EQ(9, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(512, disk.GetSectorSizeInBytes());
|
|
|
|
|
|
|
|
disk.SetSectorSizeShiftCount(10);
|
|
|
|
EXPECT_EQ(10, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(1024, disk.GetSectorSizeInBytes());
|
|
|
|
disk.SetSectorSizeInBytes(1024);
|
|
|
|
EXPECT_EQ(10, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(1024, disk.GetSectorSizeInBytes());
|
|
|
|
|
|
|
|
disk.SetSectorSizeShiftCount(11);
|
|
|
|
EXPECT_EQ(11, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(2048, disk.GetSectorSizeInBytes());
|
|
|
|
disk.SetSectorSizeInBytes(2048);
|
|
|
|
EXPECT_EQ(11, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(2048, disk.GetSectorSizeInBytes());
|
|
|
|
|
|
|
|
disk.SetSectorSizeShiftCount(12);
|
|
|
|
EXPECT_EQ(12, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(4096, disk.GetSectorSizeInBytes());
|
|
|
|
disk.SetSectorSizeInBytes(4096);
|
|
|
|
EXPECT_EQ(12, disk.GetSectorSizeShiftCount());
|
|
|
|
EXPECT_EQ(4096, disk.GetSectorSizeInBytes());
|
|
|
|
|
|
|
|
EXPECT_THROW(disk.SetSectorSizeInBytes(1234), io_exception);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, ConfiguredSectorSize)
|
|
|
|
{
|
|
|
|
DeviceFactory device_factory;
|
2022-10-04 15:23:42 +00:00
|
|
|
const unordered_set<uint32_t> sector_sizes;
|
|
|
|
MockSCSIHD disk(0, sector_sizes, false);
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
EXPECT_TRUE(disk.SetConfiguredSectorSize(device_factory, 512));
|
|
|
|
EXPECT_EQ(512, disk.GetConfiguredSectorSize());
|
|
|
|
|
|
|
|
EXPECT_FALSE(disk.SetConfiguredSectorSize(device_factory, 1234));
|
|
|
|
EXPECT_EQ(512, disk.GetConfiguredSectorSize());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, BlockCount)
|
|
|
|
{
|
2022-10-04 15:23:42 +00:00
|
|
|
MockDisk disk;
|
2022-09-25 21:49:24 +00:00
|
|
|
|
|
|
|
disk.SetBlockCount(0x1234567887654321);
|
|
|
|
EXPECT_EQ(0x1234567887654321, disk.GetBlockCount());
|
|
|
|
}
|
2022-10-08 17:26:04 +00:00
|
|
|
|
|
|
|
TEST(DiskTest, GetIdsForReservedFile)
|
|
|
|
{
|
|
|
|
const int ID = 1;
|
|
|
|
const int LUN = 2;
|
|
|
|
|
|
|
|
Filepath path;
|
|
|
|
path.SetPath("path");
|
|
|
|
MockDisk disk;
|
|
|
|
|
|
|
|
disk.SetPath(path);
|
|
|
|
Filepath result;
|
|
|
|
disk.GetPath(result);
|
|
|
|
EXPECT_STREQ("path", result.GetPath());
|
|
|
|
|
|
|
|
int id;
|
|
|
|
int lun;
|
|
|
|
EXPECT_FALSE(Disk::GetIdsForReservedFile(path, id, lun));
|
|
|
|
|
|
|
|
disk.ReserveFile(path, ID, LUN);
|
|
|
|
EXPECT_TRUE(Disk::GetIdsForReservedFile(path, id, lun));
|
|
|
|
EXPECT_EQ(ID, id);
|
|
|
|
EXPECT_EQ(LUN, lun);
|
|
|
|
|
|
|
|
disk.UnreserveFile();
|
|
|
|
EXPECT_FALSE(Disk::GetIdsForReservedFile(path, id, lun));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiskTest, UnreserveAll)
|
|
|
|
{
|
|
|
|
const int ID = 2;
|
|
|
|
const int LUN = 31;
|
|
|
|
|
|
|
|
Filepath path;
|
|
|
|
path.SetPath("path");
|
|
|
|
MockDisk disk;
|
|
|
|
|
|
|
|
disk.ReserveFile(path, ID, LUN);
|
|
|
|
Disk::UnreserveAll();
|
|
|
|
int id;
|
|
|
|
int lun;
|
|
|
|
EXPECT_FALSE(Disk::GetIdsForReservedFile(path, id, lun));
|
|
|
|
}
|