]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/recursordist/test-rec-tcounters_cc.cc
Introducing TCounters
[thirdparty/pdns.git] / pdns / recursordist / test-rec-tcounters_cc.cc
1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
3
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7
8 #include <boost/test/unit_test.hpp>
9
10 #include <unistd.h>
11 #include <thread>
12 #include "rec-tcounters.hh"
13
14 static rec::GlobalCounters global;
15 static thread_local rec::TCounters tlocal(global);
16
17 BOOST_AUTO_TEST_SUITE(test_rec_tcounters_cc)
18
19 BOOST_AUTO_TEST_CASE(destruct)
20 {
21 global.reset();
22
23 const size_t count = 100000;
24 std::thread thread1([] {
25 for (size_t i = 0; i < count; i++) {
26 ++tlocal.at(rec::Counter::servFails);
27 }
28 });
29 std::thread thread2([] {
30 for (size_t i = 0; i < count; i++) {
31 ++tlocal.at(rec::Counter::nxDomains);
32 }
33 });
34 thread1.join();
35 thread2.join();
36 BOOST_CHECK_EQUAL(global.sum(rec::Counter::servFails), count);
37 BOOST_CHECK_EQUAL(global.sum(rec::Counter::nxDomains), count);
38 }
39
40 BOOST_AUTO_TEST_CASE(update_fast)
41 {
42 global.reset();
43
44 std::atomic<uint64_t> done{};
45
46 const size_t count = 10000000;
47 std::thread thread1([&done] {
48 for (size_t i = 0; i < count; i++) {
49 ++tlocal.at(rec::Counter::servFails);
50 ++tlocal.at(rec::Counter::nxDomains);
51 tlocal.at(rec::DoubleWAvgCounter::avgLatencyUsec).add(1.1);
52 if (random() % 10000 == 0) {
53 tlocal.updateSnap();
54 }
55 }
56 done++;
57 });
58 std::thread thread2([&done] {
59 for (size_t i = 0; i < count / 2; i++) {
60 ++tlocal.at(rec::Counter::servFails);
61 ++tlocal.at(rec::Counter::nxDomains);
62 tlocal.at(rec::DoubleWAvgCounter::avgLatencyUsec).add(2.2);
63 if (random() % 10000 == 0) {
64 tlocal.updateSnap();
65 }
66 }
67 done++;
68 });
69 std::thread thread3([&done] {
70 while (done < 2) {
71 auto counts = global.aggregatedSnap();
72 BOOST_CHECK_EQUAL(counts.uint64Count[0], counts.uint64Count[1]);
73 auto avg = counts.at(rec::DoubleWAvgCounter::avgLatencyUsec).avg;
74 BOOST_CHECK(avg == 0.0 || (avg >= 1.1 && avg <= 2.2));
75 }
76 });
77 thread1.join();
78 thread2.join();
79 thread3.join();
80 BOOST_CHECK_EQUAL(global.sum(rec::Counter::servFails), count + count / 2);
81 BOOST_CHECK_EQUAL(global.sum(rec::Counter::nxDomains), count + count / 2);
82 auto avg = global.avg(rec::DoubleWAvgCounter::avgLatencyUsec);
83 BOOST_CHECK(avg >= 1.1 && avg <= 2.2);
84 }
85
86 BOOST_AUTO_TEST_CASE(update_with_sleep)
87 {
88
89 global.reset();
90
91 std::atomic<int> done{};
92
93 const size_t count = 1000000;
94 std::thread thread1([&done] {
95 for (size_t i = 0; i < count; i++) {
96 ++tlocal.at(rec::Counter::servFails);
97 ++tlocal.at(rec::Counter::nxDomains);
98 tlocal.at(rec::DoubleWAvgCounter::avgLatencyUsec).add(1.1);
99 if (random() % 10000 == 0) {
100 tlocal.updateSnap();
101 }
102 struct timespec interval
103 {
104 0, random() % 5000
105 };
106 nanosleep(&interval, nullptr);
107 }
108 done++;
109 });
110 std::thread thread2([&done] {
111 for (size_t i = 0; i < count / 2; i++) {
112 ++tlocal.at(rec::Counter::servFails);
113 ++tlocal.at(rec::Counter::nxDomains);
114 tlocal.at(rec::DoubleWAvgCounter::avgLatencyUsec).add(2.2);
115 if (random() % 10000 == 0) {
116 tlocal.updateSnap();
117 }
118 struct timespec interval
119 {
120 0, random() % 999
121 };
122 nanosleep(&interval, nullptr);
123 }
124 done++;
125 });
126 std::thread thread3([&done] {
127 while (done < 2) {
128 auto counts = global.aggregatedSnap();
129 BOOST_CHECK_EQUAL(counts.uint64Count[0], counts.uint64Count[1]);
130 auto avg = counts.at(rec::DoubleWAvgCounter::avgLatencyUsec).avg;
131 // std::cerr << avg << std::endl;
132 BOOST_CHECK(avg == 0.0 || (avg >= 1.1 && avg <= 2.2));
133 struct timespec interval
134 {
135 0, random() % 10000
136 };
137 nanosleep(&interval, nullptr);
138 }
139 });
140 thread1.join();
141 thread2.join();
142 thread3.join();
143 BOOST_CHECK_EQUAL(global.sum(rec::Counter::servFails), count + count / 2);
144 BOOST_CHECK_EQUAL(global.sum(rec::Counter::nxDomains), count + count / 2);
145 auto avg = global.avg(rec::DoubleWAvgCounter::avgLatencyUsec);
146 BOOST_CHECK(avg >= 1.1 && avg <= 2.2);
147 }
148
149 BOOST_AUTO_TEST_SUITE_END()