/*
* @project The CERN Tape Archive (CTA)
* @copyright Copyright(C) 2003-2021 CERN
* @license This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include "Device.hpp"
#include "../system/Wrapper.hpp"
#include "common/exception/Errnum.hpp"
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::_;
namespace unitTests {
TEST(castor_tape_SCSI_DeviceList, TriesToFind) {
/* Give minimal service output from mock system calls:
* at least pretend there is a directory to scan */
/* _ means anything goes */
castor::tape::System::mockWrapper sysWrapper;
EXPECT_CALL(sysWrapper, opendir(_)).Times(1);
EXPECT_CALL(sysWrapper, readdir(sysWrapper.m_DIR)).Times(1);
EXPECT_CALL(sysWrapper, closedir(sysWrapper.m_DIR)).Times(1);
castor::tape::SCSI::DeviceVector dl(sysWrapper);
}
TEST(castor_tape_SCSI_DeviceList, ScansCorrectly) {
castor::tape::System::mockWrapper sysWrapper;
/* Configure the mock to use fake */
sysWrapper.delegateToFake();
/* Populate the test harness */
sysWrapper.fake.setupSLC5();
// TODO: Test against SLC6 setup
/* We expect the following calls: */
EXPECT_CALL(sysWrapper, opendir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, readdir(_)).Times(AtLeast(30));
EXPECT_CALL(sysWrapper, closedir(_)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, realpath(_, _)).Times(6);
EXPECT_CALL(sysWrapper, open(_, _)).Times(38);
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(76);
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, close(_)).Times(38);
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(6);
EXPECT_CALL(sysWrapper, stat(_,_)).Times(14);
/* Everything should have been found correctly */
castor::tape::SCSI::DeviceVector dl(sysWrapper);
ASSERT_EQ(6U, dl.size());
ASSERT_EQ(castor::tape::SCSI::Types::mediumChanger, dl[0].type);
ASSERT_EQ(castor::tape::SCSI::Types::tape, dl[1].type);
ASSERT_EQ(castor::tape::SCSI::Types::tape, dl[2].type);
ASSERT_EQ(castor::tape::SCSI::Types::mediumChanger, dl[3].type);
ASSERT_EQ(castor::tape::SCSI::Types::tape, dl[4].type);
ASSERT_EQ(castor::tape::SCSI::Types::tape, dl[5].type);
ASSERT_EQ( "/dev/sg2", dl[0].sg_dev);
ASSERT_EQ( "/dev/sg0", dl[1].sg_dev);
ASSERT_EQ( "/dev/sg1", dl[2].sg_dev);
ASSERT_EQ( "/dev/sg5", dl[3].sg_dev);
ASSERT_EQ( "/dev/sg3", dl[4].sg_dev);
ASSERT_EQ( "/dev/sg4", dl[5].sg_dev);
ASSERT_EQ( "", dl[0].st_dev);
ASSERT_EQ( "/dev/st0", dl[1].st_dev);
ASSERT_EQ( "/dev/st1", dl[2].st_dev);
ASSERT_EQ( "", dl[3].st_dev);
ASSERT_EQ( "/dev/st2", dl[4].st_dev);
ASSERT_EQ( "/dev/st3", dl[5].st_dev);
ASSERT_EQ( "", dl[0].nst_dev);
ASSERT_EQ("/dev/nst0", dl[1].nst_dev);
ASSERT_EQ("/dev/nst1", dl[2].nst_dev);
ASSERT_EQ( "", dl[3].nst_dev);
ASSERT_EQ("/dev/nst2", dl[4].nst_dev);
ASSERT_EQ("/dev/nst3", dl[5].nst_dev);
ASSERT_EQ("/sys/devices/pseudo_0/adapter0/host3/target3:0:0/3:0:0:0", dl[0].sysfs_entry);
ASSERT_EQ("/sys/devices/pseudo_0/adapter0/host3/target3:0:1/3:0:1:0", dl[1].sysfs_entry);
ASSERT_EQ("/sys/devices/pseudo_0/adapter0/host3/target3:0:2/3:0:2:0", dl[2].sysfs_entry);
ASSERT_EQ("/sys/devices/pseudo_0/adapter0/host2/target2:0:0/2:0:0:0", dl[3].sysfs_entry);
ASSERT_EQ("/sys/devices/pseudo_0/adapter0/host2/target2:0:1/2:0:1:0", dl[4].sysfs_entry);
ASSERT_EQ("/sys/devices/pseudo_0/adapter0/host2/target2:0:2/2:0:2:0", dl[5].sysfs_entry);
ASSERT_EQ( 21U, dl[0].sg.major);
ASSERT_EQ( 2U, dl[0].sg.minor);
ASSERT_EQ( 21U, dl[1].sg.major);
ASSERT_EQ( 0U, dl[1].sg.minor);
ASSERT_EQ( 21U, dl[2].sg.major);
ASSERT_EQ( 1U, dl[2].sg.minor);
ASSERT_EQ( 21U, dl[3].sg.major);
ASSERT_EQ( 5U, dl[3].sg.minor);
ASSERT_EQ( 21U, dl[4].sg.major);
ASSERT_EQ( 3U, dl[4].sg.minor);
ASSERT_EQ( 21U, dl[5].sg.major);
ASSERT_EQ( 4U, dl[5].sg.minor);
ASSERT_EQ( 0U, dl[0].st.major);
ASSERT_EQ( 0U, dl[0].st.minor);
ASSERT_EQ( 9U, dl[1].st.major);
ASSERT_EQ( 0U, dl[1].st.minor);
ASSERT_EQ( 9U, dl[2].st.major);
ASSERT_EQ( 1U, dl[2].st.minor);
ASSERT_EQ( 0U, dl[3].st.major);
ASSERT_EQ( 0U, dl[3].st.minor);
ASSERT_EQ( 9U, dl[4].st.major);
ASSERT_EQ( 2U, dl[4].st.minor);
ASSERT_EQ( 9U, dl[5].st.major);
ASSERT_EQ( 3U, dl[5].st.minor);
ASSERT_EQ( 0U, dl[0].nst.major);
ASSERT_EQ( 0U, dl[0].nst.minor);
ASSERT_EQ( 9U, dl[1].nst.major);
ASSERT_EQ(128U, dl[1].nst.minor);
ASSERT_EQ( 9U, dl[2].nst.major);
ASSERT_EQ(129U, dl[2].nst.minor);
ASSERT_EQ( 0U, dl[3].nst.major);
ASSERT_EQ( 0U, dl[3].nst.minor);
ASSERT_EQ( 9U, dl[4].nst.major);
ASSERT_EQ(130U, dl[4].nst.minor);
ASSERT_EQ( 9U, dl[5].nst.major);
ASSERT_EQ(131U, dl[5].nst.minor);
ASSERT_EQ("STK", dl[0].vendor);
ASSERT_EQ("STK", dl[1].vendor);
ASSERT_EQ("STK", dl[2].vendor);
ASSERT_EQ("VL32STK1", dl[0].product);
ASSERT_EQ("T10000B", dl[1].product);
ASSERT_EQ("T10000B", dl[2].product);
ASSERT_EQ("0104", dl[0].productRevisionLevel);
ASSERT_EQ("0104", dl[1].productRevisionLevel);
ASSERT_EQ("0104", dl[2].productRevisionLevel);
ASSERT_EQ("IBM", dl[3].vendor);
ASSERT_EQ("IBM", dl[4].vendor);
ASSERT_EQ("IBM", dl[5].vendor);
ASSERT_EQ("03584L22", dl[3].product);
ASSERT_EQ("03592E08", dl[4].product);
ASSERT_EQ("03592E08", dl[5].product);
ASSERT_EQ("F030", dl[3].productRevisionLevel);
ASSERT_EQ("460E", dl[4].productRevisionLevel);
ASSERT_EQ("460E", dl[5].productRevisionLevel);
}
TEST(castor_tape_SCSI_DeviceList, FindBySymlink) {
castor::tape::System::mockWrapper sysWrapper;
sysWrapper.delegateToFake();
sysWrapper.fake.setupForVirtualDriveSLC6();
/* We expect the following calls: */
EXPECT_CALL(sysWrapper, opendir(_)).Times(AtLeast(3));
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(20));
EXPECT_CALL(sysWrapper, read(_, _, _)).Times(AtLeast(38));
EXPECT_CALL(sysWrapper, write(_, _, _)).Times(0);
EXPECT_CALL(sysWrapper, close(_)).Times(AtLeast(19));
EXPECT_CALL(sysWrapper, readlink(_, _, _)).Times(AtLeast(3));
EXPECT_CALL(sysWrapper, stat(_,_)).Times(AtLeast(7));
castor::tape::SCSI::DeviceVector dl(sysWrapper);
ASSERT_NO_THROW(dl.findBySymlink("/dev/tape_T10D6116"));
ASSERT_THROW(dl.findBySymlink("NoSuchPath"),
cta::exception::Errnum);
ASSERT_THROW(dl.findBySymlink("/dev/noSuchTape"),
castor::tape::SCSI::DeviceVector::NotFound);
castor::tape::SCSI::DeviceInfo & di = dl.findBySymlink("/dev/tape_T10D6116");
// The symlink is supposed to point to nst0 which is 9,128 (maj,min)
ASSERT_EQ(9U, di.nst.major);
ASSERT_EQ(128U, di.nst.minor);
// We expect to get a module type of "VIRTUAL" here. This will be used
// in other tests
ASSERT_EQ("VIRTUAL", di.product);
}
}