CatalogueTest.cpp 268 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * The CERN Tape Archive (CTA) project
 * Copyright (C) 2015  CERN
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

#include "catalogue/ArchiveFileRow.hpp"
#include "catalogue/CatalogueFactory.hpp"
#include "catalogue/CatalogueTest.hpp"
#include "common/exception/Exception.hpp"
23
#include "common/exception/UserError.hpp"
24

25
#include <algorithm>
26
#include <gtest/gtest.h>
27
#include <limits>
28
29
30
31
32
33
#include <map>
#include <memory>
#include <set>

namespace unitTests {

34
35
36
37
38
39
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta_catalogue_CatalogueTest::cta_catalogue_CatalogueTest():
  m_bootstrapComment("bootstrap") {

Steven Murray's avatar
Steven Murray committed
40
41
  m_bootstrapAdmin.username = "bootstrap_admin_user_name";
  m_bootstrapAdmin.host = "bootstrap_host";
42

Steven Murray's avatar
Steven Murray committed
43
44
  m_admin.username = "admin_user_name";
  m_admin.host = "admin_host";
45
46
47
48
49
50
51
52
53
}

//------------------------------------------------------------------------------
// Setup
//------------------------------------------------------------------------------
void cta_catalogue_CatalogueTest::SetUp() {
  using namespace cta;
  using namespace cta::catalogue;

54
  try {
55
    const uint64_t nbConns = 2;
56
    m_catalogue = CatalogueFactory::create(GetParam()->create(), nbConns);
57

58
59
60
61
62
    {
      const std::list<common::dataStructures::AdminUser> adminUsers = m_catalogue->getAdminUsers();
      for(auto &adminUser: adminUsers) {
        m_catalogue->deleteAdminUser(adminUser.name);
      }
63
    }
64
65
66
67
68
    {
      const std::list<common::dataStructures::AdminHost> adminHosts = m_catalogue->getAdminHosts();
      for(auto &adminHost: adminHosts) {
        m_catalogue->deleteAdminHost(adminHost.name);
      }
69
    }
70
71
72
73
74
75
    {
      const std::list<common::dataStructures::ArchiveRoute> archiveRoutes = m_catalogue->getArchiveRoutes();
      for(auto &archiveRoute: archiveRoutes) {
        m_catalogue->deleteArchiveRoute(archiveRoute.diskInstanceName, archiveRoute.storageClassName,
          archiveRoute.copyNb);
      }
76
    }
77
78
79
80
81
    {
      const std::list<common::dataStructures::RequesterMountRule> rules = m_catalogue->getRequesterMountRules();
      for(auto &rule: rules) {
        m_catalogue->deleteRequesterMountRule(rule.diskInstance, rule.name);
      }
82
    }
83
84
85
86
87
88
    {
      const std::list<common::dataStructures::RequesterGroupMountRule> rules =
        m_catalogue->getRequesterGroupMountRules();
      for(auto &rule: rules) {
        m_catalogue->deleteRequesterGroupMountRule(rule.diskInstance, rule.name);
      }
89
    }
90
91
92
93
94
95
    {
      std::unique_ptr<ArchiveFileItor> itor = m_catalogue->getArchiveFileItor();
      while(itor->hasMore()) {
        const auto archiveFile = itor->next();
        m_catalogue->deleteArchiveFile(archiveFile.diskInstance, archiveFile.archiveFileID);
      }
96
    }
97
98
99
100
101
    {
      const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes();
      for(auto &tape: tapes) {
        m_catalogue->deleteTape(tape.vid);
      }
102
    }
103
104
105
106
107
    {
      const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();
      for(auto &storageClass: storageClasses) {
        m_catalogue->deleteStorageClass(storageClass.diskInstance, storageClass.name);
      }
108
    }
109
110
111
112
113
    {
      const std::list<common::dataStructures::TapePool> tapePools = m_catalogue->getTapePools();
      for(auto &tapePool: tapePools) {
        m_catalogue->deleteTapePool(tapePool.name);
      }
114
    }
115
116
117
118
119
    {
      const std::list<common::dataStructures::LogicalLibrary> logicalLibraries = m_catalogue->getLogicalLibraries();
      for(auto &logicalLibrary: logicalLibraries) {
        m_catalogue->deleteLogicalLibrary(logicalLibrary.name);
      }
120
    }
121
122
123
124
125
    {
      const std::list<common::dataStructures::MountPolicy> mountPolicies = m_catalogue->getMountPolicies();
      for(auto &mountPolicy: mountPolicies) {
        m_catalogue->deleteMountPolicy(mountPolicy.name);
      }
126
    }
127
128
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  }
}

//------------------------------------------------------------------------------
// TearDown
//------------------------------------------------------------------------------
void cta_catalogue_CatalogueTest::TearDown() {
  m_catalogue.reset();
}

//------------------------------------------------------------------------------
// tapeListToMap
//------------------------------------------------------------------------------
std::map<std::string, cta::common::dataStructures::Tape> cta_catalogue_CatalogueTest::tapeListToMap(
  const std::list<cta::common::dataStructures::Tape> &listOfTapes) {
  using namespace cta;

  try {
    std::map<std::string, cta::common::dataStructures::Tape> vidToTape;

149
    for (auto &tape: listOfTapes) {
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
      if(vidToTape.end() != vidToTape.find(tape.vid)) {
        throw exception::Exception(std::string("Duplicate VID: value=") + tape.vid);
      }
      vidToTape[tape.vid] = tape;
    }

    return vidToTape;
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

//------------------------------------------------------------------------------
// archiveFileItorToMap
//------------------------------------------------------------------------------
std::map<uint64_t, cta::common::dataStructures::ArchiveFile> cta_catalogue_CatalogueTest::archiveFileItorToMap(
  cta::catalogue::ArchiveFileItor &itor) {
  using namespace cta;

  try {
    std::map<uint64_t, common::dataStructures::ArchiveFile> m;
    while(itor.hasMore()) {
172
      const auto archiveFile = itor.next();
173
174
175
176
177
178
179
180
181
182
183
184
185
      if(m.end() != m.find(archiveFile.archiveFileID)) {
        exception::Exception ex;
        ex.getMessage() << "Archive file with ID " << archiveFile.archiveFileID << " is a duplicate";
        throw ex;
      }
      m[archiveFile.archiveFileID] = archiveFile;
    }
    return m;
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//------------------------------------------------------------------------------
// adminUserListToMap
//------------------------------------------------------------------------------
std::map<std::string, cta::common::dataStructures::AdminUser> cta_catalogue_CatalogueTest::adminUserListToMap(
  const std::list<cta::common::dataStructures::AdminUser> &listOfAdminUsers) {
  using namespace cta;

  try {
    std::map<std::string, common::dataStructures::AdminUser> m;

    for(auto &adminUser: listOfAdminUsers) {
      if(m.end() != m.find(adminUser.name)) {
        exception::Exception ex;
        ex.getMessage() << "Admin user " << adminUser.name << " is a duplicate";
        throw ex;
      }
      m[adminUser.name] = adminUser;
    }
    return m;
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
//------------------------------------------------------------------------------
// adminHostListToMap
//------------------------------------------------------------------------------
std::map<std::string, cta::common::dataStructures::AdminHost> cta_catalogue_CatalogueTest::adminHostListToMap(
  const std::list<cta::common::dataStructures::AdminHost> &listOfAdminHosts) {
  using namespace cta;

  try {
    std::map<std::string, common::dataStructures::AdminHost> m;

    for(auto &adminHost: listOfAdminHosts) {
      if(m.end() != m.find(adminHost.name)) {
        exception::Exception ex;
        ex.getMessage() << "Admin host " << adminHost.name << " is a duplicate";
        throw ex;
      }
      m[adminHost.name] = adminHost;
    }
    return m;
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

234
235
236
237
238
239
240
TEST_P(cta_catalogue_CatalogueTest, createBootstrapAdminAndHostNoAuth) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());
  ASSERT_TRUE(m_catalogue->getAdminHosts().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
241
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
242
243
244
245
246
247
248
249
250
251

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
252
253
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

  {
    std::list<common::dataStructures::AdminHost> hosts;
    hosts = m_catalogue->getAdminHosts();
    ASSERT_EQ(1, hosts.size());

    const common::dataStructures::AdminHost host = hosts.front();
    ASSERT_EQ(m_bootstrapComment, host.comment);

    const common::dataStructures::EntryLog creationLog = host.creationLog;
Steven Murray's avatar
Steven Murray committed
269
270
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
271
272
273
274
275
276
277
278
279
280
281
282
283

    const common::dataStructures::EntryLog lastModificationLog =
      host.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }
}

TEST_P(cta_catalogue_CatalogueTest, createAdminUser) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
284
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
285
286
287
288
289
290
291
292
293
294

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
295
296
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
297
298
299
300
301
302

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

303
  const std::string createAdminUserComment = "Create admin user";
Steven Murray's avatar
Steven Murray committed
304
  m_catalogue->createAdminUser(m_bootstrapAdmin, m_admin.username, createAdminUserComment);
305
306
307
308
309
310
311
312
313
314
315

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(2, admins.size());

    const common::dataStructures::AdminUser a1 = admins.front();
    admins.pop_front();
    const common::dataStructures::AdminUser a2 = admins.front();

    ASSERT_NE(a1, a2);
Steven Murray's avatar
Steven Murray committed
316
317
    ASSERT_TRUE((a1.name == m_bootstrapAdmin.username && a2.name == m_admin.username) ||
      (a2.name == m_bootstrapAdmin.username && a1.name == m_admin.username));
318

Steven Murray's avatar
Steven Murray committed
319
320
    if(a1.name == m_bootstrapAdmin.username) {
      ASSERT_EQ(m_bootstrapAdmin.username, a1.name);
321
      ASSERT_EQ(m_bootstrapComment, a1.comment);
Steven Murray's avatar
Steven Murray committed
322
323
324
325
      ASSERT_EQ(m_admin.username, a1.creationLog.username);
      ASSERT_EQ(m_admin.host, a1.creationLog.host);
      ASSERT_EQ(m_admin.username, a1.lastModificationLog.username);
      ASSERT_EQ(m_admin.host, a1.lastModificationLog.host);
326

Steven Murray's avatar
Steven Murray committed
327
      ASSERT_EQ(m_admin.username, a2.name);
328
      ASSERT_EQ(createAdminUserComment, a2.comment);
Steven Murray's avatar
Steven Murray committed
329
330
331
332
      ASSERT_EQ(m_bootstrapAdmin.username, a2.creationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, a2.creationLog.host);
      ASSERT_EQ(m_bootstrapAdmin.username, a2.lastModificationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, a2.lastModificationLog.host);
333
    } else {
Steven Murray's avatar
Steven Murray committed
334
      ASSERT_EQ(m_bootstrapAdmin.username, a2.name);
335
      ASSERT_EQ(m_bootstrapComment, a2.comment);
Steven Murray's avatar
Steven Murray committed
336
337
338
339
      ASSERT_EQ(m_admin.username, a2.creationLog.username);
      ASSERT_EQ(m_admin.host, a2.creationLog.host);
      ASSERT_EQ(m_admin.username, a2.lastModificationLog.username);
      ASSERT_EQ(m_admin.host, a2.lastModificationLog.host);
340

Steven Murray's avatar
Steven Murray committed
341
      ASSERT_EQ(m_admin.username, a1.name);
342
      ASSERT_EQ(createAdminUserComment, a1.comment);
Steven Murray's avatar
Steven Murray committed
343
344
345
346
      ASSERT_EQ(m_bootstrapAdmin.username, a1.creationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, a1.creationLog.host);
      ASSERT_EQ(m_bootstrapAdmin.username, a1.lastModificationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, a1.lastModificationLog.host);
347
348
349
350
351
352
353
354
355
356
    }
  }
}

TEST_P(cta_catalogue_CatalogueTest, createAdminUser_same_twice) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
357
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
358
359
360
361
362
363
364
365
366
367

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
368
369
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
370
371
372
373
374
375

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

Steven Murray's avatar
Steven Murray committed
376
  m_catalogue->createAdminUser(m_bootstrapAdmin, m_admin.username, "comment 1");
377

Steven Murray's avatar
Steven Murray committed
378
  ASSERT_THROW(m_catalogue->createAdminUser(m_bootstrapAdmin, m_admin.username,
379
    "comment 2"), exception::UserError);
380
381
382
383
384
385
386
387
}

TEST_P(cta_catalogue_CatalogueTest, deleteAdminUser) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
388
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
389
390
391
392
393
394
395
396
397
398

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
399
400
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
401
402
403
404
405
406

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

Steven Murray's avatar
Steven Murray committed
407
  m_catalogue->deleteAdminUser(m_bootstrapAdmin.username);
408
409
410
411
412
413
414
415

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());
}

TEST_P(cta_catalogue_CatalogueTest, deleteAdminUser_non_existant) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());
416
  ASSERT_THROW(m_catalogue->deleteAdminUser("non_existant_sdmin_user"), exception::UserError);
417
418
}

419
420
421
422
423
424
TEST_P(cta_catalogue_CatalogueTest, modifyAdminUserComment) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
425
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
426
427
428
429
430
431
432
433
434
435

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
436
437
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
438
439
440
441
442
443
444

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

