LCOV - code coverage report
Current view: top level - test - test-hashmap-plain.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 715 718 99.6 %
Date: 2019-08-22 15:41:25 Functions: 39 39 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include "alloc-util.h"
       4             : #include "hashmap.h"
       5             : #include "log.h"
       6             : #include "nulstr-util.h"
       7             : #include "stdio-util.h"
       8             : #include "string-util.h"
       9             : #include "strv.h"
      10             : #include "time-util.h"
      11             : #include "tests.h"
      12             : 
      13             : void test_hashmap_funcs(void);
      14             : 
      15           1 : static void test_hashmap_replace(void) {
      16             :         Hashmap *m;
      17             :         char *val1, *val2, *val3, *val4, *val5, *r;
      18             : 
      19           1 :         log_info("/* %s */", __func__);
      20             : 
      21           1 :         m = hashmap_new(&string_hash_ops);
      22             : 
      23           1 :         val1 = strdup("val1");
      24           1 :         assert_se(val1);
      25           1 :         val2 = strdup("val2");
      26           1 :         assert_se(val2);
      27           1 :         val3 = strdup("val3");
      28           1 :         assert_se(val3);
      29           1 :         val4 = strdup("val4");
      30           1 :         assert_se(val4);
      31           1 :         val5 = strdup("val5");
      32           1 :         assert_se(val5);
      33             : 
      34           1 :         hashmap_put(m, "key 1", val1);
      35           1 :         hashmap_put(m, "key 2", val2);
      36           1 :         hashmap_put(m, "key 3", val3);
      37           1 :         hashmap_put(m, "key 4", val4);
      38             : 
      39           1 :         hashmap_replace(m, "key 3", val1);
      40           1 :         r = hashmap_get(m, "key 3");
      41           1 :         assert_se(streq(r, "val1"));
      42             : 
      43           1 :         hashmap_replace(m, "key 5", val5);
      44           1 :         r = hashmap_get(m, "key 5");
      45           1 :         assert_se(streq(r, "val5"));
      46             : 
      47           1 :         free(val1);
      48           1 :         free(val2);
      49           1 :         free(val3);
      50           1 :         free(val4);
      51           1 :         free(val5);
      52           1 :         hashmap_free(m);
      53           1 : }
      54             : 
      55           1 : static void test_hashmap_copy(void) {
      56             :         Hashmap *m, *copy;
      57             :         char *val1, *val2, *val3, *val4, *r;
      58             : 
      59           1 :         log_info("/* %s */", __func__);
      60             : 
      61           1 :         val1 = strdup("val1");
      62           1 :         assert_se(val1);
      63           1 :         val2 = strdup("val2");
      64           1 :         assert_se(val2);
      65           1 :         val3 = strdup("val3");
      66           1 :         assert_se(val3);
      67           1 :         val4 = strdup("val4");
      68           1 :         assert_se(val4);
      69             : 
      70           1 :         m = hashmap_new(&string_hash_ops);
      71             : 
      72           1 :         hashmap_put(m, "key 1", val1);
      73           1 :         hashmap_put(m, "key 2", val2);
      74           1 :         hashmap_put(m, "key 3", val3);
      75           1 :         hashmap_put(m, "key 4", val4);
      76             : 
      77           1 :         copy = hashmap_copy(m);
      78             : 
      79           1 :         r = hashmap_get(copy, "key 1");
      80           1 :         assert_se(streq(r, "val1"));
      81           1 :         r = hashmap_get(copy, "key 2");
      82           1 :         assert_se(streq(r, "val2"));
      83           1 :         r = hashmap_get(copy, "key 3");
      84           1 :         assert_se(streq(r, "val3"));
      85           1 :         r = hashmap_get(copy, "key 4");
      86           1 :         assert_se(streq(r, "val4"));
      87             : 
      88           1 :         hashmap_free_free(copy);
      89           1 :         hashmap_free(m);
      90           1 : }
      91             : 
      92           1 : static void test_hashmap_get_strv(void) {
      93             :         Hashmap *m;
      94             :         char **strv;
      95             :         char *val1, *val2, *val3, *val4;
      96             : 
      97           1 :         log_info("/* %s */", __func__);
      98             : 
      99           1 :         val1 = strdup("val1");
     100           1 :         assert_se(val1);
     101           1 :         val2 = strdup("val2");
     102           1 :         assert_se(val2);
     103           1 :         val3 = strdup("val3");
     104           1 :         assert_se(val3);
     105           1 :         val4 = strdup("val4");
     106           1 :         assert_se(val4);
     107             : 
     108           1 :         m = hashmap_new(&string_hash_ops);
     109             : 
     110           1 :         hashmap_put(m, "key 1", val1);
     111           1 :         hashmap_put(m, "key 2", val2);
     112           1 :         hashmap_put(m, "key 3", val3);
     113           1 :         hashmap_put(m, "key 4", val4);
     114             : 
     115           1 :         strv = hashmap_get_strv(m);
     116             : 
     117             : #ifndef ORDERED
     118           1 :         strv = strv_sort(strv);
     119             : #endif
     120             : 
     121           1 :         assert_se(streq(strv[0], "val1"));
     122           1 :         assert_se(streq(strv[1], "val2"));
     123           1 :         assert_se(streq(strv[2], "val3"));
     124           1 :         assert_se(streq(strv[3], "val4"));
     125             : 
     126           1 :         strv_free(strv);
     127             : 
     128           1 :         hashmap_free(m);
     129           1 : }
     130             : 
     131           1 : static void test_hashmap_move_one(void) {
     132             :         Hashmap *m, *n;
     133             :         char *val1, *val2, *val3, *val4, *r;
     134             : 
     135           1 :         log_info("/* %s */", __func__);
     136             : 
     137           1 :         val1 = strdup("val1");
     138           1 :         assert_se(val1);
     139           1 :         val2 = strdup("val2");
     140           1 :         assert_se(val2);
     141           1 :         val3 = strdup("val3");
     142           1 :         assert_se(val3);
     143           1 :         val4 = strdup("val4");
     144           1 :         assert_se(val4);
     145             : 
     146           1 :         m = hashmap_new(&string_hash_ops);
     147           1 :         n = hashmap_new(&string_hash_ops);
     148             : 
     149           1 :         hashmap_put(m, "key 1", val1);
     150           1 :         hashmap_put(m, "key 2", val2);
     151           1 :         hashmap_put(m, "key 3", val3);
     152           1 :         hashmap_put(m, "key 4", val4);
     153             : 
     154           1 :         assert_se(hashmap_move_one(n, NULL, "key 3") == -ENOENT);
     155           1 :         assert_se(hashmap_move_one(n, m, "key 5") == -ENOENT);
     156           1 :         assert_se(hashmap_move_one(n, m, "key 3") == 0);
     157           1 :         assert_se(hashmap_move_one(n, m, "key 4") == 0);
     158             : 
     159           1 :         r = hashmap_get(n, "key 3");
     160           1 :         assert_se(r && streq(r, "val3"));
     161           1 :         r = hashmap_get(n, "key 4");
     162           1 :         assert_se(r && streq(r, "val4"));
     163           1 :         r = hashmap_get(m, "key 3");
     164           1 :         assert_se(!r);
     165             : 
     166           1 :         assert_se(hashmap_move_one(n, m, "key 3") == -EEXIST);
     167             : 
     168           1 :         hashmap_free_free(m);
     169           1 :         hashmap_free_free(n);
     170           1 : }
     171             : 
     172           1 : static void test_hashmap_move(void) {
     173             :         Hashmap *m, *n;
     174             :         char *val1, *val2, *val3, *val4, *r;
     175             : 
     176           1 :         log_info("/* %s */", __func__);
     177             : 
     178           1 :         val1 = strdup("val1");
     179           1 :         assert_se(val1);
     180           1 :         val2 = strdup("val2");
     181           1 :         assert_se(val2);
     182           1 :         val3 = strdup("val3");
     183           1 :         assert_se(val3);
     184           1 :         val4 = strdup("val4");
     185           1 :         assert_se(val4);
     186             : 
     187           1 :         m = hashmap_new(&string_hash_ops);
     188           1 :         n = hashmap_new(&string_hash_ops);
     189             : 
     190           1 :         hashmap_put(n, "key 1", strdup(val1));
     191           1 :         hashmap_put(m, "key 1", val1);
     192           1 :         hashmap_put(m, "key 2", val2);
     193           1 :         hashmap_put(m, "key 3", val3);
     194           1 :         hashmap_put(m, "key 4", val4);
     195             : 
     196           1 :         assert_se(hashmap_move(n, NULL) == 0);
     197           1 :         assert_se(hashmap_move(n, m) == 0);
     198             : 
     199           1 :         assert_se(hashmap_size(m) == 1);
     200           1 :         r = hashmap_get(m, "key 1");
     201           1 :         assert_se(r && streq(r, "val1"));
     202             : 
     203           1 :         r = hashmap_get(n, "key 1");
     204           1 :         assert_se(r && streq(r, "val1"));
     205           1 :         r = hashmap_get(n, "key 2");
     206           1 :         assert_se(r && streq(r, "val2"));
     207           1 :         r = hashmap_get(n, "key 3");
     208           1 :         assert_se(r && streq(r, "val3"));
     209           1 :         r = hashmap_get(n, "key 4");
     210           1 :         assert_se(r && streq(r, "val4"));
     211             : 
     212           1 :         hashmap_free_free(m);
     213           1 :         hashmap_free_free(n);
     214           1 : }
     215             : 
     216           1 : static void test_hashmap_update(void) {
     217             :         Hashmap *m;
     218             :         char *val1, *val2, *r;
     219             : 
     220           1 :         log_info("/* %s */", __func__);
     221             : 
     222           1 :         m = hashmap_new(&string_hash_ops);
     223           1 :         val1 = strdup("old_value");
     224           1 :         assert_se(val1);
     225           1 :         val2 = strdup("new_value");
     226           1 :         assert_se(val2);
     227             : 
     228           1 :         hashmap_put(m, "key 1", val1);
     229           1 :         r = hashmap_get(m, "key 1");
     230           1 :         assert_se(streq(r, "old_value"));
     231             : 
     232           1 :         assert_se(hashmap_update(m, "key 2", val2) == -ENOENT);
     233           1 :         r = hashmap_get(m, "key 1");
     234           1 :         assert_se(streq(r, "old_value"));
     235             : 
     236           1 :         assert_se(hashmap_update(m, "key 1", val2) == 0);
     237           1 :         r = hashmap_get(m, "key 1");
     238           1 :         assert_se(streq(r, "new_value"));
     239             : 
     240           1 :         free(val1);
     241           1 :         free(val2);
     242           1 :         hashmap_free(m);
     243           1 : }
     244             : 
     245           1 : static void test_hashmap_put(void) {
     246           1 :         Hashmap *m = NULL;
     247             :         int valid_hashmap_put;
     248           1 :         void *val1 = (void*) "val 1";
     249           1 :         void *val2 = (void*) "val 2";
     250           1 :         _cleanup_free_ char* key1 = NULL;
     251             : 
     252           1 :         log_info("/* %s */", __func__);
     253             : 
     254           1 :         assert_se(hashmap_ensure_allocated(&m, &string_hash_ops) >= 0);
     255           1 :         assert_se(m);
     256             : 
     257           1 :         valid_hashmap_put = hashmap_put(m, "key 1", val1);
     258           1 :         assert_se(valid_hashmap_put == 1);
     259           1 :         assert_se(hashmap_put(m, "key 1", val1) == 0);
     260           1 :         assert_se(hashmap_put(m, "key 1", val2) == -EEXIST);
     261           1 :         key1 = strdup("key 1");
     262           1 :         assert_se(hashmap_put(m, key1, val1) == 0);
     263           1 :         assert_se(hashmap_put(m, key1, val2) == -EEXIST);
     264             : 
     265           1 :         hashmap_free(m);
     266           1 : }
     267             : 
     268           1 : static void test_hashmap_remove(void) {
     269           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     270             :         char *r;
     271             : 
     272           1 :         log_info("/* %s */", __func__);
     273             : 
     274           1 :         r = hashmap_remove(NULL, "key 1");
     275           1 :         assert_se(r == NULL);
     276             : 
     277           1 :         m = hashmap_new(&string_hash_ops);
     278           1 :         assert_se(m);
     279             : 
     280           1 :         r = hashmap_remove(m, "no such key");
     281           1 :         assert_se(r == NULL);
     282             : 
     283           1 :         hashmap_put(m, "key 1", (void*) "val 1");
     284           1 :         hashmap_put(m, "key 2", (void*) "val 2");
     285             : 
     286           1 :         r = hashmap_remove(m, "key 1");
     287           1 :         assert_se(streq(r, "val 1"));
     288             : 
     289           1 :         r = hashmap_get(m, "key 2");
     290           1 :         assert_se(streq(r, "val 2"));
     291           1 :         assert_se(!hashmap_get(m, "key 1"));
     292           1 : }
     293             : 
     294           1 : static void test_hashmap_remove2(void) {
     295           1 :         _cleanup_hashmap_free_free_free_ Hashmap *m = NULL;
     296           1 :         char key1[] = "key 1";
     297           1 :         char key2[] = "key 2";
     298           1 :         char val1[] = "val 1";
     299           1 :         char val2[] = "val 2";
     300             :         void *r, *r2;
     301             : 
     302           1 :         log_info("/* %s */", __func__);
     303             : 
     304           1 :         r = hashmap_remove2(NULL, "key 1", &r2);
     305           1 :         assert_se(r == NULL);
     306             : 
     307           1 :         m = hashmap_new(&string_hash_ops);
     308           1 :         assert_se(m);
     309             : 
     310           1 :         r = hashmap_remove2(m, "no such key", &r2);
     311           1 :         assert_se(r == NULL);
     312             : 
     313           1 :         hashmap_put(m, strdup(key1), strdup(val1));
     314           1 :         hashmap_put(m, strdup(key2), strdup(val2));
     315             : 
     316           1 :         r = hashmap_remove2(m, key1, &r2);
     317           1 :         assert_se(streq(r, val1));
     318           1 :         assert_se(streq(r2, key1));
     319           1 :         free(r);
     320           1 :         free(r2);
     321             : 
     322           1 :         r = hashmap_get(m, key2);
     323           1 :         assert_se(streq(r, val2));
     324           1 :         assert_se(!hashmap_get(m, key1));
     325           1 : }
     326             : 
     327           1 : static void test_hashmap_remove_value(void) {
     328           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     329             :         char *r;
     330             : 
     331           1 :         char val1[] = "val 1";
     332           1 :         char val2[] = "val 2";
     333             : 
     334           1 :         log_info("/* %s */", __func__);
     335             : 
     336           1 :         r = hashmap_remove_value(NULL, "key 1", val1);
     337           1 :         assert_se(r == NULL);
     338             : 
     339           1 :         m = hashmap_new(&string_hash_ops);
     340           1 :         assert_se(m);
     341             : 
     342           1 :         r = hashmap_remove_value(m, "key 1", val1);
     343           1 :         assert_se(r == NULL);
     344             : 
     345           1 :         hashmap_put(m, "key 1", val1);
     346           1 :         hashmap_put(m, "key 2", val2);
     347             : 
     348           1 :         r = hashmap_remove_value(m, "key 1", val1);
     349           1 :         assert_se(streq(r, "val 1"));
     350             : 
     351           1 :         r = hashmap_get(m, "key 2");
     352           1 :         assert_se(streq(r, "val 2"));
     353           1 :         assert_se(!hashmap_get(m, "key 1"));
     354             : 
     355           1 :         r = hashmap_remove_value(m, "key 2", val1);
     356           1 :         assert_se(r == NULL);
     357             : 
     358           1 :         r = hashmap_get(m, "key 2");
     359           1 :         assert_se(streq(r, "val 2"));
     360           1 :         assert_se(!hashmap_get(m, "key 1"));
     361           1 : }
     362             : 
     363           1 : static void test_hashmap_remove_and_put(void) {
     364           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     365             :         int valid;
     366             :         char *r;
     367             : 
     368           1 :         log_info("/* %s */", __func__);
     369             : 
     370           1 :         m = hashmap_new(&string_hash_ops);
     371           1 :         assert_se(m);
     372             : 
     373           1 :         valid = hashmap_remove_and_put(m, "invalid key", "new key", NULL);
     374           1 :         assert_se(valid == -ENOENT);
     375             : 
     376           1 :         valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
     377           1 :         assert_se(valid == 1);
     378             : 
     379           1 :         valid = hashmap_remove_and_put(NULL, "key 1", "key 2", (void*) (const char *) "val 2");
     380           1 :         assert_se(valid == -ENOENT);
     381             : 
     382           1 :         valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
     383           1 :         assert_se(valid == 0);
     384             : 
     385           1 :         r = hashmap_get(m, "key 2");
     386           1 :         assert_se(streq(r, "val 2"));
     387           1 :         assert_se(!hashmap_get(m, "key 1"));
     388             : 
     389           1 :         valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
     390           1 :         assert_se(valid == 1);
     391           1 :         valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
     392           1 :         assert_se(valid == -EEXIST);
     393           1 : }
     394             : 
     395           1 : static void test_hashmap_remove_and_replace(void) {
     396           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     397             :         int valid;
     398           1 :         void *key1 = UINT_TO_PTR(1);
     399           1 :         void *key2 = UINT_TO_PTR(2);
     400           1 :         void *key3 = UINT_TO_PTR(3);
     401             :         void *r;
     402             :         int i, j;
     403             : 
     404           1 :         log_info("/* %s */", __func__);
     405             : 
     406           1 :         m = hashmap_new(&trivial_hash_ops);
     407           1 :         assert_se(m);
     408             : 
     409           1 :         valid = hashmap_remove_and_replace(m, key1, key2, NULL);
     410           1 :         assert_se(valid == -ENOENT);
     411             : 
     412           1 :         valid = hashmap_put(m, key1, key1);
     413           1 :         assert_se(valid == 1);
     414             : 
     415           1 :         valid = hashmap_remove_and_replace(NULL, key1, key2, key2);
     416           1 :         assert_se(valid == -ENOENT);
     417             : 
     418           1 :         valid = hashmap_remove_and_replace(m, key1, key2, key2);
     419           1 :         assert_se(valid == 0);
     420             : 
     421           1 :         r = hashmap_get(m, key2);
     422           1 :         assert_se(r == key2);
     423           1 :         assert_se(!hashmap_get(m, key1));
     424             : 
     425           1 :         valid = hashmap_put(m, key3, key3);
     426           1 :         assert_se(valid == 1);
     427           1 :         valid = hashmap_remove_and_replace(m, key3, key2, key2);
     428           1 :         assert_se(valid == 0);
     429           1 :         r = hashmap_get(m, key2);
     430           1 :         assert_se(r == key2);
     431           1 :         assert_se(!hashmap_get(m, key3));
     432             : 
     433             :         /* Repeat this test several times to increase the chance of hitting
     434             :          * the less likely case in hashmap_remove_and_replace where it
     435             :          * compensates for the backward shift. */
     436          21 :         for (i = 0; i < 20; i++) {
     437          20 :                 hashmap_clear(m);
     438             : 
     439         140 :                 for (j = 1; j < 7; j++)
     440         120 :                         hashmap_put(m, UINT_TO_PTR(10*i + j), UINT_TO_PTR(10*i + j));
     441          40 :                 valid = hashmap_remove_and_replace(m, UINT_TO_PTR(10*i + 1),
     442          20 :                                                    UINT_TO_PTR(10*i + 2),
     443          20 :                                                    UINT_TO_PTR(10*i + 2));
     444          20 :                 assert_se(valid == 0);
     445          20 :                 assert_se(!hashmap_get(m, UINT_TO_PTR(10*i + 1)));
     446         120 :                 for (j = 2; j < 7; j++) {
     447         100 :                         r = hashmap_get(m, UINT_TO_PTR(10*i + j));
     448         100 :                         assert_se(r == UINT_TO_PTR(10*i + j));
     449             :                 }
     450             :         }
     451           1 : }
     452             : 
     453           1 : static void test_hashmap_ensure_allocated(void) {
     454             :         Hashmap *m;
     455             :         int valid_hashmap;
     456             : 
     457           1 :         log_info("/* %s */", __func__);
     458             : 
     459           1 :         m = hashmap_new(&string_hash_ops);
     460             : 
     461           1 :         valid_hashmap = hashmap_ensure_allocated(&m, &string_hash_ops);
     462           1 :         assert_se(valid_hashmap == 0);
     463             : 
     464           1 :         assert_se(m);
     465           1 :         hashmap_free(m);
     466           1 : }
     467             : 
     468           1 : static void test_hashmap_foreach_key(void) {
     469             :         Hashmap *m;
     470             :         Iterator i;
     471           1 :         bool key_found[] = { false, false, false, false };
     472             :         const char *s;
     473             :         const char *key;
     474             :         static const char key_table[] =
     475             :                 "key 1\0"
     476             :                 "key 2\0"
     477             :                 "key 3\0"
     478             :                 "key 4\0";
     479             : 
     480           1 :         log_info("/* %s */", __func__);
     481             : 
     482           1 :         m = hashmap_new(&string_hash_ops);
     483             : 
     484           5 :         NULSTR_FOREACH(key, key_table)
     485           4 :                 hashmap_put(m, key, (void*) (const char*) "my dummy val");
     486             : 
     487           5 :         HASHMAP_FOREACH_KEY(s, key, m, i) {
     488           4 :                 assert(s);
     489           4 :                 if (!key_found[0] && streq(key, "key 1"))
     490           1 :                         key_found[0] = true;
     491           3 :                 else if (!key_found[1] && streq(key, "key 2"))
     492           1 :                         key_found[1] = true;
     493           2 :                 else if (!key_found[2] && streq(key, "key 3"))
     494           1 :                         key_found[2] = true;
     495           1 :                 else if (!key_found[3] && streq(key, "fail"))
     496           0 :                         key_found[3] = true;
     497             :         }
     498             : 
     499           1 :         assert_se(m);
     500           1 :         assert_se(key_found[0] && key_found[1] && key_found[2] && !key_found[3]);
     501             : 
     502           1 :         hashmap_free(m);
     503           1 : }
     504             : 
     505           1 : static void test_hashmap_foreach(void) {
     506             :         Hashmap *m;
     507             :         Iterator i;
     508           1 :         bool value_found[] = { false, false, false, false };
     509             :         char *val1, *val2, *val3, *val4, *s;
     510             :         unsigned count;
     511             : 
     512           1 :         log_info("/* %s */", __func__);
     513             : 
     514           1 :         val1 = strdup("my val1");
     515           1 :         assert_se(val1);
     516           1 :         val2 = strdup("my val2");
     517           1 :         assert_se(val2);
     518           1 :         val3 = strdup("my val3");
     519           1 :         assert_se(val3);
     520           1 :         val4 = strdup("my val4");
     521           1 :         assert_se(val4);
     522             : 
     523           1 :         m = NULL;
     524             : 
     525           1 :         count = 0;
     526           1 :         HASHMAP_FOREACH(s, m, i)
     527           0 :                 count++;
     528           1 :         assert_se(count == 0);
     529             : 
     530           1 :         m = hashmap_new(&string_hash_ops);
     531             : 
     532           1 :         count = 0;
     533           1 :         HASHMAP_FOREACH(s, m, i)
     534           0 :                 count++;
     535           1 :         assert_se(count == 0);
     536             : 
     537           1 :         hashmap_put(m, "Key 1", val1);
     538           1 :         hashmap_put(m, "Key 2", val2);
     539           1 :         hashmap_put(m, "Key 3", val3);
     540           1 :         hashmap_put(m, "Key 4", val4);
     541             : 
     542           5 :         HASHMAP_FOREACH(s, m, i) {
     543           4 :                 if (!value_found[0] && streq(s, val1))
     544           1 :                         value_found[0] = true;
     545           3 :                 else if (!value_found[1] && streq(s, val2))
     546           1 :                         value_found[1] = true;
     547           2 :                 else if (!value_found[2] && streq(s, val3))
     548           1 :                         value_found[2] = true;
     549           1 :                 else if (!value_found[3] && streq(s, val4))
     550           1 :                         value_found[3] = true;
     551             :         }
     552             : 
     553           1 :         assert_se(m);
     554           1 :         assert_se(value_found[0] && value_found[1] && value_found[2] && value_found[3]);
     555             : 
     556           1 :         hashmap_free_free(m);
     557           1 : }
     558             : 
     559           1 : static void test_hashmap_merge(void) {
     560             :         Hashmap *m;
     561             :         Hashmap *n;
     562             :         char *val1, *val2, *val3, *val4, *r;
     563             : 
     564           1 :         log_info("/* %s */", __func__);
     565             : 
     566           1 :         val1 = strdup("my val1");
     567           1 :         assert_se(val1);
     568           1 :         val2 = strdup("my val2");
     569           1 :         assert_se(val2);
     570           1 :         val3 = strdup("my val3");
     571           1 :         assert_se(val3);
     572           1 :         val4 = strdup("my val4");
     573           1 :         assert_se(val4);
     574             : 
     575           1 :         n = hashmap_new(&string_hash_ops);
     576           1 :         m = hashmap_new(&string_hash_ops);
     577             : 
     578           1 :         hashmap_put(m, "Key 1", val1);
     579           1 :         hashmap_put(m, "Key 2", val2);
     580           1 :         hashmap_put(n, "Key 3", val3);
     581           1 :         hashmap_put(n, "Key 4", val4);
     582             : 
     583           1 :         assert_se(hashmap_merge(m, n) == 0);
     584           1 :         r = hashmap_get(m, "Key 3");
     585           1 :         assert_se(r && streq(r, "my val3"));
     586           1 :         r = hashmap_get(m, "Key 4");
     587           1 :         assert_se(r && streq(r, "my val4"));
     588             : 
     589           1 :         assert_se(n);
     590           1 :         assert_se(m);
     591           1 :         hashmap_free(n);
     592           1 :         hashmap_free_free(m);
     593           1 : }
     594             : 
     595           1 : static void test_hashmap_contains(void) {
     596             :         Hashmap *m;
     597             :         char *val1;
     598             : 
     599           1 :         log_info("/* %s */", __func__);
     600             : 
     601           1 :         val1 = strdup("my val");
     602           1 :         assert_se(val1);
     603             : 
     604           1 :         m = hashmap_new(&string_hash_ops);
     605             : 
     606           1 :         assert_se(!hashmap_contains(m, "Key 1"));
     607           1 :         hashmap_put(m, "Key 1", val1);
     608           1 :         assert_se(hashmap_contains(m, "Key 1"));
     609           1 :         assert_se(!hashmap_contains(m, "Key 2"));
     610             : 
     611           1 :         assert_se(!hashmap_contains(NULL, "Key 1"));
     612             : 
     613           1 :         assert_se(m);
     614           1 :         hashmap_free_free(m);
     615           1 : }
     616             : 
     617           1 : static void test_hashmap_isempty(void) {
     618             :         Hashmap *m;
     619             :         char *val1;
     620             : 
     621           1 :         log_info("/* %s */", __func__);
     622             : 
     623           1 :         val1 = strdup("my val");
     624           1 :         assert_se(val1);
     625             : 
     626           1 :         m = hashmap_new(&string_hash_ops);
     627             : 
     628           1 :         assert_se(hashmap_isempty(m));
     629           1 :         hashmap_put(m, "Key 1", val1);
     630           1 :         assert_se(!hashmap_isempty(m));
     631             : 
     632           1 :         assert_se(m);
     633           1 :         hashmap_free_free(m);
     634           1 : }
     635             : 
     636           1 : static void test_hashmap_size(void) {
     637             :         Hashmap *m;
     638             :         char *val1, *val2, *val3, *val4;
     639             : 
     640           1 :         log_info("/* %s */", __func__);
     641             : 
     642           1 :         val1 = strdup("my val");
     643           1 :         assert_se(val1);
     644           1 :         val2 = strdup("my val");
     645           1 :         assert_se(val2);
     646           1 :         val3 = strdup("my val");
     647           1 :         assert_se(val3);
     648           1 :         val4 = strdup("my val");
     649           1 :         assert_se(val4);
     650             : 
     651           1 :         assert_se(hashmap_size(NULL) == 0);
     652           1 :         assert_se(hashmap_buckets(NULL) == 0);
     653             : 
     654           1 :         m = hashmap_new(&string_hash_ops);
     655             : 
     656           1 :         hashmap_put(m, "Key 1", val1);
     657           1 :         hashmap_put(m, "Key 2", val2);
     658           1 :         hashmap_put(m, "Key 3", val3);
     659           1 :         hashmap_put(m, "Key 4", val4);
     660             : 
     661           1 :         assert_se(m);
     662           1 :         assert_se(hashmap_size(m) == 4);
     663           1 :         assert_se(hashmap_buckets(m) >= 4);
     664           1 :         hashmap_free_free(m);
     665           1 : }
     666             : 
     667           1 : static void test_hashmap_get(void) {
     668             :         Hashmap *m;
     669             :         char *r;
     670             :         char *val;
     671             : 
     672           1 :         log_info("/* %s */", __func__);
     673             : 
     674           1 :         val = strdup("my val");
     675           1 :         assert_se(val);
     676             : 
     677           1 :         r = hashmap_get(NULL, "Key 1");
     678           1 :         assert_se(r == NULL);
     679             : 
     680           1 :         m = hashmap_new(&string_hash_ops);
     681             : 
     682           1 :         hashmap_put(m, "Key 1", val);
     683             : 
     684           1 :         r = hashmap_get(m, "Key 1");
     685           1 :         assert_se(streq(r, val));
     686             : 
     687           1 :         r = hashmap_get(m, "no such key");
     688           1 :         assert_se(r == NULL);
     689             : 
     690           1 :         assert_se(m);
     691           1 :         hashmap_free_free(m);
     692           1 : }
     693             : 
     694           1 : static void test_hashmap_get2(void) {
     695             :         Hashmap *m;
     696             :         char *r;
     697             :         char *val;
     698           1 :         char key_orig[] = "Key 1";
     699             :         void *key_copy;
     700             : 
     701           1 :         log_info("/* %s */", __func__);
     702             : 
     703           1 :         val = strdup("my val");
     704           1 :         assert_se(val);
     705             : 
     706           1 :         key_copy = strdup(key_orig);
     707           1 :         assert_se(key_copy);
     708             : 
     709           1 :         r = hashmap_get2(NULL, key_orig, &key_copy);
     710           1 :         assert_se(r == NULL);
     711             : 
     712           1 :         m = hashmap_new(&string_hash_ops);
     713             : 
     714           1 :         hashmap_put(m, key_copy, val);
     715           1 :         key_copy = NULL;
     716             : 
     717           1 :         r = hashmap_get2(m, key_orig, &key_copy);
     718           1 :         assert_se(streq(r, val));
     719           1 :         assert_se(key_orig != key_copy);
     720           1 :         assert_se(streq(key_orig, key_copy));
     721             : 
     722           1 :         r = hashmap_get2(m, "no such key", NULL);
     723           1 :         assert_se(r == NULL);
     724             : 
     725           1 :         assert_se(m);
     726           1 :         hashmap_free_free_free(m);
     727           1 : }
     728             : 
     729        1033 : static void crippled_hashmap_func(const void *p, struct siphash *state) {
     730        1033 :         return trivial_hash_func(INT_TO_PTR(PTR_TO_INT(p) & 0xff), state);
     731             : }
     732             : 
     733             : static const struct hash_ops crippled_hashmap_ops = {
     734             :         .hash = crippled_hashmap_func,
     735             :         .compare = trivial_compare_func,
     736             : };
     737             : 
     738           1 : static void test_hashmap_many(void) {
     739             :         Hashmap *h;
     740             :         unsigned i, j;
     741             :         void *v, *k;
     742           1 :         bool slow = slow_tests_enabled();
     743             :         const struct {
     744             :                 const char *title;
     745             :                 const struct hash_ops *ops;
     746             :                 unsigned n_entries;
     747           3 :         } tests[] = {
     748           1 :                 { "trivial_hashmap_ops",  NULL,                  slow ? 1 << 20 : 240 },
     749           1 :                 { "crippled_hashmap_ops", &crippled_hashmap_ops, slow ? 1 << 14 : 140 },
     750             :         };
     751             : 
     752           1 :         log_info("/* %s (%s) */", __func__, slow ? "slow" : "fast");
     753             : 
     754           3 :         for (j = 0; j < ELEMENTSOF(tests); j++) {
     755           2 :                 usec_t ts = now(CLOCK_MONOTONIC), n;
     756             :                 char b[FORMAT_TIMESPAN_MAX];
     757             : 
     758           2 :                 assert_se(h = hashmap_new(tests[j].ops));
     759             : 
     760         382 :                 for (i = 1; i < tests[j].n_entries*3; i+=3) {
     761         380 :                         assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0);
     762         380 :                         assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i);
     763             :                 }
     764             : 
     765        1140 :                 for (i = 1; i < tests[j].n_entries*3; i++)
     766        1138 :                         assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1));
     767             : 
     768           2 :                 log_info("%s %u <= %u * 0.8 = %g",
     769             :                          tests[j].title, hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.8);
     770             : 
     771           2 :                 assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.8);
     772           2 :                 assert_se(hashmap_size(h) == tests[j].n_entries);
     773             : 
     774         382 :                 while (!hashmap_isempty(h)) {
     775         380 :                         k = hashmap_first_key(h);
     776         380 :                         v = hashmap_remove(h, k);
     777         380 :                         assert_se(v == k);
     778             :                 }
     779             : 
     780           2 :                 hashmap_free(h);
     781             : 
     782           2 :                 n = now(CLOCK_MONOTONIC);
     783           2 :                 log_info("test took %s", format_timespan(b, sizeof b, n - ts, 0));
     784             :         }
     785           1 : }
     786             : 
     787             : extern unsigned custom_counter;
     788             : extern const struct hash_ops boring_hash_ops, custom_hash_ops;
     789             : 
     790           1 : static void test_hashmap_free(void) {
     791             :         Hashmap *h;
     792           1 :         bool slow = slow_tests_enabled();
     793             :         usec_t ts, n;
     794             :         char b[FORMAT_TIMESPAN_MAX];
     795           1 :         unsigned n_entries = slow ? 1 << 20 : 240;
     796             : 
     797             :         const struct {
     798             :                 const char *title;
     799             :                 const struct hash_ops *ops;
     800             :                 unsigned expect_counter;
     801           2 :         } tests[] = {
     802           1 :                 { "string_hash_ops",      &boring_hash_ops, 2 * n_entries},
     803             :                 { "custom_free_hash_ops", &custom_hash_ops, 0 },
     804             :         };
     805             : 
     806           1 :         log_info("/* %s (%s, %u entries) */", __func__, slow ? "slow" : "fast", n_entries);
     807             : 
     808           3 :         for (unsigned j = 0; j < ELEMENTSOF(tests); j++) {
     809           2 :                 ts = now(CLOCK_MONOTONIC);
     810           2 :                 assert_se(h = hashmap_new(tests[j].ops));
     811             : 
     812           2 :                 custom_counter = 0;
     813         482 :                 for (unsigned i = 0; i < n_entries; i++) {
     814             :                         char s[DECIMAL_STR_MAX(unsigned)];
     815             :                         char *k, *v;
     816             : 
     817         480 :                         xsprintf(s, "%u", i);
     818         480 :                         assert_se(k = strdup(s));
     819         480 :                         assert_se(v = strdup(s));
     820         480 :                         custom_counter += 2;
     821             : 
     822         480 :                         assert_se(hashmap_put(h, k, v) >= 0);
     823             :                 }
     824             : 
     825           2 :                 hashmap_free(h);
     826             : 
     827           2 :                 n = now(CLOCK_MONOTONIC);
     828           2 :                 log_info("%s test took %s", tests[j].title, format_timespan(b, sizeof b, n - ts, 0));
     829             : 
     830           2 :                 assert_se(custom_counter == tests[j].expect_counter);
     831             :         }
     832           1 : }
     833             : 
     834             : typedef struct Item {
     835             :         int seen;
     836             : } Item;
     837           3 : static void item_seen(Item *item) {
     838           3 :         item->seen++;
     839           3 : }
     840             : 
     841           1 : static void test_hashmap_free_with_destructor(void) {
     842             :         Hashmap *m;
     843           1 :         struct Item items[4] = {};
     844             :         unsigned i;
     845             : 
     846           1 :         log_info("/* %s */", __func__);
     847             : 
     848           1 :         assert_se(m = hashmap_new(NULL));
     849           4 :         for (i = 0; i < ELEMENTSOF(items) - 1; i++)
     850           3 :                 assert_se(hashmap_put(m, INT_TO_PTR(i), items + i) == 1);
     851             : 
     852           4 :         m = hashmap_free_with_destructor(m, item_seen);
     853           1 :         assert_se(items[0].seen == 1);
     854           1 :         assert_se(items[1].seen == 1);
     855           1 :         assert_se(items[2].seen == 1);
     856           1 :         assert_se(items[3].seen == 0);
     857           1 : }
     858             : 
     859           1 : static void test_hashmap_first(void) {
     860           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     861             : 
     862           1 :         log_info("/* %s */", __func__);
     863             : 
     864           1 :         m = hashmap_new(&string_hash_ops);
     865           1 :         assert_se(m);
     866             : 
     867           1 :         assert_se(!hashmap_first(m));
     868           1 :         assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
     869           1 :         assert_se(streq(hashmap_first(m), "val 1"));
     870           1 :         assert_se(hashmap_put(m, "key 2", (void*) "val 2") == 1);
     871             : #ifdef ORDERED
     872             :         assert_se(streq(hashmap_first(m), "val 1"));
     873             :         assert_se(hashmap_remove(m, "key 1"));
     874             :         assert_se(streq(hashmap_first(m), "val 2"));
     875             : #endif
     876           1 : }
     877             : 
     878           1 : static void test_hashmap_first_key(void) {
     879           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     880             : 
     881           1 :         log_info("/* %s */", __func__);
     882             : 
     883           1 :         m = hashmap_new(&string_hash_ops);
     884           1 :         assert_se(m);
     885             : 
     886           1 :         assert_se(!hashmap_first_key(m));
     887           1 :         assert_se(hashmap_put(m, "key 1", NULL) == 1);
     888           1 :         assert_se(streq(hashmap_first_key(m), "key 1"));
     889           1 :         assert_se(hashmap_put(m, "key 2", NULL) == 1);
     890             : #ifdef ORDERED
     891             :         assert_se(streq(hashmap_first_key(m), "key 1"));
     892             :         assert_se(hashmap_remove(m, "key 1") == NULL);
     893             :         assert_se(streq(hashmap_first_key(m), "key 2"));
     894             : #endif
     895           1 : }
     896             : 
     897           1 : static void test_hashmap_steal_first_key(void) {
     898           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     899             : 
     900           1 :         log_info("/* %s */", __func__);
     901             : 
     902           1 :         m = hashmap_new(&string_hash_ops);
     903           1 :         assert_se(m);
     904             : 
     905           1 :         assert_se(!hashmap_steal_first_key(m));
     906           1 :         assert_se(hashmap_put(m, "key 1", NULL) == 1);
     907           1 :         assert_se(streq(hashmap_steal_first_key(m), "key 1"));
     908             : 
     909           1 :         assert_se(hashmap_isempty(m));
     910           1 : }
     911             : 
     912           1 : static void test_hashmap_steal_first(void) {
     913           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     914           1 :         int seen[3] = {};
     915             :         char *val;
     916             : 
     917           1 :         log_info("/* %s */", __func__);
     918             : 
     919           1 :         m = hashmap_new(&string_hash_ops);
     920           1 :         assert_se(m);
     921             : 
     922           1 :         assert_se(hashmap_put(m, "key 1", (void*) "1") == 1);
     923           1 :         assert_se(hashmap_put(m, "key 2", (void*) "22") == 1);
     924           1 :         assert_se(hashmap_put(m, "key 3", (void*) "333") == 1);
     925             : 
     926           4 :         while ((val = hashmap_steal_first(m)))
     927           3 :                 seen[strlen(val) - 1]++;
     928             : 
     929           1 :         assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
     930             : 
     931           1 :         assert_se(hashmap_isempty(m));
     932           1 : }
     933             : 
     934           1 : static void test_hashmap_clear_free_free(void) {
     935           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     936             : 
     937           1 :         log_info("/* %s */", __func__);
     938             : 
     939           1 :         m = hashmap_new(&string_hash_ops);
     940           1 :         assert_se(m);
     941             : 
     942           1 :         assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
     943           1 :         assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
     944           1 :         assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
     945             : 
     946           1 :         hashmap_clear_free_free(m);
     947           1 :         assert_se(hashmap_isempty(m));
     948             : 
     949           1 :         assert_se(hashmap_put(m, strdup("key 1"), strdup("value 1")) == 1);
     950           1 :         assert_se(hashmap_put(m, strdup("key 2"), strdup("value 2")) == 1);
     951           1 :         assert_se(hashmap_put(m, strdup("key 3"), strdup("value 3")) == 1);
     952             : 
     953           1 :         hashmap_clear_free_free(m);
     954           1 :         assert_se(hashmap_isempty(m));
     955           1 : }
     956             : 
     957           3 : DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(test_hash_ops_key, char, string_hash_func, string_compare_func, free);
     958           6 : DEFINE_PRIVATE_HASH_OPS_FULL(test_hash_ops_full, char, string_hash_func, string_compare_func, free, char, free);
     959             : 
     960           1 : static void test_hashmap_clear_free_with_destructor(void) {
     961           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     962             : 
     963           1 :         log_info("/* %s */", __func__);
     964             : 
     965           1 :         m = hashmap_new(&test_hash_ops_key);
     966           1 :         assert_se(m);
     967             : 
     968           1 :         assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
     969           1 :         assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
     970           1 :         assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
     971             : 
     972           1 :         hashmap_clear_free(m);
     973           1 :         assert_se(hashmap_isempty(m));
     974           1 :         m = hashmap_free(m);
     975             : 
     976           1 :         m = hashmap_new(&test_hash_ops_full);
     977           1 :         assert_se(m);
     978             : 
     979           1 :         assert_se(hashmap_put(m, strdup("key 1"), strdup("value 1")) == 1);
     980           1 :         assert_se(hashmap_put(m, strdup("key 2"), strdup("value 2")) == 1);
     981           1 :         assert_se(hashmap_put(m, strdup("key 3"), strdup("value 3")) == 1);
     982             : 
     983           1 :         hashmap_clear_free(m);
     984           1 :         assert_se(hashmap_isempty(m));
     985           1 : }
     986             : 
     987           1 : static void test_hashmap_reserve(void) {
     988           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
     989             : 
     990           1 :         log_info("/* %s */", __func__);
     991             : 
     992           1 :         m = hashmap_new(&string_hash_ops);
     993             : 
     994           1 :         assert_se(hashmap_reserve(m, 1) == 0);
     995           1 :         assert_se(hashmap_buckets(m) < 1000);
     996           1 :         assert_se(hashmap_reserve(m, 1000) == 0);
     997           1 :         assert_se(hashmap_buckets(m) >= 1000);
     998           1 :         assert_se(hashmap_isempty(m));
     999             : 
    1000           1 :         assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
    1001             : 
    1002           1 :         assert_se(hashmap_reserve(m, UINT_MAX) == -ENOMEM);
    1003           1 :         assert_se(hashmap_reserve(m, UINT_MAX - 1) == -ENOMEM);
    1004           1 : }
    1005             : 
    1006           1 : static void test_path_hashmap(void) {
    1007           1 :         _cleanup_hashmap_free_ Hashmap *h = NULL;
    1008             : 
    1009           1 :         log_info("/* %s */", __func__);
    1010             : 
    1011           1 :         assert_se(h = hashmap_new(&path_hash_ops));
    1012             : 
    1013           1 :         assert_se(hashmap_put(h, "foo", INT_TO_PTR(1)) >= 0);
    1014           1 :         assert_se(hashmap_put(h, "/foo", INT_TO_PTR(2)) >= 0);
    1015           1 :         assert_se(hashmap_put(h, "//foo", INT_TO_PTR(3)) == -EEXIST);
    1016           1 :         assert_se(hashmap_put(h, "//foox/", INT_TO_PTR(4)) >= 0);
    1017           1 :         assert_se(hashmap_put(h, "/foox////", INT_TO_PTR(5)) == -EEXIST);
    1018           1 :         assert_se(hashmap_put(h, "foo//////bar/quux//", INT_TO_PTR(6)) >= 0);
    1019           1 :         assert_se(hashmap_put(h, "foo/bar//quux/", INT_TO_PTR(8)) == -EEXIST);
    1020             : 
    1021           1 :         assert_se(hashmap_get(h, "foo") == INT_TO_PTR(1));
    1022           1 :         assert_se(hashmap_get(h, "foo/") == INT_TO_PTR(1));
    1023           1 :         assert_se(hashmap_get(h, "foo////") == INT_TO_PTR(1));
    1024           1 :         assert_se(hashmap_get(h, "/foo") == INT_TO_PTR(2));
    1025           1 :         assert_se(hashmap_get(h, "//foo") == INT_TO_PTR(2));
    1026           1 :         assert_se(hashmap_get(h, "/////foo////") == INT_TO_PTR(2));
    1027           1 :         assert_se(hashmap_get(h, "/////foox////") == INT_TO_PTR(4));
    1028           1 :         assert_se(hashmap_get(h, "/foox/") == INT_TO_PTR(4));
    1029           1 :         assert_se(hashmap_get(h, "/foox") == INT_TO_PTR(4));
    1030           1 :         assert_se(!hashmap_get(h, "foox"));
    1031           1 :         assert_se(hashmap_get(h, "foo/bar/quux") == INT_TO_PTR(6));
    1032           1 :         assert_se(hashmap_get(h, "foo////bar////quux/////") == INT_TO_PTR(6));
    1033           1 :         assert_se(!hashmap_get(h, "/foo////bar////quux/////"));
    1034           1 : }
    1035             : 
    1036           1 : static void test_string_strv_hashmap(void) {
    1037           1 :         _cleanup_hashmap_free_ Hashmap *m = NULL;
    1038             :         char **s;
    1039             : 
    1040           1 :         log_info("/* %s */", __func__);
    1041             : 
    1042           1 :         assert_se(string_strv_hashmap_put(&m, "foo", "bar") == 1);
    1043           1 :         assert_se(string_strv_hashmap_put(&m, "foo", "bar") == 0);
    1044           1 :         assert_se(string_strv_hashmap_put(&m, "foo", "BAR") == 1);
    1045           1 :         assert_se(string_strv_hashmap_put(&m, "foo", "BAR") == 0);
    1046           1 :         assert_se(string_strv_hashmap_put(&m, "foo", "bar") == 0);
    1047           1 :         assert_se(hashmap_contains(m, "foo"));
    1048             : 
    1049           1 :         s = hashmap_get(m, "foo");
    1050           1 :         assert_se(strv_equal(s, STRV_MAKE("bar", "BAR")));
    1051             : 
    1052           1 :         assert_se(string_strv_hashmap_put(&m, "xxx", "bar") == 1);
    1053           1 :         assert_se(string_strv_hashmap_put(&m, "xxx", "bar") == 0);
    1054           1 :         assert_se(string_strv_hashmap_put(&m, "xxx", "BAR") == 1);
    1055           1 :         assert_se(string_strv_hashmap_put(&m, "xxx", "BAR") == 0);
    1056           1 :         assert_se(string_strv_hashmap_put(&m, "xxx", "bar") == 0);
    1057           1 :         assert_se(hashmap_contains(m, "xxx"));
    1058             : 
    1059           1 :         s = hashmap_get(m, "xxx");
    1060           1 :         assert_se(strv_equal(s, STRV_MAKE("bar", "BAR")));
    1061           1 : }
    1062             : 
    1063           1 : void test_hashmap_funcs(void) {
    1064           1 :         log_info("/************ %s ************/", __func__);
    1065             : 
    1066           1 :         test_hashmap_copy();
    1067           1 :         test_hashmap_get_strv();
    1068           1 :         test_hashmap_move_one();
    1069           1 :         test_hashmap_move();
    1070           1 :         test_hashmap_replace();
    1071           1 :         test_hashmap_update();
    1072           1 :         test_hashmap_put();
    1073           1 :         test_hashmap_remove();
    1074           1 :         test_hashmap_remove2();
    1075           1 :         test_hashmap_remove_value();
    1076           1 :         test_hashmap_remove_and_put();
    1077           1 :         test_hashmap_remove_and_replace();
    1078           1 :         test_hashmap_ensure_allocated();
    1079           1 :         test_hashmap_foreach();
    1080           1 :         test_hashmap_foreach_key();
    1081           1 :         test_hashmap_contains();
    1082           1 :         test_hashmap_merge();
    1083           1 :         test_hashmap_isempty();
    1084           1 :         test_hashmap_get();
    1085           1 :         test_hashmap_get2();
    1086           1 :         test_hashmap_size();
    1087           1 :         test_hashmap_many();
    1088           1 :         test_hashmap_free();
    1089           1 :         test_hashmap_free_with_destructor();
    1090           1 :         test_hashmap_first();
    1091           1 :         test_hashmap_first_key();
    1092           1 :         test_hashmap_steal_first_key();
    1093           1 :         test_hashmap_steal_first();
    1094           1 :         test_hashmap_clear_free_free();
    1095           1 :         test_hashmap_clear_free_with_destructor();
    1096           1 :         test_hashmap_reserve();
    1097           1 :         test_path_hashmap();
    1098           1 :         test_string_strv_hashmap();
    1099           1 : }

Generated by: LCOV version 1.14