cql_lease_mgr_unittest.cc 29.9 KB
Newer Older
1
// Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
2
// Copyright (C) 2015-2017 Deutsche Telekom AG.
3
//
4 5
// Authors: Razvan Becheriu <razvan.becheriu@qualitance.com>
//          Andrei Pavel <andrei.pavel@qualitance.com>
6 7 8 9 10 11 12 13 14 15 16 17
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//           http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
18 19 20 21

#include <config.h>

#include <asiolink/io_address.h>
22
#include <cql/cql_connection.h>
23
#include <cql/testutils/cql_schema.h>
24
#include <dhcpsrv/lease_mgr_factory.h>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
25
#include <dhcpsrv/cql_lease_mgr.h>
Andrei Pavel's avatar
Andrei Pavel committed
26
#include <dhcpsrv/tests/test_utils.h>
27
#include <dhcpsrv/tests/generic_lease_mgr_unittest.h>
28 29
#include <exceptions/exceptions.h>

30 31
#include <gtest/gtest.h>

32
#include <algorithm>
33
#include <iostream>
34 35 36 37 38 39
#include <sstream>
#include <string>
#include <utility>

using namespace isc;
using namespace isc::asiolink;
40
using namespace isc::db;
41
using namespace isc::db::test;
42 43
using namespace isc::dhcp;
using namespace isc::dhcp::test;
44
using namespace std;
45 46 47

namespace {

48

Tomek Mrugalski's avatar
Tomek Mrugalski committed
49
/// @brief Test fixture class for testing Cassandra Lease Manager
50 51 52
///
/// Opens the database prior to each test and closes it afterwards.
/// All pending transactions are deleted prior to closure.
53

Tomek Mrugalski's avatar
Tomek Mrugalski committed
54
class CqlLeaseMgrTest : public GenericLeaseMgrTest {
55
public:
56 57
    /// @brief Clears the database and opens connection to it.
    void initializeTest() {
Thomas Markwalder's avatar
Thomas Markwalder committed
58 59
        // Ensure we have the proper schema with no transient data.
        createCqlSchema();
60 61 62

        // Connect to the database
        try {
Tomek Mrugalski's avatar
Tomek Mrugalski committed
63
            LeaseMgrFactory::create(validCqlConnectionString());
64 65 66
        } catch (...) {
            std::cerr << "*** ERROR: unable to open database. The test\n"
                         "*** environment is broken and must be fixed before\n"
Tomek Mrugalski's avatar
Tomek Mrugalski committed
67
                         "*** the CQL tests will run correctly.\n"
68 69 70 71
                         "*** The reason for the problem is described in the\n"
                         "*** accompanying exception output.\n";
            throw;
        }
72

73 74 75
        lmptr_ = &(LeaseMgrFactory::instance());
    }

76 77 78 79 80 81 82 83
    /// @brief Destroys the LM and the schema.
    void destroyTest() {
        try {
            lmptr_->rollback();
        } catch (...) {
            // Rollback may fail if backend is in read only mode. That's ok.
        }
        LeaseMgrFactory::destroy();
Thomas Markwalder's avatar
Thomas Markwalder committed
84 85
        // If data wipe enabled, delete transient data otherwise destroy the schema
        destroyCqlSchema();
86 87 88 89 90 91 92 93 94
    }

    /// @brief Constructor
    ///
    /// Deletes everything from the database and opens it.
    CqlLeaseMgrTest() {
        initializeTest();
    }

95 96
    /// @brief Destructor
    ///
97 98
    /// Rolls back all pending transactions.  The deletion of lmptr_ will close
    /// the database.  Then reopen it and delete everything created by the test.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
99
    virtual ~CqlLeaseMgrTest() {
100
        destroyTest();
101 102 103 104
    }

