Initial unit tests based on GoogleTest and GoogleMock (#802)

* Initial dummy test

* Makefile update

* Make protected method visible

* Test update

* Test update

* Updated mode page device

* Only build tests with explicit test target

* make test builds and executes tests

* Replaced constant

* Added TODO

* Merged develop

* Added unit test

* Comment update

* Unit test update

* Added tests

* Added tests

* Test cleanup

* Updated error handling

* Reverted MODE SENSE change

* Reverted last change

* Use GoogleMock

* Comment update

* Signature update

* Cleanup

* Cleanup

* Further cleanup

* Removed obsolete comment

* Updated error handling

* Cleanup

* Added TODO

* Added test

* Added test

* Renaming

* Added test

* Cleanup

* Header update

* Added two tests

* Renaming

* Fixed test argument order

* Namespaces are needed in order to avoid name clashes

* Added test

* Added tests

* Added tests

* Added tests

* Added tests

* Updated host services test

* Merge with develop

* Moved code

* Renaming

* Added tests

* Added tests

* Initial device tests

* Test cleanup

* Added test

* Removed cast

* RASCSI_TEST target has to depend on SRC_PROTOBUF
This commit is contained in:
Uwe Seimet 2022-08-28 19:25:08 +02:00 committed by GitHub
parent 41ddc5fc33
commit 7fc84c4217
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 571 additions and 13 deletions

View File

@ -64,6 +64,7 @@ RASCTL = rasctl
RASDUMP = rasdump
SASIDUMP = sasidump
SCSIMON = scsimon
RASCSI_TEST = rascsi_test
SYSTEMD_CONF = /etc/systemd/system/rascsi.service
RSYSLOG_CONF = /etc/rsyslog.d/rascsi.conf
@ -90,21 +91,22 @@ SRC_PROTOC = \
SRC_PROTOBUF = \
rascsi_interface.pb.cpp
SRC_RASCSI = \
rascsi.cpp \
scsi.cpp \
SRC_RASCSI_CORE = scsi.cpp \
gpiobus.cpp \
filepath.cpp \
fileio.cpp\
fileio.cpp \
rascsi_version.cpp \
rascsi_image.cpp \
rascsi_response.cpp \
rasutil.cpp \
protobuf_util.cpp \
localizer.cpp
SRC_RASCSI += $(shell find ./controllers -name '*.cpp')
SRC_RASCSI += $(shell find ./devices -name '*.cpp')
SRC_RASCSI += $(SRC_PROTOBUF)
SRC_RASCSI_CORE += $(shell find ./controllers -name '*.cpp')
SRC_RASCSI_CORE += $(shell find ./devices -name '*.cpp')
SRC_RASCSI_CORE += $(SRC_PROTOBUF)
SRC_RASCSI = rascsi.cpp
SRC_RASCSI += $(SRC_RASCSI_CORE)
SRC_SCSIMON = \
scsimon.cpp \
@ -128,7 +130,7 @@ SRC_RASDUMP = \
scsi.cpp \
gpiobus.cpp \
filepath.cpp \
fileio.cpp\
fileio.cpp \
rascsi_version.cpp
SRC_SASIDUMP = \
@ -136,11 +138,16 @@ SRC_SASIDUMP = \
scsi.cpp \
gpiobus.cpp \
filepath.cpp \
fileio.cpp\
fileio.cpp \
rascsi_version.cpp
SRC_RASCSI_TEST = $(shell find ./test -name '*.cpp')
SRC_RASCSI_TEST += $(SRC_RASCSI_CORE)
vpath %.h ./ ./controllers ./devices ./monitor
vpath %.cpp ./ ./controllers ./devices ./monitor
vpath %.cpp ./ ./controllers ./devices ./monitor ./test
vpath %.o ./$(OBJDIR)
vpath ./$(BINDIR)
@ -150,13 +157,14 @@ OBJ_RASCTL := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASCTL:%.cpp=%.o)))
OBJ_RASDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASDUMP:%.cpp=%.o)))
OBJ_SASIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SASIDUMP:%.cpp=%.o)))
OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.cpp=%.o)))
OBJ_RASCSI_TEST := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASCSI_TEST:%.cpp=%.o)))
GEN_PROTOBUF := $(SRC_PROTOBUF) rascsi_interface.pb.h
# The following will include all of the auto-generated dependency files (*.d)
# if they exist. This will trigger a rebuild of a source file if a header changes
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_SCSIMON))
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_SCSIMON) $(OBJ_RASCSI_TEST))
-include $(ALL_DEPS)
$(OBJDIR) $(BINDIR):
@ -180,6 +188,9 @@ $(SRC_PROTOBUF): $(SRC_PROTOC)
all: $(BIN_ALL) docs
ALL: all
test: $(BINDIR)/$(RASCSI_TEST)
$(BINDIR)/$(RASCSI_TEST)
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt
$(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI) | $(BINDIR)
@ -197,6 +208,9 @@ $(BINDIR)/$(SASIDUMP): $(OBJ_SASIDUMP) | $(BINDIR)
$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) -lpthread
$(BINDIR)/$(RASCSI_TEST): $(SRC_PROTOBUF) $(OBJ_RASCSI_TEST) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI_TEST) -lpcap -lprotobuf -lgmock -lgtest -lgtest_main
# Phony rules for building individual utilities
.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP) $(SCSIMON)

