/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "test/test.h" #include "lib/cc/torint.h" #include "lib/container/namemap.h" #include "lib/container/namemap_st.h" #include "lib/malloc/malloc.h" #include #include static void test_namemap_empty(void *arg) { (void)arg; namemap_t m; namemap_init(&m); namemap_t m2 = NAMEMAP_INIT(); tt_uint_op(0, OP_EQ, namemap_get_size(&m)); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m, "hello")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m, "hello")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m, "hello128")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m, "")); tt_uint_op(0, OP_EQ, namemap_get_size(&m)); tt_uint_op(0, OP_EQ, namemap_get_size(&m2)); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m2, "hello")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m2, "hello")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m2, "hello128")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m2, "")); tt_uint_op(0, OP_EQ, namemap_get_size(&m)); done: namemap_clear(&m); namemap_clear(&m2); } static void test_namemap_toolong(void *arg) { (void)arg; namemap_t m; char *ok = NULL; char *toolong = NULL; namemap_init(&m); ok = tor_malloc_zero(MAX_NAMEMAP_NAME_LEN+1); memset(ok, 'x', MAX_NAMEMAP_NAME_LEN); toolong = tor_malloc_zero(MAX_NAMEMAP_NAME_LEN+2); memset(toolong, 'x', MAX_NAMEMAP_NAME_LEN+1); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m, ok)); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m, toolong)); unsigned u1 = namemap_get_or_create_id(&m, toolong); unsigned u2 = namemap_get_or_create_id(&m, ok); tt_uint_op(u1, OP_EQ, NAMEMAP_ERR); tt_uint_op(u2, OP_NE, NAMEMAP_ERR); tt_uint_op(u2, OP_EQ, namemap_get_id(&m, ok)); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m, toolong)); tt_str_op(ok, OP_EQ, namemap_get_name(&m, u2)); tt_ptr_op(NULL, OP_EQ, namemap_get_name(&m, u1)); done: tor_free(ok); tor_free(toolong); namemap_clear(&m); } static void test_namemap_blackbox(void *arg) { (void)arg; namemap_t m1, m2; namemap_init(&m1); namemap_init(&m2); unsigned u1 = namemap_get_or_create_id(&m1, "hello"); unsigned u2 = namemap_get_or_create_id(&m1, "world"); tt_uint_op(u1, OP_NE, NAMEMAP_ERR); tt_uint_op(u2, OP_NE, NAMEMAP_ERR); tt_uint_op(u1, OP_NE, u2); tt_uint_op(u1, OP_EQ, namemap_get_id(&m1, "hello")); tt_uint_op(u1, OP_EQ, namemap_get_or_create_id(&m1, "hello")); tt_uint_op(u2, OP_EQ, namemap_get_id(&m1, "world")); tt_uint_op(u2, OP_EQ, namemap_get_or_create_id(&m1, "world")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m1, "HELLO")); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m2, "hello")); unsigned u3 = namemap_get_or_create_id(&m2, "hola"); tt_uint_op(u3, OP_NE, NAMEMAP_ERR); tt_uint_op(NAMEMAP_ERR, OP_EQ, namemap_get_id(&m1, "hola")); tt_uint_op(u3, OP_EQ, namemap_get_or_create_id(&m2, "hola")); tt_uint_op(u3, OP_EQ, namemap_get_id(&m2, "hola")); unsigned int u4 = namemap_get_or_create_id(&m1, "hola"); tt_uint_op(u4, OP_NE, NAMEMAP_ERR); tt_uint_op(u4, OP_EQ, namemap_get_id(&m1, "hola")); tt_uint_op(u3, OP_EQ, namemap_get_id(&m2, "hola")); tt_str_op("hello", OP_EQ, namemap_get_name(&m1, u1)); tt_str_op("world", OP_EQ, namemap_get_name(&m1, u2)); tt_str_op("hola", OP_EQ, namemap_get_name(&m2, u3)); tt_str_op("hola", OP_EQ, namemap_get_name(&m1, u4)); tt_ptr_op(NULL, OP_EQ, namemap_get_name(&m2, u3 + 10)); done: namemap_clear(&m1); namemap_clear(&m2); } static void test_namemap_internals(void *arg) { (void)arg; // This test actually assumes know something about the identity layout. namemap_t m; namemap_init(&m); tt_uint_op(0, OP_EQ, namemap_get_or_create_id(&m, "that")); tt_uint_op(0, OP_EQ, namemap_get_or_create_id(&m, "that")); tt_uint_op(1, OP_EQ, namemap_get_or_create_id(&m, "is")); tt_uint_op(1, OP_EQ, namemap_get_or_create_id(&m, "is")); tt_uint_op(0, OP_EQ, namemap_get_id(&m, "that")); tt_uint_op(0, OP_EQ, namemap_get_id(&m, "that")); tt_uint_op(1, OP_EQ, namemap_get_id(&m, "is")); tt_uint_op(2, OP_EQ, namemap_get_or_create_id(&m, "not")); tt_uint_op(1, OP_EQ, namemap_get_or_create_id(&m, "is")); tt_uint_op(2, OP_EQ, namemap_get_or_create_id(&m, "not")); done: namemap_clear(&m); } static void test_namemap_fmt(void *arg) { (void)arg; namemap_t m = NAMEMAP_INIT(); unsigned a = namemap_get_or_create_id(&m, "greetings"); unsigned b = namemap_get_or_create_id(&m, "earthlings"); tt_str_op(namemap_fmt_name(&m, a), OP_EQ, "greetings"); tt_str_op(namemap_fmt_name(&m, b), OP_EQ, "earthlings"); tt_int_op(a, OP_NE, 100); tt_int_op(b, OP_NE, 100); tt_str_op(namemap_fmt_name(&m, 100), OP_EQ, "{100}"); done: namemap_clear(&m); } #define T(name) \ { #name, test_namemap_ ## name , 0, NULL, NULL } struct testcase_t namemap_tests[] = { T(empty), T(toolong), T(blackbox), T(internals), T(fmt), END_OF_TESTCASES };