    /// @brief Reopen the database
    ///
105
    /// Closes the database and re-open it.  Anything committed should be
106 107
    /// visible.
    ///
108 109
    /// Parameter is ignored for CQL backend as the v4 and v6 leases share
    /// the same database.
110 111
    void reopen(Universe) {
        LeaseMgrFactory::destroy();
Tomek Mrugalski's avatar
Tomek Mrugalski committed
112
        LeaseMgrFactory::create(validCqlConnectionString());
113 114 115
        lmptr_ = &(LeaseMgrFactory::instance());
    }

Andrei Pavel's avatar
Andrei Pavel committed
116 117
    // This is the CQL implementation for
    // GenericLeaseMgrTest::testGetExpiredLeases4().
118 119 120 121
    // The GenericLeaseMgrTest implementation checks for the order of expired
    // leases to be from the most expired to the least expired. Cassandra
    // doesn't support ORDER BY without imposing a EQ / IN restriction on the
    // columns. Because of that, the order check has been excluded.
Andrei Pavel's avatar
Andrei Pavel committed
122
    void testCqlGetExpiredLeases4() {
123
        // Get the leases to be used for the test.
124
        std::vector<Lease4Ptr> leases = createLeases4();
125
        // Make sure we have at least 6 leases there.
126
        ASSERT_GE(leases.size(), 6u);
127 128 129 130 131

        // Use the same current time for all leases.
        time_t current_time = time(NULL);

        // Add them to the database
132
        for (size_t i = 0u; i < leases.size(); ++i) {
133
            // Mark every other lease as expired.
134
            if (i % 2u == 0u) {
135 136 137 138
                // Set client last transmission time to the value older than the
                // valid lifetime to make it expired. The expiration time also
                // depends on the lease index, so as we can later check that the
                // leases are ordered by the expiration time.
Andrei Pavel's avatar
Andrei Pavel committed
139 140
                leases[i]->cltt_ =
                    current_time - leases[i]->valid_lft_ - 10 - i;
141
            } else {
Andrei Pavel's avatar
Andrei Pavel committed
142 143
                // Set current time as cltt for remaining leases. These leases
                // are
144 145 146 147 148 149 150 151 152
                // not expired.
                leases[i]->cltt_ = current_time;
            }
            ASSERT_TRUE(lmptr_->addLease(leases[i]));
        }

        // Retrieve at most 1000 expired leases.
        Lease4Collection expired_leases;
        ASSERT_NO_THROW(lmptr_->getExpiredLeases4(expired_leases, 1000));
153

154
        // Leases with even indexes should be returned as expired.
155
        ASSERT_EQ(static_cast<size_t>(leases.size() / 2u),
Andrei Pavel's avatar
Andrei Pavel committed
156
                  expired_leases.size());
157 158 159 160 161 162

        // Update current time for the next test.
        current_time = time(NULL);
        // Also, remove expired leases collected during the previous test.
        expired_leases.clear();

Andrei Pavel's avatar
Andrei Pavel committed
163 164
        // This time let's reverse the expiration time and see if they will be
        // returned
165
        // in the correct order.
166
        for (size_t i = 0u; i < leases.size(); ++i) {
167
            // Update the time of expired leases with even indexes.
168
            if (i % 2u == 0u) {
Andrei Pavel's avatar
Andrei Pavel committed
169 170
                leases[i]->cltt_ =
                    current_time - leases[i]->valid_lft_ - 1000 + i;
171 172 173 174 175 176 177
            } else {
                // Make sure remaining leases remain unexpired.
                leases[i]->cltt_ = current_time + 100;
            }
            ASSERT_NO_THROW(lmptr_->updateLease4(leases[i]));
        }

Andrei Pavel's avatar
Andrei Pavel committed
178
        // Retrieve expired leases again. The limit of 0 means return all
179
        // expired leases.
180
        ASSERT_NO_THROW(lmptr_->getExpiredLeases4(expired_leases, 0));
181

182
        // The same leases should be returned.
183
        ASSERT_EQ(static_cast<size_t>(leases.size() / 2u),
Andrei Pavel's avatar
Andrei Pavel committed
184
                  expired_leases.size());
185 186 187 188 189 190 191 192 193 194 195

        // Remember expired leases returned.
        std::vector<Lease4Ptr> saved_expired_leases = expired_leases;

        // Remove expired leases again.
        expired_leases.clear();

        // Limit the number of leases to be returned to 2.
        ASSERT_NO_THROW(lmptr_->getExpiredLeases4(expired_leases, 2));

        // Make sure we have exactly 2 leases returned.
196
        ASSERT_EQ(2u, expired_leases.size());
197 198

        // Mark every other expired lease as reclaimed.
199 200
        for (size_t i = 0u; i < saved_expired_leases.size(); ++i) {
            if (i % 2u != 0u) {
Andrei Pavel's avatar
Andrei Pavel committed
201 202
                saved_expired_leases[i]->state_ =
                    Lease::STATE_EXPIRED_RECLAIMED;
203 204 205 206 207 208 209 210
            }
            ASSERT_NO_THROW(lmptr_->updateLease4(saved_expired_leases[i]));
        }

        expired_leases.clear();

        // This the returned leases should exclude reclaimed ones. So the number
        // of returned leases should be roughly half of the expired leases.
211 212
        ASSERT_NO_THROW(lmptr_->getExpiredLeases4(expired_leases, 0u));
        ASSERT_EQ(static_cast<size_t>(saved_expired_leases.size() / 2u),
213 214 215 216 217 218
                  expired_leases.size());

        // Make sure that returned leases are those that are not reclaimed, i.e.
        // those that have even index.
        for (Lease4Collection::iterator lease = expired_leases.begin();
             lease != expired_leases.end(); ++lease) {
219 220
            int32_t index = static_cast<int32_t>(
                std::distance(expired_leases.begin(), lease));
221 222 223 224
            EXPECT_EQ(saved_expired_leases[2 * index]->addr_, (*lease)->addr_);
        }
    }

Andrei Pavel's avatar
Andrei Pavel committed
225
    // This is the CQL implementation for
226
    // GenericLeaseMgrTest::testGetExpiredLeases6().
227 228 229 230
    // The GenericLeaseMgrTest implementation checks for the order of expired
    // leases to be from the most expired to the least expired. Cassandra
    // doesn't support ORDER BY without imposing a EQ / IN restriction on the
    // columns. Because of that, the order check has been excluded.
Andrei Pavel's avatar
Andrei Pavel committed
231
    void testCqlGetExpiredLeases6() {
232
        // Get the leases to be used for the test.
233
        std::vector<Lease6Ptr> leases = createLeases6();
234
        // Make sure we have at least 6 leases there.
235
        ASSERT_GE(leases.size(), 6u);
236 237 238 239 240

        // Use the same current time for all leases.
        time_t current_time = time(NULL);

        // Add them to the database
241
        for (size_t i = 0u; i < leases.size(); ++i) {
242
            // Mark every other lease as expired.
243
            if (i % 2u == 0u) {
244 245 246 247
                // Set client last transmission time to the value older than the
                // valid lifetime to make it expired. The expiration time also
                // depends on the lease index, so as we can later check that the
                // leases are ordered by the expiration time.
Andrei Pavel's avatar
Andrei Pavel committed
248 249
                leases[i]->cltt_ =
                    current_time - leases[i]->valid_lft_ - 10 - i;
250
            } else {
Andrei Pavel's avatar
Andrei Pavel committed
251 252
                // Set current time as cltt for remaining leases. These leases
                // are
253 254 255 256 257 258 259 260 261
                // not expired.
                leases[i]->cltt_ = current_time;
            }
            ASSERT_TRUE(lmptr_->addLease(leases[i]));
        }

        // Retrieve at most 1000 expired leases.
        Lease6Collection expired_leases;
        ASSERT_NO_THROW(lmptr_->getExpiredLeases6(expired_leases, 1000));
262

263
        // Leases with even indexes should be returned as expired.
264
        ASSERT_EQ(static_cast<size_t>(leases.size() / 2u),
Andrei Pavel's avatar
Andrei Pavel committed
265
                  expired_leases.size());
266 267 268 269 270 271

        // Update current time for the next test.
        current_time = time(NULL);
        // Also, remove expired leases collected during the previous test.
        expired_leases.clear();

Andrei Pavel's avatar
Andrei Pavel committed
272 273
        // This time let's reverse the expiration time and see if they will be
        // returned
274
        // in the correct order.
275
        for (size_t i = 0u; i < leases.size(); ++i) {
276
            // Update the time of expired leases with even indexes.
277
            if (i % 2u == 0u) {
Andrei Pavel's avatar
Andrei Pavel committed
278 279
                leases[i]->cltt_ =
                    current_time - leases[i]->valid_lft_ - 1000 + i;
280 281 282 283 284 285 286
            } else {
                // Make sure remaining leases remain unexpired.
                leases[i]->cltt_ = current_time + 100;
            }
            ASSERT_NO_THROW(lmptr_->updateLease6(leases[i]));
        }

Andrei Pavel's avatar
Andrei Pavel committed
287
        // Retrieve expired leases again. The limit of 0 means return all
288
        // expired leases.
289
        ASSERT_NO_THROW(lmptr_->getExpiredLeases6(expired_leases, 0));
290

291
        // The same leases should be returned.
292
        ASSERT_EQ(static_cast<size_t>(leases.size() / 2u),
Andrei Pavel's avatar
Andrei Pavel committed
293
                  expired_leases.size());
294 295 296 297 298 299 300 301 302 303 304

        // Remember expired leases returned.
        std::vector<Lease6Ptr> saved_expired_leases = expired_leases;

        // Remove expired leases again.
        expired_leases.clear();

        // Limit the number of leases to be returned to 2.
        ASSERT_NO_THROW(lmptr_->getExpiredLeases6(expired_leases, 2));

        // Make sure we have exactly 2 leases returned.
305
        ASSERT_EQ(2u, expired_leases.size());
306 307

        // Mark every other expired lease as reclaimed.
308 309
        for (size_t i = 0u; i < saved_expired_leases.size(); ++i) {
            if (i % 2u != 0u) {
Andrei Pavel's avatar
Andrei Pavel committed
310 311
                saved_expired_leases[i]->state_ =
                    Lease::STATE_EXPIRED_RECLAIMED;
312 313 314 315 316 317 318 319 320 321 322 323 324 325
            }
            ASSERT_NO_THROW(lmptr_->updateLease6(saved_expired_leases[i]));
        }

        expired_leases.clear();

        // This the returned leases should exclude reclaimed ones. So the number
        // of returned leases should be roughly half of the expired leases.
        ASSERT_NO_THROW(lmptr_->getExpiredLeases6(expired_leases, 0));

        // Make sure that returned leases are those that are not reclaimed, i.e.
        // those that have even index.
        for (Lease6Collection::iterator lease = expired_leases.begin();
             lease != expired_leases.end(); ++lease) {
326 327
            int32_t index = static_cast<int32_t>(
                std::distance(expired_leases.begin(), lease));
328 329 330
            EXPECT_EQ(saved_expired_leases[2 * index]->addr_, (*lease)->addr_);
        }
    }
331 332 333 334
};

/// @brief Check that database can be opened
///
335 336 337
/// This test checks if the CqlLeaseMgr can be instantiated.  This happens
/// only if the database can be opened.  Note that this is not part of the
/// CqlLeaseMgr test fixure set.  This test checks that the database can be
338
/// opened: the fixtures assume that and check basic operations.
Razvan Becheriu's avatar
Razvan Becheriu committed
339
TEST(CqlOpenTest, OpenDatabase) {
340

341
    // Schema needs to be created for the test to work.
Thomas Markwalder's avatar
Thomas Markwalder committed
342
    createCqlSchema();
343 344

    // Check that lease manager open the database opens correctly and tidy up.
345
    // If it fails, print the error message.
346
    try {
Tomek Mrugalski's avatar
Tomek Mrugalski committed
347
        LeaseMgrFactory::create(validCqlConnectionString());
Andrei Pavel's avatar
Andrei Pavel committed
348
        EXPECT_NO_THROW((void)LeaseMgrFactory::instance());
349 350 351 352 353
        LeaseMgrFactory::destroy();
    } catch (const isc::Exception& ex) {
        FAIL() << "*** ERROR: unable to open database, reason:\n"
               << "    " << ex.what() << "\n"
               << "*** The test environment is broken and must be fixed\n"
Tomek Mrugalski's avatar
Tomek Mrugalski committed
354
               << "*** before the CQL tests will run correctly.\n";
355 356
    }

357
    // Check that lease manager open the database opens correctly with a longer
358
    // timeout.  If it fails, print the error message.
359
    try {
Tomek Mrugalski's avatar
Tomek Mrugalski committed
360 361
        // CQL specifies the timeout values in ms, not seconds. Therefore
        // we need to add extra 000 to the "connect-timeout=10" string.
362
        string connection_string = validCqlConnectionString() + string(" ") +
Razvan Becheriu's avatar
Razvan Becheriu committed
363
                                   string(VALID_TIMEOUT) + "000";
364
        LeaseMgrFactory::create(connection_string);
365
        EXPECT_NO_THROW((void) LeaseMgrFactory::instance());
366 367 368 369 370 371 372 373
        LeaseMgrFactory::destroy();
    } catch (const isc::Exception& ex) {
        FAIL() << "*** ERROR: unable to open database, reason:\n"
               << "    " << ex.what() << "\n"
               << "*** The test environment is broken and must be fixed\n"
               << "*** before the CQL tests will run correctly.\n";
    }

374 375 376 377 378 379 380
    // Check that attempting to get an instance of the lease manager when
    // none is set throws an exception.
    EXPECT_THROW(LeaseMgrFactory::instance(), NoLeaseManager);

    // Check that wrong specification of backend throws an exception.
    // (This is really a check on LeaseMgrFactory, but is convenient to
    // perform here.)
381 382
    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
        NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
383
        InvalidParameter);
384 385 386

    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
        INVALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
387 388
        InvalidType);

