subnet_unittest.cc 41 KB
Newer Older
1
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#include <config.h>
16
17

#include <asiolink/io_address.h>
18
#include <dhcp/option.h>
19
#include <dhcp/dhcp6.h>
20
#include <dhcpsrv/subnet.h>
21
#include <exceptions/exceptions.h>
22

23
24
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
25
#include <limits>
26
27
28
29
30
31
32
33
34
35

// don't import the entire boost namespace.  It will unexpectedly hide uint8_t
// for some systems.
using boost::scoped_ptr;
using namespace isc;
using namespace isc::dhcp;
using namespace isc::asiolink;

namespace {

36
37
TEST(Subnet4Test, constructor) {
    EXPECT_NO_THROW(Subnet4 subnet1(IOAddress("192.0.2.2"), 16,
38
                                    1, 2, 3, 10));
39
40
41
42
43
44
45

    EXPECT_THROW(Subnet4 subnet2(IOAddress("192.0.2.0"), 33, 1, 2, 3),
                BadValue); // invalid prefix length
    EXPECT_THROW(Subnet4 subnet3(IOAddress("2001:db8::1"), 24, 1, 2, 3),
                BadValue); // IPv6 addresses are not allowed in Subnet4
}

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Checks that the subnet id can be either autogenerated or set to an
// arbitrary value through the constructor.
TEST(Subnet4Test, subnetID) {
    // Create subnet and don't specify id, so as it is autogenerated.
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 24, 1000, 2000,
                                  3000));
    SubnetID id0 = subnet->getID();

    // Create another subnet and let id be autogenerated.
    subnet.reset(new Subnet4(IOAddress("192.0.3.0"), 24, 1000, 2000,
                             3000));
    SubnetID id1 = subnet->getID();

    // The autogenerated ids must not be equal.
    EXPECT_NE(id0, id1);

    // Create third subnet but this time select an arbitrary id. The id
63
    // we use the one of the second subnet. That way we ensure that the
64
65
66
67
68
69
70
71
72
    // subnet id we provide via constructor is used and it is not
    // autogenerated - if it was autogenerated we would get id other
    // than id1 because id1 has already been used.
    subnet.reset(new Subnet4(IOAddress("192.0.4.0"), 24, 1000, 2000,
                             3000, id1));
    EXPECT_EQ(id1, subnet->getID());
}

TEST(Subnet4Test, inRange) {
73
74
75
76
77
78
    Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000);

    EXPECT_EQ(1000, subnet.getT1());
    EXPECT_EQ(2000, subnet.getT2());
    EXPECT_EQ(3000, subnet.getValid());

79
    EXPECT_EQ("0.0.0.0", subnet.getRelayInfo().addr_.toText());
80

81
82
83
84
85
86
87
88
89
    EXPECT_FALSE(subnet.inRange(IOAddress("192.0.0.0")));
    EXPECT_TRUE(subnet.inRange(IOAddress("192.0.2.0")));
    EXPECT_TRUE(subnet.inRange(IOAddress("192.0.2.1")));
    EXPECT_TRUE(subnet.inRange(IOAddress("192.0.2.255")));
    EXPECT_FALSE(subnet.inRange(IOAddress("192.0.3.0")));
    EXPECT_FALSE(subnet.inRange(IOAddress("0.0.0.0")));
    EXPECT_FALSE(subnet.inRange(IOAddress("255.255.255.255")));
}

90
91
92
93
94
// Checks whether the relay field has sane default and if it can
// be changed, stored and retrieved
TEST(Subnet4Test, relay) {
    Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000);

95
    EXPECT_EQ("0.0.0.0", subnet.getRelayInfo().addr_.toText());
96

97
98
    subnet.setRelayInfo(IOAddress("192.0.123.45"));
    EXPECT_EQ("192.0.123.45", subnet.getRelayInfo().addr_.toText());
99
100
}

Tomek Mrugalski's avatar
Tomek Mrugalski committed
101
// Checks whether siaddr field can be set and retrieved correctly.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
TEST(Subnet4Test, siaddr) {
    Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000);

    // Check if the default is 0.0.0.0
    EXPECT_EQ("0.0.0.0", subnet.getSiaddr().toText());

    // Check that we can set it up
    EXPECT_NO_THROW(subnet.setSiaddr(IOAddress("1.2.3.4")));

    // Check that we can get it back
    EXPECT_EQ("1.2.3.4", subnet.getSiaddr().toText());

    // Check that only v4 addresses are supported
    EXPECT_THROW(subnet.setSiaddr(IOAddress("2001:db8::1")),
        BadValue);
}

