Commit 66d77dbe authored by Eric Cano's avatar Eric Cano
Browse files

Completed support for tape density and add usage of at() in a vector access to...

Completed support for tape density and add usage of at() in a vector access to prevent segfault in unit test.
Removed some throw() specifications which led to segfaults.
parent 4e5a106c
......@@ -32,12 +32,14 @@ cta::objectstore::Tape::Tape(GenericObject& go):
}
void cta::objectstore::Tape::initialize(const std::string &name,
const std::string &logicallibrary, const cta::CreationLog & creationLog) {
const std::string &logicallibrary, const std::string & density,
const cta::CreationLog & creationLog) {
ObjectOps<serializers::Tape>::initialize();
// Set the reguired fields
objectstore::CreationLog oscl(creationLog);
oscl.serialize(*m_payload.mutable_log());
m_payload.set_vid(name);
m_payload.set_density(density);
m_payload.set_bytesstored(0);
m_payload.set_lastfseq(0);
m_payload.set_logicallibrary(logicallibrary);
......@@ -117,6 +119,18 @@ std::string cta::objectstore::Tape::getVid() {
return m_payload.vid();
}
void cta::objectstore::Tape::setDensity(const std::string& density) {
checkPayloadWritable();
m_payload.set_density(density);
}
std::string cta::objectstore::Tape::getDensity() {
checkPayloadReadable();
return m_payload.density();
}
std::string cta::objectstore::Tape::dump() {
checkPayloadReadable();
std::stringstream ret;
......
......@@ -35,7 +35,7 @@ public:
Tape(const std::string & address, Backend & os);
Tape(GenericObject & go);
void initialize(const std::string & vid, const std::string &logicalLibrary,
const cta::CreationLog & creationLog);
const std::string & density, const cta::CreationLog & creationLog);
void garbageCollect();
bool isEmpty();
CTA_GENERATE_EXCEPTION_CLASS(NotEmpty);
......@@ -89,11 +89,14 @@ public:
// -- Stored data counting ---------------------------------------------------
uint64_t getStoredData();
std::string getVid();
void setStoredData(uint64_t bytes);
void addStoredData(uint64_t bytes);
void setLastFseq(uint64_t lastFseq);
uint64_t getLastFseq();
// -- Generic parameters
std::string getVid();
std::string getDensity();
void setDensity(const std::string &density);
};
}}
\ No newline at end of file
......@@ -73,8 +73,8 @@ namespace {
}
std::string cta::objectstore::TapePool::addOrGetTapeAndCommit(const std::string& vid,
const std::string& logicalLibraryName, const uint64_t capacityInBytes,
Agent& agent, const cta::CreationLog& creationLog) {
const std::string& logicalLibraryName, const uint64_t capacityInBytes,
const std::string &density, Agent& agent, const cta::CreationLog& creationLog) {
checkPayloadWritable();
// Check the tape already exists
try {
......@@ -90,7 +90,7 @@ std::string cta::objectstore::TapePool::addOrGetTapeAndCommit(const std::string&
agent.commit();
// The create the tape object
Tape t(tapeAddress, ObjectOps<serializers::TapePool>::m_objectStore);
t.initialize(vid, logicalLibraryName, creationLog);
t.initialize(vid, logicalLibraryName, density, creationLog);
t.setOwner(agent.getAddressIfSet());
t.setBackupOwner(getAddressIfSet());
t.insert();
......
......@@ -50,8 +50,9 @@ public:
// Tapes management ==========================================================
std::string addOrGetTapeAndCommit(const std::string &vid,
const std::string &logicalLibraryName, const uint64_t capacityInBytes,
Agent & agent, const cta::CreationLog & CreationLog);
const std::string &logicalLibraryName, const uint64_t capacityInBytes,
const std::string &density, Agent & agent,
const cta::CreationLog & CreationLog);
CTA_GENERATE_EXCEPTION_CLASS(NoSuchTape);
CTA_GENERATE_EXCEPTION_CLASS(WrongTape);
void removeTapeAndCommit(const std::string &vid);
......
......@@ -32,7 +32,7 @@ TEST(ObjectStore, TapeBasicAccess) {
// Try to create the tape entry
cta::objectstore::Tape t(tapeAddress, be);
cta::CreationLog cl(cta::UserIdentity(123,456), "testHost", time(NULL), "Unit test");
t.initialize("V12345", "LIB0", cl);
t.initialize("V12345", "LIB0", "8000GC", cl);
t.insert();
}
{
......
......@@ -240,28 +240,29 @@ message MountInfo {
message Tape {
required string vid = 4300;
required string logicallibrary = 4301;
required string density = 4302;
// Statistics about what is stored in the tape
required uint64 lastfseq = 4302;
required uint64 bytesstored = 4303;
required uint64 lastfseq = 4303;
required uint64 bytesstored = 4304;
// Tape lifetime statistics
repeated MountInfo readmounts = 4304;
repeated MountInfo writemounts = 4305;
repeated MountInfo readmounts = 4305;
repeated MountInfo writemounts = 4306;
// Information about retrive jobs queued on this tape
repeated RetrieveJobPointer retrievejobs = 4306;
required uint64 retrievejobstotalsize = 4307;
required uint64 oldestjobtime = 4308;
required uint64 priority = 4309;
repeated RetrieveJobPointer retrievejobs = 4307;
required uint64 retrievejobstotalsize = 4308;
required uint64 oldestjobtime = 4309;
required uint64 priority = 4310;
// There are no per tape mount criteria/quotas (they are per tape pool).
// Tape status
required bool busy = 4310;
required MountType currentmounttype = 4311;
required MountInfo currentmount = 4312;
required bool archived = 4313;
required bool disabled = 4314;
required bool readonly = 4315;
required bool full = 4316;
required bool busy = 4311;
required MountType currentmounttype = 4312;
required MountInfo currentmount = 4313;
required bool archived = 4314;
required bool disabled = 4315;
required bool readonly = 4316;
required bool full = 4317;
// Creation log
required CreationLog log = 4317;
required CreationLog log = 4318;
}
// ------------- Archive Jobs --------------------------------------------------
......
......@@ -41,43 +41,43 @@ cta::ArchiveMount::ArchiveMount(NameServer & ns,
//------------------------------------------------------------------------------
// getMountType
//------------------------------------------------------------------------------
cta::MountType::Enum cta::ArchiveMount::getMountType() const throw() {
cta::MountType::Enum cta::ArchiveMount::getMountType() const {
return MountType::ARCHIVE;
}
//------------------------------------------------------------------------------
// getVid
//------------------------------------------------------------------------------
std::string cta::ArchiveMount::getVid() const throw() {
return "UNKNOWN_VID_FOR_ARCHIVE_MOUNT";
std::string cta::ArchiveMount::getVid() const {
throw exception::Exception("UNKNOWN_VID_FOR_ARCHIVE_MOUNT");
}
//------------------------------------------------------------------------------
// getDensity
//------------------------------------------------------------------------------
std::string cta::ArchiveMount::getDensity() const throw() {
return "UNKNOWN_DENSITY_FOR_ARCHIVE_MOUNT";
std::string cta::ArchiveMount::getDensity() const {
throw exception::Exception("UNKNOWN_DENSITY_FOR_ARCHIVE_MOUNT");
}
//------------------------------------------------------------------------------
// getPoolName
//------------------------------------------------------------------------------
std::string cta::ArchiveMount::getPoolName() const throw() {
return "UNKNOWN_POOL_FOR_ARCHIVE_MOUNT";
std::string cta::ArchiveMount::getPoolName() const {
throw exception::Exception("UNKNOWN_POOL_FOR_ARCHIVE_MOUNT");
}
//------------------------------------------------------------------------------
// getCopyNumber
//------------------------------------------------------------------------------
int cta::ArchiveMount::getCopyNumber() const throw() {
return 1;
int cta::ArchiveMount::getCopyNumber() const {
throw exception::Exception("UNKNOWN_COPY_NUMBER_ARCHIVE_MOUNT");
}
//------------------------------------------------------------------------------
// getMountTransactionId
//------------------------------------------------------------------------------
std::string cta::ArchiveMount::getMountTransactionId() const throw(){
return "UNKNOWN_MOUNTTRANSACTIONID_FOR_ARCHIVE_MOUNT";
std::string cta::ArchiveMount::getMountTransactionId() const {
throw exception::Exception("UNKNOWN_MOUNTTRANSACTIONID_FOR_ARCHIVE_MOUNT");
}
//------------------------------------------------------------------------------
......
......@@ -59,28 +59,28 @@ namespace cta {
*
* @return The type of this tape mount.
*/
virtual MountType::Enum getMountType() const throw();
virtual MountType::Enum getMountType() const;
/**
* Returns the volume identifier of the tape to be mounted.
*
* @return The volume identifier of the tape to be mounted.
*/
virtual std::string getVid() const throw();
virtual std::string getVid() const;
/**
* Returns the density of the tape to be mounted.
*
* @return The density of the tape to be mounted.
*/
virtual std::string getDensity() const throw();
virtual std::string getDensity() const;
/**
* Returns the mount transaction id.
*
* @return The mount transaction id.
*/
virtual std::string getMountTransactionId() const throw();
virtual std::string getMountTransactionId() const;
/**
* Indicates that the mount was completed.
......@@ -106,14 +106,14 @@ namespace cta {
*
* @return The tape pool of the tape to be mounted.
*/
virtual std::string getPoolName() const throw();
virtual std::string getPoolName() const;
/**
* Returns the copy number of the tape to be mounted.
*
* @return The copy number of the tape to be mounted.
*/
virtual int getCopyNumber() const throw();
virtual int getCopyNumber() const;
/**
* Destructor.
......
......@@ -515,8 +515,8 @@ void OStoreDB::deleteTapePool(const SecurityIdentity& requester,
void OStoreDB::createTape(const std::string& vid,
const std::string& logicalLibraryName,
const std::string& tapePoolName, const uint64_t capacityInBytes,
const cta::CreationLog& creationLog) {
const std::string& tapePoolName, const uint64_t capacityInBytes,
const std::string & density, const cta::CreationLog& creationLog) {
// To create a tape, we have to
// - Find the storage class and lock for write.
// - Create the tape object.
......@@ -549,7 +549,7 @@ void OStoreDB::createTape(const std::string& vid,
throw TapeAlreadyExists("In OStoreDB::createTape: trying to create an existing tape.");
} catch (cta::exception::Exception &) {}
// Create the tape. The tape pool method takes care of the gory details for us.
tp.addOrGetTapeAndCommit(vid, logicalLibraryName, capacityInBytes,
tp.addOrGetTapeAndCommit(vid, logicalLibraryName, capacityInBytes, density,
*m_agent, creationLog);
tp.commit();
}
......@@ -1229,6 +1229,7 @@ std::unique_ptr<SchedulerDatabase::RetrieveMount>
std::unique_ptr<OStoreDB::RetrieveMount> privateRet(
new OStoreDB::RetrieveMount(m_objectStore, m_agent));
auto &rm = *privateRet;
std::string tapeDensity;
// Check we hold the scheduling lock
if (!m_lockTaken)
throw SchedulingLockNotHeld("In OStoreDB::TapeMountDecisionInfo::createRetrieveMount: "
......@@ -1282,6 +1283,7 @@ std::unique_ptr<SchedulerDatabase::RetrieveMount>
}
t.setBusy(driveName, objectstore::Tape::MountType::Archive, hostName, startTime,
m_agent.getAddressIfSet());
tapeDensity = t.getDensity();
t.commit();
}
// Fill up the mount info
......@@ -1290,6 +1292,7 @@ std::unique_ptr<SchedulerDatabase::RetrieveMount>
rm.mountInfo.logicalLibrary = logicalLibrary;
rm.mountInfo.mountId = m_schedulerGlobalLock->getIncreaseCommitMountId();
rm.mountInfo.tapePool = tapePool;
rm.mountInfo.density = tapeDensity;
// Update the status of the drive in the registry
{
// Get hold of the drive registry
......
......@@ -212,7 +212,7 @@ public:
CTA_GENERATE_EXCEPTION_CLASS(NoSuchTape);
virtual void createTape(const std::string& vid, const std::string& logicalLibraryName,
const std::string& tapePoolName, const uint64_t capacityInBytes,
const cta::CreationLog& creationLog);
const std::string& density, const cta::CreationLog& creationLog);
virtual Tape getTape(const std::string &vid) const;
......
......@@ -101,8 +101,8 @@ public:
m_OStoreDB.createStorageClass(name, nbCopies, creationLog);
}
virtual void createTape(const std::string& vid, const std::string& logicalLibraryName, const std::string& tapePoolName, const uint64_t capacityInBytes, const cta::CreationLog & creationLog) {
m_OStoreDB.createTape(vid, logicalLibraryName, tapePoolName, capacityInBytes, creationLog);
virtual void createTape(const std::string& vid, const std::string& logicalLibraryName, const std::string& tapePoolName, const uint64_t capacityInBytes, const std::string & density, const cta::CreationLog & creationLog) {
m_OStoreDB.createTape(vid, logicalLibraryName, tapePoolName, capacityInBytes, density, creationLog);
}
virtual void createTapePool(const std::string& name, const uint32_t nbPartialTapes, const CreationLog& creationLog) {
......
......@@ -36,29 +36,33 @@ cta::RetrieveMount::RetrieveMount(
//------------------------------------------------------------------------------
// getMountType
//------------------------------------------------------------------------------
cta::MountType::Enum cta::RetrieveMount::getMountType() const throw() {
cta::MountType::Enum cta::RetrieveMount::getMountType() const{
return MountType::RETRIEVE;
}
//------------------------------------------------------------------------------
// getVid
//------------------------------------------------------------------------------
std::string cta::RetrieveMount::getVid() const throw() {
return "UNKNOWN_VID_FOR_RETRIEVE_MOUNT";
std::string cta::RetrieveMount::getVid() const{
return m_dbMount->mountInfo.vid;
}
//------------------------------------------------------------------------------
// getDensity
//------------------------------------------------------------------------------
std::string cta::RetrieveMount::getDensity() const throw() {
return "UNKNOWN_DENSITY_FOR_RETRIEVE_MOUNT";
std::string cta::RetrieveMount::getDensity() const{
return m_dbMount->mountInfo.density;
}
//------------------------------------------------------------------------------
// getMountTransactionId
//------------------------------------------------------------------------------
std::string cta::RetrieveMount::getMountTransactionId() const throw(){
return "UNKNOWN_MOUNTTRANSACTIONID_FOR_RETRIEVE_MOUNT";
std::string cta::RetrieveMount::getMountTransactionId() const{
std::stringstream id;
if (!m_dbMount.get())
throw exception::Exception("In cta::RetrieveMount::getMountTransactionId(): got NULL dbMount");
id << m_dbMount->mountInfo.mountId;
return id.str();
}
//------------------------------------------------------------------------------
......
......@@ -58,28 +58,28 @@ namespace cta {
*
* @return The type of this tape mount.
*/
virtual MountType::Enum getMountType() const throw();
virtual MountType::Enum getMountType() const;
/**
* Returns the volume identifier of the tape to be mounted.
*
* @return The volume identifier of the tape to be mounted.
*/
virtual std::string getVid() const throw();
virtual std::string getVid() const;
/**
* Returns the density of the tape to be mounted.
*
* @return The density of the tape to be mounted.
*/
virtual std::string getDensity() const throw();
virtual std::string getDensity() const;
/**
* Returns the mount transaction id.
*
* @return The mount transaction id.
*/
virtual std::string getMountTransactionId() const throw();
virtual std::string getMountTransactionId() const;
/**
* Indicates that the mount was completed.
......
......@@ -27,6 +27,7 @@
#include "common/Utils.hpp"
#include "common/SecurityIdentity.hpp"
#include "common/TapePool.hpp"
#include "common/CreationLog.hpp"
#include "nameserver/NameServer.hpp"
#include "remotens/RemoteNS.hpp"
#include "scheduler/ArchiveMount.hpp"
......@@ -400,10 +401,12 @@ void cta::Scheduler::createTape(
const std::string &logicalLibraryName,
const std::string &tapePoolName,
const uint64_t capacityInBytes,
const CreationLog &creationLog) {
const std::string &density,
const std::string & comment) {
m_db.assertIsAdminOnAdminHost(requester);
cta::CreationLog cl (requester.getUser(), requester.getHost(), time(NULL), comment);
m_db.createTape(vid, logicalLibraryName, tapePoolName,
capacityInBytes, creationLog);
capacityInBytes, density, cl);
}
//------------------------------------------------------------------------------
......
......@@ -439,7 +439,7 @@ public:
* belongs.
* @param tapePoolName The name of the tape pool to which the tape belongs.
* @param capacityInBytes The capacity of the tape.
* @param creationLog The who, where, when an why of this modification.
* @param comment reason for the creation of the tape
*/
virtual void createTape(
const SecurityIdentity &requester,
......@@ -447,7 +447,8 @@ public:
const std::string &logicalLibraryName,
const std::string &tapePoolName,
const uint64_t capacityInBytes,
const CreationLog &creationLog);
const std::string &density,
const std::string & comment);
/**
* Deletes the tape with the specified volume identifier.
......
......@@ -244,6 +244,7 @@ public:
std::string tapePool;
std::string drive;
uint64_t mountId;
std::string density;
} mountInfo;
virtual const MountInfo & getMountInfo() = 0;
virtual std::unique_ptr<RetrieveJob> getNextJob() = 0;
......@@ -594,6 +595,7 @@ public:
const std::string &logicalLibraryName,
const std::string &tapePoolName,
const uint64_t capacityInBytes,
const std::string &density,
const CreationLog &creationLog) = 0;
/**
......
......@@ -466,16 +466,16 @@ TEST_P(SchedulerDatabaseTest, getMountInfo) {
ASSERT_EQ(cl.time, tmdi.potentialMounts.front().oldestJobStartTime);
}
// Add 2 tapes
ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl),
ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, "8000GC", cl),
cta::exception::Exception);
db.createLogicalLibrary("Lib2", cl);
ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl),
ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, "8000GC", cl),
cta::exception::Exception);
db.createTapePool("pool2", 5, cl);
ASSERT_NO_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl));
ASSERT_NO_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, "8000GC", cl));
db.createLogicalLibrary("Lib3", cl);
db.createTapePool("pool3", 5, cl);
ASSERT_NO_THROW(db.createTape("Tape3", "Lib3", "pool3", 10L*1000*1000*1000*1000*1000, cl));
ASSERT_NO_THROW(db.createTape("Tape3", "Lib3", "pool3", 10L*1000*1000*1000*1000*1000, "8000GC", cl));
// Add retrieve jobs
std::list<TapeFileLocation> tcl;
tcl.push_back(TapeFileLocation());
......@@ -598,9 +598,9 @@ TEST_P(SchedulerDatabaseTest, createArchiveMountAndGetJob) {
"drive1", "lib1", "host1", time(NULL)), cta::OStoreDB::NoSuchTape);
}
// Add the tape (and library)
ASSERT_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, cl), cta::OStoreDB::NoSuchLibrary);
ASSERT_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, "8000GC", cl), cta::OStoreDB::NoSuchLibrary);
db.createLogicalLibrary("lib1", cl);
ASSERT_NO_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, cl));
ASSERT_NO_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, "8000GC", cl));
// This should go through
{
auto mountInfo = db.getMountInfo();
......
......@@ -886,11 +886,10 @@ TEST_P(SchedulerTest, admin_createTape_new) {
const std::string vid = "TestVid";
const uint64_t capacityInBytes = 12345678;
const std::string tapeDensity = "8000GC";
const std::string tapeComment = "Tape comment";
CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(),
time(NULL), tapeComment);
ASSERT_NO_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName, tapePoolName,
capacityInBytes, log));
capacityInBytes, tapeDensity, tapeComment));
{
std::list<Tape> tapes;
ASSERT_NO_THROW(tapes = scheduler.getTapes(s_adminOnAdminHost));
......@@ -964,11 +963,10 @@ TEST_P(SchedulerTest,
const std::string vid = "TestVid";
const uint64_t capacityInBytes = 12345678;
const std::string tapeDensity = "8000GC";
const std::string tapeComment = "Tape comment";
CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(),
time(NULL), tapeComment);
ASSERT_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName, tapePoolName,
capacityInBytes, log), std::exception);
capacityInBytes, tapeDensity, tapeComment), std::exception);
}
TEST_P(SchedulerTest, admin_createTape_new_non_existing_pool) {
......@@ -1014,11 +1012,10 @@ TEST_P(SchedulerTest, admin_createTape_new_non_existing_pool) {
const std::string vid = "TestVid";
const uint64_t capacityInBytes = 12345678;
const std::string tapeDensity = "8000GC";
const std::string tapeComment = "Tape comment";
CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(),
time(NULL), tapeComment);
ASSERT_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName, tapePoolName,
capacityInBytes, log), std::exception);
capacityInBytes, tapeDensity, tapeComment), std::exception);
}
TEST_P(SchedulerTest, getDirContents_root_dir_is_empty) {
......@@ -2329,11 +2326,10 @@ TEST_P(SchedulerTest, archive_and_retrieve_new_file) {
const std::string vid = "TestVid";
const uint64_t capacityInBytes = 12345678;
const std::string tapeComment = "Tape comment";
CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(),
time(NULL), tapeComment);
const std::string tapeDensity = "8000GC";
const std::string tapeComment = "Tape comment";
ASSERT_NO_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName,
tapePoolName, capacityInBytes, log));
tapePoolName, capacityInBytes, tapeDensity, tapeComment));
const uint16_t copyNb = 1;
const std::string archiveRouteComment = "Archive-route comment";
......@@ -2527,7 +2523,7 @@ TEST_P(SchedulerTest, setOwner_getOwner_root) {
Scheduler &scheduler = getScheduler();
const std::string dirPath = "/";
ASSERT_NO_THROW(scheduler.getOwner(s_adminOnAdminHost, dirPath));
ASSERT_NO_THROW(scheduler.getOwner(s_adminOnAdminHost, dirPath) );
ASSERT_NO_THROW(scheduler.setOwner(s_adminOnAdminHost, dirPath, s_user));
{
......
......@@ -35,28 +35,28 @@ namespace cta {
*
* @return The type of this tape mount.
*/
virtual MountType::Enum getMountType() const throw() = 0;
virtual MountType::Enum getMountType() const = 0;
/**
* Returns the volume identifier of the tape to be mounted.
*
* @return The volume identifier of the tape to be mounted.
*/
virtual std::string getVid() const throw() = 0;
virtual std::string getVid() const = 0;
/**
* Returns the density of the tape to be mounted.
*
* @return The density of the tape to be mounted.
*/
virtual std::string getDensity() const throw() = 0;
virtual std::string getDensity() const = 0;
/**
* Returns the mount transaction id.
*
* @return The mount transaction id.
*/
virtual std::string getMountTransactionId() const throw() = 0;
virtual std::string getMountTransactionId() const = 0;
/**
* Indicates that the mount was completed.
......
......@@ -195,6 +195,20 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
// files can be tested for at the end of the test
std::list<std::string> remoteFilePaths;
// 5) Create the tapepool, library and tape for the scheduler.
// Make mounts immediate.
ASSERT_NO_THROW(scheduler.createAdminUserWithoutAuthorizingRequester(requester, requester.getUser(), ""));
ASSERT_NO_THROW(scheduler.createAdminHostWithoutAuthorizingRequester(requester, requester.getHost(), ""));