quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

unit1603.c (7217B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "unitcheck.h"
     25 
     26 #include "hash.h"
     27 
     28 #include "memdebug.h" /* LAST include file */
     29 
     30 static const size_t slots = 3;
     31 
     32 static void t1603_mydtor(void *p)
     33 {
     34   /* Data are statically allocated */
     35  (void)p; /* unused */
     36 }
     37 
     38 static size_t elem_dtor_calls;
     39 
     40 static void my_elem_dtor(void *key, size_t key_len, void *p)
     41 {
     42   (void)p; /* unused */
     43   (void)key; /* unused */
     44   (void)key_len; /* unused */
     45   ++elem_dtor_calls;
     46 }
     47 
     48 static CURLcode t1603_setup(struct Curl_hash *hash_static)
     49 {
     50   Curl_hash_init(hash_static, slots, Curl_hash_str,
     51                  curlx_str_key_compare, t1603_mydtor);
     52   return CURLE_OK;
     53 }
     54 
     55 static void t1603_stop(struct Curl_hash *hash_static)
     56 {
     57   Curl_hash_destroy(hash_static);
     58 }
     59 
     60 static CURLcode test_unit1603(char *arg)
     61 {
     62   struct Curl_hash hash_static;
     63 
     64   UNITTEST_BEGIN(t1603_setup(&hash_static))
     65 
     66   char key1[] = "key1";
     67   char key2[] = "key2b";
     68   char key3[] = "key3";
     69   char key4[] = "key4";
     70   char notakey[] = "notakey";
     71   char *nodep;
     72   int rc;
     73 
     74   /* Ensure the key hashes are as expected in order to test both hash
     75      collisions and a full table. Unfortunately, the hashes can vary
     76      between architectures. */
     77   if(Curl_hash_str(key1, strlen(key1), slots) != 1 ||
     78      Curl_hash_str(key2, strlen(key2), slots) != 0 ||
     79      Curl_hash_str(key3, strlen(key3), slots) != 2 ||
     80      Curl_hash_str(key4, strlen(key4), slots) != 1)
     81     curl_mfprintf(stderr,
     82                   "Warning: hashes are not computed as expected on this "
     83                   "architecture; test coverage will be less comprehensive\n");
     84 
     85   nodep = Curl_hash_add(&hash_static, &key1, strlen(key1), &key1);
     86   fail_unless(nodep, "insertion into hash failed");
     87   nodep = Curl_hash_pick(&hash_static, &key1, strlen(key1));
     88   fail_unless(nodep == key1, "hash retrieval failed");
     89 
     90   nodep = Curl_hash_add(&hash_static, &key2, strlen(key2), &key2);
     91   fail_unless(nodep, "insertion into hash failed");
     92   nodep = Curl_hash_pick(&hash_static, &key2, strlen(key2));
     93   fail_unless(nodep == key2, "hash retrieval failed");
     94 
     95   nodep = Curl_hash_add(&hash_static, &key3, strlen(key3), &key3);
     96   fail_unless(nodep, "insertion into hash failed");
     97   nodep = Curl_hash_pick(&hash_static, &key3, strlen(key3));
     98   fail_unless(nodep == key3, "hash retrieval failed");
     99 
    100   /* The fourth element exceeds the number of slots & collides */
    101   nodep = Curl_hash_add(&hash_static, &key4, strlen(key4), &key4);
    102   fail_unless(nodep, "insertion into hash failed");
    103   nodep = Curl_hash_pick(&hash_static, &key4, strlen(key4));
    104   fail_unless(nodep == key4, "hash retrieval failed");
    105 
    106   /* Make sure all elements are still accessible */
    107   nodep = Curl_hash_pick(&hash_static, &key1, strlen(key1));
    108   fail_unless(nodep == key1, "hash retrieval failed");
    109   nodep = Curl_hash_pick(&hash_static, &key2, strlen(key2));
    110   fail_unless(nodep == key2, "hash retrieval failed");
    111   nodep = Curl_hash_pick(&hash_static, &key3, strlen(key3));
    112   fail_unless(nodep == key3, "hash retrieval failed");
    113   nodep = Curl_hash_pick(&hash_static, &key4, strlen(key4));
    114   fail_unless(nodep == key4, "hash retrieval failed");
    115 
    116   /* Delete the second of two entries in a bucket */
    117   rc = Curl_hash_delete(&hash_static, &key4, strlen(key4));
    118   fail_unless(rc == 0, "hash delete failed");
    119   nodep = Curl_hash_pick(&hash_static, &key1, strlen(key1));
    120   fail_unless(nodep == key1, "hash retrieval failed");
    121   nodep = Curl_hash_pick(&hash_static, &key4, strlen(key4));
    122   fail_unless(!nodep, "hash retrieval should have failed");
    123 
    124   /* Insert that deleted node again */
    125   nodep = Curl_hash_add(&hash_static, &key4, strlen(key4), &key4);
    126   fail_unless(nodep, "insertion into hash failed");
    127   nodep = Curl_hash_pick(&hash_static, &key4, strlen(key4));
    128   fail_unless(nodep == key4, "hash retrieval failed");
    129 
    130   /* Delete the first of two entries in a bucket */
    131   rc = Curl_hash_delete(&hash_static, &key1, strlen(key1));
    132   fail_unless(rc == 0, "hash delete failed");
    133   nodep = Curl_hash_pick(&hash_static, &key1, strlen(key1));
    134   fail_unless(!nodep, "hash retrieval should have failed");
    135   nodep = Curl_hash_pick(&hash_static, &key4, strlen(key4));
    136   fail_unless(nodep == key4, "hash retrieval failed");
    137 
    138   /* Delete the remaining one of two entries in a bucket */
    139   rc = Curl_hash_delete(&hash_static, &key4, strlen(key4));
    140   fail_unless(rc == 0, "hash delete failed");
    141   nodep = Curl_hash_pick(&hash_static, &key1, strlen(key1));
    142   fail_unless(!nodep, "hash retrieval should have failed");
    143   nodep = Curl_hash_pick(&hash_static, &key4, strlen(key4));
    144   fail_unless(!nodep, "hash retrieval should have failed");
    145 
    146   /* Delete an already deleted node */
    147   rc = Curl_hash_delete(&hash_static, &key4, strlen(key4));
    148   fail_unless(rc, "hash delete should have failed");
    149 
    150   /* Replace an existing node */
    151   nodep = Curl_hash_add(&hash_static, &key1, strlen(key1), &notakey);
    152   fail_unless(nodep, "insertion into hash failed");
    153   nodep = Curl_hash_pick(&hash_static, &key1, strlen(key1));
    154   fail_unless(nodep == notakey, "hash retrieval failed");
    155 
    156   /* Make sure all remaining elements are still accessible */
    157   nodep = Curl_hash_pick(&hash_static, &key2, strlen(key2));
    158   fail_unless(nodep == key2, "hash retrieval failed");
    159   nodep = Curl_hash_pick(&hash_static, &key3, strlen(key3));
    160   fail_unless(nodep == key3, "hash retrieval failed");
    161 
    162   /* Add element with own destructor */
    163   nodep = Curl_hash_add2(&hash_static, &key1, strlen(key1), &key1,
    164                          my_elem_dtor);
    165   fail_unless(nodep, "add2 insertion into hash failed");
    166   fail_unless(elem_dtor_calls == 0, "element destructor count should be 0");
    167   /* Add it again, should invoke destructor on first */
    168   nodep = Curl_hash_add2(&hash_static, &key1, strlen(key1), &key1,
    169                          my_elem_dtor);
    170   fail_unless(nodep, "add2 again, insertion into hash failed");
    171   fail_unless(elem_dtor_calls == 1, "element destructor count should be 1");
    172   /* remove, should invoke destructor */
    173   rc = Curl_hash_delete(&hash_static, &key1, strlen(key1));
    174   fail_unless(rc == 0, "hash delete failed");
    175   fail_unless(elem_dtor_calls == 2, "element destructor count should be 1");
    176 
    177   /* Clean up */
    178   Curl_hash_clean(&hash_static);
    179 
    180   UNITTEST_END(t1603_stop(&hash_static))
    181 }