Skip to content

Commit 31b7cab

Browse files
committed
Expand integration tests for the prometheus module
1 parent ac242a3 commit 31b7cab

File tree

1 file changed

+116
-13
lines changed

1 file changed

+116
-13
lines changed

tests/test-program-prometheus.cpp

+116-13
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,34 @@ TEST_CASE("program.c-prometheus", "[program-prometheus]") {
130130
REQUIRE(connect(clientfd, (struct sockaddr *) &address, sizeof(address)) == 0);
131131

132132
SECTION("Prometheus - /metrics endpoint") {
133+
// Build up the list of the fields in the response
134+
char *metrics_names[] = {
135+
"cachegrand_network_total_received_packets",
136+
"cachegrand_network_total_received_data",
137+
"cachegrand_network_total_sent_packets",
138+
"cachegrand_network_total_sent_data",
139+
"cachegrand_network_total_accepted_connections",
140+
"cachegrand_network_total_active_connections",
141+
"cachegrand_storage_total_written_data",
142+
"cachegrand_storage_total_write_iops",
143+
"cachegrand_storage_total_read_data",
144+
"cachegrand_storage_total_read_iops",
145+
"cachegrand_storage_total_open_files",
146+
147+
"cachegrand_network_per_minute_received_packets",
148+
"cachegrand_network_per_minute_received_data",
149+
"cachegrand_network_per_minute_sent_packets",
150+
"cachegrand_network_per_minute_sent_data",
151+
"cachegrand_network_per_minute_accepted_connections",
152+
"cachegrand_storage_per_minute_written_data",
153+
"cachegrand_storage_per_minute_write_iops",
154+
"cachegrand_storage_per_minute_read_data",
155+
"cachegrand_storage_per_minute_read_iops",
156+
157+
"cachegrand_uptime",
158+
NULL,
159+
};
160+
133161
char request_template[] =
134162
"GET /metrics HTTP/1.1\r\n"
135163
"User-Agent: cachegrand-tests\r\n"
@@ -146,27 +174,102 @@ TEST_CASE("program.c-prometheus", "[program-prometheus]") {
146174
buffer_send_data_len = strlen(buffer_send);
147175

148176
SECTION("No env vars") {
177+
char *new_line_ptr = NULL;
178+
int buffer_recv_length;
149179
REQUIRE(send(clientfd, buffer_send, buffer_send_data_len, 0) == buffer_send_data_len);
150-
REQUIRE(recv(clientfd, buffer_recv, sizeof(buffer_recv), 0) > 0);
180+
REQUIRE((buffer_recv_length = recv(clientfd, buffer_recv, sizeof(buffer_recv), 0)) > 0);
151181

152182
// Check that the response is a 200 OK and that the content type is text plain
153183
REQUIRE(strncmp(buffer_recv, "HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=ASCII\r\n",
154184
strlen("HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=ASCII\r\n")) == 0);
155185

156-
// TODO: should spot check some metrics
186+
// Search for the end of the HTTP header
187+
new_line_ptr = buffer_recv;
188+
while((new_line_ptr = (char*)memchr(
189+
new_line_ptr + 1,
190+
'\n',
191+
(buffer_recv_length - ((new_line_ptr + 1) - buffer_recv))))) {
192+
if (new_line_ptr - buffer_recv > 3) {
193+
if (strncmp(new_line_ptr - 3, "\r\n\r\n", 4) == 0) {
194+
break;
195+
}
196+
}
197+
}
198+
199+
// Ensure that has found the double new line at the end of the HTTP header
200+
REQUIRE(new_line_ptr != NULL);
201+
202+
for (char **metric_name = metrics_names; *metric_name; ++metric_name) {
203+
// Ensure that there is enough content in the buffer to contain the metric name, "{} ", at least 1 digit
204+
// and then \n
205+
REQUIRE((buffer_recv_length - ((new_line_ptr + 1) - buffer_recv)) >= strlen(*metric_name) + 3 + 1 + 1);
206+
new_line_ptr++;
207+
208+
// Ensure that the next metric is the expected one
209+
REQUIRE(strncmp(new_line_ptr, *metric_name, strlen(*metric_name)) == 0);
210+
211+
// As there are no env labels, ensure that the metric name is followed by "{} "
212+
REQUIRE(strncmp(new_line_ptr + strlen(*metric_name), "{} ", 3) == 0);
213+
214+
// THere is always a new line at the end of the line, even the last line
215+
REQUIRE((new_line_ptr = (char*)memchr(new_line_ptr, '\n', buffer_recv_length)) != NULL);
216+
}
157217
}
158218

159-
// TODO: implement tests to validate that env vars are properly caught and reported in the page
160-
// SECTION("With env vars") {
161-
// REQUIRE(send(clientfd, buffer_send, buffer_send_data_len, 0) == buffer_send_data_len);
162-
// REQUIRE(recv(clientfd, buffer_recv, sizeof(buffer_recv), 0) > 0);
163-
//
164-
// // Check that the response is a 200 OK and that the content type is text plain
165-
// REQUIRE(strncmp(buffer_recv, "HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=ASCII\r\n",
166-
// strlen("HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=ASCII\r\n")) == 0);
167-
//
168-
// // TODO: should spot check some metrics
169-
// }
219+
SECTION("With env vars") {
220+
char *new_line_ptr = NULL;
221+
int buffer_recv_length;
222+
223+
char *expected_labels = "{label_1=\"value 1\",another_label=\"another value\"}";
224+
225+
// Set 2 env vars to use them as lables in the metrics
226+
setenv("CACHEGRAND_METRIC_ENV_LABEL_1", "value 1", 1);
227+
setenv("CACHEGRAND_METRIC_ENV_ANOTHER_LABEL", "another value", 1);
228+
229+
REQUIRE(send(clientfd, buffer_send, buffer_send_data_len, 0) == buffer_send_data_len);
230+
REQUIRE((buffer_recv_length = recv(clientfd, buffer_recv, sizeof(buffer_recv), 0)) > 0);
231+
232+
// Unset the labels before doing anything else
233+
unsetenv("CACHEGRAND_METRIC_ENV_LABEL_1");
234+
unsetenv("CACHEGRAND_METRIC_ENV_ANOTHER_LABEL");
235+
236+
// Check that the response is a 200 OK and that the content type is text plain
237+
REQUIRE(strncmp(buffer_recv, "HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=ASCII\r\n",
238+
strlen("HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=ASCII\r\n")) == 0);
239+
240+
// Search for the end of the HTTP header
241+
new_line_ptr = buffer_recv;
242+
while((new_line_ptr = (char*)memchr(
243+
new_line_ptr + 1,
244+
'\n',
245+
(buffer_recv_length - ((new_line_ptr + 1) - buffer_recv))))) {
246+
if (new_line_ptr - buffer_recv > 3) {
247+
if (strncmp(new_line_ptr - 3, "\r\n\r\n", 4) == 0) {
248+
break;
249+
}
250+
}
251+
}
252+
253+
// Ensure that has found the double new line at the end of the HTTP header
254+
REQUIRE(new_line_ptr != NULL);
255+
256+
for (char **metric_name = metrics_names; *metric_name; ++metric_name) {
257+
// Ensure that there is enough content in the buffer to contain the metric name, the labels, a space, at
258+
// least 1 digit and then \n
259+
REQUIRE((buffer_recv_length - ((new_line_ptr + 1) - buffer_recv)) >=
260+
strlen(*metric_name) + strlen(expected_labels) + 1 + 1 + 1);
261+
new_line_ptr++;
262+
263+
// Ensure that the next metric is the expected one
264+
REQUIRE(strncmp(new_line_ptr, *metric_name, strlen(*metric_name)) == 0);
265+
266+
// As there are no env labels, ensure that the metric name is followed by expected_labels
267+
REQUIRE(strncmp(new_line_ptr + strlen(*metric_name), expected_labels, strlen(expected_labels)) == 0);
268+
269+
// THere is always a new line at the end of the line, even the last line
270+
REQUIRE((new_line_ptr = (char*)memchr(new_line_ptr, '\n', buffer_recv_length)) != NULL);
271+
}
272+
}
170273
}
171274

172275
SECTION("Prometheus - 404") {

0 commit comments

Comments
 (0)