Skip to content

Commit 314fee3

Browse files
committed
Add: unit test
Add: unit test for snmp_walk
1 parent 5cc7601 commit 314fee3

File tree

2 files changed

+228
-68
lines changed

2 files changed

+228
-68
lines changed

plugins/in_snmp/in_snmp.c

Lines changed: 74 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -30,63 +30,82 @@ int mock_snmp_synch_response(netsnmp_session *ss, netsnmp_pdu *pdu, netsnmp_pdu
3030
size_t mock_objid_len;
3131

3232
mock_status = getenv("TEST_SNMP_RESPONSE");
33+
if ((mock_response = flb_calloc(1, sizeof(netsnmp_pdu))) == NULL) {
34+
goto error;
35+
}
36+
37+
if (strcmp(mock_status, "snmp_get") == 0) {
38+
if ((mock_netsnmp_variable_list = flb_calloc(1, sizeof(netsnmp_variable_list))) == NULL) {
39+
goto error;
40+
}
41+
// sysUpTime
42+
mock_objid_len = MAX_OID_LEN;
43+
if (snmp_parse_oid("1.3.6.1.2.1.1.3.0", mock_objid, &mock_objid_len) == NULL) {
44+
goto error;
45+
}
46+
47+
if (snmp_set_var_objid(mock_netsnmp_variable_list, mock_objid, mock_objid_len)) {
48+
goto error;
49+
}
50+
51+
if (snmp_set_var_typed_integer(mock_netsnmp_variable_list, ASN_TIMETICKS, 123)) {
52+
goto error;
53+
}
54+
55+
mock_response->variables = mock_netsnmp_variable_list;
56+
mock_response->errstat = SNMP_ERR_NOERROR;
57+
*response = mock_response;
58+
59+
return STAT_SUCCESS;
60+
} else if (strcmp(mock_status, "snmp_walk") == 0) {
61+
if ((mock_netsnmp_variable_list = flb_calloc(1, sizeof(netsnmp_variable_list))) == NULL) {
62+
goto error;
63+
}
64+
// ifName.1
65+
mock_objid_len = MAX_OID_LEN;
66+
if (snmp_parse_oid("1.3.6.1.2.1.31.1.1.1.1.1", mock_objid, &mock_objid_len) == NULL) {
67+
goto error;
68+
}
69+
70+
if (snmp_set_var_objid(mock_netsnmp_variable_list, mock_objid, mock_objid_len)) {
71+
goto error;
72+
}
73+
74+
if (snmp_set_var_typed_value(mock_netsnmp_variable_list, ASN_OCTET_STR, "Fa0/0", strlen("Fa0/0"))) {
75+
goto error;
76+
}
77+
78+
if ((mock_netsnmp_variable_list->next_variable = flb_calloc(1, sizeof(netsnmp_variable_list))) == NULL) {
79+
goto error;
80+
}
81+
// ifName.2
82+
mock_objid_len = MAX_OID_LEN;
83+
if (snmp_parse_oid("1.3.6.1.2.1.31.1.1.1.1.2", mock_objid, &mock_objid_len) == NULL) {
84+
goto error;
85+
}
86+
87+
if (snmp_set_var_objid(mock_netsnmp_variable_list->next_variable, mock_objid, mock_objid_len)) {
88+
goto error;
89+
}
90+
91+
if (snmp_set_var_typed_value(mock_netsnmp_variable_list->next_variable, ASN_OCTET_STR, "Fa0/1", strlen("Fa0/1"))) {
92+
goto error;
93+
}
3394

34-
if (strcmp(mock_status, "normal") == 0) {
35-
// if ((mock_response = flb_calloc(1, sizeof(netsnmp_pdu))) == NULL) {
36-
// flb_errno();
37-
// flb_free(mock_status);
38-
// return NULL;
39-
// }
40-
41-
// if ((mock_netsnmp_variable_list = flb_calloc(1, sizeof(netsnmp_variable_list))) == NULL) {
42-
// flb_errno();
43-
// flb_free(mock_response);
44-
// flb_free(mock_status);
45-
// return NULL;
46-
// }
47-
48-
// // sysUpTime
49-
// mock_objid_len = MAX_OID_LEN;
50-
// if (snmp_parse_oid("1.3.6.1.2.1.1.3.0", mock_objid, &mock_objid_len) == NULL) {
51-
// flb_errno();
52-
// flb_free(mock_netsnmp_variable_list);
53-
// flb_free(mock_response);
54-
// flb_free(mock_status);
55-
// return NULL;
56-
// }
57-
58-
// mock_netsnmp_variable_list->next_variable = NULL;
59-
// mock_netsnmp_variable_list->name = NULL;
60-
// mock_netsnmp_variable_list->val.string = NULL;
61-
// mock_netsnmp_variable_list->val_len = 0;
62-
// mock_netsnmp_variable_list->data = NULL;
63-
// mock_netsnmp_variable_list->dataFreeHook = NULL;
64-
// mock_netsnmp_variable_list->index = 0;
65-
66-
// if (snmp_set_var_objid(mock_netsnmp_variable_list, mock_objid, mock_objid_len)) {
67-
// flb_errno();
68-
// flb_free(mock_netsnmp_variable_list);
69-
// flb_free(mock_response);
70-
// flb_free(mock_status);
71-
// return NULL;
72-
// }
73-
74-
// if (snmp_set_var_typed_integer(mock_netsnmp_variable_list, ASN_TIMETICKS, 123)) {
75-
// flb_errno();
76-
// flb_free(mock_netsnmp_variable_list);
77-
// flb_free(mock_response);
78-
// flb_free(mock_status);
79-
// return NULL;
80-
// }
81-
82-
// mock_response->variables = mock_netsnmp_variable_list;
83-
// mock_response->errstat == SNMP_ERR_NOERROR;
84-
// *response = mock_response;
85-
86-
// flb_free(mock_status);
95+
mock_response->variables = mock_netsnmp_variable_list;
96+
mock_response->errstat = SNMP_ERR_NOERROR;
97+
*response = mock_response;
8798

8899
return STAT_SUCCESS;
100+
} else {
101+
return STAT_ERROR;
89102
}
103+
104+
error:
105+
flb_errno();
106+
if (mock_netsnmp_variable_list) flb_free(mock_netsnmp_variable_list);
107+
if (mock_response) flb_free(mock_response);
108+
return STAT_ERROR;
90109
}
91110

92111
static int in_snmp_collect(struct flb_input_instance *ins, struct flb_config *config, void *in_context)
@@ -175,20 +194,18 @@ static int in_snmp_collect(struct flb_input_instance *ins, struct flb_config *co
175194
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
176195
} else {
177196
pdu = snmp_pdu_create(SNMP_MSG_GET);
197+
running = 0;
178198
}
179199

180200
snmp_add_null_var(pdu, name, name_len);
181201

182202
if (snmp_plugin_under_test() == FLB_TRUE) {
183-
flb_plg_error(ctx->ins, "Ha Ha");
184-
185203
status = mock_snmp_synch_response(ss, pdu, &response);
186204
} else {
187205
status = snmp_synch_response(ss, pdu, &response);
188206
}
189207

190208
if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
191-
192209
for(vars = response->variables; vars; vars = vars->next_variable) {
193210
if (is_walk && snmp_oid_compare(end_oid, end_len,
194211
vars->name, vars->name_length) <= 0) {
@@ -206,7 +223,7 @@ static int in_snmp_collect(struct flb_input_instance *ins, struct flb_config *co
206223
} else {
207224
netsnmp_sprint_realloc_objid_tree(&oid_buf, &oid_buf_len, &oid_out_len,
208225
1, &buf_overflow,
209-
vars->name, vars->name_length);
226+
vars->name, vars->name_length);
210227
if (buf_overflow) {
211228
flb_plg_error(ctx->ins, "[TRUNCATED]");
212229
return -1;

tests/runtime/in_snmp.c

Lines changed: 154 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,180 @@
11
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
22

33
#include <fluent-bit.h>
4+
#include <fluent-bit/flb_time.h>
45
#include "flb_tests_runtime.h"
56

6-
void flb_test_snmp()
7+
struct callback_record {
8+
void *data;
9+
size_t size;
10+
};
11+
12+
struct callback_records {
13+
int num_records;
14+
struct callback_record *records;
15+
};
16+
17+
int callback_add_record(void* data, size_t size, void* cb_data)
18+
{
19+
struct callback_records *ctx = (struct callback_records *)cb_data;
20+
21+
if (size > 0) {
22+
flb_info("[test] flush record");
23+
if (ctx->records == NULL) {
24+
ctx->records = (struct callback_record *)
25+
flb_calloc(1, sizeof(struct callback_record));
26+
} else {
27+
ctx->records = (struct callback_record *)
28+
flb_realloc(ctx->records,
29+
(ctx->num_records+1)*sizeof(struct callback_record));
30+
}
31+
if (ctx->records == NULL) {
32+
return -1;
33+
}
34+
ctx->records[ctx->num_records].size = size;
35+
ctx->records[ctx->num_records].data = data;
36+
ctx->num_records++;
37+
}
38+
return 0;
39+
}
40+
41+
void flb_test_snmp_records_message_get(struct callback_records *records)
742
{
8-
int ret;
9-
flb_ctx_t *ctx;
43+
int i;
44+
msgpack_unpacked result;
45+
msgpack_object *obj;
46+
size_t off = 0;
47+
struct flb_time ftm;
48+
49+
TEST_CHECK(records->num_records > 0);
50+
for (i = 0; i < records->num_records; i++) {
51+
msgpack_unpacked_init(&result);
52+
53+
while (msgpack_unpack_next(&result, records->records[i].data,
54+
records->records[i].size, &off) == MSGPACK_UNPACK_SUCCESS) {
55+
flb_time_pop_from_msgpack(&ftm, &result, &obj);
56+
TEST_CHECK(obj->type == MSGPACK_OBJECT_MAP);
57+
TEST_CHECK(strncmp("iso.3.6.1.2.1.1.3.0",
58+
obj->via.map.ptr[0].key.via.str.ptr,
59+
obj->via.map.ptr[0].key.via.str.size) == 0);
60+
TEST_CHECK(strncmp("123",
61+
obj->via.map.ptr[0].val.via.str.ptr,
62+
obj->via.map.ptr[0].val.via.str.size) == 0);
63+
}
64+
msgpack_unpacked_destroy(&result);
65+
}
66+
}
67+
68+
void flb_test_snmp_records_message_walk(struct callback_records *records)
69+
{
70+
int i, j;
71+
msgpack_unpacked result;
72+
msgpack_object *obj;
73+
size_t off = 0;
74+
struct flb_time ftm;
75+
msgpack_object key;
76+
msgpack_object val;
77+
78+
char expected_keys[2][26] = {
79+
"iso.3.6.1.2.1.31.1.1.1.1.1",
80+
"iso.3.6.1.2.1.31.1.1.1.1.2"
81+
};
82+
83+
char expected_vals[2][7] = {
84+
"\"Fa0/0\"",
85+
"\"Fa0/1\""
86+
};
87+
88+
TEST_CHECK(records->num_records > 0);
89+
for (i = 0; i < records->num_records; i++) {
90+
msgpack_unpacked_init(&result);
91+
while (msgpack_unpack_next(&result, records->records[i].data,
92+
records->records[i].size, &off) == MSGPACK_UNPACK_SUCCESS) {
93+
flb_time_pop_from_msgpack(&ftm, &result, &obj);
94+
TEST_CHECK(obj->type == MSGPACK_OBJECT_MAP);
95+
for (j = 0; j < obj->via.map.size; j++) {
96+
key = obj->via.map.ptr[j].key;
97+
val = obj->via.map.ptr[j].val;
98+
99+
TEST_CHECK(strncmp(expected_keys[j],
100+
key.via.str.ptr,
101+
26) == 0);
102+
TEST_CHECK(strncmp(expected_vals[j],
103+
val.via.str.ptr,
104+
7) == 0);
105+
}
106+
}
107+
msgpack_unpacked_destroy(&result);
108+
}
109+
}
110+
111+
112+
void do_test_records(char *response, void (*records_cb)(struct callback_records *), ...)
113+
{
114+
flb_ctx_t *ctx = NULL;
10115
int in_ffd;
11116
int out_ffd;
12-
117+
va_list va;
118+
char *key;
119+
char *value;
120+
int i;
121+
struct flb_lib_out_cb cb;
122+
struct callback_records *records;
123+
13124
/* mocks calls- signals that we are in test mode */
14125
setenv("FLB_SNMP_PLUGIN_UNDER_TEST", "true", 1);
15-
setenv("TEST_SNMP_RESPONSE", "normal", 1);
126+
setenv("TEST_SNMP_RESPONSE", response, 1);
127+
128+
records = flb_calloc(1, sizeof(struct callback_records));
129+
records->num_records = 0;
130+
records->records = NULL;
131+
cb.cb = callback_add_record;
132+
cb.data = (void *)records;
16133

134+
/* initialize */
17135
ctx = flb_create();
18136

19-
in_ffd = flb_input(ctx, (char *) "snmp", NULL);
137+
in_ffd = flb_input(ctx, "snmp", NULL);
20138
TEST_CHECK(in_ffd >= 0);
139+
TEST_CHECK(flb_input_set(ctx, in_ffd, "tag", "test", NULL) == 0);
140+
141+
va_start(va, records_cb);
142+
while ((key = va_arg(va, char *))) {
143+
value = va_arg(va, char *);
144+
TEST_CHECK(value != NULL);
145+
TEST_CHECK(flb_input_set(ctx, in_ffd, key, value, NULL) == 0);
146+
}
147+
va_end(va);
21148

22-
out_ffd = flb_output(ctx, (char *) "null", NULL);
149+
out_ffd = flb_output(ctx, (char *) "lib", &cb);
23150
TEST_CHECK(out_ffd >= 0);
24-
flb_output_set(ctx, out_ffd, "match", "test", NULL);
151+
TEST_CHECK(flb_output_set(ctx, out_ffd, "match", "test", NULL) == 0);
25152

26-
ret = flb_start(ctx);
27-
TEST_CHECK(ret == 0);
153+
/* Start test */
154+
TEST_CHECK(flb_start(ctx) == 0);
28155

29-
sleep(8);
156+
/* 4 sec passed. It must have flushed */
157+
sleep(5);
158+
159+
records_cb(records);
30160

31161
flb_stop(ctx);
162+
163+
for (i = 0; i < records->num_records; i++) {
164+
flb_lib_free(records->records[i].data);
165+
}
166+
flb_free(records->records);
167+
flb_free(records);
168+
32169
flb_destroy(ctx);
33170
}
34171

172+
void flb_test_snmp()
173+
{
174+
do_test_records("snmp_get", flb_test_snmp_records_message_get, NULL);
175+
do_test_records("snmp_walk", flb_test_snmp_records_message_walk, NULL);
176+
}
177+
35178
/* Test list */
36179
TEST_LIST = {
37180
{"snmp", flb_test_snmp},

0 commit comments

Comments
 (0)