diff options
Diffstat (limited to 'src/fluent-bit/tests/internal/hashtable.c')
-rw-r--r-- | src/fluent-bit/tests/internal/hashtable.c | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/src/fluent-bit/tests/internal/hashtable.c b/src/fluent-bit/tests/internal/hashtable.c new file mode 100644 index 000000000..a7066aeb1 --- /dev/null +++ b/src/fluent-bit/tests/internal/hashtable.c @@ -0,0 +1,413 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include <fluent-bit/flb_info.h> +#include <fluent-bit/flb_macros.h> +#include <fluent-bit/flb_hash_table.h> + +#include "flb_tests_internal.h" + +struct map { + char *key; + char *val; +}; + +struct map entries[] = { + {"key_0", "val_0"}, + {"key_1", "val_1"}, {"key_2", "val_2"}, {"key_3", "val_3"}, + {"key_4", "val_4"}, {"key_5", "val_5"}, {"key_6", "val_6"}, + {"key_7", "val_7"}, {"key_8", "val_8"}, {"key_9", "val_9"}, + {"key_10", "val_10"}, {"key_11", "val_11"}, {"key_12", "val_12"}, + {"key_13", "val_13"}, {"key_14", "val_14"}, {"key_15", "val_15"}, + {"key_16", "val_16"}, {"key_17", "val_17"}, {"key_18", "val_18"}, + {"key_19", "val_19"}, {"key_20", "val_20"}, {"key_21", "val_21"}, + {"key_22", "val_22"}, {"key_23", "val_23"}, {"key_24", "val_24"}, + {"key_25", "val_25"}, {"key_26", "val_26"}, {"key_27", "val_27"}, + {"key_28", "val_28"}, {"key_29", "val_29"}, {"key_30", "val_30"}, + {"key_31", "val_31"}, {"key_32", "val_32"}, {"key_33", "val_33"}, + {"key_34", "val_34"}, {"key_35", "val_35"}, {"key_36", "val_36"}, + {"key_37", "val_37"}, {"key_38", "val_38"}, {"key_39", "val_39"}, + {"key_40", "val_40"}, {"key_41", "val_41"}, {"key_42", "val_42"}, + {"key_43", "val_43"}, {"key_44", "val_44"}, {"key_45", "val_45"}, + {"key_46", "val_46"}, {"key_47", "val_47"}, {"key_48", "val_48"}, + {"key_49", "val_49"}, {"key_50", "val_50"}, {"key_51", "val_51"}, + {"key_52", "val_52"}, {"key_53", "val_53"}, {"key_54", "val_54"}, + {"key_55", "val_55"}, {"key_56", "val_56"}, {"key_57", "val_57"}, + {"key_58", "val_58"}, {"key_59", "val_59"}, {"key_60", "val_60"}, + {"key_61", "val_61"}, {"key_62", "val_62"}, {"key_63", "val_63"}, + {"key_64", "val_64"}, {"key_65", "val_65"}, {"key_66", "val_66"}, + {"key_67", "val_67"}, {"key_68", "val_68"}, {"key_69", "val_69"}, + {"key_70", "val_70"}, {"key_71", "val_71"}, {"key_72", "val_72"}, + {"key_73", "val_73"}, {"key_74", "val_74"}, {"key_75", "val_75"}, + {"key_76", "val_76"}, {"key_77", "val_77"}, {"key_78", "val_78"}, + {"key_79", "val_79"}, {"key_80", "val_80"}, {"key_81", "val_81"}, + {"key_82", "val_82"}, {"key_83", "val_83"}, {"key_84", "val_84"}, + {"key_85", "val_85"}, {"key_86", "val_86"}, {"key_87", "val_87"}, + {"key_88", "val_88"}, {"key_89", "val_89"}, {"key_90", "val_90"}, + {"key_91", "val_91"}, {"key_92", "val_92"}, {"key_93", "val_93"}, + {"key_94", "val_94"}, {"key_95", "val_95"}, {"key_96", "val_96"}, + {"key_97", "val_97"}, {"key_98", "val_98"}, {"key_99", "val_99"}, + + /* override some values */ + {"key_67", "val_AA"}, {"key_68", "val_BB"}, {"key_69", "val_CC"}, + +}; + +static int ht_add(struct flb_hash_table *ht, char *key, char *val) +{ + int id; + int idn; + int klen; + int vlen; + char *out_buf; + size_t out_size; + + klen = strlen(key); + vlen = strlen(val); + + /* Insert the key value */ + id = flb_hash_table_add(ht, key, klen, val, vlen); + TEST_CHECK(id >=0); + + /* Retrieve the value of the recently added key */ + idn = flb_hash_table_get(ht, key, klen, (void *) &out_buf, &out_size); + TEST_CHECK(idn == id); + TEST_CHECK(strcmp(out_buf, val) == 0); + + return id; +} + +void test_create_zero() +{ + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 0, -1); + TEST_CHECK(ht == NULL); +} + +/* bug 355 */ +void test_single() +{ + int ret; + const char *out_buf; + size_t out_size; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 1, -1); + TEST_CHECK(ht != NULL); + + ret = ht_add(ht, "key", "value"); + TEST_CHECK(ret != -1); + + ret = flb_hash_table_get(ht, "key", 3, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "NOT", 3, (void *) &out_buf, &out_size); + TEST_CHECK(ret == -1); + + flb_hash_table_destroy(ht); +} + +void test_small_table() +{ + int i; + struct map *m; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 8, -1); + TEST_CHECK(ht != NULL); + + for (i = 0; i < sizeof(entries) / sizeof(struct map); i++) { + m = &entries[i]; + ht_add(ht, m->key, m->val); + } + + flb_hash_table_destroy(ht); +} + +void test_medium_table() +{ + int i; + struct map *m; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 8, -1); + TEST_CHECK(ht != NULL); + + for (i = 0; i < sizeof(entries) / sizeof(struct map); i++) { + m = &entries[i]; + ht_add(ht, m->key, m->val); + } + + flb_hash_table_destroy(ht); +} + +void test_chaining() +{ + int i; + int inserts = 0; + int count; + int chains = 0; + struct map *m; + struct mk_list *head; + struct flb_hash_table_chain *table; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 8, -1); + TEST_CHECK(ht != NULL); + + for (i = 0; i < 8; i++) { + m = &entries[i]; + ht_add(ht, m->key, m->val); + inserts++; + } + + for (i = 0; i < ht->size; i++) { + table = &ht->table[i]; + count = 0; + mk_list_foreach(head, &table->chains) { + count++; + } + TEST_CHECK(count == table->count); + + if (count > 0) { + chains++; + } + } + + /* Tests diff between total, new minus 3 overrides */ + TEST_CHECK(chains == inserts - 3); + flb_hash_table_destroy(ht); +} + +void test_delete_all() +{ + int i; + int ret; + int count; + int not_found = 0; + int total = 0; + struct map *m; + struct flb_hash_table_chain *table; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 8, -1); + TEST_CHECK(ht != NULL); + + total = sizeof(entries) / sizeof(struct map); + for (i = 0; i < total; i++) { + m = &entries[i]; + ht_add(ht, m->key, m->val); + } + + for (i = total - 1; i >= 0; i--) { + m = &entries[i]; + ret = flb_hash_table_del(ht, m->key); + if (ret == -1) { + not_found++; + } + } + + count = 0; + for (i = 0; i < ht->size; i++) { + table = &ht->table[i]; + count += table->count; + } + + TEST_CHECK(count == 0); + flb_hash_table_destroy(ht); +} + +void test_random_eviction() +{ + int ret; + const char *out_buf; + size_t out_size; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_RANDOM, 8, 1); + TEST_CHECK(ht != NULL); + + ret = ht_add(ht, "key1", "value1"); + TEST_CHECK(ret != -1); + + ret = ht_add(ht, "key2", "value2"); + TEST_CHECK(ret != -1); + + ret = flb_hash_table_get(ht, "key1", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret == -1); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + flb_hash_table_destroy(ht); +} + +void test_less_used_eviction() +{ + int ret; + const char *out_buf; + size_t out_size; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_LESS_USED, 8, 2); + TEST_CHECK(ht != NULL); + + ret = ht_add(ht, "key1", "value1"); + TEST_CHECK(ret != -1); + + ret = ht_add(ht, "key2", "value2"); + TEST_CHECK(ret != -1); + + ret = flb_hash_table_get(ht, "key1", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = ht_add(ht, "key3", "value3"); + TEST_CHECK(ret != -1); + + ret = flb_hash_table_get(ht, "key3", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key1", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret == -1); + + flb_hash_table_destroy(ht); +} + +void test_older_eviction() +{ + int ret; + const char *out_buf; + size_t out_size; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_OLDER, 8, 2); + TEST_CHECK(ht != NULL); + + ret = ht_add(ht, "key2", "value2"); + TEST_CHECK(ret != -1); + + ret = ht_add(ht, "key1", "value1"); + TEST_CHECK(ret != -1); + + ret = flb_hash_table_get(ht, "key1", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = ht_add(ht, "key3", "value3"); + TEST_CHECK(ret != -1); + + ret = flb_hash_table_get(ht, "key3", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret == -1); + + ret = flb_hash_table_get(ht, "key1", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + + flb_hash_table_destroy(ht); +} + +void test_pointer() +{ + int ret; + const char *out_buf; + size_t out_size; + struct flb_hash_table *ht; + + char *val1 = "val1"; + char *val2 = "val2"; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 512, 0); + TEST_CHECK(ht != NULL); + + ret = flb_hash_table_add(ht, "key1", 4, (void *) val1, 0); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_add(ht, "key2", 4, (void *) val2, 0); + TEST_CHECK(ret >= 0); + + ret = flb_hash_table_get(ht, "key2", 4, (void *) &out_buf, &out_size); + TEST_CHECK(ret >= 0); + TEST_CHECK((void *) out_buf == (void *) val2); + + out_buf = flb_hash_table_get_ptr(ht, "key2", 4); + TEST_CHECK((void *) out_buf == (void *) val2); + + ret = flb_hash_table_del_ptr(ht, "key2", 4, (void *) out_buf); + TEST_CHECK(ret == 0); + + TEST_CHECK(ht->total_count == 1); + flb_hash_table_destroy(ht); +} + +void test_hash_exists() +{ + int i; + int id; + int ret; + int len; + struct map *m; + uint64_t hash; + struct flb_hash_table *ht; + + ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, 1000, 0); + TEST_CHECK(ht != NULL); + + for (i = 0; i < sizeof(entries) / sizeof(struct map); i++) { + m = &entries[i]; + id = ht_add(ht, m->key, m->val); + TEST_CHECK(id >= 0); + + len = strlen(m->key); + hash = cfl_hash_64bits(m->key, len); + + ret = flb_hash_table_exists(ht, hash); + TEST_CHECK(ret == FLB_TRUE); + } + + for (i = 0; i < sizeof(entries) / sizeof(struct map); i++) { + m = &entries[i]; + + /* get hash */ + len = strlen(m->key); + hash = cfl_hash_64bits(m->key, len); + + /* delete */ + ret = flb_hash_table_del(ht, m->key); + + ret = flb_hash_table_exists(ht, hash); + TEST_CHECK(ret == FLB_FALSE);; + } + + flb_hash_table_destroy(ht); +} + +TEST_LIST = { + { "zero_size", test_create_zero }, + { "single", test_single }, + { "small_table", test_small_table }, + { "medium_table", test_medium_table }, + { "chaining_count", test_chaining }, + { "delete_all", test_delete_all }, + { "random_eviction", test_random_eviction }, + { "less_used_eviction", test_less_used_eviction }, + { "older_eviction", test_older_eviction }, + { "pointer", test_pointer }, + { "hash_exists", test_hash_exists}, + { 0 } +}; |