Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
2de90c47
Commit
2de90c47
authored
Apr 07, 2018
by
Francis Dupont
Browse files
[5374] Checkpoint: HA tests
parent
d095150b
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/tests/classify_unittest.cc
View file @
2de90c47
...
...
@@ -64,6 +64,17 @@ namespace {
/// option[93].hex == 0x0007, set server-hostname to deneb
/// option[93].hex == 0x0006, set boot-file-name to pxelinux.0
/// option[93].hex == 0x0001, set boot-file-name to ipxe.efi
///
/// - Configuration 4:
/// - Used for complex membership (example taken from HA)
/// - 1 subnet: 10.0.0.0/24
/// - 4 pools: 10.0.0.10-10.0.0.49, 10.0.0.60-10.0.0.99,
/// 10.0.0.110-10.0.0.149, 10.0.0.1.60-10.0.0.199
/// - 4 classes to compose:
/// server1 and server2 for each HA server
/// option[93].hex == 0x0009 aka telephones
/// option[93].hex == 0x0007 aka computers
///
const
char
*
CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces-config
\"
: {"
...
...
@@ -211,7 +222,58 @@ const char* CONFIGS[] = {
"
\"
pools
\"
: [ {
\"
pool
\"
:
\"
10.0.0.10-10.0.0.100
\"
} ],"
"
\"
require-client-classes
\"
: [
\"
pxe2
\"
]"
" } ]"
"}"
"}"
,
// Configuration 4
"{
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
"},"
"
\"
valid-lifetime
\"
: 600,"
"
\"
client-classes
\"
: ["
"{"
"
\"
name
\"
:
\"
server1
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2
\"
"
"},"
"{"
"
\"
name
\"
:
\"
telephones
\"
,"
"
\"
test
\"
:
\"
option[93].hex == 0x0009
\"
"
"},"
"{"
"
\"
name
\"
:
\"
computers
\"
,"
"
\"
test
\"
:
\"
option[93].hex == 0x0007
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server1_and_telephones
\"
,"
"
\"
test
\"
:
\"
member('server1') and member('telephones')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server1_and_computers
\"
,"
"
\"
test
\"
:
\"
member('server1') and member('computers')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2_and_telephones
\"
,"
"
\"
test
\"
:
\"
member('server2') and member('telephones')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2_and_computers
\"
,"
"
\"
test
\"
:
\"
member('server2') and member('computers')
\"
"
"} ],"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
10.0.0.0/24
\"
, "
"
\"
id
\"
: 1,"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
10.0.0.10-10.0.0.49
\"
,"
"
\"
client-class
\"
:
\"
server1_and_telephones
\"
},"
" {
\"
pool
\"
:
\"
10.0.0.60-10.0.0.99
\"
,"
"
\"
client-class
\"
:
\"
server1_and_computers
\"
},"
" {
\"
pool
\"
:
\"
10.0.0.110-10.0.0.149
\"
,"
"
\"
client-class
\"
:
\"
server2_and_telephones
\"
},"
" {
\"
pool
\"
:
\"
10.0.0.160-10.0.0.199
\"
,"
"
\"
client-class
\"
:
\"
server2_and_computers
\"
} ]"
" } ]"
"}"
,
};
...
...
@@ -633,6 +695,106 @@ TEST_F(ClassifyTest, fixedFieldsInformFile32) {
testFixedFields
(
CONFIGS
[
3
],
DHCPINFORM
,
pxe
,
"0.0.0.0"
,
""
,
"ipxe.efi"
);
}
// This test checks the complex membership from HA with server1 telephone.
TEST_F
(
ClassifyTest
,
server1Telephone
)
{
Dhcp4Client
client
(
Dhcp4Client
::
SELECTING
);
// Configure DHCP server.
configure
(
CONFIGS
[
4
],
*
client
.
getServer
());
// Add option.
OptionPtr
pxe
(
new
OptionInt
<
uint16_t
>
(
Option
::
V4
,
93
,
0x0009
));
client
.
addExtraOption
(
pxe
);
// Add server1
client
.
addClass
(
"server1"
);
// Get an address
client
.
doDORA
();
// Check response.
Pkt4Ptr
resp
=
client
.
getContext
().
response_
;
ASSERT_TRUE
(
resp
);
// The address is from the first pool.
EXPECT_EQ
(
"10.0.0.10"
,
resp
->
getYiaddr
().
toText
());
}
// This test checks the complex membership from HA with server1 computer.
TEST_F
(
ClassifyTest
,
server1computer
)
{
Dhcp4Client
client
(
Dhcp4Client
::
SELECTING
);
// Configure DHCP server.
configure
(
CONFIGS
[
4
],
*
client
.
getServer
());
// Add option.
OptionPtr
pxe
(
new
OptionInt
<
uint16_t
>
(
Option
::
V4
,
93
,
0x0007
));
client
.
addExtraOption
(
pxe
);
// Add server1
client
.
addClass
(
"server1"
);
// Get an address
client
.
doDORA
();
// Check response.
Pkt4Ptr
resp
=
client
.
getContext
().
response_
;
ASSERT_TRUE
(
resp
);
// The address is from the second pool.
EXPECT_EQ
(
"10.0.0.60"
,
resp
->
getYiaddr
().
toText
());
}
// This test checks the complex membership from HA with server2 telephone.
TEST_F
(
ClassifyTest
,
server2Telephone
)
{
Dhcp4Client
client
(
Dhcp4Client
::
SELECTING
);
// Configure DHCP server.
configure
(
CONFIGS
[
4
],
*
client
.
getServer
());
// Add option.
OptionPtr
pxe
(
new
OptionInt
<
uint16_t
>
(
Option
::
V4
,
93
,
0x0009
));
client
.
addExtraOption
(
pxe
);
// Add server2
client
.
addClass
(
"server2"
);
// Get an address
client
.
doDORA
();
// Check response.
Pkt4Ptr
resp
=
client
.
getContext
().
response_
;
ASSERT_TRUE
(
resp
);
// The address is from the third pool.
EXPECT_EQ
(
"10.0.0.110"
,
resp
->
getYiaddr
().
toText
());
}
// This test checks the complex membership from HA with server2 computer.
TEST_F
(
ClassifyTest
,
server2computer
)
{
Dhcp4Client
client
(
Dhcp4Client
::
SELECTING
);
// Configure DHCP server.
configure
(
CONFIGS
[
4
],
*
client
.
getServer
());
// Add option.
OptionPtr
pxe
(
new
OptionInt
<
uint16_t
>
(
Option
::
V4
,
93
,
0x0007
));
client
.
addExtraOption
(
pxe
);
// Add server2
client
.
addClass
(
"server2"
);
// Get an address
client
.
doDORA
();
// Check response.
Pkt4Ptr
resp
=
client
.
getContext
().
response_
;
ASSERT_TRUE
(
resp
);
// The address is from the forth pool.
EXPECT_EQ
(
"10.0.0.160"
,
resp
->
getYiaddr
().
toText
());
}
// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F
(
ClassifyTest
,
precedenceNone
)
{
...
...
src/bin/dhcp4/tests/dhcp4_client.cc
View file @
2de90c47
// Copyright (C) 2014-201
7
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
8
Internet Systems Consortium, Inc. ("ISC")
//
// 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
...
...
@@ -238,6 +238,14 @@ Dhcp4Client::appendExtraOptions() {
}
}
void
Dhcp4Client
::
appendClasses
()
{
for
(
ClientClasses
::
const_iterator
cclass
=
classes_
.
cbegin
();
cclass
!=
classes_
.
cend
();
++
cclass
)
{
context_
.
query_
->
addClass
(
*
cclass
);
}
}
void
Dhcp4Client
::
doDiscover
(
const
boost
::
shared_ptr
<
IOAddress
>&
requested_addr
)
{
context_
.
query_
=
createMsg
(
DHCPDISCOVER
);
...
...
@@ -255,6 +263,7 @@ Dhcp4Client::doDiscover(const boost::shared_ptr<IOAddress>& requested_addr) {
context_
.
query_
->
setCiaddr
(
ciaddr_
.
get
());
}
appendExtraOptions
();
appendClasses
();
// Send the message to the server.
sendMsg
(
context_
.
query_
);
...
...
@@ -277,6 +286,8 @@ Dhcp4Client::doInform(const bool set_ciaddr) {
appendPRL
();
// Any other options to be sent by a client.
appendExtraOptions
();
// Add classes.
appendClasses
();
// The client sending a DHCPINFORM message has an IP address obtained
// by some other means, e.g. static configuration. The lease which we
// are using here is most likely set by the createLease method.
...
...
@@ -396,6 +407,8 @@ Dhcp4Client::doRequest() {
appendClientId
();
// Any other options to be sent by a client.
appendExtraOptions
();
// Add classes.
appendClasses
();
// Send the message to the server.
sendMsg
(
context_
.
query_
);
// Expect response.
...
...
@@ -518,6 +531,12 @@ Dhcp4Client::sendMsg(const Pkt4Ptr& msg) {
msg_copy
->
setRemoteAddr
(
msg
->
getLocalAddr
());
msg_copy
->
setLocalAddr
(
dest_addr_
);
msg_copy
->
setIface
(
iface_name_
);
// Copy classes
const
ClientClasses
&
classes
=
msg
->
getClasses
();
for
(
ClientClasses
::
const_iterator
cclass
=
classes
.
cbegin
();
cclass
!=
classes
.
cend
();
++
cclass
)
{
msg_copy
->
addClass
(
*
cclass
);
}
srv_
->
fakeReceive
(
msg_copy
);
srv_
->
run
();
}
...
...
@@ -536,6 +555,13 @@ Dhcp4Client::addExtraOption(const OptionPtr& opt) {
extra_options_
.
insert
(
std
::
make_pair
(
opt
->
getType
(),
opt
));
}
void
Dhcp4Client
::
addClass
(
const
ClientClass
&
client_class
)
{
if
(
!
classes_
.
contains
(
client_class
))
{
classes_
.
insert
(
client_class
);
}
}
}
// end of namespace isc::dhcp::test
}
// end of namespace isc::dhcp
}
// end of namespace isc
src/bin/dhcp4/tests/dhcp4_client.h
View file @
2de90c47
// Copyright (C) 2014-201
6
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
8
Internet Systems Consortium, Inc. ("ISC")
//
// 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
...
...
@@ -369,12 +369,22 @@ public:
/// @param opt additional option to be sent
void
addExtraOption
(
const
OptionPtr
&
opt
);
/// @brief Add a client class.
///
/// @param client_class name of the class to be added.
void
addClass
(
const
ClientClass
&
client_class
);
private:
/// @brief Appends extra options, previously added with addExtraOption()
///
/// @brief Copies options from extra_options_ into outgoing message
void
appendExtraOptions
();
/// @brief Appends extra classes, previously added with addClass()
///
/// @brief Add client classes from classes_ to incoming message
void
appendClasses
();
/// @brief Creates and adds Requested IP Address option to the client's
/// query.
///
...
...
@@ -491,6 +501,9 @@ private:
/// @brief Extra options the client will send.
OptionCollection
extra_options_
;
/// @brief Extra classes to add to the query.
ClientClasses
classes_
;
};
}
// end of namespace isc::dhcp::test
...
...
src/bin/dhcp6/tests/classify_unittests.cc
View file @
2de90c47
...
...
@@ -46,6 +46,27 @@ namespace {
/// the 'foo' value.
/// - There is one subnet specified 2001:db8:1::/48 with pool of
/// IPv6 addresses.
///
/// - Configuration 1:
/// - Used for complex membership (example taken from HA)
/// - 1 subnet: 2001:db8:1::/48
/// - 4 pools: 2001:db8:1:1::/64, 2001:db8:1:2::/64,
/// 2001:db8:1:3::/64 and 2001:db8:1:4::/64
/// - 4 classes to compose:
/// server1 and server2 for each HA server
/// option 1234 'foo' aka telephones
/// option 1234 'bar' aka computers
///
/// - Configuration 2:
/// - Used for complex membership (example taken from HA) and pd-pools
/// - 1 subnet: 2001:db8::/32
/// - 4 pd-pools: 2001:db8:1::/48, 2001:db8:2::/48,
/// 2001:db8:3::/48 and 2001:db8:4::/48
/// - 4 classes to compose:
/// server1 and server2 for each HA server
/// option 1234 'foo' aka telephones
/// option 1234 'bar' aka computers
///
const
char
*
CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces-config
\"
: {"
...
...
@@ -104,7 +125,128 @@ const char* CONFIGS[] = {
"
\"
client-classes
\"
: [
\"
reserved-class1
\"
,
\"
reserved-class2
\"
]"
" } ]"
" } ],"
"
\"
valid-lifetime
\"
: 4000 }"
,
// Configuration 1
"{
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
"},"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
option-def
\"
: [ "
"{"
"
\"
name
\"
:
\"
host-name
\"
,"
"
\"
code
\"
: 1234,"
"
\"
type
\"
:
\"
string
\"
"
"} ],"
"
\"
client-classes
\"
: ["
"{"
"
\"
name
\"
:
\"
server1
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2
\"
"
"},"
"{"
"
\"
name
\"
:
\"
telephones
\"
,"
"
\"
test
\"
:
\"
option[host-name].text == 'foo'
\"
"
"},"
"{"
"
\"
name
\"
:
\"
computers
\"
,"
"
\"
test
\"
:
\"
option[host-name].text == 'bar'
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server1_and_telephones
\"
,"
"
\"
test
\"
:
\"
member('server1') and member('telephones')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server1_and_computers
\"
,"
"
\"
test
\"
:
\"
member('server1') and member('computers')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2_and_telephones
\"
,"
"
\"
test
\"
:
\"
member('server2') and member('telephones')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2_and_computers
\"
,"
"
\"
test
\"
:
\"
member('server2') and member('computers')
\"
"
"}"
"],"
"
\"
subnet6
\"
: [ "
"{
\"
subnet
\"
:
\"
2001:db8:1::/48
\"
, "
"
\"
interface
\"
:
\"
eth1
\"
,"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
2001:db8:1:1::/64
\"
,"
"
\"
client-class
\"
:
\"
server1_and_telephones
\"
},"
" {
\"
pool
\"
:
\"
2001:db8:1:2::/64
\"
,"
"
\"
client-class
\"
:
\"
server1_and_computers
\"
},"
" {
\"
pool
\"
:
\"
2001:db8:1:3::/64
\"
,"
"
\"
client-class
\"
:
\"
server2_and_telephones
\"
},"
" {
\"
pool
\"
:
\"
2001:db8:1:4::/64
\"
,"
"
\"
client-class
\"
:
\"
server2_and_computers
\"
} ]"
" } ],"
"
\"
valid-lifetime
\"
: 4000 }"
,
// Configuration 2
"{
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
"},"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
option-def
\"
: [ "
"{"
"
\"
name
\"
:
\"
host-name
\"
,"
"
\"
code
\"
: 1234,"
"
\"
type
\"
:
\"
string
\"
"
"} ],"
"
\"
client-classes
\"
: ["
"{"
"
\"
name
\"
:
\"
server1
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2
\"
"
"},"
"{"
"
\"
name
\"
:
\"
telephones
\"
,"
"
\"
test
\"
:
\"
option[host-name].text == 'foo'
\"
"
"},"
"{"
"
\"
name
\"
:
\"
computers
\"
,"
"
\"
test
\"
:
\"
option[host-name].text == 'bar'
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server1_and_telephones
\"
,"
"
\"
test
\"
:
\"
member('server1') and member('telephones')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server1_and_computers
\"
,"
"
\"
test
\"
:
\"
member('server1') and member('computers')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2_and_telephones
\"
,"
"
\"
test
\"
:
\"
member('server2') and member('telephones')
\"
"
"},"
"{"
"
\"
name
\"
:
\"
server2_and_computers
\"
,"
"
\"
test
\"
:
\"
member('server2') and member('computers')
\"
"
"}"
"],"
"
\"
subnet6
\"
: [ "
"{
\"
subnet
\"
:
\"
2001:db8::/32
\"
, "
"
\"
interface
\"
:
\"
eth1
\"
,"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
2001:db8:1::/48
\"
,"
"
\"
client-class
\"
:
\"
server1_and_telephones
\"
},"
" {
\"
pool
\"
:
\"
2001:db8:2::/48
\"
,"
"
\"
client-class
\"
:
\"
server1_and_computers
\"
},"
" {
\"
pool
\"
:
\"
2001:db8:3::/48
\"
,"
"
\"
client-class
\"
:
\"
server2_and_telephones
\"
},"
" {
\"
pool
\"
:
\"
2001:db8:4::/48
\"
,"
"
\"
client-class
\"
:
\"
server2_and_computers
\"
} ]"
" } ],"
"
\"
valid-lifetime
\"
: 4000 }"
};
/// @brief Test fixture class for testing client classification by the
...
...
@@ -1551,4 +1693,32 @@ TEST_F(ClassifyTest, precedenceNetwork) {
EXPECT_EQ
(
"2001:db8:1::3"
,
addrs
[
0
].
toText
());
}
// This test checks the complex membership from HA with server1 telephone.
TEST_F
(
ClassifyTest
,
server1Telephone
)
{
// Create a client.
Dhcp6Client
client
;
client
.
setInterface
(
"eth1"
);
ASSERT_NO_THROW
(
client
.
requestAddress
(
0xabca0
));
// Add option.
OptionStringPtr
hostname
(
new
OptionString
(
Option
::
V6
,
1234
,
"foo"
));
client
.
addExtraOption
(
hostname
);
// Add server1
client
.
addClass
(
"server1"
);
// Load the config and perform a SARR
configure
(
CONFIGS
[
1
],
*
client
.
getServer
());
ASSERT_NO_THROW
(
client
.
doSARR
());
// Check response
Pkt6Ptr
resp
=
client
.
getContext
().
response_
;
ASSERT_TRUE
(
resp
);
// The address is from the first pool.
ASSERT_EQ
(
1
,
client
.
getLeaseNum
());
Lease6
lease_client
=
client
.
getLease
(
0
);
EXPECT_EQ
(
"2001:db8:1:1::"
,
lease_client
.
addr_
.
toText
());
}
}
// end of anonymous namespace
src/bin/dhcp6/tests/dhcp6_client.cc
View file @
2de90c47
// Copyright (C) 2014-201
7
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
8
Internet Systems Consortium, Inc. ("ISC")
//
// 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
...
...
@@ -423,6 +423,12 @@ Dhcp6Client::createMsg(const uint8_t msg_type) {
}
}
// Add classes.
for
(
ClientClasses
::
const_iterator
cclass
=
classes_
.
cbegin
();
cclass
!=
classes_
.
cend
();
++
cclass
)
{
msg
->
addClass
(
*
cclass
);
}
return
(
msg
);
}
...
...
@@ -930,6 +936,13 @@ Dhcp6Client::sendMsg(const Pkt6Ptr& msg) {
msg_copy
->
setLocalAddr
(
dest_addr_
);
msg_copy
->
setIface
(
iface_name_
);
// Copy classes
const
ClientClasses
&
classes
=
msg
->
getClasses
();
for
(
ClientClasses
::
const_iterator
cclass
=
classes
.
cbegin
();
cclass
!=
classes
.
cend
();
++
cclass
)
{
msg_copy
->
addClass
(
*
cclass
);
}
srv_
->
fakeReceive
(
msg_copy
);
srv_
->
run
();
}
...
...
@@ -969,6 +982,18 @@ Dhcp6Client::clearExtraOptions() {
extra_options_
.
clear
();
}
void
Dhcp6Client
::
addClass
(
const
ClientClass
&
client_class
)
{
if
(
!
classes_
.
contains
(
client_class
))
{
classes_
.
insert
(
client_class
);
}
}
void
Dhcp6Client
::
clearClasses
()
{
classes_
.
clear
();
}
void
Dhcp6Client
::
printConfiguration
()
const
{
...
...
src/bin/dhcp6/tests/dhcp6_client.h
View file @
2de90c47
// Copyright (C) 2014-201
7
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
8
Internet Systems Consortium, Inc. ("ISC")
//
// 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
...
...
@@ -753,6 +753,14 @@ public:
/// @brief Configures the client to not send any extra options.
void
clearExtraOptions
();
/// @brief Add a client class.
///
/// @param client_class name of the class to be added.
void
addClass
(
const
ClientClass
&
client_class
);
/// @brief Configures the client to not add client classes.
void
clearClasses
();
/// @brief Debugging method the prints currently held configuration
///
/// @todo: This is mostly useful when debugging tests. This method
...
...
@@ -927,6 +935,9 @@ private:
/// @brief Interface id.
OptionPtr
interface_id_
;
/// @brief Extra classes to add to the query.
ClientClasses
classes_
;
};
}
// end of namespace isc::dhcp::test
...
...
Write
Preview
Markdown
is supported
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