119
120
121
122
TEST(Subnet4Test, Pool4InSubnet4) {

    Subnet4Ptr subnet(new Subnet4(IOAddress("192.1.2.0"), 24, 1, 2, 3));

123
124
125
    PoolPtr pool1(new Pool4(IOAddress("192.1.2.0"), 25));
    PoolPtr pool2(new Pool4(IOAddress("192.1.2.128"), 26));
    PoolPtr pool3(new Pool4(IOAddress("192.1.2.192"), 30));
126

Tomek Mrugalski's avatar
Tomek Mrugalski committed
127
    EXPECT_NO_THROW(subnet->addPool(pool1));
128
129

    // If there's only one pool, get that pool
130
    PoolPtr mypool = subnet->getAnyPool(Lease::TYPE_V4);
131
132
133
    EXPECT_EQ(mypool, pool1);


Tomek Mrugalski's avatar
Tomek Mrugalski committed
134
135
    EXPECT_NO_THROW(subnet->addPool(pool2));
    EXPECT_NO_THROW(subnet->addPool(pool3));
136
137
138

    // If there are more than one pool and we didn't provide hint, we
    // should get the first pool
139
    EXPECT_NO_THROW(mypool = subnet->getAnyPool(Lease::TYPE_V4));
140
141
142
143

    EXPECT_EQ(mypool, pool1);

    // If we provide a hint, we should get a pool that this hint belongs to
144
    EXPECT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4,
Tomek Mrugalski's avatar
Tomek Mrugalski committed
145
                                             IOAddress("192.1.2.195")));
146
147
148
149
150

    EXPECT_EQ(mypool, pool3);

}

151
152
// Check if it's possible to get specified number of possible leases for
// an IPv4 subnet.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
153
TEST(Subnet4Test, getCapacity) {
154
155
156
157
158

    // There's one /24 pool.
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.1.2.0"), 24, 1, 2, 3));

    // There are no pools defined, so the total number of available addrs is 0.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
159
    EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_V4));
160
161
162
163

    // Let's add a /25 pool. That's 128 addresses.
    PoolPtr pool1(new Pool4(IOAddress("192.1.2.0"), 25));
    subnet->addPool(pool1);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
164
    EXPECT_EQ(128, subnet->getPoolCapacity(Lease::TYPE_V4));
165
166
167
168

    // Let's add another /26 pool. That's extra 64 addresses.
    PoolPtr pool2(new Pool4(IOAddress("192.1.2.128"), 26));
    subnet->addPool(pool2);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
169
    EXPECT_EQ(192, subnet->getPoolCapacity(Lease::TYPE_V4));
170
171
172
173

    // Let's add a third pool /30. This one has 4 addresses.
    PoolPtr pool3(new Pool4(IOAddress("192.1.2.192"), 30));
    subnet->addPool(pool3);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
174
    EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4));
175
176
}

177
178
179
180
181
182
TEST(Subnet4Test, Subnet4_Pool4_checks) {

    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 8, 1, 2, 3));

    // this one is in subnet
    Pool4Ptr pool1(new Pool4(IOAddress("192.255.0.0"), 16));
183
    subnet->addPool(pool1);
184
185
186
187

    // this one is larger than the subnet!
    Pool4Ptr pool2(new Pool4(IOAddress("193.0.0.0"), 24));

188
    EXPECT_THROW(subnet->addPool(pool2), BadValue);
189
190
191

    // this one is totally out of blue
    Pool4Ptr pool3(new Pool4(IOAddress("1.2.3.4"), 16));
192
    EXPECT_THROW(subnet->addPool(pool3), BadValue);
193
194
}

195
// Tests whether Subnet4 object is able to store and process properly
196
// information about allowed client class (a single class).
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
TEST(Subnet4Test, clientClasses) {
    // Create the V4 subnet.
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 8, 1, 2, 3));

    // This client does not belong to any class.
    isc::dhcp::ClientClasses no_class;

    // This client belongs to foo only.
    isc::dhcp::ClientClasses foo_class;
    foo_class.insert("foo");

    // This client belongs to bar only. I like that client.
    isc::dhcp::ClientClasses bar_class;
    bar_class.insert("bar");

    // This client belongs to foo, bar and baz classes.
    isc::dhcp::ClientClasses three_classes;
    three_classes.insert("foo");
    three_classes.insert("bar");
    three_classes.insert("baz");

    // No class restrictions defined, any client should be supported
    EXPECT_TRUE(subnet->clientSupported(no_class));
    EXPECT_TRUE(subnet->clientSupported(foo_class));
    EXPECT_TRUE(subnet->clientSupported(bar_class));
    EXPECT_TRUE(subnet->clientSupported(three_classes));

    // Let's allow only clients belongning to "bar" class.
    subnet->allowClientClass("bar");

    EXPECT_FALSE(subnet->clientSupported(no_class));
    EXPECT_FALSE(subnet->clientSupported(foo_class));
    EXPECT_TRUE(subnet->clientSupported(bar_class));
    EXPECT_TRUE(subnet->clientSupported(three_classes));
}

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
// Tests whether Subnet4 object is able to store and process properly
// information about allowed client classes (multiple classes allowed).
TEST(Subnet4Test, clientClassesMultiple) {
    // Create the V4 subnet.
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 8, 1, 2, 3));

    // This client does not belong to any class.
    isc::dhcp::ClientClasses no_class;

    // This client belongs to foo only.
    isc::dhcp::ClientClasses foo_class;
    foo_class.insert("foo");

    // This client belongs to bar only. I like that client.
    isc::dhcp::ClientClasses bar_class;
    bar_class.insert("bar");

    // No class restrictions defined, any client should be supported
    EXPECT_TRUE(subnet->clientSupported(no_class));
    EXPECT_TRUE(subnet->clientSupported(foo_class));
    EXPECT_TRUE(subnet->clientSupported(bar_class));

    // Let's allow clients belongning to "bar" or "foo" class.
    subnet->allowClientClass("bar");
    subnet->allowClientClass("foo");

    // Class-less clients are to be rejected.
    EXPECT_FALSE(subnet->clientSupported(no_class));

    // Clients in foo class should be accepted.
    EXPECT_TRUE(subnet->clientSupported(foo_class));

    // Clients in bar class should be accepted as well.
    EXPECT_TRUE(subnet->clientSupported(bar_class));
}

