test_hashtable.c (13160B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* 5 * test_hashtable.c 6 * 7 * Tests Hashtables 8 * 9 */ 10 11 #include "testutil.h" 12 #include "testutil_nss.h" 13 14 static void *plContext = NULL; 15 16 static void 17 createHashTables( 18 PKIX_PL_HashTable **ht, 19 PKIX_PL_HashTable **ht2, 20 PKIX_PL_HashTable **ht3, 21 PKIX_PL_HashTable **ht4) 22 { 23 PKIX_TEST_STD_VARS(); 24 25 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Create(1, 0, ht, plContext)); 26 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Create(5, 0, ht2, plContext)); 27 28 /* at most two entries per bucket */ 29 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Create(1, 2, ht4, plContext)); 30 31 *ht3 = *ht; 32 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)*ht3, plContext)); 33 34 cleanup: 35 PKIX_TEST_RETURN(); 36 } 37 38 static void 39 testAdd( 40 PKIX_PL_HashTable *ht, 41 PKIX_PL_HashTable *ht2, 42 PKIX_PL_String **testString, 43 PKIX_PL_String **testString2, 44 PKIX_PL_String **testString3, 45 PKIX_PL_OID **testOID) 46 { 47 char *dummyString = "test string 1"; 48 char *dummyString2 = "test string 2"; 49 char *dummyString3 = "test string 3"; 50 char *dummyOID = "2.11.22222.33333"; 51 52 PKIX_TEST_STD_VARS(); 53 54 /* Make some dummy objects */ 55 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create( 56 PKIX_ESCASCII, 57 dummyString, 58 PL_strlen(dummyString), 59 testString, 60 plContext)); 61 62 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create( 63 PKIX_ESCASCII, 64 dummyString2, 65 PL_strlen(dummyString2), 66 testString2, 67 plContext)); 68 69 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create( 70 PKIX_ESCASCII, 71 dummyString3, 72 PL_strlen(dummyString3), 73 testString3, 74 plContext)); 75 76 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(dummyOID, testOID, plContext)); 77 78 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht, 79 (PKIX_PL_Object *)*testString, 80 (PKIX_PL_Object *)*testString2, 81 plContext)); 82 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht2, 83 (PKIX_PL_Object *)*testString, 84 (PKIX_PL_Object *)*testString2, 85 plContext)); 86 87 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht, 88 (PKIX_PL_Object *)*testString2, 89 (PKIX_PL_Object *)*testString, 90 plContext)); 91 92 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht2, 93 (PKIX_PL_Object *)*testString2, 94 (PKIX_PL_Object *)*testString, 95 plContext)); 96 97 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht, 98 (PKIX_PL_Object *)*testOID, 99 (PKIX_PL_Object *)*testOID, 100 plContext)); 101 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht2, 102 (PKIX_PL_Object *)*testOID, 103 (PKIX_PL_Object *)*testOID, 104 plContext)); 105 106 cleanup: 107 PKIX_TEST_RETURN(); 108 } 109 110 static void 111 testAddFIFO( 112 PKIX_PL_HashTable *ht, 113 PKIX_PL_String **testString, 114 PKIX_PL_String **testString2, 115 PKIX_PL_String **testString3) 116 { 117 PKIX_PL_String *targetString = NULL; 118 PKIX_Boolean cmpResult; 119 120 PKIX_TEST_STD_VARS(); 121 122 /* 123 * ht is created as one bucket, two entries per bucket. Since we add 124 * three items to the ht, we expect the first one to be deleted. 125 */ 126 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht, 127 (PKIX_PL_Object *)*testString, 128 (PKIX_PL_Object *)*testString, 129 plContext)); 130 131 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht, 132 (PKIX_PL_Object *)*testString2, 133 (PKIX_PL_Object *)*testString2, 134 plContext)); 135 136 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Add(ht, 137 (PKIX_PL_Object *)*testString3, 138 (PKIX_PL_Object *)*testString3, 139 plContext)); 140 141 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht, 142 (PKIX_PL_Object *)*testString, 143 (PKIX_PL_Object **)&targetString, 144 plContext)); 145 if (targetString != NULL) { 146 testError("HashTable_Lookup retrieved a supposed deleted item"); 147 PKIX_TEST_DECREF_BC(targetString); 148 } 149 150 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht, 151 (PKIX_PL_Object *)*testString3, 152 (PKIX_PL_Object **)&targetString, 153 plContext)); 154 155 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals( 156 (PKIX_PL_Object *)targetString, 157 (PKIX_PL_Object *)*testString3, 158 &cmpResult, 159 plContext)); 160 if (cmpResult != PKIX_TRUE) { 161 testError("HashTable_Lookup failed"); 162 } 163 PKIX_TEST_DECREF_BC(targetString); 164 165 cleanup: 166 PKIX_TEST_RETURN(); 167 } 168 169 static void 170 testLookup( 171 PKIX_PL_HashTable *ht, 172 PKIX_PL_HashTable *ht2, 173 PKIX_PL_String *testString, 174 PKIX_PL_String *testString2, 175 PKIX_PL_String *testString3, 176 PKIX_PL_OID *testOID) 177 { 178 PKIX_PL_String *targetString = NULL; 179 PKIX_PL_String *targetOID = NULL; 180 PKIX_Boolean cmpResult; 181 182 PKIX_TEST_STD_VARS(); 183 184 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht, 185 (PKIX_PL_Object *)testString, 186 (PKIX_PL_Object **)&targetString, 187 plContext)); 188 189 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals( 190 (PKIX_PL_Object *)targetString, 191 (PKIX_PL_Object *)testString2, 192 &cmpResult, 193 plContext)); 194 if (cmpResult != PKIX_TRUE) { 195 testError("HashTable_Lookup failed"); 196 } 197 PKIX_TEST_DECREF_BC(targetString); 198 199 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht2, 200 (PKIX_PL_Object *)testString, 201 (PKIX_PL_Object **)&targetString, 202 plContext)); 203 204 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals( 205 (PKIX_PL_Object *)targetString, 206 (PKIX_PL_Object *)testString2, 207 &cmpResult, 208 plContext)); 209 if (cmpResult != PKIX_TRUE) { 210 testError("HashTable_Lookup failed"); 211 } 212 PKIX_TEST_DECREF_BC(targetString); 213 214 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht2, 215 (PKIX_PL_Object *)testString2, 216 (PKIX_PL_Object **)&targetString, 217 plContext)); 218 219 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals( 220 (PKIX_PL_Object *)targetString, 221 (PKIX_PL_Object *)testString, 222 &cmpResult, 223 plContext)); 224 if (cmpResult != PKIX_TRUE) { 225 testError("HashTable_Lookup failed"); 226 } 227 PKIX_TEST_DECREF_BC(targetString); 228 229 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht, 230 (PKIX_PL_Object *)testOID, 231 (PKIX_PL_Object **)&targetOID, 232 plContext)); 233 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)targetOID, &targetString, plContext)); 234 235 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals( 236 (PKIX_PL_Object *)targetOID, 237 (PKIX_PL_Object *)testOID, 238 &cmpResult, 239 plContext)); 240 if (cmpResult != PKIX_TRUE) { 241 testError("HashTable_Lookup failed"); 242 } 243 PKIX_TEST_DECREF_BC(targetString); 244 PKIX_TEST_DECREF_BC(targetOID); 245 246 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht2, 247 (PKIX_PL_Object *)testOID, 248 (PKIX_PL_Object **)&targetOID, 249 plContext)); 250 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)targetOID, &targetString, plContext)); 251 252 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals( 253 (PKIX_PL_Object *)targetOID, 254 (PKIX_PL_Object *)testOID, 255 &cmpResult, 256 plContext)); 257 if (cmpResult != PKIX_TRUE) { 258 testError("HashTable_Lookup failed"); 259 } 260 PKIX_TEST_DECREF_BC(targetString); 261 PKIX_TEST_DECREF_BC(targetOID); 262 263 (void)printf("Looking up item not in HashTable.\n"); 264 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Lookup(ht, 265 (PKIX_PL_Object *)testString3, 266 (PKIX_PL_Object **)&targetString, 267 plContext)); 268 if (targetString == NULL) 269 (void)printf("\tCorrectly returned NULL.\n"); 270 else 271 testError("Hashtable did not return NULL value as expected"); 272 273 cleanup: 274 PKIX_TEST_RETURN(); 275 } 276 277 static void 278 testRemove( 279 PKIX_PL_HashTable *ht, 280 PKIX_PL_HashTable *ht2, 281 PKIX_PL_String *testString, 282 PKIX_PL_String *testString2, 283 PKIX_PL_OID *testOID) 284 { 285 286 PKIX_TEST_STD_VARS(); 287 288 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Remove(ht, 289 (PKIX_PL_Object *)testString, 290 plContext)); 291 292 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Remove(ht, 293 (PKIX_PL_Object *)testOID, 294 plContext)); 295 296 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HashTable_Remove(ht2, 297 (PKIX_PL_Object *)testString2, 298 plContext)); 299 300 PKIX_TEST_EXPECT_ERROR(PKIX_PL_HashTable_Remove(ht, 301 (PKIX_PL_Object *)testString, 302 plContext)); 303 304 cleanup: 305 PKIX_TEST_RETURN(); 306 } 307 308 static void 309 testDestroy( 310 PKIX_PL_HashTable *ht, 311 PKIX_PL_HashTable *ht2, 312 PKIX_PL_HashTable *ht3, 313 PKIX_PL_HashTable *ht4) 314 { 315 PKIX_TEST_STD_VARS(); 316 317 PKIX_TEST_DECREF_BC(ht); 318 PKIX_TEST_DECREF_BC(ht2); 319 PKIX_TEST_DECREF_BC(ht3); 320 PKIX_TEST_DECREF_BC(ht4); 321 322 cleanup: 323 PKIX_TEST_RETURN(); 324 } 325 326 int 327 test_hashtable(int argc, char *argv[]) 328 { 329 330 PKIX_PL_HashTable *ht, *ht2, *ht3, *ht4; 331 PKIX_PL_String *testString, *testString2, *testString3; 332 PKIX_PL_OID *testOID; 333 PKIX_UInt32 actualMinorVersion; 334 PKIX_UInt32 j = 0; 335 336 PKIX_TEST_STD_VARS(); 337 338 startTests("HashTables"); 339 340 PKIX_TEST_EXPECT_NO_ERROR( 341 PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext)); 342 343 subTest("PKIX_PL_HashTable_Create"); 344 createHashTables(&ht, &ht2, &ht3, &ht4); 345 346 PKIX_TEST_EQ_HASH_TOSTR_DUP(ht, 347 ht3, 348 ht2, 349 NULL, 350 HashTable, 351 PKIX_FALSE); 352 353 subTest("PKIX_PL_HashTable_Add"); 354 testAdd(ht, ht2, &testString, &testString2, &testString3, &testOID); 355 356 subTest("PKIX_PL_HashTable_ADD - with Bucket Size limit"); 357 testAddFIFO(ht4, &testString, &testString2, &testString3); 358 359 subTest("PKIX_PL_HashTable_Lookup"); 360 testLookup(ht, ht2, testString, testString2, testString3, testOID); 361 362 subTest("PKIX_PL_HashTable_Remove"); 363 testRemove(ht, ht2, testString, testString2, testOID); 364 365 PKIX_TEST_DECREF_BC(testString); 366 PKIX_TEST_DECREF_BC(testString2); 367 PKIX_TEST_DECREF_BC(testString3); 368 PKIX_TEST_DECREF_BC(testOID); 369 370 subTest("PKIX_PL_HashTable_Destroy"); 371 testDestroy(ht, ht2, ht3, ht4); 372 373 cleanup: 374 375 PKIX_Shutdown(plContext); 376 377 endTests("BigInt"); 378 379 return (0); 380 }