lfc_controller_unittests.cc 24 KB
Newer Older
1
// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
2
//
3
4
5
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6

7
#include <lfc/lfc_controller.h>
8
#include <util/csv_file.h>
9
#include <gtest/gtest.h>
10
11
#include <fstream>
#include <cerrno>
12
13
14
15

using namespace isc::lfc;
using namespace std;

16
17
namespace {

18
19
class LFCControllerTest : public ::testing::Test {
public:
20
21
22
23
24
25
    string pstr_; ///< String for name for pid file
    string xstr_; ///< String for name for previous file
    string istr_; ///< String for name for copy file
    string ostr_; ///< String for name for output file
    string fstr_; ///< String for name for finish file
    string cstr_; ///< String for name for config file
26

27
28
    string v4_hdr_; ///< String for the header of the v4 csv test file
    string v6_hdr_; ///< String for the header of the v6 csv test file
29

30
31
32
    /// @brief Create a file and write the given string into it.
    void writeFile(const std::string& filename, const std::string& contents) const;

33
    /// @brief Read a string from a file
34
35
36
37
38
39
    std::string readFile(const std::string& filename) const;

    /// @brief Test if a file doesn't exist
    ///
    /// @returns true if the file doesn't exist, false if it does
    bool noExist(const std::string& filename) const {
40
        return ((remove(filename.c_str()) != 0) && (errno == ENOENT));
41
42
43
44
45
46
47
    }

    /// @brief Test if any of the temporary (copy, output or finish)
    /// files exist
    ///
    /// @returns true if no files exist, and false if any do.
    bool noExistIOF() const {
48
        return (noExist(istr_) && noExist(ostr_) && noExist(fstr_));
49
50
51
52
53
54
55
    }

    /// @brief Test if any of the temporary (copy, output or finish)
    /// files and the pid file exist
    ///
    /// @returns true if no files exist, and false if any do.
    bool noExistIOFP() const {
56
57
        return ((noExist(istr_) && noExist(ostr_) &&
                 noExist(fstr_) && noExist(pstr_)));
58
59
60
61
62
63
64
65
66
67
    }

    /// @brief Remove any files we may have created
    void removeTestFile() const {
        remove(pstr_.c_str());
        remove(xstr_.c_str());
        remove(istr_.c_str());
        remove(ostr_.c_str());
        remove(fstr_.c_str());
    }
68

69
protected:
70
    /// @brief Sets up the file names and header string and removes
71
    /// any old test files before the test
72
73
    virtual void SetUp() {
        // set up the test files we need
74
75
76
77
78
79
80
81
82
83
84
        string base_dir = TEST_DATA_BUILDDIR;
        string lf = "lease_file.";

        pstr_ = base_dir + "/" + lf + "pid";        // pid
        xstr_ = base_dir + "/" + lf + "2";          // previous
        istr_ = base_dir + "/" + lf + "1";          // copy
        ostr_ = base_dir + "/" + lf + "output";     // output
        fstr_ = base_dir + "/" + lf + "completed";  // finish
        cstr_ = base_dir + "/" + "config_file";     // config

        v4_hdr_ = "address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
85
                  "fqdn_fwd,fqdn_rev,hostname,state\n";
86
87
88

        v6_hdr_ = "address,duid,valid_lifetime,expire,subnet_id,"
                  "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
89
                  "fqdn_rev,hostname,hwaddr,state\n";
90
91
92
93
94
95
96
97
98
99

        // and remove any outstanding test files
        removeTestFile();
    }