269
270
271
272
273
274
275
276
TEST(Subnet4Test, addInvalidOption) {
    // Create the V4 subnet.
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 8, 1, 2, 3));

    // Create NULL pointer option. Attempt to add NULL option
    // should result in exception.
    OptionPtr option2;
    ASSERT_FALSE(option2);
277
    EXPECT_THROW(subnet->getCfgOption()->add(option2, false, "dhcp4"),
278
                 isc::BadValue);
279
280
}

281
282
283
284
285
286
// This test verifies that inRange() and inPool() methods work properly.
TEST(Subnet4Test, inRangeinPool) {
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.0.0"), 8, 1, 2, 3));

    // this one is in subnet
    Pool4Ptr pool1(new Pool4(IOAddress("192.2.0.0"), 16));
287
    subnet->addPool(pool1);
288
289
290
291
292

    // 192.1.1.1 belongs to the subnet...
    EXPECT_TRUE(subnet->inRange(IOAddress("192.1.1.1")));

    // ... but it does not belong to any pool within
293
    EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.1.1.1")));
294
295
296

    // the last address that is in range, but out of pool
    EXPECT_TRUE(subnet->inRange(IOAddress("192.1.255.255")));
297
    EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.1.255.255")));
298
299
300

    // the first address that is in range, in pool
    EXPECT_TRUE(subnet->inRange(IOAddress("192.2.0.0")));
301
    EXPECT_TRUE (subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.0.0")));
302
303
304

    // let's try something in the middle as well
    EXPECT_TRUE(subnet->inRange(IOAddress("192.2.3.4")));
305
    EXPECT_TRUE (subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4")));
306
307
308

    // the last address that is in range, in pool
    EXPECT_TRUE(subnet->inRange(IOAddress("192.2.255.255")));
309
    EXPECT_TRUE (subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.255.255")));
310
311
312

    // the first address that is in range, but out of pool
    EXPECT_TRUE(subnet->inRange(IOAddress("192.3.0.0")));
313
    EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.3.0.0")));
314
315
}

316
317
318
319
320
321
322
323
324
325
326
327
328
// This test checks if the toText() method returns text representation
TEST(Subnet4Test, toText) {
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
    EXPECT_EQ("192.0.2.0/24", subnet->toText());
}

// This test checks if the get() method returns proper parameters
TEST(Subnet4Test, get) {
    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 28, 1, 2, 3));
    EXPECT_EQ("192.0.2.0", subnet->get().first.toText());
    EXPECT_EQ(28, subnet->get().second);
}

329
330
331
332
333
334
335
336
337
338

// Checks if last allocated address/prefix is stored/retrieved properly
TEST(Subnet4Test, lastAllocated) {
    IOAddress addr("192.0.2.17");

    IOAddress last("192.0.2.255");

    Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));

    // Check initial conditions (all should be set to the last address in range)
339
    EXPECT_EQ(last.toText(), subnet->getLastAllocated(Lease::TYPE_V4).toText());
340
341

    // Now set last allocated for IA
342
343
    EXPECT_NO_THROW(subnet->setLastAllocated(Lease::TYPE_V4, addr));
    EXPECT_EQ(addr.toText(), subnet->getLastAllocated(Lease::TYPE_V4).toText());
344
345

    // No, you can't set the last allocated IPv6 address in IPv4 subnet
346
347
348
    EXPECT_THROW(subnet->setLastAllocated(Lease::TYPE_TA, addr), BadValue);
    EXPECT_THROW(subnet->setLastAllocated(Lease::TYPE_TA, addr), BadValue);
    EXPECT_THROW(subnet->setLastAllocated(Lease::TYPE_PD, addr), BadValue);
349
350
}

351
352
353
354
355
356
357
358
// Checks if the V4 is the only allowed type for Pool4 and if getPool()
// is working properly.
TEST(Subnet4Test, PoolType) {

    Subnet4Ptr subnet(new Subnet4(IOAddress("192.2.0.0"), 16, 1, 2, 3));

    PoolPtr pool1(new Pool4(IOAddress("192.2.1.0"), 24));
    PoolPtr pool2(new Pool4(IOAddress("192.2.2.0"), 24));
359
360
361
    PoolPtr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:3::"), 64));
    PoolPtr pool4(new Pool6(Lease::TYPE_TA, IOAddress("2001:db8:1:4::"), 64));
    PoolPtr pool5(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:1::"), 64));
362
363

    // There should be no pools of any type by default
364
    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_V4));
365
366

    // It should not be possible to ask for V6 pools in Subnet4
367
368
369
    EXPECT_THROW(subnet->getAnyPool(Lease::TYPE_NA), BadValue);
    EXPECT_THROW(subnet->getAnyPool(Lease::TYPE_TA), BadValue);
    EXPECT_THROW(subnet->getAnyPool(Lease::TYPE_PD), BadValue);
370
371

    // Let's add a single V4 pool and check that it can be retrieved
Tomek Mrugalski's avatar
Tomek Mrugalski committed
372
    EXPECT_NO_THROW(subnet->addPool(pool1));
