Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
4698f464
Commit
4698f464
authored
Feb 06, 2015
by
Tomek Mrugalski
🛰
Browse files
[3677] Initial handful of reservation+renewal tests implemented.
parent
e171825f
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcpsrv/alloc_engine.cc
View file @
4698f464
...
...
@@ -1672,6 +1672,11 @@ AllocEngine::renewLeases6(ClientContext6& ctx) {
removeNonreservedLeases6
(
ctx
,
leases
);
}
// If we happen to removed all leases, get something new for this guy.
if
(
leases
.
empty
())
{
leases
=
allocateUnreservedLeases6
(
ctx
);
}
// Extend all existing leases that passed all checks.
for
(
Lease6Collection
::
iterator
l
=
leases
.
begin
();
l
!=
leases
.
end
();
++
l
)
{
extendLease6
(
ctx
,
*
l
);
...
...
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
View file @
4698f464
...
...
@@ -17,6 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcp/duid.h>
#include <dhcp/dhcp4.h>
#include <dhcp/dhcp6.h>
#include <dhcpsrv/alloc_engine.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/host_mgr.h>
...
...
@@ -298,6 +299,98 @@ public:
return
(
lease
);
}
/// @brief Checks if the simple allocation can succeed
///
/// The type of lease is determined by pool type (pool->getType()
///
/// @param pool pool from which the lease will be allocated from
/// @param hint address to be used as a hint
/// @param fake true - this is fake allocation (SOLICIT)
/// @param in_pool specifies whether the lease is expected to be in pool
/// @return allocated lease(s) (may be empty)
Lease6Collection
allocateTest
(
AllocEngine
&
engine
,
const
Pool6Ptr
&
pool
,
const
IOAddress
&
hint
,
bool
fake
,
bool
in_pool
=
true
)
{
Lease
::
Type
type
=
pool
->
getType
();
uint8_t
expected_len
=
pool
->
getLength
();
AllocEngine
::
ClientContext6
ctx
(
subnet_
,
duid_
,
iaid_
,
hint
,
type
,
false
,
false
,
""
,
fake
);
Lease6Collection
leases
;
EXPECT_NO_THROW
(
leases
=
engine
.
allocateLeases6
(
ctx
));
for
(
Lease6Collection
::
iterator
it
=
leases
.
begin
();
it
!=
leases
.
end
();
++
it
)
{
// Do all checks on the lease
checkLease6
(
*
it
,
type
,
expected_len
,
in_pool
,
in_pool
);
// Check that the lease is indeed in LeaseMgr
Lease6Ptr
from_mgr
=
LeaseMgrFactory
::
instance
().
getLease6
(
type
,
(
*
it
)
->
addr_
);
if
(
!
fake
)
{
// This is a real (REQUEST) allocation, the lease must be in the DB
EXPECT_TRUE
(
from_mgr
)
<<
"Lease "
<<
from_mgr
->
addr_
.
toText
()
<<
" returned by allocateLeases6(), "
<<
"but was not present in LeaseMgr"
;
if
(
!
from_mgr
)
{
return
(
leases
);
}
// Now check that the lease in LeaseMgr has the same parameters
detailCompareLease
(
*
it
,
from_mgr
);
}
else
{
// This is a fake (SOLICIT) allocation, the lease must not be in DB
EXPECT_FALSE
(
from_mgr
)
<<
"Lease "
<<
from_mgr
->
addr_
.
toText
()
<<
" returned by allocateLeases6(), "
<<
"was present in LeaseMgr (expected to be"
<<
" not present)"
;
if
(
from_mgr
)
{
return
(
leases
);
}
}
}
return
(
leases
);
}
Lease6Collection
renewTest
(
AllocEngine
&
engine
,
const
Pool6Ptr
&
pool
,
AllocEngine
::
HintContainer
&
hints
,
bool
in_pool
=
true
)
{
Lease
::
Type
type
=
pool
->
getType
();
uint8_t
expected_len
=
pool
->
getLength
();
AllocEngine
::
ClientContext6
ctx
(
subnet_
,
duid_
,
iaid_
,
IOAddress
(
"::"
),
type
,
false
,
false
,
""
,
false
);
ctx
.
hints_
=
hints
;
ctx
.
query_
.
reset
(
new
Pkt6
(
DHCPV6_RENEW
,
123
));
Lease6Collection
leases
=
engine
.
renewLeases6
(
ctx
);
for
(
Lease6Collection
::
iterator
it
=
leases
.
begin
();
it
!=
leases
.
end
();
++
it
)
{
// Do all checks on the lease
checkLease6
(
*
it
,
type
,
expected_len
,
in_pool
,
in_pool
);
// Check that the lease is indeed in LeaseMgr
Lease6Ptr
from_mgr
=
LeaseMgrFactory
::
instance
().
getLease6
(
type
,
(
*
it
)
->
addr_
);
// This is a real (REQUEST) allocation, the lease must be in the DB
EXPECT_TRUE
(
from_mgr
)
<<
"Lease "
<<
from_mgr
->
addr_
.
toText
()
<<
" returned by allocateLeases6(), "
<<
"but was not present in LeaseMgr"
;
if
(
!
from_mgr
)
{
return
(
leases
);
}
// Now check that the lease in LeaseMgr has the same parameters
detailCompareLease
(
*
it
,
from_mgr
);
}
return
(
leases
);
}
/// @brief Checks if the address allocation with a hint that is in range,
/// in pool, but is currently used, can succeed
///
...
...
@@ -1526,6 +1619,127 @@ TEST_F(AllocEngine6Test, allocateLeasesInvalidData) {
}
// Checks whether an address can be renewed (simple case, no reservation tricks)
TEST_F
(
AllocEngine6Test
,
addressRenewal
)
{
AllocEngine
engine
(
AllocEngine
::
ALLOC_ITERATIVE
,
100
);
Lease6Collection
leases
;
leases
=
allocateTest
(
engine
,
pool_
,
IOAddress
(
"::"
),
false
,
true
);
ASSERT_EQ
(
1
,
leases
.
size
());
// This is what the client will send in his renew message.
AllocEngine
::
HintContainer
hints
;
hints
.
push_back
(
make_pair
(
leases
[
0
]
->
addr_
,
128
));
Lease6Collection
renewed
=
renewTest
(
engine
,
pool_
,
hints
);
ASSERT_EQ
(
1
,
renewed
.
size
());
// Check that the lease was indeed renewed and hasn't changed
// (i.e. the same address, preferred and valid lifetimes)
/// @todo: use leaseCompare, but ignore cltt_
EXPECT_EQ
(
leases
[
0
]
->
addr_
,
renewed
[
0
]
->
addr_
);
EXPECT_EQ
(
leases
[
0
]
->
type_
,
renewed
[
0
]
->
type_
);
EXPECT_EQ
(
leases
[
0
]
->
preferred_lft_
,
renewed
[
0
]
->
preferred_lft_
);
EXPECT_EQ
(
leases
[
0
]
->
valid_lft_
,
renewed
[
0
]
->
valid_lft_
);
}
// Checks whether an address can be renewed (in-pool reservation)
TEST_F
(
AllocEngine6Test
,
reservedAddressRenewal
)
{
// Create reservation for the client. This is in-pool reservation,
// as the pool is 2001:db8:1::10 - 2001:db8:1::20.
createHost6
(
true
,
IPv6Resrv
::
TYPE_NA
,
IOAddress
(
"2001:db8:1::1c"
),
128
);
AllocEngine
engine
(
AllocEngine
::
ALLOC_ITERATIVE
,
100
);
Lease6Collection
leases
;
leases
=
allocateTest
(
engine
,
pool_
,
IOAddress
(
"::"
),
false
,
true
);
ASSERT_EQ
(
1
,
leases
.
size
());
ASSERT_EQ
(
"2001:db8:1::1c"
,
leases
[
0
]
->
addr_
.
toText
());
// This is what the client will send in his renew message.
AllocEngine
::
HintContainer
hints
;
hints
.
push_back
(
make_pair
(
leases
[
0
]
->
addr_
,
128
));
Lease6Collection
renewed
=
renewTest
(
engine
,
pool_
,
hints
);
ASSERT_EQ
(
1
,
renewed
.
size
());
ASSERT_EQ
(
"2001:db8:1::1c"
,
leases
[
0
]
->
addr_
.
toText
());
}
// Checks whether address can change during renew (if there is a new
// reservation for this client)
TEST_F
(
AllocEngine6Test
,
reservedAddressRenewChange
)
{
AllocEngine
engine
(
AllocEngine
::
ALLOC_ITERATIVE
,
100
);
Lease6Collection
leases
;
leases
=
allocateTest
(
engine
,
pool_
,
IOAddress
(
"::"
),
false
,
true
);
ASSERT_EQ
(
1
,
leases
.
size
());
ASSERT_NE
(
"2001:db8:1::1c"
,
leases
[
0
]
->
addr_
.
toText
());
// This is what the client will send in his renew message.
AllocEngine
::
HintContainer
hints
;
hints
.
push_back
(
make_pair
(
leases
[
0
]
->
addr_
,
128
));
// Create reservation for the client. This is in-pool reservation,
// as the pool is 2001:db8:1::10 - 2001:db8:1::20.
createHost6
(
true
,
IPv6Resrv
::
TYPE_NA
,
IOAddress
(
"2001:db8:1::1c"
),
128
);
Lease6Collection
renewed
=
renewTest
(
engine
,
pool_
,
hints
);
ASSERT_EQ
(
1
,
renewed
.
size
());
ASSERT_EQ
(
"2001:db8:1::1c"
,
renewed
[
0
]
->
addr_
.
toText
());
}
// Checks whether address can change during renew (if there is a new
// reservation for this address for another client)
TEST_F
(
AllocEngine6Test
,
reservedAddressRenewReserved
)
{
AllocEngine
engine
(
AllocEngine
::
ALLOC_ITERATIVE
,
100
);
Lease6Collection
leases
;
leases
=
allocateTest
(
engine
,
pool_
,
IOAddress
(
"::"
),
false
,
true
);
ASSERT_EQ
(
1
,
leases
.
size
());
// This is what the client will send in his renew message.
AllocEngine
::
HintContainer
hints
;
hints
.
push_back
(
make_pair
(
leases
[
0
]
->
addr_
,
128
));
// Create reservation for this address, but for another client.
// This is in-pool reservation, as the pool is 2001:db8:1::10 - 2001:db8:1::20.
HostPtr
host
=
createHost6
(
false
,
IPv6Resrv
::
TYPE_NA
,
leases
[
0
]
->
addr_
,
128
);
// We need to tweak reservation id: use a different DUID for client Y
vector
<
uint8_t
>
other_duid
(
8
,
0x45
);
host
->
setIdentifier
(
&
other_duid
[
0
],
other_duid
.
size
(),
Host
::
IDENT_DUID
);
// Ok, now add it to the HostMgr
CfgMgr
::
instance
().
getStagingCfg
()
->
getCfgHosts
()
->
add
(
host
);
CfgMgr
::
instance
().
commit
();
Lease6Collection
renewed
=
renewTest
(
engine
,
pool_
,
hints
);
ASSERT_EQ
(
1
,
renewed
.
size
());
// Check that we no longer have the reserved address.
ASSERT_NE
(
leases
[
0
]
->
addr_
.
toText
(),
renewed
[
0
]
->
addr_
.
toText
());
// Check that the lease for the now reserved address is no longer in
// the lease database.
Lease6Ptr
from_mgr
=
LeaseMgrFactory
::
instance
().
getLease6
(
Lease
::
TYPE_NA
,
leases
[
0
]
->
addr_
);
EXPECT_FALSE
(
from_mgr
);
}
TEST_F
(
AllocEngine6Test
,
prefixRenewal
)
{
}
/// @todo: The following methods are tested indirectly by allocateLeases6()
/// tests, but could use more direct testing:
/// - AllocEngine::allocateUnreservedLeases6
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment