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

Changed the Drive classes layout:

Tape::Drive is now a container, taking care of allocating the proper type of drive depending on the device information.
Tape::DriveGeneric is the old parent class. It is now a pure virtual for lack of the non-common functions.

The tests (unit and system) have been adapated.

The system test environement now has a vide sampler of drive types (LTO from IBM and HP, 3592 from IBM in 3 flavors and T10K A, B and C from Oracle). The complete list of flavors is in usr/vtltape.c in mhvtl sources.
parent 6d1a8640
......@@ -22,7 +22,7 @@
#include "Drive.hh"
Tape::Drive::Drive(SCSI::DeviceInfo di, System::virtualWrapper& sw) : m_SCSIInfo(di),
Tape::DriveGeneric::DriveGeneric(SCSI::DeviceInfo di, System::virtualWrapper& sw) : m_SCSIInfo(di),
m_tapeFD(-1), m_sysWrapper(sw) {
/* Open the device files */
/* We open the tape device file non-blocking as blocking open on rewind tapes (at least)
......@@ -41,7 +41,7 @@ m_tapeFD(-1), m_sysWrapper(sw) {
* All comulative and threshold log counter values will be reset to their
* default values as specified in that pages reset behavior section.
*/
void Tape::Drive::clearCompressionStats() throw (Tape::Exception) {
void Tape::DriveGeneric::clearCompressionStats() throw (Tape::Exception) {
SCSI::Structures::logSelectCDB_t cdb;
cdb.PCR = 1; /* PCR set */
cdb.PC = 0x3; /* PC = 11b for T10000 only*/
......@@ -63,7 +63,7 @@ void Tape::Drive::clearCompressionStats() throw (Tape::Exception) {
* Information about the drive. The vendor id is used in the user labels of the files.
* @return The deviceInfo structure with the information about the drive.
*/
Tape::deviceInfo Tape::Drive::getDeviceInfo() throw (Tape::Exception) {
Tape::deviceInfo Tape::DriveGeneric::getDeviceInfo() throw (Tape::Exception) {
SCSI::Structures::inquiryCDB_t cdb;
SCSI::Structures::inquiryData_t inquiryData;
SCSI::Structures::senseData_t<255> senseBuff;
......@@ -93,7 +93,7 @@ Tape::deviceInfo Tape::Drive::getDeviceInfo() throw (Tape::Exception) {
* Information about the serial number of the drive.
* @return Right-aligned ASCII data for the vendor-assigned serial number.
*/
std::string Tape::Drive::getSerialNumber() throw (Tape::Exception) {
std::string Tape::DriveGeneric::getSerialNumber() throw (Tape::Exception) {
SCSI::Structures::inquiryCDB_t cdb;
SCSI::Structures::inquiryUnitSerialNumberData_t inquirySerialData;
SCSI::Structures::senseData_t<255> senseBuff;
......@@ -127,7 +127,7 @@ std::string Tape::Drive::getSerialNumber() throw (Tape::Exception) {
* has completed.
* @param blockId The blockId, represented in local endianness.
*/
void Tape::Drive::positionToLogicalObject(uint32_t blockId)
void Tape::DriveGeneric::positionToLogicalObject(uint32_t blockId)
throw (Tape::Exception) {
SCSI::Structures::locate10CDB_t cdb;
uint32_t blkId = SCSI::Structures::fromLtoB32(blockId);
......@@ -154,7 +154,7 @@ throw (Tape::Exception) {
* @return positionInfo class. This contains the logical position, plus information
* on the dirty data still in the write buffer.
*/
Tape::positionInfo Tape::Drive::getPositionInfo()
Tape::positionInfo Tape::DriveGeneric::getPositionInfo()
throw (Tape::Exception) {
SCSI::Structures::readPositionCDB_t cdb;
SCSI::Structures::readPositionDataShortForm_t positionData;
......@@ -197,7 +197,7 @@ throw (Tape::Exception) {
* Section is 4.2.17 in SSC-3.
* @return list of tape alerts descriptions. They are simply used for logging.
*/
std::vector<std::string> Tape::Drive::getTapeAlerts() throw (Tape::Exception) {
std::vector<std::string> Tape::DriveGeneric::getTapeAlerts() throw (Tape::Exception) {
/* return vector */
std::vector<std::string> ret;
/* We don't know how many elements we'll get. Prepare a 100 parameters array */
......@@ -243,7 +243,7 @@ std::vector<std::string> Tape::Drive::getTapeAlerts() throw (Tape::Exception) {
* @param compression The boolean variable to enable or disable compression
* on the drive for the tape. By default it is enabled.
*/
void Tape::Drive::setDensityAndCompression(unsigned char densityCode,
void Tape::DriveGeneric::setDensityAndCompression(unsigned char densityCode,
bool compression) throw (Tape::Exception) {
SCSI::Structures::modeSenseDeviceConfiguration_t devConfig;
{ // get info from the drive
......@@ -300,7 +300,7 @@ void Tape::Drive::setDensityAndCompression(unsigned char densityCode,
* layer, unless the parameter turns out to be disused.
* @param bufWrite: value of the buffer write switch
*/
void Tape::Drive::setSTBufferWrite(bool bufWrite) throw (Tape::Exception) {
void Tape::DriveGeneric::setSTBufferWrite(bool bufWrite) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTSETDRVBUFFER;
m_mtCmd.mt_count = bufWrite ? (MT_ST_SETBOOLEANS | MT_ST_BUFFER_WRITES) : (MT_ST_CLEARBOOLEANS | MT_ST_BUFFER_WRITES);
......@@ -316,7 +316,7 @@ void Tape::Drive::setSTBufferWrite(bool bufWrite) throw (Tape::Exception) {
* all tape drives.
* TODO: synchronous? Timeout?
*/
void Tape::Drive::spaceToEOM(void) throw (Tape::Exception) {
void Tape::DriveGeneric::spaceToEOM(void) throw (Tape::Exception) {
setSTFastMTEOM(false);
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTEOM;
......@@ -331,7 +331,7 @@ void Tape::Drive::spaceToEOM(void) throw (Tape::Exception) {
* the higher levels of the software (TODO: protected?).
* @param fastMTEOM the option switch.
*/
void Tape::Drive::setSTFastMTEOM(bool fastMTEOM) throw (Tape::Exception) {
void Tape::DriveGeneric::setSTFastMTEOM(bool fastMTEOM) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTSETDRVBUFFER;
m_mtCmd.mt_count = fastMTEOM ? (MT_ST_SETBOOLEANS | MT_ST_FAST_MTEOM) : (MT_ST_CLEARBOOLEANS | MT_ST_FAST_MTEOM);
......@@ -343,7 +343,7 @@ void Tape::Drive::setSTFastMTEOM(bool fastMTEOM) throw (Tape::Exception) {
* Jump to end of data. EOM in ST driver jargon, end of data (which is more accurate)
* in SCSI terminology). This uses the fast setting (not to be used for MIR rebuild)
*/
void Tape::Drive::fastSpaceToEOM(void) throw (Tape::Exception) {
void Tape::DriveGeneric::fastSpaceToEOM(void) throw (Tape::Exception) {
setSTFastMTEOM(true);
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTEOM;
......@@ -355,7 +355,7 @@ void Tape::Drive::fastSpaceToEOM(void) throw (Tape::Exception) {
/**
* Rewind tape.
*/
void Tape::Drive::rewind(void) throw (Tape::Exception) {
void Tape::DriveGeneric::rewind(void) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTREW;
m_mtCmd.mt_count = 1;
......@@ -367,7 +367,7 @@ void Tape::Drive::rewind(void) throw (Tape::Exception) {
* Space count file marks backwards.
* @param count
*/
void Tape::Drive::spaceFileMarksBackwards(size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::spaceFileMarksBackwards(size_t count) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTBSF;
m_mtCmd.mt_count = (int)count;
......@@ -379,7 +379,7 @@ void Tape::Drive::spaceFileMarksBackwards(size_t count) throw (Tape::Exception)
* Space count file marks forward.
* @param count
*/
void Tape::Drive::spaceFileMarksForward(size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::spaceFileMarksForward(size_t count) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTFSF;
m_mtCmd.mt_count = (int)count;
......@@ -394,7 +394,7 @@ void Tape::Drive::spaceFileMarksForward(size_t count) throw (Tape::Exception) {
* next logical object is not a logical block (i.e. if it is a file mark instead).
* @param count
*/
void Tape::Drive::spaceBlocksBackwards(size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::spaceBlocksBackwards(size_t count) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTBSR;
m_mtCmd.mt_count = (int)count;
......@@ -409,7 +409,7 @@ void Tape::Drive::spaceBlocksBackwards(size_t count) throw (Tape::Exception) {
* next logical object is not a logical block (i.e. if it is a file mark instead).
* @param count
*/
void Tape::Drive::spaceBlocksForward(size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::spaceBlocksForward(size_t count) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTFSR;
m_mtCmd.mt_count = (int)count;
......@@ -420,7 +420,7 @@ void Tape::Drive::spaceBlocksForward(size_t count) throw (Tape::Exception) {
/**
* Unload the tape.
*/
void Tape::Drive::unloadTape(void) throw (Tape::Exception) {
void Tape::DriveGeneric::unloadTape(void) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTUNLOAD;
m_mtCmd.mt_count = 1;
......@@ -432,7 +432,7 @@ void Tape::Drive::unloadTape(void) throw (Tape::Exception) {
* Synch call to the tape drive. This function will not return before the
* data in the drive's buffer is actually comitted to the medium.
*/
void Tape::Drive::sync(void) throw (Tape::Exception) {
void Tape::DriveGeneric::sync(void) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTNOP; //The side effect of the no-op is to actually flush the driver's buffer to tape (see "man st").
m_mtCmd.mt_count = 1;
......@@ -445,7 +445,7 @@ void Tape::Drive::sync(void) throw (Tape::Exception) {
* are committed to medium.
* @param count
*/
void Tape::Drive::writeSyncFileMarks(size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::writeSyncFileMarks(size_t count) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTWEOF;
m_mtCmd.mt_count = (int)count;
......@@ -458,7 +458,7 @@ void Tape::Drive::writeSyncFileMarks(size_t count) throw (Tape::Exception) {
* buffer and the function return immediately.
* @param count
*/
void Tape::Drive::writeImmediateFileMarks(size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::writeImmediateFileMarks(size_t count) throw (Tape::Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTWEOFI; //Undocumented in "man st" needs the mtio_add.hh header file (see above)
m_mtCmd.mt_count = (int)count;
......@@ -471,7 +471,7 @@ void Tape::Drive::writeImmediateFileMarks(size_t count) throw (Tape::Exception)
* @param data pointer the the data block
* @param count size of the data block
*/
void Tape::Drive::writeBlock(const unsigned char * data, size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::writeBlock(const unsigned char * data, size_t count) throw (Tape::Exception) {
if (-1 == m_sysWrapper.write(m_tapeFD, data, count))
throw Tape::Exceptions::Errnum("Failed ST write");
}
......@@ -481,17 +481,17 @@ void Tape::Drive::writeBlock(const unsigned char * data, size_t count) throw (Ta
* @param data pointer the the data block
* @param count size of the data block
*/
void Tape::Drive::readBlock(unsigned char * data, size_t count) throw (Tape::Exception) {
void Tape::DriveGeneric::readBlock(unsigned char * data, size_t count) throw (Tape::Exception) {
if (-1 == m_sysWrapper.read(m_tapeFD, data, count))
throw Tape::Exceptions::Errnum("Failed ST read");
}
void Tape::Drive::SCSI_inquiry() {
void Tape::DriveGeneric::SCSI_inquiry() {
std::cout << "Re-doing a SCSI inquiry via st device:" << std::endl;
SCSI_inquiry(m_tapeFD);
}
void Tape::Drive::SCSI_inquiry(int fd) {
void Tape::DriveGeneric::SCSI_inquiry(int fd) {
unsigned char dataBuff[130];
unsigned char senseBuff[256];
SCSI::Structures::inquiryCDB_t cdb;
......
......@@ -99,9 +99,9 @@ namespace Tape {
* system without paying performance price when calling system calls in the
* production system.
*/
class Drive {
class DriveGeneric {
public:
Drive(SCSI::DeviceInfo di, System::virtualWrapper & sw);
DriveGeneric(SCSI::DeviceInfo di, System::virtualWrapper & sw);
/* Operations to be used by the higher levels */
......@@ -112,9 +112,7 @@ namespace Tape {
* fields toHost, fromDrive are related to the read operation.
* @return compressionStats
*/
virtual compressionStats getCompression() throw (Exception) {
throw Exception("getCompression unavailable in Tape::Drive generic version");
}
virtual compressionStats getCompression() throw (Exception) = 0;
/**
* Reset all statistics about data movements on the drive.
......@@ -308,12 +306,15 @@ namespace Tape {
*/
virtual void readBlock(unsigned char * data, size_t count) throw (Exception);
virtual ~Drive() {
virtual ~DriveGeneric() {
if (-1 != m_tapeFD)
m_sysWrapper.close(m_tapeFD);
}
void SCSI_inquiry();
/**
*/
protected:
SCSI::DeviceInfo m_SCSIInfo;
int m_tapeFD;
......@@ -330,30 +331,54 @@ namespace Tape {
void SCSI_inquiry(int fd);
};
class DriveT10000 : public Drive {
class DriveT10000 : public DriveGeneric {
public:
DriveT10000(SCSI::DeviceInfo di, System::virtualWrapper & sw) : Drive(di, sw) {
DriveT10000(SCSI::DeviceInfo di, System::virtualWrapper & sw) : DriveGeneric(di, sw) {
}
virtual compressionStats getCompression() throw (Exception);
};
class DriveLTO : public Drive {
class DriveLTO : public DriveGeneric {
public:
DriveLTO(SCSI::DeviceInfo di, System::virtualWrapper & sw) : Drive(di, sw) {
DriveLTO(SCSI::DeviceInfo di, System::virtualWrapper & sw) : DriveGeneric(di, sw) {
}
virtual compressionStats getCompression() throw (Exception);
};
class DriveIBM3592 : public Drive {
class DriveIBM3592 : public DriveGeneric {
public:
DriveIBM3592(SCSI::DeviceInfo di, System::virtualWrapper & sw) : Drive(di, sw) {
DriveIBM3592(SCSI::DeviceInfo di, System::virtualWrapper & sw) : DriveGeneric(di, sw) {
}
virtual compressionStats getCompression() throw (Exception);
};
class Drive {
public:
Drive(SCSI::DeviceInfo di, System::virtualWrapper & sw): m_drive(NULL) {
if (di.product.find("T10000")) {
m_drive = new DriveT10000(di, sw);
} else if (di.product.find("ULT" || di.product.find("Ultrium"))) {
m_drive = new DriveLTO(di, sw);
} else if (di.product.find("03592")) {
m_drive = new DriveIBM3592(di, sw);
} else {
throw Tape::Exception(std::string("Unsupported drive type: ")+di.product);
}
}
~Drive() {
delete m_drive;
}
operator DriveGeneric &() {
return *m_drive;
}
private:
DriveGeneric * m_drive;
};
}
......@@ -44,11 +44,11 @@ TEST(TapeDrive, OpensCorrectly) {
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(3);
EXPECT_CALL(sysWrapper, open(_, _)).Times(12);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(20);
EXPECT_CALL(sysWrapper, open(_, _)).Times(21);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(38);
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<mtget*>())).Times(2);
EXPECT_CALL(sysWrapper, close(_)).Times(12);
EXPECT_CALL(sysWrapper, close(_)).Times(21);
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(3);
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
......@@ -73,11 +73,11 @@ TEST(TapeDrive, getPositionInfoAndPositionToLogicalObject) {
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(3);
EXPECT_CALL(sysWrapper, open(_, _)).Times(12);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(20);
EXPECT_CALL(sysWrapper, open(_, _)).Times(21);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(38);
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<mtget*>())).Times(2);
EXPECT_CALL(sysWrapper, close(_)).Times(12);
EXPECT_CALL(sysWrapper, close(_)).Times(21);
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(3);
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
......@@ -86,7 +86,10 @@ TEST(TapeDrive, getPositionInfoAndPositionToLogicalObject) {
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive drive(*i, sysWrapper);
Tape::Drive dContainer(*i, sysWrapper);
/* Compiler cannot implicitly use the conversion operator. Create an
* intermediate reference*/
Tape::DriveGeneric & drive = dContainer;
Tape::positionInfo posInfo;
EXPECT_CALL(sysWrapper, ioctl(_,_,An<sg_io_hdr_t*>())).Times(1);
......@@ -121,11 +124,11 @@ TEST(TapeDrive, setDensityAndCompression) {
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(3);
EXPECT_CALL(sysWrapper, open(_, _)).Times(12);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(20);
EXPECT_CALL(sysWrapper, open(_, _)).Times(21);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(38);
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<mtget*>())).Times(2);
EXPECT_CALL(sysWrapper, close(_)).Times(12);
EXPECT_CALL(sysWrapper, close(_)).Times(21);
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(3);
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
......@@ -134,7 +137,10 @@ TEST(TapeDrive, setDensityAndCompression) {
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive drive(*i, sysWrapper);
Tape::Drive dContainer(*i, sysWrapper);
/* Compiler cannot implicitly use the conversion operator. Create an
* intermediate reference*/
Tape::DriveGeneric & drive = dContainer;
EXPECT_CALL(sysWrapper, ioctl(_,_,An<sg_io_hdr_t*>())).Times(2);
drive.setDensityAndCompression();
......@@ -165,11 +171,11 @@ TEST(TapeDrive, setStDriverOptions) {
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(3);
EXPECT_CALL(sysWrapper, open(_, _)).Times(12);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(20);
EXPECT_CALL(sysWrapper, open(_, _)).Times(21);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(38);
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<mtget*>())).Times(2);
EXPECT_CALL(sysWrapper, close(_)).Times(12);
EXPECT_CALL(sysWrapper, close(_)).Times(21);
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(3);
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
......@@ -177,7 +183,10 @@ TEST(TapeDrive, setStDriverOptions) {
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 drive(*i, sysWrapper);
Tape::Drive dContainer(*i, sysWrapper);
/* Compiler cannot implicitly use the conversion operator. Create an
* intermediate reference*/
Tape::DriveGeneric & drive = dContainer;
EXPECT_CALL(sysWrapper, ioctl(_,_,An<struct mtop *>())).Times(1);
drive.setSTBufferWrite(true);
......@@ -199,11 +208,11 @@ TEST(TapeDrive, getDeviceInfo) {
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(3);
EXPECT_CALL(sysWrapper, open(_, _)).Times(12);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(20);
EXPECT_CALL(sysWrapper, open(_, _)).Times(21);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(38);
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<mtget*>())).Times(2);
EXPECT_CALL(sysWrapper, close(_)).Times(12);
EXPECT_CALL(sysWrapper, close(_)).Times(21);
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(3);
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
......@@ -212,7 +221,10 @@ TEST(TapeDrive, getDeviceInfo) {
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive drive(*i, sysWrapper);
Tape::Drive dContainer(*i, sysWrapper);
/* Compiler cannot implicitly use the conversion operator. Create an
* intermediate reference*/
Tape::DriveGeneric & drive = dContainer;
Tape::deviceInfo devInfo;
EXPECT_CALL(sysWrapper, ioctl(_,_,An<sg_io_hdr_t*>())).Times(2);
......@@ -237,11 +249,11 @@ TEST(TapeDrive, getCompressionAndClearCompressionStats) {
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(3);
EXPECT_CALL(sysWrapper, open(_, _)).Times(16);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(20);
EXPECT_CALL(sysWrapper, open(_, _)).Times(25);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(38);
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, ioctl(_,_,An<mtget*>())).Times(6);
EXPECT_CALL(sysWrapper, close(_)).Times(16);
EXPECT_CALL(sysWrapper, close(_)).Times(25);
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(3);
EXPECT_CALL(sysWrapper, stat(_,_)).Times(7);
......@@ -250,7 +262,7 @@ TEST(TapeDrive, getCompressionAndClearCompressionStats) {
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive *drive;
Tape::DriveGeneric *drive;
Tape::compressionStats comp;
{
......@@ -336,11 +348,11 @@ TEST(TapeDrive, getTapeAlerts) {
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, open(_, _)).Times(AtLeast(12));
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(AtLeast(20));
EXPECT_CALL(sysWrapper, open(_, _)).Times(AtLeast(21));
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(AtLeast(38));
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, ioctl(_, _, An<mtget*>())).Times(2);
EXPECT_CALL(sysWrapper, close(_)).Times(AtLeast(12));
EXPECT_CALL(sysWrapper, close(_)).Times(AtLeast(21));
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, stat(_, _)).Times(AtLeast(7));
......@@ -349,7 +361,10 @@ TEST(TapeDrive, getTapeAlerts) {
for (std::vector<SCSI::DeviceInfo>::iterator i = dl.begin();
i != dl.end(); i++) {
if (SCSI::Types::tape == i->type) {
Tape::Drive drive(*i, sysWrapper);
Tape::Drive dContainer(*i, sysWrapper);
/* Compiler cannot implicitly use the conversion operator. Create an
* intermediate reference*/
Tape::DriveGeneric & drive = dContainer;
EXPECT_CALL(sysWrapper, ioctl(_, _, An<sg_io_hdr_t*>())).Times(1);
std::vector<std::string> alerts = drive.getTapeAlerts();
ASSERT_EQ(3U, alerts.size());
......
......@@ -36,9 +36,9 @@
* assertion and exits.
* @param expected_position expected position
*/
void print_and_assert_position(Tape::Drive *drive, int expected_position)
void print_and_assert_position(Tape::DriveGeneric &drive, int expected_position)
{
int curPos = (int)drive->getPositionInfo().currentPosition;
int curPos = (int)drive.getPositionInfo().currentPosition;
std::cout << "CurrentPosition: " << curPos << " (Expected: " << expected_position << ")" << std::endl;
assert(expected_position == curPos);
return;
......@@ -68,11 +68,14 @@ int main ()
std::cout << std::endl << "-- SCSI device: "
<< dev.sg_dev << " (" << dev.nst_dev << ")" << std::endl;
if (dev.type == SCSI::Types::tape) {
Tape::Drive *drive = new Tape::Drive(dev, sWrapper);
Tape::Drive dContainer(dev, sWrapper);
/* Compiler cannot implicitly use the conversion operator. Create an
* intermediate reference*/
Tape::DriveGeneric & drive = dContainer;
Tape::deviceInfo devInfo;
try {
devInfo = drive->getDeviceInfo();
devInfo = drive.getDeviceInfo();
std::cout << "-- INFO --------------------------------------" << std::endl
<< " devInfo.vendor : '" << devInfo.vendor << "'" << std::endl
<< " devInfo.product : '" << devInfo.product << "'" << std::endl
......@@ -86,13 +89,6 @@ int main ()
<< temp
<< "----------------------------------------------" << std::endl;
}
/* here we detect drive type and switch to appropriate class */
if (std::string::npos != devInfo.product.find("T10000")) {
delete drive;
drive = new Tape::DriveT10000(dev, sWrapper);
std::cout << "** Switch to DriveT10000" << std::endl;
}
try {
/**
* We will write on the tape, so prepare 2 blocks
......@@ -100,14 +96,14 @@ int main ()
std::cout << "-- INFO --------------------------------------" << std::endl
<< " Rewinding, writing 2 blocks and repositioning on block 2" << std::endl
<< "----------------------------------------------" << std::endl;
drive->rewind();
drive.rewind();
/* For some unexplained (TODO) reason, mhvtl does not accept blocks smaller than 4 bytes */
drive->writeBlock((unsigned char *)"X123", 4);
drive->writeBlock((unsigned char *)"Y123", 4);
drive.writeBlock((unsigned char *)"X123", 4);
drive.writeBlock((unsigned char *)"Y123", 4);
/**
* trying to do position to the block 2.
*/
drive->positionToLogicalObject(2);
drive.positionToLogicalObject(2);
} catch (std::exception & e) {
fail = 1;
std::string temp = e.what();
......@@ -117,7 +113,7 @@ int main ()
}
try {
Tape::positionInfo posInfo = drive->getPositionInfo();
Tape::positionInfo posInfo = drive.getPositionInfo();
std::cout << "-- INFO --------------------------------------" << std::endl
<< " posInfo.currentPosition : " << posInfo.currentPosition <<std::endl
<< " posInfo.oldestDirtyObject : "<< posInfo.oldestDirtyObject <<std::endl
......@@ -134,7 +130,7 @@ int main ()
try { // switch off compression on the drive
std::cout << "** set density and compression" << std::endl;
drive->setDensityAndCompression(false);
drive.setDensityAndCompression(false);
} catch (std::exception & e) {
fail = 1;
std::string temp = e.what();
......@@ -148,7 +144,7 @@ int main ()
* Trying to get compression from the drive. Read or write should be
* done before to have something in the data fields.
*/
Tape::compressionStats comp = drive->getCompression();
Tape::compressionStats comp = drive.getCompression();
std::cout << "-- INFO --------------------------------------" << std::endl
<< " fromHost : " << comp.fromHost << std::endl
<< " toHost : " << comp.toHost << std::endl
......@@ -157,9 +153,9 @@ int main ()
<< "----------------------------------------------" << std::endl;
std::cout << "** clear compression stats" << std::endl;
drive->clearCompressionStats();
drive.clearCompressionStats();
comp = drive->getCompression();
comp = drive.getCompression();
std::cout << "-- INFO --------------------------------------" << std::endl
<< " fromHost : " << comp.fromHost << std::endl
<< " toHost : " << comp.toHost << std::endl
......@@ -174,7 +170,7 @@ int main ()
<< "----------------------------------------------" << std::endl;
}
std::vector<std::string> Alerts(drive->getTapeAlerts());
std::vector<std::string> Alerts(drive.getTapeAlerts());
while (Alerts.size()) {
std::cout << "Tape alert: " << Alerts.back() << std::endl;
Alerts.pop_back();
......@@ -193,178 +189,178 @@ int main ()
std::cout << "************** BEGIN: Rewind/Read/Write/Skip Test *************" << std::endl;
std::cout << "Rewinding..." << std::endl;
drive->rewind(); // go back to the beginning of tape after Victor's positioning
drive.rewind(); // go back to the beginning of tape after Victor's positioning
print_and_assert_position(drive, 0);
memset(data, 'a', count-1);
std::cout << "Writing 1st block (9 a's)..." << std::endl;
drive->writeBlock(data, count); // write 9 a's + string term
drive.writeBlock(data, count); // write 9 a's + string term
print_and_assert_position(drive, 1);
std::cout << "Writing 1st Synchronous filemark..." << std::endl;
drive->writeSyncFileMarks(1); // filemark and flush