373
374

    // If there's only one IA pool, get that pool (without and with hint)
375
376
    EXPECT_EQ(pool1, subnet->getAnyPool(Lease::TYPE_V4));
    EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.1.167")));
377
378

    // Let's add additional V4 pool
Tomek Mrugalski's avatar
Tomek Mrugalski committed
379
    EXPECT_NO_THROW(subnet->addPool(pool2));
380
381

    // Try without hints
382
    EXPECT_EQ(pool1, subnet->getAnyPool(Lease::TYPE_V4));
383
384

    // Try with valid hints
385
386
    EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_V4, IOAddress("192.2.1.5")));
    EXPECT_EQ(pool2, subnet->getPool(Lease::TYPE_V4, IOAddress("192.2.2.254")));
387
388

    // Try with bogus hints (hints should be ingored)
389
    EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_V4, IOAddress("10.1.1.1")));
390
391
392
393
394
395
396

    // Trying to add Pool6 to Subnet4 is a big no,no!
    EXPECT_THROW(subnet->addPool(pool3), BadValue);
    EXPECT_THROW(subnet->addPool(pool4), BadValue);
    EXPECT_THROW(subnet->addPool(pool5), BadValue);
}

397
398
// Tests for Subnet6

399
400
401
402
403
404
405
406
407
408
409
TEST(Subnet6Test, constructor) {

    EXPECT_NO_THROW(Subnet6 subnet1(IOAddress("2001:db8:1::"), 64,
                                    1, 2, 3, 4));

    EXPECT_THROW(Subnet6 subnet2(IOAddress("2001:db8:1::"), 129, 1, 2, 3, 4),
                BadValue); // invalid prefix length
    EXPECT_THROW(Subnet6 subnet3(IOAddress("192.168.0.0"), 32, 1, 2, 3, 4),
                BadValue); // IPv4 addresses are not allowed in Subnet6
}

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
// Checks that the subnet id can be either autogenerated or set to an
// arbitrary value through the constructor.
TEST(Subnet6Test, subnetID) {
    // Create subnet and don't specify id, so as it is autogenerated.
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 64, 1000, 2000,
                                  3000, 4000));
    SubnetID id0 = subnet->getID();

    // Create another subnet and let id be autogenerated.
    subnet.reset(new Subnet6(IOAddress("2001:db8:2::"), 64, 1000, 2000,
                             3000, 4000));
    SubnetID id1 = subnet->getID();

    // The autogenerated ids must not be equal.
    EXPECT_NE(id0, id1);

    // Create third subnet but this time select an arbitrary id. The id
    // we use us the one of second subnet. That way we ensure that the
    // subnet id we provide via constructor is used and it is not
    // autogenerated - if it was autogenerated we would get id other
    // than id1 because id1 has already been used.
    subnet.reset(new Subnet6(IOAddress("2001:db8:3::"), 64, 1000, 2000,
                             3000, 4000, id1));
    EXPECT_EQ(id1, subnet->getID());
}

TEST(Subnet6Test, inRange) {
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
    Subnet6 subnet(IOAddress("2001:db8:1::"), 64, 1000, 2000, 3000, 4000);

    EXPECT_EQ(1000, subnet.getT1());
    EXPECT_EQ(2000, subnet.getT2());
    EXPECT_EQ(3000, subnet.getPreferred());
    EXPECT_EQ(4000, subnet.getValid());

    EXPECT_FALSE(subnet.inRange(IOAddress("2001:db8:0:ffff:ffff:ffff:ffff:ffff")));
    EXPECT_TRUE(subnet.inRange(IOAddress("2001:db8:1::0")));
    EXPECT_TRUE(subnet.inRange(IOAddress("2001:db8:1::1")));
    EXPECT_TRUE(subnet.inRange(IOAddress("2001:db8:1::ffff:ffff:ffff:ffff")));
    EXPECT_FALSE(subnet.inRange(IOAddress("2001:db8:1:1::")));
    EXPECT_FALSE(subnet.inRange(IOAddress("::")));
}

452
453
454
455
456
// Checks whether the relay field has sane default and if it can
// be changed, stored and retrieved
TEST(Subnet6Test, relay) {
    Subnet6 subnet(IOAddress("2001:db8:1::"), 64, 1000, 2000, 3000, 4000);

457
    EXPECT_EQ("::", subnet.getRelayInfo().addr_.toText());
458

459
    subnet.setRelayInfo(IOAddress("2001:ffff::1"));
460

461
    EXPECT_EQ("2001:ffff::1", subnet.getRelayInfo().addr_.toText());
462
463
}

464
465
// Test checks whether the number of addresses available in the pools are
// calculated properly.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
466
TEST(Subnet6Test, Pool6getCapacity) {
467
468
469
470
471
472
473
474
475
476

    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // There's 2^16 = 65536 addresses in this one.
    PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 112));

    // There's 2^32 = 4294967296 addresses in each of those.
    PoolPtr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:2::"), 96));
    PoolPtr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:3::"), 96));

Tomek Mrugalski's avatar
Tomek Mrugalski committed
477
478
479
    EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_NA));
    EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_TA));
    EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_PD));
480
481

    subnet->addPool(pool1);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
482
    EXPECT_EQ(65536, subnet->getPoolCapacity(Lease::TYPE_NA));
