]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Carbon.py
Merge pull request #10530 from ZaphodB/ZaphodB-patch-1
[thirdparty/pdns.git] / regression-tests.dnsdist / test_Carbon.py
1 #!/usr/bin/env python
2 import threading
3 import socket
4 import sys
5 import time
6 from dnsdisttests import DNSDistTest, Queue
7
8 class TestCarbon(DNSDistTest):
9
10 _carbonServer1Port = 8000
11 _carbonServer1Name = "carbonname1"
12 _carbonServer2Port = 8001
13 _carbonServer2Name = "carbonname2"
14 _carbonQueue1 = Queue()
15 _carbonQueue2 = Queue()
16 _carbonInterval = 2
17 _carbonCounters = {}
18 _config_params = ['_carbonServer1Port', '_carbonServer1Name', '_carbonInterval',
19 '_carbonServer2Port', '_carbonServer2Name', '_carbonInterval']
20 _config_template = """
21 s = newServer{address="127.0.0.1:5353"}
22 s:setDown()
23 s = newServer{address="127.0.0.1:5354"}
24 s:setUp()
25 s = newServer{address="127.0.0.1:5355"}
26 s:setUp()
27 carbonServer("127.0.0.1:%s", "%s", %s)
28 carbonServer("127.0.0.1:%s", "%s", %s)
29 """
30
31 @classmethod
32 def CarbonResponder(cls, port):
33 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
34 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
35 try:
36 sock.bind(("127.0.0.1", port))
37 except socket.error as e:
38 print("Error binding in the Carbon responder: %s" % str(e))
39 sys.exit(1)
40
41 sock.listen(100)
42 while True:
43 (conn, _) = sock.accept()
44 conn.settimeout(2.0)
45 lines = b''
46 while True:
47 data = conn.recv(4096)
48 if not data:
49 break
50 lines += data
51
52 if port == cls._carbonServer1Port:
53 cls._carbonQueue1.put(lines, True, timeout=2.0)
54 else:
55 cls._carbonQueue2.put(lines, True, timeout=2.0)
56 if threading.currentThread().name in cls._carbonCounters:
57 cls._carbonCounters[threading.currentThread().name] += 1
58 else:
59 cls._carbonCounters[threading.currentThread().name] = 1
60
61 conn.close()
62 sock.close()
63
64 @classmethod
65 def startResponders(cls):
66 cls._CarbonResponder1 = threading.Thread(name='Carbon Responder 1', target=cls.CarbonResponder, args=[cls._carbonServer1Port])
67 cls._CarbonResponder1.setDaemon(True)
68 cls._CarbonResponder1.start()
69
70 cls._CarbonResponder2 = threading.Thread(name='Carbon Responder 2', target=cls.CarbonResponder, args=[cls._carbonServer2Port])
71 cls._CarbonResponder2.setDaemon(True)
72 cls._CarbonResponder2.start()
73
74 def testCarbon(self):
75 """
76 Carbon: send data to 2 carbon servers
77 """
78 # wait for the carbon data to be sent
79 time.sleep(self._carbonInterval + 1)
80
81 # check if the servers have received our data
82 # we will block for a short while if the data is not already there,
83 # and an exception will be raised after the timeout
84 # first server
85 data1 = self._carbonQueue1.get(block=True, timeout=2.0)
86 # second server
87 data2 = self._carbonQueue2.get(block=True, timeout=2.0)
88 after = time.time()
89
90 self.assertTrue(data1)
91 self.assertTrue(len(data1.splitlines()) > 1)
92 expectedStart = b"dnsdist.%s.main." % self._carbonServer1Name.encode('UTF-8')
93 for line in data1.splitlines():
94 self.assertTrue(line.startswith(expectedStart))
95 parts = line.split(b' ')
96 self.assertEqual(len(parts), 3)
97 self.assertTrue(parts[1].isdigit())
98 self.assertTrue(parts[2].isdigit())
99 self.assertTrue(int(parts[2]) <= int(after))
100
101 self.assertTrue(data2)
102 self.assertTrue(len(data2.splitlines()) > 1)
103 expectedStart = b"dnsdist.%s.main." % self._carbonServer2Name.encode('UTF-8')
104 for line in data2.splitlines():
105 self.assertTrue(line.startswith(expectedStart))
106 parts = line.split(b' ')
107 self.assertEqual(len(parts), 3)
108 self.assertTrue(parts[1].isdigit())
109 self.assertTrue(parts[2].isdigit())
110 self.assertTrue(int(parts[2]) <= int(after))
111
112 # make sure every carbon server has received at least one connection
113 for key in self._carbonCounters:
114 value = self._carbonCounters[key]
115 self.assertTrue(value >= 1)
116
117 def testCarbonServerUp(self):
118 """
119 Carbon: set up 2 carbon servers
120 """
121 # wait for the carbon data to be sent
122 time.sleep(self._carbonInterval + 1)
123
124 # check if the servers have received our data
125 # we will block for a short while if the data is not already there,
126 # and an exception will be raised after the timeout
127 # first server
128 data1 = self._carbonQueue1.get(block=True, timeout=2.0)
129 # second server
130 data2 = self._carbonQueue2.get(block=True, timeout=2.0)
131 after = time.time()
132
133 # check the first carbon server got both servers and
134 # servers-up metrics and that they are the same as
135 # configured in the class definition
136 self.assertTrue(data1)
137 self.assertTrue(len(data1.splitlines()) > 1)
138 expectedStart = b"dnsdist.%s.main.pools._default_.servers" % self._carbonServer1Name.encode('UTF-8')
139 for line in data1.splitlines():
140 if expectedStart in line:
141 parts = line.split(b' ')
142 if b'servers-up' in line:
143 self.assertEqual(len(parts), 3)
144 self.assertTrue(parts[1].isdigit())
145 self.assertEqual(int(parts[1]), 2)
146 self.assertTrue(parts[2].isdigit())
147 self.assertTrue(int(parts[2]) <= int(after))
148 else:
149 self.assertEqual(len(parts), 3)
150 self.assertTrue(parts[1].isdigit())
151 self.assertEqual(int(parts[1]), 3)
152 self.assertTrue(parts[2].isdigit())
153 self.assertTrue(int(parts[2]) <= int(after))
154
155 # check the second carbon server got both servers and
156 # servers-up metrics and that they are the same as
157 # configured in the class definition and the same as
158 # the first carbon server
159 self.assertTrue(data2)
160 self.assertTrue(len(data2.splitlines()) > 1)
161 expectedStart = b"dnsdist.%s.main.pools._default_.servers" % self._carbonServer2Name.encode('UTF-8')
162 for line in data2.splitlines():
163 if expectedStart in line:
164 parts = line.split(b' ')
165 if b'servers-up' in line:
166 self.assertEqual(len(parts), 3)
167 self.assertTrue(parts[1].isdigit())
168 self.assertEqual(int(parts[1]), 2)
169 self.assertTrue(parts[2].isdigit())
170 self.assertTrue(int(parts[2]) <= int(after))
171 else:
172 self.assertEqual(len(parts), 3)
173 self.assertTrue(parts[1].isdigit())
174 self.assertEqual(int(parts[1]), 3)
175 self.assertTrue(parts[2].isdigit())
176 self.assertTrue(int(parts[2]) <= int(after))