Andrei Pavel's avatar
Andrei Pavel committed
389 390 391 392
    // Check that invalid login data does not cause an exception, CQL should use
    // default values.
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)));
393

Andrei Pavel's avatar
Andrei Pavel committed
394 395
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)));
396

Andrei Pavel's avatar
Andrei Pavel committed
397 398
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)));
399

400 401
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)));
402

403
    // Check for invalid timeouts
404
    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
405 406 407
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_1)),
        DbOperationError);

408
    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
409 410
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_2)),
        DbOperationError);
411

412
    // Check for missing parameters
413 414
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)));
415

Andrei Pavel's avatar
Andrei Pavel committed
416 417 418 419
    // Check that invalid login data does not cause an exception, CQL should use
    // default values.
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)));
420

Andrei Pavel's avatar
Andrei Pavel committed
421 422
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)));
423

Andrei Pavel's avatar
Andrei Pavel committed
424 425
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)));
426

Andrei Pavel's avatar
Andrei Pavel committed
427 428 429 430 431
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)));

    // Check that invalid timeouts throw DbOperationError.
    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
432 433 434
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD,
        INVALID_TIMEOUT_1)),
        DbOperationError);
Andrei Pavel's avatar
Andrei Pavel committed
435
    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
436 437 438
        CQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD,
        INVALID_TIMEOUT_2)),
        DbOperationError);