483
484

    subnet->addPool(pool2);
485
    EXPECT_EQ(uint64_t(4294967296ull + 65536), subnet->getPoolCapacity(Lease::TYPE_NA));
486
487

    subnet->addPool(pool3);
488
    EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536),
Tomek Mrugalski's avatar
Tomek Mrugalski committed
489
              subnet->getPoolCapacity(Lease::TYPE_NA));
490
491
492
493
494

    // This is 2^64 prefixes. We're overflown uint64_t.
    PoolPtr pool4(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:4::"), 64));
    subnet->addPool(pool4);
    EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
Tomek Mrugalski's avatar
Tomek Mrugalski committed
495
              subnet->getPoolCapacity(Lease::TYPE_NA));
496
497
498
499

    PoolPtr pool5(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:5::"), 64));
    subnet->addPool(pool5);
    EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
Tomek Mrugalski's avatar
Tomek Mrugalski committed
500
              subnet->getPoolCapacity(Lease::TYPE_NA));
501
502
503
504
}

// Test checks whether the number of prefixes available in the pools are
// calculated properly.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
505
TEST(Subnet6Test, Pool6PdgetPoolCapacity) {
506
507
508
509
510
511
512
513
514
515

    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));

    // There's 2^16 = 65536 addresses in this one.
    PoolPtr pool1(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1::"), 48, 64));

    // There's 2^32 = 4294967296 addresses in each of those.
    PoolPtr pool2(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:2::"), 48, 80));
    PoolPtr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:3::"), 48, 80));

Tomek Mrugalski's avatar
Tomek Mrugalski committed
516
517
518
    EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_NA));
    EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_TA));
    EXPECT_EQ(0, subnet->getPoolCapacity(Lease::TYPE_PD));
519
520

    subnet->addPool(pool1);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
521
    EXPECT_EQ(65536, subnet->getPoolCapacity(Lease::TYPE_PD));
522
523

    subnet->addPool(pool2);
524
    EXPECT_EQ(uint64_t(4294967296ull + 65536), subnet->getPoolCapacity(Lease::TYPE_PD));
525
526

    subnet->addPool(pool3);
527
    EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536),
Tomek Mrugalski's avatar
Tomek Mrugalski committed
528
              subnet->getPoolCapacity(Lease::TYPE_PD));
529
530
531
532
533

    // This is 2^64.
    PoolPtr pool4(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:4::"), 48, 112));
    subnet->addPool(pool4);
    EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
Tomek Mrugalski's avatar
Tomek Mrugalski committed
534
              subnet->getPoolCapacity(Lease::TYPE_PD));
535
536
537
538

    PoolPtr pool5(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:5::"), 48, 112));
    subnet->addPool(pool5);
    EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
Tomek Mrugalski's avatar
Tomek Mrugalski committed
539
              subnet->getPoolCapacity(Lease::TYPE_PD));
540
541
}

542
543
544
545
TEST(Subnet6Test, Pool6InSubnet6) {

    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

546
547
548
    PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64));
    PoolPtr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:2::"), 64));
    PoolPtr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:3::"), 64));
549

550
    subnet->addPool(pool1);
551
552

    // If there's only one pool, get that pool
553
    PoolPtr mypool = subnet->getAnyPool(Lease::TYPE_NA);
554
555
    EXPECT_EQ(mypool, pool1);

556
557
    subnet->addPool(pool2);
    subnet->addPool(pool3);
558
559
560

    // If there are more than one pool and we didn't provide hint, we
    // should get the first pool
561
    mypool = subnet->getAnyPool(Lease::TYPE_NA);
562
563
564
565

    EXPECT_EQ(mypool, pool1);

    // If we provide a hint, we should get a pool that this hint belongs to
566
    mypool = subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:3::dead:beef"));
567
568
569
570

    EXPECT_EQ(mypool, pool3);
}

571
// Check if Subnet6 supports different types of pools properly.
572
TEST(Subnet6Test, poolTypes) {
573
574
575

    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

576
577
578
    PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64));
    PoolPtr pool2(new Pool6(Lease::TYPE_TA, IOAddress("2001:db8:1:2::"), 64));
    PoolPtr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:3::"), 64));
579
    PoolPtr pool4(new Pool6(Lease::TYPE_PD, IOAddress("3000:1::"), 64));
580
581
582
583

    PoolPtr pool5(new Pool4(IOAddress("192.0.2.0"), 24));

    // There should be no pools of any type by default
584
585
586
    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_NA));
    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_TA));
    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_PD));
587
588

    // Trying to get IPv4 pool from Subnet6 is not allowed
589
    EXPECT_THROW(subnet->getAnyPool(Lease::TYPE_V4), BadValue);
590
591

    // Let's add a single IA pool and check that it can be retrieved
Tomek Mrugalski's avatar
Tomek Mrugalski committed
592
    EXPECT_NO_THROW(subnet->addPool(pool1));
593
594

    // If there's only one IA pool, get that pool
595
596
    EXPECT_EQ(pool1, subnet->getAnyPool(Lease::TYPE_NA));
    EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:1::1")));
597
598

    // Check if pools of different type are not returned
599
600
    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_TA));
    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Lease::TYPE_PD));
601
602

    // We ask with good hints, but wrong types, should return nothing
