Skip to content

Commit

Permalink
curl_json plugin: Implement a unit test.
Browse files Browse the repository at this point in the history
  • Loading branch information
octo committed May 16, 2017
1 parent 1b5d701 commit 2dd57c5
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 3 deletions.
9 changes: 9 additions & 0 deletions Makefile.am
Expand Up @@ -691,6 +691,15 @@ curl_json_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
curl_json_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
curl_json_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
curl_json_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS)

test_plugin_curl_json_SOURCES = src/curl_json_test.c \
src/utils_curl_stats.c \
src/daemon/configfile.c \
src/daemon/types_list.c
test_plugin_curl_json_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
test_plugin_curl_json_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
test_plugin_curl_json_LDADD = libavltree.la liboconfig.la libplugin_mock.la $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS)
check_PROGRAMS += test_plugin_curl_json
endif

if BUILD_PLUGIN_CURL_XML
Expand Down
10 changes: 7 additions & 3 deletions src/curl_json.c
Expand Up @@ -106,7 +106,11 @@ typedef unsigned int yajl_len_t;
#endif

static int cj_read(user_data_t *ud);
static void cj_submit(cj_t *db, cj_key_t *key, value_t *value);
static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value);

/* cj_submit is a function pointer to cj_submit_impl, allowing the unit-test to
* overwrite which function is called. */
static void (*cj_submit)(cj_t *, cj_key_t *, value_t *) = cj_submit_impl;

static size_t cj_curl_callback(void *buf, /* {{{ */
size_t size, size_t nmemb, void *user_data) {
Expand Down Expand Up @@ -773,7 +777,7 @@ static const char *cj_host(cj_t *db) /* {{{ */
return db->host;
} /* }}} cj_host */

static void cj_submit(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
{
value_list_t vl = VALUE_LIST_INIT;

Expand All @@ -797,7 +801,7 @@ static void cj_submit(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
vl.interval = db->interval;

plugin_dispatch_values(&vl);
} /* }}} int cj_submit */
} /* }}} int cj_submit_impl */

static int cj_sock_perform(cj_t *db) /* {{{ */
{
Expand Down
121 changes: 121 additions & 0 deletions src/curl_json_test.c
@@ -0,0 +1,121 @@
/**
* collectd - src/curl_json.c
* Copyright (C) 2017 Florian octo Forster
*
* Licensed under the same terms and conditions as src/curl_json.c.
*
* Authors:
* Florian octo Forster <octo at collectd.org>
**/

#include "curl_json.c"

#include "testing.h"

static void test_submit(cj_t *db, cj_key_t *key, value_t *value) {
/* hack: we repurpose db->curl to store received values. */
c_avl_tree_t *values = (void *)db->curl;

value_t *value_copy = calloc(1, sizeof(*value_copy));
memmove(value_copy, value, sizeof(*value_copy));

assert(c_avl_insert(values, key->path, value_copy) == 0);
}

static derive_t test_metric(cj_t *db, char const *path) {
c_avl_tree_t *values = (void *)db->curl;

value_t *ret = NULL;
if (c_avl_get(values, path, (void *)&ret) == 0) {
return ret->derive;
}

return NAN;
}

static cj_t *test_setup(char *json, char *key_path) {
cj_t *db = calloc(1, sizeof(*db));
db->yajl = yajl_alloc(&ycallbacks,
#if HAVE_YAJL_V2
/* alloc funcs = */ NULL,
#else
/* alloc funcs = */ NULL, NULL,
#endif
/* context = */ (void *)db);

/* hack; see above. */
db->curl = (void *)cj_avl_create();

cj_key_t *key = calloc(1, sizeof(*key));
key->magic = CJ_KEY_MAGIC;
key->path = strdup(key_path);
key->type = strdup("MAGIC");

assert(cj_append_key(db, key) == 0);

db->state[0].tree = db->tree;

cj_curl_callback(json, strlen(json), 1, db);
#if HAVE_YAJL_V2
yajl_complete_parse(db->yajl);
#else
yajl_parse_complete(db->yajl);
#endif

return db;
}

static void test_teardown(cj_t *db) {
c_avl_tree_t *values = (void *)db->curl;
db->curl = NULL;

void *key;
void *value;
while (c_avl_pick(values, &key, &value) == 0) {
/* key will be freed by cj_free. */
free(value);
}
c_avl_destroy(values);

yajl_free(db->yajl);
db->yajl = NULL;

cj_free(db);
}

DEF_TEST(parse) {
struct {
char *json;
char *key_path;
derive_t want;
} cases[] = {
{"{\"foo\":42,\"bar\":23}", "foo", 42},
{"{\"foo\":42,\"bar\":23}", "bar", 23},
{"{\"a\":{\"b\":{\"c\":123}}", "a/b/c", 123},
{"{\"x\":{\"y\":{\"z\":789}}", "x/*/z", 789},
// {"[10,11,12,13]", "0", 10},
// {"{\"a\":[[10,11,12,13,14]]}", "a/0/0", 10},
// {"{\"a\":[[10,11,12,13,14]]}", "a/0/1", 11},
// {"{\"a\":[[10,11,12,13,14]]}", "a/0/2", 12},
// {"{\"a\":[[10,11,12,13,14]]}", "a/0/3", 13},
// {"{\"a\":[[10,11,12,13,14]]}", "a/0/4", 14},
};

for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
cj_t *db = test_setup(cases[i].json, cases[i].key_path);

EXPECT_EQ_INT(cases[i].want, test_metric(db, cases[i].key_path));

test_teardown(db);
}

return 0;
}

int main(int argc, char **argv) {
cj_submit = test_submit;

RUN_TEST(parse);

END_TEST;
}

0 comments on commit 2dd57c5

Please sign in to comment.