unit_hpack_tables.c (102531B)
1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ 2 /* 3 This file is part of GNU libmicrohttpd. 4 Copyright (C) 2025 Evgeny Grin (Karlson2k) 5 6 GNU libmicrohttpd is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 GNU libmicrohttpd is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 Alternatively, you can redistribute GNU libmicrohttpd and/or 17 modify it under the terms of the GNU General Public License as 18 published by the Free Software Foundation; either version 2 of 19 the License, or (at your option) any later version, together 20 with the eCos exception, as follows: 21 22 As a special exception, if other files instantiate templates or 23 use macros or inline functions from this file, or you compile this 24 file and link it with other works to produce a work based on this 25 file, this file does not by itself cause the resulting work to be 26 covered by the GNU General Public License. However the source code 27 for this file must still be made available in accordance with 28 section (3) of the GNU General Public License v2. 29 30 This exception does not invalidate any other reasons why a work 31 based on this file might be covered by the GNU General Public 32 License. 33 34 You should have received copies of the GNU Lesser General Public 35 License and the GNU General Public License along with this library; 36 if not, see <https://www.gnu.org/licenses/>. 37 */ 38 39 /** 40 * @file src/test/unit/unit_hpack_tables.c 41 * @brief The tests for HPACK tables functions 42 * @author Karlson2k (Evgeny Grin) 43 */ 44 45 46 #include "mhd_sys_options.h" 47 48 #define mhd_HPACK_TESTING_TABLES_ONLY 1 49 /* Include .c file (!) to access static functions. 50 Only official interface mhd_* is used to handle the tables. */ 51 #include "h2/hpack/mhd_hpack_codec.c" 52 53 #include "mhdt_has_in_name.h" 54 #include "mhdt_has_param.h" 55 #include "mhdt_checks.h" 56 57 #ifndef MHD_ENABLE_SLOW_TESTS 58 static int mhdtl_enable_deep_tests = 0; 59 #else 60 static int mhdtl_enable_deep_tests = ! 0; 61 #endif 62 63 #define MHDTL_DYN_ENTRY_MIN_SIZE mhd_HPACK_ENTRY_OVERHEAD 64 65 /* 66 * Local test helpers 67 */ 68 69 #define MHDTL_HPACK_ENTRY_SIZE(name_len,val_len) \ 70 (name_len + val_len + mhd_HPACK_ENTRY_OVERHEAD) 71 72 73 static inline uint_least16_t 74 mhdtl_rotl16 (uint_least16_t val, unsigned int rot) 75 { 76 return 77 (uint_least16_t) 78 (((val & 0xFFFFu) << (rot % 16u)) 79 | ((val & 0xFFFFu) >> ((16u - (rot % 16u)) % 16u))); 80 } 81 82 83 static inline uint_least16_t 84 mhdtl_mix16 (uint_fast16_t a, uint_fast16_t b) 85 { 86 /* Mix with Golden Ratio's fractional part */ 87 uint_least16_t res = 88 (uint_least16_t) (((a & 0xFFFFu) * 0x9E37u) 89 ^ mhdtl_rotl16 ((uint_least16_t) b, 5)); 90 /* Re-mix bits better */ 91 res ^= (uint_least16_t) (res >> 7); 92 res = (uint_least16_t) ((res * 0x9E37u) & 0xFFFFu); 93 res ^= (uint_least16_t) (res >> 9); 94 95 return res; 96 } 97 98 99 static size_t 100 mhdtl_dyn_get_size_used (const struct mhd_HpackDTblContext *dyn) 101 { 102 const size_t used = mhd_dtbl_get_table_used (dyn); 103 MHDT_EXPECT_UINT_GE_VAL (mhd_dtbl_get_table_max_size (dyn), \ 104 used); 105 return used; 106 } 107 108 109 static size_t 110 mhdtl_dyn_get_free (const struct mhd_HpackDTblContext *dyn) 111 { 112 const size_t used = mhd_dtbl_get_table_used (dyn); 113 const size_t max_size = mhd_dtbl_get_table_max_size (dyn); 114 MHDT_EXPECT_UINT_GE_VAL (max_size, used); 115 return max_size - used; 116 } 117 118 119 #define MHDTL_DTBL_FIND_ENTRY_STR(dyn,name,val) \ 120 mhd_dtbl_find_entry (dyn, strlen (name), name, strlen (val), val) 121 122 #define MHDTL_DTBL_FIND_NAME_STR(dyn,name) \ 123 mhd_dtbl_find_name (dyn, strlen (name), name) 124 125 126 /* Return non-zero if succeeded, zero if failed */ 127 static int 128 mhdtl_dyn_check_get_valid_invalid (const struct mhd_HpackDTblContext *dyn) 129 { 130 const dtbl_idx_ft num_entries = (dtbl_idx_t) mhd_dtbl_get_num_entries (dyn); 131 struct mhd_BufferConst check_name; 132 struct mhd_BufferConst check_value; 133 134 if (! MHDT_EXPECT_FALSE_D (mhd_dtbl_get_entry (dyn, \ 135 mhd_HPACK_STBL_LAST_IDX + 1u \ 136 + num_entries, \ 137 &check_name, \ 138 &check_value), \ 139 "getting entry with the index outside valid " 140 "range should fail")) 141 return 0; 142 143 if (0u == num_entries) 144 return ! 0; 145 146 if (! MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \ 147 mhd_HPACK_STBL_LAST_IDX + 1u, \ 148 &check_name, \ 149 &check_value), \ 150 "non-empty table should return successfully " \ 151 "the first valid entry")) 152 return 0; 153 if (! MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \ 154 mhd_HPACK_STBL_LAST_IDX \ 155 + num_entries, \ 156 &check_name, \ 157 &check_value), \ 158 "non-empty table should return successfully " \ 159 "the last valid entry")) 160 return 0; 161 162 return ! 0; 163 } 164 165 166 /* Return non-zero if succeeded, zero if failed */ 167 static int 168 mhdtl_dyn_check_entry_n_at_idx (struct mhd_HpackDTblContext *dyn, 169 size_t idx, 170 size_t expect_name_len, 171 const char *expect_name, 172 size_t expect_value_len, 173 const char *expect_value) 174 { 175 struct mhd_BufferConst check_name; 176 struct mhd_BufferConst check_value; 177 178 dtbl_idx_t idx_idx = (dtbl_idx_t) idx; 179 if (0 == idx) 180 MHDT_ERR_EXIT (); 181 if (idx_idx != idx) 182 MHDT_ERR_EXIT (); 183 184 if (MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \ 185 idx_idx, \ 186 &check_name, \ 187 &check_value), \ 188 "the entry with specified index should exist")) 189 { 190 MHDT_EXPECT_STRN_EQ_STR_D (check_name.size, \ 191 check_name.data, \ 192 expect_name, \ 193 "the name of the entry should match " \ 194 "expected value"); 195 MHDT_EXPECT_STRN_EQ_STR_D (check_value.size, \ 196 check_value.data, \ 197 expect_value, \ 198 "the name of the entry should match " \ 199 "expected value"); 200 } 201 else 202 return 0; 203 204 /* It should be possible to find the entry. The index could be different 205 if entries are duplicated. */ 206 207 MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_entry (dyn, \ 208 expect_name_len, \ 209 expect_name, \ 210 expect_value_len, \ 211 expect_value), \ 212 mhd_HPACK_STBL_LAST_IDX, \ 213 "search by known entry name and value " \ 214 "should succeed"); 215 MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_name (dyn, \ 216 expect_name_len, \ 217 expect_name), \ 218 mhd_HPACK_STBL_LAST_IDX, \ 219 "search by known entry name " \ 220 "should succeed"); 221 222 return ! 0; 223 } 224 225 226 /* Return non-zero if succeeded, zero if failed */ 227 static int 228 mhdtl_dyn_check_entry_at_idx (struct mhd_HpackDTblContext *dyn, 229 size_t idx, 230 const char *expect_name, 231 const char *expect_value) 232 { 233 return mhdtl_dyn_check_entry_n_at_idx (dyn, 234 idx, 235 strlen (expect_name), 236 expect_name, 237 strlen (expect_value), 238 expect_value); 239 } 240 241 242 /* Return non-zero if succeeded, zero if failed */ 243 static MHD_FN_PAR_IN_SIZE_ (3,2) MHD_FN_PAR_IN_SIZE_ (5,4) int 244 mhdtl_dyn_add_hdr_n_with_check (struct mhd_HpackDTblContext *dyn, 245 size_t hdr_name_len, 246 const char *hdr_name, 247 size_t hdr_value_len, 248 const char *hdr_value) 249 { 250 char prev_name_buf[512]; 251 size_t prev_name_len = 0u; 252 char prev_val_buf[512]; 253 size_t prev_val_len = 0u; 254 int have_prev_entry = 0; 255 char last_name_buf[512]; 256 size_t last_name_len = 0u; 257 char last_val_buf[512]; 258 size_t last_val_len = 0u; 259 int have_last_entry = 0; 260 const size_t hdr_size = MHDTL_HPACK_ENTRY_SIZE (hdr_name_len, hdr_value_len); 261 const size_t table_max_size = mhd_dtbl_get_table_max_size (dyn); 262 const size_t table_free_before = mhdtl_dyn_get_free (dyn); 263 const dtbl_idx_ft num_entries_before = (dtbl_idx_t) 264 mhd_dtbl_get_num_entries (dyn); 265 struct mhd_BufferConst check_name = {0u, NULL}; 266 struct mhd_BufferConst check_value = {0u, NULL}; 267 268 if ((mhd_DTBL_MAX_SIZE < hdr_name_len) || 269 (mhd_DTBL_MAX_SIZE < hdr_value_len) || 270 (mhd_DTBL_MAX_SIZE < hdr_size)) 271 MHDT_ERR_EXIT (); 272 273 MHDT_EXPECT_UINT_GE_VAL (table_max_size, table_free_before); 274 MHDT_EXPECT_UINT_GE_VAL_D (mhdtl_dyn_get_size_used (dyn), \ 275 num_entries_before * MHDTL_DYN_ENTRY_MIN_SIZE, \ 276 "Each entry should have at least a minimal size"); 277 278 if (mhd_dtbl_get_entry (dyn, 279 mhd_HPACK_STBL_LAST_IDX + 1u, 280 &check_name, &check_value)) 281 { /* Check whether the current newest entry and the new entry will fit 282 the table together */ 283 if (hdr_size + MHDTL_HPACK_ENTRY_SIZE (check_name.size, check_value.size) 284 <= mhd_dtbl_get_table_max_size (dyn)) 285 { 286 if ((sizeof(prev_name_buf) > check_name.size) 287 && (sizeof(prev_val_buf) > check_value.size)) 288 { 289 /* Save the first entry to check later that it is not changed after 290 adding the new entry */ 291 memcpy (prev_name_buf, 292 check_name.data, 293 check_name.size); 294 prev_name_buf[check_name.size] = 0; /* Zero-terminate for convenience */ 295 prev_name_len = check_name.size; 296 memcpy (prev_val_buf, 297 check_value.data, 298 check_value.size); 299 prev_val_buf[check_value.size] = 0; /* Zero-terminate for convenience */ 300 prev_val_len = check_value.size; 301 have_prev_entry = ! 0; 302 } 303 } 304 } 305 if ((1u < mhd_dtbl_get_num_entries (dyn)) 306 && (hdr_size <= table_free_before)) 307 { 308 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, 309 mhd_HPACK_STBL_LAST_IDX 310 + num_entries_before, 311 &check_name, &check_value))) 312 { 313 if ((sizeof(last_name_buf) > check_name.size) 314 && (sizeof(last_val_buf) > check_value.size)) 315 { 316 /* Save the last entry to check later that it is not changed after 317 adding the new entry */ 318 memcpy (last_name_buf, 319 check_name.data, 320 check_name.size); 321 last_name_buf[check_name.size] = 0; /* Zero-terminate for convenience */ 322 last_name_len = check_name.size; 323 memcpy (last_val_buf, 324 check_value.data, 325 check_value.size); 326 last_val_buf[check_value.size] = 0; /* Zero-terminate for convenience */ 327 last_val_len = check_value.size; 328 have_last_entry = ! 0; 329 } 330 } 331 } 332 333 mhd_dtbl_new_entry (dyn, 334 hdr_name_len, 335 hdr_name, 336 hdr_value_len, 337 hdr_value); 338 339 if (hdr_size <= table_free_before) 340 { 341 /* No eviction */ 342 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), \ 343 num_entries_before + 1u, \ 344 "added one entry without eviction"); 345 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_free (dyn), \ 346 table_free_before - hdr_size); 347 if (have_last_entry) 348 mhdtl_dyn_check_entry_n_at_idx (dyn, 349 mhd_HPACK_STBL_LAST_IDX 350 + num_entries_before + 1u, 351 last_name_len, 352 last_name_buf, 353 last_val_len, 354 last_val_buf); 355 } 356 else 357 { 358 /* Eviction */ 359 MHDT_EXPECT_UINT_LE_VAL_D (mhd_dtbl_get_num_entries (dyn), \ 360 num_entries_before, 361 "some entries evicted when adding new entry"); 362 if (hdr_size > table_max_size) 363 { 364 /* Full eviction */ 365 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 0u, \ 366 "all entries evicted by adding too large " \ 367 "new entry"); 368 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_free (dyn), table_max_size); 369 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), \ 370 table_max_size); 371 return ! 0; 372 } 373 else if (hdr_size + MHDTL_DYN_ENTRY_MIN_SIZE > table_max_size) 374 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 1u, \ 375 "exactly one new entry fits the table"); 376 else 377 MHDT_EXPECT_UINT_GE_VAL_D (mhd_dtbl_get_num_entries (dyn), 1u, 378 "some entries evicted and one entry added"); 379 380 } 381 382 /* The new entry has been added to the table */ 383 384 if (1u == mhd_dtbl_get_num_entries (dyn)) 385 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), hdr_size); 386 else 387 MHDT_EXPECT_UINT_GE_VAL (mhdtl_dyn_get_size_used (dyn), \ 388 hdr_size + MHDTL_DYN_ENTRY_MIN_SIZE); 389 390 if (! MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \ 391 mhd_HPACK_STBL_LAST_IDX + 1u, \ 392 &check_name, \ 393 &check_value), \ 394 "new entry should be available as the newest " \ 395 "entry in the dynamic table")) 396 return 0; 397 398 if (! MHDT_EXPECT_STRN_EQ_D (check_name.size, \ 399 check_name.data, \ 400 hdr_name_len, \ 401 hdr_name, \ 402 "The name of the newest entry should " \ 403 "match the last added entry's name")) 404 return 0; 405 if (! MHDT_EXPECT_STRN_EQ_D (check_value.size, \ 406 check_value.data, \ 407 hdr_value_len, \ 408 hdr_value, \ 409 "The value of the newest entry should " \ 410 "match the last added entry's value")) 411 return 0; 412 413 if (! MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_entry (dyn, \ 414 hdr_name_len, \ 415 hdr_name, \ 416 hdr_value_len, \ 417 hdr_value), \ 418 mhd_HPACK_STBL_LAST_IDX, \ 419 "search for the newly added entry should " \ 420 "be successful")) 421 return 0; 422 if (! MHDT_EXPECT_UINT_GT_VAL_D (mhd_dtbl_find_name (dyn, \ 423 hdr_name_len, \ 424 hdr_name), \ 425 mhd_HPACK_STBL_LAST_IDX, \ 426 "search for the newly added entry name " 427 "should be successful")) 428 return 0; 429 430 if (have_prev_entry) 431 { 432 if (MHDT_EXPECT_TRUE_D (mhd_dtbl_get_entry (dyn, \ 433 mhd_HPACK_STBL_LAST_IDX + 2u, \ 434 &check_name, &check_value), \ 435 "previous entry must remain the same")) 436 { 437 MHDT_EXPECT_STRN_EQ_D (check_name.size, check_name.data, \ 438 prev_name_len, prev_name_buf, \ 439 "previous entry must be unchanged"); 440 MHDT_EXPECT_STRN_EQ_D (check_value.size, check_value.data, \ 441 prev_val_len, prev_val_buf, \ 442 "previous entry must be unchanged"); 443 } 444 } 445 446 447 mhdtl_dyn_check_get_valid_invalid (dyn); 448 449 return ! 0; 450 } 451 452 453 /* Return non-zero if succeeded, zero if failed */ 454 static MHD_FN_PAR_CSTR_ (2) MHD_FN_PAR_CSTR_ (3) int 455 mhdtl_dyn_add_hdr_with_check (struct mhd_HpackDTblContext *dyn, 456 const char *hdr_name, 457 const char *hdr_value) 458 { 459 const size_t hdr_name_len = strlen (hdr_name); 460 const size_t hdr_value_len = strlen (hdr_value); 461 462 return mhdtl_dyn_add_hdr_n_with_check (dyn, 463 hdr_name_len, 464 hdr_name, 465 hdr_value_len, 466 hdr_value); 467 } 468 469 470 /* Return non-zero if succeeded, zero if failed */ 471 static int 472 mhdtl_dyn_add_sized_strs_with_check (struct mhd_HpackDTblContext *dyn, 473 size_t hdr_strings_size) 474 { 475 #define MHDTL_NAMES_BUF_SIZE 512 476 static char names[MHDTL_NAMES_BUF_SIZE] = ""; 477 static char values[MHDTL_NAMES_BUF_SIZE] = ""; 478 #undef MHDTL_NAMES_BUF_SIZE 479 /* Use '- 1u' to have valid addresses for zero-sized names and values */ 480 static const size_t bufs_size = sizeof(names) - 1u; 481 static size_t names_off = 0u; 482 static size_t values_off = 0u; 483 size_t name_size; 484 size_t value_size; 485 char *hdr_name; 486 char *hdr_value; 487 488 if ((bufs_size + bufs_size) < hdr_strings_size) 489 MHDT_ERR_EXIT_D ("the entry must not be larger than a hardcoded limit"); 490 491 if (0 == values[0]) 492 { 493 size_t i; 494 for (i = 0; i < sizeof(names); ++i) 495 { 496 names[i] = (char) ('a' + (char) (i % ('z' - 'a' + 1))); 497 values[i] = (char) (' ' + (char) ((bufs_size - i) % ('~' - ' ' + 1))); 498 } 499 } 500 501 value_size = hdr_strings_size / 2; 502 name_size = hdr_strings_size - value_size; 503 504 hdr_name = 505 names + (names_off++) % (bufs_size - name_size + 1u); 506 hdr_value = 507 values + (bufs_size - value_size) 508 - ((values_off++) % (bufs_size - value_size + 1u)); 509 510 return mhdtl_dyn_add_hdr_n_with_check (dyn, 511 name_size, 512 hdr_name, 513 value_size, 514 hdr_value); 515 } 516 517 518 /* Return non-zero if succeeded, zero if failed */ 519 static int 520 mhdtl_dyn_add_sized_entry_with_check (struct mhd_HpackDTblContext *dyn, 521 size_t entry_size) 522 { 523 if (MHDTL_DYN_ENTRY_MIN_SIZE > entry_size) 524 MHDT_ERR_EXIT_D ("the entry must be at least a minimal entry size"); 525 526 return mhdtl_dyn_add_sized_strs_with_check (dyn, 527 entry_size 528 - mhd_HPACK_ENTRY_OVERHEAD); 529 } 530 531 532 static void 533 mhdtl_stat_check_entry_n_at_idx (size_t idx, 534 size_t expect_name_len, 535 const char *expect_name, 536 size_t expect_value_len, 537 const char *expect_value) 538 { 539 struct mhd_BufferConst check_name; 540 struct mhd_BufferConst check_value; 541 542 dtbl_idx_t idx_idx = (dtbl_idx_t) idx; 543 if (0 == idx) 544 MHDT_ERR_EXIT (); 545 if (idx_idx != idx) 546 MHDT_ERR_EXIT (); 547 if (0u == idx) 548 MHDT_ERR_EXIT (); 549 if (mhd_HPACK_STBL_LAST_IDX < idx) 550 MHDT_ERR_EXIT (); 551 if (0u == expect_name_len) 552 MHDT_ERR_EXIT (); 553 if ((':' == expect_name[0]) != (idx < (mhd_HPACK_STBL_NORM_START_POS + 1u))) 554 MHDT_ERR_EXIT (); 555 556 mhd_stbl_get_entry (idx_idx, 557 &check_name, 558 &check_value); 559 560 MHDT_EXPECT_STRN_EQ_STR_D (check_name.size, \ 561 check_name.data, \ 562 expect_name, \ 563 "the name of the entry should match " \ 564 "expected value"); 565 MHDT_EXPECT_STRN_EQ_STR_D (check_value.size, \ 566 check_value.data, \ 567 expect_value, \ 568 "the name of the entry should match " \ 569 "expected value"); 570 571 /* It should be possible to find the entry. The index could be different 572 if entries are duplicated. */ 573 574 if (':' != expect_name[0]) 575 { 576 MHDT_EXPECT_UINT_NE_VAL_D (mhd_stbl_find_entry_real (expect_name_len, \ 577 expect_name, \ 578 expect_value_len, 579 expect_value), \ 580 0u, \ 581 "search by known entry name and value " \ 582 "should not fail"); 583 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_stbl_find_entry_real (expect_name_len, \ 584 expect_name, \ 585 expect_value_len, 586 expect_value), \ 587 idx, \ 588 "search by known entry name and value " \ 589 "should return the " \ 590 "known entry index"); 591 592 MHDT_EXPECT_UINT_NE_VAL_D (mhd_stbl_find_name_real (expect_name_len, \ 593 expect_name), \ 594 0u, \ 595 "search by known entry name " \ 596 "should not fail"); 597 MHDT_EXPECT_UINT_LE_VAL_D (mhd_stbl_find_name_real (expect_name_len, \ 598 expect_name), \ 599 idx, \ 600 "search by known entry name " \ 601 "should return value not greater than the " \ 602 "known entry index"); 603 } 604 else 605 { 606 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_stbl_find_entry_real (expect_name_len, \ 607 expect_name, \ 608 expect_value_len, 609 expect_value), \ 610 0u, \ 611 "search by pseudo-header entry name " \ 612 "and value should fail"); 613 614 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_stbl_find_name_real (expect_name_len, \ 615 expect_name), \ 616 0u, \ 617 "search by pseudo-header entry name " \ 618 "should fail"); 619 } 620 } 621 622 623 static void 624 mhdtl_stat_check_entry_at_idx (size_t idx, 625 const char *expect_name, 626 const char *expect_value) 627 { 628 mhdtl_stat_check_entry_n_at_idx (idx, 629 strlen (expect_name), 630 expect_name, 631 strlen (expect_value), 632 expect_value); 633 } 634 635 636 #define MHDTL_STBL_FIND_ENTRY_REAL_STR(name,value) \ 637 mhd_stbl_find_entry_real (strlen (name),(name), \ 638 strlen (value),(value)) 639 #define MHDTL_STBL_FIND_NAME_REAL_STR(name) \ 640 mhd_stbl_find_name_real (strlen (name),(name)) 641 642 643 /* Return non-zero if succeeded, zero if failed */ 644 static int 645 mhdtl_comb_check_entry_n_at_idx (struct mhd_HpackDTblContext *dyn, 646 size_t idx, 647 size_t expect_name_len, 648 const char *expect_name, 649 size_t expect_value_len, 650 const char *expect_value) 651 { 652 struct mhd_BufferConst check_name; 653 struct mhd_BufferConst check_value; 654 655 dtbl_idx_t idx_idx = (dtbl_idx_t) idx; 656 dtbl_idx_t found_by_name_and_value; 657 dtbl_idx_t found_by_name_only; 658 if (0 == idx) 659 MHDT_ERR_EXIT (); 660 if (idx_idx != idx) 661 MHDT_ERR_EXIT (); 662 if ((':' == expect_name[0]) != (idx < (mhd_HPACK_STBL_NORM_START_POS + 1u))) 663 MHDT_ERR_EXIT_D ("pseudo-header entries are allowed only at first " \ 664 "static table positions"); 665 666 if (MHDT_EXPECT_TRUE_D (mhd_htbl_get_entry (dyn, \ 667 idx_idx, \ 668 &check_name, \ 669 &check_value), \ 670 "the entry with specified index should exist")) 671 { 672 MHDT_EXPECT_STRN_EQ_STR_D (check_name.size, \ 673 check_name.data, \ 674 expect_name, \ 675 "the name of the entry should match " \ 676 "expected value"); 677 MHDT_EXPECT_STRN_EQ_STR_D (check_value.size, \ 678 check_value.data, \ 679 expect_value, \ 680 "the name of the entry should match " \ 681 "expected value"); 682 } 683 else 684 return 0; 685 686 /* It should be possible to find the entry. */ 687 found_by_name_and_value = 688 mhd_htbl_find_entry_real (dyn, 689 expect_name_len, 690 expect_name, 691 expect_value_len, 692 expect_value); 693 found_by_name_only = 694 mhd_htbl_find_name_real (dyn, 695 expect_name_len, 696 expect_name); 697 698 if ((0u == expect_name_len) || 699 (':' != expect_name[0])) 700 { 701 MHDT_EXPECT_UINT_NE_VAL_D (found_by_name_and_value, \ 702 0u, \ 703 "search by known entry name and value " \ 704 "should not fail"); 705 MHDT_EXPECT_UINT_LE_VAL_D (found_by_name_and_value, \ 706 mhd_HPACK_STBL_LAST_IDX \ 707 + mhd_dtbl_get_num_entries (dyn), \ 708 "search by known entry name and value " \ 709 "should return a valid index number"); 710 if (mhd_HPACK_STBL_LAST_IDX >= idx) 711 MHDT_EXPECT_UINT_EQ_VAL_D (found_by_name_and_value, \ 712 idx, \ 713 "search by known entry name and value " \ 714 "should return the " \ 715 "known entry index"); 716 717 718 MHDT_EXPECT_UINT_NE_VAL_D (found_by_name_only, \ 719 0u, \ 720 "search by known entry name " \ 721 "should not fail"); 722 MHDT_EXPECT_UINT_LE_VAL_D (found_by_name_only, \ 723 mhd_HPACK_STBL_LAST_IDX \ 724 + mhd_dtbl_get_num_entries (dyn), \ 725 "search by known entry name " \ 726 "should return a valid index number"); 727 /* The next check is not required by RFC, but guaranteed by implementation 728 design. */ 729 if (mhd_HPACK_STBL_LAST_IDX >= idx) 730 MHDT_EXPECT_UINT_LE_VAL_D (found_by_name_and_value, \ 731 mhd_HPACK_STBL_LAST_IDX, \ 732 "search by known static entry name " \ 733 "should return the " \ 734 "static table index"); 735 } 736 else 737 { 738 MHDT_EXPECT_UINT_EQ_VAL_D (found_by_name_and_value, \ 739 0u, \ 740 "search by pseudo-header entry name " \ 741 "and value should fail"); 742 743 MHDT_EXPECT_UINT_EQ_VAL_D (found_by_name_only, \ 744 0u, \ 745 "search by pseudo-header entry name " \ 746 "should fail"); 747 } 748 749 return ! 0; 750 } 751 752 753 /* Return non-zero if succeeded, zero if failed */ 754 static int 755 mhdtl_comb_check_entry_at_idx (struct mhd_HpackDTblContext *dyn, 756 size_t idx, 757 const char *expect_name, 758 const char *expect_value) 759 { 760 return mhdtl_comb_check_entry_n_at_idx (dyn, 761 idx, 762 strlen (expect_name), 763 expect_name, 764 strlen (expect_value), 765 expect_value); 766 } 767 768 769 #define MHDTL_HTBL_FIND_ENTRY_REAL_STR(dyn,name,value) \ 770 mhd_htbl_find_entry_real (dyn,strlen (name),(name), \ 771 strlen (value),(value)) 772 #define MHDTL_HTBL_FIND_NAME_REAL_STR(dyn,name) \ 773 mhd_htbl_find_name_real (dyn,strlen (name),(name)) 774 775 776 /* 777 * The dynamic table tests 778 */ 779 780 static int 781 test_dyn_create_destroy (void) 782 { 783 struct mhd_HpackDTblContext*dyn; 784 785 MHDT_EXPECT_PTR_NONNULL_D (dyn = \ 786 mhd_dtbl_create (mhd_hpack_def_dyn_table_size), \ 787 "Create HPACK dynamic table"); 788 if (NULL == dyn) 789 return MHDT_TEST_RESULT (); 790 791 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 0u, \ 792 "an empty table must have no entries"); 793 mhdtl_dyn_check_get_valid_invalid (dyn); 794 795 mhd_dtbl_destroy (dyn); 796 797 return MHDT_TEST_RESULT (); 798 } 799 800 801 static int 802 test_dyn_create_destroy_larger (void) 803 { 804 struct mhd_HpackDTblContext*dyn; 805 806 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (59u * 1024u), \ 807 "Create HPACK dynamic table"); 808 if (NULL == dyn) 809 return MHDT_TEST_RESULT (); 810 811 MHDT_EXPECT_UINT_EQ_VAL_D (mhd_dtbl_get_num_entries (dyn), 0u, \ 812 "an empty table must have no entries"); 813 mhdtl_dyn_check_get_valid_invalid (dyn); 814 815 mhd_dtbl_destroy (dyn); 816 817 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (mhd_DTBL_MAX_SIZE), \ 818 "Create HPACK dynamic table with maximum size"); 819 if (NULL == dyn) 820 return MHDT_TEST_RESULT (); 821 822 /* Add some entries with checks */ 823 mhdtl_dyn_add_sized_entry_with_check (dyn, 123u); 824 mhdtl_dyn_add_sized_entry_with_check (dyn, 234u); 825 mhdtl_dyn_check_get_valid_invalid (dyn); 826 827 mhd_dtbl_destroy (dyn); 828 829 return MHDT_TEST_RESULT (); 830 } 831 832 833 static int 834 test_dyn_add_three (void) 835 { 836 struct mhd_HpackDTblContext*dyn; 837 838 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \ 839 "Create HPACK dynamic table"); 840 if (NULL == dyn) 841 return MHDT_TEST_RESULT (); 842 843 mhdtl_dyn_add_hdr_with_check (dyn, "header1", "value1"); 844 mhdtl_dyn_add_hdr_with_check (dyn, "header2", "longer value of the header2"); 845 mhdtl_dyn_add_hdr_with_check (dyn, "Header3", "value of the header with the " 846 "uppercase name"); 847 848 mhd_dtbl_destroy (dyn); 849 850 return MHDT_TEST_RESULT (); 851 } 852 853 854 static int 855 test_dyn_add_empty (void) 856 { 857 struct mhd_HpackDTblContext*dyn; 858 859 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \ 860 "Create HPACK dynamic table"); 861 if (NULL == dyn) 862 return MHDT_TEST_RESULT (); 863 864 mhdtl_dyn_add_hdr_with_check (dyn, "", ""); 865 mhdtl_dyn_add_hdr_with_check (dyn, "h", ""); 866 mhdtl_dyn_add_hdr_with_check (dyn, "", "v"); 867 868 mhd_dtbl_destroy (dyn); 869 870 return MHDT_TEST_RESULT (); 871 } 872 873 874 static int 875 test_dyn_add_evict_simple (void) 876 { 877 struct mhd_HpackDTblContext*dyn; 878 879 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (128u), \ 880 "Create HPACK dynamic table"); 881 if (NULL == dyn) 882 return MHDT_TEST_RESULT (); 883 884 mhdtl_dyn_add_hdr_with_check (dyn, "header1", "value1"); 885 mhdtl_dyn_add_hdr_with_check (dyn, "header2", "longer value of the header2"); 886 mhdtl_dyn_add_hdr_with_check (dyn, "Header3", "value of the header with the " 887 "uppercase name"); 888 mhdtl_dyn_add_hdr_with_check (dyn, "header4", "smaller header"); 889 mhdtl_dyn_add_hdr_with_check (dyn, "header5", "value5"); 890 891 mhd_dtbl_destroy (dyn); 892 893 return MHDT_TEST_RESULT (); 894 } 895 896 897 static int 898 test_dyn_add_evict_wrap (void) 899 { 900 struct mhd_HpackDTblContext*dyn; 901 902 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (280u), \ 903 "Create HPACK dynamic table"); 904 if (NULL == dyn) 905 return MHDT_TEST_RESULT (); 906 907 #define MHDTL_H01N "notably-long-name1" /* length: 18 */ 908 #define MHDTL_H01V "some notably long data1" /* length: 23 */ 909 #define MHDTL_H02N "longer-name2" /* length: 12 */ 910 #define MHDTL_H02V "some longer data2" /* length: 17 */ 911 #define MHDTL_H03N "abcdefgh3" /* length: 9 */ 912 #define MHDTL_H03V "random data3" /* length: 12 */ 913 #define MHDTL_H04N "short-hdr4" /* length: 10 */ 914 #define MHDTL_H04V "value4" /* length: 6 */ 915 #define MHDTL_H05N "some-header5" /* length: 12 */ 916 #define MHDTL_H05V "even longer value of the header5" /* length: 32 */ 917 #define MHDTL_H06N "longer-name6" /* length: 12 */ 918 #define MHDTL_H06V "some longer data6" /* length: 17 */ 919 #define MHDTL_H07N "some-extremely-long-name7" /* length: 25 */ 920 #define MHDTL_H07V "some really long value of the header7" /* length: 37 */ 921 #define MHDTL_H08N "someheader8" /* length: 11 */ 922 #define MHDTL_H08V "value8" /* length: 6 */ 923 #define MHDTL_H09N "the-long-long-long-long-long-long-long-name9" /* length: 44 */ 924 #define MHDTL_H09V "the header (field) value, with commas and other " \ 925 "extra characters to make it really huge, larger " \ 926 "enough to replace all other headers but one, the " \ 927 "last one." /* length: 154 */ 928 #define MHDTL_H10N "the-long-long-long-long-long-long-long-name10" /* length: 45 */ 929 #define MHDTL_H10V "the header (field) value, with commas and other " \ 930 "extra characters to make it really huge, larger " \ 931 "enough to replace all other headers, leaving space " \ 932 "only for a tiny header" /* length: 169 */ 933 #define MHDTL_H11N "a" /* length: 1 */ 934 #define MHDTL_H11V "B" /* length: 1 */ 935 #define MHDTL_H12N "c" /* length: 1 */ 936 #define MHDTL_H12V "D" /* length: 1 */ 937 #define MHDTL_H13N "e" /* length: 1 */ 938 #define MHDTL_H13V "F" /* length: 1 */ 939 #define MHDTL_H14N "g" /* length: 1 */ 940 #define MHDTL_H14V "H" /* length: 1 */ 941 #define MHDTL_H15N "i" /* length: 1 */ 942 #define MHDTL_H15V "J" /* length: 1 */ 943 #define MHDTL_H16N "k" /* length: 1 */ 944 #define MHDTL_H16V "L" /* length: 1 */ 945 #define MHDTL_H17N "m" /* length: 1 */ 946 #define MHDTL_H17V "N" /* length: 1 */ 947 #define MHDTL_H18N "name18" /* length: 6 */ 948 #define MHDTL_H18V "vl18" /* length: 4 */ 949 #define MHDTL_H19N "o" /* length: 1 */ 950 #define MHDTL_H19V "P" /* length: 1 */ 951 #define MHDTL_H20N "m" /* length: 1 */ 952 #define MHDTL_H20V "N" /* length: 1 */ 953 954 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H01N, MHDTL_H01V); /* 18 + 23 + 32 = 73 */ 955 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H02N, MHDTL_H02V); /* 12 + 17 + 32 = 61 */ 956 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H03N, MHDTL_H03V); /* 9 + 12 + 32 = 53 */ 957 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H04N, MHDTL_H04V); /* 10 + 6 + 32 = 48 */ 958 /* 73 + 61 + 48 + 76 = 258 */ 959 960 /* '1', '2', '3', '4' [insert pos] */ 961 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 235u); 962 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 963 964 mhdtl_dyn_check_entry_at_idx (dyn, 965 mhd_HPACK_STBL_LAST_IDX + 1u, 966 MHDTL_H04N, MHDTL_H04V); 967 mhdtl_dyn_check_entry_at_idx (dyn, 968 mhd_HPACK_STBL_LAST_IDX + 2u, 969 MHDTL_H03N, MHDTL_H03V); 970 mhdtl_dyn_check_entry_at_idx (dyn, 971 mhd_HPACK_STBL_LAST_IDX + 3u, 972 MHDTL_H02N, MHDTL_H02V); 973 mhdtl_dyn_check_entry_at_idx (dyn, 974 mhd_HPACK_STBL_LAST_IDX + 4u, 975 MHDTL_H01N, MHDTL_H01V); 976 977 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H05N, MHDTL_H05V); /* 12 + 32 + 32 = 76 */ 978 /* '5' [insert pos], '2', '3', '4' */ 979 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 238u); 980 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 981 982 mhdtl_dyn_check_entry_at_idx (dyn, 983 mhd_HPACK_STBL_LAST_IDX + 1u, 984 MHDTL_H05N, MHDTL_H05V); 985 mhdtl_dyn_check_entry_at_idx (dyn, 986 mhd_HPACK_STBL_LAST_IDX + 2u, 987 MHDTL_H04N, MHDTL_H04V); 988 mhdtl_dyn_check_entry_at_idx (dyn, 989 mhd_HPACK_STBL_LAST_IDX + 3u, 990 MHDTL_H03N, MHDTL_H03V); 991 mhdtl_dyn_check_entry_at_idx (dyn, 992 mhd_HPACK_STBL_LAST_IDX + 4u, 993 MHDTL_H02N, MHDTL_H02V); 994 995 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H06N, MHDTL_H06V); /* 12 + 17 + 32 = 61 */ 996 /* '5', '6' [insert pos], '3', '4' */ 997 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 238u); 998 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 999 1000 mhdtl_dyn_check_entry_at_idx (dyn, 1001 mhd_HPACK_STBL_LAST_IDX + 1u, 1002 MHDTL_H06N, MHDTL_H06V); 1003 mhdtl_dyn_check_entry_at_idx (dyn, 1004 mhd_HPACK_STBL_LAST_IDX + 2u, 1005 MHDTL_H05N, MHDTL_H05V); 1006 mhdtl_dyn_check_entry_at_idx (dyn, 1007 mhd_HPACK_STBL_LAST_IDX + 3u, 1008 MHDTL_H04N, MHDTL_H04V); 1009 mhdtl_dyn_check_entry_at_idx (dyn, 1010 mhd_HPACK_STBL_LAST_IDX + 4u, 1011 MHDTL_H03N, MHDTL_H03V); 1012 1013 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H07N, MHDTL_H07V); /* 25 + 37 + 32 = 94 */ 1014 /* '5', '6', '7' [insert pos], '4' */ 1015 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 279u); 1016 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1017 1018 mhdtl_dyn_check_entry_at_idx (dyn, 1019 mhd_HPACK_STBL_LAST_IDX + 1u, 1020 MHDTL_H07N, MHDTL_H07V); 1021 mhdtl_dyn_check_entry_at_idx (dyn, 1022 mhd_HPACK_STBL_LAST_IDX + 2u, 1023 MHDTL_H06N, MHDTL_H06V); 1024 mhdtl_dyn_check_entry_at_idx (dyn, 1025 mhd_HPACK_STBL_LAST_IDX + 3u, 1026 MHDTL_H05N, MHDTL_H05V); 1027 mhdtl_dyn_check_entry_at_idx (dyn, 1028 mhd_HPACK_STBL_LAST_IDX + 4u, 1029 MHDTL_H04N, MHDTL_H04V); 1030 1031 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H08N, MHDTL_H08V); /* 11 + 6 + 32 = 49 */ 1032 /* '5', '6', '7', '8' [insert pos] */ 1033 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1034 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1035 1036 mhdtl_dyn_check_entry_at_idx (dyn, 1037 mhd_HPACK_STBL_LAST_IDX + 1u, 1038 MHDTL_H08N, MHDTL_H08V); 1039 mhdtl_dyn_check_entry_at_idx (dyn, 1040 mhd_HPACK_STBL_LAST_IDX + 2u, 1041 MHDTL_H07N, MHDTL_H07V); 1042 mhdtl_dyn_check_entry_at_idx (dyn, 1043 mhd_HPACK_STBL_LAST_IDX + 3u, 1044 MHDTL_H06N, MHDTL_H06V); 1045 mhdtl_dyn_check_entry_at_idx (dyn, 1046 mhd_HPACK_STBL_LAST_IDX + 4u, 1047 MHDTL_H05N, MHDTL_H05V); 1048 1049 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H09N, MHDTL_H09V); /* 44 + 154 + 32 = 230 */ 1050 /* '9' [insert pos], '8' */ 1051 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 279u); 1052 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1053 1054 mhdtl_dyn_check_entry_at_idx (dyn, 1055 mhd_HPACK_STBL_LAST_IDX + 1u, 1056 MHDTL_H09N, MHDTL_H09V); 1057 mhdtl_dyn_check_entry_at_idx (dyn, 1058 mhd_HPACK_STBL_LAST_IDX + 2u, 1059 MHDTL_H08N, MHDTL_H08V); 1060 1061 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H10N, MHDTL_H10V); /* 45 + 169 + 32 = 246 */ 1062 /* '10' [insert pos] */ 1063 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 246u); 1064 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 1065 1066 mhdtl_dyn_check_entry_at_idx (dyn, 1067 mhd_HPACK_STBL_LAST_IDX + 1u, 1068 MHDTL_H10N, MHDTL_H10V); 1069 1070 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H11N, MHDTL_H11V); /* 1 + 1 + 32 = 34 */ 1071 /* '10', '11' [insert pos] */ 1072 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1073 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1074 1075 mhdtl_dyn_check_entry_at_idx (dyn, 1076 mhd_HPACK_STBL_LAST_IDX + 1u, 1077 MHDTL_H11N, MHDTL_H11V); 1078 mhdtl_dyn_check_entry_at_idx (dyn, 1079 mhd_HPACK_STBL_LAST_IDX + 2u, 1080 MHDTL_H10N, MHDTL_H10V); 1081 1082 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H12N, MHDTL_H12V); /* 1 + 1 + 32 = 34 */ 1083 /* '12' [insert pos], '11' */ 1084 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 68u); 1085 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1086 1087 mhdtl_dyn_check_entry_at_idx (dyn, 1088 mhd_HPACK_STBL_LAST_IDX + 1u, 1089 MHDTL_H12N, MHDTL_H12V); 1090 mhdtl_dyn_check_entry_at_idx (dyn, 1091 mhd_HPACK_STBL_LAST_IDX + 2u, 1092 MHDTL_H11N, MHDTL_H11V); 1093 1094 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H13N, MHDTL_H13V); /* 1 + 1 + 32 = 34 */ 1095 /* '12', '13' [insert pos], '11' */ 1096 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 102u); 1097 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1098 1099 mhdtl_dyn_check_entry_at_idx (dyn, 1100 mhd_HPACK_STBL_LAST_IDX + 1u, 1101 MHDTL_H13N, MHDTL_H13V); 1102 mhdtl_dyn_check_entry_at_idx (dyn, 1103 mhd_HPACK_STBL_LAST_IDX + 2u, 1104 MHDTL_H12N, MHDTL_H12V); 1105 mhdtl_dyn_check_entry_at_idx (dyn, 1106 mhd_HPACK_STBL_LAST_IDX + 3u, 1107 MHDTL_H11N, MHDTL_H11V); 1108 1109 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H14N, MHDTL_H14V); /* 1 + 1 + 32 = 34 */ 1110 /* '12', '13', '14' [insert pos], '11' */ 1111 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 136u); 1112 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1113 1114 mhdtl_dyn_check_entry_at_idx (dyn, 1115 mhd_HPACK_STBL_LAST_IDX + 1u, 1116 MHDTL_H14N, MHDTL_H14V); 1117 mhdtl_dyn_check_entry_at_idx (dyn, 1118 mhd_HPACK_STBL_LAST_IDX + 2u, 1119 MHDTL_H13N, MHDTL_H13V); 1120 mhdtl_dyn_check_entry_at_idx (dyn, 1121 mhd_HPACK_STBL_LAST_IDX + 3u, 1122 MHDTL_H12N, MHDTL_H12V); 1123 mhdtl_dyn_check_entry_at_idx (dyn, 1124 mhd_HPACK_STBL_LAST_IDX + 4u, 1125 MHDTL_H11N, MHDTL_H11V); 1126 1127 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H15N, MHDTL_H15V); /* 1 + 1 + 32 = 34 */ 1128 /* '12', '13', '14', '15' [insert pos], '11' */ 1129 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 170u); 1130 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u); 1131 1132 mhdtl_dyn_check_entry_at_idx (dyn, 1133 mhd_HPACK_STBL_LAST_IDX + 1u, 1134 MHDTL_H15N, MHDTL_H15V); 1135 mhdtl_dyn_check_entry_at_idx (dyn, 1136 mhd_HPACK_STBL_LAST_IDX + 2u, 1137 MHDTL_H14N, MHDTL_H14V); 1138 mhdtl_dyn_check_entry_at_idx (dyn, 1139 mhd_HPACK_STBL_LAST_IDX + 3u, 1140 MHDTL_H13N, MHDTL_H13V); 1141 mhdtl_dyn_check_entry_at_idx (dyn, 1142 mhd_HPACK_STBL_LAST_IDX + 4u, 1143 MHDTL_H12N, MHDTL_H12V); 1144 mhdtl_dyn_check_entry_at_idx (dyn, 1145 mhd_HPACK_STBL_LAST_IDX + 5u, 1146 MHDTL_H11N, MHDTL_H11V); 1147 1148 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H16N, MHDTL_H16V); /* 1 + 1 + 32 = 34 */ 1149 /* '12', '13', '14', '15', '16' [insert pos], '11' */ 1150 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 204u); 1151 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 6u); 1152 1153 mhdtl_dyn_check_entry_at_idx (dyn, 1154 mhd_HPACK_STBL_LAST_IDX + 1u, 1155 MHDTL_H16N, MHDTL_H16V); 1156 mhdtl_dyn_check_entry_at_idx (dyn, 1157 mhd_HPACK_STBL_LAST_IDX + 2u, 1158 MHDTL_H15N, MHDTL_H15V); 1159 mhdtl_dyn_check_entry_at_idx (dyn, 1160 mhd_HPACK_STBL_LAST_IDX + 3u, 1161 MHDTL_H14N, MHDTL_H14V); 1162 mhdtl_dyn_check_entry_at_idx (dyn, 1163 mhd_HPACK_STBL_LAST_IDX + 4u, 1164 MHDTL_H13N, MHDTL_H13V); 1165 mhdtl_dyn_check_entry_at_idx (dyn, 1166 mhd_HPACK_STBL_LAST_IDX + 5u, 1167 MHDTL_H12N, MHDTL_H12V); 1168 mhdtl_dyn_check_entry_at_idx (dyn, 1169 mhd_HPACK_STBL_LAST_IDX + 6u, 1170 MHDTL_H11N, MHDTL_H11V); 1171 1172 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H17N, MHDTL_H17V); /* 1 + 1 + 32 = 34 */ 1173 /* '12', '13', '14', '15', '16', '17' [insert pos], '11' */ 1174 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 238u); 1175 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 7u); 1176 1177 mhdtl_dyn_check_entry_at_idx (dyn, 1178 mhd_HPACK_STBL_LAST_IDX + 1u, 1179 MHDTL_H17N, MHDTL_H17V); 1180 mhdtl_dyn_check_entry_at_idx (dyn, 1181 mhd_HPACK_STBL_LAST_IDX + 2u, 1182 MHDTL_H16N, MHDTL_H16V); 1183 mhdtl_dyn_check_entry_at_idx (dyn, 1184 mhd_HPACK_STBL_LAST_IDX + 3u, 1185 MHDTL_H15N, MHDTL_H15V); 1186 mhdtl_dyn_check_entry_at_idx (dyn, 1187 mhd_HPACK_STBL_LAST_IDX + 4u, 1188 MHDTL_H14N, MHDTL_H14V); 1189 mhdtl_dyn_check_entry_at_idx (dyn, 1190 mhd_HPACK_STBL_LAST_IDX + 5u, 1191 MHDTL_H13N, MHDTL_H13V); 1192 mhdtl_dyn_check_entry_at_idx (dyn, 1193 mhd_HPACK_STBL_LAST_IDX + 6u, 1194 MHDTL_H12N, MHDTL_H12V); 1195 mhdtl_dyn_check_entry_at_idx (dyn, 1196 mhd_HPACK_STBL_LAST_IDX + 7u, 1197 MHDTL_H11N, MHDTL_H11V); 1198 1199 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H18N, MHDTL_H18V); /* 6 + 4 + 32 = 42 */ 1200 /* '12', '13', '14', '15', '16', '17', '18' [insert pos], '11' */ 1201 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1202 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u); 1203 1204 mhdtl_dyn_check_entry_at_idx (dyn, 1205 mhd_HPACK_STBL_LAST_IDX + 1u, 1206 MHDTL_H18N, MHDTL_H18V); 1207 mhdtl_dyn_check_entry_at_idx (dyn, 1208 mhd_HPACK_STBL_LAST_IDX + 2u, 1209 MHDTL_H17N, MHDTL_H17V); 1210 mhdtl_dyn_check_entry_at_idx (dyn, 1211 mhd_HPACK_STBL_LAST_IDX + 3u, 1212 MHDTL_H16N, MHDTL_H16V); 1213 mhdtl_dyn_check_entry_at_idx (dyn, 1214 mhd_HPACK_STBL_LAST_IDX + 4u, 1215 MHDTL_H15N, MHDTL_H15V); 1216 mhdtl_dyn_check_entry_at_idx (dyn, 1217 mhd_HPACK_STBL_LAST_IDX + 5u, 1218 MHDTL_H14N, MHDTL_H14V); 1219 mhdtl_dyn_check_entry_at_idx (dyn, 1220 mhd_HPACK_STBL_LAST_IDX + 6u, 1221 MHDTL_H13N, MHDTL_H13V); 1222 mhdtl_dyn_check_entry_at_idx (dyn, 1223 mhd_HPACK_STBL_LAST_IDX + 7u, 1224 MHDTL_H12N, MHDTL_H12V); 1225 mhdtl_dyn_check_entry_at_idx (dyn, 1226 mhd_HPACK_STBL_LAST_IDX + 8u, 1227 MHDTL_H11N, MHDTL_H11V); 1228 1229 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H19N, MHDTL_H19V); /* 1 + 1 + 32 = 34 */ 1230 /* '12', '13', '14', '15', '16', '17', '18', '19' [insert pos] */ 1231 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1232 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u); 1233 1234 mhdtl_dyn_check_entry_at_idx (dyn, 1235 mhd_HPACK_STBL_LAST_IDX + 1u, 1236 MHDTL_H19N, MHDTL_H19V); 1237 mhdtl_dyn_check_entry_at_idx (dyn, 1238 mhd_HPACK_STBL_LAST_IDX + 2u, 1239 MHDTL_H18N, MHDTL_H18V); 1240 mhdtl_dyn_check_entry_at_idx (dyn, 1241 mhd_HPACK_STBL_LAST_IDX + 3u, 1242 MHDTL_H17N, MHDTL_H17V); 1243 mhdtl_dyn_check_entry_at_idx (dyn, 1244 mhd_HPACK_STBL_LAST_IDX + 4u, 1245 MHDTL_H16N, MHDTL_H16V); 1246 mhdtl_dyn_check_entry_at_idx (dyn, 1247 mhd_HPACK_STBL_LAST_IDX + 5u, 1248 MHDTL_H15N, MHDTL_H15V); 1249 mhdtl_dyn_check_entry_at_idx (dyn, 1250 mhd_HPACK_STBL_LAST_IDX + 6u, 1251 MHDTL_H14N, MHDTL_H14V); 1252 mhdtl_dyn_check_entry_at_idx (dyn, 1253 mhd_HPACK_STBL_LAST_IDX + 7u, 1254 MHDTL_H13N, MHDTL_H13V); 1255 mhdtl_dyn_check_entry_at_idx (dyn, 1256 mhd_HPACK_STBL_LAST_IDX + 8u, 1257 MHDTL_H12N, MHDTL_H12V); 1258 1259 mhdtl_dyn_add_sized_entry_with_check (dyn, 246u); 1260 /* 'generated' [insert pos], '19' */ 1261 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1262 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1263 1264 mhdtl_dyn_check_entry_at_idx (dyn, 1265 mhd_HPACK_STBL_LAST_IDX + 2u, 1266 MHDTL_H19N, MHDTL_H19V); 1267 1268 mhdtl_dyn_add_sized_entry_with_check (dyn, 247u); /* Should be reset on the next add */ 1269 /* Re-use headers */ 1270 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H12N, MHDTL_H12V); /* 1 + 1 + 32 = 34 */ 1271 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H13N, MHDTL_H13V); /* 1 + 1 + 32 = 34 */ 1272 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H14N, MHDTL_H14V); /* 1 + 1 + 32 = 34 */ 1273 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H15N, MHDTL_H15V); /* 1 + 1 + 32 = 34 */ 1274 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H16N, MHDTL_H16V); /* 1 + 1 + 32 = 34 */ 1275 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H17N, MHDTL_H17V); /* 1 + 1 + 32 = 34 */ 1276 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H18N, MHDTL_H18V); /* 6 + 4 + 32 = 42 */ 1277 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H19N, MHDTL_H19V); /* 1 + 1 + 32 = 34 */ 1278 /* '12', '13', '14', '15', '16', '17', '18', '19' [insert pos] */ 1279 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1280 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u); 1281 1282 mhdtl_dyn_check_entry_at_idx (dyn, 1283 mhd_HPACK_STBL_LAST_IDX + 1u, 1284 MHDTL_H19N, MHDTL_H19V); 1285 mhdtl_dyn_check_entry_at_idx (dyn, 1286 mhd_HPACK_STBL_LAST_IDX + 2u, 1287 MHDTL_H18N, MHDTL_H18V); 1288 mhdtl_dyn_check_entry_at_idx (dyn, 1289 mhd_HPACK_STBL_LAST_IDX + 3u, 1290 MHDTL_H17N, MHDTL_H17V); 1291 mhdtl_dyn_check_entry_at_idx (dyn, 1292 mhd_HPACK_STBL_LAST_IDX + 4u, 1293 MHDTL_H16N, MHDTL_H16V); 1294 mhdtl_dyn_check_entry_at_idx (dyn, 1295 mhd_HPACK_STBL_LAST_IDX + 5u, 1296 MHDTL_H15N, MHDTL_H15V); 1297 mhdtl_dyn_check_entry_at_idx (dyn, 1298 mhd_HPACK_STBL_LAST_IDX + 6u, 1299 MHDTL_H14N, MHDTL_H14V); 1300 mhdtl_dyn_check_entry_at_idx (dyn, 1301 mhd_HPACK_STBL_LAST_IDX + 7u, 1302 MHDTL_H13N, MHDTL_H13V); 1303 mhdtl_dyn_check_entry_at_idx (dyn, 1304 mhd_HPACK_STBL_LAST_IDX + 8u, 1305 MHDTL_H12N, MHDTL_H12V); 1306 1307 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H20N, MHDTL_H20V); /* 1 + 1 + 32 = 34 */ 1308 /* '20' [insert pos], '13', '14', '15', '16', '17', '18', '19' */ 1309 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1310 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 8u); 1311 1312 mhdtl_dyn_check_entry_at_idx (dyn, 1313 mhd_HPACK_STBL_LAST_IDX + 1u, 1314 MHDTL_H20N, MHDTL_H20V); 1315 mhdtl_dyn_check_entry_at_idx (dyn, 1316 mhd_HPACK_STBL_LAST_IDX + 2u, 1317 MHDTL_H19N, MHDTL_H19V); 1318 mhdtl_dyn_check_entry_at_idx (dyn, 1319 mhd_HPACK_STBL_LAST_IDX + 3u, 1320 MHDTL_H18N, MHDTL_H18V); 1321 mhdtl_dyn_check_entry_at_idx (dyn, 1322 mhd_HPACK_STBL_LAST_IDX + 4u, 1323 MHDTL_H17N, MHDTL_H17V); 1324 mhdtl_dyn_check_entry_at_idx (dyn, 1325 mhd_HPACK_STBL_LAST_IDX + 5u, 1326 MHDTL_H16N, MHDTL_H16V); 1327 mhdtl_dyn_check_entry_at_idx (dyn, 1328 mhd_HPACK_STBL_LAST_IDX + 6u, 1329 MHDTL_H15N, MHDTL_H15V); 1330 mhdtl_dyn_check_entry_at_idx (dyn, 1331 mhd_HPACK_STBL_LAST_IDX + 7u, 1332 MHDTL_H14N, MHDTL_H14V); 1333 mhdtl_dyn_check_entry_at_idx (dyn, 1334 mhd_HPACK_STBL_LAST_IDX + 8u, 1335 MHDTL_H13N, MHDTL_H13V); 1336 1337 mhdtl_dyn_add_sized_entry_with_check (dyn, 212u); 1338 /* '20', 'generated' [insert pos], '19' */ 1339 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 280u); 1340 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1341 1342 mhdtl_dyn_check_entry_at_idx (dyn, 1343 mhd_HPACK_STBL_LAST_IDX + 2u, 1344 MHDTL_H20N, MHDTL_H20V); 1345 mhdtl_dyn_check_entry_at_idx (dyn, 1346 mhd_HPACK_STBL_LAST_IDX + 3u, 1347 MHDTL_H19N, MHDTL_H19V); 1348 1349 mhd_dtbl_destroy (dyn); 1350 1351 #undef MHDTL_H01N 1352 #undef MHDTL_H01V 1353 #undef MHDTL_H02N 1354 #undef MHDTL_H02V 1355 #undef MHDTL_H03N 1356 #undef MHDTL_H03V 1357 #undef MHDTL_H04N 1358 #undef MHDTL_H04V 1359 #undef MHDTL_H05N 1360 #undef MHDTL_H05V 1361 #undef MHDTL_H06N 1362 #undef MHDTL_H06V 1363 #undef MHDTL_H07N 1364 #undef MHDTL_H07V 1365 #undef MHDTL_H08N 1366 #undef MHDTL_H08V 1367 #undef MHDTL_H09N 1368 #undef MHDTL_H09V 1369 #undef MHDTL_H10N 1370 #undef MHDTL_H10V 1371 #undef MHDTL_H11N 1372 #undef MHDTL_H11V 1373 #undef MHDTL_H12N 1374 #undef MHDTL_H12V 1375 #undef MHDTL_H13N 1376 #undef MHDTL_H13V 1377 #undef MHDTL_H14N 1378 #undef MHDTL_H14V 1379 #undef MHDTL_H15N 1380 #undef MHDTL_H15V 1381 #undef MHDTL_H16N 1382 #undef MHDTL_H16V 1383 #undef MHDTL_H17N 1384 #undef MHDTL_H17V 1385 #undef MHDTL_H18N 1386 #undef MHDTL_H18V 1387 #undef MHDTL_H19N 1388 #undef MHDTL_H19V 1389 #undef MHDTL_H20N 1390 #undef MHDTL_H20V 1391 1392 return MHDT_TEST_RESULT (); 1393 } 1394 1395 1396 static int 1397 test_dyn_add_evict_inter (void) 1398 { 1399 struct mhd_HpackDTblContext*dyn; 1400 struct mhd_BufferConst check_name; 1401 struct mhd_BufferConst check_value; 1402 1403 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (705u), \ 1404 "Create HPACK dynamic table"); 1405 if (NULL == dyn) 1406 return MHDT_TEST_RESULT (); 1407 1408 mhdtl_dyn_add_sized_entry_with_check (dyn, 50u); 1409 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 1410 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 50u); 1411 mhdtl_dyn_add_sized_entry_with_check (dyn, 75u); 1412 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1413 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 125u); 1414 mhdtl_dyn_add_sized_entry_with_check (dyn, 100u); 1415 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1416 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 225u); 1417 mhdtl_dyn_add_sized_entry_with_check (dyn, 125u); 1418 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1419 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 350u); 1420 mhdtl_dyn_add_sized_entry_with_check (dyn, 150u); 1421 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u); 1422 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 500u); 1423 mhdtl_dyn_add_sized_entry_with_check (dyn, 175u); 1424 1425 /* { 50, 75, 100, 125, 150, 175 [insert pos] } */ 1426 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 675u); 1427 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 6u); 1428 1429 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1430 mhd_HPACK_STBL_LAST_IDX + 6u, \ 1431 &check_name, \ 1432 &check_value))) 1433 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1434 check_value.size), \ 1435 50u); 1436 1437 /* First two entries should be replaced with a single entry, which 1438 is 2 bytes smaller than two entries. 1439 (50, 75) -> (123) */ 1440 mhdtl_dyn_add_sized_entry_with_check (dyn, 123u); 1441 /* { 123 [insert pos], 100, 125, 150, 175 } */ 1442 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 673u); 1443 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u); 1444 1445 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1446 mhd_HPACK_STBL_LAST_IDX + 5u, \ 1447 &check_name, \ 1448 &check_value))) 1449 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1450 check_value.size), \ 1451 100u); 1452 1453 /* Next entry should be replaced with a smaller entry. 1454 (100) -> (35) */ 1455 mhdtl_dyn_add_sized_entry_with_check (dyn, 35u); 1456 /* { 123, 35 [insert pos], 125, 150, 175 } */ 1457 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 608u); 1458 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u); 1459 1460 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1461 mhd_HPACK_STBL_LAST_IDX + 5u, \ 1462 &check_name, \ 1463 &check_value))) 1464 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1465 check_value.size), \ 1466 125u); 1467 1468 /* Should be added without eviction. 1469 -> (97) */ 1470 mhdtl_dyn_add_sized_entry_with_check (dyn, 97u); 1471 /* { 123, 35, 97 [insert pos], 125, 150, 175 } */ 1472 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u); 1473 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 6u); 1474 1475 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1476 mhd_HPACK_STBL_LAST_IDX + 6u, \ 1477 &check_name, \ 1478 &check_value))) 1479 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1480 check_value.size), \ 1481 125u); 1482 1483 /* Two entries should be replaced with single one. 1484 (125, 150) -> (275) */ 1485 mhdtl_dyn_add_sized_entry_with_check (dyn, 275u); 1486 /* { 123, 35, 97, 275 [insert pos], 175 } */ 1487 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u); 1488 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u); 1489 1490 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1491 mhd_HPACK_STBL_LAST_IDX + 5u, \ 1492 &check_name, \ 1493 &check_value))) 1494 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1495 check_value.size), \ 1496 175u); 1497 1498 /* Two entries should be replaced with single one. 1499 (175, 123) -> (251) */ 1500 mhdtl_dyn_add_sized_entry_with_check (dyn, 251u); 1501 /* { 35, 97, 275, 251 [insert pos] } */ 1502 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 658u); 1503 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1504 1505 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1506 mhd_HPACK_STBL_LAST_IDX + 4u, \ 1507 &check_name, \ 1508 &check_value))) 1509 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1510 check_value.size), \ 1511 35u); 1512 1513 /* Should be added without eviction. 1514 -> (42) */ 1515 mhdtl_dyn_add_sized_entry_with_check (dyn, 42u); 1516 /* { 42 [insert pos], 35, 97, 275, 251 } */ 1517 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 700u); 1518 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 5u); 1519 1520 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1521 mhd_HPACK_STBL_LAST_IDX + 5u, \ 1522 &check_name, \ 1523 &check_value))) 1524 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1525 check_value.size), \ 1526 35u); 1527 1528 /* Two entries should be replaced with single one. 1529 (35, 97) -> (51) */ 1530 mhdtl_dyn_add_sized_entry_with_check (dyn, 51u); 1531 /* { 42, 51 [insert pos], 275, 251 } */ 1532 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 619u); 1533 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1534 1535 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 1536 mhd_HPACK_STBL_LAST_IDX + 4u, \ 1537 &check_name, \ 1538 &check_value))) 1539 MHDT_EXPECT_UINT_EQ_VAL (MHDTL_HPACK_ENTRY_SIZE (check_name.size, \ 1540 check_value.size), \ 1541 275u); 1542 1543 /* Three entries should be replaced with single one. 1544 (275, 251, 42) -> (613) */ 1545 mhdtl_dyn_add_sized_entry_with_check (dyn, 613u); 1546 /* { 51, 613 [insert pos] } */ 1547 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 664u); 1548 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1549 1550 /* (51, 613) -> (672) */ 1551 mhdtl_dyn_add_sized_entry_with_check (dyn, 672u); 1552 /* { 672 [insert pos] } */ 1553 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 672u); 1554 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 1555 1556 /* -> (33) */ 1557 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1558 /* { 672, 33 [insert pos] } */ 1559 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u); 1560 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1561 1562 /* (672) -> (33) */ 1563 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1564 /* { 33 [insert pos], 33 } */ 1565 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 66u); 1566 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1567 1568 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1569 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1570 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1571 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1572 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1573 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1574 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1575 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1576 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1577 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1578 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1579 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1580 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1581 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1582 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1583 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1584 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1585 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1586 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1587 /* { 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 1588 33, 33, 33 [insert pos], 33 } */ 1589 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u); 1590 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u); 1591 1592 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1593 /* { 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 1594 33, 33, 33, 33 [insert pos] } */ 1595 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u); 1596 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u); 1597 1598 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1599 /* { 33 [insert pos], 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 1600 33, 33, 33, 33, 33, 33, 33 } */ 1601 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u); 1602 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u); 1603 1604 mhdtl_dyn_add_sized_entry_with_check (dyn, 639u); 1605 /* { 33, 639 [insert pos], 33 } */ 1606 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u); 1607 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1608 1609 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1610 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1611 /* { 33 [insert pos], 639, 33 } */ 1612 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 705u); 1613 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1614 1615 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1616 /* { 33, 33 [insert pos], 33 } */ 1617 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 99u); 1618 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1619 1620 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1621 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1622 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1623 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1624 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1625 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1626 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1627 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1628 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1629 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1630 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1631 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1632 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1633 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1634 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1635 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1636 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1637 mhdtl_dyn_add_sized_entry_with_check (dyn, 33u); 1638 /* { 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 1639 33, 33, 33 [insert pos], 33 } */ 1640 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 693u); 1641 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 21u); 1642 1643 mhd_dtbl_destroy (dyn); 1644 1645 return MHDT_TEST_RESULT (); 1646 } 1647 1648 1649 static int 1650 test_dyn_add_series (void) 1651 { 1652 const uint_fast16_t num_inter = 1653 (uint_fast16_t) 1654 (mhdtl_enable_deep_tests ? (16u * 1024u) : (1024u)); 1655 struct mhd_HpackDTblContext*dyn; 1656 uint_fast16_t i; 1657 1658 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (925u), \ 1659 "Create HPACK dynamic table"); 1660 if (NULL == dyn) 1661 return MHDT_TEST_RESULT (); 1662 1663 /* Add large strings */ 1664 for (i = 0; i < num_inter; ++i) 1665 { 1666 size_t prev_used; 1667 size_t cur_used; 1668 size_t strs_size; 1669 1670 cur_used = mhdtl_dyn_get_size_used (dyn); 1671 do 1672 { 1673 strs_size = 50u + mhdtl_mix16 (i, 1674 (uint_least16_t) prev_used) % 256u; 1675 prev_used = cur_used; 1676 mhdtl_dyn_add_sized_strs_with_check (dyn, 1677 strs_size); 1678 cur_used = mhdtl_dyn_get_size_used (dyn); 1679 } while (prev_used + strs_size + mhd_HPACK_ENTRY_OVERHEAD 1680 == cur_used); 1681 mhd_dtbl_evict_to_size (dyn, 1682 0u); 1683 } 1684 1685 /* Add small strings */ 1686 for (i = 0; i < num_inter; ++i) 1687 { 1688 size_t prev_used; 1689 size_t cur_used; 1690 size_t strs_size; 1691 1692 cur_used = mhdtl_dyn_get_size_used (dyn); 1693 do 1694 { 1695 strs_size = mhdtl_mix16 (i, 1696 (uint_least16_t) prev_used) % 16u; 1697 prev_used = cur_used; 1698 mhdtl_dyn_add_sized_strs_with_check (dyn, 1699 strs_size); 1700 cur_used = mhdtl_dyn_get_size_used (dyn); 1701 } while (prev_used + strs_size + mhd_HPACK_ENTRY_OVERHEAD 1702 == cur_used); 1703 mhd_dtbl_evict_to_size (dyn, 1704 0u); 1705 } 1706 1707 /* Add mixed-size strings */ 1708 for (i = 0; i < num_inter; ++i) 1709 { 1710 size_t prev_used; 1711 size_t cur_used; 1712 size_t strs_size; 1713 1714 cur_used = mhdtl_dyn_get_size_used (dyn); 1715 do 1716 { 1717 strs_size = mhdtl_mix16 (i, 1718 (uint_least16_t) prev_used) % 312u; 1719 prev_used = cur_used; 1720 mhdtl_dyn_add_sized_strs_with_check (dyn, 1721 strs_size); 1722 cur_used = mhdtl_dyn_get_size_used (dyn); 1723 } while (prev_used + strs_size + mhd_HPACK_ENTRY_OVERHEAD 1724 == cur_used); 1725 mhd_dtbl_evict_to_size (dyn, 1726 0u); 1727 } 1728 1729 mhd_dtbl_destroy (dyn); 1730 1731 return MHDT_TEST_RESULT (); 1732 } 1733 1734 1735 static int 1736 test_dyn_add_evict_series (void) 1737 { 1738 const uint_fast16_t num_inter = 1739 (uint_fast16_t) 1740 (mhdtl_enable_deep_tests ? (1024u) : (64u)); 1741 struct mhd_HpackDTblContext*dyn; 1742 uint_fast16_t i; 1743 1744 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (925u), \ 1745 "Create HPACK dynamic table"); 1746 if (NULL == dyn) 1747 return MHDT_TEST_RESULT (); 1748 1749 for (i = 0; i < num_inter; ++i) 1750 { 1751 uint_fast16_t j; 1752 /* Add large strings */ 1753 for (j = 0; j < 128u; ++j) 1754 { 1755 size_t strs_size = 50u + mhdtl_mix16 (i, j) % 256u; 1756 mhdtl_dyn_add_sized_strs_with_check (dyn, 1757 strs_size); 1758 /* Sometimes repeat the same size */ 1759 if (16u == (j % 32u)) 1760 { 1761 unsigned int num_rep = mhdtl_mix16 (j, i) % 16u; 1762 while (0 != num_rep--) 1763 mhdtl_dyn_add_sized_strs_with_check (dyn, 1764 strs_size); 1765 } 1766 } 1767 /* Add small strings */ 1768 for (j = 0; j < 512u; ++j) 1769 { 1770 size_t strs_size = mhdtl_mix16 (i, j) % 15u; 1771 mhdtl_dyn_add_sized_strs_with_check (dyn, 1772 strs_size); 1773 /* Sometimes repeat the same size */ 1774 if (16u == (j % 32u)) 1775 { 1776 unsigned int num_rep = mhdtl_mix16 (j, i) % 32u; 1777 while (0 != num_rep--) 1778 mhdtl_dyn_add_sized_strs_with_check (dyn, 1779 strs_size); 1780 } 1781 } 1782 /* Add mixed-size strings */ 1783 for (j = 0; j < 256u; ++j) 1784 { 1785 size_t strs_size = mhdtl_mix16 (i, j) % 312u; 1786 mhdtl_dyn_add_sized_strs_with_check (dyn, 1787 strs_size); 1788 /* Sometimes repeat the same size */ 1789 if (16u == (j % 32u)) 1790 { 1791 unsigned int num_rep = mhdtl_mix16 (j, i) % 24u; 1792 while (0 != num_rep--) 1793 mhdtl_dyn_add_sized_strs_with_check (dyn, 1794 strs_size); 1795 } 1796 } 1797 /* Again add small strings before adding large strings */ 1798 for (j = 0; j < 32u; ++j) 1799 { 1800 size_t strs_size = mhdtl_mix16 (i, j) % 15u; 1801 mhdtl_dyn_add_sized_strs_with_check (dyn, 1802 strs_size); 1803 } 1804 } 1805 1806 mhd_dtbl_destroy (dyn); 1807 1808 return MHDT_TEST_RESULT (); 1809 } 1810 1811 1812 static int 1813 test_dyn_evict_to_size (void) 1814 { 1815 struct mhd_HpackDTblContext*dyn; 1816 1817 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \ 1818 "Create HPACK dynamic table"); 1819 if (NULL == dyn) 1820 return MHDT_TEST_RESULT (); 1821 1822 #define MHDTL_H01N "a" /* length: 1 */ 1823 #define MHDTL_H01V "b" /* length: 1 */ 1824 #define MHDTL_H02N "cd" /* length: 2 */ 1825 #define MHDTL_H02V "ef" /* length: 2 */ 1826 #define MHDTL_H03N "header3" /* length: 7 */ 1827 #define MHDTL_H03V "value of header3" /* length: 16 */ 1828 #define MHDTL_H04N "some-header4" /* length: 12 */ 1829 #define MHDTL_H04V "even longer value of the header4" /* length: 32 */ 1830 1831 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H01N, MHDTL_H01V); /* 1 + 1 + 32 = 34 */ 1832 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H02N, MHDTL_H02V); /* 2 + 2 + 32 = 36 */ 1833 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H03N, MHDTL_H03V); /* 7 + 16 + 32 = 55 */ 1834 mhdtl_dyn_add_hdr_with_check (dyn, MHDTL_H04N, MHDTL_H04V); /* 12 + 32 + 32 = 76 */ 1835 /* Total size: 34 + 36 + 55 + 76 = 201 */ 1836 1837 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u); 1838 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1839 1840 mhdtl_dyn_check_entry_at_idx (dyn, 1841 mhd_HPACK_STBL_LAST_IDX + 1u, 1842 MHDTL_H04N, MHDTL_H04V); 1843 mhdtl_dyn_check_entry_at_idx (dyn, 1844 mhd_HPACK_STBL_LAST_IDX + 2u, 1845 MHDTL_H03N, MHDTL_H03V); 1846 mhdtl_dyn_check_entry_at_idx (dyn, 1847 mhd_HPACK_STBL_LAST_IDX + 3u, 1848 MHDTL_H02N, MHDTL_H02V); 1849 mhdtl_dyn_check_entry_at_idx (dyn, 1850 mhd_HPACK_STBL_LAST_IDX + 4u, 1851 MHDTL_H01N, MHDTL_H01V); 1852 1853 mhdtl_dyn_check_get_valid_invalid (dyn); 1854 1855 mhd_dtbl_evict_to_size (dyn, 202u); /* Nothing should be evicted */ 1856 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u); 1857 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1858 mhdtl_dyn_check_get_valid_invalid (dyn); 1859 1860 mhd_dtbl_evict_to_size (dyn, 201u); /* Still nothing should be evicted */ 1861 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u); 1862 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 1863 mhdtl_dyn_check_get_valid_invalid (dyn); 1864 1865 mhd_dtbl_evict_to_size (dyn, 200u); /* Oldest entry should be evicted */ 1866 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 201u - 34u); 1867 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1868 1869 mhdtl_dyn_check_entry_at_idx (dyn, 1870 mhd_HPACK_STBL_LAST_IDX + 1u, 1871 MHDTL_H04N, MHDTL_H04V); 1872 mhdtl_dyn_check_entry_at_idx (dyn, 1873 mhd_HPACK_STBL_LAST_IDX + 2u, 1874 MHDTL_H03N, MHDTL_H03V); 1875 mhdtl_dyn_check_entry_at_idx (dyn, 1876 mhd_HPACK_STBL_LAST_IDX + 3u, 1877 MHDTL_H02N, MHDTL_H02V); 1878 1879 mhdtl_dyn_check_get_valid_invalid (dyn); 1880 1881 mhd_dtbl_evict_to_size (dyn, 76u + 1u); /* Only last entry should be left */ 1882 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 76u); 1883 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 1884 1885 mhdtl_dyn_check_entry_at_idx (dyn, 1886 mhd_HPACK_STBL_LAST_IDX + 1u, 1887 MHDTL_H04N, MHDTL_H04V); 1888 1889 mhdtl_dyn_check_get_valid_invalid (dyn); 1890 1891 mhd_dtbl_evict_to_size (dyn, 76u - 1u); /* Everything should be evicted */ 1892 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 0u); 1893 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 1894 1895 mhdtl_dyn_check_get_valid_invalid (dyn); 1896 1897 #undef MHDTL_H01N 1898 #undef MHDTL_H01V 1899 #undef MHDTL_H02N 1900 #undef MHDTL_H02V 1901 #undef MHDTL_H03N 1902 #undef MHDTL_H03V 1903 #undef MHDTL_H04N 1904 #undef MHDTL_H04V 1905 1906 mhd_dtbl_destroy (dyn); 1907 1908 return MHDT_TEST_RESULT (); 1909 } 1910 1911 1912 static int 1913 test_dyn_resize (void) 1914 { 1915 struct mhd_HpackDTblContext*dyn; 1916 1917 /* zero-sized table */ 1918 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (321u), \ 1919 "Create HPACK dynamic table"); 1920 if (NULL == dyn) 1921 return MHDT_TEST_RESULT (); 1922 1923 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 1924 mhdtl_dyn_add_sized_entry_with_check (dyn, 150u); 1925 mhdtl_dyn_add_hdr_with_check (dyn, "c", "d"); 1926 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1927 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 218u); 1928 1929 /* Resize table (should be no eviction) */ 1930 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 230u), "resize of the table"); 1931 MHDT_EXPECT_PTR_NONNULL (dyn); 1932 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 230u); 1933 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1934 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 218u); 1935 mhdtl_dyn_check_entry_at_idx (dyn, 1936 mhd_HPACK_STBL_LAST_IDX + 3u, 1937 "a", 1938 "b"); 1939 mhdtl_dyn_check_entry_at_idx (dyn, 1940 mhd_HPACK_STBL_LAST_IDX + 1u, 1941 "c", 1942 "d"); 1943 1944 /* Resize table (should be still no eviction) */ 1945 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 218u), "resize of the table"); 1946 MHDT_EXPECT_PTR_NONNULL (dyn); 1947 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 218u); 1948 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1949 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 218u); 1950 mhdtl_dyn_check_entry_at_idx (dyn, 1951 mhd_HPACK_STBL_LAST_IDX + 3u, 1952 "a", 1953 "b"); 1954 mhdtl_dyn_check_entry_at_idx (dyn, 1955 mhd_HPACK_STBL_LAST_IDX + 1u, 1956 "c", 1957 "d"); 1958 1959 /* Resize table (oldest entry should be evicted) */ 1960 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 217u), "resize of the table"); 1961 MHDT_EXPECT_PTR_NONNULL (dyn); 1962 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 217u); 1963 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1964 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 184u); 1965 mhdtl_dyn_add_hdr_with_check (dyn, "x", ""); 1966 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 1967 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 217u); 1968 mhdtl_dyn_check_entry_at_idx (dyn, 1969 mhd_HPACK_STBL_LAST_IDX + 1u, 1970 "x", 1971 ""); 1972 1973 /* Resize table (all entries except the newest should be evicted) */ 1974 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 33u), "resize of the table"); 1975 MHDT_EXPECT_PTR_NONNULL (dyn); 1976 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 33u); 1977 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 1978 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 33u); 1979 mhdtl_dyn_check_entry_at_idx (dyn, 1980 mhd_HPACK_STBL_LAST_IDX + 1u, 1981 "x", 1982 ""); 1983 1984 /* Resize table (grow, no eviction) */ 1985 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 501u), "resize of the table"); 1986 MHDT_EXPECT_PTR_NONNULL (dyn); 1987 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 501u); 1988 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 1989 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 33u); 1990 mhdtl_dyn_add_sized_entry_with_check (dyn, 468u); 1991 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 1992 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 501u); 1993 mhdtl_dyn_check_entry_at_idx (dyn, 1994 mhd_HPACK_STBL_LAST_IDX + 2u, 1995 "x", 1996 ""); 1997 1998 mhd_dtbl_destroy (dyn); 1999 2000 return MHDT_TEST_RESULT (); 2001 } 2002 2003 2004 static int 2005 test_dyn_find (void) 2006 { 2007 static const char *hdr1_name = "first-hdr"; 2008 static const char *hdr1_val = "first value"; 2009 static const char *hdr2_name = "second-hdr"; 2010 static const char *hdr2_val = "second value"; 2011 static const char *hdr3_name = "third-hdr"; 2012 static const char *hdr3_val = "third value"; 2013 static const char *hdr4_name = "fourth-hdr"; 2014 static const char *hdr4_val = "fourth value"; 2015 struct mhd_HpackDTblContext*dyn; 2016 2017 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (256u), \ 2018 "Create HPACK dynamic table"); 2019 if (NULL == dyn) 2020 return MHDT_TEST_RESULT (); 2021 2022 mhdtl_dyn_add_hdr_with_check (dyn, hdr1_name, hdr1_val); 2023 mhdtl_dyn_add_hdr_with_check (dyn, hdr2_name, hdr2_val); 2024 mhdtl_dyn_add_hdr_with_check (dyn, hdr3_name, hdr3_val); 2025 mhdtl_dyn_add_hdr_with_check (dyn, hdr4_name, hdr4_val); 2026 2027 mhdtl_dyn_check_entry_at_idx (dyn, 2028 mhd_HPACK_STBL_LAST_IDX + 4u, 2029 hdr1_name, hdr1_val); 2030 mhdtl_dyn_check_entry_at_idx (dyn, 2031 mhd_HPACK_STBL_LAST_IDX + 3u, 2032 hdr2_name, hdr2_val); 2033 mhdtl_dyn_check_entry_at_idx (dyn, 2034 mhd_HPACK_STBL_LAST_IDX + 2u, 2035 hdr3_name, hdr3_val); 2036 mhdtl_dyn_check_entry_at_idx (dyn, 2037 mhd_HPACK_STBL_LAST_IDX + 1u, 2038 hdr4_name, hdr4_val); 2039 2040 mhd_dtbl_destroy (dyn); 2041 2042 return MHDT_TEST_RESULT (); 2043 } 2044 2045 2046 static int 2047 test_dyn_reset_on_too_large (void) 2048 { 2049 static const size_t tbl_size = 133u; /* not a power of two */ 2050 struct mhd_HpackDTblContext*dyn; 2051 2052 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (tbl_size), \ 2053 "Create HPACK dynamic table"); 2054 if (NULL == dyn) 2055 return MHDT_TEST_RESULT (); 2056 2057 /* Add small entries */ 2058 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 2059 mhdtl_dyn_add_hdr_with_check (dyn, "c", "d"); 2060 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 2061 2062 mhdtl_dyn_add_sized_entry_with_check (dyn, tbl_size + 1); 2063 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2064 2065 /* Re-add small entries */ 2066 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 2067 mhdtl_dyn_add_hdr_with_check (dyn, "c", "d"); 2068 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 2069 2070 mhdtl_dyn_add_sized_entry_with_check (dyn, tbl_size); 2071 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 2072 2073 if (1) 2074 { 2075 struct mhd_BufferConst check_name; 2076 struct mhd_BufferConst check_value; 2077 2078 if (MHDT_EXPECT_TRUE (mhd_dtbl_get_entry (dyn, \ 2079 mhd_HPACK_STBL_LAST_IDX + 1u, \ 2080 &check_name, 2081 &check_value))) 2082 { 2083 MHDT_EXPECT_UINT_GT_VAL (check_name.size, 1u); 2084 MHDT_EXPECT_UINT_GT_VAL (check_value.size, 1u); 2085 } 2086 } 2087 2088 mhd_dtbl_destroy (dyn); 2089 2090 return MHDT_TEST_RESULT (); 2091 } 2092 2093 2094 static int 2095 test_dyn_zero_sizes (void) 2096 { 2097 struct mhd_HpackDTblContext*dyn; 2098 2099 /* zero-sized table */ 2100 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (0u), \ 2101 "Create HPACK dynamic table"); 2102 if (NULL == dyn) 2103 return MHDT_TEST_RESULT (); 2104 2105 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 2106 mhdtl_dyn_add_hdr_with_check (dyn, "c", "d"); 2107 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2108 /* smallest entry (zero-sized strings) */ 2109 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2110 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2111 2112 /* Resize table to the same zero size */ 2113 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \ 2114 "resize of the table"); 2115 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u); 2116 /* smallest entry (zero-sized strings) */ 2117 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2118 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2119 2120 /* Resize table to non-zero size */ 2121 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 127u), \ 2122 "resize of the table"); 2123 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 127u); 2124 2125 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 2126 mhdtl_dyn_add_hdr_with_check (dyn, "c", "d"); 2127 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 2128 2129 mhd_dtbl_evict_to_size (dyn, 0u); 2130 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2131 2132 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 2133 mhdtl_dyn_add_hdr_with_check (dyn, "c", "d"); 2134 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 2u); 2135 2136 mhdtl_dyn_add_sized_entry_with_check (dyn, 45u); 2137 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 2138 mhdtl_dyn_check_entry_at_idx (dyn, 2139 mhd_HPACK_STBL_LAST_IDX + 3u, 2140 "a", 2141 "b"); 2142 mhdtl_dyn_check_entry_at_idx (dyn, 2143 mhd_HPACK_STBL_LAST_IDX + 2u, 2144 "c", 2145 "d"); 2146 2147 /* smallest entries (zero-sized strings) */ 2148 mhdtl_dyn_add_hdr_with_check (dyn, "", ""); 2149 mhdtl_dyn_add_hdr_with_check (dyn, "", ""); 2150 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 2151 mhdtl_dyn_check_entry_at_idx (dyn, 2152 mhd_HPACK_STBL_LAST_IDX + 1u, 2153 "", 2154 ""); 2155 mhdtl_dyn_check_entry_at_idx (dyn, 2156 mhd_HPACK_STBL_LAST_IDX + 2u, 2157 "", 2158 ""); 2159 2160 /* Resize table to zero size again */ 2161 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \ 2162 "resize of the table"); 2163 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u); 2164 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2165 mhd_dtbl_evict_to_size (dyn, 0u); 2166 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u); 2167 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2168 2169 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 2170 mhdtl_dyn_add_hdr_with_check (dyn, "c", "d"); 2171 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2172 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2173 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2174 2175 /* Resize table to the size smaller than minimal entry size */ 2176 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 31u), \ 2177 "resize of the table"); 2178 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2179 mhdtl_dyn_add_hdr_with_check (dyn, "a", "b"); 2180 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2181 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2182 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2183 2184 /* Resize table to the minimal size */ 2185 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 32u), \ 2186 "resize of the table"); 2187 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 32u); 2188 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2189 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 1u); 2190 /* Resize table back to the size smaller than minimal entry size */ 2191 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 31u), \ 2192 "resize of the table"); 2193 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 31u); 2194 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2195 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2196 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2197 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \ 2198 "resize of the table"); 2199 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u); 2200 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2201 2202 /* Resize table to the usable size */ 2203 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 128u), \ 2204 "resize of the table"); 2205 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 128u); 2206 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2207 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2208 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2209 mhdtl_dyn_add_sized_strs_with_check (dyn, 0u); 2210 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 4u); 2211 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 128u); 2212 mhdtl_dyn_add_hdr_with_check (dyn, "a", "1"); 2213 mhdtl_dyn_add_hdr_with_check (dyn, "b", "2"); 2214 mhdtl_dyn_add_hdr_with_check (dyn, "c", "3"); 2215 mhdtl_dyn_add_hdr_with_check (dyn, "d", "4"); 2216 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 3u); 2217 MHDT_EXPECT_UINT_EQ_VAL (mhdtl_dyn_get_size_used (dyn), 102u); 2218 mhdtl_dyn_check_entry_at_idx (dyn, 2219 mhd_HPACK_STBL_LAST_IDX + 3u, 2220 "b", 2221 "2"); 2222 /* Resize table to zero size again */ 2223 MHDT_EXPECT_TRUE_D (mhd_dtbl_resize (&dyn, 0u), \ 2224 "resize of the table"); 2225 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_table_max_size (dyn), 0u); 2226 MHDT_EXPECT_UINT_EQ_VAL (mhd_dtbl_get_num_entries (dyn), 0u); 2227 2228 mhd_dtbl_destroy (dyn); 2229 2230 return MHDT_TEST_RESULT (); 2231 } 2232 2233 2234 static int 2235 test_stat_get_find (void) 2236 { 2237 mhdtl_stat_check_entry_at_idx (1u, 2238 ":authority", 2239 ""); 2240 mhdtl_stat_check_entry_at_idx (5u, 2241 ":path", 2242 "/index.html"); 2243 mhdtl_stat_check_entry_at_idx (14u, 2244 ":status", 2245 "500"); 2246 mhdtl_stat_check_entry_at_idx (15u, 2247 "accept-charset", 2248 ""); 2249 mhdtl_stat_check_entry_at_idx (16u, 2250 "accept-encoding", 2251 "gzip, deflate"); 2252 mhdtl_stat_check_entry_at_idx (17u, 2253 "accept-language", 2254 ""); 2255 mhdtl_stat_check_entry_at_idx (31u, 2256 "content-type", 2257 ""); 2258 mhdtl_stat_check_entry_at_idx (42u, 2259 "if-range", 2260 ""); 2261 mhdtl_stat_check_entry_at_idx (47u, 2262 "max-forwards", 2263 ""); 2264 mhdtl_stat_check_entry_at_idx (51u, 2265 "referer", 2266 ""); 2267 mhdtl_stat_check_entry_at_idx (58u, 2268 "user-agent", 2269 ""); 2270 mhdtl_stat_check_entry_at_idx (61u, 2271 "www-authenticate", 2272 ""); 2273 2274 return MHDT_TEST_RESULT (); 2275 } 2276 2277 2278 static int 2279 test_stat_find_non_pseudo_entry_absent (void) 2280 { 2281 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("foo","bar"), \ 2282 0u, \ 2283 "search for non-existing header should fail"); 2284 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("foo",""), \ 2285 0u, \ 2286 "search for non-existing header should fail"); 2287 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("","bar"), \ 2288 0u, \ 2289 "search for non-existing header should fail"); 2290 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR ("",""), \ 2291 0u, \ 2292 "search for non-existing header should fail"); 2293 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR (":foo",""), \ 2294 0u, \ 2295 "search for non-existing header should fail"); 2296 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR (":authority",""), \ 2297 0u, \ 2298 "search for pseudo-header should fail"); 2299 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_ENTRY_REAL_STR (":status", \ 2300 "200"), \ 2301 0u, \ 2302 "search for pseudo-header should fail"); 2303 2304 return MHDT_TEST_RESULT_D ("search for non-existing non-pseudo headers"); 2305 } 2306 2307 2308 static int 2309 test_stat_find_non_pseudo_name_absent (void) 2310 { 2311 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR ("foo"), \ 2312 0u, \ 2313 "search for non-existing header should fail"); 2314 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (""), \ 2315 0u, \ 2316 "search for non-existing header should fail"); 2317 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (":foo"), \ 2318 0u, \ 2319 "search for non-existing header should fail"); 2320 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (":authority"), \ 2321 0u, \ 2322 "search for pseudo-header should fail"); 2323 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_STBL_FIND_NAME_REAL_STR (":status"), \ 2324 0u, \ 2325 "search for pseudo-header should fail"); 2326 2327 return MHDT_TEST_RESULT_D ("search for non-existing non-pseudo names"); 2328 } 2329 2330 2331 static int 2332 test_comb_get_find (void) 2333 { 2334 struct mhd_HpackDTblContext *dyn; 2335 2336 /* zero-sized table */ 2337 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (456u), \ 2338 "Create HPACK dynamic table"); 2339 if (NULL == dyn) 2340 return MHDT_TEST_RESULT (); 2341 2342 mhdtl_dyn_add_hdr_with_check (dyn, "abc", "xyz"); 2343 mhdtl_dyn_add_hdr_with_check (dyn, "", "empty-name"); 2344 mhdtl_dyn_add_hdr_with_check (dyn, "empty-value", ""); 2345 mhdtl_dyn_add_hdr_with_check (dyn, "", ""); 2346 mhdtl_dyn_add_hdr_with_check (dyn, "2", "two"); 2347 2348 mhdtl_comb_check_entry_at_idx (dyn, 2349 1u, 2350 ":authority", 2351 ""); 2352 mhdtl_comb_check_entry_at_idx (dyn, 2353 5u, 2354 ":path", 2355 "/index.html"); 2356 mhdtl_comb_check_entry_at_idx (dyn, 2357 16u, 2358 "accept-encoding", 2359 "gzip, deflate"); 2360 mhdtl_comb_check_entry_at_idx (dyn, 2361 17u, 2362 "accept-language", 2363 ""); 2364 mhdtl_comb_check_entry_at_idx (dyn, 2365 42u, 2366 "if-range", 2367 ""); 2368 mhdtl_comb_check_entry_at_idx (dyn, 2369 61u, 2370 "www-authenticate", 2371 ""); 2372 mhdtl_comb_check_entry_at_idx (dyn, 2373 62u, 2374 "2", 2375 "two"); 2376 mhdtl_comb_check_entry_at_idx (dyn, 2377 63u, 2378 "", 2379 ""); 2380 mhdtl_comb_check_entry_at_idx (dyn, 2381 64u, 2382 "empty-value", 2383 ""); 2384 mhdtl_comb_check_entry_at_idx (dyn, 2385 65u, 2386 "", 2387 "empty-name"); 2388 mhdtl_comb_check_entry_at_idx (dyn, 2389 66u, 2390 "abc", 2391 "xyz"); 2392 2393 mhd_dtbl_destroy (dyn); 2394 2395 return MHDT_TEST_RESULT (); 2396 } 2397 2398 2399 static int 2400 test_comb_find_entry_absent (void) 2401 { 2402 struct mhd_HpackDTblContext *dyn; 2403 2404 /* zero-sized table */ 2405 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (456u), \ 2406 "Create HPACK dynamic table"); 2407 if (NULL == dyn) 2408 return MHDT_TEST_RESULT (); 2409 2410 mhdtl_dyn_add_hdr_with_check (dyn, "", ""); 2411 mhdtl_dyn_add_hdr_with_check (dyn, "hdr1", "value1"); 2412 mhdtl_dyn_add_hdr_with_check (dyn, "", "empty-name"); 2413 mhdtl_dyn_add_hdr_with_check (dyn, "hdr2", "value2"); 2414 mhdtl_dyn_add_hdr_with_check (dyn, "empty-value", ""); 2415 2416 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, "foo","bar"), \ 2417 0u, \ 2418 "search for non-existing header should fail"); 2419 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, "foo",""), \ 2420 0u, \ 2421 "search for non-existing header should fail"); 2422 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, "","bar"), \ 2423 0u, \ 2424 "search for non-existing header should fail"); 2425 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, ":foo",""), \ 2426 0u, \ 2427 "search for non-existing header should fail"); 2428 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, \ 2429 ":authority",""), \ 2430 0u, \ 2431 "search for pseudo-header should fail"); 2432 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_ENTRY_REAL_STR (dyn, ":status", \ 2433 "200"), \ 2434 0u, \ 2435 "search for pseudo-header should fail"); 2436 2437 mhdtl_comb_check_entry_at_idx (dyn, mhd_HPACK_STBL_LAST_IDX + 5u, 2438 "", 2439 ""); 2440 mhdtl_comb_check_entry_at_idx (dyn, mhd_HPACK_STBL_LAST_IDX + 1u, 2441 "empty-value", 2442 ""); 2443 2444 mhd_dtbl_destroy (dyn); 2445 2446 return MHDT_TEST_RESULT (); 2447 } 2448 2449 2450 static int 2451 test_comb_find_name_absent (void) 2452 { 2453 struct mhd_HpackDTblContext *dyn; 2454 2455 /* zero-sized table */ 2456 MHDT_EXPECT_PTR_NONNULL_D (dyn = mhd_dtbl_create (456u), \ 2457 "Create HPACK dynamic table"); 2458 if (NULL == dyn) 2459 return MHDT_TEST_RESULT (); 2460 2461 mhdtl_dyn_add_hdr_with_check (dyn, "hdr1", "value1"); 2462 mhdtl_dyn_add_hdr_with_check (dyn, "hdr2", "value2"); 2463 mhdtl_dyn_add_hdr_with_check (dyn, "empty-value", ""); 2464 mhdtl_dyn_add_hdr_with_check (dyn, "", "empty-name"); 2465 mhdtl_dyn_add_hdr_with_check (dyn, "", ""); 2466 2467 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, "foo"), \ 2468 0u, \ 2469 "search for non-existing header should fail"); 2470 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, ":foo"), \ 2471 0u, \ 2472 "search for non-existing header should fail"); 2473 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, ":authority"), \ 2474 0u, \ 2475 "search for pseudo-header should fail"); 2476 MHDT_EXPECT_UINT_EQ_VAL_D (MHDTL_HTBL_FIND_NAME_REAL_STR (dyn, ":status"), \ 2477 0u, \ 2478 "search for pseudo-header should fail"); 2479 2480 mhdtl_comb_check_entry_at_idx (dyn, 2481 mhd_HPACK_STBL_LAST_IDX + 1u, 2482 "", 2483 ""); 2484 mhdtl_comb_check_entry_at_idx (dyn, 2485 mhd_HPACK_STBL_LAST_IDX + 5u, 2486 "hdr1", 2487 "value1"); 2488 2489 mhd_dtbl_destroy (dyn); 2490 2491 return MHDT_TEST_RESULT (); 2492 } 2493 2494 2495 int 2496 main (int argc, 2497 char *const *argv) 2498 { 2499 if (argc < 1) 2500 return 99; 2501 2502 if (mhdt_has_param (argc, argv, "-v") || 2503 mhdt_has_param (argc, argv, "--verbose")) 2504 MHDT_set_verbosity (MHDT_VERB_LVL_VERBOSE); 2505 else if (mhdt_has_param (argc, argv, "-s") || 2506 mhdt_has_param (argc, argv, "--silent")) 2507 MHDT_set_verbosity (MHDT_VERB_LVL_SILENT); 2508 2509 if (! mhdtl_enable_deep_tests) 2510 mhdtl_enable_deep_tests = mhdt_has_param (argc, argv, "--deep"); 2511 2512 if (mhdt_has_in_name (argv[0], "_dynamic")) 2513 { 2514 test_dyn_create_destroy (); 2515 test_dyn_create_destroy_larger (); 2516 test_dyn_add_three (); 2517 test_dyn_add_empty (); 2518 test_dyn_add_evict_simple (); 2519 test_dyn_add_evict_wrap (); 2520 test_dyn_add_evict_inter (); 2521 test_dyn_evict_to_size (); 2522 test_dyn_resize (); 2523 test_dyn_find (); 2524 test_dyn_reset_on_too_large (); 2525 test_dyn_zero_sizes (); 2526 test_dyn_add_series (); 2527 test_dyn_add_evict_series (); 2528 } 2529 else if (mhdt_has_in_name (argv[0], "_static")) 2530 { 2531 test_stat_get_find (); 2532 test_stat_find_non_pseudo_entry_absent (); 2533 test_stat_find_non_pseudo_name_absent (); 2534 } 2535 else if (mhdt_has_in_name (argv[0], "_combined")) 2536 { 2537 test_comb_get_find (); 2538 test_comb_find_entry_absent (); 2539 test_comb_find_name_absent (); 2540 } 2541 else 2542 MHDT_ERR_EXIT_D ("The test subtype marker string was not found in " \ 2543 "the name of this binary"); 2544 2545 return MHDT_FINAL_RESULT (argv[0]); 2546 }