Andrei Pavel's avatar
Andrei Pavel committed
439 440 441 442 443

    // Check that CQL allows the hostname to not be specified.
    EXPECT_NO_THROW(LeaseMgrFactory::create(connectionString(
        CQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)));

444
    // Tidy up after the test
Thomas Markwalder's avatar
Thomas Markwalder committed
445
    destroyCqlSchema();
446 447 448 449 450
}

/// @brief Check the getType() method
///
/// getType() returns a string giving the type of the backend, which should
451
/// always be "cql".
Tomek Mrugalski's avatar
Tomek Mrugalski committed
452
TEST_F(CqlLeaseMgrTest, getType) {
453
    EXPECT_EQ(std::string("cql"), lmptr_->getType());
454 455
}

456
/// @brief Check conversion functions
457
///
458
/// The server works using cltt and valid_filetime.  In the database, the
459 460 461 462 463 464
/// information is stored as expire_time and valid-lifetime, which are
/// related by
///
/// expire_time = cltt + valid_lifetime
///
/// This test checks that the conversion is correct.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
465
TEST_F(CqlLeaseMgrTest, checkTimeConversion) {
466
    const time_t cltt = time(NULL);
Razvan Becheriu's avatar
Razvan Becheriu committed
467
    const uint32_t valid_lft = 86400;  // 1 day
Andrei Pavel's avatar
Andrei Pavel committed
468
    cass_int64_t cql_expire;
Tomek Mrugalski's avatar
Tomek Mrugalski committed
469

470
    // Convert to the database time.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
471
    CqlExchange::convertToDatabaseTime(cltt, valid_lft, cql_expire);
472

473
    // Convert back
474
    time_t converted_cltt = 0;
Tomek Mrugalski's avatar
Tomek Mrugalski committed
475
    CqlExchange::convertFromDatabaseTime(cql_expire, valid_lft, converted_cltt);
476 477 478
    EXPECT_EQ(cltt, converted_cltt);
}

