mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-21 23:29:39 +00:00
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:
parent
41ddc5fc33
commit
7fc84c4217
@ -64,6 +64,7 @@ RASCTL = rasctl
|
|||||||
RASDUMP = rasdump
|
RASDUMP = rasdump
|
||||||
SASIDUMP = sasidump
|
SASIDUMP = sasidump
|
||||||
SCSIMON = scsimon
|
SCSIMON = scsimon
|
||||||
|
RASCSI_TEST = rascsi_test
|
||||||
|
|
||||||
SYSTEMD_CONF = /etc/systemd/system/rascsi.service
|
SYSTEMD_CONF = /etc/systemd/system/rascsi.service
|
||||||
RSYSLOG_CONF = /etc/rsyslog.d/rascsi.conf
|
RSYSLOG_CONF = /etc/rsyslog.d/rascsi.conf
|
||||||
@ -90,21 +91,22 @@ SRC_PROTOC = \
|
|||||||
SRC_PROTOBUF = \
|
SRC_PROTOBUF = \
|
||||||
rascsi_interface.pb.cpp
|
rascsi_interface.pb.cpp
|
||||||
|
|
||||||
SRC_RASCSI = \
|
SRC_RASCSI_CORE = scsi.cpp \
|
||||||
rascsi.cpp \
|
|
||||||
scsi.cpp \
|
|
||||||
gpiobus.cpp \
|
gpiobus.cpp \
|
||||||
filepath.cpp \
|
filepath.cpp \
|
||||||
fileio.cpp\
|
fileio.cpp \
|
||||||
rascsi_version.cpp \
|
rascsi_version.cpp \
|
||||||
rascsi_image.cpp \
|
rascsi_image.cpp \
|
||||||
rascsi_response.cpp \
|
rascsi_response.cpp \
|
||||||
rasutil.cpp \
|
rasutil.cpp \
|
||||||
protobuf_util.cpp \
|
protobuf_util.cpp \
|
||||||
localizer.cpp
|
localizer.cpp
|
||||||
SRC_RASCSI += $(shell find ./controllers -name '*.cpp')
|
SRC_RASCSI_CORE += $(shell find ./controllers -name '*.cpp')
|
||||||
SRC_RASCSI += $(shell find ./devices -name '*.cpp')
|
SRC_RASCSI_CORE += $(shell find ./devices -name '*.cpp')
|
||||||
SRC_RASCSI += $(SRC_PROTOBUF)
|
SRC_RASCSI_CORE += $(SRC_PROTOBUF)
|
||||||
|
|
||||||
|
SRC_RASCSI = rascsi.cpp
|
||||||
|
SRC_RASCSI += $(SRC_RASCSI_CORE)
|
||||||
|
|
||||||
SRC_SCSIMON = \
|
SRC_SCSIMON = \
|
||||||
scsimon.cpp \
|
scsimon.cpp \
|
||||||
@ -128,7 +130,7 @@ SRC_RASDUMP = \
|
|||||||
scsi.cpp \
|
scsi.cpp \
|
||||||
gpiobus.cpp \
|
gpiobus.cpp \
|
||||||
filepath.cpp \
|
filepath.cpp \
|
||||||
fileio.cpp\
|
fileio.cpp \
|
||||||
rascsi_version.cpp
|
rascsi_version.cpp
|
||||||
|
|
||||||
SRC_SASIDUMP = \
|
SRC_SASIDUMP = \
|
||||||
@ -136,11 +138,16 @@ SRC_SASIDUMP = \
|
|||||||
scsi.cpp \
|
scsi.cpp \
|
||||||
gpiobus.cpp \
|
gpiobus.cpp \
|
||||||
filepath.cpp \
|
filepath.cpp \
|
||||||
fileio.cpp\
|
fileio.cpp \
|
||||||
rascsi_version.cpp
|
rascsi_version.cpp
|
||||||
|
|
||||||
|
|
||||||
|
SRC_RASCSI_TEST = $(shell find ./test -name '*.cpp')
|
||||||
|
SRC_RASCSI_TEST += $(SRC_RASCSI_CORE)
|
||||||
|
|
||||||
|
|
||||||
vpath %.h ./ ./controllers ./devices ./monitor
|
vpath %.h ./ ./controllers ./devices ./monitor
|
||||||
vpath %.cpp ./ ./controllers ./devices ./monitor
|
vpath %.cpp ./ ./controllers ./devices ./monitor ./test
|
||||||
vpath %.o ./$(OBJDIR)
|
vpath %.o ./$(OBJDIR)
|
||||||
vpath ./$(BINDIR)
|
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_RASDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASDUMP:%.cpp=%.o)))
|
||||||
OBJ_SASIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SASIDUMP:%.cpp=%.o)))
|
OBJ_SASIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SASIDUMP:%.cpp=%.o)))
|
||||||
OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.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
|
GEN_PROTOBUF := $(SRC_PROTOBUF) rascsi_interface.pb.h
|
||||||
|
|
||||||
|
|
||||||
# The following will include all of the auto-generated dependency files (*.d)
|
# 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
|
# 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)
|
-include $(ALL_DEPS)
|
||||||
|
|
||||||
$(OBJDIR) $(BINDIR):
|
$(OBJDIR) $(BINDIR):
|
||||||
@ -180,6 +188,9 @@ $(SRC_PROTOBUF): $(SRC_PROTOC)
|
|||||||
all: $(BIN_ALL) docs
|
all: $(BIN_ALL) docs
|
||||||
ALL: all
|
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
|
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)
|
$(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI) | $(BINDIR)
|
||||||
@ -197,6 +208,9 @@ $(BINDIR)/$(SASIDUMP): $(OBJ_SASIDUMP) | $(BINDIR)
|
|||||||
$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) | $(BINDIR)
|
$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) | $(BINDIR)
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) -lpthread
|
$(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 rules for building individual utilities
|
||||||
.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP) $(SCSIMON)
|
.PHONY: $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP) $(SCSIMON)
|
||||||
|
@ -26,7 +26,6 @@ class Device;
|
|||||||
|
|
||||||
class DeviceFactory
|
class DeviceFactory
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
DeviceFactory();
|
DeviceFactory();
|
||||||
~DeviceFactory() {}
|
~DeviceFactory() {}
|
||||||
|
|
||||||
|
@ -34,12 +34,15 @@ public:
|
|||||||
|
|
||||||
bool SupportsFile() const override { return false; }
|
bool SupportsFile() const override { return false; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void AddModePages(map<int, vector<BYTE>>&, int, bool) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef ModePageDevice super;
|
typedef ModePageDevice super;
|
||||||
|
|
||||||
Dispatcher<HostServices, SCSIDEV> dispatcher;
|
Dispatcher<HostServices, SCSIDEV> dispatcher;
|
||||||
|
|
||||||
void AddModePages(map<int, vector<BYTE>>&, int, bool) const override;
|
|
||||||
void AddRealtimeClockPage(map<int, vector<BYTE>>&, bool) const;
|
void AddRealtimeClockPage(map<int, vector<BYTE>>&, bool) const;
|
||||||
};
|
};
|
||||||
|
286
src/raspberrypi/test/device_factory_test.cpp
Normal file
286
src/raspberrypi/test/device_factory_test.cpp
Normal 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
72
src/raspberrypi/test/device_test.cpp
Normal file
72
src/raspberrypi/test/device_test.cpp
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
184
src/raspberrypi/test/mode_pages_test.cpp
Normal file
184
src/raspberrypi/test/mode_pages_test.cpp
Normal 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user