    /// @brief Removes any remaining test files after the test
    virtual void TearDown() {
        removeTestFile();
    }

100
101
102
103
    /// @Wrapper to invoke the controller's launch method  Please refer to
    /// lfcController::launch for details.  This is wrapped to provide
    /// a single place to update the test_mode throughout the file.
    void launch(LFCController lfc_controller, int argc, char* argv[]) {
Shawn Routhier's avatar
Shawn Routhier committed
104
        lfc_controller.launch(argc, argv, true);
105
106
    }

107
108
109
private:
};

110
111
112
113
std::string
LFCControllerTest::readFile(const std::string& filename) const {
    std::ifstream fs;

114
    fs.open(filename.c_str(), std::ifstream::in);
115
    std::string contents((std::istreambuf_iterator<char>(fs)),
116
                         std::istreambuf_iterator<char>());
117
118
119
120
121
122
    fs.close();
    return (contents);
}

void
LFCControllerTest::writeFile(const std::string& filename,
123
                             const std::string& contents) const {
124
    std::ofstream fs(filename.c_str(), std::ofstream::out);
125
126
127

    if (fs.is_open()) {
        fs << contents;
128
        fs.close();
129
    }
130
131
}

132
133
134
/// @brief Verify initial state of LFC controller.
/// Create an instance of the controller and see that
/// all of the initial values are empty as expected.
135
TEST_F(LFCControllerTest, initialValues) {
136
137
138
139
140
141
142
143
144
145
    LFCController lfc_controller;

    // Verify that we start with all the private variables empty
    EXPECT_EQ(lfc_controller.getProtocolVersion(), 0);
    EXPECT_TRUE(lfc_controller.getConfigFile().empty());
    EXPECT_TRUE(lfc_controller.getPreviousFile().empty());
    EXPECT_TRUE(lfc_controller.getCopyFile().empty());
    EXPECT_TRUE(lfc_controller.getOutputFile().empty());
    EXPECT_TRUE(lfc_controller.getFinishFile().empty());
    EXPECT_TRUE(lfc_controller.getPidFile().empty());
146
147
}

148
/// @todo verify that parsing -v/V/W/h works well without ASSERT_EXIT
149

150
151
152
/// @brief Verify that parsing a full command line works.
/// Parse a complete command line then verify the parsed
/// and saved data matches our expectations.
153
TEST_F(LFCControllerTest, fullCommandLine) {
154
    LFCController lfc_controller;
155
156
157

    // Verify that standard options can be parsed without error
    char* argv[] = { const_cast<char*>("progName"),
Shawn Routhier's avatar
Shawn Routhier committed
158
                     const_cast<char*>("-4"),
159
                     const_cast<char*>("-x"),
Shawn Routhier's avatar
Shawn Routhier committed
160
161
162
163
164
165
166
167
                     const_cast<char*>("previous"),
                     const_cast<char*>("-i"),
                     const_cast<char*>("copy"),
                     const_cast<char*>("-o"),
                     const_cast<char*>("output"),
                     const_cast<char*>("-c"),
                     const_cast<char*>("config"),
                     const_cast<char*>("-f"),
168
169
170
171
                     const_cast<char*>("finish"),
                     const_cast<char*>("-p"),
                     const_cast<char*>("pid") };
    int argc = 14;
172

173
    ASSERT_NO_THROW(lfc_controller.parseArgs(argc, argv));
174

175
176
177
178
179
180
181
    // Check all the parsed data from above to the known values
    EXPECT_EQ(lfc_controller.getProtocolVersion(), 4);
    EXPECT_EQ(lfc_controller.getConfigFile(), "config");
    EXPECT_EQ(lfc_controller.getPreviousFile(), "previous");
    EXPECT_EQ(lfc_controller.getCopyFile(), "copy");
    EXPECT_EQ(lfc_controller.getOutputFile(), "output");
    EXPECT_EQ(lfc_controller.getFinishFile(), "finish");
182
    EXPECT_EQ(lfc_controller.getPidFile(), "pid");
183
184
}

185
186
187
188
/// @brief Verify that parsing a correct but incomplete line fails.
/// Parse a command line that is correctly formatted but isn't complete
/// (doesn't include some options or an some option arguments).  We
/// expect that the parse will fail with an InvalidUsage exception.
189
TEST_F(LFCControllerTest, notEnoughData) {
190
    LFCController lfc_controller;
191

192
193
194
    // Test the results if we don't include all of the required arguments
    // This argument list is correct but we shall only suppy part of it
    // to the parse routine via the argc variable.
195
    char* argv[] = { const_cast<char*>("progName"),
Shawn Routhier's avatar
Shawn Routhier committed
196
                     const_cast<char*>("-4"),
197
                     const_cast<char*>("-x"),
Shawn Routhier's avatar
Shawn Routhier committed
198
199
200
201
202
203
204
205
                     const_cast<char*>("previous"),
                     const_cast<char*>("-i"),
                     const_cast<char*>("copy"),
                     const_cast<char*>("-o"),
                     const_cast<char*>("output"),
                     const_cast<char*>("-c"),
                     const_cast<char*>("config"),
                     const_cast<char*>("-f"),
206
207
208
                     const_cast<char*>("finish"),
                     const_cast<char*>("-p"),
                     const_cast<char*>("pid") };
209

210
    int argc = 1;
211

212
    for (; argc < 14; ++argc) {
213
214
215
        EXPECT_THROW(lfc_controller.parseArgs(argc, argv), InvalidUsage)
            << "test failed for argc = " << argc;
    }
216

217
218
    // Verify we can still parse the full string properly
    ASSERT_NO_THROW(lfc_controller.parseArgs(argc, argv));
219
220
}

221
222
223
/// @brief Verify that extra arguments cause the parse to fail.
/// Parse a full command line plus some extra arguments on the end
/// to verify that we don't stop parsing when we find all of the
Andrei Pavel's avatar
Andrei Pavel committed
224
/// required arguments.  We expect the parse to fail with an
225
/// InvalidUsage exception.
226
TEST_F(LFCControllerTest, tooMuchData) {
227
    LFCController lfc_controller;
228
229
230
231

    // The standard options plus some others

    char* argv[] = { const_cast<char*>("progName"),
Shawn Routhier's avatar
Shawn Routhier committed
232
                     const_cast<char*>("-4"),
233
                     const_cast<char*>("-x"),
Shawn Routhier's avatar
Shawn Routhier committed
234
235
236
237
238
239
240
241
242
                     const_cast<char*>("previous"),
                     const_cast<char*>("-i"),
                     const_cast<char*>("copy"),
                     const_cast<char*>("-o"),
                     const_cast<char*>("output"),
                     const_cast<char*>("-c"),
                     const_cast<char*>("config"),
                     const_cast<char*>("-f"),
                     const_cast<char*>("finish"),
243
244
                     const_cast<char*>("-p"),
                     const_cast<char*>("pid"),
Shawn Routhier's avatar
Shawn Routhier committed
245
246
247
                     const_cast<char*>("some"),
                     const_cast<char*>("other"),
                     const_cast<char*>("args"),
248
    };
249
    int argc = 17;
250

251
252
    // We expect an error as we have arguments that aren't valid
    EXPECT_THROW(lfc_controller.parseArgs(argc, argv), InvalidUsage);
253
254
}

255
256
257
/// @brief Verify that unknown arguments cause the parse to fail.
/// Parse some unknown arguments to verify that we generate the
/// proper InvalidUsage exception.
258
TEST_F(LFCControllerTest, someBadData) {
259
    LFCController lfc_controller;
260

261
    // Some random arguments
262
263

    char* argv[] = { const_cast<char*>("progName"),
Shawn Routhier's avatar
Shawn Routhier committed
264
265
266
                     const_cast<char*>("some"),
                     const_cast<char*>("bad"),
                     const_cast<char*>("args"),
267
268
269
    };
    int argc = 4;

270
271
    // We expect an error as the arguments aren't valid
    EXPECT_THROW(lfc_controller.parseArgs(argc, argv), InvalidUsage);
272
}
273

274
/// @brief Verify that we do file rotation correctly.  We create different
275
/// files and see if we properly delete and move them.
276
TEST_F(LFCControllerTest, fileRotate) {
277
278
279
    LFCController lfc_controller, lfc_controller_launch;

    // We can use the same arguments and controller for all of the tests
280
281
282
    // as the files get redone for each subtest.  We leave "-d" in the arg
    // list but don't pass it as we use 14 as the argument count.  This
    // makes it easy to turn it on by simply increasing argc below to 15
283
284
285
    char* argv[] = { const_cast<char*>("progName"),
                     const_cast<char*>("-4"),
                     const_cast<char*>("-x"),
286
                     const_cast<char*>(xstr_.c_str()),
287
                     const_cast<char*>("-i"),
288
                     const_cast<char*>(istr_.c_str()),
289
290
291
                     const_cast<char*>("-o"),
                     const_cast<char*>(ostr_.c_str()),
                     const_cast<char*>("-c"),
292
                     const_cast<char*>(cstr_.c_str()),
293
294
295
                     const_cast<char*>("-f"),
                     const_cast<char*>(fstr_.c_str()),
                     const_cast<char*>("-p"),
296
                     const_cast<char*>(pstr_.c_str()),
297
298
                     const_cast<char*>("-d")
    };
299
    int argc = 14;
300
301
    lfc_controller.parseArgs(argc, argv);

Andrei Pavel's avatar
Andrei Pavel committed
302
    // Test 1: Start with no files - we expect an exception as there
303
    // is no file to copy.
304
305
    EXPECT_THROW(lfc_controller.fileRotate(), RunTimeFail);
    removeTestFile();
306
307
308

    // Test 2: Create a file for each of previous, copy and finish.  We should
    // delete the previous and copy files then move finish to previous.
309
310
311
    writeFile(xstr_, "1");
    writeFile(istr_, "2");
    writeFile(fstr_, "3");
312

313
    lfc_controller.fileRotate();
314

315
316
317
318
    // verify finish is now previous and no temp files remain.
    EXPECT_EQ(readFile(xstr_), "3");
    EXPECT_TRUE(noExistIOF());
    removeTestFile();
319
320
321


    // Test 3: Create a file for previous and finish but not copy.
322
323
    writeFile(xstr_, "4");
    writeFile(fstr_, "6");
324

325
    lfc_controller.fileRotate();
326

327
328
329
330
    // verify finish is now previous and no temp files remain.
    EXPECT_EQ(readFile(xstr_), "6");
    EXPECT_TRUE(noExistIOF());
    removeTestFile();
331
332
333


    // Test 4: Create a file for copy and finish but not previous.
334
335
    writeFile(istr_, "8");
    writeFile(fstr_, "9");
336

337
    lfc_controller.fileRotate();
338

339
340
341
342
    // verify finish is now previous and no temp files remain.
    EXPECT_EQ(readFile(xstr_), "9");
    EXPECT_TRUE(noExistIOF());
    removeTestFile();
343
344
345
346
347


    // Test 5: rerun test 2 but using launch instead of cleanup
    // as we already have a finish file we shouldn't do any extra
    // processing
348
349
350
    writeFile(xstr_, "10");
    writeFile(istr_, "11");
    writeFile(fstr_, "12");
351

352
    launch(lfc_controller_launch, argc, argv);
353

354
355
356
357
    // verify finish is now previous and no temp files or pid remain.
    EXPECT_EQ(readFile(xstr_), "12");
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
358
359
}

360
/// @brief Verify that we properly combine and clean up files
361
///
362
363
/// This is mostly a retest as we already test that the loader and
/// writer functions work in their own tests but we combine it all
364
365
366
/// here.  We check: both files available, only previous, only copy
/// neither and one of them having many lease errors.  This is the
/// v4 version.
367

368
TEST_F(LFCControllerTest, launch4) {
369
370
    LFCController lfc_controller;

371
372
373
374
375
    // The arg list for our test.  We generally use the
    // same file names to make it easy.  We include the -d
    // in the argv list in case we want to enable verbose
    // for debugging purposes.  To enable it change argc from
    // 14 to 15
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
    char* argv[] = { const_cast<char*>("progName"),
                     const_cast<char*>("-4"),
                     const_cast<char*>("-x"),
                     const_cast<char*>(xstr_.c_str()),
                     const_cast<char*>("-i"),
                     const_cast<char*>(istr_.c_str()),
                     const_cast<char*>("-o"),
                     const_cast<char*>(ostr_.c_str()),
                     const_cast<char*>("-c"),
                     const_cast<char*>(cstr_.c_str()),
                     const_cast<char*>("-f"),
                     const_cast<char*>(fstr_.c_str()),
                     const_cast<char*>("-p"),
                     const_cast<char*>(pstr_.c_str()),
                     const_cast<char*>("-d")
    };
    int argc = 14;
393
394
395
396
397
    string test_str, astr;

    // Create the various strings we want to use, the header is predefined.
    // We have several entries for different leases, the naming is:
    // <lease letter>_<version#>
398
    string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
399
                 "200,200,8,1,1,host.example.com,1\n";
400
    string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
401
                 "200,500,8,1,1,host.example.com,1\n";
402
    string a_3 = "192.0.2.1,06:07:08:09:0a:bc,,"
403
                 "200,800,8,1,1,host.example.com,1\n";
404

405
    string b_1 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
406
                 "100,100,7,0,0,,1\n";
407
    string b_2 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
408
                 "100,135,7,0,0,,1\n";
409
    string b_3 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
410
                 "100,150,7,0,0,,1\n";
411

412
    // This one should be invalid, no hardware address and state is not declined
413
    string c_1 = "192.0.2.3,,a:11:01:04,"
414
                 "200,200,8,1,1,host.example.com,0\n";
415

416
    string d_1 = "192.0.2.5,16:17:18:19:1a:bc,,"
417
                 "200,200,8,1,1,host.example.com,1\n";
418
    string d_2 = "192.0.2.5,16:17:18:19:1a:bc,,"
419
                 "0,200,8,1,1,host.example.com,1\n";
420
421
422

    // Subtest 1: both previous and copy available.
    // Create the test previous file
423
424
    test_str = v4_hdr_ + a_1 + b_1 + c_1 + b_2 + a_2 + d_1;
    writeFile(xstr_, test_str);
425
426

    // Create the test copy file
427
428
    test_str = v4_hdr_ + a_3 + b_3 + d_2;
    writeFile(istr_, test_str);
429
430

    // Run the cleanup
431
    launch(lfc_controller, argc, argv);
432
433

    // Compare the results, we expect the last lease for each ip
434
435
436
437
438
439
    // except for C which was invalid and D which has expired.
    // We also verify none of the temp or pid files remain.
    test_str = v4_hdr_ + a_3 + b_3;
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
440

441

442
    // Subtest 2: only previous available
443
    // Create the test previous file
444
445
    test_str = v4_hdr_ + a_1 + b_1 + c_1 + b_2 + a_2 + d_1;
    writeFile(xstr_, test_str);
446

447
    // No copy file
448

449
    // Run the cleanup
450
    launch(lfc_controller, argc, argv);
451
452

    // Compare the results, we expect the last lease for each ip
453
454
455
456
457
458
    // except for C which was invalid and D which has expired.
    // We also verify none of the temp or pid files remain.
    test_str = v4_hdr_ + a_2 + d_1 + b_2;
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
459
460
461
462


    // Subtest 3: only copy available
    // No previous file
463
464

    // Create the test copy file
465
466
    test_str = v4_hdr_ + d_1 + a_1 + b_1 + b_3 + d_2 + a_3;
    writeFile(istr_, test_str);
467
468

    // Run the cleanup
469
    launch(lfc_controller, argc, argv);
470

471
    // Compare the results, we expect the last lease for each ip
472
473
474
475
476
477
    // except for C which was invalid and D which has expired.
    // We also verify none of the temp or pid files remain.
    test_str = v4_hdr_ + a_3 + b_3;
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
478
479
480
481
482
483
484
485


    // Subtest 4: neither available
    // No previous file

    // No copy file

    // Run the cleanup
486
    launch(lfc_controller, argc, argv);
487

Josh Soref's avatar
Josh Soref committed
488
    // Compare the results, we expect a header and no leases.
489
    // We also verify none of the temp or pid files remain.
490
    test_str = v4_hdr_;
491
492
493
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
494

495
496
497
498
499
500

    // Subtest 5: a file with a lot of errors
    // A previous file with a lot of errors
    astr = "1,\n2,\n3,\n4,\n5,\n6,\n7,\n7,\n8,\n9,\n10,\n";
    test_str = v4_hdr_ + astr + astr + astr + astr + astr +
               astr + astr + astr + astr + astr + astr;
501
    writeFile(xstr_, test_str);
502
503
504
505
506

    // No copy file

    // Run the cleanup, the file should fail but we should
    // catch the error and properly cleanup.
507
    launch(lfc_controller, argc, argv);
508

509
510
511
512
    // And we shouldn't have deleted the previous file.
    // We also verify none of the temp or pid files remain.
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
513
514
515
}

/// @brief Verify that we properly combine and clean up files
516
///
517
518
/// This is mostly a retest as we already test that the loader and
/// writer functions work in their own tests but we combine it all
519
520
521
/// here.  We check: both files available, only previous, only copy
/// neither and one of them having many lease errors.  This is the
/// v6 version.
522

523
TEST_F(LFCControllerTest, launch6) {
524
525
    LFCController lfc_controller;

526
527
528
529
530
    // The arg list for our test.  We generally use the
    // same file names to make it easy.  We include the -d
    // in the argv list in case we want to enable verbose
    // for debugging purposes.  To enable it change argc from
    // 14 to 15
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
    char* argv[] = { const_cast<char*>("progName"),
                     const_cast<char*>("-6"),
                     const_cast<char*>("-x"),
                     const_cast<char*>(xstr_.c_str()),
                     const_cast<char*>("-i"),
                     const_cast<char*>(istr_.c_str()),
                     const_cast<char*>("-o"),
                     const_cast<char*>(ostr_.c_str()),
                     const_cast<char*>("-c"),
                     const_cast<char*>(cstr_.c_str()),
                     const_cast<char*>("-f"),
                     const_cast<char*>(fstr_.c_str()),
                     const_cast<char*>("-p"),
                     const_cast<char*>(pstr_.c_str()),
                     const_cast<char*>("-d")
    };
    int argc = 14;
548
549
550
551
552
    string test_str, astr;

    // Create the various strings we want to use, the header is predefined.
    // We have several entries for different leases, the naming is:
    // <lease letter>_<version#>.
553
    string a_1 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
554
555
                 "200,200,8,100,0,7,0,1,1,host.example.com,,1\n";
    string a_2 = "2001:db8:1::1,,200,200,8,100,0,7,0,1,1,host.example.com,,1\n";
556
    string a_3 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
557
                 "200,400,8,100,0,7,0,1,1,host.example.com,,1\n";
558
    string a_4 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
559
                 "0,200,8,100,0,7,0,1,1,host.example.com,,1\n";
560

561
    string b_1 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
562
                 "300,300,6,150,0,8,0,0,0,,,1\n";
563
    string b_2 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
564
                 "300,800,6,150,0,8,0,0,0,,,1\n";
565
    string b_3 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
566
                 "300,1000,6,150,0,8,0,0,0,,,1\n";
567

568
    string c_1 = "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
569
                 "100,200,8,0,2,16,64,0,0,,,1\n";
570
    string c_2 = "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
571
                 "100,400,8,0,2,16,64,0,0,,,1\n";
572

573
    string d_1 = "2001:db8:1::3,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
574
                 "200,600,8,100,0,7,0,1,1,host.example.com,,1\n";
575
576
577

    // Subtest 1: bot previous and copy available
    // Create the test previous file
578
579
    test_str = v6_hdr_ + a_1 + b_1 + a_2 + c_1 + a_3 + b_2;
    writeFile(xstr_, test_str);
580

581
    // Create the test copy file
582
583
    test_str = v6_hdr_ + b_3 + a_4 + d_1 + c_2;
    writeFile(istr_, test_str);
584
585

    // Run the cleanup
586
    launch(lfc_controller, argc, argv);
587
588

    // Compare the results, we expect the last lease for each ip
589
590
591
592
593
594
    // except for A which has expired.
    // We also verify none of the temp or pid files remain.
    test_str = v6_hdr_ + d_1 + b_3 + c_2;
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
595
596
597


    // Subtest 2: only previous available
598
    // Create the test previous file
599
600
    test_str = v6_hdr_ + a_1 + b_1 + a_2 + c_1 + a_3 + b_2;
    writeFile(xstr_, test_str);
601
602
603
604

    // No copy file

    // Run the cleanup
605
    launch(lfc_controller, argc, argv);
606

607
608
609
610
611
612
    // Compare the results, we expect the last lease for each ip.
    // We also verify none of the temp or pid files remain.
    test_str = v6_hdr_ + a_3 + b_2 + c_1;
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
613
614
615
616


    // Subtest 3: only copy available
    // No previous file
617
618

    // Create the test copy file
619
620
    test_str = v6_hdr_ + a_1 + b_2 + b_3 + a_4 + d_1 + c_2;
    writeFile(istr_, test_str);
621
622

    // Run the cleanup
623
    launch(lfc_controller, argc, argv);
624

625
626
627
628
629
630
    // Compare the results, we expect the last lease for each ip.
    // We also verify none of the temp or pid files remain.
    test_str = v6_hdr_ + d_1 + b_3 + c_2;
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
631
632
633
634
635
636
637
638


    // Subtest 4: neither available
    // No previous file

    // No copy file

    // Run the cleanup
639
    launch(lfc_controller, argc, argv);
640

641
642
    // Compare the results, we expect a header and no leases.
    // We also verify none of the temp or pid files remain.
643
    test_str = v6_hdr_;
644
645
646
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
    removeTestFile();
647
648
649


    // Subtest 5: a file with a lot of errors
650
    // A previous file with a lot of errors.
651
652
653
    astr = "1,\n2,\n3,\n4,\n5,\n6,\n7,\n7,\n8,\n9,\n10,\n";
    test_str = v6_hdr_ + astr + astr + astr + astr + astr +
               astr + astr + astr + astr + astr + astr;
654
    writeFile(xstr_, test_str);
655
656
657
658
659

    // No copy file

    // Run the cleanup, the file should fail but we should
    // catch the error and properly cleanup.
660
    launch(lfc_controller, argc, argv);
661

662
663
664
665
    // And we shouldn't have deleted the previous file.
    // We also verify none of the temp or pid files remain.
    EXPECT_EQ(readFile(xstr_), test_str);
    EXPECT_TRUE(noExistIOFP());
666
667
}

668
669
// @todo double launch (how to do that)

670
} // end of anonymous namespace