  const std::string createAdminUserComment = "Create admin user";
Steven Murray's avatar
Steven Murray committed
445
  m_catalogue->createAdminUser(m_bootstrapAdmin, m_admin.username, createAdminUserComment);
446
447
448
449
450

  {
    std::map<std::string, common::dataStructures::AdminUser> admins = adminUserListToMap(m_catalogue->getAdminUsers());
    ASSERT_EQ(2, admins.size());

Steven Murray's avatar
Steven Murray committed
451
    const auto itor = admins.find(m_admin.username);
452
453
454
455
456
457
    ASSERT_FALSE(admins.end() == itor);

    ASSERT_EQ(createAdminUserComment, itor->second.comment);
  }

  const std::string modifiedComment = "Modified comment";
Steven Murray's avatar
Steven Murray committed
458
  m_catalogue->modifyAdminUserComment(m_bootstrapAdmin, m_admin.username, modifiedComment);
459
460
461
462
463

  {
    std::map<std::string, common::dataStructures::AdminUser> admins = adminUserListToMap(m_catalogue->getAdminUsers());
    ASSERT_EQ(2, admins.size());

Steven Murray's avatar
Steven Murray committed
464
    const auto itor = admins.find(m_admin.username);
465
466
467
468
469
470
    ASSERT_FALSE(admins.end() == itor);

    ASSERT_EQ(modifiedComment, itor->second.comment);
  }
}

