]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/test-dnsdistpacketcache_cc.cc
Merge pull request #3466 from janeczku/skipcache-lua-binding
[thirdparty/pdns.git] / pdns / test-dnsdistpacketcache_cc.cc
CommitLineData
886e2cf2
RG
1#define BOOST_TEST_DYN_LINK
2#define BOOST_TEST_NO_MAIN
3
4#include <boost/test/unit_test.hpp>
5
6#include "iputils.hh"
7#include "dnsdist-cache.hh"
8#include "dnswriter.hh"
9
10BOOST_AUTO_TEST_SUITE(dnsdistpacketcache_cc)
11
12BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) {
13 const size_t maxEntries = 150000;
14 DNSDistPacketCache PC(maxEntries, 86400, 1);
15 BOOST_CHECK_EQUAL(PC.getSize(), 0);
16
17 size_t counter=0;
18 size_t skipped=0;
19 try {
20 for(counter = 0; counter < 100000; ++counter) {
21 DNSName a=DNSName("hello ")+DNSName(std::to_string(counter));
22 BOOST_CHECK_EQUAL(DNSName(a.toString()), a);
23
24 vector<uint8_t> query;
25 DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0);
26 pwQ.getHeader()->rd = 1;
27
28 vector<uint8_t> response;
29 DNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0);
30 pwR.getHeader()->rd = 1;
31 pwR.getHeader()->ra = 1;
32 pwR.getHeader()->qr = 1;
33 pwR.getHeader()->id = pwQ.getHeader()->id;
34 pwR.startRecord(a, QType::A, 100, QClass::IN, DNSResourceRecord::ANSWER);
35 pwR.xfr32BitInt(0x01020304);
36 pwR.commit();
37 uint16_t responseLen = response.size();
38
39 char responseBuf[4096];
40 uint16_t responseBufSize = sizeof(responseBuf);
41 uint32_t key = 0;
a176d205 42 bool found = PC.get((const unsigned char*) query.data(), query.size(), a, QType::A, QClass::IN, a.wirelength(), 0, responseBuf, &responseBufSize, false, &key);
886e2cf2
RG
43 BOOST_CHECK_EQUAL(found, false);
44
a176d205 45 PC.insert(key, a, QType::A, QClass::IN, (const char*) response.data(), responseLen, false);
886e2cf2 46
a176d205 47 found = PC.get((const unsigned char*) query.data(), query.size(), a, QType::A, QClass::IN, a.wirelength(), pwR.getHeader()->id, responseBuf, &responseBufSize, false, &key, true);
886e2cf2
RG
48 if (found == true) {
49 BOOST_CHECK_EQUAL(responseBufSize, responseLen);
50 int match = memcmp(responseBuf, response.data(), responseLen);
51 BOOST_CHECK_EQUAL(match, 0);
52 }
53 else {
54 skipped++;
55 }
56 }
57
58 BOOST_CHECK_EQUAL(skipped, PC.getInsertCollisions());
59 BOOST_CHECK_EQUAL(PC.getSize(), counter - skipped);
60
61 size_t deleted=0;
62 size_t delcounter=0;
63 for(delcounter=0; delcounter < counter/1000; ++delcounter) {
64 DNSName a=DNSName("hello ")+DNSName(std::to_string(delcounter));
65 vector<uint8_t> query;
66 DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0);
67 pwQ.getHeader()->rd = 1;
68 char responseBuf[4096];
69 uint16_t responseBufSize = sizeof(responseBuf);
70 uint32_t key = 0;
a176d205 71 bool found = PC.get((const unsigned char*) query.data(), query.size(), a, QType::A, QClass::IN, a.wirelength(), 0, responseBuf, &responseBufSize, false, &key);
886e2cf2
RG
72 if (found == true) {
73 PC.expunge(a);
74 deleted++;
75 }
76 }
77 BOOST_CHECK_EQUAL(PC.getSize(), counter - skipped - deleted);
78
79 size_t matches=0;
80 vector<DNSResourceRecord> entry;
81 size_t expected=counter-skipped-deleted;
82 for(; delcounter < counter; ++delcounter) {
83 DNSName a(DNSName("hello ")+DNSName(std::to_string(delcounter)));
84 vector<uint8_t> query;
85 DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0);
86 pwQ.getHeader()->rd = 1;
87 uint16_t len = query.size();
88 uint32_t key = 0;
89 char response[4096];
90 uint16_t responseSize = sizeof(response);
a176d205 91 if(PC.get(query.data(), len, a, QType::A, QClass::IN, a.wirelength(), pwQ.getHeader()->id, response, &responseSize, false, &key)) {
886e2cf2
RG
92 matches++;
93 }
94 }
95 BOOST_CHECK_EQUAL(matches, expected);
96 }
97 catch(PDNSException& e) {
98 cerr<<"Had error: "<<e.reason<<endl;
99 throw;
100 }
101}
102
103static DNSDistPacketCache PC(500000);
104
105static void *threadMangler(void* a)
106{
107 try {
108 unsigned int offset=(unsigned int)(unsigned long)a;
109 for(unsigned int counter=0; counter < 100000; ++counter) {
110 DNSName a=DNSName("hello ")+DNSName(std::to_string(counter+offset));
111 vector<uint8_t> query;
112 DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0);
113 pwQ.getHeader()->rd = 1;
114
115 vector<uint8_t> response;
116 DNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0);
117 pwR.getHeader()->rd = 1;
118 pwR.getHeader()->ra = 1;
119 pwR.getHeader()->qr = 1;
120 pwR.getHeader()->id = pwQ.getHeader()->id;
121 pwR.startRecord(a, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER);
122 pwR.xfr32BitInt(0x01020304);
123 pwR.commit();
124 uint16_t responseLen = response.size();
125
126 char responseBuf[4096];
127 uint16_t responseBufSize = sizeof(responseBuf);
128 uint32_t key = 0;
a176d205 129 PC.get((const unsigned char*) query.data(), query.size(), a, QType::A, QClass::IN, a.wirelength(), 0, responseBuf, &responseBufSize, false, &key);
886e2cf2 130
a176d205 131 PC.insert(key, a, QType::A, QClass::IN, (const char*) response.data(), responseLen, false);
886e2cf2
RG
132 }
133 }
134 catch(PDNSException& e) {
135 cerr<<"Had error: "<<e.reason<<endl;
136 throw;
137 }
138 return 0;
139}
140
141AtomicCounter g_missing;
142
143static void *threadReader(void* a)
144{
145 try
146 {
147 unsigned int offset=(unsigned int)(unsigned long)a;
148 vector<DNSResourceRecord> entry;
149 for(unsigned int counter=0; counter < 100000; ++counter) {
150 DNSName a=DNSName("hello ")+DNSName(std::to_string(counter+offset));
151 vector<uint8_t> query;
152 DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0);
153 pwQ.getHeader()->rd = 1;
154
155 char responseBuf[4096];
156 uint16_t responseBufSize = sizeof(responseBuf);
157 uint32_t key = 0;
a176d205 158 bool found = PC.get((const unsigned char*) query.data(), query.size(), a, QType::A, QClass::IN, a.wirelength(), 0, responseBuf, &responseBufSize, false, &key);
886e2cf2
RG
159 if (!found) {
160 g_missing++;
161 }
162 }
163 }
164 catch(PDNSException& e) {
165 cerr<<"Had error in threadReader: "<<e.reason<<endl;
166 throw;
167 }
168 return 0;
169}
170
171BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded) {
172 try {
173 pthread_t tid[4];
174 for(int i=0; i < 4; ++i)
175 pthread_create(&tid[i], 0, threadMangler, (void*)(i*1000000UL));
176 void* res;
177 for(int i=0; i < 4 ; ++i)
178 pthread_join(tid[i], &res);
179
180 BOOST_CHECK_EQUAL(PC.getSize() + PC.getDeferredInserts() + PC.getInsertCollisions(), 400000);
181 BOOST_CHECK_SMALL(1.0*PC.getInsertCollisions(), 10000.0);
182
183 for(int i=0; i < 4; ++i)
184 pthread_create(&tid[i], 0, threadReader, (void*)(i*1000000UL));
185 for(int i=0; i < 4 ; ++i)
186 pthread_join(tid[i], &res);
187
188 BOOST_CHECK((PC.getDeferredInserts() + PC.getDeferredLookups() + PC.getInsertCollisions()) >= g_missing);
189 }
190 catch(PDNSException& e) {
191 cerr<<"Had error: "<<e.reason<<endl;
192 throw;
193 }
194
195}
196
197BOOST_AUTO_TEST_SUITE_END()