From a19e8244dd57b161858c3a793b255a0d72035ebc Mon Sep 17 00:00:00 2001 From: Yorhel Date: Mon, 18 Aug 2014 15:39:17 +0200 Subject: Add test for ypc_val/ypc_get functions + fix two bugs found with it --- Makefile.am | 4 +- lib/util/byteswap.h | 2 +- lib/val/ypc_add_int.c | 8 ++-- lib/ypc.h | 4 +- test/hex.c | 5 +++ test/val.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 test/val.c diff --git a/Makefile.am b/Makefile.am index 1d2f745..369aa70 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,7 +51,7 @@ EXTRA_DIST=\ include_HEADERS=lib/ypc.h -TESTS=test/str2sockaddr test/hex test/val_parse +TESTS=test/str2sockaddr test/hex test/val_parse test/val check_PROGRAMS=$(TESTS) test_str2sockaddr_SOURCES=test/str2sockaddr.c lib/util/str2sockaddr.c lib/util/str2sockaddr_ip.c lib/util/str2sockaddr_port.c test_str2sockaddr_CFLAGS=$(AM_CFLAGS) @@ -59,6 +59,8 @@ test_hex_SOURCES=test/hex.c lib/util/hex2bin.c lib/util/bin2hex.c test_hex_CFLAGS=$(AM_CFLAGS) test_val_parse_SOURCES=test/val_parse.c test_val_parse_LDADD=libypc.la +test_val_SOURCES=test/val.c +test_val_LDADD=libypc.la MOSTLYCLEANFILES=ypc.dll ypc.lib ypc.exp ypc.pdb ypc.ilk *.obj ACLOCAL_AMFLAGS=-I ac diff --git a/lib/util/byteswap.h b/lib/util/byteswap.h index 99981a6..13fbc23 100644 --- a/lib/util/byteswap.h +++ b/lib/util/byteswap.h @@ -31,7 +31,7 @@ static inline uint32_t ypc__swap32(uint32_t v) { } -static inline uint32_t ypc__swap64(uint64_t v) { +static inline uint64_t ypc__swap64(uint64_t v) { #if defined(_MSC_VER) return _byteswap_uint64(v); #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) diff --git a/lib/val/ypc_add_int.c b/lib/val/ypc_add_int.c index bb31983..68095fe 100644 --- a/lib/val/ypc_add_int.c +++ b/lib/val/ypc_add_int.c @@ -5,20 +5,20 @@ YPC_EXPORT int ypc_add_int(ypc_val *v, int64_t i) { if(v->size < v->len + 9 && ypc_val_resize(v, v->len+9) != 0) return -1; if(i >= INT8_MIN && i <= INT8_MAX) { - v->buf[v->len++] = 3; + v->buf[v->len++] = YPCT_INT8; v->buf[v->len++] = i; } else if(i >= INT16_MIN && i <= INT16_MAX) { - v->buf[v->len++] = 4; + v->buf[v->len++] = YPCT_INT16; uint16_t n = ypc__hn16(i); memcpy(v->buf+v->len, &n, 2); v->len += 2; } else if(i >= INT32_MIN && i <= INT32_MAX) { - v->buf[v->len++] = 5; + v->buf[v->len++] = YPCT_INT32; uint32_t n = ypc__hn32(i); memcpy(v->buf+v->len, &n, 4); v->len += 4; } else { - v->buf[v->len++] = 6; + v->buf[v->len++] = YPCT_INT64; uint64_t n = ypc__hn64(i); memcpy(v->buf+v->len, &n, 8); v->len += 8; diff --git a/lib/ypc.h b/lib/ypc.h index ee71df5..2885ab4 100644 --- a/lib/ypc.h +++ b/lib/ypc.h @@ -145,8 +145,8 @@ static inline ypc_get ypc_iter_next(ypc_iter *i) { ypc_get g = {i->buf}; * *v->buf == 9, which is much cheaper than a function call. A similar * optimization is possible when using ypc_get_type() in a switch statement. */ -static inline ypc_type ypc_get_type(ypc_get *v) { - switch(*v->buf) { +static inline ypc_type ypc_get_type(ypc_get v) { + switch(*v.buf) { case 0: return YPC_NULL; case 1: diff --git a/test/hex.c b/test/hex.c index df3ec9f..9531948 100644 --- a/test/hex.c +++ b/test/hex.c @@ -1,5 +1,10 @@ #include "../lib/internal.h" +#ifdef NDEBUG +#undef NDEBUG +#endif +#include + int main(int argc, char **argv) { #define E(str, len) do {\ uint8_t buf[len];\ diff --git a/test/val.c b/test/val.c new file mode 100644 index 0000000..743a977 --- /dev/null +++ b/test/val.c @@ -0,0 +1,119 @@ +#include "../lib/ypc.h" +#include "../lib/util/bin2hex.c" +#include +#include + +#ifdef NDEBUG +#undef NDEBUG +#endif +#include + + +#define T_MSG\ + C("\x0a", ypc_add_array(v))\ + C("\x00", ypc_add_null(v))\ + C("\x02", ypc_add_bool(v, true))\ + C("\x01", ypc_add_bool(v, false))\ + C("\x03\x01", ypc_add_int(v, 1))\ + C("\x03\xff", ypc_add_int(v, -1))\ + C("\x04\x01\xf4", ypc_add_int(v, 500))\ + C("\x04\xfe\x0c", ypc_add_int(v, -500))\ + C("\x05\x00\x07\xa1\x20", ypc_add_int(v, 500000))\ + C("\x05\xff\xf8\x5e\xe0", ypc_add_int(v, -500000))\ + C("\x06\x7f\xff\xff\xff\xff\xff\xff\xff", ypc_add_int(v, INT64_MAX))\ + C("\x06\x80\x00\x00\x00\x00\x00\x00\x00", ypc_add_int(v, INT64_MIN))\ + C("\x07\x00\x00\x00\x00\x00\x00\x00\x00", ypc_add_float(v, 0.0))\ + C("\x07\x40\x09\x21\xfb\x54\x44\x2d\x18", ypc_add_float(v, M_PI))\ + C("\x07\x7f\xf0\x00\x00\x00\x00\x00\x00", ypc_add_float(v, HUGE_VAL))\ + C("\x0b", ypc_add_map(v))\ + C("\x0c", ypc_add_close(v))\ + C("\x0b", ypc_add_map(v))\ + C("\x09""abc\0", ypc_add_text(v, "abc"))\ + C("\x09""foob\0", ypc_add_textn(v, "foobar", 4))\ + C("\x08\0\0\5\0\1\2\3\xff", ypc_add_bin(v, (const uint8_t *)"\0\1\2\3\xff", 5))\ + C("\x08\0\0\0", ypc_add_bin(v, (const uint8_t *)"", 0))\ + C("\x0c", ypc_add_close(v))\ + C("\x0c", ypc_add_close(v)) + +#define C(s, x) s +static const char msg[] = T_MSG; +#undef C + +#define STR(x) #x + +static void t_create(ypc_val *v) { + assert(ypc_val_init(v, 32) == 0); +#define C(s, x) do {\ + size_t l = v->len;\ + if(x != 0) {\ + fputs(STR(x)" failed\n", stderr);\ + exit(1);\ + }\ + l = v->len - l;\ + if(l != sizeof s - 1 || memcmp(v->buf + v->len - l, s, l) != 0) {\ + char exp[2*sizeof s];\ + ypc__bin2hex(exp, (const uint8_t *)s, sizeof s - 1);\ + char got[2*l+1];\ + ypc__bin2hex(got, v->buf + v->len - l, l);\ + fprintf(stderr, "%s produced wrong output\n Got: %s\n Expected: %s\n", STR(x), got, exp);\ + exit(1);\ + }\ + } while(0); + T_MSG +#undef C + + assert(v->len == sizeof msg - 1); + assert(memcmp(v->buf, msg, v->len) == 0); +} + + +static void t_read(ypc_get g) { + assert(ypc_get_type(g) == YPC_ARRAY); + assert(ypc_get_size(g) == sizeof msg - 1); + ypc_iter i = ypc_get_iter(g); + ypc_iter m; + +#define V(i, t, x) do {\ + assert(!ypc_iter_end(i));\ + g = ypc_iter_next(&i);\ + assert(ypc_get_type(g) == t);\ + assert(x);\ + } while(0) + + V(i, YPC_NULL, 1); + V(i, YPC_BOOL, ypc_get_bool(g) == true); + V(i, YPC_BOOL, ypc_get_bool(g) == false); + V(i, YPC_INT, ypc_get_int(g) == 1); + V(i, YPC_INT, ypc_get_int(g) == -1); + V(i, YPC_INT, ypc_get_int(g) == 500); + V(i, YPC_INT, ypc_get_int(g) == -500); + V(i, YPC_INT, ypc_get_int(g) == 500000); + V(i, YPC_INT, ypc_get_int(g) == -500000); + V(i, YPC_INT, ypc_get_int(g) == INT64_MAX); + V(i, YPC_INT, ypc_get_int(g) == INT64_MIN); + V(i, YPC_FLOAT, ypc_get_float(g) == 0.0); + V(i, YPC_FLOAT, ypc_get_float(g) == M_PI); + V(i, YPC_FLOAT, ypc_get_float(g) == HUGE_VAL); + + V(i, YPC_MAP, ypc_iter_end(ypc_get_iter(g))); + + V(i, YPC_MAP, 1); + m = ypc_get_iter(g); + V(m, YPC_TEXT, strcmp(ypc_get_text(g), "abc") == 0); + V(m, YPC_TEXT, strcmp(ypc_get_text(g), "foob") == 0); + V(m, YPC_BIN, ypc_get_bin_len(g) == 5 && memcmp(ypc_get_bin(g), "\0\1\2\3\xff", 5) == 0); + V(m, YPC_BIN, ypc_get_bin_len(g) == 0); + assert(ypc_iter_end(m)); +#undef V + + assert(ypc_iter_end(i)); +} + + +int main(int argc, char **argv) { + ypc_val v; + t_create(&v); + t_read(ypc_val_get(&v)); + ypc_val_free(&v); + return 0; +} -- cgit v1.2.3