471
472
473
474
475
476
TEST_P(cta_catalogue_CatalogueTest, modifyAdminUserComment_nonExtistentAdminUser) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminUsers().empty());

  const std::string modifiedComment = "Modified comment";
Steven Murray's avatar
Steven Murray committed
477
  ASSERT_THROW(m_catalogue->modifyAdminUserComment(m_bootstrapAdmin, m_admin.username, modifiedComment),
478
479
480
    exception::UserError);
}

481
482
483
484
485
486
TEST_P(cta_catalogue_CatalogueTest, createAdminHost) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminHosts().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
487
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
488
489
490
491
492
493
494
495
496
497

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
498
499
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
500
501
502
503
504
505

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

506
  const std::string createAdminHostComment = "Create host user";
507
  const std::string anotherAdminHost = "another_admin_host";
Steven Murray's avatar
Steven Murray committed
508
  m_catalogue->createAdminHost(m_bootstrapAdmin,
509
510
511
512
513
514
515
516
517
518
519
520
521
    anotherAdminHost, createAdminHostComment);

  {
    std::list<common::dataStructures::AdminHost> hosts;
    hosts = m_catalogue->getAdminHosts();
    ASSERT_EQ(2, hosts.size());

    const common::dataStructures::AdminHost h1 = hosts.front();
    hosts.pop_front();
    const common::dataStructures::AdminHost h2 = hosts.front();

    ASSERT_NE(h1, h2);
    ASSERT_TRUE(
Steven Murray's avatar
Steven Murray committed
522
      (h1.name == m_bootstrapAdmin.host && h2.name == anotherAdminHost)
523
      ||
Steven Murray's avatar
Steven Murray committed
524
      (h2.name == anotherAdminHost && h1.name == m_bootstrapAdmin.host)
525
526
    );

Steven Murray's avatar
Steven Murray committed
527
528
    if(h1.name == m_bootstrapAdmin.host) {
      ASSERT_EQ(m_bootstrapAdmin.host, h1.name);
529
      ASSERT_EQ(m_bootstrapComment, h1.comment);
Steven Murray's avatar
Steven Murray committed
530
531
532
533
      ASSERT_EQ(m_admin.username, h1.creationLog.username);
      ASSERT_EQ(m_admin.host, h1.creationLog.host);
      ASSERT_EQ(m_admin.username, h1.lastModificationLog.username);
      ASSERT_EQ(m_admin.host, h1.lastModificationLog.host);
534
535
536

      ASSERT_EQ(anotherAdminHost, h2.name);
      ASSERT_EQ(createAdminHostComment, h2.comment);
Steven Murray's avatar
Steven Murray committed
537
538
539
540
      ASSERT_EQ(m_bootstrapAdmin.username, h2.creationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, h2.creationLog.host);
      ASSERT_EQ(m_bootstrapAdmin.username, h2.lastModificationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, h2.lastModificationLog.host);
541
    } else {
Steven Murray's avatar
Steven Murray committed
542
      ASSERT_EQ(m_bootstrapAdmin.host, h2.name);
543
      ASSERT_EQ(m_bootstrapComment, h2.comment);
Steven Murray's avatar
Steven Murray committed
544
545
546
547
      ASSERT_EQ(m_admin.username, h2.creationLog.username);
      ASSERT_EQ(m_admin.host, h2.creationLog.host);
      ASSERT_EQ(m_admin.username, h2.lastModificationLog.username);
      ASSERT_EQ(m_admin.host, h2.lastModificationLog.host);
548
549
550

      ASSERT_EQ(anotherAdminHost, h1.name);
      ASSERT_EQ(createAdminHostComment, h1.comment);
Steven Murray's avatar
Steven Murray committed
551
552
553
554
      ASSERT_EQ(m_bootstrapAdmin.username, h1.creationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, h1.creationLog.host);
      ASSERT_EQ(m_bootstrapAdmin.username, h1.lastModificationLog.username);
      ASSERT_EQ(m_bootstrapAdmin.host, h1.lastModificationLog.host);
555
556
557
558
559
560
561
562
    }
  }
}

