From c98c52ffb827acceebd892273fab8501d15758c4 Mon Sep 17 00:00:00 2001 From: Uwe Seimet <48174652+uweseimet@users.noreply.github.com> Date: Fri, 4 Nov 2022 08:22:32 +0100 Subject: [PATCH] Cleaned up dependencies on controller manager (#964) * Cleaned up dependencies on controller manager * Removed global fields * Simplified setting up RascsiResponse and RascsiExecutor * Got rid of remaining raw pointers * Use references instead of pointers * Improved encapsulation --- cpp/controllers/abstract_controller.cpp | 2 +- cpp/controllers/abstract_controller.h | 13 +- cpp/controllers/controller_manager.cpp | 9 +- cpp/controllers/controller_manager.h | 8 +- cpp/controllers/scsi_controller.cpp | 106 ++++---- cpp/controllers/scsi_controller.h | 3 +- cpp/devices/device_factory.cpp | 20 +- cpp/devices/device_factory.h | 7 +- cpp/devices/disk.cpp | 73 +++--- cpp/devices/disk.h | 8 +- cpp/devices/host_services.cpp | 28 +- cpp/devices/host_services.h | 8 +- cpp/devices/mode_page_device.cpp | 22 +- cpp/devices/mode_page_device.h | 10 +- cpp/devices/primary_device.cpp | 56 ++-- cpp/devices/primary_device.h | 13 +- cpp/devices/scsi_daynaport.cpp | 68 ++--- cpp/devices/scsi_daynaport.h | 8 +- cpp/devices/scsi_host_bridge.cpp | 22 +- cpp/devices/scsi_host_bridge.h | 2 +- cpp/devices/scsi_printer.cpp | 10 +- cpp/devices/scsicd.cpp | 2 +- cpp/rascsi/rascsi_core.cpp | 97 +++---- cpp/rascsi/rascsi_core.h | 30 ++- cpp/rascsi/rascsi_executor.cpp | 6 +- cpp/rascsi/rascsi_executor.h | 33 ++- cpp/rascsi/rascsi_response.cpp | 31 +-- cpp/rascsi/rascsi_response.h | 29 +-- cpp/rascsi/rascsi_service.cpp | 5 +- cpp/test/abstract_controller_test.cpp | 112 +++++--- cpp/test/controller_manager_test.cpp | 70 ++--- cpp/test/device_factory_test.cpp | 47 ++-- cpp/test/disk_test.cpp | 324 ++++++++++++++---------- cpp/test/host_services_test.cpp | 71 +++--- cpp/test/mocks.h | 13 +- cpp/test/mode_page_device_test.cpp | 36 ++- cpp/test/primary_device_test.cpp | 116 +++++---- cpp/test/rascsi_executor_test.cpp | 174 ++++++------- cpp/test/rascsi_response_test.cpp | 75 +++--- cpp/test/scsi_controller_test.cpp | 86 ++++--- cpp/test/scsi_daynaport_test.cpp | 84 +++--- cpp/test/scsi_printer_test.cpp | 78 +++--- cpp/test/scsicd_test.cpp | 6 +- cpp/test/test_shared.cpp | 15 +- 44 files changed, 1071 insertions(+), 965 deletions(-) diff --git a/cpp/controllers/abstract_controller.cpp b/cpp/controllers/abstract_controller.cpp index 0dd6a1a2..7354bce3 100644 --- a/cpp/controllers/abstract_controller.cpp +++ b/cpp/controllers/abstract_controller.cpp @@ -117,7 +117,7 @@ bool AbstractController::AddDevice(shared_ptr device) } luns[device->GetLun()] = device; - device->SetController(this); + device->SetController(shared_from_this()); return true; } diff --git a/cpp/controllers/abstract_controller.h b/cpp/controllers/abstract_controller.h index 0ab370eb..0b4a24f0 100644 --- a/cpp/controllers/abstract_controller.h +++ b/cpp/controllers/abstract_controller.h @@ -14,6 +14,7 @@ #include "scsi.h" #include "hal/bus.h" #include "phase_handler.h" +#include "controller_manager.h" #include #include #include @@ -23,7 +24,7 @@ using namespace std; class PrimaryDevice; -class AbstractController : public PhaseHandler +class AbstractController : public PhaseHandler, public enable_shared_from_this { public: @@ -34,7 +35,8 @@ public: RESTART_PI }; - AbstractController(shared_ptr bus, int target_id, int max_luns) : target_id(target_id), bus(bus), max_luns(max_luns) {} + AbstractController(shared_ptr controller_manager, int target_id, int max_luns) + : controller_manager(controller_manager), target_id(target_id), max_luns(max_luns) {} ~AbstractController() override = default; virtual void Error(scsi_defs::sense_key, scsi_defs::asc = scsi_defs::asc::NO_ADDITIONAL_SENSE_INFORMATION, @@ -82,7 +84,8 @@ public: protected: - inline shared_ptr GetBus() const { return bus; } + shared_ptr GetControllerManager() const { return controller_manager.lock(); } + inline BUS& GetBus() const { return controller_manager.lock()->GetBus(); } scsi_defs::scsi_command GetOpcode() const { return static_cast(ctrl.cmd[0]); } int GetLun() const { return (ctrl.cmd[1] >> 5) & 0x07; } @@ -116,13 +119,13 @@ private: ctrl_t ctrl = {}; + weak_ptr controller_manager; + // Logical units of this controller mapped to their LUN numbers unordered_map> luns; int target_id; - shared_ptr bus; - int max_luns; bool is_byte_transfer = false; diff --git a/cpp/controllers/controller_manager.cpp b/cpp/controllers/controller_manager.cpp index 424e4ba6..a5cbba86 100644 --- a/cpp/controllers/controller_manager.cpp +++ b/cpp/controllers/controller_manager.cpp @@ -23,7 +23,7 @@ bool ControllerManager::AttachToScsiController(int id, shared_ptr // If there is no LUN yet the first LUN must be LUN 0 if (device->GetLun() == 0) { - controller = make_shared(bus, id); + controller = make_shared(shared_from_this(), id); if (controller->AddDevice(device)) { controllers[id] = controller; @@ -74,13 +74,6 @@ void ControllerManager::DeleteAllControllers() controllers.clear(); } -void ControllerManager::ResetAllControllers() const -{ - for (const auto& [id, controller] : controllers) { - controller->Reset(); - } -} - shared_ptr ControllerManager::GetDeviceByIdAndLun(int id, int lun) const { if (const auto& controller = FindController(id); controller != nullptr) { diff --git a/cpp/controllers/controller_manager.h b/cpp/controllers/controller_manager.h index 36a28fa9..640eaade 100644 --- a/cpp/controllers/controller_manager.h +++ b/cpp/controllers/controller_manager.h @@ -21,26 +21,26 @@ class BUS; class AbstractController; class PrimaryDevice; -class ControllerManager +class ControllerManager : public enable_shared_from_this { - shared_ptr bus; + BUS& bus; unordered_map> controllers; public: - explicit ControllerManager(shared_ptr bus) : bus(bus) {} + explicit ControllerManager(BUS& bus) : bus(bus) {} ~ControllerManager() = default; // Maximum number of controller devices static const int DEVICE_MAX = 8; + inline BUS& GetBus() const { return bus; } bool AttachToScsiController(int, shared_ptr); bool DeleteController(shared_ptr); shared_ptr IdentifyController(int) const; shared_ptr FindController(int) const; unordered_set> GetAllDevices() const; void DeleteAllControllers(); - void ResetAllControllers() const; shared_ptr GetDeviceByIdAndLun(int, int) const; }; diff --git a/cpp/controllers/scsi_controller.cpp b/cpp/controllers/scsi_controller.cpp index 16166a98..e53fab05 100644 --- a/cpp/controllers/scsi_controller.cpp +++ b/cpp/controllers/scsi_controller.cpp @@ -28,7 +28,8 @@ using namespace scsi_defs; -ScsiController::ScsiController(shared_ptr bus, int target_id) : AbstractController(bus, target_id, LUN_MAX) +ScsiController::ScsiController(shared_ptr controller_manager, int target_id) + : AbstractController(controller_manager, target_id, LUN_MAX) { // The initial buffer size will default to either the default buffer size OR // the size of an Ethernet message, whichever is larger. @@ -51,18 +52,14 @@ void ScsiController::Reset() BUS::phase_t ScsiController::Process(int id) { - // Get bus information - GetBus()->Acquire(); + GetBus().Acquire(); - // Check to see if the reset signal was asserted - if (GetBus()->GetRST()) { + if (GetBus().GetRST()) { LOGWARN("RESET signal received!") - // Reset the controller Reset(); - // Reset the bus - GetBus()->Reset(); + GetBus().Reset(); return GetPhase(); } @@ -84,7 +81,7 @@ BUS::phase_t ScsiController::Process(int id) LOGERROR("%s Unhandled SCSI error, resetting controller and bus and entering bus free phase", __PRETTY_FUNCTION__) Reset(); - GetBus()->Reset(); + GetBus().Reset(); BusFree(); } @@ -99,11 +96,11 @@ void ScsiController::BusFree() SetPhase(BUS::phase_t::busfree); - GetBus()->SetREQ(false); - GetBus()->SetMSG(false); - GetBus()->SetCD(false); - GetBus()->SetIO(false); - GetBus()->SetBSY(false); + GetBus().SetREQ(false); + GetBus().SetMSG(false); + GetBus().SetCD(false); + GetBus().SetIO(false); + GetBus().SetBSY(false); // Initialize status and message SetStatus(status::GOOD); @@ -116,6 +113,13 @@ void ScsiController::BusFree() SetByteTransfer(false); + if (shutdown_mode != rascsi_shutdown_mode::NONE) { + // Prepare the shutdown by flushing all caches + for (const auto& device : GetControllerManager()->GetAllDevices()) { + device->FlushCache(); + } + } + // When the bus is free RaSCSI or the Pi may be shut down. // This code has to be executed in the bus free phase and thus has to be located in the controller. switch(shutdown_mode) { @@ -146,7 +150,7 @@ void ScsiController::BusFree() } // Move to selection phase - if (GetBus()->GetSEL() && !GetBus()->GetBSY()) { + if (GetBus().GetSEL() && !GetBus().GetBSY()) { Selection(); } } @@ -155,7 +159,7 @@ void ScsiController::Selection() { if (!IsSelection()) { // A different device controller was selected - if (int id = 1 << GetTargetId(); (static_cast(GetBus()->GetDAT()) & id) == 0) { + if (int id = 1 << GetTargetId(); (static_cast(GetBus().GetDAT()) & id) == 0) { return; } @@ -169,14 +173,14 @@ void ScsiController::Selection() SetPhase(BUS::phase_t::selection); // Raise BSY and respond - GetBus()->SetBSY(true); + GetBus().SetBSY(true); return; } // Selection completed - if (!GetBus()->GetSEL() && GetBus()->GetBSY()) { + if (!GetBus().GetSEL() && GetBus().GetBSY()) { // Message out phase if ATN=1, otherwise command phase - if (GetBus()->GetATN()) { + if (GetBus().GetATN()) { MsgOut(); } else { Command(); @@ -191,11 +195,11 @@ void ScsiController::Command() SetPhase(BUS::phase_t::command); - GetBus()->SetMSG(false); - GetBus()->SetCD(true); - GetBus()->SetIO(false); + GetBus().SetMSG(false); + GetBus().SetCD(true); + GetBus().SetIO(false); - const int actual_count = GetBus()->CommandHandShake(GetBuffer().data()); + const int actual_count = GetBus().CommandHandShake(GetBuffer().data()); const int command_byte_count = BUS::GetCommandByteCount(GetBuffer()[0]); // If not able to receive all, move to the status phase @@ -295,9 +299,9 @@ void ScsiController::Status() SetPhase(BUS::phase_t::status); // Signal line operated by the target - GetBus()->SetMSG(false); - GetBus()->SetCD(true); - GetBus()->SetIO(true); + GetBus().SetMSG(false); + GetBus().SetCD(true); + GetBus().SetIO(true); // Data transfer is 1 byte x 1 block ResetOffset(); @@ -318,9 +322,9 @@ void ScsiController::MsgIn() SetPhase(BUS::phase_t::msgin); - GetBus()->SetMSG(true); - GetBus()->SetCD(true); - GetBus()->SetIO(true); + GetBus().SetMSG(true); + GetBus().SetCD(true); + GetBus().SetIO(true); ResetOffset(); return; @@ -345,9 +349,9 @@ void ScsiController::MsgOut() SetPhase(BUS::phase_t::msgout); - GetBus()->SetMSG(true); - GetBus()->SetCD(true); - GetBus()->SetIO(false); + GetBus().SetMSG(true); + GetBus().SetCD(true); + GetBus().SetIO(false); // Data transfer is 1 byte x 1 block ResetOffset(); @@ -378,9 +382,9 @@ void ScsiController::DataIn() SetPhase(BUS::phase_t::datain); - GetBus()->SetMSG(false); - GetBus()->SetCD(false); - GetBus()->SetIO(true); + GetBus().SetMSG(false); + GetBus().SetCD(false); + GetBus().SetIO(true); ResetOffset(); @@ -409,9 +413,9 @@ void ScsiController::DataOut() SetPhase(BUS::phase_t::dataout); // Signal line operated by the target - GetBus()->SetMSG(false); - GetBus()->SetCD(false); - GetBus()->SetIO(false); + GetBus().SetMSG(false); + GetBus().SetCD(false); + GetBus().SetIO(false); ResetOffset(); return; @@ -423,12 +427,12 @@ void ScsiController::DataOut() void ScsiController::Error(sense_key sense_key, asc asc, status status) { // Get bus information - GetBus()->Acquire(); + GetBus().Acquire(); // Reset check - if (GetBus()->GetRST()) { + if (GetBus().GetRST()) { Reset(); - GetBus()->Reset(); + GetBus().Reset(); return; } @@ -472,8 +476,8 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status) void ScsiController::Send() { - assert(!GetBus()->GetREQ()); - assert(GetBus()->GetIO()); + assert(!GetBus().GetREQ()); + assert(GetBus().GetIO()); if (HasValidLength()) { LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(GetOffset()) + ", length " @@ -481,7 +485,7 @@ void ScsiController::Send() // The delay should be taken from the respective LUN, but as there are no Daynaport drivers for // LUNs other than 0 this work-around works. - if (const int len = GetBus()->SendHandShake(GetBuffer().data() + GetOffset(), GetLength(), + if (const int len = GetBus().SendHandShake(GetBuffer().data() + GetOffset(), GetLength(), HasDeviceForLun(0) ? GetDeviceForLun(0)->GetSendDelay() : 0); len != static_cast(GetLength())) { // If you cannot send all, move to status phase @@ -568,15 +572,15 @@ void ScsiController::Receive() LOGTRACE("%s",__PRETTY_FUNCTION__) // REQ is low - assert(!GetBus()->GetREQ()); - assert(!GetBus()->GetIO()); + assert(!GetBus().GetREQ()); + assert(!GetBus().GetIO()); // Length != 0 if received if (HasValidLength()) { LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, GetLength()) // If not able to receive all, move to status phase - if (int len = GetBus()->ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength()); + if (int len = GetBus().ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength()); len != static_cast(GetLength())) { LOGERROR("%s Not able to receive %d bytes of data, only received %d",__PRETTY_FUNCTION__, GetLength(), len) Error(sense_key::ABORTED_COMMAND); @@ -673,14 +677,14 @@ bool ScsiController::XferMsg(int msg) void ScsiController::ReceiveBytes() { - assert(!GetBus()->GetREQ()); - assert(!GetBus()->GetIO()); + assert(!GetBus().GetREQ()); + assert(!GetBus().GetIO()); if (HasValidLength()) { LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, GetLength()) // If not able to receive all, move to status phase - if (uint32_t len = GetBus()->ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength()); len != GetLength()) { + if (uint32_t len = GetBus().ReceiveHandShake(GetBuffer().data() + GetOffset(), GetLength()); len != GetLength()) { LOGERROR("%s Not able to receive %d bytes of data, only received %d", __PRETTY_FUNCTION__, GetLength(), len) Error(sense_key::ABORTED_COMMAND); @@ -1014,7 +1018,7 @@ void ScsiController::ParseMessage() void ScsiController::ProcessMessage() { // Continue message out phase as long as ATN keeps asserting - if (GetBus()->GetATN()) { + if (GetBus().GetATN()) { // Data transfer is 1 byte x 1 block ResetOffset(); SetLength(1); diff --git a/cpp/controllers/scsi_controller.h b/cpp/controllers/scsi_controller.h index 8616b796..b1167540 100644 --- a/cpp/controllers/scsi_controller.h +++ b/cpp/controllers/scsi_controller.h @@ -14,6 +14,7 @@ #pragma once +#include "controller_manager.h" #include "abstract_controller.h" #include "scsi.h" #include @@ -53,7 +54,7 @@ public: // Maximum number of logical units static inline const int LUN_MAX = 32; - ScsiController(shared_ptr, int); + explicit ScsiController(shared_ptr, int); ~ScsiController() override = default; void Reset() override; diff --git a/cpp/devices/device_factory.cpp b/cpp/devices/device_factory.cpp index dff49457..5706035c 100644 --- a/cpp/devices/device_factory.cpp +++ b/cpp/devices/device_factory.cpp @@ -14,7 +14,6 @@ #include "scsi_printer.h" #include "scsi_host_bridge.h" #include "scsi_daynaport.h" -#include "rascsi_exceptions.h" #include "host_services.h" #include "rasutil.h" #include "device_factory.h" @@ -78,8 +77,7 @@ PbDeviceType DeviceFactory::GetTypeForFile(const string& filename) const return UNDEFINED; } -shared_ptr DeviceFactory::CreateDevice(const ControllerManager& controller_manager, PbDeviceType type, - int lun, const string& filename) +shared_ptr DeviceFactory::CreateDevice(PbDeviceType type, int lun, const string& filename) const { // If no type was specified try to derive the device type from the filename if (type == UNDEFINED) { @@ -95,7 +93,7 @@ shared_ptr DeviceFactory::CreateDevice(const ControllerManager& c if (const string ext = GetExtensionLowerCase(filename); ext == "hdn" || ext == "hdi" || ext == "nhd") { device = make_shared(lun); } else { - device = make_shared(lun, sector_sizes[SCHD], false, + device = make_shared(lun, sector_sizes.find(SCHD)->second, false, ext == "hd1" ? scsi_level::SCSI_1_CCS : scsi_level::SCSI_2); // Some Apple tools require a particular drive identification @@ -108,17 +106,17 @@ shared_ptr DeviceFactory::CreateDevice(const ControllerManager& c } case SCRM: - device = make_shared(lun, sector_sizes[SCRM], true); + device = make_shared(lun, sector_sizes.find(SCRM)->second, true); device->SetProduct("SCSI HD (REM.)"); break; case SCMO: - device = make_shared(lun, sector_sizes[SCMO]); + device = make_shared(lun, sector_sizes.find(SCMO)->second); device->SetProduct("SCSI MO"); break; case SCCD: - device = make_shared(lun, sector_sizes[SCCD]); + device = make_shared(lun, sector_sizes.find(SCCD)->second); device->SetProduct("SCSI CD-ROM"); break; @@ -126,7 +124,7 @@ shared_ptr DeviceFactory::CreateDevice(const ControllerManager& c device = make_shared(lun); // Since this is an emulation for a specific driver the product name has to be set accordingly device->SetProduct("RASCSI BRIDGE"); - device->SetDefaultParams(default_params[SCBR]); + device->SetDefaultParams(default_params.find(SCBR)->second); break; case SCDP: @@ -135,11 +133,11 @@ shared_ptr DeviceFactory::CreateDevice(const ControllerManager& c device->SetVendor("Dayna"); device->SetProduct("SCSI/Link"); device->SetRevision("1.4a"); - device->SetDefaultParams(default_params[SCDP]); + device->SetDefaultParams(default_params.find(SCDP)->second); break; case SCHS: - device = make_shared(lun, controller_manager); + device = make_shared(lun); // Since this is an emulation for a specific device the full INQUIRY data have to be set accordingly device->SetVendor("RaSCSI"); device->SetProduct("Host Services"); @@ -148,7 +146,7 @@ shared_ptr DeviceFactory::CreateDevice(const ControllerManager& c case SCLP: device = make_shared(lun); device->SetProduct("SCSI PRINTER"); - device->SetDefaultParams(default_params[SCLP]); + device->SetDefaultParams(default_params.find(SCLP)->second); break; default: diff --git a/cpp/devices/device_factory.h b/cpp/devices/device_factory.h index 43ac0bd3..08287952 100644 --- a/cpp/devices/device_factory.h +++ b/cpp/devices/device_factory.h @@ -5,7 +5,7 @@ // // Copyright (C) 2021-2022 Uwe Seimet // -// The DeviceFactory singleton creates devices based on their type and the image file extension +// The DeviceFactory creates devices based on their type and the image file extension // //--------------------------------------------------------------------------- @@ -20,19 +20,18 @@ using namespace std; using namespace rascsi_interface; -class ControllerManager; class PrimaryDevice; class DeviceFactory { - const string DEFAULT_IP = "10.10.20.1/24"; //NOSONAR This hardcoded IP address is safe + const inline static string DEFAULT_IP = "10.10.20.1/24"; //NOSONAR This hardcoded IP address is safe public: DeviceFactory(); ~DeviceFactory() = default; - shared_ptr CreateDevice(const ControllerManager&, PbDeviceType, int, const string&); + shared_ptr CreateDevice(PbDeviceType, int, const string&) const; PbDeviceType GetTypeForFile(const string&) const; const unordered_set& GetSectorSizes(PbDeviceType type) const; const unordered_map& GetDefaultParams(PbDeviceType type) const; diff --git a/cpp/devices/disk.cpp b/cpp/devices/disk.cpp index e619b326..95285931 100644 --- a/cpp/devices/disk.cpp +++ b/cpp/devices/disk.cpp @@ -71,7 +71,7 @@ void Disk::Dispatch(scsi_command cmd) SetMediumChanged(false); - controller->Error(sense_key::UNIT_ATTENTION, asc::NOT_READY_TO_READY_CHANGE); + GetController()->Error(sense_key::UNIT_ATTENTION, asc::NOT_READY_TO_READY_CHANGE); } else { PrimaryDevice::Dispatch(cmd); @@ -102,7 +102,7 @@ void Disk::FormatUnit() CheckReady(); // FMTDATA=1 is not supported (but OK if there is no DEFECT LIST) - if ((controller->GetCmd(1) & 0x10) != 0 && controller->GetCmd(4) != 0) { + if ((GetController()->GetCmd(1) & 0x10) != 0 && GetController()->GetCmd(4) != 0) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } @@ -113,13 +113,13 @@ void Disk::Read(access_mode mode) { const auto& [valid, start, blocks] = CheckAndGetStartAndCount(mode); if (valid) { - controller->SetBlocks(blocks); - controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), start)); + GetController()->SetBlocks(blocks); + GetController()->SetLength(Read(GetController()->GetCmd(), GetController()->GetBuffer(), start)); - LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, controller->GetLength()) + LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, GetController()->GetLength()) // Set next block - controller->SetNext(start + 1); + GetController()->SetNext(start + 1); EnterDataInPhase(); } @@ -128,31 +128,31 @@ void Disk::Read(access_mode mode) } } -void Disk::ReadWriteLong10() +void Disk::ReadWriteLong10() const { ValidateBlockAddress(RW10); // Transfer lengths other than 0 are not supported, which is compliant with the SCSI standard - if (GetInt16(controller->GetCmd(), 7) != 0) { + if (GetInt16(GetController()->GetCmd(), 7) != 0) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } EnterStatusPhase(); } -void Disk::ReadWriteLong16() +void Disk::ReadWriteLong16() const { ValidateBlockAddress(RW16); // Transfer lengths other than 0 are not supported, which is compliant with the SCSI standard - if (GetInt16(controller->GetCmd(), 12) != 0) { + if (GetInt16(GetController()->GetCmd(), 12) != 0) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } EnterStatusPhase(); } -void Disk::Write(access_mode mode) +void Disk::Write(access_mode mode) const { if (IsProtected()) { throw scsi_exception(sense_key::DATA_PROTECT, asc::WRITE_PROTECTED); @@ -160,11 +160,11 @@ void Disk::Write(access_mode mode) const auto& [valid, start, blocks] = CheckAndGetStartAndCount(mode); if (valid) { - controller->SetBlocks(blocks); - controller->SetLength(GetSectorSizeInBytes()); + GetController()->SetBlocks(blocks); + GetController()->SetLength(GetSectorSizeInBytes()); // Set next block - controller->SetNext(start + 1); + GetController()->SetNext(start + 1); EnterDataOutPhase(); } @@ -178,17 +178,17 @@ void Disk::Verify(access_mode mode) const auto& [valid, start, blocks] = CheckAndGetStartAndCount(mode); if (valid) { // if BytChk=0 - if ((controller->GetCmd(1) & 0x02) == 0) { + if ((GetController()->GetCmd(1) & 0x02) == 0) { Seek(); return; } // Test reading - controller->SetBlocks(blocks); - controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), start)); + GetController()->SetBlocks(blocks); + GetController()->SetLength(Read(GetController()->GetCmd(), GetController()->GetBuffer(), start)); // Set next block - controller->SetNext(start + 1); + GetController()->SetNext(start + 1); EnterDataOutPhase(); } @@ -199,8 +199,8 @@ void Disk::Verify(access_mode mode) void Disk::StartStopUnit() { - const bool start = controller->GetCmd(4) & 0x01; - const bool load = controller->GetCmd(4) & 0x02; + const bool start = GetController()->GetCmd(4) & 0x01; + const bool load = GetController()->GetCmd(4) & 0x02; if (load) { LOGTRACE(start ? "Loading medium" : "Ejecting medium") @@ -236,7 +236,7 @@ void Disk::PreventAllowMediumRemoval() { CheckReady(); - const bool lock = controller->GetCmd(4) & 0x01; + const bool lock = GetController()->GetCmd(4) & 0x01; LOGTRACE(lock ? "Locking medium" : "Unlocking medium") @@ -252,13 +252,14 @@ void Disk::SynchronizeCache() EnterStatusPhase(); } -void Disk::ReadDefectData10() +void Disk::ReadDefectData10() const { - const size_t allocation_length = min(static_cast(GetInt16(controller->GetCmd(), 7)), static_cast(4)); + const size_t allocation_length = min(static_cast(GetInt16(GetController()->GetCmd(), 7)), + static_cast(4)); // The defect list is empty - fill_n(controller->GetBuffer().begin(), allocation_length, 0); - controller->SetLength(static_cast(allocation_length)); + fill_n(GetController()->GetBuffer().begin(), allocation_length, 0); + GetController()->SetLength(static_cast(allocation_length)); EnterDataInPhase(); } @@ -549,7 +550,7 @@ void Disk::ReadCapacity10() throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::MEDIUM_NOT_PRESENT); } - vector& buf = controller->GetBuffer(); + vector& buf = GetController()->GetBuffer(); // Create end of logical block address (blocks-1) uint64_t capacity = GetBlockCount() - 1; @@ -563,7 +564,7 @@ void Disk::ReadCapacity10() // Create block length (1 << size) SetInt32(buf, 4, 1 << size_shift_count); - controller->SetLength(8); + GetController()->SetLength(8); EnterDataInPhase(); } @@ -576,7 +577,7 @@ void Disk::ReadCapacity16() throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::MEDIUM_NOT_PRESENT); } - vector& buf = controller->GetBuffer(); + vector& buf = GetController()->GetBuffer(); // Create end of logical block address (blocks-1) SetInt64(buf, 0, GetBlockCount() - 1); @@ -589,7 +590,7 @@ void Disk::ReadCapacity16() // Logical blocks per physical block: not reported (1 or more) buf[13] = 0; - controller->SetLength(14); + GetController()->SetLength(14); EnterDataInPhase(); } @@ -597,7 +598,7 @@ void Disk::ReadCapacity16() void Disk::ReadCapacity16_ReadLong16() { // The service action determines the actual command - switch (controller->GetCmd(1) & 0x1f) { + switch (GetController()->GetCmd(1) & 0x1f) { case 0x10: ReadCapacity16(); break; @@ -614,7 +615,7 @@ void Disk::ReadCapacity16_ReadLong16() void Disk::ValidateBlockAddress(access_mode mode) const { - const uint64_t block = mode == RW16 ? GetInt64(controller->GetCmd(), 2) : GetInt32(controller->GetCmd(), 2); + const uint64_t block = mode == RW16 ? GetInt64(GetController()->GetCmd(), 2) : GetInt32(GetController()->GetCmd(), 2); if (block > GetBlockCount()) { LOGTRACE("%s", ("Capacity of " + to_string(GetBlockCount()) + " block(s) exceeded: Trying to access block " @@ -629,21 +630,21 @@ tuple Disk::CheckAndGetStartAndCount(access_mode mode) uint32_t count; if (mode == RW6 || mode == SEEK6) { - start = GetInt24(controller->GetCmd(), 1); + start = GetInt24(GetController()->GetCmd(), 1); - count = controller->GetCmd(4); + count = GetController()->GetCmd(4); if (!count) { count= 0x100; } } else { - start = mode == RW16 ? GetInt64(controller->GetCmd(), 2) : GetInt32(controller->GetCmd(), 2); + start = mode == RW16 ? GetInt64(GetController()->GetCmd(), 2) : GetInt32(GetController()->GetCmd(), 2); if (mode == RW16) { - count = GetInt32(controller->GetCmd(), 10); + count = GetInt32(GetController()->GetCmd(), 10); } else if (mode != SEEK6 && mode != SEEK10) { - count = GetInt16(controller->GetCmd(), 7); + count = GetInt16(GetController()->GetCmd(), 7); } else { count = 0; diff --git a/cpp/devices/disk.h b/cpp/devices/disk.h index 31c46146..c6d10b00 100644 --- a/cpp/devices/disk.h +++ b/cpp/devices/disk.h @@ -67,7 +67,7 @@ private: void StartStopUnit(); void PreventAllowMediumRemoval(); void SynchronizeCache(); - void ReadDefectData10(); + void ReadDefectData10() const; virtual void Read6() { Read(RW6); } void Read10() override { Read(RW10); } void Read16() override { Read(RW16); } @@ -83,10 +83,10 @@ private: void FormatUnit() override; void Seek6(); void Read(access_mode); - void Write(access_mode); + void Write(access_mode) const; void Verify(access_mode); - void ReadWriteLong10(); - void ReadWriteLong16(); + void ReadWriteLong10() const; + void ReadWriteLong16() const; void ReadCapacity16_ReadLong16(); void ValidateBlockAddress(access_mode) const; diff --git a/cpp/devices/host_services.cpp b/cpp/devices/host_services.cpp index 043d2f7c..88bc6558 100644 --- a/cpp/devices/host_services.cpp +++ b/cpp/devices/host_services.cpp @@ -20,7 +20,6 @@ // c) start && load (LOAD): Reboot the Raspberry Pi // -#include "controllers/controller_manager.h" #include "controllers/scsi_controller.h" #include "rascsi_exceptions.h" #include "scsi_command_util.h" @@ -53,26 +52,21 @@ vector HostServices::InquiryInternal() const return HandleInquiry(device_type::PROCESSOR, scsi_level::SPC_3, false); } -void HostServices::StartStopUnit() +void HostServices::StartStopUnit() const { - const bool start = controller->GetCmd(4) & 0x01; - const bool load = controller->GetCmd(4) & 0x02; + const bool start = GetController()->GetCmd(4) & 0x01; + const bool load = GetController()->GetCmd(4) & 0x02; if (!start) { - // Flush any caches - for (const auto& device : controller_manager.GetAllDevices()) { - device->FlushCache(); - } - if (load) { - controller->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI); + GetController()->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI); } else { - controller->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI); + GetController()->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI); } } else if (load) { - controller->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI); + GetController()->ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI); } else { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); @@ -92,7 +86,7 @@ int HostServices::ModeSense6(const vector& cdb, vector& buf) const fill_n(buf.begin(), length, 0); // 4 bytes basic information - int size = AddModePages(cdb, buf, 4, length, 255); + const int size = AddModePages(cdb, buf, 4, length, 255); buf[0] = (uint8_t)size; @@ -110,7 +104,7 @@ int HostServices::ModeSense10(const vector& cdb, vector& buf) cons fill_n(buf.begin(), length, 0); // 8 bytes basic information - int size = AddModePages(cdb, buf, 8, length, 65535); + const int size = AddModePages(cdb, buf, 8, length, 65535); SetInt16(buf, 0, size); @@ -126,7 +120,7 @@ void HostServices::SetUpModePages(map>& pages, int page, bool void HostServices::AddRealtimeClockPage(map>& pages, bool changeable) const { - vector buf(10); + pages[32] = vector(10); if (!changeable) { time_t t = time(nullptr); @@ -144,8 +138,6 @@ void HostServices::AddRealtimeClockPage(map>& pages, bool chan // Ignore leap second for simplicity datetime.second = (uint8_t)(localtime.tm_sec < 60 ? localtime.tm_sec : 59); - memcpy(&buf[2], &datetime, sizeof(datetime)); + memcpy(&pages[32][2], &datetime, sizeof(datetime)); } - - pages[32] = buf; } diff --git a/cpp/devices/host_services.h b/cpp/devices/host_services.h index 365c5b5a..5beb7b47 100644 --- a/cpp/devices/host_services.h +++ b/cpp/devices/host_services.h @@ -15,14 +15,12 @@ #include #include -class ControllerManager; - class HostServices: public ModePageDevice { public: - HostServices(int lun, const ControllerManager& manager) : ModePageDevice(SCHS, lun), controller_manager(manager) {} + explicit HostServices(int lun) : ModePageDevice(SCHS, lun) {} ~HostServices() override = default; bool Init(const unordered_map&) override; @@ -49,9 +47,7 @@ private: uint8_t second; // 0-59 }; - const ControllerManager& controller_manager; - - void StartStopUnit(); + void StartStopUnit() const; int ModeSense6(const vector&, vector&) const override; int ModeSense10(const vector&, vector&) const override; diff --git a/cpp/devices/mode_page_device.cpp b/cpp/devices/mode_page_device.cpp index 2c021086..ff069fb9 100644 --- a/cpp/devices/mode_page_device.cpp +++ b/cpp/devices/mode_page_device.cpp @@ -96,16 +96,16 @@ int ModePageDevice::AddModePages(const vector& cdb, vector& buf, i return size + offset < length ? size + offset : length; } -void ModePageDevice::ModeSense6() +void ModePageDevice::ModeSense6() const { - controller->SetLength(ModeSense6(controller->GetCmd(), controller->GetBuffer())); + GetController()->SetLength(ModeSense6(GetController()->GetCmd(), GetController()->GetBuffer())); EnterDataInPhase(); } -void ModePageDevice::ModeSense10() +void ModePageDevice::ModeSense10() const { - controller->SetLength(ModeSense10(controller->GetCmd(), controller->GetBuffer())); + GetController()->SetLength(ModeSense10(GetController()->GetCmd(), GetController()->GetBuffer())); EnterDataInPhase(); } @@ -116,25 +116,25 @@ void ModePageDevice::ModeSelect(scsi_command, const vector&, const vectorGetCmd(4)); + SaveParametersCheck(GetController()->GetCmd(4)); } -void ModePageDevice::ModeSelect10() +void ModePageDevice::ModeSelect10() const { - const auto length = min(controller->GetBuffer().size(), static_cast(GetInt16(controller->GetCmd(), 7))); + const auto length = min(GetController()->GetBuffer().size(), static_cast(GetInt16(GetController()->GetCmd(), 7))); SaveParametersCheck(static_cast(length)); } -void ModePageDevice::SaveParametersCheck(int length) +void ModePageDevice::SaveParametersCheck(int length) const { - if (!SupportsSaveParameters() && (controller->GetCmd(1) & 0x01)) { + if (!SupportsSaveParameters() && (GetController()->GetCmd(1) & 0x01)) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } - controller->SetLength(length); + GetController()->SetLength(length); EnterDataOutPhase(); } diff --git a/cpp/devices/mode_page_device.h b/cpp/devices/mode_page_device.h index fa6dd838..ac8cd07e 100644 --- a/cpp/devices/mode_page_device.h +++ b/cpp/devices/mode_page_device.h @@ -42,10 +42,10 @@ private: virtual int ModeSense6(const vector&, vector&) const = 0; virtual int ModeSense10(const vector&, vector&) const = 0; - void ModeSense6(); - void ModeSense10(); - void ModeSelect6(); - void ModeSelect10(); + void ModeSense6() const; + void ModeSense10() const; + void ModeSelect6() const; + void ModeSelect10() const; - void SaveParametersCheck(int); + void SaveParametersCheck(int) const; }; diff --git a/cpp/devices/primary_device.cpp b/cpp/devices/primary_device.cpp index f9478d87..94545636 100644 --- a/cpp/devices/primary_device.cpp +++ b/cpp/devices/primary_device.cpp @@ -62,14 +62,14 @@ void PrimaryDevice::Reset() int PrimaryDevice::GetId() const { - if (controller == nullptr) { + if (GetController() == nullptr) { LOGERROR("Device is missing its controller") } - return controller != nullptr ? controller->GetTargetId() : -1; + return GetController() != nullptr ? GetController()->GetTargetId() : -1; } -void PrimaryDevice::SetController(AbstractController *c) +void PrimaryDevice::SetController(shared_ptr c) { controller = c; } @@ -84,23 +84,23 @@ void PrimaryDevice::TestUnitReady() void PrimaryDevice::Inquiry() { // EVPD and page code check - if ((controller->GetCmd(1) & 0x01) || controller->GetCmd(2)) { + if ((GetController()->GetCmd(1) & 0x01) || GetController()->GetCmd(2)) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } vector buf = InquiryInternal(); - const size_t allocation_length = min(buf.size(), static_cast(GetInt16(controller->GetCmd(), 3))); + const size_t allocation_length = min(buf.size(), static_cast(GetInt16(GetController()->GetCmd(), 3))); - memcpy(controller->GetBuffer().data(), buf.data(), allocation_length); - controller->SetLength(static_cast(allocation_length)); + memcpy(GetController()->GetBuffer().data(), buf.data(), allocation_length); + GetController()->SetLength(static_cast(allocation_length)); // Report if the device does not support the requested LUN - if (int lun = controller->GetEffectiveLun(); !controller->HasDeviceForLun(lun)) { + if (int lun = GetController()->GetEffectiveLun(); !GetController()->HasDeviceForLun(lun)) { LOGTRACE("Reporting LUN %d for device ID %d as not supported", lun, GetId()) // Signal that the requested LUN does not exist - controller->GetBuffer().data()[0] = 0x7f; + GetController()->GetBuffer().data()[0] = 0x7f; } EnterDataInPhase(); @@ -109,18 +109,18 @@ void PrimaryDevice::Inquiry() void PrimaryDevice::ReportLuns() { // Only SELECT REPORT mode 0 is supported - if (controller->GetCmd(2)) { + if (GetController()->GetCmd(2)) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } - const uint32_t allocation_length = GetInt32(controller->GetCmd(), 6); + const uint32_t allocation_length = GetInt32(GetController()->GetCmd(), 6); - vector& buf = controller->GetBuffer(); + vector& buf = GetController()->GetBuffer(); fill_n(buf.begin(), min(buf.size(), static_cast(allocation_length)), 0); uint32_t size = 0; - for (int lun = 0; lun < controller->GetMaxLuns(); lun++) { - if (controller->HasDeviceForLun(lun)) { + for (int lun = 0; lun < GetController()->GetMaxLuns(); lun++) { + if (GetController()->HasDeviceForLun(lun)) { size += 8; buf[size + 7] = (uint8_t)lun; } @@ -130,35 +130,35 @@ void PrimaryDevice::ReportLuns() size += 8; - controller->SetLength(min(allocation_length, size)); + GetController()->SetLength(min(allocation_length, size)); EnterDataInPhase(); } void PrimaryDevice::RequestSense() { - int lun = controller->GetEffectiveLun(); + int lun = GetController()->GetEffectiveLun(); // Note: According to the SCSI specs the LUN handling for REQUEST SENSE non-existing LUNs do *not* result // in CHECK CONDITION. Only the Sense Key and ASC are set in order to signal the non-existing LUN. - if (!controller->HasDeviceForLun(lun)) { + if (!GetController()->HasDeviceForLun(lun)) { // LUN 0 can be assumed to be present (required to call RequestSense() below) - assert(controller->HasDeviceForLun(0)); + assert(GetController()->HasDeviceForLun(0)); lun = 0; // Do not raise an exception here because the rest of the code must be executed - controller->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_LUN); + GetController()->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_LUN); - controller->SetStatus(status::GOOD); + GetController()->SetStatus(status::GOOD); } - vector buf = controller->GetDeviceForLun(lun)->HandleRequestSense(); + vector buf = GetController()->GetDeviceForLun(lun)->HandleRequestSense(); - const size_t allocation_length = min(buf.size(), static_cast(controller->GetCmd(4))); + const size_t allocation_length = min(buf.size(), static_cast(GetController()->GetCmd(4))); - memcpy(controller->GetBuffer().data(), buf.data(), allocation_length); - controller->SetLength(static_cast(allocation_length)); + memcpy(GetController()->GetBuffer().data(), buf.data(), allocation_length); + GetController()->SetLength(static_cast(allocation_length)); EnterDataInPhase(); } @@ -166,12 +166,12 @@ void PrimaryDevice::RequestSense() void PrimaryDevice::SendDiagnostic() { // Do not support PF bit - if (controller->GetCmd(1) & 0x10) { + if (GetController()->GetCmd(1) & 0x10) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } // Do not support parameter list - if ((controller->GetCmd(3) != 0) || (controller->GetCmd(4) != 0)) { + if ((GetController()->GetCmd(3) != 0) || (GetController()->GetCmd(4) != 0)) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } @@ -246,7 +246,7 @@ vector PrimaryDevice::HandleRequestSense() const buf[12] = (byte)(GetStatusCode() >> 8); buf[13] = (byte)GetStatusCode(); - LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, static_cast(controller->GetStatus()), + LOGTRACE("%s Status $%02X, Sense Key $%02X, ASC $%02X",__PRETTY_FUNCTION__, static_cast(GetController()->GetStatus()), static_cast(buf[2]), static_cast(buf[12])) return buf; @@ -261,7 +261,7 @@ bool PrimaryDevice::WriteByteSequence(vector&, uint32_t) void PrimaryDevice::ReserveUnit() { - reserving_initiator = controller->GetInitiatorId(); + reserving_initiator = GetController()->GetInitiatorId(); if (reserving_initiator != -1) { LOGTRACE("Reserved device ID %d, LUN %d for initiator ID %d", GetId(), GetLun(), reserving_initiator) diff --git a/cpp/devices/primary_device.h b/cpp/devices/primary_device.h index 1933dd5e..d57791f9 100644 --- a/cpp/devices/primary_device.h +++ b/cpp/devices/primary_device.h @@ -37,7 +37,7 @@ public: int GetId() const override; - void SetController(AbstractController *); + void SetController(shared_ptr); virtual bool WriteByteSequence(vector&, uint32_t); @@ -66,12 +66,11 @@ protected: void ReserveUnit() override; void ReleaseUnit() override; - void EnterStatusPhase() { controller->Status(); } - void EnterDataInPhase() { controller->DataIn(); } - void EnterDataOutPhase() { controller->DataOut(); } + void EnterStatusPhase() const { controller.lock()->Status(); } + void EnterDataInPhase() const { controller.lock()->DataIn(); } + void EnterDataOutPhase() const { controller.lock()->DataOut(); } - // TODO Try to replace this raw pointer, maybe by a weak_ptr - AbstractController *controller = nullptr; + inline shared_ptr GetController() const { return controller.lock(); } private: @@ -84,6 +83,8 @@ private: vector HandleRequestSense() const; + weak_ptr controller; + unordered_map commands; int send_delay = BUS::SEND_NO_DELAY; diff --git a/cpp/devices/scsi_daynaport.cpp b/cpp/devices/scsi_daynaport.cpp index 55ef94d4..08821a2e 100644 --- a/cpp/devices/scsi_daynaport.cpp +++ b/cpp/devices/scsi_daynaport.cpp @@ -265,7 +265,7 @@ bool SCSIDaynaPort::WriteBytes(const vector& cdb, vector& buf, uin LOGWARN("%s Unknown data format %02X", __PRETTY_FUNCTION__, data_format) } - controller->SetBlocks(0); + GetController()->SetBlocks(0); return true; } @@ -302,65 +302,65 @@ void SCSIDaynaPort::TestUnitReady() void SCSIDaynaPort::Read6() { // Get record number and block number - const uint32_t record = GetInt24(controller->GetCmd(), 1) & 0x1fffff; - controller->SetBlocks(1); + const uint32_t record = GetInt24(GetController()->GetCmd(), 1) & 0x1fffff; + GetController()->SetBlocks(1); // If any commands have a bogus control value, they were probably not // generated by the DaynaPort driver so ignore them - if (controller->GetCmd(5) != 0xc0 && controller->GetCmd(5) != 0x80) { + if (GetController()->GetCmd(5) != 0xc0 && GetController()->GetCmd(5) != 0x80) { LOGTRACE("%s Control value %d, (%04X), returning invalid CDB", __PRETTY_FUNCTION__, - controller->GetCmd(5), controller->GetCmd(5)) + GetController()->GetCmd(5), GetController()->GetCmd(5)) throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } - LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, record, controller->GetBlocks()) + LOGTRACE("%s READ(6) command record=%d blocks=%d", __PRETTY_FUNCTION__, record, GetController()->GetBlocks()) - controller->SetLength(Read(controller->GetCmd(), controller->GetBuffer(), record)); - LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, controller->GetLength()) + GetController()->SetLength(Read(GetController()->GetCmd(), GetController()->GetBuffer(), record)); + LOGTRACE("%s ctrl.length is %d", __PRETTY_FUNCTION__, GetController()->GetLength()) // Set next block - controller->SetNext(record + 1); + GetController()->SetNext(record + 1); EnterDataInPhase(); } -void SCSIDaynaPort::Write6() +void SCSIDaynaPort::Write6() const { // Ensure a sufficient buffer size (because it is not transfer for each block) - controller->AllocateBuffer(DAYNAPORT_BUFFER_SIZE); + GetController()->AllocateBuffer(DAYNAPORT_BUFFER_SIZE); - const int data_format = controller->GetCmd(5); + const int data_format = GetController()->GetCmd(5); if (data_format == 0x00) { - controller->SetLength(GetInt16(controller->GetCmd(), 3)); + GetController()->SetLength(GetInt16(GetController()->GetCmd(), 3)); } else if (data_format == 0x80) { - controller->SetLength(GetInt16(controller->GetCmd(), 3) + 8); + GetController()->SetLength(GetInt16(GetController()->GetCmd(), 3) + 8); } else { LOGWARN("%s Unknown data format $%02X", __PRETTY_FUNCTION__, data_format) } - LOGTRACE("%s length: $%04X (%d) format: $%02X", __PRETTY_FUNCTION__, controller->GetLength(), - controller->GetLength(), data_format) + LOGTRACE("%s length: $%04X (%d) format: $%02X", __PRETTY_FUNCTION__, GetController()->GetLength(), + GetController()->GetLength(), data_format) - if (controller->GetLength() <= 0) { + if (GetController()->GetLength() <= 0) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } // Set next block - controller->SetBlocks(1); - controller->SetNext(1); + GetController()->SetBlocks(1); + GetController()->SetNext(1); EnterDataOutPhase(); } -void SCSIDaynaPort::RetrieveStatistics() +void SCSIDaynaPort::RetrieveStatistics() const { - controller->SetLength(RetrieveStats(controller->GetCmd(), controller->GetBuffer())); + GetController()->SetLength(RetrieveStats(GetController()->GetCmd(), GetController()->GetBuffer())); // Set next block - controller->SetBlocks(1); - controller->SetNext(1); + GetController()->SetBlocks(1); + GetController()->SetNext(1); EnterDataInPhase(); } @@ -391,41 +391,41 @@ void SCSIDaynaPort::RetrieveStatistics() // value. // //--------------------------------------------------------------------------- -void SCSIDaynaPort::SetInterfaceMode() +void SCSIDaynaPort::SetInterfaceMode() const { // Check whether this command is telling us to "Set Interface Mode" or "Set MAC Address" - controller->SetLength(RetrieveStats(controller->GetCmd(), controller->GetBuffer())); - switch(controller->GetCmd(5)){ + GetController()->SetLength(RetrieveStats(GetController()->GetCmd(), GetController()->GetBuffer())); + switch(GetController()->GetCmd(5)){ case CMD_SCSILINK_SETMODE: // TODO Not implemented, do nothing EnterStatusPhase(); break; case CMD_SCSILINK_SETMAC: - controller->SetLength(6); + GetController()->SetLength(6); EnterDataOutPhase(); break; case CMD_SCSILINK_STATS: case CMD_SCSILINK_ENABLE: case CMD_SCSILINK_SET: - LOGWARN("%s Unsupported SetInterface command received: %02X", __PRETTY_FUNCTION__, controller->GetCmd(5)) + LOGWARN("%s Unsupported SetInterface command received: %02X", __PRETTY_FUNCTION__, GetController()->GetCmd(5)) throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE); break; default: - LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, controller->GetCmd(5)) + LOGWARN("%s Unknown SetInterface command received: %02X", __PRETTY_FUNCTION__, GetController()->GetCmd(5)) throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_COMMAND_OPERATION_CODE); break; } } -void SCSIDaynaPort::SetMcastAddr() +void SCSIDaynaPort::SetMcastAddr() const { - controller->SetLength(controller->GetCmd(4)); - if (controller->GetLength() == 0) { - LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, controller->GetCmd(2)) + GetController()->SetLength(GetController()->GetCmd(4)); + if (GetController()->GetLength() == 0) { + LOGWARN("%s Not supported SetMcastAddr Command %02X", __PRETTY_FUNCTION__, GetController()->GetCmd(2)) throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } @@ -447,7 +447,7 @@ void SCSIDaynaPort::SetMcastAddr() //--------------------------------------------------------------------------- void SCSIDaynaPort::EnableInterface() { - if (controller->GetCmd(5) & 0x80) { + if (GetController()->GetCmd(5) & 0x80) { if (!m_tap.Enable()) { LOGWARN("Unable to enable the DaynaPort Interface") diff --git a/cpp/devices/scsi_daynaport.h b/cpp/devices/scsi_daynaport.h index 0a2dfa9f..f5c66b8a 100644 --- a/cpp/devices/scsi_daynaport.h +++ b/cpp/devices/scsi_daynaport.h @@ -59,10 +59,10 @@ public: void TestUnitReady() override; void Read6(); - void Write6(); - void RetrieveStatistics(); - void SetInterfaceMode(); - void SetMcastAddr(); + void Write6() const; + void RetrieveStatistics() const; + void SetInterfaceMode() const; + void SetMcastAddr() const; void EnableInterface(); static const int DAYNAPORT_BUFFER_SIZE = 0x1000000; diff --git a/cpp/devices/scsi_host_bridge.cpp b/cpp/devices/scsi_host_bridge.cpp index 4429fd01..7be8c333 100644 --- a/cpp/devices/scsi_host_bridge.cpp +++ b/cpp/devices/scsi_host_bridge.cpp @@ -246,16 +246,16 @@ bool SCSIBR::WriteBytes(const vector& cdb, vector& buf, uint32_t) void SCSIBR::GetMessage10() { // Ensure a sufficient buffer size (because it is not a transfer for each block) - controller->AllocateBuffer(0x1000000); + GetController()->AllocateBuffer(0x1000000); - controller->SetLength(GetMessage10(controller->GetCmd(), controller->GetBuffer())); - if (controller->GetLength() <= 0) { + GetController()->SetLength(GetMessage10(GetController()->GetCmd(), GetController()->GetBuffer())); + if (GetController()->GetLength() <= 0) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } // Set next block - controller->SetBlocks(1); - controller->SetNext(1); + GetController()->SetBlocks(1); + GetController()->SetNext(1); EnterDataInPhase(); } @@ -267,19 +267,19 @@ void SCSIBR::GetMessage10() // This Send Message command is used by the X68000 host driver // //--------------------------------------------------------------------------- -void SCSIBR::SendMessage10() +void SCSIBR::SendMessage10() const { - controller->SetLength(GetInt24(controller->GetCmd(), 6)); - if (controller->GetLength() <= 0) { + GetController()->SetLength(GetInt24(GetController()->GetCmd(), 6)); + if (GetController()->GetLength() <= 0) { throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } // Ensure a sufficient buffer size (because it is not a transfer for each block) - controller->AllocateBuffer(0x1000000); + GetController()->AllocateBuffer(0x1000000); // Set next block - controller->SetBlocks(1); - controller->SetNext(1); + GetController()->SetBlocks(1); + GetController()->SetNext(1); EnterDataOutPhase(); } diff --git a/cpp/devices/scsi_host_bridge.h b/cpp/devices/scsi_host_bridge.h index d2a69612..6472a35c 100644 --- a/cpp/devices/scsi_host_bridge.h +++ b/cpp/devices/scsi_host_bridge.h @@ -43,7 +43,7 @@ public: bool WriteBytes(const vector&, vector&, uint32_t) override; void TestUnitReady() override; void GetMessage10(); - void SendMessage10(); + void SendMessage10() const; private: diff --git a/cpp/devices/scsi_printer.cpp b/cpp/devices/scsi_printer.cpp index fa242063..986ca0ff 100644 --- a/cpp/devices/scsi_printer.cpp +++ b/cpp/devices/scsi_printer.cpp @@ -84,19 +84,19 @@ vector SCSIPrinter::InquiryInternal() const void SCSIPrinter::Print() { - const uint32_t length = GetInt24(controller->GetCmd(), 2); + const uint32_t length = GetInt24(GetController()->GetCmd(), 2); LOGTRACE("Receiving %d byte(s) to be printed", length) - if (length > controller->GetBuffer().size()) { - LOGERROR("%s", ("Transfer buffer overflow: Buffer size is " + to_string(controller->GetBuffer().size()) + + if (length > GetController()->GetBuffer().size()) { + LOGERROR("%s", ("Transfer buffer overflow: Buffer size is " + to_string(GetController()->GetBuffer().size()) + " bytes, " + to_string(length) + " bytes expected").c_str()) throw scsi_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB); } - controller->SetLength(length); - controller->SetByteTransfer(true); + GetController()->SetLength(length); + GetController()->SetByteTransfer(true); EnterDataOutPhase(); } diff --git a/cpp/devices/scsicd.cpp b/cpp/devices/scsicd.cpp index 735f5f2b..cabe321d 100644 --- a/cpp/devices/scsicd.cpp +++ b/cpp/devices/scsicd.cpp @@ -162,7 +162,7 @@ void SCSICD::CreateDataTrack() void SCSICD::ReadToc() { - controller->SetLength(ReadTocInternal(controller->GetCmd(), controller->GetBuffer())); + GetController()->SetLength(ReadTocInternal(GetController()->GetCmd(), GetController()->GetBuffer())); EnterDataInPhase(); } diff --git a/cpp/rascsi/rascsi_core.cpp b/cpp/rascsi/rascsi_core.cpp index 63aca543..f57a64d8 100644 --- a/cpp/rascsi/rascsi_core.cpp +++ b/cpp/rascsi/rascsi_core.cpp @@ -15,19 +15,15 @@ #include "controllers/controller_manager.h" #include "controllers/scsi_controller.h" #include "devices/device_factory.h" -#include "devices/disk.h" +#include "devices/storage_device.h" #include "hal/gpiobus.h" #include "hal/gpiobus_factory.h" #include "hal/sbc_version.h" #include "hal/systimer.h" #include "rascsi_version.h" -#include "rascsi_exceptions.h" #include "protobuf_serializer.h" #include "protobuf_util.h" #include "rascsi/rascsi_executor.h" -#include "rascsi/rascsi_response.h" -#include "rascsi/rascsi_image.h" -#include "rascsi/rascsi_service.h" #include "rascsi/rascsi_core.h" #include "rasutil.h" #include "spdlog/sinks/stdout_color_sinks.h" @@ -45,20 +41,6 @@ using namespace rascsi_interface; using namespace ras_util; using namespace protobuf_util; -//--------------------------------------------------------------------------- -// -// Variable declarations -// TODO Make these fields class fields -// -//--------------------------------------------------------------------------- -RascsiService service; -shared_ptr bus; -DeviceFactory device_factory; -shared_ptr controller_manager; -RascsiImage rascsi_image; -shared_ptr rascsi_response; -shared_ptr executor; - void Rascsi::Banner(const vector& args) const { cout << ras_util::Banner("Reloaded"); @@ -100,14 +82,15 @@ bool Rascsi::InitBus() const bus->Reset(); - controller_manager = make_shared(bus); - rascsi_response = make_shared(device_factory, *controller_manager, ScsiController::LUN_MAX); - executor = make_shared(*rascsi_response, rascsi_image, device_factory, *controller_manager); + auto b = bus; + controller_manager = make_shared(*b); + auto c = controller_manager; + executor = make_shared(rascsi_image, *c); return true; } -void Cleanup() +void Rascsi::Cleanup() { executor->DetachAll(); @@ -116,13 +99,6 @@ void Cleanup() bus->Cleanup(); } -void Rascsi::Reset() const -{ - controller_manager->ResetAllControllers(); - - bus->Reset(); -} - bool Rascsi::ReadAccessToken(const char *filename) const { struct stat st; @@ -166,11 +142,9 @@ void Rascsi::LogDevices(string_view devices) const } } -void TerminationHandler(int signum) +void Rascsi::TerminationHandler(int) { Cleanup(); - - exit(signum); } bool Rascsi::ProcessId(const string& id_spec, int& id, int& unit) const @@ -214,10 +188,11 @@ bool Rascsi::ParseArguments(const vector& args, int& port, optarg_queue_ case 'F': case 'z': { - string optarg_str = (optarg == nullptr) ? "" : string(optarg); - post_process.emplace_back(opt ,optarg_str); + const string optarg_str = optarg == nullptr ? "" : optarg; + post_process.emplace_back(opt, optarg_str); continue; } + case 'b': { if (!GetAsInt(optarg, block_size)) { cerr << "Invalid block size " << optarg << endl; @@ -348,6 +323,9 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const case 1: // Encountered filename break; + + default: + return false; } // Set up the device data @@ -390,7 +368,7 @@ bool Rascsi::CreateInitialDevices(const optarg_queue_type& optarg_queue) const // Display and log the device list PbServerInfo server_info; - rascsi_response->GetDevices(server_info, rascsi_image.GetDefaultFolder()); + rascsi_response.GetDevices(controller_manager->GetAllDevices(), server_info, rascsi_image.GetDefaultFolder()); const list& devices = { server_info.devices_info().devices().begin(), server_info.devices_info().devices().end() }; const string device_list = ListDevices(devices); LogDevices(device_list); @@ -441,19 +419,20 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm } case DEVICES_INFO: { - rascsi_response->GetDevicesInfo(result, command, rascsi_image.GetDefaultFolder()); + rascsi_response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, + rascsi_image.GetDefaultFolder()); serializer.SerializeMessage(context.GetFd(), result); break; } case DEVICE_TYPES_INFO: { - result.set_allocated_device_types_info(rascsi_response->GetDeviceTypesInfo(result).release()); + result.set_allocated_device_types_info(rascsi_response.GetDeviceTypesInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case SERVER_INFO: { - result.set_allocated_server_info(rascsi_response->GetServerInfo( + result.set_allocated_server_info(rascsi_response.GetServerInfo(controller_manager->GetAllDevices(), result, executor->GetReservedIds(), current_log_level, rascsi_image.GetDefaultFolder(), GetParam(command, "folder_pattern"), GetParam(command, "file_pattern"), rascsi_image.GetDepth()).release()); @@ -462,19 +441,19 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm } case VERSION_INFO: { - result.set_allocated_version_info(rascsi_response->GetVersionInfo(result).release()); + result.set_allocated_version_info(rascsi_response.GetVersionInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case LOG_LEVEL_INFO: { - result.set_allocated_log_level_info(rascsi_response->GetLogLevelInfo(result, current_log_level).release()); + result.set_allocated_log_level_info(rascsi_response.GetLogLevelInfo(result, current_log_level).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case DEFAULT_IMAGE_FILES_INFO: { - result.set_allocated_image_files_info(rascsi_response->GetAvailableImages(result, + result.set_allocated_image_files_info(rascsi_response.GetAvailableImages(result, rascsi_image.GetDefaultFolder(), GetParam(command, "folder_pattern"), GetParam(command, "file_pattern"), rascsi_image.GetDepth()).release()); serializer.SerializeMessage(context.GetFd(), result); @@ -487,7 +466,7 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm } else { auto image_file = make_unique(); - const bool status = rascsi_response->GetImageFile(*image_file.get(), rascsi_image.GetDefaultFolder(), filename); + const bool status = rascsi_response.GetImageFile(*image_file.get(), rascsi_image.GetDefaultFolder(), filename); if (status) { result.set_status(true); result.set_allocated_image_file_info(image_file.get()); @@ -501,26 +480,26 @@ bool Rascsi::ExecuteCommand(const CommandContext& context, const PbCommand& comm } case NETWORK_INTERFACES_INFO: { - result.set_allocated_network_interfaces_info(rascsi_response->GetNetworkInterfacesInfo(result).release()); + result.set_allocated_network_interfaces_info(rascsi_response.GetNetworkInterfacesInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case MAPPING_INFO: { - result.set_allocated_mapping_info(rascsi_response->GetMappingInfo(result).release()); + result.set_allocated_mapping_info(rascsi_response.GetMappingInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case OPERATION_INFO: { - result.set_allocated_operation_info(rascsi_response->GetOperationInfo(result, + result.set_allocated_operation_info(rascsi_response.GetOperationInfo(result, rascsi_image.GetDepth()).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case RESERVED_IDS_INFO: { - result.set_allocated_reserved_ids_info(rascsi_response->GetReservedIds(result, + result.set_allocated_reserved_ids_info(rascsi_response.GetReservedIds(result, executor->GetReservedIds()).release()); serializer.SerializeMessage(context.GetFd(), result); break; @@ -552,15 +531,12 @@ int Rascsi::run(const vector& args) const { GOOGLE_PROTOBUF_VERIFY_VERSION; - // added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits. - setvbuf(stdout, nullptr, _IONBF, 0); - Banner(args); int port = DEFAULT_PORT; optarg_queue_type optarg_queue; if (!ParseArguments(args, port, optarg_queue)) { - return -1; + return EXIT_FAILURE; } // Note that current_log_level may have been modified by ParseArguments() @@ -570,18 +546,18 @@ int Rascsi::run(const vector& args) const const auto logger = stdout_color_mt("rascsi stdout logger"); if (!InitBus()) { - return EPERM; - } - - if (!service.Init(&ExecuteCommand, port)) { - return EPERM; + return EXIT_FAILURE; } // We need to wait to create the devices until after the bus/controller/etc // objects have been created. if (!CreateInitialDevices(optarg_queue)) { Cleanup(); - return -1; + return EXIT_FAILURE; + } + + if (!service.Init(&ExecuteCommand, port)) { + return EXIT_FAILURE; } // Signal handler to detach all devices on a KILL or TERM signal @@ -592,9 +568,6 @@ int Rascsi::run(const vector& args) const sigaction(SIGINT, &termination_handler, nullptr); sigaction(SIGTERM, &termination_handler, nullptr); - // Reset - Reset(); - // Set the affinity to a specific processor core FixCpu(3); @@ -658,7 +631,7 @@ int Rascsi::run(const vector& args) const BUS::phase_t phase = BUS::phase_t::busfree; // Identify the responsible controller - shared_ptr controller = controller_manager->IdentifyController(id_data); + auto controller = controller_manager->IdentifyController(id_data); if (controller != nullptr) { initiator_id = controller->ExtractInitiatorId(id_data); @@ -702,5 +675,5 @@ int Rascsi::run(const vector& args) const active = false; } - return 0; + return EXIT_SUCCESS; } diff --git a/cpp/rascsi/rascsi_core.h b/cpp/rascsi/rascsi_core.h index 9eea1520..ef13b912 100644 --- a/cpp/rascsi/rascsi_core.h +++ b/cpp/rascsi/rascsi_core.h @@ -10,17 +10,23 @@ #pragma once #include "rascsi/command_context.h" +#include "rascsi/rascsi_service.h" +#include "rascsi/rascsi_image.h" +#include "rascsi/rascsi_response.h" #include "rascsi_interface.pb.h" -#include #include #include using namespace std; +// TODO Only BUS should be known +class GPIOBUS; +class ControllerManager; +class RascsiExecutor; + class Rascsi { - using optarg_value_type = pair; - using optarg_queue_type = deque; + using optarg_queue_type = vector>; static const int DEFAULT_PORT = 6868; static const char COMPONENT_SEPARATOR = ':'; @@ -36,16 +42,30 @@ private: void Banner(const vector&) const; bool InitBus() const; - void Reset() const; + static void Cleanup(); bool ReadAccessToken(const char *) const; void LogDevices(string_view) const; + static void TerminationHandler(int); bool ProcessId(const string&, int&, int&) const; bool ParseArguments(const vector&, int&, optarg_queue_type&) const; bool CreateInitialDevices(const optarg_queue_type&) const; + // TODO Should not be static and should be moved to RascsiService static bool ExecuteCommand(const CommandContext&, const PbCommand&); - // TODO Get rid of static fields + // TODO These fields should not be static + + static inline RascsiService service; + + static inline RascsiImage rascsi_image; + + const static inline RascsiResponse rascsi_response; + + static inline shared_ptr bus; + + static inline shared_ptr controller_manager; + + static inline shared_ptr executor; // Processing flag static inline volatile bool active; diff --git a/cpp/rascsi/rascsi_executor.cpp b/cpp/rascsi/rascsi_executor.cpp index 4c7095db..dd8f8ba2 100644 --- a/cpp/rascsi/rascsi_executor.cpp +++ b/cpp/rascsi/rascsi_executor.cpp @@ -14,7 +14,6 @@ #include "devices/primary_device.h" #include "devices/disk.h" #include "rascsi_service.h" -#include "rascsi_response.h" #include "rascsi_image.h" #include "rascsi_exceptions.h" #include "localizer.h" @@ -157,7 +156,8 @@ bool RascsiExecutor::ProcessCmd(const CommandContext& context, const PbCommand& // A new command with an empty device list is required here in order to return data for all devices PbCommand cmd; PbResult result; - rascsi_response.GetDevicesInfo(result, cmd, rascsi_image.GetDefaultFolder()); + rascsi_response.GetDevicesInfo(controller_manager.GetAllDevices(), result, cmd, + rascsi_image.GetDefaultFolder()); serializer.SerializeMessage(context.GetFd(), result); return true; } @@ -668,7 +668,7 @@ bool RascsiExecutor::VerifyExistingIdAndLun(const CommandContext& context, int i shared_ptr RascsiExecutor::CreateDevice(const CommandContext& context, const PbDeviceType type, int lun, const string& filename) const { - auto device = device_factory.CreateDevice(controller_manager, type, lun, filename); + auto device = device_factory.CreateDevice(type, lun, filename); if (device == nullptr) { if (type == UNDEFINED) { context.ReturnLocalizedError(LocalizationKey::ERROR_MISSING_DEVICE_TYPE, filename); diff --git a/cpp/rascsi/rascsi_executor.h b/cpp/rascsi/rascsi_executor.h index 1e6d45a7..942f7f7b 100644 --- a/cpp/rascsi/rascsi_executor.h +++ b/cpp/rascsi/rascsi_executor.h @@ -9,9 +9,9 @@ #pragma once +#include "rascsi/rascsi_response.h" #include "protobuf_serializer.h" -class RascsiResponse; class RascsiImage; class DeviceFactory; class ControllerManager; @@ -20,24 +20,10 @@ class CommandContext; class RascsiExecutor { - RascsiResponse& rascsi_response; - - RascsiImage& rascsi_image; - - DeviceFactory& device_factory; - - ControllerManager& controller_manager; - - ProtobufSerializer serializer; - - unordered_set reserved_ids; - public: - RascsiExecutor(RascsiResponse& rascsi_response, RascsiImage& rascsi_image, DeviceFactory& device_factory, - ControllerManager& controller_manager) - : rascsi_response(rascsi_response), rascsi_image(rascsi_image), device_factory(device_factory), - controller_manager(controller_manager) {} + RascsiExecutor(RascsiImage& rascsi_image, ControllerManager& controller_manager) + : rascsi_image(rascsi_image), controller_manager(controller_manager) {} ~RascsiExecutor() = default; unordered_set GetReservedIds() const { return reserved_ids; } @@ -67,4 +53,17 @@ public: static bool ValidateIdAndLun(const CommandContext&, int, int); static bool SetProductData(const CommandContext&, const PbDeviceDefinition&, PrimaryDevice&); +private: + + const RascsiResponse rascsi_response; + + RascsiImage& rascsi_image; + + ControllerManager& controller_manager; + + const DeviceFactory device_factory; + + const ProtobufSerializer serializer; + + unordered_set reserved_ids; }; diff --git a/cpp/rascsi/rascsi_response.cpp b/cpp/rascsi/rascsi_response.cpp index 8c1ce5bb..6444994f 100644 --- a/cpp/rascsi/rascsi_response.cpp +++ b/cpp/rascsi/rascsi_response.cpp @@ -8,7 +8,6 @@ //--------------------------------------------------------------------------- #include "log.h" -#include "controllers/controller_manager.h" #include "devices/disk.h" #include "devices/device_factory.h" #include "protobuf_util.h" @@ -26,7 +25,8 @@ unique_ptr RascsiResponse::GetDeviceProperties(const Device& { auto properties = make_unique(); - properties->set_luns(max_luns); + // Currently there is only a SCSI controller, i.e. there can always be 32 LUNs + properties->set_luns(32); properties->set_read_only(device.IsReadOnly()); properties->set_protectable(device.IsProtectable()); properties->set_stoppable(device.IsStoppable()); @@ -53,7 +53,7 @@ void RascsiResponse::GetDeviceTypeProperties(PbDeviceTypesInfo& device_types_inf { auto type_properties = device_types_info.add_properties(); type_properties->set_type(type); - const auto device = device_factory.CreateDevice(controller_manager, type, 0, ""); + const auto device = device_factory.CreateDevice(type, 0, ""); type_properties->set_allocated_properties(GetDeviceProperties(*device).release()); } //NOSONAR The allocated memory is managed by protobuf @@ -215,20 +215,20 @@ unique_ptr RascsiResponse::GetReservedIds(PbResult& result, c return reserved_ids_info; } -void RascsiResponse::GetDevices(PbServerInfo& server_info, const string& default_folder) const +void RascsiResponse::GetDevices(const unordered_set>& devices, PbServerInfo& server_info, + const string& default_folder) const { - for (const auto& device : controller_manager.GetAllDevices()) { + for (const auto& device : devices) { PbDevice *pb_device = server_info.mutable_devices_info()->add_devices(); GetDevice(*device, *pb_device, default_folder); } } -void RascsiResponse::GetDevicesInfo(PbResult& result, const PbCommand& command, const string& default_folder) const +void RascsiResponse::GetDevicesInfo(const unordered_set>& devices, PbResult& result, + const PbCommand& command, const string& default_folder) const { set id_sets; - const auto& devices = controller_manager.GetAllDevices(); - // If no device list was provided in the command get information on all devices if (!command.devices_size()) { for (const auto& device : devices) { @@ -237,7 +237,7 @@ void RascsiResponse::GetDevicesInfo(PbResult& result, const PbCommand& command, } // Otherwise get information on the devices provided in the command else { - id_sets = MatchDevices(result, command); + id_sets = MatchDevices(devices, result, command); if (id_sets.empty()) { return; } @@ -269,9 +269,9 @@ unique_ptr RascsiResponse::GetDeviceTypesInfo(PbResult& resul return device_types_info; } -unique_ptr RascsiResponse::GetServerInfo(PbResult& result, const unordered_set& reserved_ids, - const string& current_log_level, const string& default_folder, const string& folder_pattern, - const string& file_pattern, int scan_depth) const +unique_ptr RascsiResponse::GetServerInfo(const unordered_set>& devices, + PbResult& result, const unordered_set& reserved_ids, const string& current_log_level, + const string& default_folder, const string& folder_pattern, const string& file_pattern, int scan_depth) const { auto server_info = make_unique(); @@ -281,7 +281,7 @@ unique_ptr RascsiResponse::GetServerInfo(PbResult& result, const u GetAvailableImages(result, *server_info, default_folder, folder_pattern, file_pattern, scan_depth); server_info->set_allocated_network_interfaces_info(GetNetworkInterfacesInfo(result).release()); server_info->set_allocated_mapping_info(GetMappingInfo(result).release()); //NOSONAR The allocated memory is managed by protobuf - GetDevices(*server_info, default_folder); //NOSONAR The allocated memory is managed by protobuf + GetDevices(devices, *server_info, default_folder); //NOSONAR The allocated memory is managed by protobuf server_info->set_allocated_reserved_ids_info(GetReservedIds(result, reserved_ids).release()); server_info->set_allocated_operation_info(GetOperationInfo(result, scan_depth).release()); //NOSONAR The allocated memory is managed by protobuf @@ -494,13 +494,14 @@ unique_ptr RascsiResponse::AddOperationParameter(PbOperati return parameter; } -set RascsiResponse::MatchDevices(PbResult& result, const PbCommand& command) const +set RascsiResponse::MatchDevices(const unordered_set>& devices, PbResult& result, + const PbCommand& command) const { set id_sets; for (const auto& device : command.devices()) { bool has_device = false; - for (const auto& d : controller_manager.GetAllDevices()) { + for (const auto& d : devices) { if (d->GetId() == device.id() && d->GetLun() == device.unit()) { id_sets.insert(make_pair(device.id(), device.unit())); has_device = true; diff --git a/cpp/rascsi/rascsi_response.h b/cpp/rascsi/rascsi_response.h index f6635030..d9a188ff 100644 --- a/cpp/rascsi/rascsi_response.h +++ b/cpp/rascsi/rascsi_response.h @@ -9,6 +9,8 @@ #pragma once +#include "devices/device_factory.h" +#include "devices/primary_device.h" #include "rascsi_interface.pb.h" #include #include @@ -17,27 +19,24 @@ using namespace std; using namespace rascsi_interface; -class DeviceFactory; -class ControllerManager; -class Device; - class RascsiResponse { + using id_set = pair; + public: - RascsiResponse(DeviceFactory& device_factory, const ControllerManager& controller_manager, int max_luns) - : device_factory(device_factory), controller_manager(controller_manager), max_luns(max_luns) {} + RascsiResponse() = default; ~RascsiResponse() = default; bool GetImageFile(PbImageFile&, const string&, const string&) const; unique_ptr GetAvailableImages(PbResult&, const string&, const string&, const string&, int) const; unique_ptr GetReservedIds(PbResult&, const unordered_set&) const; - void GetDevices(PbServerInfo&, const string&) const; - void GetDevicesInfo(PbResult&, const PbCommand&, const string&) const; + void GetDevices(const unordered_set>&, PbServerInfo&, const string&) const; + void GetDevicesInfo(const unordered_set>&, PbResult&, const PbCommand&, const string&) const; unique_ptr GetDeviceTypesInfo(PbResult&) const; unique_ptr GetVersionInfo(PbResult&) const; - unique_ptr GetServerInfo(PbResult&, const unordered_set&, const string&, const string&, const string&, - const string&, int) const; + unique_ptr GetServerInfo(const unordered_set>&, PbResult&, const unordered_set&, + const string&, const string&, const string&, const string&, int) const; unique_ptr GetNetworkInterfacesInfo(PbResult&) const; unique_ptr GetMappingInfo(PbResult&) const; unique_ptr GetLogLevelInfo(PbResult&, const string&) const; @@ -45,13 +44,9 @@ public: private: - DeviceFactory& device_factory; + DeviceFactory device_factory; - const ControllerManager& controller_manager; - - int max_luns; - - const array log_levels = { "trace", "debug", "info", "warn", "err", "off" }; + const inline static array log_levels = { "trace", "debug", "info", "warn", "err", "off" }; unique_ptr GetDeviceProperties(const Device&) const; void GetDevice(const Device&, PbDevice&, const string&) const; @@ -62,7 +57,7 @@ private: unique_ptr CreateOperation(PbOperationInfo&, const PbOperation&, const string&) const; unique_ptr AddOperationParameter(PbOperationMetaData&, const string&, const string&, const string& = "", bool = false) const; - set MatchDevices(PbResult&, const PbCommand&) const; + set MatchDevices(const unordered_set>&, PbResult&, const PbCommand&) const; static string GetNextImageFile(const dirent *, const string&); }; diff --git a/cpp/rascsi/rascsi_service.cpp b/cpp/rascsi/rascsi_service.cpp index 511b71c3..68a94323 100644 --- a/cpp/rascsi/rascsi_service.cpp +++ b/cpp/rascsi/rascsi_service.cpp @@ -18,9 +18,12 @@ #include using namespace rascsi_interface; +using namespace ras_util; void RascsiService::Cleanup() const { + running = false; + if (service_socket != -1) { close(service_socket); } @@ -76,7 +79,7 @@ void RascsiService::Execute() const #endif // Set the affinity to a specific processor core - ras_util::FixCpu(2); + FixCpu(2); // Wait for the execution to start const timespec ts = { .tv_sec = 0, .tv_nsec = 1000}; diff --git a/cpp/test/abstract_controller_test.cpp b/cpp/test/abstract_controller_test.cpp index b38db366..963df7b9 100644 --- a/cpp/test/abstract_controller_test.cpp +++ b/cpp/test/abstract_controller_test.cpp @@ -15,7 +15,9 @@ using namespace scsi_defs; TEST(AbstractControllerTest, AllocateCmd) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); EXPECT_EQ(16, controller.GetCmd().size()); controller.AllocateCmd(1234); @@ -24,7 +26,9 @@ TEST(AbstractControllerTest, AllocateCmd) TEST(AbstractControllerTest, AllocateBuffer) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.AllocateBuffer(1); EXPECT_LE(1, controller.GetBuffer().size()); @@ -34,22 +38,26 @@ TEST(AbstractControllerTest, AllocateBuffer) TEST(AbstractControllerTest, Reset) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(0); - controller.AddDevice(device); + controller->AddDevice(device); - controller.SetPhase(BUS::phase_t::status); - EXPECT_EQ(BUS::phase_t::status, controller.GetPhase()); - controller.Reset(); - EXPECT_TRUE(controller.IsBusFree()); - EXPECT_EQ(status::GOOD, controller.GetStatus()); - EXPECT_EQ(0, controller.GetLength()); + controller->SetPhase(BUS::phase_t::status); + EXPECT_EQ(BUS::phase_t::status, controller->GetPhase()); + controller->Reset(); + EXPECT_TRUE(controller->IsBusFree()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); + EXPECT_EQ(0, controller->GetLength()); } TEST(AbstractControllerTest, Next) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.SetNext(0x1234); EXPECT_EQ(0x1234, controller.GetNext()); @@ -59,7 +67,9 @@ TEST(AbstractControllerTest, Next) TEST(AbstractControllerTest, Message) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.SetMessage(0x12); EXPECT_EQ(0x12, controller.GetMessage()); @@ -67,7 +77,9 @@ TEST(AbstractControllerTest, Message) TEST(AbstractControllerTest, ByteTransfer) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.SetByteTransfer(false); EXPECT_FALSE(controller.IsByteTransfer()); @@ -77,7 +89,9 @@ TEST(AbstractControllerTest, ByteTransfer) TEST(AbstractControllerTest, BytesToTransfer) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.SetBytesToTransfer(0x1234); EXPECT_EQ(0x1234, controller.GetBytesToTransfer()); @@ -87,14 +101,18 @@ TEST(AbstractControllerTest, BytesToTransfer) TEST(AbstractControllerTest, GetMaxLuns) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); EXPECT_EQ(32, controller.GetMaxLuns()); } TEST(AbstractControllerTest, Status) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.SetStatus(status::RESERVATION_CONFLICT); EXPECT_EQ(status::RESERVATION_CONFLICT, controller.GetStatus()); @@ -102,7 +120,9 @@ TEST(AbstractControllerTest, Status) TEST(AbstractControllerTest, ProcessPhase) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::selection); EXPECT_CALL(controller, Selection); @@ -152,25 +172,27 @@ TEST(AbstractControllerTest, DeviceLunLifeCycle) const int ID = 1; const int LUN = 4; - MockAbstractController controller(make_shared(), ID); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, ID); auto device1 = make_shared(LUN); auto device2 = make_shared(32); auto device3 = make_shared(-1); - EXPECT_EQ(0, controller.GetLunCount()); - EXPECT_EQ(ID, controller.GetTargetId()); - EXPECT_TRUE(controller.AddDevice(device1)); - EXPECT_FALSE(controller.AddDevice(device2)); - EXPECT_FALSE(controller.AddDevice(device3)); - EXPECT_TRUE(controller.GetLunCount() > 0); - EXPECT_TRUE(controller.HasDeviceForLun(LUN)); - EXPECT_FALSE(controller.HasDeviceForLun(0)); - EXPECT_NE(nullptr, controller.GetDeviceForLun(LUN)); - EXPECT_EQ(nullptr, controller.GetDeviceForLun(0)); - EXPECT_TRUE(controller.RemoveDevice(device1)); - EXPECT_EQ(0, controller.GetLunCount()); - EXPECT_FALSE(controller.RemoveDevice(device1)); + EXPECT_EQ(0, controller->GetLunCount()); + EXPECT_EQ(ID, controller->GetTargetId()); + EXPECT_TRUE(controller->AddDevice(device1)); + EXPECT_FALSE(controller->AddDevice(device2)); + EXPECT_FALSE(controller->AddDevice(device3)); + EXPECT_TRUE(controller->GetLunCount() > 0); + EXPECT_TRUE(controller->HasDeviceForLun(LUN)); + EXPECT_FALSE(controller->HasDeviceForLun(0)); + EXPECT_NE(nullptr, controller->GetDeviceForLun(LUN)); + EXPECT_EQ(nullptr, controller->GetDeviceForLun(0)); + EXPECT_TRUE(controller->RemoveDevice(device1)); + EXPECT_EQ(0, controller->GetLunCount()); + EXPECT_FALSE(controller->RemoveDevice(device1)); } TEST(AbstractControllerTest, ExtractInitiatorId) @@ -179,7 +201,9 @@ TEST(AbstractControllerTest, ExtractInitiatorId) const int INITIATOR_ID = 7; const int UNKNOWN_INITIATOR_ID = -1; - MockAbstractController controller(make_shared(), ID); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, ID); EXPECT_EQ(INITIATOR_ID, controller.ExtractInitiatorId((1 << INITIATOR_ID) | ( 1 << ID))); EXPECT_EQ(UNKNOWN_INITIATOR_ID, controller.ExtractInitiatorId(1 << ID)); @@ -187,7 +211,9 @@ TEST(AbstractControllerTest, ExtractInitiatorId) TEST(AbstractControllerTest, GetOpcode) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); auto& cmd = controller.GetCmd(); @@ -199,7 +225,9 @@ TEST(AbstractControllerTest, GetLun) { const int LUN = 3; - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); auto& cmd = controller.GetCmd(); @@ -209,7 +237,9 @@ TEST(AbstractControllerTest, GetLun) TEST(AbstractControllerTest, Blocks) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.SetBlocks(1); EXPECT_EQ(1, controller.GetBlocks()); @@ -219,7 +249,9 @@ TEST(AbstractControllerTest, Blocks) TEST(AbstractControllerTest, Length) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); EXPECT_FALSE(controller.HasValidLength()); @@ -230,7 +262,9 @@ TEST(AbstractControllerTest, Length) TEST(AbstractControllerTest, UpdateOffsetAndLength) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); EXPECT_FALSE(controller.HasValidLength()); @@ -240,7 +274,9 @@ TEST(AbstractControllerTest, UpdateOffsetAndLength) TEST(AbstractControllerTest, Offset) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); controller.ResetOffset(); EXPECT_EQ(0, controller.GetOffset()); diff --git a/cpp/test/controller_manager_test.cpp b/cpp/test/controller_manager_test.cpp index caecde4b..996b2f0a 100644 --- a/cpp/test/controller_manager_test.cpp +++ b/cpp/test/controller_manager_test.cpp @@ -18,32 +18,32 @@ TEST(ControllerManagerTest, LifeCycle) const int LUN2 = 3; auto bus = make_shared(); - ControllerManager controller_manager(bus); + auto controller_manager = make_shared(*bus); DeviceFactory device_factory; - auto device = device_factory.CreateDevice(controller_manager, SCHS, -1, ""); - EXPECT_FALSE(controller_manager.AttachToScsiController(ID, device)); + auto device = device_factory.CreateDevice(SCHS, -1, ""); + EXPECT_FALSE(controller_manager->AttachToScsiController(ID, device)); - device = device_factory.CreateDevice(controller_manager, SCHS, LUN1, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device)); - auto controller = controller_manager.FindController(ID); + device = device_factory.CreateDevice(SCHS, LUN1, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device)); + auto controller = controller_manager->FindController(ID); EXPECT_NE(nullptr, controller); EXPECT_EQ(1, controller->GetLunCount()); - EXPECT_NE(nullptr, controller_manager.IdentifyController(1 << ID)); - EXPECT_EQ(nullptr, controller_manager.IdentifyController(0)); - EXPECT_EQ(nullptr, controller_manager.FindController(0)); - EXPECT_NE(nullptr, controller_manager.GetDeviceByIdAndLun(ID, LUN1)); - EXPECT_EQ(nullptr, controller_manager.GetDeviceByIdAndLun(0, 0)); + EXPECT_NE(nullptr, controller_manager->IdentifyController(1 << ID)); + EXPECT_EQ(nullptr, controller_manager->IdentifyController(0)); + EXPECT_EQ(nullptr, controller_manager->FindController(0)); + EXPECT_NE(nullptr, controller_manager->GetDeviceByIdAndLun(ID, LUN1)); + EXPECT_EQ(nullptr, controller_manager->GetDeviceByIdAndLun(0, 0)); - device = device_factory.CreateDevice(controller_manager, SCHS, LUN2, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device)); - controller = controller_manager.FindController(ID); - EXPECT_TRUE(controller_manager.DeleteController(controller)); - EXPECT_EQ(nullptr, controller_manager.FindController(ID)); + device = device_factory.CreateDevice(SCHS, LUN2, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device)); + controller = controller_manager->FindController(ID); + EXPECT_TRUE(controller_manager->DeleteController(controller)); + EXPECT_EQ(nullptr, controller_manager->FindController(ID)); - controller_manager.DeleteAllControllers(); - EXPECT_EQ(nullptr, controller_manager.FindController(ID)); - EXPECT_EQ(nullptr, controller_manager.GetDeviceByIdAndLun(ID, LUN1)); + controller_manager->DeleteAllControllers(); + EXPECT_EQ(nullptr, controller_manager->FindController(ID)); + EXPECT_EQ(nullptr, controller_manager->GetDeviceByIdAndLun(ID, LUN1)); } TEST(ControllerManagerTest, AttachToScsiController) @@ -53,32 +53,14 @@ TEST(ControllerManagerTest, AttachToScsiController) const int LUN2 = 0; auto bus = make_shared(); - ControllerManager controller_manager(bus); + auto controller_manager = make_shared(*bus); DeviceFactory device_factory; - auto device1 = device_factory.CreateDevice(controller_manager, SCHS, LUN1, ""); - EXPECT_FALSE(controller_manager.AttachToScsiController(ID, device1)) << "LUN 0 is missing"; + auto device1 = device_factory.CreateDevice(SCHS, LUN1, ""); + EXPECT_FALSE(controller_manager->AttachToScsiController(ID, device1)) << "LUN 0 is missing"; - auto device2 = device_factory.CreateDevice(controller_manager, SCLP, LUN2, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2)); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1)); - EXPECT_FALSE(controller_manager.AttachToScsiController(ID, device1)); -} - -TEST(ControllerManagerTest, ResetAllControllers) -{ - const int ID = 2; - - auto bus = make_shared(); - ControllerManager controller_manager(bus); - DeviceFactory device_factory; - - auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device)); - auto controller = controller_manager.FindController(ID); - EXPECT_NE(nullptr, controller); - - controller->SetStatus(status::RESERVATION_CONFLICT); - controller_manager.ResetAllControllers(); - EXPECT_EQ(status::GOOD, controller->GetStatus()); + auto device2 = device_factory.CreateDevice(SCLP, LUN2, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2)); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1)); + EXPECT_FALSE(controller_manager->AttachToScsiController(ID, device1)); } diff --git a/cpp/test/device_factory_test.cpp b/cpp/test/device_factory_test.cpp index 63786caf..c63bfba4 100644 --- a/cpp/test/device_factory_test.cpp +++ b/cpp/test/device_factory_test.cpp @@ -122,27 +122,24 @@ TEST(DeviceFactoryTest, GetDefaultParams) TEST(DeviceFactoryTest, UnknownDeviceType) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - auto device1 = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test"); + auto device1 = device_factory.CreateDevice(UNDEFINED, 0, "test"); EXPECT_EQ(nullptr, device1); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - auto device2 = device_factory.CreateDevice(controller_manager, SAHD, 0, "test"); + auto device2 = device_factory.CreateDevice(SAHD, 0, "test"); #pragma GCC diagnostic pop EXPECT_EQ(nullptr, device2); } TEST(DeviceFactoryTest, SCHD_Device_Defaults) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.hda"); + auto device = device_factory.CreateDevice(UNDEFINED, 0, "test.hda"); + const unordered_map params; device->Init(params); @@ -165,26 +162,23 @@ TEST(DeviceFactoryTest, SCHD_Device_Defaults) EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2), device->GetRevision()); - device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.hds"); + device = device_factory.CreateDevice(UNDEFINED, 0, "test.hds"); EXPECT_NE(nullptr, device); EXPECT_EQ(SCHD, device->GetType()); - device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.hdi"); + device = device_factory.CreateDevice(UNDEFINED, 0, "test.hdi"); EXPECT_NE(nullptr, device); EXPECT_EQ(SCHD, device->GetType()); - device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.nhd"); + device = device_factory.CreateDevice(UNDEFINED, 0, "test.nhd"); EXPECT_NE(nullptr, device); EXPECT_EQ(SCHD, device->GetType()); } void TestRemovableDrive(PbDeviceType type, const string& filename, const string& product) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - - auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, filename); + auto device = device_factory.CreateDevice(UNDEFINED, 0, filename); const unordered_map params; device->Init(params); @@ -221,11 +215,10 @@ TEST(DeviceFactoryTest, SCMO_Device_Defaults) TEST(DeviceFactoryTest, SCCD_Device_Defaults) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.iso"); + auto device = device_factory.CreateDevice(UNDEFINED, 0, "test.iso"); + const unordered_map params; device->Init(params); @@ -251,11 +244,10 @@ TEST(DeviceFactoryTest, SCCD_Device_Defaults) TEST(DeviceFactoryTest, SCBR_Device_Defaults) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "bridge"); + auto device = device_factory.CreateDevice(UNDEFINED, 0, "bridge"); + const unordered_map params; device->Init(params); @@ -281,11 +273,10 @@ TEST(DeviceFactoryTest, SCBR_Device_Defaults) TEST(DeviceFactoryTest, SCDP_Device_Defaults) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "daynaport"); + auto device = device_factory.CreateDevice(UNDEFINED, 0, "daynaport"); + const unordered_map params; device->Init(params); @@ -310,11 +301,10 @@ TEST(DeviceFactoryTest, SCDP_Device_Defaults) TEST(DeviceFactoryTest, SCHS_Device_Defaults) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "services"); + auto device = device_factory.CreateDevice(UNDEFINED, 0, "services"); + const unordered_map params; device->Init(params); @@ -340,11 +330,10 @@ TEST(DeviceFactoryTest, SCHS_Device_Defaults) TEST(DeviceFactoryTest, SCLP_Device_Defaults) { - auto bus = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); - auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "printer"); + auto device = device_factory.CreateDevice(UNDEFINED, 0, "printer"); + const unordered_map params; device->Init(params); diff --git a/cpp/test/disk_test.cpp b/cpp/test/disk_test.cpp index c1df0b0f..f741e1b8 100644 --- a/cpp/test/disk_test.cpp +++ b/cpp/test/disk_test.cpp @@ -18,34 +18,38 @@ using namespace scsi_command_util; TEST(DiskTest, Dispatch) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); disk->SetRemovable(true); disk->SetMediumChanged(false); disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdTestUnitReady); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); disk->SetMediumChanged(true); - EXPECT_CALL(controller, Error); + EXPECT_CALL(*controller, Error); disk->Dispatch(scsi_command::eCmdTestUnitReady); EXPECT_FALSE(disk->IsMediumChanged()); } TEST(DiskTest, Rezero) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRezero); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::NOT_READY), @@ -54,21 +58,23 @@ TEST(DiskTest, Rezero) disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdRezero); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(DiskTest, FormatUnit) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdFormatUnit); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::NOT_READY), @@ -77,9 +83,9 @@ TEST(DiskTest, FormatUnit) disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdFormatUnit); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); cmd[1] = 0x10; cmd[4] = 1; @@ -90,12 +96,14 @@ TEST(DiskTest, FormatUnit) TEST(DiskTest, ReassignBlocks) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReassignBlocks); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::NOT_READY), @@ -104,21 +112,23 @@ TEST(DiskTest, ReassignBlocks) disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdReassignBlocks); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(DiskTest, Seek6) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek6); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -135,21 +145,23 @@ TEST(DiskTest, Seek6) disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdSeek6); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(DiskTest, Seek10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdSeek10); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -166,19 +178,21 @@ TEST(DiskTest, Seek10) disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdSeek10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(DiskTest, ReadCapacity10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity10); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::NOT_READY), @@ -192,30 +206,32 @@ TEST(DiskTest, ReadCapacity10) << "READ CAPACITY(10) must fail because the medium has no capacity"; disk->SetBlockCount(0x12345678); - EXPECT_CALL(controller, DataIn); + EXPECT_CALL(*controller, DataIn); disk->Dispatch(scsi_command::eCmdReadCapacity10); - auto& buf = controller.GetBuffer(); + auto& buf = controller->GetBuffer(); EXPECT_EQ(0x1234, GetInt16(buf, 0)); EXPECT_EQ(0x5677, GetInt16(buf, 2)); disk->SetBlockCount(0x1234567887654321); - EXPECT_CALL(controller, DataIn); + EXPECT_CALL(*controller, DataIn); disk->Dispatch(scsi_command::eCmdReadCapacity10); - buf = controller.GetBuffer(); + buf = controller->GetBuffer(); EXPECT_EQ(0xffff, GetInt16(buf, 0)); EXPECT_EQ(0xffff, GetInt16(buf, 2)); } TEST(DiskTest, ReadCapacity16) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); cmd[1] = 0x00; EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws(AllOf( @@ -238,9 +254,9 @@ TEST(DiskTest, ReadCapacity16) disk->SetBlockCount(0x1234567887654321); disk->SetSectorSizeInBytes(1024); - EXPECT_CALL(controller, DataIn); + EXPECT_CALL(*controller, DataIn); disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); - const auto& buf = controller.GetBuffer(); + const auto& buf = controller->GetBuffer(); EXPECT_EQ(0x1234, GetInt16(buf, 0)); EXPECT_EQ(0x5678, GetInt16(buf, 2)); EXPECT_EQ(0x8765, GetInt16(buf, 4)); @@ -251,12 +267,14 @@ TEST(DiskTest, ReadCapacity16) TEST(DiskTest, Read6) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead6); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -268,12 +286,14 @@ TEST(DiskTest, Read6) TEST(DiskTest, Read10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead10); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -281,21 +301,23 @@ TEST(DiskTest, Read10) << "READ(10) must fail for a medium with 0 blocks"; disk->SetBlockCount(1); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdRead10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // Further testing requires filesystem access } TEST(DiskTest, Read16) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdRead16); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -303,21 +325,23 @@ TEST(DiskTest, Read16) << "READ(16) must fail for a medium with 0 blocks"; disk->SetBlockCount(1); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdRead16); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // Further testing requires filesystem access } TEST(DiskTest, Write6) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite6); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -337,12 +361,14 @@ TEST(DiskTest, Write6) TEST(DiskTest, Write10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite10); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -350,21 +376,23 @@ TEST(DiskTest, Write10) << "WRITE(10) must fail for a medium with 0 blocks"; disk->SetBlockCount(1); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdWrite10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // Further testing requires filesystem access } TEST(DiskTest, Write16) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWrite16); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -372,21 +400,23 @@ TEST(DiskTest, Write16) << "WRITE(16) must fail for a medium with 0 blocks"; disk->SetBlockCount(1); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdWrite16); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // Further testing requires filesystem access } TEST(DiskTest, Verify10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdVerify10); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -394,21 +424,23 @@ TEST(DiskTest, Verify10) << "VERIFY(10) must fail for a medium with 0 blocks"; disk->SetBlockCount(1); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdVerify10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // Further testing requires filesystem access } TEST(DiskTest, Verify16) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdVerify16); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -416,27 +448,29 @@ TEST(DiskTest, Verify16) << "VERIFY(16) must fail for a medium with 0 blocks"; disk->SetBlockCount(1); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdVerify16); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // Further testing requires filesystem access } TEST(DiskTest, ReadLong10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdReadLong10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); cmd[2] = 1; EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadLong10); }, Throws(AllOf( @@ -454,14 +488,16 @@ TEST(DiskTest, ReadLong10) TEST(DiskTest, ReadLong16) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // READ LONG(16), not READ CAPACITY(16) cmd[1] = 0x11; @@ -472,9 +508,9 @@ TEST(DiskTest, ReadLong16) << "READ LONG(16) must fail because the capacity is exceeded"; cmd[2] = 0; - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); cmd[13] = 1; EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdReadCapacity16_ReadLong16); }, Throws(AllOf( @@ -485,18 +521,20 @@ TEST(DiskTest, ReadLong16) TEST(DiskTest, WriteLong10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdWriteLong10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); cmd[2] = 1; EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong10); }, Throws(AllOf( @@ -514,14 +552,16 @@ TEST(DiskTest, WriteLong10) TEST(DiskTest, WriteLong16) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); cmd[2] = 1; EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong16); }, Throws(AllOf( @@ -530,9 +570,9 @@ TEST(DiskTest, WriteLong16) << "WRITE LONG(16) must fail because the capacity is exceeded"; cmd[2] = 0; - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdWriteLong16); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); cmd[13] = 1; EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdWriteLong16); }, Throws(AllOf( @@ -543,33 +583,35 @@ TEST(DiskTest, WriteLong16) TEST(DiskTest, StartStopUnit) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); disk->SetRemovable(true); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // Stop/Unload disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); EXPECT_CALL(*disk, FlushCache); disk->Dispatch(scsi_command::eCmdStartStop); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); EXPECT_TRUE(disk->IsStopped()); // Stop/Load cmd[4] = 0x02; disk->SetReady(true); disk->SetLocked(false); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); EXPECT_CALL(*disk, FlushCache); disk->Dispatch(scsi_command::eCmdStartStop); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); disk->SetReady(false); EXPECT_CALL(*disk, FlushCache).Times(0); @@ -586,28 +628,30 @@ TEST(DiskTest, StartStopUnit) // Start/Unload cmd[4] = 0x01; - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdStartStop); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); EXPECT_FALSE(disk->IsStopped()); // Start/Load cmd[4] = 0x03; - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdStartStop); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(DiskTest, PreventAllowMediumRemoval) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); EXPECT_THAT([&] { disk->Dispatch(scsi_command::eCmdPreventAllowMediumRemoval); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::NOT_READY), @@ -616,15 +660,15 @@ TEST(DiskTest, PreventAllowMediumRemoval) disk->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdPreventAllowMediumRemoval); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); EXPECT_FALSE(disk->IsLocked()); cmd[4] = 1; - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdPreventAllowMediumRemoval); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); EXPECT_TRUE(disk->IsLocked()); } @@ -657,9 +701,9 @@ TEST(DiskTest, Eject) EXPECT_TRUE(disk.Eject(true)); } -void DiskTest_ValidateFormatPage(AbstractController& controller, int offset) +void DiskTest_ValidateFormatPage(shared_ptr controller, int offset) { - const auto& buf = controller.GetBuffer(); + const auto& buf = controller->GetBuffer(); EXPECT_EQ(0x08, buf[offset + 3]) << "Wrong number of trackes in one zone"; EXPECT_EQ(25, GetInt16(buf, offset + 10)) << "Wrong number of sectors per track"; EXPECT_EQ(1024, GetInt16(buf, offset + 12)) << "Wrong number of bytes per sector"; @@ -670,18 +714,18 @@ void DiskTest_ValidateFormatPage(AbstractController& controller, int offset) EXPECT_TRUE(buf[offset + 20] & 0x40) << "Wrong hard-sectored flag"; } -void DiskTest_ValidateDrivePage(AbstractController& controller, int offset) +void DiskTest_ValidateDrivePage(shared_ptr controller, int offset) { - const auto& buf = controller.GetBuffer(); + const auto& buf = controller->GetBuffer(); EXPECT_EQ(0x17, buf[offset + 2]); EXPECT_EQ(0x4d3b, GetInt16(buf, offset + 3)); EXPECT_EQ(8, buf[offset + 5]) << "Wrong number of heads"; EXPECT_EQ(7200, GetInt16(buf, offset + 20)) << "Wrong medium rotation rate"; } -void DiskTest_ValidateCachePage(AbstractController& controller, int offset) +void DiskTest_ValidateCachePage(shared_ptr controller, int offset) { - const auto& buf = controller.GetBuffer(); + const auto& buf = controller->GetBuffer(); EXPECT_EQ(0xffff, GetInt16(buf, offset + 4)) << "Wrong pre-fetch transfer length"; EXPECT_EQ(0xffff, GetInt16(buf, offset + 8)) << "Wrong maximum pre-fetch"; EXPECT_EQ(0xffff, GetInt16(buf, offset + 10)) << "Wrong maximum pre-fetch ceiling"; @@ -689,14 +733,16 @@ void DiskTest_ValidateCachePage(AbstractController& controller, int offset) TEST(DiskTest, ModeSense6) { - NiceMock controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // Drive must be ready on order to return all data disk->SetReady(true); @@ -705,18 +751,18 @@ TEST(DiskTest, ModeSense6) // ALLOCATION LENGTH cmd[4] = 255; disk->Dispatch(scsi_command::eCmdModeSense6); - EXPECT_EQ(0x08, controller.GetBuffer()[3]) << "Wrong block descriptor length"; + EXPECT_EQ(0x08, controller->GetBuffer()[3]) << "Wrong block descriptor length"; // No block descriptor cmd[1] = 0x08; disk->Dispatch(scsi_command::eCmdModeSense6); - EXPECT_EQ(0x00, controller.GetBuffer()[2]) << "Wrong device-specific parameter"; + EXPECT_EQ(0x00, controller->GetBuffer()[2]) << "Wrong device-specific parameter"; disk->SetReadOnly(false); disk->SetProtectable(true); disk->SetProtected(true); disk->Dispatch(scsi_command::eCmdModeSense6); - const auto& buf = controller.GetBuffer(); + const auto& buf = controller->GetBuffer(); EXPECT_EQ(0x80, buf[2]) << "Wrong device-specific parameter"; // Return block descriptor @@ -742,14 +788,16 @@ TEST(DiskTest, ModeSense6) TEST(DiskTest, ModeSense10) { - NiceMock controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // Drive must be ready on order to return all data disk->SetReady(true); @@ -758,19 +806,19 @@ TEST(DiskTest, ModeSense10) // ALLOCATION LENGTH cmd[8] = 255; disk->Dispatch(scsi_command::eCmdModeSense10); - EXPECT_EQ(0x08, controller.GetBuffer()[7]) << "Wrong block descriptor length"; + EXPECT_EQ(0x08, controller->GetBuffer()[7]) << "Wrong block descriptor length"; // No block descriptor cmd[1] = 0x08; disk->Dispatch(scsi_command::eCmdModeSense10); - auto& buf = controller.GetBuffer(); - EXPECT_EQ(0x00, controller.GetBuffer()[3]) << "Wrong device-specific parameter"; + auto& buf = controller->GetBuffer(); + EXPECT_EQ(0x00, controller->GetBuffer()[3]) << "Wrong device-specific parameter"; disk->SetReadOnly(false); disk->SetProtectable(true); disk->SetProtected(true); disk->Dispatch(scsi_command::eCmdModeSense10); - buf = controller.GetBuffer(); + buf = controller->GetBuffer(); EXPECT_EQ(0x80, buf[3]) << "Wrong device-specific parameter"; // Return short block descriptor @@ -778,7 +826,7 @@ TEST(DiskTest, ModeSense10) disk->SetBlockCount(0x1234); disk->SetSectorSizeInBytes(1024); disk->Dispatch(scsi_command::eCmdModeSense10); - buf = controller.GetBuffer(); + buf = controller->GetBuffer(); EXPECT_EQ(0x00, buf[4]) << "Wrong LONGLBA field"; EXPECT_EQ(0x08, buf[7]) << "Wrong block descriptor length"; EXPECT_EQ(0x00, GetInt16(buf, 8)); @@ -790,7 +838,7 @@ TEST(DiskTest, ModeSense10) cmd[1] = 0x10; disk->SetBlockCount((uint64_t)0xffffffff + 1); disk->Dispatch(scsi_command::eCmdModeSense10); - buf = controller.GetBuffer(); + buf = controller->GetBuffer(); EXPECT_EQ(0x01, buf[4]) << "Wrong LONGLBA field"; EXPECT_EQ(0x10, buf[7]) << "Wrong block descriptor length"; EXPECT_EQ(0x00, GetInt16(buf, 8)); @@ -821,36 +869,40 @@ TEST(DiskTest, ModeSense10) TEST(DiskTest, SynchronizeCache) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); EXPECT_CALL(*disk, FlushCache); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdSynchronizeCache10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); EXPECT_CALL(*disk, FlushCache); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); disk->Dispatch(scsi_command::eCmdSynchronizeCache16); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(DiskTest, ReadDefectData) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto disk = make_shared(); const unordered_map params; disk->Init(params); - controller.AddDevice(disk); + controller->AddDevice(disk); - EXPECT_CALL(controller, DataIn); + EXPECT_CALL(*controller, DataIn); disk->Dispatch(scsi_command::eCmdReadDefectData10); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(DiskTest, SectorSize) diff --git a/cpp/test/host_services_test.cpp b/cpp/test/host_services_test.cpp index 3ea261b1..78d2e50b 100644 --- a/cpp/test/host_services_test.cpp +++ b/cpp/test/host_services_test.cpp @@ -22,12 +22,14 @@ void HostServices_SetUpModePages(map>& pages) TEST(HostServicesTest, TestUnitReady) { - NiceMock controller(make_shared(), 0); - auto services = CreateDevice(SCHS, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto services = CreateDevice(SCHS, *controller); - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, Status()); services->Dispatch(scsi_command::eCmdTestUnitReady); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(HostServicesTest, Inquiry) @@ -37,30 +39,32 @@ TEST(HostServicesTest, Inquiry) TEST(HostServicesTest, StartStopUnit) { - NiceMock controller(make_shared(), 0); - auto services = CreateDevice(SCHS, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto services = CreateDevice(SCHS, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // STOP - EXPECT_CALL(controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI)); - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_RASCSI)); + EXPECT_CALL(*controller, Status()); services->Dispatch(scsi_command::eCmdStartStop); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // LOAD cmd[4] = 0x02; - EXPECT_CALL(controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI)); - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::STOP_PI)); + EXPECT_CALL(*controller, Status()); services->Dispatch(scsi_command::eCmdStartStop); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // UNLOAD cmd[4] = 0x03; - EXPECT_CALL(controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI)); - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, ScheduleShutdown(AbstractController::rascsi_shutdown_mode::RESTART_PI)); + EXPECT_CALL(*controller, Status()); services->Dispatch(scsi_command::eCmdStartStop); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); // START cmd[4] = 0x01; @@ -71,12 +75,14 @@ TEST(HostServicesTest, StartStopUnit) TEST(HostServicesTest, ModeSense6) { - NiceMock controller(make_shared(), 0); - auto services = CreateDevice(SCHS, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto services = CreateDevice(SCHS, *controller); const unordered_map params; services->Init(params); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense6); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -92,9 +98,9 @@ TEST(HostServicesTest, ModeSense6) cmd[1] = 0x08; // ALLOCATION LENGTH cmd[4] = 255; - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); services->Dispatch(scsi_command::eCmdModeSense6); - vector& buffer = controller.GetBuffer(); + vector& buffer = controller->GetBuffer(); // Major version 1 EXPECT_EQ(0x01, buffer[6]); // Minor version 0 @@ -106,20 +112,22 @@ TEST(HostServicesTest, ModeSense6) // ALLOCATION LENGTH cmd[4] = 2; - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); services->Dispatch(scsi_command::eCmdModeSense6); - buffer = controller.GetBuffer(); + buffer = controller->GetBuffer(); EXPECT_EQ(0x02, buffer[0]); } TEST(HostServicesTest, ModeSense10) { - NiceMock controller(make_shared(), 0); - auto services = CreateDevice(SCHS, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto services = CreateDevice(SCHS, *controller); const unordered_map params; services->Init(params); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); EXPECT_THAT([&] { services->Dispatch(scsi_command::eCmdModeSense10); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -135,9 +143,9 @@ TEST(HostServicesTest, ModeSense10) cmd[1] = 0x08; // ALLOCATION LENGTH cmd[8] = 255; - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); services->Dispatch(scsi_command::eCmdModeSense10); - vector& buffer = controller.GetBuffer(); + vector& buffer = controller->GetBuffer(); // Major version 1 EXPECT_EQ(0x01, buffer[10]); // Minor version 0 @@ -149,16 +157,15 @@ TEST(HostServicesTest, ModeSense10) // ALLOCATION LENGTH cmd[8] = 2; - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); services->Dispatch(scsi_command::eCmdModeSense10); - buffer = controller.GetBuffer(); + buffer = controller->GetBuffer(); EXPECT_EQ(0x02, buffer[1]); } TEST(HostServicesTest, SetUpModePages) { - ControllerManager controller_manager(make_shared()); - MockHostServices services(0, controller_manager); + MockHostServices services(0); map> pages; // Non changeable diff --git a/cpp/test/mocks.h b/cpp/test/mocks.h index ff3a1a66..044c8ca8 100644 --- a/cpp/test/mocks.h +++ b/cpp/test/mocks.h @@ -103,6 +103,7 @@ class MockAbstractController : public AbstractController //NOSONAR Having many f FRIEND_TEST(AbstractControllerTest, Length); FRIEND_TEST(AbstractControllerTest, UpdateOffsetAndLength); FRIEND_TEST(AbstractControllerTest, Offset); + FRIEND_TEST(ScsiControllerTest, Selection); FRIEND_TEST(PrimaryDeviceTest, Inquiry); FRIEND_TEST(PrimaryDeviceTest, TestUnitReady); FRIEND_TEST(PrimaryDeviceTest, RequestSense); @@ -153,14 +154,15 @@ public: MOCK_METHOD(void, MsgOut, (), ()); MOCK_METHOD(void, ScheduleShutdown, (rascsi_shutdown_mode), (override)); - explicit MockAbstractController(shared_ptr bus, int target_id) : AbstractController(bus, target_id, 32) { + explicit MockAbstractController(shared_ptr controller_manager, int target_id) + : AbstractController(controller_manager, target_id, 32) { AllocateBuffer(512); } ~MockAbstractController() override = default; // Permit access to all tests without the need for numerous FRIEND_TEST vector& GetCmd() { return AbstractController::GetCmd(); } //NOSONAR Hides function on purpose - shared_ptr GetBus() { return AbstractController::GetBus(); } //NOSONAR Hides function on purpose + BUS& GetBus() { return AbstractController::GetBus(); } //NOSONAR Hides function on purpose }; class MockScsiController : public ScsiController @@ -184,9 +186,10 @@ public: MOCK_METHOD(void, Execute, (), ()); using ScsiController::ScsiController; - explicit MockScsiController(shared_ptr> bus, int target_id) : ScsiController(bus, target_id) {} - explicit MockScsiController(shared_ptr bus, int target_id) : ScsiController(bus, target_id) {} - explicit MockScsiController(shared_ptr bus) : ScsiController(bus, 0) {} + MockScsiController(shared_ptr controller_manager, int target_id) + : ScsiController(controller_manager, target_id) {} + explicit MockScsiController(shared_ptr controller_manager) + : ScsiController(controller_manager, 0) {} ~MockScsiController() override = default; }; diff --git a/cpp/test/mode_page_device_test.cpp b/cpp/test/mode_page_device_test.cpp index df0b2c4c..bbccb790 100644 --- a/cpp/test/mode_page_device_test.cpp +++ b/cpp/test/mode_page_device_test.cpp @@ -80,27 +80,31 @@ TEST(ModePageDeviceTest, AddVendorPage) TEST(ModePageDeviceTest, ModeSense6) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared>(); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); device->Dispatch(scsi_command::eCmdModeSense6); } TEST(ModePageDeviceTest, ModeSense10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared>(); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); device->Dispatch(scsi_command::eCmdModeSense10); } @@ -122,16 +126,18 @@ TEST(ModePageDeviceTest, ModeSelect) TEST(ModePageDeviceTest, ModeSelect6) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); - EXPECT_CALL(controller, DataOut()); + EXPECT_CALL(*controller, DataOut()); device->Dispatch(scsi_command::eCmdModeSelect6); cmd[1] = 0x01; @@ -143,16 +149,18 @@ TEST(ModePageDeviceTest, ModeSelect6) TEST(ModePageDeviceTest, ModeSelect10) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); - EXPECT_CALL(controller, DataOut()); + EXPECT_CALL(*controller, DataOut()); device->Dispatch(scsi_command::eCmdModeSelect10); cmd[1] = 0x01; diff --git a/cpp/test/primary_device_test.cpp b/cpp/test/primary_device_test.cpp index 575f3222..c32ad813 100644 --- a/cpp/test/primary_device_test.cpp +++ b/cpp/test/primary_device_test.cpp @@ -21,44 +21,50 @@ TEST(PrimaryDeviceTest, GetId) { const int ID = 5; - MockAbstractController controller(make_shared(), ID); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, ID); auto device = make_shared(0); const unordered_map params; device->Init(params); EXPECT_EQ(-1, device->GetId()) << "Device ID cannot be known without assignment to a controller"; - controller.AddDevice(device); + controller->AddDevice(device); EXPECT_EQ(ID, device->GetId()); } TEST(PrimaryDeviceTest, PhaseChange) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); device->EnterStatusPhase(); - EXPECT_CALL(controller, DataIn); + EXPECT_CALL(*controller, DataIn); device->EnterDataInPhase(); - EXPECT_CALL(controller, DataOut); + EXPECT_CALL(*controller, DataOut); device->EnterDataOutPhase(); } TEST(PrimaryDeviceTest, Reset) { - NiceMock controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); device->Dispatch(scsi_command::eCmdReserve6); EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false)) @@ -70,12 +76,14 @@ TEST(PrimaryDeviceTest, Reset) TEST(PrimaryDeviceTest, CheckReservation) { - NiceMock controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); EXPECT_TRUE(device->CheckReservation(0, scsi_command::eCmdTestUnitReady, false)) << "Device must not be reserved for initiator ID 0"; @@ -102,12 +110,14 @@ TEST(PrimaryDeviceTest, CheckReservation) TEST(PrimaryDeviceTest, ReserveReleaseUnit) { - NiceMock controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); device->Dispatch(scsi_command::eCmdReserve6); EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false)) @@ -117,7 +127,7 @@ TEST(PrimaryDeviceTest, ReserveReleaseUnit) EXPECT_TRUE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false)) << "Device must not be reserved anymore for initiator ID 1"; - ON_CALL(controller, GetInitiatorId).WillByDefault(Return(-1)); + ON_CALL(*controller, GetInitiatorId).WillByDefault(Return(-1)); device->Dispatch(scsi_command::eCmdReserve6); EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false)) << "Device must be reserved for unknown initiator"; @@ -129,12 +139,14 @@ TEST(PrimaryDeviceTest, ReserveReleaseUnit) TEST(PrimaryDeviceTest, DiscardReservation) { - NiceMock controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); device->Dispatch(scsi_command::eCmdReserve6); EXPECT_FALSE(device->CheckReservation(1, scsi_command::eCmdTestUnitReady, false)) @@ -146,56 +158,60 @@ TEST(PrimaryDeviceTest, DiscardReservation) TEST(PrimaryDeviceTest, TestUnitReady) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); device->SetReset(true); device->SetAttn(true); device->SetReady(false); - EXPECT_CALL(controller, DataIn).Times(0); + EXPECT_CALL(*controller, DataIn).Times(0); EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION), Property(&scsi_exception::get_asc, asc::POWER_ON_OR_RESET)))); device->SetReset(false); - EXPECT_CALL(controller, DataIn).Times(0); + EXPECT_CALL(*controller, DataIn).Times(0); EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION), Property(&scsi_exception::get_asc, asc::NOT_READY_TO_READY_CHANGE)))); device->SetReset(true); device->SetAttn(false); - EXPECT_CALL(controller, DataIn).Times(0); + EXPECT_CALL(*controller, DataIn).Times(0); EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION), Property(&scsi_exception::get_asc, asc::POWER_ON_OR_RESET)))); device->SetReset(false); device->SetAttn(true); - EXPECT_CALL(controller, DataIn).Times(0); + EXPECT_CALL(*controller, DataIn).Times(0); EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::UNIT_ATTENTION), Property(&scsi_exception::get_asc, asc::NOT_READY_TO_READY_CHANGE)))); device->SetAttn(false); - EXPECT_CALL(controller, DataIn).Times(0); + EXPECT_CALL(*controller, DataIn).Times(0); EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdTestUnitReady); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::NOT_READY), Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT)))); device->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); device->Dispatch(scsi_command::eCmdTestUnitReady); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(PrimaryDeviceTest, Inquiry) { - auto controller = make_shared>(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); @@ -266,14 +282,16 @@ TEST(PrimaryDeviceTest, Inquiry) TEST(PrimaryDeviceTest, RequestSense) { - NiceMock controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // ALLOCATION LENGTH cmd[4] = 255; @@ -283,25 +301,27 @@ TEST(PrimaryDeviceTest, RequestSense) Property(&scsi_exception::get_asc, asc::MEDIUM_NOT_PRESENT)))); device->SetReady(true); - EXPECT_CALL(controller, DataIn); + EXPECT_CALL(*controller, DataIn); device->Dispatch(scsi_command::eCmdRequestSense); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(PrimaryDeviceTest, SendDiagnostic) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); device->Dispatch(scsi_command::eCmdSendDiagnostic); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); cmd[1] = 0x10; EXPECT_THAT([&] { device->Dispatch(scsi_command::eCmdSendDiagnostic); }, Throws(AllOf( @@ -328,25 +348,27 @@ TEST(PrimaryDeviceTest, ReportLuns) const int LUN1 = 1; const int LUN2 = 4; - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device1 = make_shared(LUN1); auto device2 = make_shared(LUN2); const unordered_map params; device1->Init(params); device2->Init(params); - controller.AddDevice(device1); - EXPECT_TRUE(controller.HasDeviceForLun(LUN1)); - controller.AddDevice(device2); - EXPECT_TRUE(controller.HasDeviceForLun(LUN2)); + controller->AddDevice(device1); + EXPECT_TRUE(controller->HasDeviceForLun(LUN1)); + controller->AddDevice(device2); + EXPECT_TRUE(controller->HasDeviceForLun(LUN2)); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // ALLOCATION LENGTH cmd[9] = 255; - EXPECT_CALL(controller, DataIn); + EXPECT_CALL(*controller, DataIn); device1->Dispatch(scsi_command::eCmdReportLuns); - const vector& buffer = controller.GetBuffer(); + const vector& buffer = controller->GetBuffer(); EXPECT_EQ(0, GetInt16(buffer, 0)) << "Wrong data length"; EXPECT_EQ(16, GetInt16(buffer, 2)) << "Wrong data length"; EXPECT_EQ(0, GetInt16(buffer, 8)) << "Wrong LUN1 number"; @@ -367,12 +389,14 @@ TEST(PrimaryDeviceTest, ReportLuns) TEST(PrimaryDeviceTest, Dispatch) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); EXPECT_THROW(device->Dispatch(static_cast(0x1f)), scsi_exception) << "Unknown command"; } diff --git a/cpp/test/rascsi_executor_test.cpp b/cpp/test/rascsi_executor_test.cpp index 86bcddbc..f16e05ee 100644 --- a/cpp/test/rascsi_executor_test.cpp +++ b/cpp/test/rascsi_executor_test.cpp @@ -40,12 +40,10 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd) const int LUN = 0; auto bus = make_shared(); - DeviceFactory device_factory; - MockAbstractController controller(bus, ID); - ControllerManager controller_manager(bus); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, ID); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - auto executor = make_shared(rascsi_response, rascsi_image, device_factory, controller_manager); + auto executor = make_shared(rascsi_image, *controller_manager); PbDeviceDefinition definition; PbCommand command; MockCommandContext context; @@ -68,19 +66,19 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd) EXPECT_FALSE(executor->ProcessDeviceCmd(context, definition, command, true)) << "Operation for unknown device type must fail"; auto device1 = make_shared(LUN); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1)); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1)); definition.set_type(SCHS); command.set_operation(INSERT); EXPECT_FALSE(executor->ProcessDeviceCmd(context, definition, command, true)) << "Operation unsupported by device must fail"; - controller_manager.DeleteAllControllers(); + controller_manager->DeleteAllControllers(); definition.set_type(SCRM); auto device2 = make_shared(LUN); device2->SetRemovable(true); device2->SetProtectable(true); device2->SetReady(true); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2)); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2)); command.set_operation(ATTACH); EXPECT_FALSE(executor->ProcessDeviceCmd(context, definition, command, true)) << "ID and LUN already exist"; @@ -113,7 +111,7 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd) command.set_operation(DETACH); EXPECT_TRUE(executor->ProcessDeviceCmd(context, definition, command, true)); EXPECT_TRUE(executor->ProcessDeviceCmd(context, definition, command, false)); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2)); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2)); command.set_operation(CHECK_AUTHENTICATION); EXPECT_TRUE(executor->ProcessDeviceCmd(context, definition, command, true)); @@ -152,13 +150,11 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd) TEST_F(RascsiExecutorTest, ProcessCmd) { - shared_ptr bus; - DeviceFactory device_factory; - MockAbstractController controller(bus, 0); - ControllerManager controller_manager(bus); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - auto executor = make_shared(rascsi_response, rascsi_image, device_factory, controller_manager); + auto executor = make_shared(rascsi_image, *controller_manager); PbCommand command1; PbCommand command2; MockCommandContext context; @@ -219,11 +215,11 @@ TEST_F(RascsiExecutorTest, ProcessCmd) TEST_F(RascsiExecutorTest, SetLogLevel) { - DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + MockAbstractController controller(controller_manager, 0); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); EXPECT_TRUE(executor.SetLogLevel("trace")); EXPECT_TRUE(executor.SetLogLevel("debug")); @@ -240,17 +236,17 @@ TEST_F(RascsiExecutorTest, Attach) const int LUN = 0; DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); PbDeviceDefinition definition; MockCommandContext context; definition.set_unit(32); EXPECT_FALSE(executor.Attach(context, definition, false)); - auto device = device_factory.CreateDevice(controller_manager, SCHD, LUN, ""); + auto device = device_factory.CreateDevice(SCHD, LUN, ""); definition.set_id(ID); definition.set_unit(LUN); @@ -262,7 +258,7 @@ TEST_F(RascsiExecutorTest, Attach) definition.set_type(PbDeviceType::SCHS); EXPECT_TRUE(executor.Attach(context, definition, false)); - controller_manager.DeleteAllControllers(); + controller_manager->DeleteAllControllers(); definition.set_type(PbDeviceType::SCHD); EXPECT_FALSE(executor.Attach(context, definition, false)) << "Drive without sectors not rejected"; @@ -290,7 +286,7 @@ TEST_F(RascsiExecutorTest, Attach) bool result = executor.Attach(context, definition, false); remove(filename); EXPECT_TRUE(result); - controller_manager.DeleteAllControllers(); + controller_manager->DeleteAllControllers(); filename = CreateTempFile(513); SetParam(definition, "file", filename.c_str()); @@ -315,20 +311,20 @@ TEST_F(RascsiExecutorTest, Attach) remove(filename); EXPECT_TRUE(result); - controller_manager.DeleteAllControllers(); + controller_manager->DeleteAllControllers(); } TEST_F(RascsiExecutorTest, Insert) { DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); PbDeviceDefinition definition; MockCommandContext context; - auto device = device_factory.CreateDevice(controller_manager, SCRM, 0, "test"); + auto device = device_factory.CreateDevice(SCRM, 0, "test"); device->SetRemoved(false); EXPECT_FALSE(executor.Insert(context, definition, device, false)) << "Medium is not removed"; @@ -381,23 +377,23 @@ TEST_F(RascsiExecutorTest, Detach) const int LUN2 = 1; DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; - auto device1 = device_factory.CreateDevice(controller_manager, SCHS, LUN1, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1)); - auto device2 = device_factory.CreateDevice(controller_manager, SCHS, LUN2, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2)); + auto device1 = device_factory.CreateDevice(SCHS, LUN1, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1)); + auto device2 = device_factory.CreateDevice(SCHS, LUN2, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2)); - auto d1 = controller_manager.GetDeviceByIdAndLun(ID, LUN1); + auto d1 = controller_manager->GetDeviceByIdAndLun(ID, LUN1); EXPECT_FALSE(executor.Detach(context, d1, false)) << "LUNs > 0 have to be detached first"; - auto d2 = controller_manager.GetDeviceByIdAndLun(ID, LUN2); + auto d2 = controller_manager->GetDeviceByIdAndLun(ID, LUN2); EXPECT_TRUE(executor.Detach(context, d2, false)); EXPECT_TRUE(executor.Detach(context, d1, false)); - EXPECT_TRUE(controller_manager.GetAllDevices().empty()); + EXPECT_TRUE(controller_manager->GetAllDevices().empty()); EXPECT_FALSE(executor.Detach(context, d1, false)); } @@ -407,28 +403,27 @@ TEST_F(RascsiExecutorTest, DetachAll) const int ID = 4; DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); - auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device)); - EXPECT_NE(nullptr, controller_manager.FindController(ID)); - EXPECT_FALSE(controller_manager.GetAllDevices().empty()); + auto device = device_factory.CreateDevice(SCHS, 0, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device)); + EXPECT_NE(nullptr, controller_manager->FindController(ID)); + EXPECT_FALSE(controller_manager->GetAllDevices().empty()); executor.DetachAll(); - EXPECT_EQ(nullptr, controller_manager.FindController(ID)); - EXPECT_TRUE(controller_manager.GetAllDevices().empty()); + EXPECT_EQ(nullptr, controller_manager->FindController(ID)); + EXPECT_TRUE(controller_manager->GetAllDevices().empty()); } TEST_F(RascsiExecutorTest, ShutDown) { - DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; EXPECT_FALSE(executor.ShutDown(context, "")); @@ -441,10 +436,10 @@ TEST_F(RascsiExecutorTest, ShutDown) TEST_F(RascsiExecutorTest, SetReservedIds) { DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); string error = executor.SetReservedIds("xyz"); EXPECT_FALSE(error.empty()); @@ -472,8 +467,8 @@ TEST_F(RascsiExecutorTest, SetReservedIds) EXPECT_NE(reserved_ids.end(), reserved_ids.find(5)); EXPECT_NE(reserved_ids.end(), reserved_ids.find(7)); - auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(5, device)); + auto device = device_factory.CreateDevice(SCHS, 0, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(5, device)); error = executor.SetReservedIds("5"); EXPECT_FALSE(error.empty()); } @@ -481,14 +476,14 @@ TEST_F(RascsiExecutorTest, SetReservedIds) TEST_F(RascsiExecutorTest, ValidateImageFile) { DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; string full_path; - auto device = dynamic_pointer_cast(device_factory.CreateDevice(controller_manager, SCHD, 0, "test")); + auto device = dynamic_pointer_cast(device_factory.CreateDevice(SCHD, 0, "test")); EXPECT_TRUE(executor.ValidateImageFile(context, *device, "", full_path)); EXPECT_TRUE(full_path.empty()); @@ -499,10 +494,10 @@ TEST_F(RascsiExecutorTest, ValidateImageFile) TEST_F(RascsiExecutorTest, ValidateLunSetup) { DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); PbCommand command; auto device1 = command.add_devices(); @@ -514,8 +509,8 @@ TEST_F(RascsiExecutorTest, ValidateLunSetup) error = executor.ValidateLunSetup(command); EXPECT_FALSE(error.empty()); - auto device2 = device_factory.CreateDevice(controller_manager, SCHS, 0, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(0, device2)); + auto device2 = device_factory.CreateDevice(SCHS, 0, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(0, device2)); error = executor.ValidateLunSetup(command); EXPECT_TRUE(error.empty()); } @@ -527,26 +522,25 @@ TEST_F(RascsiExecutorTest, VerifyExistingIdAndLun) const int LUN2 = 3; DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; EXPECT_FALSE(executor.VerifyExistingIdAndLun(context, ID, LUN1)); - auto device = device_factory.CreateDevice(controller_manager, SCHS, LUN1, ""); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device)); + auto device = device_factory.CreateDevice(SCHS, LUN1, ""); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device)); EXPECT_TRUE(executor.VerifyExistingIdAndLun(context, ID, LUN1)); EXPECT_FALSE(executor.VerifyExistingIdAndLun(context, ID, LUN2)); } TEST_F(RascsiExecutorTest, CreateDevice) { - DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; EXPECT_EQ(nullptr, executor.CreateDevice(context, UNDEFINED, 0, "")); @@ -560,11 +554,10 @@ TEST_F(RascsiExecutorTest, CreateDevice) TEST_F(RascsiExecutorTest, SetSectorSize) { - DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; unordered_set sizes; @@ -580,11 +573,10 @@ TEST_F(RascsiExecutorTest, SetSectorSize) TEST_F(RascsiExecutorTest, ValidateOperationAgainstDevice) { - DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; auto device = make_shared(0); @@ -634,11 +626,10 @@ TEST_F(RascsiExecutorTest, ValidateOperationAgainstDevice) TEST_F(RascsiExecutorTest, ValidateIdAndLun) { - DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; EXPECT_FALSE(executor.ValidateIdAndLun(context, -1, 0)); @@ -651,11 +642,10 @@ TEST_F(RascsiExecutorTest, ValidateIdAndLun) TEST_F(RascsiExecutorTest, SetProductData) { - DeviceFactory device_factory; - ControllerManager controller_manager(make_shared()); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); RascsiImage rascsi_image; - RascsiResponse rascsi_response(device_factory, controller_manager, 32); - RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); + RascsiExecutor executor(rascsi_image, *controller_manager); MockCommandContext context; PbDeviceDefinition definition; diff --git a/cpp/test/rascsi_response_test.cpp b/cpp/test/rascsi_response_test.cpp index 43f627d9..f773571f 100644 --- a/cpp/test/rascsi_response_test.cpp +++ b/cpp/test/rascsi_response_test.cpp @@ -18,10 +18,7 @@ using namespace rascsi_interface; TEST(RascsiResponseTest, Operation_Count) { - auto bus = make_shared(); - ControllerManager controller_manager(bus); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; PbResult result; const auto info = response.GetOperationInfo(result, 0); @@ -31,17 +28,17 @@ TEST(RascsiResponseTest, Operation_Count) void TestNonDiskDevice(PbDeviceType type, int default_param_count) { auto bus = make_shared(); - ControllerManager controller_manager(bus); + auto controller_manager = make_shared(*bus); DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; - auto d = device_factory.CreateDevice(controller_manager, type, 0, ""); + auto d = device_factory.CreateDevice(type, 0, ""); const unordered_map params; d->Init(params); - EXPECT_TRUE(controller_manager.AttachToScsiController(0, d)); + EXPECT_TRUE(controller_manager->AttachToScsiController(0, d)); PbServerInfo info; - response.GetDevices(info, "image_folder"); + response.GetDevices(controller_manager->GetAllDevices(), info, "image_folder"); EXPECT_EQ(1, info.devices_info().devices().size()); @@ -73,9 +70,7 @@ TEST(RascsiResponseTest, GetDevices) TEST(RascsiResponseTest, GetImageFile) { - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; PbImageFile image_file; EXPECT_FALSE(response.GetImageFile(image_file, "default_folder", "")); @@ -88,10 +83,7 @@ TEST(RascsiResponseTest, GetImageFile) TEST(RascsiResponseTest, GetReservedIds) { - auto bus = make_shared(); - ControllerManager controller_manager(bus); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; unordered_set ids; PbResult result; @@ -113,20 +105,20 @@ TEST(RascsiResponseTest, GetDevicesInfo) const int LUN2 = 5; const int LUN3 = 6; - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + RascsiResponse response; PbCommand command; PbResult result; - response.GetDevicesInfo(result, command, ""); + response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, ""); EXPECT_TRUE(result.status()); EXPECT_TRUE(result.devices_info().devices().empty()); - auto device1 = make_shared(LUN1, controller_manager); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device1)); + auto device1 = make_shared(LUN1); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device1)); - response.GetDevicesInfo(result, command, ""); + response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, ""); EXPECT_TRUE(result.status()); auto& devices1 = result.devices_info().devices(); EXPECT_EQ(1, devices1.size()); @@ -135,9 +127,9 @@ TEST(RascsiResponseTest, GetDevicesInfo) EXPECT_EQ(LUN1, devices1[0].unit()); auto device2 = make_shared(LUN2); - EXPECT_TRUE(controller_manager.AttachToScsiController(ID, device2)); + EXPECT_TRUE(controller_manager->AttachToScsiController(ID, device2)); - response.GetDevicesInfo(result, command, ""); + response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, ""); EXPECT_TRUE(result.status()); auto& devices2 = result.devices_info().devices(); EXPECT_EQ(2, devices2.size()) << "Data for all devices must be returned"; @@ -145,7 +137,7 @@ TEST(RascsiResponseTest, GetDevicesInfo) auto requested_device = command.add_devices(); requested_device->set_id(ID); requested_device->set_unit(LUN1); - response.GetDevicesInfo(result, command, ""); + response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, ""); EXPECT_TRUE(result.status()); auto& devices3 = result.devices_info().devices(); EXPECT_EQ(1, devices3.size()) << "Only data for the specified ID and LUN must be returned"; @@ -155,15 +147,13 @@ TEST(RascsiResponseTest, GetDevicesInfo) requested_device->set_id(ID); requested_device->set_unit(LUN3); - response.GetDevicesInfo(result, command, ""); + response.GetDevicesInfo(controller_manager->GetAllDevices(), result, command, ""); EXPECT_FALSE(result.status()) << "Only data for the specified ID and LUN must be returned"; } TEST(RascsiResponseTest, GetDeviceTypesInfo) { - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; PbResult result; const auto& info = response.GetDeviceTypesInfo(result); @@ -173,13 +163,14 @@ TEST(RascsiResponseTest, GetDeviceTypesInfo) TEST(RascsiResponseTest, GetServerInfo) { - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + RascsiResponse response; + const unordered_set> devices; const unordered_set ids = { 1, 3 }; PbResult result; - const auto& info = response.GetServerInfo(result, ids, "log_level", "default_folder", "", "", 1234); + const auto& info = response.GetServerInfo(devices, result, ids, "log_level", "default_folder", "", "", 1234); EXPECT_TRUE(result.status()); EXPECT_EQ(rascsi_major_version, info->version_info().major_version()); EXPECT_EQ(rascsi_minor_version, info->version_info().minor_version()); @@ -192,9 +183,7 @@ TEST(RascsiResponseTest, GetServerInfo) TEST(RascsiResponseTest, GetVersionInfo) { - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; PbResult result; const auto& info = response.GetVersionInfo(result); @@ -206,9 +195,7 @@ TEST(RascsiResponseTest, GetVersionInfo) TEST(RascsiResponseTest, GetLogLevelInfo) { - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; PbResult result; const auto& info = response.GetLogLevelInfo(result, "level"); @@ -219,9 +206,7 @@ TEST(RascsiResponseTest, GetLogLevelInfo) TEST(RascsiResponseTest, GetNetworkInterfacesInfo) { - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; PbResult result; const auto& info = response.GetNetworkInterfacesInfo(result); @@ -231,9 +216,7 @@ TEST(RascsiResponseTest, GetNetworkInterfacesInfo) TEST(RascsiResponseTest, GetMappingInfo) { - ControllerManager controller_manager(make_shared()); - DeviceFactory device_factory; - RascsiResponse response(device_factory, controller_manager, 32); + RascsiResponse response; PbResult result; const auto& info = response.GetMappingInfo(result); diff --git a/cpp/test/scsi_controller_test.cpp b/cpp/test/scsi_controller_test.cpp index 76ab8cf3..2fa611c8 100644 --- a/cpp/test/scsi_controller_test.cpp +++ b/cpp/test/scsi_controller_test.cpp @@ -18,7 +18,9 @@ TEST(ScsiControllerTest, GetInitiatorId) { const int ID = 2; - MockScsiController controller(make_shared>()); + auto bus = make_shared>(); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.Process(ID); EXPECT_EQ(ID, controller.GetInitiatorId()); @@ -29,7 +31,8 @@ TEST(ScsiControllerTest, GetInitiatorId) TEST(ScsiControllerTest, Process) { auto bus = make_shared>(); - MockScsiController controller(bus); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::reserved); ON_CALL(*bus, GetRST).WillByDefault(Return(true)); @@ -55,7 +58,9 @@ TEST(ScsiControllerTest, Process) TEST(ScsiControllerTest, BusFree) { - MockScsiController controller(make_shared>()); + auto bus = make_shared>(); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::busfree); controller.BusFree(); @@ -87,63 +92,65 @@ TEST(ScsiControllerTest, BusFree) TEST(ScsiControllerTest, Selection) { auto bus = make_shared>(); - MockScsiController controller(bus, 0); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); - controller.SetPhase(BUS::phase_t::selection); + controller->SetPhase(BUS::phase_t::selection); ON_CALL(*bus, GetSEL).WillByDefault(Return(true)); ON_CALL(*bus, GetBSY).WillByDefault(Return(true)); EXPECT_CALL(*bus, GetATN).Times(0); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); + controller->Selection(); + EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase()); ON_CALL(*bus, GetSEL).WillByDefault(Return(true)); ON_CALL(*bus, GetBSY).WillByDefault(Return(false)); EXPECT_CALL(*bus, GetATN).Times(0); - EXPECT_CALL(controller, Status); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); + EXPECT_CALL(*controller, Status); + controller->Selection(); + EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase()); ON_CALL(*bus, GetSEL).WillByDefault(Return(false)); ON_CALL(*bus, GetBSY).WillByDefault(Return(false)); EXPECT_CALL(*bus, GetATN).Times(0); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); + controller->Selection(); + EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase()); ON_CALL(*bus, GetSEL).WillByDefault(Return(false)); ON_CALL(*bus, GetBSY).WillByDefault(Return(true)); ON_CALL(*bus, GetATN).WillByDefault(Return(false)); EXPECT_CALL(*bus, GetATN); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::command, controller.GetPhase()); + controller->Selection(); + EXPECT_EQ(BUS::phase_t::command, controller->GetPhase()); - controller.SetPhase(BUS::phase_t::selection); + controller->SetPhase(BUS::phase_t::selection); ON_CALL(*bus, GetSEL).WillByDefault(Return(false)); ON_CALL(*bus, GetBSY).WillByDefault(Return(true)); ON_CALL(*bus, GetATN).WillByDefault(Return(true)); EXPECT_CALL(*bus, GetATN); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::msgout, controller.GetPhase()); + controller->Selection(); + EXPECT_EQ(BUS::phase_t::msgout, controller->GetPhase()); - controller.SetPhase(BUS::phase_t::reserved); + controller->SetPhase(BUS::phase_t::reserved); ON_CALL(*bus, GetDAT).WillByDefault(Return(0)); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()); + controller->Selection(); + EXPECT_EQ(BUS::phase_t::reserved, controller->GetPhase()); ON_CALL(*bus, GetDAT).WillByDefault(Return(1)); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()) << "There is no device that can be selected"; + controller->Selection(); + EXPECT_EQ(BUS::phase_t::reserved, controller->GetPhase()) << "There is no device that can be selected"; auto device = make_shared(0); - controller.AddDevice(device); + controller->AddDevice(device); EXPECT_CALL(*bus, SetBSY(true)); - controller.Selection(); - EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); + controller->Selection(); + EXPECT_EQ(BUS::phase_t::selection, controller->GetPhase()); } TEST(ScsiControllerTest, Command) { auto bus = make_shared>(); - MockScsiController controller(bus, 0); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::command); EXPECT_CALL(controller, Status); @@ -170,7 +177,8 @@ TEST(ScsiControllerTest, Command) TEST(ScsiControllerTest, MsgIn) { auto bus = make_shared>(); - MockScsiController controller(bus, 0); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::reserved); EXPECT_CALL(*bus, SetMSG(true)); @@ -185,7 +193,8 @@ TEST(ScsiControllerTest, MsgIn) TEST(ScsiControllerTest, MsgOut) { auto bus = make_shared>(); - MockScsiController controller(bus, 0); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::reserved); EXPECT_CALL(*bus, SetMSG(true)); @@ -200,7 +209,8 @@ TEST(ScsiControllerTest, MsgOut) TEST(ScsiControllerTest, DataIn) { auto bus = make_shared>(); - MockScsiController controller(bus, 0); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::reserved); controller.SetLength(0); @@ -220,7 +230,8 @@ TEST(ScsiControllerTest, DataIn) TEST(ScsiControllerTest, DataOut) { auto bus = make_shared>(); - MockScsiController controller(bus, 0); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); controller.SetPhase(BUS::phase_t::reserved); controller.SetLength(0); @@ -240,7 +251,8 @@ TEST(ScsiControllerTest, DataOut) TEST(ScsiControllerTest, Error) { auto bus = make_shared>(); - MockScsiController controller(bus, 0); + auto controller_manager = make_shared(*bus); + MockScsiController controller(controller_manager, 0); ON_CALL(*bus, GetRST).WillByDefault(Return(true)); controller.SetPhase(BUS::phase_t::reserved); @@ -282,21 +294,23 @@ TEST(ScsiControllerTest, Error) TEST(ScsiControllerTest, RequestSense) { - MockScsiController controller(make_shared>()); + auto bus = make_shared>(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); auto device = make_shared(0); const unordered_map params; device->Init(params); - controller.AddDevice(device); + controller->AddDevice(device); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // ALLOCATION LENGTH cmd[4] = 255; // Non-existing LUN cmd[1] = 0x20; device->SetReady(true); - EXPECT_CALL(controller, Status); + EXPECT_CALL(*controller, Status); device->Dispatch(scsi_command::eCmdRequestSense); - EXPECT_EQ(status::GOOD, controller.GetStatus()) << "Illegal CHECK CONDITION for non-existing LUN"; + EXPECT_EQ(status::GOOD, controller->GetStatus()) << "Wrong CHECK CONDITION for non-existing LUN"; } diff --git a/cpp/test/scsi_daynaport_test.cpp b/cpp/test/scsi_daynaport_test.cpp index 297800b9..d9352554 100644 --- a/cpp/test/scsi_daynaport_test.cpp +++ b/cpp/test/scsi_daynaport_test.cpp @@ -18,21 +18,25 @@ TEST(ScsiDaynaportTest, Inquiry) TEST(ScsiDaynaportTest, TestUnitReady) { - NiceMock controller(make_shared(), 0); - auto daynaport = CreateDevice(SCDP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = CreateDevice(SCDP, *controller); - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, Status()); daynaport->Dispatch(scsi_command::eCmdTestUnitReady); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(ScsiDaynaportTest, Read) { vector buf(0); - NiceMock controller(make_shared(), 0); - auto daynaport = dynamic_pointer_cast(CreateDevice(SCDP, controller)); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = dynamic_pointer_cast(CreateDevice(SCDP, *controller)); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // ALLOCATION LENGTH cmd[4] = 1; @@ -42,10 +46,12 @@ TEST(ScsiDaynaportTest, Read) TEST(ScsiDaynaportTest, WriteBytes) { vector buf(0); - NiceMock controller(make_shared(), 0); - auto daynaport = dynamic_pointer_cast(CreateDevice(SCDP, controller)); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = dynamic_pointer_cast(CreateDevice(SCDP, *controller)); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // Unknown data format cmd[5] = 0xff; @@ -54,10 +60,12 @@ TEST(ScsiDaynaportTest, WriteBytes) TEST(ScsiDaynaportTest, Read6) { - NiceMock controller(make_shared(), 0); - auto daynaport = CreateDevice(SCDP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = CreateDevice(SCDP, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); cmd[5] = 0xff; EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdRead6); }, Throws(AllOf( @@ -68,10 +76,12 @@ TEST(ScsiDaynaportTest, Read6) TEST(ScsiDaynaportTest, Write6) { - NiceMock controller(make_shared(), 0); - auto daynaport = CreateDevice(SCDP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = CreateDevice(SCDP, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); cmd[5] = 0x00; EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdWrite6); }, Throws(AllOf( @@ -98,23 +108,27 @@ TEST(ScsiDaynaportTest, Write6) TEST(ScsiDaynaportTest, TestRetrieveStats) { - NiceMock controller(make_shared(), 0); - auto daynaport = CreateDevice(SCDP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = CreateDevice(SCDP, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // ALLOCATION LENGTH cmd[4] = 255; - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); daynaport->Dispatch(scsi_command::eCmdRetrieveStats); } TEST(ScsiDaynaportTest, SetInterfaceMode) { - NiceMock controller(make_shared(), 0); - auto daynaport = CreateDevice(SCDP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = CreateDevice(SCDP, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // Unknown interface command EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); }, Throws(AllOf( @@ -123,12 +137,12 @@ TEST(ScsiDaynaportTest, SetInterfaceMode) // Not implemented, do nothing cmd[5] = SCSIDaynaPort::CMD_SCSILINK_SETMODE; - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, Status()); daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); cmd[5] = SCSIDaynaPort::CMD_SCSILINK_SETMAC; - EXPECT_CALL(controller, DataOut()); + EXPECT_CALL(*controller, DataOut()); daynaport->Dispatch(scsi_command::eCmdSetIfaceMode); // Not implemented @@ -152,10 +166,12 @@ TEST(ScsiDaynaportTest, SetInterfaceMode) TEST(ScsiDaynaportTest, SetMcastAddr) { - NiceMock controller(make_shared(), 0); - auto daynaport = CreateDevice(SCDP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = CreateDevice(SCDP, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdSetMcastAddr); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ILLEGAL_REQUEST), @@ -163,16 +179,18 @@ TEST(ScsiDaynaportTest, SetMcastAddr) << "Length of 0 is not supported"; cmd[4] = 1; - EXPECT_CALL(controller, DataOut()); + EXPECT_CALL(*controller, DataOut()); daynaport->Dispatch(scsi_command::eCmdSetMcastAddr); } TEST(ScsiDaynaportTest, EnableInterface) { - NiceMock controller(make_shared(), 0); - auto daynaport = CreateDevice(SCDP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); + auto daynaport = CreateDevice(SCDP, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // Enable EXPECT_THAT([&] { daynaport->Dispatch(scsi_command::eCmdEnableInterface); }, Throws(AllOf( diff --git a/cpp/test/scsi_printer_test.cpp b/cpp/test/scsi_printer_test.cpp index b397fbb1..76430502 100644 --- a/cpp/test/scsi_printer_test.cpp +++ b/cpp/test/scsi_printer_test.cpp @@ -16,8 +16,10 @@ using namespace std; TEST(ScsiPrinterTest, Init) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); unordered_map params; EXPECT_TRUE(printer->Init(params)); @@ -31,12 +33,14 @@ TEST(ScsiPrinterTest, Init) TEST(ScsiPrinterTest, TestUnitReady) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, Status()); printer->Dispatch(scsi_command::eCmdTestUnitReady); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(ScsiPrinterTest, Inquiry) @@ -46,42 +50,50 @@ TEST(ScsiPrinterTest, Inquiry) TEST(ScsiPrinterTest, ReserveUnit) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); - EXPECT_CALL(controller, Status()).Times(1); + EXPECT_CALL(*controller, Status()).Times(1); printer->Dispatch(scsi_command::eCmdReserve6); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(ScsiPrinterTest, ReleaseUnit) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); - EXPECT_CALL(controller, Status()).Times(1); + EXPECT_CALL(*controller, Status()).Times(1); printer->Dispatch(scsi_command::eCmdRelease6); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(ScsiPrinterTest, SendDiagnostic) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); - EXPECT_CALL(controller, Status()).Times(1); + EXPECT_CALL(*controller, Status()).Times(1); printer->Dispatch(scsi_command::eCmdSendDiagnostic); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(ScsiPrinterTest, Print) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); - EXPECT_CALL(controller, DataOut()); + EXPECT_CALL(*controller, DataOut()); printer->Dispatch(scsi_command::eCmdPrint); cmd[3] = 0xff; @@ -94,18 +106,22 @@ TEST(ScsiPrinterTest, Print) TEST(ScsiPrinterTest, StopPrint) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); - EXPECT_CALL(controller, Status()); + EXPECT_CALL(*controller, Status()); printer->Dispatch(scsi_command::eCmdStopPrint); - EXPECT_EQ(status::GOOD, controller.GetStatus()); + EXPECT_EQ(status::GOOD, controller->GetStatus()); } TEST(ScsiPrinterTest, SynchronizeBuffer) { - NiceMock controller(make_shared(), 0); - auto printer = CreateDevice(SCLP, controller); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); EXPECT_THAT([&] { printer->Dispatch(scsi_command::eCmdSynchronizeBuffer); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::ABORTED_COMMAND), @@ -117,8 +133,10 @@ TEST(ScsiPrinterTest, SynchronizeBuffer) TEST(ScsiPrinterTest, WriteByteSequence) { - NiceMock controller(make_shared(), 0); - auto printer = dynamic_pointer_cast(CreateDevice(SCLP, controller)); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto printer = CreateDevice(SCLP, *controller); vector buf(1); EXPECT_TRUE(printer->WriteByteSequence(buf, buf.size())); diff --git a/cpp/test/scsicd_test.cpp b/cpp/test/scsicd_test.cpp index b027b078..bb03e1c6 100644 --- a/cpp/test/scsicd_test.cpp +++ b/cpp/test/scsicd_test.cpp @@ -112,13 +112,15 @@ TEST(ScsiCdTest, Open) TEST(ScsiCdTest, ReadToc) { - MockAbstractController controller(make_shared(), 0); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared(controller_manager, 0); const unordered_set sector_sizes; auto cd = make_shared(0, sector_sizes); const unordered_map params; cd->Init(params); - controller.AddDevice(cd); + controller->AddDevice(cd); EXPECT_THAT([&] { cd->Dispatch(scsi_command::eCmdReadToc); }, Throws(AllOf( Property(&scsi_exception::get_sense_key, sense_key::NOT_READY), diff --git a/cpp/test/test_shared.cpp b/cpp/test/test_shared.cpp index f4532a30..9dc80ae1 100644 --- a/cpp/test/test_shared.cpp +++ b/cpp/test/test_shared.cpp @@ -23,9 +23,8 @@ using namespace filesystem; shared_ptr CreateDevice(PbDeviceType type, MockAbstractController& controller, const string& extension) { DeviceFactory device_factory; - auto controller_manager = make_shared(controller.GetBus()); - auto device = device_factory.CreateDevice(*controller_manager, type, 0, extension); + auto device = device_factory.CreateDevice(type, 0, extension); unordered_map params; device->Init(params); @@ -37,16 +36,18 @@ shared_ptr CreateDevice(PbDeviceType type, MockAbstractController void TestInquiry(PbDeviceType type, device_type t, scsi_level l, const string& ident, int additional_length, bool removable, const string& extension) { - NiceMock controller(make_shared(), 0); - auto device = CreateDevice(type, controller, extension); + auto bus = make_shared(); + auto controller_manager = make_shared(*bus); + auto controller = make_shared>(controller_manager, 0); + auto device = CreateDevice(type, *controller, extension); - auto& cmd = controller.GetCmd(); + auto& cmd = controller->GetCmd(); // ALLOCATION LENGTH cmd[4] = 255; - EXPECT_CALL(controller, DataIn()); + EXPECT_CALL(*controller, DataIn()); device->Dispatch(scsi_command::eCmdInquiry); - const vector& buffer = controller.GetBuffer(); + const vector& buffer = controller->GetBuffer(); EXPECT_EQ(t, static_cast(buffer[0])); EXPECT_EQ(removable ? 0x80: 0x00, buffer[1]); EXPECT_EQ(l, static_cast(buffer[2]));