View File

@ -26,7 +26,6 @@ class Device;
class DeviceFactory
{
private:
DeviceFactory();
~DeviceFactory() {}

View File

@ -34,12 +34,15 @@ public:
bool SupportsFile() const override { return false; }
protected:
void AddModePages(map<int, vector<BYTE>>&, int, bool) const override;
private:
typedef ModePageDevice super;
Dispatcher<HostServices, SCSIDEV> dispatcher;
void AddModePages(map<int, vector<BYTE>>&, int, bool) const override;
void AddRealtimeClockPage(map<int, vector<BYTE>>&, bool) const;
};

View File

@ -0,0 +1,286 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2022 Uwe Seimet
//
// Unit tests based on GoogleTest and GoogleMock
//
//---------------------------------------------------------------------------
#include <gtest/gtest.h>
#include "rascsi_version.h"
#include "../devices/device.h"
#include "../devices/device_factory.h"
using namespace rascsi_interface;
namespace DeviceFactoryTest
{
DeviceFactory& device_factory = DeviceFactory::instance();
TEST(DeviceFactoryTest, GetTypeForFile)
{
EXPECT_EQ(device_factory.GetTypeForFile("test.hdf"), SAHD);
EXPECT_EQ(device_factory.GetTypeForFile("test.hds"), SCHD);
EXPECT_EQ(device_factory.GetTypeForFile("test.HDS"), SCHD);
EXPECT_EQ(device_factory.GetTypeForFile("test.hda"), SCHD);
EXPECT_EQ(device_factory.GetTypeForFile("test.hdn"), SCHD);
EXPECT_EQ(device_factory.GetTypeForFile("test.hdi"), SCHD);
EXPECT_EQ(device_factory.GetTypeForFile("test.nhd"), SCHD);
EXPECT_EQ(device_factory.GetTypeForFile("test.hdr"), SCRM);
EXPECT_EQ(device_factory.GetTypeForFile("test.mos"), SCMO);
EXPECT_EQ(device_factory.GetTypeForFile("test.iso"), SCCD);
EXPECT_EQ(device_factory.GetTypeForFile("test.suffix.iso"), SCCD);
EXPECT_EQ(device_factory.GetTypeForFile("bridge"), SCBR);
EXPECT_EQ(device_factory.GetTypeForFile("daynaport"), SCDP);
EXPECT_EQ(device_factory.GetTypeForFile("printer"), SCLP);
EXPECT_EQ(device_factory.GetTypeForFile("services"), SCHS);
EXPECT_EQ(device_factory.GetTypeForFile("unknown"), UNDEFINED);
EXPECT_EQ(device_factory.GetTypeForFile("test.iso.suffix"), UNDEFINED);
}
TEST(DeviceFactoryTest, GetSectorSizes)
{
unordered_set<uint32_t> sector_sizes;
sector_sizes = device_factory.GetSectorSizes("SCHD");
EXPECT_EQ(4, sector_sizes.size());
sector_sizes = device_factory.GetSectorSizes(SCHD);
EXPECT_EQ(4, sector_sizes.size());
EXPECT_TRUE(sector_sizes.find(512) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(1024) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(2048) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(4096) != sector_sizes.end());
sector_sizes = device_factory.GetSectorSizes("SCRM");
EXPECT_EQ(4, sector_sizes.size());
sector_sizes = device_factory.GetSectorSizes(SCRM);
EXPECT_EQ(4, sector_sizes.size());
EXPECT_TRUE(sector_sizes.find(512) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(1024) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(2048) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(4096) != sector_sizes.end());
sector_sizes = device_factory.GetSectorSizes("SCMO");
EXPECT_EQ(4, sector_sizes.size());
sector_sizes = device_factory.GetSectorSizes(SCMO);
EXPECT_EQ(4, sector_sizes.size());
EXPECT_TRUE(sector_sizes.find(512) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(1024) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(2048) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(4096) != sector_sizes.end());
sector_sizes = device_factory.GetSectorSizes("SCCD");
EXPECT_EQ(2, sector_sizes.size());
sector_sizes = device_factory.GetSectorSizes(SCCD);
EXPECT_EQ(2, sector_sizes.size());
EXPECT_TRUE(sector_sizes.find(512) != sector_sizes.end());
EXPECT_TRUE(sector_sizes.find(2048) != sector_sizes.end());
}
TEST(DeviceFactoryTest, UnknownDeviceType)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test");
EXPECT_EQ(nullptr, device);
}
TEST(DeviceFactoryTest, SCHD_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.hda");
EXPECT_NE(nullptr, device);
EXPECT_TRUE(device->SupportsFile());
EXPECT_FALSE(device->SupportsParams());
EXPECT_TRUE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_FALSE(device->IsReadOnly());
EXPECT_FALSE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_FALSE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_TRUE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("QUANTUM", device->GetVendor()) << "Invalid default vendor for Apple drive";
EXPECT_EQ("FIREBALL", device->GetProduct()) << "Invalid default vendor for Apple drive";
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
TEST(DeviceFactoryTest, SCRM_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.hdr");
EXPECT_NE(nullptr, device);
EXPECT_TRUE(device->SupportsFile());
EXPECT_FALSE(device->SupportsParams());
EXPECT_TRUE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_FALSE(device->IsReadOnly());
EXPECT_TRUE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_TRUE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_TRUE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("RaSCSI", device->GetVendor());
EXPECT_EQ("SCSI HD (REM.)", device->GetProduct());
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
TEST(DeviceFactoryTest, SCMO_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.mos");
EXPECT_NE(nullptr, device);
EXPECT_TRUE(device->SupportsFile());
EXPECT_FALSE(device->SupportsParams());
EXPECT_TRUE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_FALSE(device->IsReadOnly());
EXPECT_TRUE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_TRUE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_TRUE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("RaSCSI", device->GetVendor());
EXPECT_EQ("SCSI MO", device->GetProduct());
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
TEST(DeviceFactoryTest, SCCD_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.iso");
EXPECT_NE(nullptr, device);
EXPECT_TRUE(device->SupportsFile());
EXPECT_FALSE(device->SupportsParams());
EXPECT_FALSE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_TRUE(device->IsReadOnly());
EXPECT_TRUE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_TRUE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_TRUE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("RaSCSI", device->GetVendor());
EXPECT_EQ("SCSI CD-ROM", device->GetProduct());
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
TEST(DeviceFactoryTest, SCBR_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "bridge");
EXPECT_NE(nullptr, device);
EXPECT_FALSE(device->SupportsFile());
EXPECT_TRUE(device->SupportsParams());
EXPECT_FALSE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_FALSE(device->IsReadOnly());
EXPECT_FALSE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_FALSE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_FALSE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("RaSCSI", device->GetVendor());
EXPECT_EQ("SCSI HOST BRIDGE", device->GetProduct());
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
TEST(DeviceFactoryTest, SCDP_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "daynaport");
EXPECT_NE(nullptr, device);
EXPECT_FALSE(device->SupportsFile());
EXPECT_TRUE(device->SupportsParams());
EXPECT_FALSE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_FALSE(device->IsReadOnly());
EXPECT_FALSE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_FALSE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_FALSE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("Dayna", device->GetVendor());
EXPECT_EQ("SCSI/Link", device->GetProduct());
EXPECT_EQ("1.4a", device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
TEST(DeviceFactoryTest, SCHS_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "services");
EXPECT_NE(nullptr, device);
EXPECT_FALSE(device->SupportsFile());
EXPECT_FALSE(device->SupportsParams());
EXPECT_FALSE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_FALSE(device->IsReadOnly());
EXPECT_FALSE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_FALSE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_FALSE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("RaSCSI", device->GetVendor());
EXPECT_EQ("Host Services", device->GetProduct());
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
TEST(DeviceFactoryTest, SCLP_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "printer");
EXPECT_NE(nullptr, device);
EXPECT_FALSE(device->SupportsFile());
EXPECT_TRUE(device->SupportsParams());
EXPECT_FALSE(device->IsProtectable());
EXPECT_FALSE(device->IsProtected());
EXPECT_FALSE(device->IsReadOnly());
EXPECT_FALSE(device->IsRemovable());
EXPECT_FALSE(device->IsRemoved());
EXPECT_FALSE(device->IsLockable());
EXPECT_FALSE(device->IsLocked());
EXPECT_FALSE(device->IsStoppable());
EXPECT_FALSE(device->IsStopped());
EXPECT_EQ("RaSCSI", device->GetVendor());
EXPECT_EQ("SCSI PRINTER", device->GetProduct());
EXPECT_EQ(string(rascsi_get_version_string()).substr(0, 2) + string(rascsi_get_version_string()).substr(3, 2),
device->GetRevision());
EXPECT_EQ(32, device->GetSupportedLuns());
}
}

View File

@ -0,0 +1,72 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2022 Uwe Seimet
//
// Unit tests based on GoogleTest and GoogleMock
//
//---------------------------------------------------------------------------
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "gpiobus.h"
#include "../devices/scsihd.h"
#include "../devices/device_factory.h"
using namespace rascsi_interface;
namespace DeviceTest
{
class MockController : public SCSIDEV
{
MOCK_METHOD(BUS::phase_t, Process, (int), (override));
MOCK_METHOD(int, GetEffectiveLun, (), ());
MOCK_METHOD(void, Error, (scsi_defs::sense_key, scsi_defs::asc, scsi_defs::status), (override));
MOCK_METHOD(int, GetInitiatorId, (), ());
MOCK_METHOD(void, SetUnit, (int), ());
MOCK_METHOD(void, Connect, (int, BUS *), ());
MOCK_METHOD(void, Status, (), ());
MOCK_METHOD(void, DataIn, (), ());
MOCK_METHOD(void, DataOut, (), ());
MOCK_METHOD(void, BusFree, (), ());
MOCK_METHOD(void, Selection, (), ());
MOCK_METHOD(void, Command, (), ());
MOCK_METHOD(void, MsgIn, (), ());
MOCK_METHOD(void, MsgOut, (), ());
MOCK_METHOD(void, Send, (), (override));
MOCK_METHOD(bool, XferMsg, (int), ());
MOCK_METHOD(bool, XferIn, (BYTE *), ());
MOCK_METHOD(bool, XferOut, (bool), (override));
MOCK_METHOD(void, ReceiveBytes, (), ());
MOCK_METHOD(void, Execute, (), (override));
MOCK_METHOD(void, FlushUnit, (), ());
MOCK_METHOD(void, Receive, (), (override));
MOCK_METHOD(bool, HasUnit, (), (const override));
FRIEND_TEST(DeviceTest, TestUnitReady);
MockController() { }
~MockController() { }
};
DeviceFactory& device_factory = DeviceFactory::instance();
TEST(DeviceTest, TestUnitReady)
{
MockController controller;
Device *device = device_factory.CreateDevice(SCHD, "test");
controller.ctrl.cmd[0] = eCmdTestUnitReady;
device->SetReady(false);
EXPECT_CALL(controller, Error);
EXPECT_TRUE(device->Dispatch(&controller));
// TODO Add tests for a device that is ready after the SASI code removal
}
}

View File

@ -0,0 +1,184 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2022 Uwe Seimet
//
// Unit tests based on GoogleTest and GoogleMock
//
//---------------------------------------------------------------------------
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "../devices/scsihd.h"
#include "../devices/scsihd_nec.h"
#include "../devices/scsicd.h"
#include "../devices/scsimo.h"
#include "../devices/host_services.h"
using namespace std;
namespace ModePagesTest
{
unordered_set<uint32_t> sector_sizes;
class MockModePageDevice : public ModePageDevice
{
public:
MockModePageDevice() : ModePageDevice("test") { }
~MockModePageDevice() { }
MOCK_METHOD(vector<BYTE>, Inquiry, (), (const, override));
MOCK_METHOD(int, ModeSense6, (const DWORD *, BYTE *), (override));
MOCK_METHOD(int, ModeSense10, (const DWORD *, BYTE *, int), (override));
void AddModePages(map<int, vector<BYTE>>& pages, int page, bool) const override {
// Return dummy data for other pages than page 0
if (page) {
vector<BYTE> buf(255);
pages[page] = buf;
}
}
// Make protected methods visible for testing
// TODO Why does FRIEND_TEST not work for this method?
int AddModePages(const DWORD *cdb, BYTE *buf, int max_length) {
return ModePageDevice::AddModePages(cdb, buf, max_length);
}
};
class MockSCSIHD : public SCSIHD
{
FRIEND_TEST(ModePagesTest, SCSIHD_AddModePages);
MockSCSIHD(const unordered_set<uint32_t>& sector_sizes) : SCSIHD(sector_sizes, false) { };
~MockSCSIHD() { };
};
class MockSCSIHD_NEC : public SCSIHD_NEC
{
FRIEND_TEST(ModePagesTest, SCSIHD_NEC_AddModePages);
MockSCSIHD_NEC(const unordered_set<uint32_t>& sector_sizes) : SCSIHD_NEC(sector_sizes) { };
~MockSCSIHD_NEC() { };
};
class MockSCSICD : public SCSICD
{
FRIEND_TEST(ModePagesTest, SCSICD_AddModePages);
MockSCSICD(const unordered_set<uint32_t>& sector_sizes) : SCSICD(sector_sizes) { };
~MockSCSICD() { };
};
class MockSCSIMO : public SCSIMO
{
FRIEND_TEST(ModePagesTest, SCSIMO_AddModePages);
MockSCSIMO(const unordered_set<uint32_t>& sector_sizes, const unordered_map<uint64_t, Geometry>& geometries)
: SCSIMO(sector_sizes, geometries) { };
~MockSCSIMO() { };
};
class MockHostServices : public HostServices
{
FRIEND_TEST(ModePagesTest, HostServices_AddModePages);
MockHostServices() { };
~MockHostServices() { };
};
TEST(ModePagesTest, ModePageDevice_AddModePages)
{
DWORD cdb[6];
BYTE buf[512];
MockModePageDevice device;
cdb[2] = 0x3f;
EXPECT_EQ(1, device.AddModePages(cdb, buf, 1)) << "Allocation length was not limited";
cdb[2] = 0x00;
EXPECT_EQ(0, device.AddModePages(cdb, buf, 12)) << "Data for non-existing code page 0 were returned";
}
TEST(ModePagesTest, SCSIHD_AddModePages)
{
map<int, vector<BYTE>> mode_pages;
MockSCSIHD device(sector_sizes);
device.AddModePages(mode_pages, 0x3f, false);
EXPECT_EQ(5, mode_pages.size()) << "Unexpected number of code pages";
EXPECT_EQ(12, mode_pages[1].size());
EXPECT_EQ(24, mode_pages[3].size());
EXPECT_EQ(24, mode_pages[4].size());
EXPECT_EQ(12, mode_pages[8].size());
EXPECT_EQ(30, mode_pages[48].size());
}
TEST(ModePagesTest, SCSIHD_NEC_AddModePages)
{
map<int, vector<BYTE>> mode_pages;
MockSCSIHD_NEC device(sector_sizes);
device.AddModePages(mode_pages, 0x3f, false);
EXPECT_EQ(5, mode_pages.size()) << "Unexpected number of code pages";
EXPECT_EQ(8, mode_pages[1].size());
EXPECT_EQ(24, mode_pages[3].size());
EXPECT_EQ(20, mode_pages[4].size());
EXPECT_EQ(12, mode_pages[8].size());
EXPECT_EQ(30, mode_pages[48].size());
}
TEST(ModePagesTest, SCSICD_AddModePages)
{
map<int, vector<BYTE>> mode_pages;
MockSCSICD device(sector_sizes);
device.AddModePages(mode_pages, 0x3f, false);
EXPECT_EQ(6, mode_pages.size()) << "Unexpected number of code pages";
EXPECT_EQ(12, mode_pages[1].size());
EXPECT_EQ(24, mode_pages[3].size());
EXPECT_EQ(24, mode_pages[4].size());
EXPECT_EQ(12, mode_pages[8].size());
EXPECT_EQ(8, mode_pages[13].size());
EXPECT_EQ(16, mode_pages[14].size());
}
TEST(ModePagesTest, SCSIMO_AddModePages)
{
map<int, vector<BYTE>> mode_pages;
unordered_map<uint64_t, Geometry> geometries;
MockSCSIMO device(sector_sizes, geometries);
device.AddModePages(mode_pages, 0x3f, false);
EXPECT_EQ(6, mode_pages.size()) << "Unexpected number of code pages";
EXPECT_EQ(12, mode_pages[1].size());
EXPECT_EQ(24, mode_pages[3].size());
EXPECT_EQ(24, mode_pages[4].size());
EXPECT_EQ(4, mode_pages[6].size());
EXPECT_EQ(12, mode_pages[8].size());
EXPECT_EQ(12, mode_pages[32].size());
}
TEST(ModePagesTest, HostServices_AddModePages)
{
map<int, vector<BYTE>> mode_pages;
MockHostServices device;
device.AddModePages(mode_pages, 0x3f, false);
EXPECT_EQ(1, mode_pages.size()) << "Unexpected number of code pages";
EXPECT_EQ(10, mode_pages[32].size());
}
}