Skip to content

Commit 64f0b88

Browse files
Merge pull request #151 from danielealbano/misc-bugfixes
Misc bugfixes
2 parents 62ac35a + b082024 commit 64f0b88

File tree

4 files changed

+123
-22
lines changed

4 files changed

+123
-22
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,5 @@ docker run \
148148
--ulimit memlock=-1:-1 \
149149
--ulimit nofile=262144:262144 \
150150
-p 6379:6379 \
151-
cachegrand/cachegrand-server:v0.1.0
151+
cachegrand/cachegrand-server:latest
152152
```

src/network/protocol/prometheus/network_protocol_prometheus.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ bool network_protocol_prometheus_process_metrics_request_add_metric(
464464
0,
465465
metric_template_with_value_formatter,
466466
name,
467-
extra_env_metrics,
467+
extra_env_metrics ? extra_env_metrics : "",
468468
value);
469469

470470
if (*length + metric_length + 1 > *size) {
@@ -486,7 +486,7 @@ bool network_protocol_prometheus_process_metrics_request_add_metric(
486486
*size - *length,
487487
metric_template_with_value_formatter,
488488
name,
489-
extra_env_metrics,
489+
extra_env_metrics ? extra_env_metrics : "",
490490
value);
491491

492492
*length += metric_length;
@@ -589,8 +589,8 @@ bool network_protocol_prometheus_process_request(
589589
channel,
590590
404,
591591
"Page not found",
592-
"The page <b>%*s</b> doesn't exist",
593-
http_request_data->url_length,
592+
"The page <b>%.*s</b> doesn't exist",
593+
(int)http_request_data->url_length,
594594
http_request_data->url);
595595
}
596596

src/program_ulimit.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ bool program_ulimit_set_nofile(
3737
ulong value) {
3838
LOG_V(TAG, "> Setting max opened file ulimit to %lu", value);
3939
if (program_ulimit_wrapper(RLIMIT_NOFILE, value) == false) {
40-
LOG_E(TAG, "Unable to set max opened file ulimit");
41-
LOG_E_OS_ERROR(TAG);
40+
LOG_W(TAG, "Unable to set max opened file ulimit");
4241
return false;
4342
}
4443

@@ -49,8 +48,7 @@ bool program_ulimit_set_memlock(
4948
ulong value) {
5049
LOG_V(TAG, "> Setting max lockable memory ulimit to %lu", value);
5150
if (program_ulimit_wrapper(RLIMIT_MEMLOCK, value) == false) {
52-
LOG_E(TAG, "Unable to set the lockable memory ulimit");
53-
LOG_E_OS_ERROR(TAG);
51+
LOG_W(TAG, "Unable to set the lockable memory ulimit");
5452
return false;
5553
}
5654

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)