1 // Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7 #include <config.h>
8 #include "test_utils.h"
9 #include <asiolink/io_address.h>
10 #include <gtest/gtest.h>
11 #include <sstream>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15
16 using namespace std;
17 using namespace isc::asiolink;
18
19 namespace isc {
20 namespace dhcp {
21 namespace test {
22
23 void
detailCompareLease(const Lease4Ptr & first,const Lease4Ptr & second)24 detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
25 // Compare address strings. Comparison of address objects is not used, as
26 // odd things happen when they are different: the EXPECT_EQ macro appears to
27 // call the operator uint32_t() function, which causes an exception to be
28 // thrown for IPv6 addresses.
29 ASSERT_TRUE(first);
30 ASSERT_TRUE(second);
31 EXPECT_EQ(first->addr_, second->addr_);
32
33 // We need to compare the actual HWAddr objects, not pointers
34 EXPECT_TRUE(*first->hwaddr_ == *second->hwaddr_);
35
36 if (first->client_id_ && second->client_id_) {
37 EXPECT_TRUE(*first->client_id_ == *second->client_id_);
38 } else {
39 if (first->client_id_ && !second->client_id_) {
40
41 ADD_FAILURE() << "Client-id present in first lease ("
42 << first->client_id_->getClientId().size()
43 << " bytes), but missing in second.";
44 }
45 if (!first->client_id_ && second->client_id_) {
46 ADD_FAILURE() << "Client-id missing in first lease, but present in second ("
47 << second->client_id_->getClientId().size()
48 << " bytes).";
49 }
50 // else here would mean that both leases do not have client_id_
51 // which makes them equal in that regard. It is ok.
52 }
53 EXPECT_EQ(first->valid_lft_, second->valid_lft_);
54 EXPECT_EQ(first->cltt_, second->cltt_);
55 EXPECT_EQ(first->subnet_id_, second->subnet_id_);
56 EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_);
57 EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_);
58 EXPECT_EQ(first->hostname_, second->hostname_);
59 if (first->getContext()) {
60 EXPECT_TRUE(second->getContext());
61 if (second->getContext()) {
62 EXPECT_EQ(first->getContext()->str(), second->getContext()->str());
63 }
64 } else {
65 EXPECT_FALSE(second->getContext());
66 }
67 }
68
69 void
detailCompareLease(const Lease6Ptr & first,const Lease6Ptr & second)70 detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
71 ASSERT_TRUE(first);
72 ASSERT_TRUE(second);
73 EXPECT_EQ(first->type_, second->type_);
74
75 // Compare address strings. Comparison of address objects is not used, as
76 // odd things happen when they are different: the EXPECT_EQ macro appears to
77 // call the operator uint32_t() function, which causes an exception to be
78 // thrown for IPv6 addresses.
79 EXPECT_EQ(first->addr_, second->addr_);
80 EXPECT_EQ(first->prefixlen_, second->prefixlen_);
81 EXPECT_EQ(first->iaid_, second->iaid_);
82 ASSERT_TRUE(first->duid_);
83 ASSERT_TRUE(second->duid_);
84 EXPECT_TRUE(*first->duid_ == *second->duid_);
85 EXPECT_EQ(first->preferred_lft_, second->preferred_lft_);
86 EXPECT_EQ(first->valid_lft_, second->valid_lft_);
87 EXPECT_EQ(first->cltt_, second->cltt_);
88 EXPECT_EQ(first->subnet_id_, second->subnet_id_);
89 EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_);
90 EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_);
91 EXPECT_EQ(first->hostname_, second->hostname_);
92 if (first->getContext()) {
93 EXPECT_TRUE(second->getContext());
94 if (second->getContext()) {
95 EXPECT_EQ(first->getContext()->str(), second->getContext()->str());
96 }
97 } else {
98 EXPECT_FALSE(second->getContext());
99 }
100 }
101
findLastSocketFd()102 int findLastSocketFd() {
103 int max_fd_number = getdtablesize();
104 int last_socket = -1;
105 struct stat stats;
106
107 // Iterate over the open fds
108 for (int fd = 0; fd <= max_fd_number; fd++ ) {
109 errno = 0;
110 fstat(fd, &stats);
111
112 if (errno == EBADF ) {
113 // Skip any that aren't open
114 continue;
115 }
116
117 // it's a socket, remember it
118 if (S_ISSOCK(stats.st_mode)) {
119 last_socket = fd;
120 }
121 }
122
123 return (last_socket);
124 }
125
FillFdHoles(int limit)126 FillFdHoles::FillFdHoles(int limit) : fds_() {
127 if (limit <= 0) {
128 return;
129 }
130 for (;;) {
131 int fd = open("/dev/null", O_RDWR, 0);
132 if (fd == -1) {
133 return;
134 }
135 if (fd < limit) {
136 fds_.push_front(fd);
137 } else {
138 static_cast<void>(close(fd));
139 return;
140 }
141 }
142 }
143
~FillFdHoles()144 FillFdHoles::~FillFdHoles() {
145 while (!fds_.empty()) {
146 static_cast<void>(close(fds_.back()));
147 fds_.pop_back();
148 }
149 }
150
151 } // namespace test
152 } // namespace dhcp
153 } // namespace isc
154