TEST_P(cta_catalogue_CatalogueTest, createAdminHost_same_twice) {
  using namespace cta;

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
563
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
564
565
566
567
568
569
570
571
572
573

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
574
575
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
576
577
578
579
580
581
582
583

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

  const std::string anotherAdminHost = "another_admin_host";

Steven Murray's avatar
Steven Murray committed
584
  m_catalogue->createAdminHost(m_bootstrapAdmin, anotherAdminHost, "comment 1");
585

Steven Murray's avatar
Steven Murray committed
586
  ASSERT_THROW(m_catalogue->createAdminHost(m_bootstrapAdmin,
587
    anotherAdminHost, "comment 2"), exception::UserError);
588
589
590
591
592
593
594
595
}

TEST_P(cta_catalogue_CatalogueTest, deleteAdminHost) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminHosts().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
596
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
597
598
599
600
601
602
603
604
605
606

  {
    std::list<common::dataStructures::AdminUser> admins;
    admins = m_catalogue->getAdminUsers();
    ASSERT_EQ(1, admins.size());

    const common::dataStructures::AdminUser admin = admins.front();
    ASSERT_EQ(m_bootstrapComment, admin.comment);

    const common::dataStructures::EntryLog creationLog = admin.creationLog;
Steven Murray's avatar
Steven Murray committed
607
608
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
609
610
611
612
613
614

    const common::dataStructures::EntryLog lastModificationLog =
      admin.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

Steven Murray's avatar
Steven Murray committed
615
  m_catalogue->deleteAdminHost(m_bootstrapAdmin.host);
616
617
618
619
620
621
622
623

  ASSERT_TRUE(m_catalogue->getAdminHosts().empty());
}

