]>
Commit | Line | Data |
---|---|---|
fbe23e18 | 1 | #define BOOST_TEST_DYN_LINK |
2 | #define BOOST_TEST_NO_MAIN | |
3 | ||
870a0fe4 AT |
4 | #ifdef HAVE_CONFIG_H |
5 | #include "config.h" | |
6 | #endif | |
fbe23e18 | 7 | #include <boost/test/unit_test.hpp> |
8 | #include <boost/test/floating_point_comparison.hpp> | |
9 | #include "iputils.hh" | |
10 | #include "nameserver.hh" | |
11 | #include "statbag.hh" | |
12 | #include "packetcache.hh" | |
13 | #include "arguments.hh" | |
14 | #include <utility> | |
15 | extern StatBag S; | |
16 | ||
fbe23e18 | 17 | BOOST_AUTO_TEST_SUITE(packetcache_cc) |
18 | ||
19 | BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { | |
20 | PacketCache PC; | |
21 | ||
22 | ::arg().set("max-cache-entries", "Maximum number of cache entries")="1000000"; | |
23 | ::arg().set("cache-ttl","Seconds to store packets in the PacketCache")="20"; | |
24 | ::arg().set("recursive-cache-ttl","Seconds to store packets for recursive queries in the PacketCache")="10"; | |
25 | ::arg().set("negquery-cache-ttl","Seconds to store negative query results in the QueryCache")="60"; | |
26 | ::arg().set("query-cache-ttl","Seconds to store query results in the QueryCache")="20"; | |
27 | ::arg().set("recursor","If recursion is desired, IP address of a recursing nameserver")="no"; | |
28 | ||
29 | S.declare("deferred-cache-inserts","Amount of cache inserts that were deferred because of maintenance"); | |
30 | S.declare("deferred-cache-lookup","Amount of cache lookups that were deferred because of maintenance"); | |
31 | ||
32 | ||
33 | BOOST_CHECK_EQUAL(PC.size(), 0); | |
eaedd091 | 34 | PC.insert(DNSName("hello"), QType(QType::A), PacketCache::QUERYCACHE, "something", 3600, 1); |
fbe23e18 | 35 | BOOST_CHECK_EQUAL(PC.size(), 1); |
36 | PC.purge(); | |
37 | BOOST_CHECK_EQUAL(PC.size(), 0); | |
38 | ||
39 | int counter=0; | |
40 | try { | |
41 | for(counter = 0; counter < 100000; ++counter) { | |
335da0ba | 42 | DNSName a=DNSName("hello ")+DNSName(std::to_string(counter)); |
46e4b77c | 43 | BOOST_CHECK_EQUAL(DNSName(a.toString()), a); |
44 | ||
45 | PC.insert(a, QType(QType::A), PacketCache::QUERYCACHE, "something", 3600, 1); | |
46 | if(!PC.purge(a.toString())) | |
47 | BOOST_FAIL("Could not remove entry we just added to packet cache!"); | |
48 | PC.insert(a, QType(QType::A), PacketCache::QUERYCACHE, "something", 3600, 1); | |
fbe23e18 | 49 | } |
50 | ||
51 | BOOST_CHECK_EQUAL(PC.size(), counter); | |
52 | ||
53 | int delcounter=0; | |
54 | for(delcounter=0; delcounter < counter/100; ++delcounter) { | |
335da0ba | 55 | DNSName a=DNSName("hello ")+DNSName(std::to_string(delcounter)); |
46e4b77c | 56 | PC.purge(a.toString()); |
fbe23e18 | 57 | } |
58 | ||
59 | BOOST_CHECK_EQUAL(PC.size(), counter-delcounter); | |
60 | ||
61 | int matches=0; | |
a3b6f8d0 | 62 | vector<DNSResourceRecord> entry; |
fbe23e18 | 63 | int expected=counter-delcounter; |
64 | for(; delcounter < counter; ++delcounter) { | |
335da0ba | 65 | if(PC.getEntry(DNSName("hello ")+DNSName(std::to_string(delcounter)), QType(QType::A), PacketCache::QUERYCACHE, entry, 1)) { |
fbe23e18 | 66 | matches++; |
67 | } | |
68 | } | |
69 | BOOST_CHECK_EQUAL(matches, expected); | |
a3b6f8d0 | 70 | // BOOST_CHECK_EQUAL(entry, "something"); |
fbe23e18 | 71 | } |
72 | catch(PDNSException& e) { | |
73 | cerr<<"Had error: "<<e.reason<<endl; | |
74 | throw; | |
75 | } | |
76 | ||
77 | } | |
78 | ||
79 | static PacketCache* g_PC; | |
80 | ||
81 | static void *threadMangler(void* a) | |
82 | try | |
83 | { | |
84 | unsigned int offset=(unsigned int)(unsigned long)a; | |
85 | for(unsigned int counter=0; counter < 100000; ++counter) | |
335da0ba | 86 | g_PC->insert(DNSName("hello ")+DNSName(std::to_string(counter+offset)), QType(QType::A), PacketCache::QUERYCACHE, "something", 3600, 1); |
fbe23e18 | 87 | return 0; |
88 | } | |
89 | catch(PDNSException& e) { | |
90 | cerr<<"Had error: "<<e.reason<<endl; | |
91 | throw; | |
92 | } | |
93 | ||
94 | AtomicCounter g_missing; | |
95 | ||
96 | static void *threadReader(void* a) | |
97 | try | |
98 | { | |
99 | unsigned int offset=(unsigned int)(unsigned long)a; | |
a3b6f8d0 | 100 | vector<DNSResourceRecord> entry; |
fbe23e18 | 101 | for(unsigned int counter=0; counter < 100000; ++counter) |
335da0ba | 102 | if(!g_PC->getEntry(DNSName("hello ")+DNSName(std::to_string(counter+offset)), QType(QType::A), PacketCache::QUERYCACHE, entry, 1)) { |
fbe23e18 | 103 | g_missing++; |
104 | } | |
105 | return 0; | |
106 | } | |
107 | catch(PDNSException& e) { | |
108 | cerr<<"Had error in threadReader: "<<e.reason<<endl; | |
109 | throw; | |
110 | } | |
111 | ||
112 | ||
20ac38f9 | 113 | |
fbe23e18 | 114 | BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded) { |
115 | try { | |
116 | PacketCache PC; | |
117 | g_PC=&PC; | |
118 | pthread_t tid[4]; | |
119 | for(int i=0; i < 4; ++i) | |
120 | pthread_create(&tid[i], 0, threadMangler, (void*)(i*1000000UL)); | |
121 | void* res; | |
122 | for(int i=0; i < 4 ; ++i) | |
123 | pthread_join(tid[i], &res); | |
124 | ||
125 | BOOST_CHECK_EQUAL(PC.size() + S.read("deferred-cache-inserts"), 400000); | |
126 | BOOST_CHECK_SMALL(1.0*S.read("deferred-cache-inserts"), 10000.0); | |
127 | ||
128 | for(int i=0; i < 4; ++i) | |
129 | pthread_create(&tid[i], 0, threadReader, (void*)(i*1000000UL)); | |
130 | for(int i=0; i < 4 ; ++i) | |
131 | pthread_join(tid[i], &res); | |
132 | ||
20ac38f9 | 133 | BOOST_CHECK(S.read("deferred-cache-inserts") + S.read("deferred-cache-lookup") >= g_missing); |
134 | // BOOST_CHECK_EQUAL(S.read("deferred-cache-lookup"), 0); // cache cleaning invalidates this | |
fbe23e18 | 135 | } |
136 | catch(PDNSException& e) { | |
137 | cerr<<"Had error: "<<e.reason<<endl; | |
138 | throw; | |
139 | } | |
140 | ||
141 | } | |
142 | ||
20ac38f9 | 143 | bool g_stopCleaning; |
144 | static void *cacheCleaner(void*) | |
145 | try | |
146 | { | |
147 | while(!g_stopCleaning) { | |
148 | g_PC->cleanup(); | |
149 | } | |
150 | ||
151 | return 0; | |
152 | } | |
153 | catch(PDNSException& e) { | |
154 | cerr<<"Had error in threadReader: "<<e.reason<<endl; | |
155 | throw; | |
156 | } | |
157 | ||
158 | BOOST_AUTO_TEST_CASE(test_PacketCacheClean) { | |
159 | try { | |
160 | PacketCache PC; | |
161 | ||
162 | for(unsigned int counter = 0; counter < 1000000; ++counter) { | |
335da0ba | 163 | PC.insert(DNSName("hello ")+DNSName(std::to_string(counter)), QType(QType::A), PacketCache::QUERYCACHE, "something", 1, 1); |
20ac38f9 | 164 | } |
165 | ||
166 | sleep(1); | |
167 | ||
168 | g_PC=&PC; | |
169 | pthread_t tid[4]; | |
170 | ||
171 | ::arg().set("max-cache-entries")="10000"; | |
172 | ||
173 | pthread_create(&tid[0], 0, threadReader, (void*)(0*1000000UL)); | |
174 | pthread_create(&tid[1], 0, threadReader, (void*)(1*1000000UL)); | |
175 | pthread_create(&tid[2], 0, threadReader, (void*)(2*1000000UL)); | |
176 | // pthread_create(&tid[2], 0, threadMangler, (void*)(0*1000000UL)); | |
177 | pthread_create(&tid[3], 0, cacheCleaner, 0); | |
178 | ||
179 | void *res; | |
180 | for(int i=0; i < 3 ; ++i) | |
181 | pthread_join(tid[i], &res); | |
182 | g_stopCleaning=true; | |
183 | pthread_join(tid[3], &res); | |
184 | } | |
185 | catch(PDNSException& e) { | |
186 | cerr<<"Had error in threadReader: "<<e.reason<<endl; | |
187 | throw; | |
188 | } | |
189 | } | |
c2ff5f42 | 190 | |
191 | BOOST_AUTO_TEST_CASE(test_PacketCachePacket) { | |
192 | try { | |
193 | ::arg().setSwitch("no-shuffle","Set this to prevent random shuffling of answers - for regression testing")="off"; | |
194 | ||
195 | PacketCache PC; | |
196 | vector<uint8_t> pak; | |
197 | vector<pair<uint16_t,string > > opts; | |
198 | ||
eaedd091 | 199 | DNSPacketWriter pw(pak, DNSName("www.powerdns.com"), QType::A); |
c2ff5f42 | 200 | DNSPacket q, r, r2; |
201 | q.parse((char*)&pak[0], pak.size()); | |
202 | ||
203 | pak.clear(); | |
eaedd091 | 204 | DNSPacketWriter pw2(pak, DNSName("www.powerdns.com"), QType::A); |
e693ff5a | 205 | pw2.startRecord(DNSName("www.powerdns.com"), QType::A, 16, 1, DNSResourceRecord::ANSWER); |
c2ff5f42 | 206 | pw2.xfrIP(htonl(0x7f000001)); |
207 | pw2.commit(); | |
208 | ||
660ec637 | 209 | r.parse((char*)&pak[0], pak.size()); |
c2ff5f42 | 210 | |
211 | PC.insert(&q, &r, false, 3600); | |
212 | ||
213 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 1); | |
660ec637 | 214 | BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain); |
c2ff5f42 | 215 | |
216 | PC.purge("www.powerdns.com"); | |
217 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 0); | |
218 | ||
219 | PC.insert(&q, &r, false, 3600); | |
220 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 1); | |
660ec637 | 221 | BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain); |
c2ff5f42 | 222 | PC.purge("com$"); |
223 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 0); | |
224 | ||
225 | PC.insert(&q, &r, false, 3600); | |
226 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 1); | |
660ec637 | 227 | BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain); |
c2ff5f42 | 228 | PC.purge("powerdns.com$"); |
229 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 0); | |
230 | ||
231 | PC.insert(&q, &r, false, 3600); | |
232 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 1); | |
660ec637 | 233 | BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain); |
c2ff5f42 | 234 | PC.purge("www.powerdns.com$"); |
235 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 0); | |
236 | ||
237 | PC.insert(&q, &r, false, 3600); | |
238 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, true), 0); | |
239 | PC.purge("www.powerdns.com$"); | |
240 | ||
241 | PC.insert(&q, &r, true, 3600); | |
242 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, false), 0); | |
243 | PC.purge("www.powerdns.com$"); | |
244 | ||
245 | PC.insert(&q, &r, true, 3600); | |
246 | PC.purge("www.powerdns.net"); | |
247 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, true), 1); | |
660ec637 | 248 | BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain); |
c2ff5f42 | 249 | PC.purge("net$"); |
250 | BOOST_CHECK_EQUAL(PC.get(&q, &r2, true), 1); | |
660ec637 | 251 | BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain); |
c2ff5f42 | 252 | PC.purge("www.powerdns.com$"); |
253 | BOOST_CHECK_EQUAL(PC.size(), 0); | |
254 | } | |
255 | catch(PDNSException& e) { | |
256 | cerr<<"Had error in threadReader: "<<e.reason<<endl; | |
257 | throw; | |
258 | } | |
259 | } | |
fbe23e18 | 260 | |
261 | BOOST_AUTO_TEST_SUITE_END() |