From 299d8ae505f7c7262a8faa7564839322c26a1ffb Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 20 May 2015 23:53:48 +0200 Subject: [PATCH] data: Use a predefined format for sdb_strftime(). Also, print the nanosecond fraction of a second. --- src/core/data.c | 7 +- src/core/store.c | 9 +- src/core/store_json.c | 3 +- src/core/time.c | 18 +++- src/include/core/time.h | 3 +- src/parser/analyzer.c | 4 +- t/unit/core/data_test.c | 2 +- t/unit/core/store_json_test.c | 168 +++++++++++++++++----------------- t/unit/core/time_test.c | 46 ++++++++++ t/unit/frontend/query_test.c | 84 ++++++++--------- t/unit/testutils.h | 2 + 11 files changed, 202 insertions(+), 144 deletions(-) diff --git a/src/core/data.c b/src/core/data.c index 444f5a1..58c8b52 100644 --- a/src/core/data.c +++ b/src/core/data.c @@ -931,8 +931,8 @@ sdb_data_strlen(const sdb_data_t *datum) /* in the worst case, each character needs to be escaped */ return 2 * strlen(datum->data.string) + 2; case SDB_TYPE_DATETIME: - /* "YYYY-MM-DD HH:MM:SS +zzzz" */ - return 27; + /* "YYYY-MM-DD HH:MM:SS[.nnnnnnnnn] +zzzz" */ + return 37; case SDB_TYPE_BINARY: if (! datum->data.binary.datum) return 6; /* NULL */ @@ -1013,8 +1013,7 @@ sdb_data_format(const sdb_data_t *datum, char *buf, size_t buflen, int quoted) } } else if (datum->type == SDB_TYPE_DATETIME) { - if (! sdb_strftime(tmp, sizeof(tmp), "%F %T %z", - datum->data.datetime)) + if (! sdb_strftime(tmp, sizeof(tmp), datum->data.datetime)) return -1; tmp[sizeof(tmp) - 1] = '\0'; data = tmp; diff --git a/src/core/store.c b/src/core/store.c index bf12a93..171e319 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -488,12 +488,10 @@ ts_tojson(sdb_timeseries_t *ts, sdb_strbuf_t *buf) size_t i; /* TODO: make time format configurable */ - if (! sdb_strftime(start_str, sizeof(start_str), - "%F %T %z", ts->start)) + if (! sdb_strftime(start_str, sizeof(start_str), ts->start)) snprintf(start_str, sizeof(start_str), ""); start_str[sizeof(start_str) - 1] = '\0'; - if (! sdb_strftime(end_str, sizeof(end_str), - "%F %T %z", ts->end)) + if (! sdb_strftime(end_str, sizeof(end_str), ts->end)) snprintf(end_str, sizeof(end_str), ""); end_str[sizeof(end_str) - 1] = '\0'; @@ -507,8 +505,7 @@ ts_tojson(sdb_timeseries_t *ts, sdb_strbuf_t *buf) for (j = 0; j < ts->data_len; ++j) { char time_str[64]; - if (! sdb_strftime(time_str, sizeof(time_str), - "%F %T %z", ts->data[i][j].timestamp)) + if (! sdb_strftime(time_str, sizeof(time_str), ts->data[i][j].timestamp)) snprintf(time_str, sizeof(time_str), ""); time_str[sizeof(time_str) - 1] = '\0'; diff --git a/src/core/store_json.c b/src/core/store_json.c index a772dc3..7362691 100644 --- a/src/core/store_json.c +++ b/src/core/store_json.c @@ -140,8 +140,7 @@ json_emit(sdb_store_json_formatter_t *f, sdb_store_obj_t *obj) } /* TODO: make time and interval formats configurable */ - if (! sdb_strftime(time_str, sizeof(time_str), - "%F %T %z", obj->last_update)) + if (! sdb_strftime(time_str, sizeof(time_str), obj->last_update)) snprintf(time_str, sizeof(time_str), ""); time_str[sizeof(time_str) - 1] = '\0'; diff --git a/src/core/time.c b/src/core/time.c index d0ed0b8..d8e8fab 100644 --- a/src/core/time.c +++ b/src/core/time.c @@ -78,18 +78,30 @@ sdb_sleep(sdb_time_t reg, sdb_time_t *rem) } /* sdb_sleep */ size_t -sdb_strftime(char *s, size_t len, const char *format, sdb_time_t t) +sdb_strftime(char *s, size_t len, sdb_time_t t) { + char tmp[len]; time_t tstamp; struct tm tm; + long tz; memset(&tm, 0, sizeof(tm)); - tstamp = (time_t)SDB_TIME_TO_SECS(t); if (! localtime_r (&tstamp, &tm)) return 0; - return strftime(s, len, format, &tm); + if (! strftime(tmp, len, "%F %T", &tm)) + return 0; + tmp[sizeof(tmp) - 1] = '\0'; + + tz = -timezone / 36; + if (tm.tm_isdst > 0) + tz += 100; + + t %= SDB_INTERVAL_SECOND; + if (! t) + return snprintf(s, len, "%s %+05ld", tmp, tz); + return snprintf(s, len, "%s.%09ld %+05ld", tmp, t, tz); } /* sdb_strftime */ size_t diff --git a/src/include/core/time.h b/src/include/core/time.h index c48a2e1..a9ca72f 100644 --- a/src/include/core/time.h +++ b/src/include/core/time.h @@ -74,8 +74,7 @@ int sdb_sleep(sdb_time_t reg, sdb_time_t *rem); size_t -sdb_strftime(char *s, size_t len, const char *format, sdb_time_t) - __attribute__((format(strftime, 3, 0))); +sdb_strftime(char *s, size_t len, sdb_time_t); size_t sdb_strfinterval(char *s, size_t len, sdb_time_t interval); diff --git a/src/parser/analyzer.c b/src/parser/analyzer.c index dea83d7..9bbd9ba 100644 --- a/src/parser/analyzer.c +++ b/src/parser/analyzer.c @@ -568,8 +568,8 @@ analyze_timeseries(sdb_ast_timeseries_t *ts, sdb_strbuf_t *errbuf) } if (ts->end <= ts->start) { char start_str[64], end_str[64]; - sdb_strftime(start_str, sizeof(start_str), "%F %T Tz", ts->start); - sdb_strftime(end_str, sizeof(end_str), "%F %T Tz", ts->end); + sdb_strftime(start_str, sizeof(start_str), ts->start); + sdb_strftime(end_str, sizeof(end_str), ts->end); sdb_strbuf_sprintf(errbuf, "Start time (%s) greater than " "end time (%s) in STORE command", start_str, end_str); return -1; diff --git a/t/unit/core/data_test.c b/t/unit/core/data_test.c index d421e64..27daaae 100644 --- a/t/unit/core/data_test.c +++ b/t/unit/core/data_test.c @@ -2350,7 +2350,7 @@ START_TEST(test_format) }, { { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } }, - "\"1984-12-06 02:11:54 +0000\"", + "\"1984-12-06 02:11:54.711471100 +0000\"", }, { { SDB_TYPE_BINARY, { .binary = { 0, NULL } } }, diff --git a/t/unit/core/store_json_test.c b/t/unit/core/store_json_test.c index b69573c..113d3a0 100644 --- a/t/unit/core/store_json_test.c +++ b/t/unit/core/store_json_test.c @@ -35,46 +35,50 @@ #include #include +/* Make SDB_INTERVAL_SECOND a constant initializer. */ +#undef SDB_INTERVAL_SECOND +#define SDB_INTERVAL_SECOND 1000000000L + static void populate(void) { sdb_data_t datum; - sdb_store_host("h1", 1); - sdb_store_host("h2", 3); + sdb_store_host("h1", 1 * SDB_INTERVAL_SECOND); + sdb_store_host("h2", 3 * SDB_INTERVAL_SECOND); datum.type = SDB_TYPE_STRING; datum.data.string = "v1"; - sdb_store_attribute("h1", "k1", &datum, 1); + sdb_store_attribute("h1", "k1", &datum, 1 * SDB_INTERVAL_SECOND); datum.data.string = "v2"; - sdb_store_attribute("h1", "k2", &datum, 2); + sdb_store_attribute("h1", "k2", &datum, 2 * SDB_INTERVAL_SECOND); datum.data.string = "v3"; - sdb_store_attribute("h1", "k3", &datum, 2); + sdb_store_attribute("h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND); /* make sure that older updates don't overwrite existing values */ datum.data.string = "fail"; - sdb_store_attribute("h1", "k2", &datum, 1); - sdb_store_attribute("h1", "k3", &datum, 2); + sdb_store_attribute("h1", "k2", &datum, 1 * SDB_INTERVAL_SECOND); + sdb_store_attribute("h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND); - sdb_store_metric("h1", "m1", /* store */ NULL, 2); - sdb_store_metric("h1", "m2", /* store */ NULL, 1); - sdb_store_metric("h2", "m1", /* store */ NULL, 1); + sdb_store_metric("h1", "m1", /* store */ NULL, 2 * SDB_INTERVAL_SECOND); + sdb_store_metric("h1", "m2", /* store */ NULL, 1 * SDB_INTERVAL_SECOND); + sdb_store_metric("h2", "m1", /* store */ NULL, 1 * SDB_INTERVAL_SECOND); - sdb_store_service("h2", "s1", 1); - sdb_store_service("h2", "s2", 2); + sdb_store_service("h2", "s1", 1 * SDB_INTERVAL_SECOND); + sdb_store_service("h2", "s2", 2 * SDB_INTERVAL_SECOND); datum.type = SDB_TYPE_INTEGER; datum.data.integer = 42; - sdb_store_metric_attr("h1", "m1", "k3", &datum, 2); + sdb_store_metric_attr("h1", "m1", "k3", &datum, 2 * SDB_INTERVAL_SECOND); datum.data.integer = 123; - sdb_store_service_attr("h2", "s2", "k1", &datum, 2); + sdb_store_service_attr("h2", "s2", "k1", &datum, 2 * SDB_INTERVAL_SECOND); datum.data.integer = 4711; - sdb_store_service_attr("h2", "s2", "k2", &datum, 1); + sdb_store_service_attr("h2", "s2", "k2", &datum, 1 * SDB_INTERVAL_SECOND); /* don't overwrite k1 */ datum.data.integer = 666; - sdb_store_service_attr("h2", "s2", "k1", &datum, 2); + sdb_store_service_attr("h2", "s2", "k1", &datum, 2 * SDB_INTERVAL_SECOND); } /* populate */ static int @@ -133,76 +137,76 @@ struct { { { NULL, 0, SDB_DATA_INIT }, SDB_HOST, scan_tojson_full, "[" - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"k1\", \"value\": \"v1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k2\", \"value\": \"v2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k3\", \"value\": \"v3\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "], " "\"metrics\": [" "{\"name\": \"m1\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k3\", \"value\": 42, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}," "{\"name\": \"m2\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}," - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"metrics\": [" "{\"name\": \"m1\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "], " "\"services\": [" "{\"name\": \"s1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}," "{\"name\": \"s2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k1\", \"value\": 123, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k2\", \"value\": 4711, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}" @@ -210,66 +214,66 @@ struct { { { NULL, 0, SDB_DATA_INIT }, SDB_HOST, scan_tojson, "[" - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]" }, { { sdb_store_eq_matcher, SDB_FIELD_NAME, { SDB_TYPE_STRING, { .string = "h1" } } }, SDB_HOST, scan_tojson_full, "[" - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]" }, { { sdb_store_gt_matcher, SDB_FIELD_LAST_UPDATE, - { SDB_TYPE_DATETIME, { .datetime = 1 } } }, + { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } }, SDB_HOST, scan_tojson_full, "[" - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"services\": [" "{\"name\": \"s2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k1\", \"value\": 123, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}" "]" }, { { sdb_store_le_matcher, SDB_FIELD_LAST_UPDATE, - { SDB_TYPE_DATETIME, { .datetime = 1 } } }, + { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } }, SDB_HOST, scan_tojson_full, "[" - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"k1\", \"value\": \"v1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "], " "\"metrics\": [" "{\"name\": \"m2\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}" "]" }, { { sdb_store_ge_matcher, SDB_FIELD_LAST_UPDATE, - { SDB_TYPE_DATETIME, { .datetime = 3 } } }, + { SDB_TYPE_DATETIME, { .datetime = 3 * SDB_INTERVAL_SECOND } } }, SDB_HOST, scan_tojson_full, "[" - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]" }, { { sdb_store_lt_matcher, SDB_FIELD_LAST_UPDATE, @@ -280,29 +284,29 @@ struct { { { NULL, 0, SDB_DATA_INIT }, SDB_SERVICE, scan_tojson_full, "[" - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"services\": [" "{\"name\": \"s1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}," "{\"name\": \"s2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k1\", \"value\": 123, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k2\", \"value\": 4711, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}" @@ -310,33 +314,33 @@ struct { { { NULL, 0, SDB_DATA_INIT }, SDB_SERVICE, scan_tojson, "[" - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"services\": [" "{\"name\": \"s1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"s2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]" }, { { sdb_store_gt_matcher, SDB_FIELD_LAST_UPDATE, - { SDB_TYPE_DATETIME, { .datetime = 1 } } }, + { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } }, SDB_SERVICE, scan_tojson_full, "[" - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"services\": [" "{\"name\": \"s2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k1\", \"value\": 123, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}" @@ -348,41 +352,41 @@ struct { { { NULL, 0, SDB_DATA_INIT }, SDB_METRIC, scan_tojson_full, "[" - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"metrics\": [" "{\"name\": \"m1\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"k3\", \"value\": 42, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}," "{\"name\": \"m2\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}," - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"metrics\": [" "{\"name\": \"m1\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h2\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}" @@ -390,41 +394,41 @@ struct { { { NULL, 0, SDB_DATA_INIT }, SDB_METRIC, scan_tojson, "[" - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"metrics\": [" "{\"name\": \"m1\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "{\"name\": \"m2\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}," - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"metrics\": [" "{\"name\": \"m1\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]" }, { { sdb_store_le_matcher, SDB_FIELD_LAST_UPDATE, - { SDB_TYPE_DATETIME, { .datetime = 1 } } }, + { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } }, SDB_METRIC, scan_tojson_full, "[" - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"metrics\": [" "{\"name\": \"m2\", " "\"timeseries\": false, " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": [], " "\"attributes\": [" "{\"name\": \"hostname\", \"value\": \"h1\", " - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}" "]}" "]}" diff --git a/t/unit/core/time_test.c b/t/unit/core/time_test.c index 9fee9db..978fc02 100644 --- a/t/unit/core/time_test.c +++ b/t/unit/core/time_test.c @@ -44,6 +44,51 @@ #define US 1000L #define NS 1L +struct { + sdb_time_t t; + const char *tz; + const char *expected; +} strftime_data[] = { + { 0, "UTC", "1970-01-01 00:00:00 +0000" }, + { 1428066243000000000L, "Europe/Berlin", "2015-04-03 15:04:03 +0200" }, + { 1420113661000000000L, "Europe/Berlin", "2015-01-01 13:01:01 +0100" }, + { 1428066243000000000L, "US/Pacific", "2015-04-03 06:04:03 -0700" }, + { 1420113661000000000L, "US/Pacific", "2015-01-01 04:01:01 -0800" }, + { 1146747723000000123L, "UTC", "2006-05-04 13:02:03.000000123 +0000" }, + { 1146747723123456789L, "UTC", "2006-05-04 13:02:03.123456789 +0000" }, +}; + +START_TEST(test_strftime) +{ + char buf[1024], tz[64]; + size_t check; + + /* strftime does not provide the number of bytes that would have been + * written. Only check that it does not segfault. */ + sdb_strftime(NULL, 0, strftime_data[_i].t); + + snprintf(tz, sizeof(tz), "TZ=%s", strftime_data[_i].tz); + putenv(tz); + tzset(); + + check = sdb_strftime(buf, sizeof(buf), strftime_data[_i].t); + fail_unless(check > 0, + "%s; sdb_strftime(, , %"PRIsdbTIME") = %zu; " + "expected: >0", tz, strftime_data[_i].t, check); + fail_unless(!strcmp(buf, strftime_data[_i].expected), + "%s; sdb_strftime(, , %"PRIsdbTIME") did not " + "format time correctly; got: '%s'; expected: '%s'", + tz, strftime_data[_i].t, buf, strftime_data[_i].expected); + fail_unless(check == strlen(strftime_data[_i].expected), + "%s; sdb_strftime(, , %"PRIsdbTIME") = %zu; " + "expected: %zu", tz, strftime_data[_i].t, check, + strlen(strftime_data[_i].expected)); + + putenv("TZ=UTC"); + tzset(); +} +END_TEST + struct { sdb_time_t interval; const char *expected; @@ -130,6 +175,7 @@ END_TEST TEST_MAIN("core::time") { TCase *tc = tcase_create("core"); + TC_ADD_LOOP_TEST(tc, strftime); TC_ADD_LOOP_TEST(tc, strfinterval); TC_ADD_LOOP_TEST(tc, strpunit); ADD_TCASE(tc); diff --git a/t/unit/frontend/query_test.c b/t/unit/frontend/query_test.c index 861313f..8872e5b 100644 --- a/t/unit/frontend/query_test.c +++ b/t/unit/frontend/query_test.c @@ -44,134 +44,134 @@ populate(void) { sdb_data_t datum; - sdb_store_host("h1", 1); - sdb_store_host("h2", 3); + sdb_store_host("h1", 1 * SDB_INTERVAL_SECOND); + sdb_store_host("h2", 3 * SDB_INTERVAL_SECOND); datum.type = SDB_TYPE_STRING; datum.data.string = "v1"; - sdb_store_attribute("h1", "k1", &datum, 1); + sdb_store_attribute("h1", "k1", &datum, 1 * SDB_INTERVAL_SECOND); datum.data.string = "v2"; - sdb_store_attribute("h1", "k2", &datum, 2); + sdb_store_attribute("h1", "k2", &datum, 2 * SDB_INTERVAL_SECOND); datum.data.string = "v3"; - sdb_store_attribute("h1", "k3", &datum, 2); + sdb_store_attribute("h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND); - sdb_store_metric("h1", "m1", /* store */ NULL, 2); - sdb_store_metric("h1", "m2", /* store */ NULL, 1); - sdb_store_metric("h2", "m1", /* store */ NULL, 1); + sdb_store_metric("h1", "m1", /* store */ NULL, 2 * SDB_INTERVAL_SECOND); + sdb_store_metric("h1", "m2", /* store */ NULL, 1 * SDB_INTERVAL_SECOND); + sdb_store_metric("h2", "m1", /* store */ NULL, 1 * SDB_INTERVAL_SECOND); datum.type = SDB_TYPE_INTEGER; datum.data.integer = 42; - sdb_store_metric_attr("h1", "m1", "k3", &datum, 2); + sdb_store_metric_attr("h1", "m1", "k3", &datum, 2 * SDB_INTERVAL_SECOND); - sdb_store_service("h2", "s1", 1); - sdb_store_service("h2", "s2", 2); + sdb_store_service("h2", "s1", 1 * SDB_INTERVAL_SECOND); + sdb_store_service("h2", "s2", 2 * SDB_INTERVAL_SECOND); datum.data.integer = 123; - sdb_store_service_attr("h2", "s2", "k1", &datum, 2); + sdb_store_service_attr("h2", "s2", "k1", &datum, 2 * SDB_INTERVAL_SECOND); datum.data.integer = 4711; - sdb_store_service_attr("h2", "s2", "k2", &datum, 1); + sdb_store_service_attr("h2", "s2", "k2", &datum, 1 * SDB_INTERVAL_SECOND); } /* populate */ #define HOST_H1 \ - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"attributes\": [" \ "{\"name\": \"k1\", \"value\": \"v1\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}," \ "{\"name\": \"k2\", \"value\": \"v2\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}," \ "{\"name\": \"k3\", \"value\": \"v3\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}], " \ "\"metrics\": [" \ "{\"name\": \"m1\", \"timeseries\": false, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"attributes\": [" \ "{\"name\": \"hostname\", \"value\": \"h1\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}," \ "{\"name\": \"k3\", \"value\": 42, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}," \ "{\"name\": \"m2\", \"timeseries\": false, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"attributes\": [" \ "{\"name\": \"hostname\", \"value\": \"h1\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}]}" #define HOST_H1_ARRAY "["HOST_H1"]" #define HOST_H1_LISTING \ - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}" #define HOST_H2_LISTING \ - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}" #define SERVICE_H2_S1 \ - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"services\": [" \ - "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"attributes\": [" \ "{\"name\": \"hostname\", \"value\": \"h2\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}]}" #define SERVICE_H2_S1_ARRAY "["SERVICE_H2_S1"]" #define SERVICE_H2_S12_LISTING \ - "[{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "[{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"services\": [" \ - "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}," \ - "{\"name\": \"s2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"s2\", \"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}]" #define METRIC_H1_M1 \ - "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"metrics\": [" \ "{\"name\": \"m1\", \"timeseries\": false, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"attributes\": [" \ "{\"name\": \"hostname\", \"value\": \"h1\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}," \ "{\"name\": \"k3\", \"value\": 42, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}]}" #define METRIC_H12_M1_ARRAY \ "["METRIC_H1_M1"," \ - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"metrics\": [" \ "{\"name\": \"m1\", \"timeseries\": false, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"attributes\": [" \ "{\"name\": \"hostname\", \"value\": \"h2\", " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}]}]" #define METRIC_H12_M12_LISTING \ - "[{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "[{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"metrics\": [" \ "{\"name\": \"m1\", \"timeseries\": false, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}," \ "{\"name\": \"m2\", \"timeseries\": false, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}," \ - "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": [], " \ "\"metrics\": [" \ "{\"name\": \"m1\", \"timeseries\": false, " \ - "\"last_update\": \"1970-01-01 00:00:00 +0000\", " \ + "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \ "\"update_interval\": \"0s\", \"backends\": []}]}]" typedef struct { diff --git a/t/unit/testutils.h b/t/unit/testutils.h index a698965..5e0cc85 100644 --- a/t/unit/testutils.h +++ b/t/unit/testutils.h @@ -37,6 +37,7 @@ #include #include #include +#include #define TEST_MAIN(name) \ int main(void) \ @@ -45,6 +46,7 @@ Suite *s; \ int failed; \ putenv("TZ=UTC"); \ + tzset(); \ s = suite_create(name); \ sr = srunner_create(s); \ -- 2.30.2