479
/// @brief Check getName() returns correct database name
Tomek Mrugalski's avatar
Tomek Mrugalski committed
480
TEST_F(CqlLeaseMgrTest, getName) {
481 482 483 484
    EXPECT_EQ(std::string("keatest"), lmptr_->getName());
}

/// @brief Check that getVersion() returns the expected version
Tomek Mrugalski's avatar
Tomek Mrugalski committed
485
TEST_F(CqlLeaseMgrTest, checkVersion) {
486
    // Check version
487
    pair<uint32_t, uint32_t> version;
488
    ASSERT_NO_THROW(version = lmptr_->getVersion());
489 490
    EXPECT_EQ(CQL_SCHEMA_VERSION_MAJOR, version.first);
    EXPECT_EQ(CQL_SCHEMA_VERSION_MINOR, version.second);
491 492 493 494 495 496 497 498 499 500
}

////////////////////////////////////////////////////////////////////////////////
/// LEASE4 /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4 (by address) and deleteLease (with an
/// IPv4 address) works.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
501
TEST_F(CqlLeaseMgrTest, basicLease4) {
502 503 504
    testBasicLease4();
}

505 506 507
/// @brief checks that infinite lifetimes do not overflow.
TEST_F(CqlLeaseMgrTest, infiniteLifeTime4) {
    testInfiniteLifeTime4();
508 509 510 511 512
}

/// @brief Lease4 update tests
///
/// Checks that we are able to update a lease in the database.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
513
TEST_F(CqlLeaseMgrTest, updateLease4) {
514 515 516 517
    testUpdateLease4();
}

