#include #include #include "msgpack.h" #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__); \ 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 _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"); \ } 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) \ do { \ int prev_failed_asserts = failed_asserts; \ call; \ assert("Failed Test Condition", \ prev_failed_asserts == failed_asserts, \ 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"); \ failed_test_counter++; \ } else { \ printf("[PASSED] "#test"\n"); \ passed_test_counter++; \ } \ } while(0) int main(void) { TEST(test_internal()); TEST(test_bool()); TEST(test_int()); printf("\n------------------------------\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() { return 0; } #define BODY_SUCCESS_1(t, type) \ { \ assert(t == type, \ logvar(t, msgpack_type_string[t], "%s")); \ } #define BODY_SUCCESS_2(t, a, type, subtype) \ { \ BODY_SUCCESS_1(t, type); \ assert(a == subtype, \ logvar(a, msgpack_type_string[a], "%s")); \ } #define BODY_FAILED_1(t, e, a) \ { \ assert("Failed Call", 0, ;); \ logvar(t, msgpack_type_string[t], "%s"); \ logvar(e, msgpack_error_string[e], "%s"); \ if(e == MSGPACK_ERROR_WRONG_TYPE) \ logvar(a, msgpack_type_string[a], "%s"); \ else logvar(a, "%hhx"); \ return; \ } 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)), { \ logbytes(buf, (_buf), sizeof(_buf)); \ logvar(value, (_value), "%d"); \ printf("\n"); \ }); \ int test_bool() { failed_asserts = 0; bool_template(1, (uint8_t []){0xC2}, true); bool_template(1, (uint8_t []){0xC3}, false); return failed_asserts; } void int_1(uint8_t *buf, size_t size, union mp_int value, enum msgpack_type subtype) { 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")); 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"); \ }); \ 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 []){0xFF}), ((union mp_int){.i=-1}), MSGPACK_INT_SIGNED); return failed_asserts; }