Commit d4afab27 authored by Eric Cano's avatar Eric Cano
Browse files

Added a dependancy between the test and real system wrappers.

As a consequence, removed the templatisation of Tape::Drive* and SCSI::DeviceVector
Moved much of their functions from .hh to .cc (thanks to end of templatisation).
Removed copilation options from many .cc after moving Tape::System::mockWrapper::mockWrapper to a .cc.
parent b47f3258
add_library(TapeDrive Drive.cc)
set_property(SOURCE Drive.cc
PROPERTY COMPILE_FLAGS -fno-strict-aliasing
)
add_executable(TapeDriveInfo TapeDriveInfo.cc)
set_property(SOURCE TapeDriveInfo.cc
PROPERTY COMPILE_FLAGS -fno-strict-aliasing
)
target_link_libraries(TapeDriveInfo Exception SCSI System Utils ${GTEST_LIBRARY} gmock pthread)
target_link_libraries(TapeDriveInfo TapeDrive Exception SCSI System Utils ${GTEST_LIBRARY} gmock pthread)
install(TARGETS TapeDriveInfo
RUNTIME DESTINATION bin)
This diff is collapsed.
This diff is collapsed.
......@@ -54,11 +54,11 @@ TEST(TapeDrive, OpensCorrectly) {
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
/* Test: detect devices, then open the device files */
SCSI::DeviceVector<Tape::System::mockWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive<Tape::System::mockWrapper> drive(*i, sysWrapper);
Tape::Drive drive(*i, sysWrapper);
}
}
}
......@@ -83,11 +83,11 @@ TEST(TapeDrive, getPositionInfoAndPositionToLogicalObject) {
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
/* Test: detect devices, then open the device files */
SCSI::DeviceVector<Tape::System::mockWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive<Tape::System::mockWrapper> drive(*i, sysWrapper);
Tape::Drive drive(*i, sysWrapper);
Tape::positionInfo posInfo;
EXPECT_CALL(sysWrapper, ioctl(_,_,An<sg_io_hdr_t*>())).Times(1);
......@@ -131,11 +131,11 @@ TEST(TapeDrive, setDensityAndCompression) {
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
/* Test: detect devices, then open the device files */
SCSI::DeviceVector<Tape::System::mockWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive<Tape::System::mockWrapper> drive(*i, sysWrapper);
Tape::Drive drive(*i, sysWrapper);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<sg_io_hdr_t*>())).Times(2);
drive.setDensityAndCompression();
......@@ -175,10 +175,10 @@ TEST(TapeDrive, setStDriverOptions) {
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
/* Test: detect devices, then open the device files */
SCSI::DeviceVector<Tape::System::mockWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin(); i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive<Tape::System::mockWrapper> drive(*i, sysWrapper);
Tape::Drive drive(*i, sysWrapper);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<struct mtop *>())).Times(1);
drive.setSTBufferWrite(true);
......@@ -215,11 +215,11 @@ TEST(TapeDrive, getDeviceInfo) {
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
/* Test: detect devices, then open the device files */
SCSI::DeviceVector<Tape::System::mockWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive<Tape::System::mockWrapper> drive(*i, sysWrapper);
Tape::Drive drive(*i, sysWrapper);
Tape::deviceInfo devInfo;
EXPECT_CALL(sysWrapper, ioctl(_,_,An<sg_io_hdr_t*>())).Times(2);
......@@ -253,15 +253,15 @@ TEST(TapeDrive, getCompressionAndClearCompressionStats) {
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
/* Test: detect devices, then open the device files */
SCSI::DeviceVector<Tape::System::mockWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive<Tape::System::mockWrapper> *drive;
Tape::Drive *drive;
Tape::compressionStats comp;
{
drive = new Tape::DriveT10000<Tape::System::mockWrapper>(*i, sysWrapper);
drive = new Tape::DriveT10000(*i, sysWrapper);
EXPECT_CALL(sysWrapper, ioctl(_, _, An<sg_io_hdr_t*>())).Times(1);
comp = drive->getCompression();
......@@ -283,7 +283,7 @@ TEST(TapeDrive, getCompressionAndClearCompressionStats) {
delete drive;
}
{
drive = new Tape::DriveIBM3592<Tape::System::mockWrapper>(*i, sysWrapper);
drive = new Tape::DriveIBM3592(*i, sysWrapper);
EXPECT_CALL(sysWrapper, ioctl(_, _, An<sg_io_hdr_t*>())).Times(1);
comp = drive->getCompression();
......@@ -305,7 +305,7 @@ TEST(TapeDrive, getCompressionAndClearCompressionStats) {
delete drive;
}
{
drive = new Tape::DriveLTO<Tape::System::mockWrapper>(*i, sysWrapper);
drive = new Tape::DriveLTO(*i, sysWrapper);
EXPECT_CALL(sysWrapper, ioctl(_, _, An<sg_io_hdr_t*>())).Times(1);
comp = drive->getCompression();
......
......@@ -33,13 +33,13 @@
int main ()
{
Tape::System::realWrapper sWrapper;
SCSI::DeviceVector<Tape::System::realWrapper> dl(sWrapper);
for(SCSI::DeviceVector<Tape::System::realWrapper>::iterator i = dl.begin();
SCSI::DeviceVector dl(sWrapper);
for(SCSI::DeviceVector::iterator i = dl.begin();
i != dl.end(); i++) {
SCSI::DeviceInfo & dev = (*i);
std::cout << dev.sg_dev << std::endl;
if (dev.type == SCSI::Types::tape) {
Tape::Drive<Tape::System::realWrapper> drive(dev,sWrapper);
Tape::Drive drive(dev,sWrapper);
drive.SCSI_inquiry();
std::vector<std::string> Alerts(drive.getTapeAlerts());
while (Alerts.size()) {
......
add_library(SCSI Device.cc Structures.cc Constants.cc Exception.cc)
#add_executable(SCSIDumpTest DumpTest.cc)
#target_link_libraries(SCSIDumpTest SCSI)
......@@ -24,4 +24,173 @@
#include <cstdlib>
#include <scsi/sg.h>
#include "Device.hh"
/**
* Fill up the array that the device list is with all the system's
* SCSI devices information.
*
* (all code using templates must be in the header file)
*/
SCSI::DeviceVector::DeviceVector(Tape::System::virtualWrapper& sysWrapper) : m_sysWrapper(sysWrapper) {
std::string sysDevsPath = "/sys/bus/scsi/devices";
DIR* dirp = m_sysWrapper.opendir(sysDevsPath.c_str());
if (!dirp) throw Tape::Exceptions::Errnum("Error opening sysfs scsi devs");
while (struct dirent * dent = m_sysWrapper.readdir(dirp)) {
std::string dn(dent->d_name);
if ("." == dn || ".." == dn) continue;
std::string fullpath = sysDevsPath + "/" + std::string(dent->d_name);
/* We expect only symbolic links in this directory, */
char rp[PATH_MAX];
if (NULL == m_sysWrapper.realpath(fullpath.c_str(), rp))
throw Tape::Exceptions::Errnum("Could not find realpath for " + fullpath);
this->push_back(getDeviceInfo(rp));
}
sysWrapper.closedir(dirp);
}
std::string SCSI::DeviceVector::readfile(std::string path) {
int fd = m_sysWrapper.open(path.c_str(), 0);
if (-1 == fd) {
throw Tape::Exceptions::Errnum("Could not open file " + path);
}
char buf[readfileBlockSize];
std::string ret;
while (ssize_t sread = m_sysWrapper.read(fd, buf, readfileBlockSize)) {
if (-1 == sread)
throw Tape::Exceptions::Errnum("Could not read from open file " + path);
ret.append(buf, sread);
}
if (m_sysWrapper.close(fd))
throw Tape::Exceptions::Errnum("Error closing file " + path);
return ret;
}
SCSI::DeviceInfo::DeviceFile SCSI::DeviceVector::readDeviceFile(std::string path) {
DeviceInfo::DeviceFile ret;
std::string file = readfile(path);
if (!::sscanf(file.c_str(), "%d:%d\n", &ret.major, &ret.minor))
throw Tape::Exception(std::string("Could not parse file: ") + path);
return ret;
}
SCSI::DeviceInfo::DeviceFile SCSI::DeviceVector::statDeviceFile(std::string path) {
struct stat sbuf;
if (m_sysWrapper.stat(path.c_str(), &sbuf))
throw Tape::Exceptions::Errnum("Could not stat file " + path);
if (!S_ISCHR(sbuf.st_mode))
throw Tape::Exception("Device file " + path + " is not a character device");
DeviceInfo::DeviceFile ret;
ret.major = major(sbuf.st_rdev);
ret.minor = minor(sbuf.st_rdev);
return ret;
}
/**
* Part factored out of getDeviceInfo: get the tape specifics
* from sysfs.
* @param devinfo
*/
void SCSI::DeviceVector::getTapeInfo(DeviceInfo & devinfo) {
/* Find the st and nst devices for this SCSI device */
Tape::Utils::regex st_re("^scsi_tape:(st[[:digit:]]+)$");
Tape::Utils::regex nst_re("^scsi_tape:(nst[[:digit:]]+)$");
DIR * dirp = m_sysWrapper.opendir(devinfo.sysfs_entry.c_str());
if (!dirp) throw Tape::Exceptions::Errnum(std::string("Error opening device directory ") +
devinfo.sysfs_entry);
while (struct dirent * dent = m_sysWrapper.readdir(dirp)) {
std::vector<std::string> res;
/* Check if it's the st information */
res = st_re.exec(dent->d_name);
if (res.size()) {
if (!devinfo.st_dev.size()) {
devinfo.st_dev = std::string("/dev/") + res[1];
} else
throw Tape::Exception("Matched st device several times!");
/* Read the major and major number */
devinfo.st = readDeviceFile(devinfo.sysfs_entry + "/"
+ std::string(dent->d_name) + "/dev");
/* Check the actual device file */
DeviceInfo::DeviceFile realFile = statDeviceFile(devinfo.st_dev);
if (devinfo.st != realFile) {
std::stringstream err;
err << "Mismatch between sysfs info and actual device file: "
<< devinfo.sysfs_entry + "/" + dent->d_name << " indicates "
<< devinfo.st.major << ":" << devinfo.st.minor
<< " while " << devinfo.st_dev << " is: "
<< realFile.major << ":" << realFile.minor;
throw Tape::Exception(err.str());
}
}
/* Check if it's the nst information */
res = nst_re.exec(dent->d_name);
if (res.size()) {
if (!devinfo.nst_dev.size()) {
devinfo.nst_dev = std::string("/dev/") + res[1];
} else
throw Tape::Exception("Matched nst device several times!");
/* Read the major and major number */
devinfo.nst = readDeviceFile(devinfo.sysfs_entry + "/"
+ std::string(dent->d_name) + "/dev");
/* Check the actual device file */
DeviceInfo::DeviceFile realFile = statDeviceFile(devinfo.nst_dev);
if (devinfo.nst != realFile) {
std::stringstream err;
err << "Mismatch between sysfs info and actual device file: "
<< devinfo.sysfs_entry + "/" + dent->d_name << " indicates "
<< devinfo.nst.major << ":" << devinfo.nst.minor
<< " while " << devinfo.st_dev << " is: "
<< realFile.major << ":" << realFile.minor;
throw Tape::Exception(err.str());
}
}
}
m_sysWrapper.closedir(dirp);
}
/**
* Extract information from sysfs about a SCSI device.
* @param path Path to the directory with information about
* @return
*/
SCSI::DeviceInfo SCSI::DeviceVector::getDeviceInfo(const char * path) {
DeviceInfo ret;
ret.sysfs_entry = path;
std::string buf;
/* Get device type */
{
buf = readfile(ret.sysfs_entry + "/type");
if (!sscanf(buf.c_str(), "%d", &ret.type))
throw Tape::Exception(std::string("Could not parse file: ") + ret.sysfs_entry + "/type");
}
/* Get name of sg device */
{
char rl[PATH_MAX];
std::string lp = ret.sysfs_entry + "/generic";
if (-1 == m_sysWrapper.readlink(lp.c_str(), rl, sizeof (rl)))
throw Tape::Exceptions::Errnum("Could not read link " + lp);
std::string gl(rl);
size_t pos = gl.find_last_of("/");
if (pos == std::string::npos)
throw Tape::Exception(std::string("Could not find last / in link: ") + gl +
" read from " + ret.sysfs_entry + "/generic");
ret.sg_dev = std::string("/dev/") + gl.substr(pos + 1);
}
/* Get the major and minor number of the device file */
ret.sg = readDeviceFile(ret.sysfs_entry + "/generic/dev");
/* Check that we have an agreement with the actual device file */
DeviceInfo::DeviceFile realFile = statDeviceFile(ret.sg_dev);
if (ret.sg != realFile) {
std::stringstream err;
err << "Mismatch between sysfs info and actual device file: "
<< ret.sysfs_entry + "/generic/dev" << " indicates "
<< ret.sg.major << ":" << ret.sg.minor
<< " while " << ret.sg_dev << " is: "
<< realFile.major << ":" << realFile.minor;
throw Tape::Exception(err.str());
}
/* Handle more if we have a tape device */
if (Types::tape == ret.type)
getTapeInfo(ret);
return ret;
}
......@@ -66,7 +66,6 @@ namespace SCSI {
/**
* Automatic lister of the system's SCSI devices
*/
template<class sysWrapperClass>
class DeviceVector : public std::vector<DeviceInfo> {
public:
......@@ -76,180 +75,31 @@ namespace SCSI {
*
* (all code using templates must be in the header file)
*/
DeviceVector(sysWrapperClass & sysWrapper) : m_sysWrapper(sysWrapper) {
std::string sysDevsPath = "/sys/bus/scsi/devices";
DIR* dirp = m_sysWrapper.opendir(sysDevsPath.c_str());
if (!dirp) throw Tape::Exceptions::Errnum("Error opening sysfs scsi devs");
while (struct dirent * dent = m_sysWrapper.readdir(dirp)) {
std::string dn(dent->d_name);
if ("." == dn || ".." == dn) continue;
std::string fullpath = sysDevsPath + "/" + std::string(dent->d_name);
/* We expect only symbolic links in this directory, */
char rp[PATH_MAX];
if (NULL == m_sysWrapper.realpath(fullpath.c_str(), rp))
throw Tape::Exceptions::Errnum("Could not find realpath for " + fullpath);
this->push_back(getDeviceInfo(rp));
}
sysWrapper.closedir(dirp);
}
DeviceVector(Tape::System::virtualWrapper & sysWrapper);
private:
#undef ConvenientCoding
#ifdef ConvenientCoding
syntax error here!!!; /* So we don't compile in this configuration */
/* This makes code completion more efficient in editors */
Tape::System::fakeWrapper & m_sysWrapper;
#else
sysWrapperClass & m_sysWrapper;
#endif
Tape::System::virtualWrapper & m_sysWrapper;
static const size_t readfileBlockSize = 1024;
std::string readfile(std::string path) {
int fd = m_sysWrapper.open(path.c_str(), 0);
if (-1 == fd) {
throw Tape::Exceptions::Errnum("Could not open file " + path);
}
char buf[readfileBlockSize];
std::string ret;
while (ssize_t sread = m_sysWrapper.read(fd, buf, readfileBlockSize)) {
if (-1 == sread)
throw Tape::Exceptions::Errnum("Could not read from open file " + path);
ret.append(buf, sread);
}
if (m_sysWrapper.close(fd))
throw Tape::Exceptions::Errnum("Error closing file " + path);
return ret;
}
std::string readfile(std::string path);
DeviceInfo::DeviceFile readDeviceFile(std::string path) {
DeviceInfo::DeviceFile ret;
std::string file = readfile(path);
if (!::sscanf(file.c_str(), "%d:%d\n", &ret.major, &ret.minor))
throw Tape::Exception(std::string("Could not parse file: ") + path);
return ret;
}
DeviceInfo::DeviceFile readDeviceFile(std::string path);
DeviceInfo::DeviceFile statDeviceFile(std::string path) {
struct stat sbuf;
if (m_sysWrapper.stat(path.c_str(), &sbuf))
throw Tape::Exceptions::Errnum("Could not stat file " + path);
if (!S_ISCHR(sbuf.st_mode))
throw Tape::Exception("Device file " + path + " is not a character device");
DeviceInfo::DeviceFile ret;
ret.major = major(sbuf.st_rdev);
ret.minor = minor(sbuf.st_rdev);
return ret;
}
DeviceInfo::DeviceFile statDeviceFile(std::string path);
/**
* Part factored out of getDeviceInfo: get the tape specifics
* from sysfs.
* @param devinfo
*/
void getTapeInfo(DeviceInfo & devinfo) {
/* Find the st and nst devices for this SCSI device */
Tape::Utils::regex st_re("^scsi_tape:(st[[:digit:]]+)$");
Tape::Utils::regex nst_re("^scsi_tape:(nst[[:digit:]]+)$");
DIR * dirp = m_sysWrapper.opendir(devinfo.sysfs_entry.c_str());
if (!dirp) throw Tape::Exceptions::Errnum(std::string("Error opening device directory ") +
devinfo.sysfs_entry);
while (struct dirent * dent = m_sysWrapper.readdir(dirp)) {
std::vector<std::string> res;
/* Check if it's the st information */
res = st_re.exec(dent->d_name);
if (res.size()) {
if (!devinfo.st_dev.size()) {
devinfo.st_dev = std::string("/dev/") + res[1];
} else
throw Tape::Exception("Matched st device several times!");
/* Read the major and major number */
devinfo.st = readDeviceFile(devinfo.sysfs_entry + "/"
+ std::string(dent->d_name) + "/dev");
/* Check the actual device file */
DeviceInfo::DeviceFile realFile = statDeviceFile(devinfo.st_dev);
if (devinfo.st != realFile) {
std::stringstream err;
err << "Mismatch between sysfs info and actual device file: "
<< devinfo.sysfs_entry + "/" + dent->d_name << " indicates "
<< devinfo.st.major << ":" << devinfo.st.minor
<< " while " << devinfo.st_dev << " is: "
<< realFile.major << ":" << realFile.minor;
throw Tape::Exception(err.str());
}
}
/* Check if it's the nst information */
res = nst_re.exec(dent->d_name);
if (res.size()) {
if (!devinfo.nst_dev.size()) {
devinfo.nst_dev = std::string("/dev/") + res[1];
} else
throw Tape::Exception("Matched nst device several times!");
/* Read the major and major number */
devinfo.nst = readDeviceFile(devinfo.sysfs_entry + "/"
+ std::string(dent->d_name) + "/dev");
/* Check the actual device file */
DeviceInfo::DeviceFile realFile = statDeviceFile(devinfo.nst_dev);
if (devinfo.nst != realFile) {
std::stringstream err;
err << "Mismatch between sysfs info and actual device file: "
<< devinfo.sysfs_entry + "/" + dent->d_name << " indicates "
<< devinfo.nst.major << ":" << devinfo.nst.minor
<< " while " << devinfo.st_dev << " is: "
<< realFile.major << ":" << realFile.minor;
throw Tape::Exception(err.str());
}
}
}
m_sysWrapper.closedir(dirp);
}
void getTapeInfo(DeviceInfo & devinfo);
/**
* Extract information from sysfs about a SCSI device.
* @param path Path to the directory with information about
* @return
*/
DeviceInfo getDeviceInfo(const char * path) {
DeviceInfo ret;
ret.sysfs_entry = path;
std::string buf;
/* Get device type */
{
buf = readfile(ret.sysfs_entry + "/type");
if (!sscanf(buf.c_str(), "%d", &ret.type))
throw Tape::Exception(std::string("Could not parse file: ") + ret.sysfs_entry + "/type");
}
/* Get name of sg device */
{
char rl[PATH_MAX];
std::string lp = ret.sysfs_entry + "/generic";
if (-1 == m_sysWrapper.readlink(lp.c_str(), rl, sizeof (rl)))
throw Tape::Exceptions::Errnum("Could not read link " + lp);
std::string gl(rl);
size_t pos = gl.find_last_of("/");
if (pos == std::string::npos)
throw Tape::Exception(std::string("Could not find last / in link: ") + gl +
" read from " + ret.sysfs_entry + "/generic");
ret.sg_dev = std::string("/dev/") + gl.substr(pos + 1);
}
/* Get the major and minor number of the device file */
ret.sg = readDeviceFile(ret.sysfs_entry + "/generic/dev");
/* Check that we have an agreement with the actual device file */
DeviceInfo::DeviceFile realFile = statDeviceFile(ret.sg_dev);
if (ret.sg != realFile) {
std::stringstream err;
err << "Mismatch between sysfs info and actual device file: "
<< ret.sysfs_entry + "/generic/dev" << " indicates "
<< ret.sg.major << ":" << ret.sg.minor
<< " while " << ret.sg_dev << " is: "
<< realFile.major << ":" << realFile.minor;
throw Tape::Exception(err.str());
}
/* Handle more if we have a tape device */
if (Types::tape == ret.type)
getTapeInfo(ret);
return ret;
}
DeviceInfo getDeviceInfo(const char * path);
}; /* class DeviceVector */
......
......@@ -41,7 +41,7 @@ TEST(DeviceList, TriesToFind) {
EXPECT_CALL(sysWrapper, readdir(sysWrapper.m_DIR)).Times(1);
EXPECT_CALL(sysWrapper, closedir(sysWrapper.m_DIR)).Times(1);
SCSI::DeviceVector<Tape::System::virtualWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
}
TEST(DeviceList, ScansCorrectly) {
......@@ -64,7 +64,7 @@ TEST(DeviceList, ScansCorrectly) {
/* Everything should have been found correctly */
SCSI::DeviceVector<Tape::System::virtualWrapper> dl(sysWrapper);
SCSI::DeviceVector dl(sysWrapper);
ASSERT_EQ(3U, dl.size());
ASSERT_EQ(SCSI::Types::mediumChanger, dl[0].type);
......
add_library(System Wrapper.cc FileWrappers.cc)
set_property(SOURCE Wrapper.cc
PROPERTY COMPILE_FLAGS -fno-strict-aliasing
)
\ No newline at end of file
......@@ -200,6 +200,12 @@ void Tape::System::fakeWrapper::referenceFiles() {
m_files[i->first] = &m_genericFiles[i->first];
}
Tape::System::mockWrapper::mockWrapper() {
m_DIR = reinterpret_cast<DIR*> (& m_DIRfake);
ON_CALL(*this, opendir(::testing::_))
.WillByDefault(::testing::Return(m_DIR));
}
void Tape::System::mockWrapper::delegateToFake() {
ON_CALL(*this, opendir(_)).WillByDefault(Invoke(&fake, &fakeWrapper::opendir));
ON_CALL(*this, readdir(_)).WillByDefault(Invoke(&fake, &fakeWrapper::readdir));
......
......@@ -40,40 +40,9 @@
namespace Tape {
namespace System {
/**
* Wrapper class the all system calls used, allowing writing of test harnesses
* for unit testing.
* The member functions are purposedly non-virtual, allowing full
* performance with inline member functions.
*/
class realWrapper {
public:
DIR* opendir(const char *name) { return ::opendir(name); }
struct dirent * readdir(DIR* dirp) { return ::readdir(dirp); }
int closedir(DIR* dirp) { return ::closedir(dirp); }
int readlink(const char* path, char* buf, size_t len) { return ::readlink(path, buf, len); }
char * realpath(const char* name, char* resolved) { return ::realpath(name, resolved); }
int open(const char* file, int oflag) { return ::open(file, oflag); }
int ioctl(int fd, unsigned long int request, struct mtop * mt_cmd) {
return ::ioctl(fd, request, mt_cmd);
}
int ioctl(int fd, unsigned long int request, struct mtget * mt_status) {
return ::ioctl(fd, request, mt_status);
}
int ioctl(int fd, unsigned long int request, sg_io_hdr_t * sgh) {
return ::ioctl(fd, request, sgh);
}
ssize_t read(int fd, void* buf, size_t nbytes) { return ::read(fd, buf, nbytes); }
ssize_t write(int fd, const void *buf, size_t nbytes) { return ::write(fd, buf, nbytes); }
int close(int fd) { return ::close(fd); }
int stat(const char * path, struct stat *buf) { return ::stat(path, buf); }
};
/**
* Intermediate class definition, allowing common ancestor between
* mockWrapper and fakeWrapper