LCOV - code coverage report
Current view: top level - test - test-hashmap-plain.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 715 718 99.6 %
Date: 2019-08-23 13:36:53 Functions: 39 39 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 386 720 53.6 %

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

Generated by: LCOV version 1.14