TEST_P(cta_catalogue_CatalogueTest, deleteAdminHost_non_existant) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminHosts().empty());
624
  ASSERT_THROW(m_catalogue->deleteAdminHost("non_exstant_admin_host"), exception::UserError);
625
626
}

627
628
629
630
631
632
TEST_P(cta_catalogue_CatalogueTest, modifyAdminHostComment) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getAdminHosts().empty());

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
633
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
634
635
636
637
638
639
640
641
642

  {
    const std::list<common::dataStructures::AdminHost> hosts = m_catalogue->getAdminHosts();
    ASSERT_EQ(1, hosts.size());

    const common::dataStructures::AdminHost host = hosts.front();
    ASSERT_EQ(m_bootstrapComment, host.comment);

    const common::dataStructures::EntryLog creationLog = host.creationLog;
Steven Murray's avatar
Steven Murray committed
643
644
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
645
646
647
648
649
650
651

    const common::dataStructures::EntryLog lastModificationLog = host.lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

  const std::string createAdminHostComment = "Create host user";
  const std::string anotherAdminHost = "another_admin_host";
Steven Murray's avatar
Steven Murray committed
652
  m_catalogue->createAdminHost(m_bootstrapAdmin, anotherAdminHost, createAdminHostComment);
653
654
655
656
657
658
659
660
661
662
663
664

  {
    std::map<std::string, common::dataStructures::AdminHost> hosts = adminHostListToMap(m_catalogue->getAdminHosts());
    ASSERT_EQ(2, hosts.size());

    const auto itor = hosts.find(anotherAdminHost);
    ASSERT_FALSE(hosts.end() == itor);

    ASSERT_EQ(createAdminHostComment, itor->second.comment);
  }

  const std::string modifiedComment = "Modified comment";
Steven Murray's avatar
Steven Murray committed
665
  m_catalogue->modifyAdminHostComment(m_bootstrapAdmin, anotherAdminHost, modifiedComment);
666
667
668
669
670
671
672
673
674
675
676
677

  {
    std::map<std::string, common::dataStructures::AdminHost> hosts = adminHostListToMap(m_catalogue->getAdminHosts());
    ASSERT_EQ(2, hosts.size());

    const auto itor = hosts.find(anotherAdminHost);
    ASSERT_FALSE(hosts.end() == itor);

    ASSERT_EQ(modifiedComment, itor->second.comment);
  }
}

678
679
680
TEST_P(cta_catalogue_CatalogueTest, isAdmin_false) {
  using namespace cta;

Steven Murray's avatar
Steven Murray committed
681
  ASSERT_FALSE(m_catalogue->isAdmin(m_admin));
682
683
684
685
686
687
}

