From 25792c81d9e4c1667ca6bcac28ae7b49afff90a1 Mon Sep 17 00:00:00 2001 From: kartofen Date: Fri, 18 Apr 2025 23:17:29 +0300 Subject: floats, raws, more testing --- test.c | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 220 insertions(+), 44 deletions(-) (limited to 'test.c') diff --git a/test.c b/test.c index f7e821a..4ee5298 100644 --- a/test.c +++ b/test.c @@ -1,39 +1,72 @@ #include #include +#include +#include +#include #include "msgpack.h" -#define _IN " " +// fprintf to logfp, but doesn't +// move the file position indicator +static FILE *logfp; +#define logprintf(...) \ + do { \ + long pos = ftell(logfp); \ + fseek(logfp, 0, SEEK_END); \ + fprintf(logfp, __VA_ARGS__); \ + fseek(logfp, pos, SEEK_SET); \ + } while(0) +#define _IN " " #define _assert1(c) _assert2(c, ;) #define _assert2(c, b) _assert3(#c, c, b) #define _assert3(n, c, b) \ do { \ if(!(c)) { \ - printf("Assertion error '%s' in %s:%d\n", n, __FILE__, __LINE__); \ + logprintf("Assertion error '%s' in %s:%d\n", n, __FILE__, __LINE__); \ b; \ failed_asserts++; \ } \ } while (0); #define _logvar2(v, fmt) _logvar3(v, v, fmt) -#define _logvar3(n, v, fmt) printf(_IN #n" = "fmt"\n", v) +#define _logvar3(n, v, fmt) logprintf(_IN #n" = "fmt"\n", v) #define _logbuf3(b, l, fmt) _logbuf4(b, b, l, fmt) -#define _logbuf4(n, b, l, fmt) \ - do { \ - printf(_IN #n" = { "fmt, b[0]); \ - for(size_t i = 1; i < l; i++) printf(", "fmt, b[i]); \ - printf(" }\n"); \ +#define _logbuf4(n, b, l, fmt) \ + do { \ + logprintf(_IN #n" = { "fmt, b[0]); \ + for(size_t i = 1; i < l; i++) \ + logprintf(", "fmt, b[i]); \ + logprintf(" }\n"); \ } while(0) - #define OVERLOAD_MACRO_4(_1, _2, _3, _4, NAME, ...) NAME #define assert(...) OVERLOAD_MACRO_4(__VA_ARGS__, _, _assert3, _assert2, _assert1) (__VA_ARGS__) #define logvar(...) OVERLOAD_MACRO_4(__VA_ARGS__, _, _logvar3, _logvar2, _) (__VA_ARGS__) #define logbuf(...) OVERLOAD_MACRO_4(__VA_ARGS__, _logbuf4, _logbuf3, _, _) (__VA_ARGS__) #define logbytes(...) logbuf(__VA_ARGS__, "0x%hhx") -#define make_template(call, body) \ +// copy source fp from its file position indicator +// to dest fp using sendfile (logfprintf is for that) +static int fsendfile(FILE *dest, FILE *source) +{ + fflush(dest); + fflush(source); + + long cur = ftell(source); + fseek(source, 0, SEEK_END); + long end = ftell(source); + + int fd = fileno(source); + return sendfile(fileno(dest), fd, &cur, end - cur); +} + + +static int passed_test_counter; +static int failed_test_counter; +static int failed_asserts; + +#define check_condition(call, body) \ do { \ int prev_failed_asserts = failed_asserts; \ call; \ @@ -42,42 +75,48 @@ body); \ } while(0) -static int passed_test_counter; -static int failed_test_counter; -static int failed_asserts; - -int test_internal(); -int test_bool(); -int test_int(); - #define TEST(test) \ do { \ - if(test) { \ - printf("[FAILED] "#test"\n"); \ + int r = 0; \ + if((r = test)) { \ + printf("[FAILED] "#test \ + " with %d errors\n", r); \ failed_test_counter++; \ } else { \ printf("[PASSED] "#test"\n"); \ passed_test_counter++; \ } \ + fsendfile(stdout, logfp) \ + ? printf("\n") : 0; \ } while(0) +int test_internal(); +int test_bool(); +int test_int(); +int test_float(); +int test_raw(); +int test_compound(); + int main(void) { + logfp = tmpfile(); + TEST(test_internal()); TEST(test_bool()); TEST(test_int()); + TEST(test_float()); + TEST(test_raw()); + TEST(test_compound()); - printf("\n------------------------------\n"); + printf("------------------------------\n"); printf("PASSED %d/%d tests, (%.1f%%)\n", passed_test_counter, failed_test_counter + passed_test_counter, 100.0f * passed_test_counter / (failed_test_counter + passed_test_counter)); - return 0; -} -int test_internal() -{ + + fclose(logfp); return 0; } @@ -90,10 +129,10 @@ int test_internal() #define BODY_SUCCESS_2(t, a, type, subtype) \ { \ BODY_SUCCESS_1(t, type); \ - assert(a == subtype, \ + assert((int)a == (int)subtype, \ logvar(a, msgpack_type_string[a], "%s")); \ } - + #define BODY_FAILED_1(t, e, a) \ { \ assert("Failed Call", 0, ;); \ @@ -105,23 +144,30 @@ int test_internal() return; \ } +int test_internal() +{ + failed_asserts = 0; + + return failed_asserts; +} void bool_1(uint8_t *buf, size_t size, bool value) { uint8_t b[1] = {0}; bool v; - + MSGPACK_CHECK2(msgpack_read_bool(&msgpack_init(buf, size, NULL), &v), (t, e, a), BODY_SUCCESS_1(t, MSGPACK_BOOL), BODY_FAILED_1(t, e, a)); assert(v == value, logvar(v, "%d")); - + MSGPACK_CHECK2(msgpack_write_bool(&msgpack_init(b, size, NULL), &value), (t, e, a), BODY_SUCCESS_1(t, MSGPACK_BOOL), BODY_FAILED_1(t, e, a)); assert(memcmp(buf, b, size) == 0, logbytes(b, size)); } - + #define bool_template(n, _buf, _value) \ - make_template(bool_##n((_buf), sizeof(_buf), (_value)), { \ + check_condition(bool_##n((_buf), sizeof(_buf), (_value)), \ + { \ logbytes(buf, (_buf), sizeof(_buf)); \ logvar(value, (_value), "%d"); \ printf("\n"); \ @@ -141,36 +187,166 @@ void int_1(uint8_t *buf, size_t size, union mp_int value, enum msgpack_type subt { uint8_t b[9] = {0}; union mp_int v; - + MSGPACK_CHECK2(msgpack_read_int(&msgpack_init(buf, size, NULL), &v), (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_INT, subtype), BODY_FAILED_1(t, e, a)); - assert(v.i == value.i, logvar(v.u, "%lld")); - + assert(v.u == value.u, logvar(v.u, "%"PRIu64)); + MSGPACK_CHECK2(msgpack_write_int(&msgpack_init(b, size, NULL), &value, subtype), (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_INT, subtype), BODY_FAILED_1(t, e, a)); assert(memcmp(buf, b, size) == 0, logbytes(b, size)); } -#define int_template(n, _buf, _value, _subtype) \ - make_template(int_##n((_buf), sizeof(_buf), (_value), (_subtype)), { \ - logbytes(buf, (_buf), sizeof(_buf)); \ - if((_subtype) == MSGPACK_INT_SIGNED) \ - logvar(value.i, (_value).i, "%lld"); \ - else logvar(value.u, (_value).u, "%lld"); \ - logvar(subtype, msgpack_type_string[(_subtype)], "%s"); \ - printf("\n"); \ - }); \ +#define int_template(n, _buf, _value, _subtype) \ + check_condition(int_##n((_buf), sizeof(_buf), (_value), (_subtype)), \ + { \ + logbytes(buf, (_buf), sizeof(_buf)); \ + if((_subtype) == MSGPACK_INT_SIGNED) \ + logvar(value.i, (_value).i, "%"PRIi64); \ + else logvar(value.u, (_value).u, "%"PRIu64); \ + logvar(subtype, msgpack_type_string[(_subtype)], "%s"); \ + printf("\n"); \ + }); \ int test_int() { failed_asserts = 0; - + int_template(1, ((uint8_t []){0xD3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01}), ((union mp_int){.i=0x0100000000000201}), MSGPACK_INT_SIGNED); + int_template(1, ((uint8_t []){0xCF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01}), + ((union mp_int){.u=0x0100000000000201}), MSGPACK_INT_UNSIGNED); int_template(1, ((uint8_t []){0xFF}), ((union mp_int){.i=-1}), MSGPACK_INT_SIGNED); return failed_asserts; } + +// void float_1(uint8_t *buf, size_t size, union mp_float value, enum msgpack_type subtype) +// { +// uint8_t b[9] = {0}; +// union mp_float v; + +// MSGPACK_CHECK2(msgpack_read_float(&msgpack_init(buf, size, NULL), &v), +// (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_FLOAT, subtype), +// BODY_FAILED_1(t, e, a)); + +// if(subtype == MSGPACK_FLOAT_32) { +// assert(v.f == value.f, logvar(v.f, "%f")); +// } else { +// assert(v.d == value.d, logvar(v.d, "%f")); +// } + +// MSGPACK_CHECK2(msgpack_write_float(&msgpack_init(b, size, NULL), &value, subtype), +// (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_FLOAT, subtype), +// BODY_FAILED_1(t, e, a)); +// assert(memcmp(buf, b, size) == 0, logbytes(b, size)); +// } + +// #define float_template(n, _buf, _value, _subtype) \ +// check_condition(float_##n((_buf), sizeof(_buf), (_value), (_subtype)), \ +// { \ +// logbytes(buf, (_buf), sizeof(_buf)); \ +// if((_subtype) == MSGPACK_FLOAT_32) \ +// logvar(value.f, (_value).f, "%f"); \ +// else logvar(value.d, (_value).d, "%f"); \ +// logvar(subtype, msgpack_type_string[(_subtype)], "%s"); \ +// printf("\n"); \ +// }); + +void float_2(union mp_float value, enum msgpack_type subtype) +{ + uint8_t b[9] = {0}; + size_t size = 9; + union mp_float v; + + MSGPACK_CHECK2(msgpack_write_float(&msgpack_init(b, size, NULL), &value, subtype), + (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_FLOAT, subtype), + BODY_FAILED_1(t, e, a)); + + MSGPACK_CHECK2(msgpack_read_float(&msgpack_init(b, size, NULL), &v), + (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_FLOAT, subtype), + BODY_FAILED_1(t, e, a)); + + if(subtype == MSGPACK_FLOAT_32) { + assert(v.f == value.f, logvar(v.f, "%f")); + logbytes(b, 5); + } else { + assert(v.d == value.d, logvar(v.d, "%f")); + logbytes(b, 9); + } +} + +#define float_template(n, _value, _subtype) \ + check_condition(float_##n((_value), (_subtype)), \ + { \ + if((_subtype) == MSGPACK_FLOAT_32) \ + logvar(value.f, (_value).f, "%f"); \ + else logvar(value.d, (_value).d, "%f"); \ + logvar(subtype, \ + msgpack_type_string[(_subtype)], "%s"); \ + }) + +#include +int test_float() +{ + failed_asserts = 0; + + float_template(2, ((union mp_float){.f=-1.7}), MSGPACK_FLOAT_32); + float_template(2, ((union mp_float){.f=FLT_MAX}), MSGPACK_FLOAT_32); + float_template(2, ((union mp_float){.f=FLT_MIN}), MSGPACK_FLOAT_32); + float_template(2, ((union mp_float){.d=DBL_MAX}), MSGPACK_FLOAT_64); + float_template(2, ((union mp_float){.d=DBL_MIN}), MSGPACK_FLOAT_64); + + return failed_asserts; +} + +void raw_1(uint8_t *bin, size_t size, struct mp_bin b) +{ + msgpack_t pack = msgpack_init(bin, size, NULL); + struct mp_bin v = {0}; + + MSGPACK_CHECK2(msgpack_read_raw(&pack, &v), (t, e, a), + BODY_SUCCESS_2(t, a, MSGPACK_RAW, MSGPACK_RAW_STRING), + BODY_FAILED_1(t, e, a)); + + assert(v.size == b.size, logvar(v.size, "%z")); + assert(memcmp(v.bin, b.bin, v.size) == 0, logbytes(v.bin, v.size)); + +} + +int test_raw() +{ + failed_asserts = 0; + check_condition(raw_1("\xa5hello", 6, + (struct mp_bin){.size = 5, .bin = "hello"}), ); + check_condition(raw_1("\xd9\x05hello", 7, + (struct mp_bin){.size = 5, .bin = "hello"}), ); + return failed_asserts; +} + +void compound_1() +{ + uint8_t bin[] = {0x0A, 0xCF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01}; + msgpack_t pack = msgpack_init(bin, sizeof(bin), NULL); + union mp_int v = {0}; + + MSGPACK_CHECK2(msgpack_read_int(&pack, &v), + (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_INT, MSGPACK_INT_UNSIGNED), + BODY_FAILED_1(t, e, a)); + assert(v.i == 10, logvar(v.u, "%"PRIi64)); + + MSGPACK_CHECK2(msgpack_read_int(&pack, &v), + (t, e, a), BODY_SUCCESS_2(t, a, MSGPACK_INT, MSGPACK_INT_UNSIGNED), + BODY_FAILED_1(t, e, a)); + assert(v.i == 0x0100000000000201, logvar(v.u, "%"PRIi64)); +} + +int test_compound() +{ + failed_asserts = 0; + compound_1(); + return failed_asserts; +} -- cgit v1.2.3