603
604
    EXPECT_EQ(PoolPtr(), subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:2::1")));
    EXPECT_EQ(PoolPtr(), subnet->getPool(Lease::TYPE_TA, IOAddress("2001:db8:1:3::1")));
605
606

    // Let's add TA and PD pools
Tomek Mrugalski's avatar
Tomek Mrugalski committed
607
608
    EXPECT_NO_THROW(subnet->addPool(pool2));
    EXPECT_NO_THROW(subnet->addPool(pool3));
609
610

    // Try without hints
611
612
613
    EXPECT_EQ(pool1, subnet->getAnyPool(Lease::TYPE_NA));
    EXPECT_EQ(pool2, subnet->getAnyPool(Lease::TYPE_TA));
    EXPECT_EQ(pool3, subnet->getAnyPool(Lease::TYPE_PD));
614
615

    // Try with valid hints
616
617
618
    EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:1::1")));
    EXPECT_EQ(pool2, subnet->getPool(Lease::TYPE_TA, IOAddress("2001:db8:1:2::1")));
    EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:3::1")));
619
620

    // Try with bogus hints (hints should be ingored)
621
622
623
    EXPECT_EQ(pool1, subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8:1:7::1")));
    EXPECT_EQ(pool2, subnet->getPool(Lease::TYPE_TA, IOAddress("2001:db8:1:7::1")));
    EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:7::1")));
624
625

    // Let's add a second PD pool
Tomek Mrugalski's avatar
Tomek Mrugalski committed
626
    EXPECT_NO_THROW(subnet->addPool(pool4));
627
628

    // Without hints, it should return the first pool
629
    EXPECT_EQ(pool3, subnet->getAnyPool(Lease::TYPE_PD));
630
631

    // With valid hint, it should return that hint
632
    EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:3::1")));
633
    EXPECT_EQ(pool4, subnet->getPool(Lease::TYPE_PD, IOAddress("3000:1::")));
634
635

    // With invalid hint, it should return the first pool
636
    EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8::123")));
637
638
639
640
641

    // Adding Pool4 to Subnet6 is a big no, no!
    EXPECT_THROW(subnet->addPool(pool5), BadValue);
}

642
// Tests whether Subnet6 object is able to store and process properly
643
// information about allowed client class (a single class).
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
TEST(Subnet6Test, clientClasses) {
    // Create the V6 subnet.
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // This client does not belong to any class.
    isc::dhcp::ClientClasses no_class;

    // This client belongs to foo only.
    isc::dhcp::ClientClasses foo_class;
    foo_class.insert("foo");

    // This client belongs to bar only. I like that client.
    isc::dhcp::ClientClasses bar_class;
    bar_class.insert("bar");

    // This client belongs to foo, bar and baz classes.
    isc::dhcp::ClientClasses three_classes;
    three_classes.insert("foo");
    three_classes.insert("bar");
    three_classes.insert("baz");

    // No class restrictions defined, any client should be supported
    EXPECT_TRUE(subnet->clientSupported(no_class));
    EXPECT_TRUE(subnet->clientSupported(foo_class));
    EXPECT_TRUE(subnet->clientSupported(bar_class));
    EXPECT_TRUE(subnet->clientSupported(three_classes));

    // Let's allow only clients belongning to "bar" class.
    subnet->allowClientClass("bar");

    EXPECT_FALSE(subnet->clientSupported(no_class));
    EXPECT_FALSE(subnet->clientSupported(foo_class));
    EXPECT_TRUE(subnet->clientSupported(bar_class));
    EXPECT_TRUE(subnet->clientSupported(three_classes));
}

680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
// Tests whether Subnet6 object is able to store and process properly
// information about allowed client class (multiple classes allowed).
TEST(Subnet6Test, clientClassesMultiple) {
    // Create the V6 subnet.
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // This client does not belong to any class.
    isc::dhcp::ClientClasses no_class;

    // This client belongs to foo only.
    isc::dhcp::ClientClasses foo_class;
    foo_class.insert("foo");

    // This client belongs to bar only. I like that client.
    isc::dhcp::ClientClasses bar_class;
    bar_class.insert("bar");

    // No class restrictions defined, any client should be supported
    EXPECT_TRUE(subnet->clientSupported(no_class));
    EXPECT_TRUE(subnet->clientSupported(foo_class));
    EXPECT_TRUE(subnet->clientSupported(bar_class));

    // Let's allow only clients belongning to "foo" or "bar" class.
    subnet->allowClientClass("foo");
    subnet->allowClientClass("bar");

    // Class-less clients are to be rejected.
    EXPECT_FALSE(subnet->clientSupported(no_class));

    // Clients in foo class should be accepted.
    EXPECT_TRUE(subnet->clientSupported(foo_class));

    // Clients in bar class should be accepted as well.
    EXPECT_TRUE(subnet->clientSupported(bar_class));
}

716
717
718
719
720
TEST(Subnet6Test, Subnet6_Pool6_checks) {

    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // this one is in subnet
721
    Pool6Ptr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64));
722
    subnet->addPool(pool1);
723
724

    // this one is larger than the subnet!
725
    Pool6Ptr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8::"), 48));
726

727
    EXPECT_THROW(subnet->addPool(pool2), BadValue);
728
729
730


    // this one is totally out of blue
731
    Pool6Ptr pool3(new Pool6(Lease::TYPE_NA, IOAddress("3000::"), 16));