TEST_P(cta_catalogue_CatalogueTest, isAdmin_true) {
  using namespace cta;

  m_catalogue->createBootstrapAdminAndHostNoAuth(
Steven Murray's avatar
Steven Murray committed
688
    m_admin, m_bootstrapAdmin.username, m_bootstrapAdmin.host, m_bootstrapComment);
689

Steven Murray's avatar
Steven Murray committed
690
  ASSERT_TRUE(m_catalogue->isAdmin(m_bootstrapAdmin));
691
692
693
694
695
696
697
}

TEST_P(cta_catalogue_CatalogueTest, createStorageClass) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());

698
699
700
701
  common::dataStructures::StorageClass storageClass;
  storageClass.diskInstance = "disk_instance";
  storageClass.name = "storage_class";
  storageClass.nbCopies = 2;
702
  storageClass.comment = "Create storage class";
Steven Murray's avatar
Steven Murray committed
703
  m_catalogue->createStorageClass(m_admin, storageClass);
704
705
706
707
708
709

  const std::list<common::dataStructures::StorageClass> storageClasses =
    m_catalogue->getStorageClasses();

  ASSERT_EQ(1, storageClasses.size());

710
711
712
713
  ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
  ASSERT_EQ(storageClass.name, storageClasses.front().name);
  ASSERT_EQ(storageClass.nbCopies, storageClasses.front().nbCopies);
  ASSERT_EQ(storageClass.comment, storageClasses.front().comment);
714

715
  const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
Steven Murray's avatar
Steven Murray committed
716
717
  ASSERT_EQ(m_admin.username, creationLog.username);
  ASSERT_EQ(m_admin.host, creationLog.host);
718

719
  const common::dataStructures::EntryLog lastModificationLog = storageClasses.front().lastModificationLog;
720
721
722
723
724
725
  ASSERT_EQ(creationLog, lastModificationLog);
}

TEST_P(cta_catalogue_CatalogueTest, createStorageClass_same_twice) {
  using namespace cta;

726
727
728
729
  common::dataStructures::StorageClass storageClass;
  storageClass.diskInstance = "disk_instance";
  storageClass.name = "storage_class";
  storageClass.nbCopies = 2;
730
  storageClass.comment = "Create storage class";
Steven Murray's avatar
Steven Murray committed
731
732
  m_catalogue->createStorageClass(m_admin, storageClass);
  ASSERT_THROW(m_catalogue->createStorageClass(m_admin, storageClass), exception::UserError);
733
734
}

735
736
737
738
739
740
741
TEST_P(cta_catalogue_CatalogueTest, createStorageClass_same_name_different_disk_instance) {
  using namespace cta;

  common::dataStructures::StorageClass storageClass1;
  storageClass1.diskInstance = "disk_instance_1";
  storageClass1.name = "storage_class";
  storageClass1.nbCopies = 2;
742
  storageClass1.comment = "Create storage class";
743
744
745
746

  common::dataStructures::StorageClass storageClass2 = storageClass1;
  storageClass2.diskInstance = "disk_instance_2";

Steven Murray's avatar
Steven Murray committed
747
748
  m_catalogue->createStorageClass(m_admin, storageClass1);
  m_catalogue->createStorageClass(m_admin, storageClass2);
749
750
751
752
753
754

  const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();

  ASSERT_EQ(2, storageClasses.size());

  {
755
756
757
758
    auto eqStorageClass1 = [&storageClass1](const common::dataStructures::StorageClass &obj) {
      return obj.diskInstance == storageClass1.diskInstance && obj.name == storageClass1.name;
    };
    auto itor = std::find_if(storageClasses.begin(), storageClasses.end(), eqStorageClass1);
759
760
761
762
    ASSERT_FALSE(itor == storageClasses.end());
  }

  {
763
764
765
766
    auto eqStorageClass2 = [&storageClass2](const common::dataStructures::StorageClass &obj) {
      return obj.diskInstance == storageClass2.diskInstance && obj.name == storageClass2.name;
    };
    auto itor = std::find_if(storageClasses.begin(), storageClasses.end(), eqStorageClass2);
767
768
769
770
    ASSERT_FALSE(itor == storageClasses.end());
  }
}

771
772
773
774
775
TEST_P(cta_catalogue_CatalogueTest, deleteStorageClass) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());

776
777
778
779
  common::dataStructures::StorageClass storageClass;
  storageClass.diskInstance = "disk_instance";
  storageClass.name = "storage_class";
  storageClass.nbCopies = 2;
780
  storageClass.comment = "Create storage class";
Steven Murray's avatar
Steven Murray committed
781
  m_catalogue->createStorageClass(m_admin, storageClass);
782
783
784
785
786
787

  const std::list<common::dataStructures::StorageClass> storageClasses =
    m_catalogue->getStorageClasses();

  ASSERT_EQ(1, storageClasses.size());

