Home | History | Annotate | Download | only in test
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2014 Google, Inc.
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include "AllocationTestHarness.h"
     22 
     23 extern "C" {
     24 #include "osi/include/hash_map.h"
     25 #include "osi/include/osi.h"
     26 }
     27 
     28 class HashMapTest : public AllocationTestHarness {};
     29 
     30 hash_index_t hash_map_fn00(const void *key) {
     31   hash_index_t hash_key = (hash_index_t)key;
     32   return hash_key;
     33 }
     34 
     35 static size_t g_key_free;
     36 void key_free_fn00(UNUSED_ATTR void *data) {
     37   g_key_free++;
     38 }
     39 
     40 static size_t g_data_free;
     41 void data_free_fn00(UNUSED_ATTR void *data) {
     42   g_data_free++;
     43 }
     44 
     45 TEST_F(HashMapTest, test_new_free_simple) {
     46   hash_map_t *hash_map = hash_map_new(5, hash_map_fn00, NULL, NULL, NULL);
     47   ASSERT_TRUE(hash_map != NULL);
     48   hash_map_free(hash_map);
     49 }
     50 
     51 TEST_F(HashMapTest, test_insert_simple) {
     52   hash_map_t *hash_map = hash_map_new(5, hash_map_fn00, NULL, NULL, NULL);
     53   ASSERT_TRUE(hash_map != NULL);
     54 
     55   struct {
     56     const char *key;
     57     const char *data;
     58   } data[] = {
     59     { "0", "zero" },
     60     { "1", "one" },
     61     { "2", "two" },
     62     { "3", "three" },
     63   };
     64 
     65   size_t data_sz = sizeof(data)/sizeof(data[0]);
     66 
     67   for (size_t i = 0; i < data_sz; i++) {
     68     EXPECT_EQ(i, hash_map_size(hash_map));
     69     hash_map_set(hash_map, data[i].key, (void*)data[i].data);
     70     EXPECT_EQ(i + 1, hash_map_size(hash_map));
     71   }
     72 
     73   EXPECT_EQ(data_sz, hash_map_size(hash_map));
     74 
     75   for (size_t i = 0; i < data_sz; i++) {
     76     char *val = (char *)hash_map_get(hash_map, data[i].key);
     77     EXPECT_STREQ(data[i].data, val);
     78   }
     79   EXPECT_EQ(data_sz, hash_map_size(hash_map));
     80 
     81   hash_map_free(hash_map);
     82 }
     83 
     84 TEST_F(HashMapTest, test_insert_same) {
     85   hash_map_t *hash_map = hash_map_new(5, hash_map_fn00, NULL, NULL, NULL);
     86   ASSERT_TRUE(hash_map != NULL);
     87 
     88   struct {
     89     const char *key;
     90     const char *data;
     91   } data[] = {
     92     { "0", "zero" },
     93     { "0", "one" },
     94     { "0", "two" },
     95     { "0", "three" },
     96   };
     97 
     98   size_t data_sz = sizeof(data)/sizeof(data[0]);
     99 
    100   for (size_t i = 0; i < data_sz; i++) {
    101     hash_map_set(hash_map, data[i].key, (void*)data[i].data);
    102     EXPECT_EQ(1U, hash_map_size(hash_map));
    103   }
    104 
    105   EXPECT_EQ(1U, hash_map_size(hash_map));
    106 
    107   for (size_t i = 0; i < data_sz; i++) {
    108     char *val = (char *)hash_map_get(hash_map, data[i].key);
    109     EXPECT_STREQ(data[data_sz - 1].data, val);
    110   }
    111 
    112   hash_map_free(hash_map);
    113 }
    114 
    115 TEST_F(HashMapTest, test_functions) {
    116   hash_map_t *hash_map = hash_map_new(5, hash_map_fn00, key_free_fn00, data_free_fn00, NULL);
    117   ASSERT_TRUE(hash_map != NULL);
    118 
    119   struct {
    120     const char *key;
    121     const char *data;
    122   } data[] = {
    123     { "0", "zero" },
    124     { "1", "one" },
    125     { "2", "two" },
    126     { "3", "three" },
    127   };
    128 
    129   g_data_free = 0;
    130   g_key_free = 0;
    131 
    132   size_t data_sz = sizeof(data)/sizeof(data[0]);
    133 
    134   for (size_t i = 0; i < data_sz; i++) {
    135     EXPECT_EQ(hash_map_size(hash_map), i);
    136     hash_map_set(hash_map, data[i].key, (void*)data[i].data);
    137   }
    138 
    139   EXPECT_EQ(data_sz, hash_map_size(hash_map));
    140   EXPECT_EQ((size_t)0, g_data_free);
    141   EXPECT_EQ((size_t)0, g_key_free);
    142 
    143   for (size_t i = 0; i < data_sz; i++) {
    144     char *val = (char *)hash_map_get(hash_map, data[i].key);
    145     EXPECT_TRUE(val != NULL);
    146     EXPECT_STREQ(data[i].data, val);
    147     hash_map_erase(hash_map, (void*)data[i].key);
    148     EXPECT_EQ(i + 1, g_data_free);
    149     EXPECT_EQ(i + 1, g_key_free);
    150   }
    151 
    152   hash_map_free(hash_map);
    153 }
    154 
    155 struct hash_test_iter_data_s {
    156   const char *key;
    157   const char *data;
    158 } hash_test_iter_data[] = {
    159   { "0", "zero" },
    160   { "1", "one" },
    161   { "2", "two" },
    162   { "3", "three" },
    163   { "elephant", "big" },
    164   { "fox", "medium" },
    165   { "gerbil", "small" },
    166 };
    167 
    168 bool hash_test_iter_ro_cb(hash_map_entry_t *hash_map_entry, void *context) {
    169   const char *key = (const char *)hash_map_entry->key;
    170   char *data = (char *)hash_map_entry->data;
    171   EXPECT_TRUE(data != NULL);
    172 
    173   size_t hash_test_iter_data_sz = sizeof(hash_test_iter_data)/sizeof(hash_test_iter_data[0]);
    174   size_t i;
    175   for (i = 0; i < hash_test_iter_data_sz; i++) {
    176     if (!strcmp(hash_test_iter_data[i].key, key))
    177       break;
    178   }
    179   EXPECT_NE(hash_test_iter_data_sz, i);
    180   EXPECT_EQ(NULL, context);
    181   EXPECT_STREQ(hash_test_iter_data[i].data, data);
    182   return true;
    183 }
    184 
    185 TEST_F(HashMapTest, test_iter) {
    186   hash_map_t *hash_map = hash_map_new(5, hash_map_fn00, key_free_fn00, data_free_fn00, NULL);
    187   ASSERT_TRUE(hash_map != NULL);
    188   g_data_free = 0;
    189   g_key_free = 0;
    190 
    191   size_t hash_test_iter_data_sz = sizeof(hash_test_iter_data)/sizeof(hash_test_iter_data[0]);
    192 
    193   for (size_t i = 0; i < hash_test_iter_data_sz; i++) {
    194     EXPECT_EQ(hash_map_size(hash_map), i);
    195     hash_map_set(hash_map, hash_test_iter_data[i].key, (void*)hash_test_iter_data[i].data);
    196   }
    197 
    198   void *context = NULL;
    199   hash_map_foreach(hash_map, hash_test_iter_ro_cb, context);
    200 
    201   hash_map_free(hash_map);
    202 }
    203