732
    EXPECT_THROW(subnet->addPool(pool3), BadValue);
733
734


735
    Pool6Ptr pool4(new Pool6(Lease::TYPE_NA, IOAddress("4001:db8:1::"), 80));
736
    EXPECT_THROW(subnet->addPool(pool4), BadValue);
737
}
738

739
740
741
742
743
744
745
TEST(Subnet6Test, addOptions) {
    // Create as subnet to add options to it.
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // Differentiate options by their codes (100-109)
    for (uint16_t code = 100; code < 110; ++code) {
        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
746
        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
747
748
749
750
751
752
    }

    // Add 7 options to another option space. The option codes partially overlap
    // with option codes that we have added to dhcp6 option space.
    for (uint16_t code = 105; code < 112; ++code) {
        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
753
        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "isc"));
754
755
756
    }

    // Get options from the Subnet and check if all 10 are there.
757
    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
758
759
    ASSERT_TRUE(options);
    ASSERT_EQ(10, options->size());
760

761
    // Validate codes of options added to dhcp6 option space.
762
    uint16_t expected_code = 100;
763
    for (OptionContainer::const_iterator option_desc = options->begin();
764
         option_desc != options->end(); ++option_desc) {
765
766
        ASSERT_TRUE(option_desc->option_);
        EXPECT_EQ(expected_code, option_desc->option_->getType());
767
768
769
        ++expected_code;
    }

770
    options = subnet->getCfgOption()->getAll("isc");
771
772
    ASSERT_TRUE(options);
    ASSERT_EQ(7, options->size());
773
774
775

    // Validate codes of options added to isc option space.
    expected_code = 105;
776
    for (OptionContainer::const_iterator option_desc = options->begin();
777
         option_desc != options->end(); ++option_desc) {
778
779
        ASSERT_TRUE(option_desc->option_);
        EXPECT_EQ(expected_code, option_desc->option_->getType());
780
781
782
783
        ++expected_code;
    }

    // Try to get options from a non-existing option space.
784
    options = subnet->getCfgOption()->getAll("abcd");
785
786
    ASSERT_TRUE(options);
    EXPECT_TRUE(options->empty());
787
788
789
790
791
792
793
794
795
796
797
}

TEST(Subnet6Test, addNonUniqueOptions) {
    // Create as subnet to add options to it.
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // Create a set of options with non-unique codes.
    for (int i = 0;  i < 2; ++i) {
        // In the inner loop we create options with unique codes (100-109).
        for (uint16_t code = 100; code < 110; ++code) {
            OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
798
            ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
799
800
801
802
        }
    }

    // Sanity check that all options are there.
803
    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
804
    ASSERT_EQ(20, options->size());
805
806

    // Use container index #1 to get the options by their codes.
807
    OptionContainerTypeIndex& idx = options->get<1>();
808
809
    // Look for the codes 100-109.
    for (uint16_t code = 100; code < 110; ++ code) {
810
        // For each code we should get two instances of options->
811
812
        std::pair<OptionContainerTypeIndex::const_iterator,
                  OptionContainerTypeIndex::const_iterator> range =
813
814
815
816
817
            idx.equal_range(code);
        // Distance between iterators indicates how many options
        // have been retured for the particular code.
        ASSERT_EQ(2, distance(range.first, range.second));
        // Check that returned options actually have the expected option code.
818
        for (OptionContainerTypeIndex::const_iterator option_desc = range.first;
819
             option_desc != range.second; ++option_desc) {
820
821
            ASSERT_TRUE(option_desc->option_);
            EXPECT_EQ(code, option_desc->option_->getType());
822
823
824
825
826
        }
    }

    // Let's try to find some non-exiting option.
    const uint16_t non_existing_code = 150;
827
828
    std::pair<OptionContainerTypeIndex::const_iterator,
              OptionContainerTypeIndex::const_iterator> range =
829
830
831
832
833
834
835
836
837
838
839
840
        idx.equal_range(non_existing_code);
    // Empty set is expected.
    EXPECT_EQ(0, distance(range.first, range.second));
}

TEST(Subnet6Test, addPersistentOption) {
    // Create as subnet to add options to it.
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // Add 10 options to the subnet with option codes 100 - 109.
    for (uint16_t code = 100; code < 110; ++code) {
        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
841
842
843
844
845
        // We create 10 options and want some of them to be flagged
        // persistent and some non-persistent. Persistent options are
        // those that server sends to clients regardless if they ask
        // for them or not. We pick 3 out of 10 options and mark them
        // non-persistent and 7 other options persistent.
846
        // Code values: 102, 105 and 108 are divisible by 3
847
848
849
        // and options with these codes will be flagged non-persistent.
        // Options with other codes will be flagged persistent.
        bool persistent = (code % 3) ? true : false;
850
        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, persistent, "dhcp6"));
851
852
853
    }

    // Get added options from the subnet.
854
    OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
855

856
    // options->get<2> returns reference to container index #2. This
857
    // index is used to access options by the 'persistent' flag.
858
    OptionContainerPersistIndex& idx = options->get<2>();
859

860
    // Get all persistent options->
861
862
    std::pair<OptionContainerPersistIndex::const_iterator,
              OptionContainerPersistIndex::const_iterator> range_persistent =
863
        idx.equal_range(true);
