From b7ebd3b8c6fe39f99c40b10c1b563e4adb607b6c Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Wed, 26 Nov 2014 16:33:03 -0800 Subject: Initial import. --- test/core/support/time_test.c | 255 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 test/core/support/time_test.c (limited to 'test/core/support/time_test.c') diff --git a/test/core/support/time_test.c b/test/core/support/time_test.c new file mode 100644 index 0000000000..d74d6a52d9 --- /dev/null +++ b/test/core/support/time_test.c @@ -0,0 +1,255 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Test of gpr time support. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "test/core/util/test_config.h" + +static void to_fp(void *arg, const char *buf, int len) { + fwrite(buf, 1, len, (FILE *)arg); +} + +/* Convert gpr_uintmax x to ascii base b (2..16), and write with + (*writer)(arg, ...), zero padding to "chars" digits). */ +static void u_to_s(gpr_uintmax x, unsigned base, int chars, + void (*writer)(void *arg, const char *buf, int len), + void *arg) { + char buf[64]; + char *p = buf + sizeof(buf); + do { + *--p = "0123456789abcdef"[x % base]; + x /= base; + chars--; + } while (x != 0 || chars > 0); + (*writer)(arg, p, buf + sizeof(buf) - p); +} + +/* Convert gpr_intmax x to ascii base b (2..16), and write with + (*writer)(arg, ...), zero padding to "chars" digits). */ +static void i_to_s(gpr_intmax x, unsigned base, int chars, + void (*writer)(void *arg, const char *buf, int len), + void *arg) { + if (x < 0) { + (*writer)(arg, "-", 1); + u_to_s(-x, base, chars - 1, writer, arg); + } else { + u_to_s(x, base, chars, writer, arg); + } +} + +/* Convert ts to ascii, and write with (*writer)(arg, ...). */ +static void ts_to_s(gpr_timespec t, + void (*writer)(void *arg, const char *buf, int len), + void *arg) { + if (t.tv_sec < 0 && t.tv_nsec != 0) { + t.tv_sec++; + t.tv_nsec = 1000000000 - t.tv_nsec; + } + i_to_s(t.tv_sec, 10, 0, writer, arg); + (*writer)(arg, ".", 1); + i_to_s(t.tv_nsec, 10, 9, writer, arg); +} + +static void test_values(void) { + int i; + + gpr_timespec x = gpr_time_0; + GPR_ASSERT(x.tv_sec == 0 && x.tv_nsec == 0); + + x = gpr_inf_future; + fprintf(stderr, "far future "); + u_to_s(x.tv_sec, 16, 16, &to_fp, stderr); + fprintf(stderr, "\n"); + GPR_ASSERT(x.tv_sec >= INT_MAX); + fprintf(stderr, "far future "); + ts_to_s(x, &to_fp, stderr); + fprintf(stderr, "\n"); + + x = gpr_inf_past; + fprintf(stderr, "far past "); + u_to_s(x.tv_sec, 16, 16, &to_fp, stderr); + fprintf(stderr, "\n"); + GPR_ASSERT(x.tv_sec <= INT_MIN); + fprintf(stderr, "far past "); + ts_to_s(x, &to_fp, stderr); + fprintf(stderr, "\n"); + + for (i = 1; i != 1000 * 1000 * 1000; i *= 10) { + x = gpr_time_from_micros(i); + GPR_ASSERT(x.tv_sec == i / GPR_US_PER_SEC && + x.tv_nsec == (i % GPR_US_PER_SEC) * GPR_NS_PER_US); + x = gpr_time_from_nanos(i); + GPR_ASSERT(x.tv_sec == i / GPR_NS_PER_SEC && + x.tv_nsec == (i % GPR_NS_PER_SEC)); + x = gpr_time_from_millis(i); + GPR_ASSERT(x.tv_sec == i / GPR_MS_PER_SEC && + x.tv_nsec == (i % GPR_MS_PER_SEC) * GPR_NS_PER_MS); + } + + /* Test possible overflow in conversion of -ve values. */ + x = gpr_time_from_micros(-(LONG_MAX - 999997)); + GPR_ASSERT(x.tv_sec < 0); + GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < 1000000000); + + x = gpr_time_from_nanos(-(LONG_MAX - 999999997)); + GPR_ASSERT(x.tv_sec < 0); + GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < 1000000000); + + x = gpr_time_from_millis(-(LONG_MAX - 997)); + GPR_ASSERT(x.tv_sec < 0); + GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < 1000000000); + + /* Test general -ve values. */ + for (i = -1; i > -1000 * 1000 * 1000; i *= 7) { + x = gpr_time_from_micros(i); + GPR_ASSERT(x.tv_sec * GPR_US_PER_SEC + x.tv_nsec / GPR_NS_PER_US == i); + x = gpr_time_from_nanos(i); + GPR_ASSERT(x.tv_sec * GPR_NS_PER_SEC + x.tv_nsec == i); + x = gpr_time_from_millis(i); + GPR_ASSERT(x.tv_sec * GPR_MS_PER_SEC + x.tv_nsec / GPR_NS_PER_MS == i); + } +} + +static void test_add_sub(void) { + int i; + int j; + int k; + /* Basic addition and subtraction. */ + for (i = -100; i <= 100; i++) { + for (j = -100; j <= 100; j++) { + for (k = 1; k <= 10000000; k *= 10) { + int sum = i + j; + int diff = i - j; + gpr_timespec it = gpr_time_from_micros(i * k); + gpr_timespec jt = gpr_time_from_micros(j * k); + gpr_timespec sumt = gpr_time_add(it, jt); + gpr_timespec difft = gpr_time_sub(it, jt); + if (gpr_time_cmp(gpr_time_from_micros(sum * k), sumt) != 0) { + fprintf(stderr, "i %d j %d sum %d sumt ", i, j, sum); + ts_to_s(sumt, &to_fp, stderr); + fprintf(stderr, "\n"); + GPR_ASSERT(0); + } + if (gpr_time_cmp(gpr_time_from_micros(diff * k), difft) != 0) { + fprintf(stderr, "i %d j %d diff %d diff ", i, j, diff); + ts_to_s(sumt, &to_fp, stderr); + fprintf(stderr, "\n"); + GPR_ASSERT(0); + } + } + } + } +} + +static void test_overflow(void) { + /* overflow */ + gpr_timespec x = gpr_time_from_micros(1); + do { + x = gpr_time_add(x, x); + } while (gpr_time_cmp(x, gpr_inf_future) < 0); + GPR_ASSERT(gpr_time_cmp(x, gpr_inf_future) == 0); + x = gpr_time_from_micros(-1); + do { + x = gpr_time_add(x, x); + } while (gpr_time_cmp(x, gpr_inf_past) > 0); + GPR_ASSERT(gpr_time_cmp(x, gpr_inf_past) == 0); +} + +static void test_sticky_infinities(void) { + int i; + int j; + int k; + static const gpr_timespec *infinity[] = {&gpr_inf_future, &gpr_inf_past}; + static const gpr_timespec *addend[] = {&gpr_inf_future, &gpr_inf_past, + &gpr_time_0, NULL}; + + /* Infinities are sticky */ + for (i = 0; i != sizeof(infinity) / sizeof(infinity[0]); i++) { + for (j = 0; j != sizeof(addend) / sizeof(addend[0]); j++) { + if (addend[j] == NULL) { + for (k = -200; k <= 200; k++) { + gpr_timespec y = gpr_time_from_micros(k * 100000); + gpr_timespec x = gpr_time_add(*infinity[i], y); + GPR_ASSERT(gpr_time_cmp(x, *infinity[i]) == 0); + x = gpr_time_sub(*infinity[i], y); + GPR_ASSERT(gpr_time_cmp(x, *infinity[i]) == 0); + } + } else { + gpr_timespec x = gpr_time_add(*infinity[i], *addend[j]); + GPR_ASSERT(gpr_time_cmp(x, *infinity[i]) == 0); + x = gpr_time_sub(*infinity[i], *addend[j]); + GPR_ASSERT(gpr_time_cmp(x, *infinity[i]) == 0); + } + } + } +} + +static void test_similar() { + GPR_ASSERT(1 == gpr_time_similar(gpr_inf_future, gpr_inf_future, gpr_time_0)); + GPR_ASSERT(1 == gpr_time_similar(gpr_inf_past, gpr_inf_past, gpr_time_0)); + GPR_ASSERT(0 == gpr_time_similar(gpr_inf_past, gpr_inf_future, gpr_time_0)); + GPR_ASSERT(0 == gpr_time_similar(gpr_inf_future, gpr_inf_past, gpr_time_0)); + GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(10), + gpr_time_from_micros(10), gpr_time_0)); + GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(10), + gpr_time_from_micros(15), + gpr_time_from_micros(10))); + GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(15), + gpr_time_from_micros(10), + gpr_time_from_micros(10))); + GPR_ASSERT(0 == gpr_time_similar(gpr_time_from_micros(10), + gpr_time_from_micros(25), + gpr_time_from_micros(10))); + GPR_ASSERT(0 == gpr_time_similar(gpr_time_from_micros(25), + gpr_time_from_micros(10), + gpr_time_from_micros(10))); +} + +int main(int argc, char *argv[]) { + grpc_test_init(argc, argv); + + test_values(); + test_add_sub(); + test_overflow(); + test_sticky_infinities(); + test_similar(); + return 0; +} -- cgit v1.2.3