/// @brief Check GetLease4 methods - access by Hardware Address
Tomek Mrugalski's avatar
Tomek Mrugalski committed
518
TEST_F(CqlLeaseMgrTest, getLease4HWAddr1) {
519 520 521 522
    testGetLease4HWAddr1();
}

/// @brief Check GetLease4 methods - access by Hardware Address
Tomek Mrugalski's avatar
Tomek Mrugalski committed
523
TEST_F(CqlLeaseMgrTest, getLease4HWAddr2) {
524 525 526
    testGetLease4HWAddr2();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
527 528 529 530
/// @brief Get lease4 by hardware address (2)
///
/// Check that the system can cope with getting a hardware address of
/// any size.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
531
TEST_F(CqlLeaseMgrTest, getLease4HWAddrSize) {
532 533 534 535 536 537 538
    testGetLease4HWAddrSize();
}

/// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
///
/// Adds leases to the database and checks that they can be accessed via
/// a combination of hardware address and subnet ID
Tomek Mrugalski's avatar
Tomek Mrugalski committed
539
TEST_F(CqlLeaseMgrTest, getLease4HwaddrSubnetId) {
540 541 542
    testGetLease4HWAddrSubnetId();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
543 544 545 546
/// @brief Get lease4 by hardware address and subnet ID (2)
///
/// Check that the system can cope with getting a hardware address of
/// any size.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
547
TEST_F(CqlLeaseMgrTest, getLease4HWAddrSubnetIdSize) {
548 549 550
    testGetLease4HWAddrSubnetIdSize();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
551
/// @brief This test was derived from memfile.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
552
TEST_F(CqlLeaseMgrTest, getLease4ClientId) {
553 554 555 556 557 558 559
    testGetLease4ClientId();
}

/// @brief Check GetLease4 methods - access by Client ID
///
/// Adds leases to the database and checks that they can be accessed via
/// the Client ID.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
560
TEST_F(CqlLeaseMgrTest, getLease4ClientId2) {
561 562 563
    testGetLease4ClientId2();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
564 565 566
/// @brief Get Lease4 by client ID (2)
///
/// Check that the system can cope with a client ID of any size.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
567
TEST_F(CqlLeaseMgrTest, getLease4ClientIdSize) {
568 569 570 571 572 573 574
    testGetLease4ClientIdSize();
}

/// @brief Check GetLease4 methods - access by Client ID & Subnet ID
///
/// Adds leases to the database and checks that they can be accessed via
/// a combination of client and subnet IDs.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
575
TEST_F(CqlLeaseMgrTest, getLease4ClientIdSubnetId) {
576 577 578
    testGetLease4ClientIdSubnetId();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
579 580

/// @brief This test checks that all IPv4 leases for a specified subnet id are returned.
581 582 583 584
TEST_F(CqlLeaseMgrTest, getLeases4SubnetId) {
    testGetLeases4SubnetId();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
585 586

/// @brief This test checks that all IPv4 leases with a specified hostname are returned.
587 588 589 590
TEST_F(CqlLeaseMgrTest, getLeases4Hostname) {
    testGetLeases4Hostname();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
591 592

/// @brief This test checks that all IPv4 leases are returned.
593 594 595 596
TEST_F(CqlLeaseMgrTest, getLeases4) {
    testGetLeases4();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
597
/// @brief Test that a range of IPv4 leases is returned with paging.
598 599 600 601
TEST_F(CqlLeaseMgrTest, getLeases4Paged) {
    testGetLeases4Paged();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
/// @brief This test checks that all IPv6 leases for a specified subnet id are returned.
TEST_F(CqlLeaseMgrTest, getLeases6SubnetId) {
    testGetLeases6SubnetId();
}

/// @brief This test checks that all IPv6 leases with a specified hostname are returned.
TEST_F(CqlLeaseMgrTest, getLeases6Hostname) {
    testGetLeases6Hostname();
}

/// @brief This test checks that all IPv6 leases are returned.
TEST_F(CqlLeaseMgrTest, getLeases6) {
    testGetLeases6();
}

/// @brief Test that a range of IPv6 leases is returned with paging.
TEST_F(CqlLeaseMgrTest, getLeases6Paged) {
    testGetLeases6Paged();
}

622 623
/// @brief Basic Lease4 Checks
///
624
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
625
/// updateLease4() and deleteLease can handle NULL client-id.
626
/// (client-id is optional and may not be present)
Tomek Mrugalski's avatar
Tomek Mrugalski committed
627
TEST_F(CqlLeaseMgrTest, lease4NullClientId) {
628 629 630 631 632 633 634
    testLease4NullClientId();
}

/// @brief Verify that too long hostname for Lease4 is not accepted.
///
/// Checks that the it is not possible to create a lease when the hostname
/// length exceeds 255 characters.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
635
TEST_F(CqlLeaseMgrTest, lease4InvalidHostname) {
636 637 638
    testLease4InvalidHostname();
}

639 640 641 642 643 644 645 646 647 648 649
/// @brief Check that the expired DHCPv4 leases can be retrieved.
///
/// This test adds a number of leases to the lease database and marks
/// some of them as expired. Then it queries for expired leases and checks
/// whether only expired leases are returned, and that they are returned in
/// the order from most to least expired. It also checks that the lease
/// which is marked as 'reclaimed' is not returned.
TEST_F(CqlLeaseMgrTest, getExpiredLeases4) {
    testCqlGetExpiredLeases4();
}

Francis Dupont's avatar
Francis Dupont committed
650 651
/// @brief Checks that DHCPv4 leases with infinite valid lifetime
/// will never expire.
652 653
TEST_F(CqlLeaseMgrTest, infiniteAreNotExpired4) {
    testInfiniteAreNotExpired4();
654 655
}

656 657 658 659 660
/// @brief Check that expired reclaimed DHCPv4 leases are removed.
TEST_F(CqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
    testDeleteExpiredReclaimedLeases4();
}

661 662 663 664
////////////////////////////////////////////////////////////////////////////////
/// LEASE6 /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

Razvan Becheriu's avatar
Razvan Becheriu committed
665 666
/// @brief Test checks whether simple add, get and delete operations
/// are possible on Lease6
Tomek Mrugalski's avatar
Tomek Mrugalski committed
667
TEST_F(CqlLeaseMgrTest, testAddGetDelete6) {
668
    testAddGetDelete6();
669 670 671 672 673 674
}

/// @brief Basic Lease6 Checks
///
/// Checks that the addLease, getLease6 (by address) and deleteLease (with an
/// IPv6 address) works.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
675
TEST_F(CqlLeaseMgrTest, basicLease6) {
676 677 678
    testBasicLease6();
}

679 680 681
/// @brief checks that infinite lifetimes do not overflow.
TEST_F(CqlLeaseMgrTest, infiniteLifeTime6) {
    testInfiniteLifeTime6();
682 683 684 685 686 687
}

/// @brief Verify that too long hostname for Lease6 is not accepted.
///
/// Checks that the it is not possible to create a lease when the hostname
/// length exceeds 255 characters.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
688
TEST_F(CqlLeaseMgrTest, lease6InvalidHostname) {
689 690 691
    testLease6InvalidHostname();
}

692 693 694 695 696 697 698 699
/// @brief Verify that large IAID values work correctly.
///
/// Adds lease with a large IAID to the database and verifies it can
/// fetched correclty.
TEST_F(CqlLeaseMgrTest, leases6LargeIaidCheck) {
    testLease6LargeIaidCheck();
}

700 701 702 703
/// @brief Check GetLease6 methods - access by DUID/IAID
///
/// Adds leases to the database and checks that they can be accessed via
/// a combination of DUID and IAID.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
704
TEST_F(CqlLeaseMgrTest, getLeases6DuidIaid) {
705 706 707
    testGetLeases6DuidIaid();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
708
/// @brief Check that the system can cope with a DUID of allowed size.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
709
TEST_F(CqlLeaseMgrTest, getLeases6DuidSize) {
710 711 712 713 714 715 716 717 718
    testGetLeases6DuidSize();
}

/// @brief Check that getLease6 methods discriminate by lease type.
///
/// Adds six leases, two per lease type all with the same duid and iad but
/// with alternating subnet_ids.
/// It then verifies that all of getLeases6() method variants correctly
/// discriminate between the leases based on lease type alone.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
719
TEST_F(CqlLeaseMgrTest, lease6LeaseTypeCheck) {
720 721 722 723 724 725 726
    testLease6LeaseTypeCheck();
}

/// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
///
/// Adds leases to the database and checks that they can be accessed via
/// a combination of DIUID and IAID.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
727
TEST_F(CqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
728 729 730
    testGetLease6DuidIaidSubnetId();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
731 732

/// @brief Test checks that getLease6() works with different DUID sizes
Tomek Mrugalski's avatar
Tomek Mrugalski committed
733
TEST_F(CqlLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
734 735 736
    testGetLease6DuidIaidSubnetIdSize();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
737 738 739 740 741 742
/// @brief check leases could be retrieved by DUID
///
/// Create leases, add them to backend and verify if it can be queried
/// using DUID index
TEST_F(CqlLeaseMgrTest, getLeases6Duid) {
    testGetLeases6Duid();
743 744
}

745 746 747
/// @brief Lease6 update tests
///
/// Checks that we are able to update a lease in the database.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
748
TEST_F(CqlLeaseMgrTest, updateLease6) {
749 750 751 752 753 754 755 756
    testUpdateLease6();
}

/// @brief DHCPv4 Lease recreation tests
///
/// Checks that the lease can be created, deleted and recreated with
/// different parameters. It also checks that the re-created lease is
/// correctly stored in the lease database.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
757
TEST_F(CqlLeaseMgrTest, testRecreateLease4) {
758 759 760 761 762 763 764 765
    testRecreateLease4();
}

/// @brief DHCPv6 Lease recreation tests
///
/// Checks that the lease can be created, deleted and recreated with
/// different parameters. It also checks that the re-created lease is
/// correctly stored in the lease database.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
766
TEST_F(CqlLeaseMgrTest, testRecreateLease6) {
767 768 769 770
    testRecreateLease6();
}

/// @brief Checks that null DUID is not allowed.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
771
TEST_F(CqlLeaseMgrTest, nullDuid) {
772 773 774
    testNullDuid();
}

775
/// @brief Tests whether CQL can store and retrieve hardware addresses
Tomek Mrugalski's avatar
Tomek Mrugalski committed
776
TEST_F(CqlLeaseMgrTest, testLease6Mac) {
777 778 779
    testLease6MAC();
}

780
/// @brief Tests whether CQL can store and retrieve hardware addresses
Tomek Mrugalski's avatar
Tomek Mrugalski committed
781
TEST_F(CqlLeaseMgrTest, testLease6HWTypeAndSource) {
782 783 784 785 786 787 788 789 790 791
    testLease6HWTypeAndSource();
}

/// @brief Check that the expired DHCPv6 leases can be retrieved.
///
/// This test adds a number of leases to the lease database and marks
/// some of them as expired. Then it queries for expired leases and checks
/// whether only expired leases are returned, and that they are returned in
/// the order from most to least expired. It also checks that the lease
/// which is marked as 'reclaimed' is not returned.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
792
TEST_F(CqlLeaseMgrTest, getExpiredLeases6) {
793
    testCqlGetExpiredLeases6();
794 795
}

Francis Dupont's avatar
Francis Dupont committed
796 797
/// @brief Checks that DHCPv6 leases with infinite valid lifetime
/// will never expire.
798 799
TEST_F(CqlLeaseMgrTest, infiniteAreNotExpired6) {
    testInfiniteAreNotExpired6();
800 801
}

802
/// @brief Check that expired reclaimed DHCPv6 leases are removed.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
803
TEST_F(CqlLeaseMgrTest, deleteExpiredReclaimedLeases6) {
804 805 806
    testDeleteExpiredReclaimedLeases6();
}

Thomas Markwalder's avatar
Thomas Markwalder committed
807 808
/// @brief Verifies that IPv4 lease statistics can be recalculated.
TEST_F(CqlLeaseMgrTest, recountLeaseStats4) {
809 810 811
    testRecountLeaseStats4();
}

Thomas Markwalder's avatar
Thomas Markwalder committed
812 813
/// @brief Verifies that IPv6 lease statistics can be recalculated.
TEST_F(CqlLeaseMgrTest, recountLeaseStats6) {
814 815 816
    testRecountLeaseStats6();
}

817
/// @brief Tests that leases from specific subnet can be removed.
818 819
/// @todo: uncomment this once lease wipe is implemented
/// for Cassandra (see #5485)
820 821 822 823
TEST_F(CqlLeaseMgrTest, DISABLED_wipeLeases4) {
    testWipeLeases4();
}

824
/// @brief Tests that leases from specific subnet can be removed.
825 826
/// @todo: uncomment this once lease wipe is implemented
/// for Cassandra (see #5485)
827 828 829 830
TEST_F(CqlLeaseMgrTest, DISABLED_wipeLeases6) {
    testWipeLeases6();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
831
/// @brief Tests v4 lease stats query variants.
832 833 834 835
TEST_F(CqlLeaseMgrTest, leaseStatsQuery4) {
    testLeaseStatsQuery4();
}

Razvan Becheriu's avatar
Razvan Becheriu committed
836 837

/// @brief Tests v6 lease stats query variants.
838 839 840 841
TEST_F(CqlLeaseMgrTest, leaseStatsQuery6) {
    testLeaseStatsQuery6();
}

Andrei Pavel's avatar
Andrei Pavel committed
842
}  // namespace