864
865
    // 3 out of 10 options have been flagged persistent.
    ASSERT_EQ(7, distance(range_persistent.first, range_persistent.second));
866

867
    // Get all non-persistent options->
868
869
    std::pair<OptionContainerPersistIndex::const_iterator,
              OptionContainerPersistIndex::const_iterator> range_non_persistent =
870
        idx.equal_range(false);
871
872
    // 7 out of 10 options have been flagged persistent.
    ASSERT_EQ(3, distance(range_non_persistent.first, range_non_persistent.second));
873
}
874

875
TEST(Subnet6Test, getOptions) {
876
877
878
879
880
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 56, 1, 2, 3, 4));

    // Add 10 options to a "dhcp6" option space in the subnet.
    for (uint16_t code = 100; code < 110; ++code) {
        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
881
        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
882
883
884
885
886
887
888
    }

    // Check that we can get each added option descriptor using
    // individually.
    for (uint16_t code = 100; code < 110; ++code) {
        std::ostringstream stream;
        // First, try the invalid option space name.
889
        OptionDescriptor desc = subnet->getCfgOption()->get("isc", code);
890
        // Returned descriptor should contain NULL option ptr.
891
        EXPECT_FALSE(desc.option_);
892
        // Now, try the valid option space.
893
        desc = subnet->getCfgOption()->get("dhcp6", code);
894
        // Test that the option code matches the expected code.
895
896
        ASSERT_TRUE(desc.option_);
        EXPECT_EQ(code, desc.option_->getType());
897
898
899
    }
}

900

901
TEST(Subnet6Test, addVendorOption) {
902
903
904
905
906
907
908

    // Create as subnet to add options to it.
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));

    // Differentiate options by their codes (100-109)
    for (uint16_t code = 100; code < 110; ++code) {
        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
909
        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "vendor-12345678"));
910
911
912
913
914
915
    }

    // Add 7 options to another option space. The option codes partially overlap
    // with option codes that we have added to dhcp6 option space.
    for (uint16_t code = 105; code < 112; ++code) {
        OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
916
        ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "vendor-87654321"));
917
918
919
    }

    // Get options from the Subnet and check if all 10 are there.
920
    OptionContainerPtr options = subnet->getCfgOption()->getAll(12345678);
921
922
923
924
925
    ASSERT_TRUE(options);
    ASSERT_EQ(10, options->size());

    // Validate codes of options added to dhcp6 option space.
    uint16_t expected_code = 100;
926
    for (OptionContainer::const_iterator option_desc = options->begin();
927
         option_desc != options->end(); ++option_desc) {
928
929
        ASSERT_TRUE(option_desc->option_);
        EXPECT_EQ(expected_code, option_desc->option_->getType());
930
931
932
        ++expected_code;
    }

933
    options = subnet->getCfgOption()->getAll(87654321);
934
935
936
937
938
    ASSERT_TRUE(options);
    ASSERT_EQ(7, options->size());

    // Validate codes of options added to isc option space.
    expected_code = 105;
939
    for (OptionContainer::const_iterator option_desc = options->begin();
940
         option_desc != options->end(); ++option_desc) {
941
942
        ASSERT_TRUE(option_desc->option_);
        EXPECT_EQ(expected_code, option_desc->option_->getType());
943
944
945
946
        ++expected_code;
    }

    // Try to get options from a non-existing option space.
947
    options = subnet->getCfgOption()->getAll(1111111);
948
949
950
951
952
953
    ASSERT_TRUE(options);
    EXPECT_TRUE(options->empty());
}



954
955
956
957
958
// This test verifies that inRange() and inPool() methods work properly.
TEST(Subnet6Test, inRangeinPool) {
    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));

    // this one is in subnet
959
    Pool6Ptr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8::10"),
960
                             IOAddress("2001:db8::20")));
961
    subnet->addPool(pool1);
962
963
964
965

    // 192.1.1.1 belongs to the subnet...
    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::1")));
    // ... but it does not belong to any pool within
966
    EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::1")));
967
968
969

    // the last address that is in range, but out of pool
    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::f")));
970
    EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::f")));
971
972
973

    // the first address that is in range, in pool
    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::10")));
974
    EXPECT_TRUE (subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::10")));
975
976
977

    // let's try something in the middle as well
    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::18")));
978
    EXPECT_TRUE (subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18")));
979
980
981

    // the last address that is in range, in pool
    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::20")));
982
    EXPECT_TRUE (subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::20")));
983
984
985

    // the first address that is in range, but out of pool
    EXPECT_TRUE(subnet->inRange(IOAddress("2001:db8::21")));
986
    EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::21")));
987
988
}

989
990
// This test checks if the toText() method returns text representation
TEST(Subnet6Test, toText) {
991
992
    Subnet6 subnet(IOAddress("2001:db8::"), 32, 1, 2, 3, 4);
    EXPECT_EQ("2001:db8::/32", subnet.toText());
993
994
995
996
}

// This test checks if the get() method returns proper parameters
TEST(Subnet6Test, get) {
997
998
999
    Subnet6 subnet(IOAddress("2001:db8::"), 32, 1, 2, 3, 4);
    EXPECT_EQ("2001:db8::", subnet.get().first.toText());
    EXPECT_EQ(32, subnet.get().second);
1000
}
For faster browsing, not all history is shown. View entire blame