788
789
790
791
  ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
  ASSERT_EQ(storageClass.name, storageClasses.front().name);
  ASSERT_EQ(storageClass.nbCopies, storageClasses.front().nbCopies);
  ASSERT_EQ(storageClass.comment, storageClasses.front().comment);
792

793
  const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
Steven Murray's avatar
Steven Murray committed
794
795
  ASSERT_EQ(m_admin.username, creationLog.username);
  ASSERT_EQ(m_admin.host, creationLog.host);
796

797
  const common::dataStructures::EntryLog lastModificationLog = storageClasses.front().lastModificationLog;
798
799
  ASSERT_EQ(creationLog, lastModificationLog);

800
  m_catalogue->deleteStorageClass(storageClass.diskInstance, storageClass.name);
801
802
803
804
805
806
807
  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());
}

TEST_P(cta_catalogue_CatalogueTest, deleteStorageClass_non_existant) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());
808
809
  ASSERT_THROW(m_catalogue->deleteStorageClass("non_existant_disk_instance", "non_existant_storage_class"),
    exception::UserError);
810
811
}

812
813
814
815
816
817
818
819
820
821
TEST_P(cta_catalogue_CatalogueTest, modifyStorageClassNbCopies) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());

  common::dataStructures::StorageClass storageClass;
  storageClass.diskInstance = "disk_instance";
  storageClass.name = "storage_class";
  storageClass.nbCopies = 2;
  storageClass.comment = "Create storage class";
Steven Murray's avatar
Steven Murray committed
822
  m_catalogue->createStorageClass(m_admin, storageClass);
823
824
825
826
827
828
829
830
831
832
833
834

  {
    const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();

    ASSERT_EQ(1, storageClasses.size());

    ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
    ASSERT_EQ(storageClass.name, storageClasses.front().name);
    ASSERT_EQ(storageClass.nbCopies, storageClasses.front().nbCopies);
    ASSERT_EQ(storageClass.comment, storageClasses.front().comment);

    const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
Steven Murray's avatar
Steven Murray committed
835
836
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
837
838
839
840
841
842

    const common::dataStructures::EntryLog lastModificationLog = storageClasses.front().lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

  const uint64_t modifiedNbCopies = 5;
Steven Murray's avatar
Steven Murray committed
843
  m_catalogue->modifyStorageClassNbCopies(m_admin, storageClass.diskInstance, storageClass.name, modifiedNbCopies);
844
845
846
847
848
849
850
851
852
853
854
855

  {
    const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();

    ASSERT_EQ(1, storageClasses.size());

    ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
    ASSERT_EQ(storageClass.name, storageClasses.front().name);
    ASSERT_EQ(modifiedNbCopies, storageClasses.front().nbCopies);
    ASSERT_EQ(storageClass.comment, storageClasses.front().comment);

    const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
Steven Murray's avatar
Steven Murray committed
856
857
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
858
859
860
  }
}

861
862
863
864
865
866
867
868
TEST_P(cta_catalogue_CatalogueTest, modifyStorageClassNbCopies_nonExistentStorageClass) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());

  const std::string diskInstance = "disk_instance";
  const std::string storageClassName = "storage_class";
  const uint64_t nbCopies = 5;
Steven Murray's avatar
Steven Murray committed
869
  ASSERT_THROW(m_catalogue->modifyStorageClassNbCopies(m_admin, diskInstance, storageClassName, nbCopies),
870
871
872
    exception::UserError);
}

873
874
875
876
877
878
879
880
881
882
TEST_P(cta_catalogue_CatalogueTest, modifyStorageClassComment) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());

  common::dataStructures::StorageClass storageClass;
  storageClass.diskInstance = "disk_instance";
  storageClass.name = "storage_class";
  storageClass.nbCopies = 2;
  storageClass.comment = "Create storage class";
Steven Murray's avatar
Steven Murray committed
883
  m_catalogue->createStorageClass(m_admin, storageClass);
884
885
886
887
888
889
890
891
892
893
894
895

  {
    const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();

    ASSERT_EQ(1, storageClasses.size());

    ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
    ASSERT_EQ(storageClass.name, storageClasses.front().name);
    ASSERT_EQ(storageClass.nbCopies, storageClasses.front().nbCopies);
    ASSERT_EQ(storageClass.comment, storageClasses.front().comment);

    const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
Steven Murray's avatar
Steven Murray committed
896
897
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
898
899
900
901
902
903

    const common::dataStructures::EntryLog lastModificationLog = storageClasses.front().lastModificationLog;
    ASSERT_EQ(creationLog, lastModificationLog);
  }

  const std::string modifiedComment = "Modified comment";
Steven Murray's avatar
Steven Murray committed
904
  m_catalogue->modifyStorageClassComment(m_admin, storageClass.diskInstance, storageClass.name, modifiedComment);
905
906
907
908
909
910
911
912
913
914
915
916

  {
    const std::list<common::dataStructures::StorageClass> storageClasses = m_catalogue->getStorageClasses();

    ASSERT_EQ(1, storageClasses.size());

    ASSERT_EQ(storageClass.diskInstance, storageClasses.front().diskInstance);
    ASSERT_EQ(storageClass.name, storageClasses.front().name);
    ASSERT_EQ(storageClass.nbCopies, storageClasses.front().nbCopies);
    ASSERT_EQ(modifiedComment, storageClasses.front().comment);

    const common::dataStructures::EntryLog creationLog = storageClasses.front().creationLog;
Steven Murray's avatar
Steven Murray committed
917
918
    ASSERT_EQ(m_admin.username, creationLog.username);
    ASSERT_EQ(m_admin.host, creationLog.host);
919
920
921
  }
}

922
923
924
925
926
927
928
929
TEST_P(cta_catalogue_CatalogueTest, modifyStorageClassComment_nonExistentStorageClass) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getStorageClasses().empty());

  const std::string diskInstance = "disk_instance";
  const std::string storageClassName = "storage_class";
  const std::string comment = "Comment";
Steven Murray's avatar
Steven Murray committed
930
  ASSERT_THROW(m_catalogue->modifyStorageClassComment(m_admin, diskInstance, storageClassName, comment),
931
932
933
    exception::UserError);
}

934
935
936
937
938
939
940
TEST_P(cta_catalogue_CatalogueTest, createTapePool) {
  using namespace cta;
      
  ASSERT_TRUE(m_catalogue->getTapePools().empty());
      
  const std::string tapePoolName = "tape_pool";
  const uint64_t nbPartialTapes = 2;
941
  const bool isEncrypted = true;
942
  const std::string comment = "Create tape pool";
Steven Murray's avatar
Steven Murray committed
943
  m_catalogue->createTapePool(m_admin, tapePoolName, nbPartialTapes, isEncrypted,
944
945
946
947
948
949
950
951
952
953
    comment);
      
  const std::list<common::dataStructures::TapePool> pools =
    m_catalogue->getTapePools();
      
  ASSERT_EQ(1, pools.size());
      
  const common::dataStructures::TapePool pool = pools.front();
  ASSERT_EQ(tapePoolName, pool.name);
  ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
954
  ASSERT_EQ(isEncrypted, pool.encryption);
955
956
957
  ASSERT_EQ(comment, pool.comment);

  const common::dataStructures::EntryLog creationLog = pool.creationLog;
Steven Murray's avatar
Steven Murray committed
958
959
  ASSERT_EQ(m_admin.username, creationLog.username);
  ASSERT_EQ(m_admin.host, creationLog.host);
960
961
962
963
964
965
966
967
968
969
970
  
  const common::dataStructures::EntryLog lastModificationLog =
    pool.lastModificationLog;
  ASSERT_EQ(creationLog, lastModificationLog);
}
  
TEST_P(cta_catalogue_CatalogueTest, createTapePool_same_twice) {
  using namespace cta;
  
  const std::string tapePoolName = "tape_pool";
  const uint64_t nbPartialTapes = 2;
971
  const bool isEncrypted = true;
972
  const std::string comment = "Create tape pool";
Steven Murray's avatar
Steven Murray committed
973
  m_catalogue->createTapePool(m_admin, tapePoolName, nbPartialTapes, isEncrypted,
974
    comment);
Steven Murray's avatar
Steven Murray committed
975
  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, nbPartialTapes, isEncrypted, comment),
976
    exception::UserError);
977
978
979
980
981
982
983
984
985
}

TEST_P(cta_catalogue_CatalogueTest, deleteTapePool) {
  using namespace cta;

  ASSERT_TRUE(m_catalogue->getTapePools().empty());

  const std::string tapePoolName = "tape_pool";
  const uint64_t nbPartialTapes = 2;
986
  const bool isEncrypted = true;
987
  const std::string comment = "Create tape pool";
Steven Murray's avatar
Steven Murray committed
988
  m_catalogue->createTapePool(m_admin, tapePoolName, nbPartialTapes, isEncrypted,
989
990
991
992
993
994
995
996
997
998
    comment);

  const std::list<common::dataStructures::TapePool> pools =
    m_catalogue->getTapePools();

  ASSERT_EQ(1, pools.size());

  const common::dataStructures::TapePool pool = pools.front();
  ASSERT_EQ(tapePoolName, pool.name);
  ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
999
  ASSERT_EQ(isEncrypted, pool.encryption);
1000
  ASSERT_EQ(comment, pool.comment);
For faster browsing, not all history is shown. View entire blame