test_rechist.c revision 1a0003e3
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <inttypes.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7 8#ifdef WIN32 9#include "vc_compat.h" 10#endif 11 12#include "lsquic_int_types.h" 13#include "lsquic_rechist.h" 14#include "lsquic_util.h" 15 16 17static void 18test4 (void) 19{ 20 lsquic_rechist_t rechist; 21 const struct lsquic_packno_range *range; 22 lsquic_packno_t packno; 23 24 lsquic_rechist_init(&rechist, 0, 0); 25 26 for (packno = 11917; packno <= 11941; ++packno) 27 lsquic_rechist_received(&rechist, packno, 0); 28 for (packno = 11946; packno <= 11994; ++packno) 29 lsquic_rechist_received(&rechist, packno, 0); 30 31 range = lsquic_rechist_first(&rechist); 32 assert(range); 33 assert(range->high == 11994); 34 assert(range->low == 11946); 35 range = lsquic_rechist_next(&rechist); 36 assert(range); 37 assert(range->high == 11941); 38 assert(range->low == 11917); 39 range = lsquic_rechist_next(&rechist); 40 assert(!range); 41 42 lsquic_rechist_received(&rechist, 11995, 0); 43 lsquic_rechist_received(&rechist, 11996, 0); 44 45 range = lsquic_rechist_first(&rechist); 46 assert(range); 47 assert(range->high == 11996); 48 assert(range->low == 11946); 49 range = lsquic_rechist_next(&rechist); 50 assert(range); 51 assert(range->high == 11941); 52 assert(range->low == 11917); 53 range = lsquic_rechist_next(&rechist); 54 assert(!range); 55 56 lsquic_rechist_received(&rechist, 11912, 0); 57 lsquic_rechist_stop_wait(&rechist, 11860); 58 59 range = lsquic_rechist_first(&rechist); 60 assert(range); 61 assert(range->high == 11996); 62 assert(range->low == 11946); 63 range = lsquic_rechist_next(&rechist); 64 assert(range); 65 assert(range->high == 11941); 66 assert(range->low == 11917); 67 range = lsquic_rechist_next(&rechist); 68 assert(range); 69 assert(range->high == 11912); 70 assert(range->low == 11912); 71 range = lsquic_rechist_next(&rechist); 72 assert(!range); 73 74 for (packno = 12169; packno <= 12193; ++packno) 75 lsquic_rechist_received(&rechist, packno, 0); 76 77 range = lsquic_rechist_first(&rechist); 78 assert(range); 79 assert(range->high == 12193); 80 assert(range->low == 12169); 81 range = lsquic_rechist_next(&rechist); 82 assert(range); 83 assert(range->high == 11996); 84 assert(range->low == 11946); 85 range = lsquic_rechist_next(&rechist); 86 assert(range); 87 assert(range->high == 11941); 88 assert(range->low == 11917); 89 range = lsquic_rechist_next(&rechist); 90 assert(range); 91 assert(range->high == 11912); 92 assert(range->low == 11912); 93 range = lsquic_rechist_next(&rechist); 94 assert(!range); 95 96 lsquic_rechist_cleanup(&rechist); 97} 98 99 100static void 101rechist2str (lsquic_rechist_t *rechist, char *buf, size_t bufsz) 102{ 103 const struct lsquic_packno_range *range; 104 size_t off; 105 int n; 106 107 for (off = 0, range = lsquic_rechist_first(rechist); 108 range && off < bufsz; 109 off += n, range = lsquic_rechist_next(rechist)) 110 { 111 n = snprintf(buf + off, bufsz - off, "[%"PRIu64"-%"PRIu64"]", 112 range->high, range->low); 113 if (n < 0 || (size_t) n >= bufsz - off) 114 break; 115 } 116} 117 118 119static void 120test_range_copy (struct lsquic_rechist *orig, int ietf) 121{ 122 char orig_str[0x1000], new_str[0x1000]; 123 struct lsquic_rechist new; 124 125 rechist2str(orig, orig_str, sizeof(orig_str)); 126 127 lsquic_rechist_init(&new, ietf, 0); 128 lsquic_rechist_copy_ranges(&new, orig, 129 (const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_first, 130 (const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_next); 131 rechist2str(&new, new_str, sizeof(new_str)); 132 assert(0 == strcmp(orig_str, new_str)); 133} 134 135 136static void 137test5 (void) 138{ 139 lsquic_rechist_t rechist; 140 char buf[100]; 141 142 lsquic_rechist_init(&rechist, 0, 0); 143 144 lsquic_rechist_received(&rechist, 1, 0); 145 /* Packet 2 omitted because it could not be decrypted */ 146 lsquic_rechist_received(&rechist, 3, 0); 147 lsquic_rechist_received(&rechist, 12, 0); 148 149 rechist2str(&rechist, buf, sizeof(buf)); 150 assert(0 == strcmp(buf, "[12-12][3-3][1-1]")); 151 152 lsquic_rechist_received(&rechist, 4, 0); 153 lsquic_rechist_received(&rechist, 10, 0); 154 155 rechist2str(&rechist, buf, sizeof(buf)); 156 assert(0 == strcmp(buf, "[12-12][10-10][4-3][1-1]")); 157 158 lsquic_rechist_received(&rechist, 6, 0); 159 160 rechist2str(&rechist, buf, sizeof(buf)); 161 assert(0 == strcmp(buf, "[12-12][10-10][6-6][4-3][1-1]")); 162 163 lsquic_rechist_received(&rechist, 7, 0); 164 lsquic_rechist_received(&rechist, 8, 0); 165 166 rechist2str(&rechist, buf, sizeof(buf)); 167 assert(0 == strcmp(buf, "[12-12][10-10][8-6][4-3][1-1]")); 168 169 lsquic_rechist_received(&rechist, 9, 0); 170 test_range_copy(&rechist, 0); 171 172 rechist2str(&rechist, buf, sizeof(buf)); 173 assert(0 == strcmp(buf, "[12-12][10-6][4-3][1-1]")); 174 175 lsquic_rechist_received(&rechist, 5, 0); 176 lsquic_rechist_received(&rechist, 11, 0); 177 178 rechist2str(&rechist, buf, sizeof(buf)); 179 assert(0 == strcmp(buf, "[12-3][1-1]")); 180 181 lsquic_rechist_cleanup(&rechist); 182} 183 184 185static void 186test_rand_sequence (unsigned seed, unsigned max) 187{ 188 struct lsquic_rechist rechist; 189 const struct lsquic_packno_range *range; 190 lsquic_packno_t prev_low; 191 enum received_st st; 192 unsigned i, count; 193 194 lsquic_rechist_init(&rechist, 1, max); 195 srand(seed); 196 197 for (i = 0; i < 10000; ++i) 198 { 199 st = lsquic_rechist_received(&rechist, (unsigned) rand(), 0); 200 assert(st == REC_ST_OK || st == REC_ST_DUP); 201 } 202 203 test_range_copy(&rechist, 1); 204 205 range = lsquic_rechist_first(&rechist); 206 assert(range); 207 assert(range->high >= range->low); 208 prev_low = range->low; 209 count = 1; 210 211 while (range = lsquic_rechist_next(&rechist), range != NULL) 212 { 213 ++count; 214 assert(range->high >= range->low); 215 assert(range->high < prev_low); 216 prev_low = range->low; 217 } 218 if (max) 219 assert(count <= max); 220 221 lsquic_rechist_cleanup(&rechist); 222} 223 224 225struct shuffle_elem { 226 unsigned packno; 227 int rand; 228}; 229 230 231static int 232comp_els (const void *a_p, const void *b_p) 233{ 234 const struct shuffle_elem *a = a_p, *b = b_p; 235 if (a->rand < b->rand) 236 return -1; 237 if (a->rand > b->rand) 238 return 1; 239 return (a->packno > b->packno) - (b->packno > a->packno); 240} 241 242 243static void 244test_shuffle_1000 (unsigned seed) 245{ 246 struct lsquic_rechist rechist; 247 const struct lsquic_packno_range *range; 248 enum received_st st; 249 unsigned i; 250 struct shuffle_elem *els; 251 252 els = malloc(sizeof(els[0]) * 10000); 253 lsquic_rechist_init(&rechist, 1, 0); 254 srand(seed); 255 256 for (i = 0; i < 10000; ++i) 257 { 258 els[i].packno = i; 259 els[i].rand = rand(); 260 } 261 262 qsort(els, 10000, sizeof(els[0]), comp_els); 263 264 for (i = 0; i < 10000; ++i) 265 { 266 st = lsquic_rechist_received(&rechist, els[i].packno, 0); 267 assert(st == REC_ST_OK || st == REC_ST_DUP); 268 } 269 test_range_copy(&rechist, 1); 270 271 range = lsquic_rechist_first(&rechist); 272 assert(range); 273 assert(range->high == 9999); 274 assert(range->low == 0); 275 range = lsquic_rechist_next(&rechist); 276 assert(!range); 277 278 lsquic_rechist_cleanup(&rechist); 279 free(els); 280} 281 282 283int 284main (void) 285{ 286 enum received_st st; 287 lsquic_rechist_t rechist; 288 unsigned i; 289 const struct lsquic_packno_range *range; 290 291 lsquic_rechist_init(&rechist, 0, 0); 292 293 lsquic_time_t now = 1234; 294 st = lsquic_rechist_received(&rechist, 0, now); 295 assert(("inserting packet number zero results in error", st == REC_ST_ERR)); 296 297 st = lsquic_rechist_received(&rechist, 1, now); 298 assert(("inserting packet number one is successful", st == REC_ST_OK)); 299 300 st = lsquic_rechist_received(&rechist, 1, now); 301 assert(("inserting packet number one again results in duplicate error", 302 st == REC_ST_DUP)); 303 304 range = lsquic_rechist_first(&rechist); 305 assert(("first range returned correctly", range)); 306 assert(("first range low value checks out", range->low == 1)); 307 assert(("first range high value checks out", range->high == 1)); 308 range = lsquic_rechist_next(&rechist); 309 assert(("second range does not exist", !range)); 310 311 for (i = 3; i <= 5; ++i) 312 { 313 st = lsquic_rechist_received(&rechist, i, now); 314 assert(("inserting packet", st == REC_ST_OK)); 315 } 316 317 range = lsquic_rechist_first(&rechist); 318 assert(("first range returned correctly", range)); 319 assert(("first range low value checks out", range->low == 3)); 320 assert(("first range high value checks out", range->high == 5)); 321 range = lsquic_rechist_next(&rechist); 322 assert(("second range returned correctly", range)); 323 assert(("second range low value checks out", range->low == 1)); 324 assert(("second range high value checks out", range->high == 1)); 325 range = lsquic_rechist_next(&rechist); 326 assert(("third range does not exist", !range)); 327 328 lsquic_rechist_stop_wait(&rechist, 3); 329 330 st = lsquic_rechist_received(&rechist, 1, now); 331 assert(("inserting packet number one is unsuccessful after cutoff 3", 332 st == REC_ST_DUP)); 333 334 range = lsquic_rechist_first(&rechist); 335 assert(("first range returned correctly", range)); 336 assert(("first range low value checks out", range->low == 3)); 337 assert(("first range high value checks out", range->high == 5)); 338 range = lsquic_rechist_next(&rechist); 339 assert(("second range does not exist", !range)); 340 341 for (i = 9; i >= 7; --i) 342 { 343 st = lsquic_rechist_received(&rechist, i, now); 344 assert(("inserting packet", st == REC_ST_OK)); 345 } 346 347 range = lsquic_rechist_first(&rechist); 348 assert(("first range returned correctly", range)); 349 assert(("first range low value checks out", range->low == 7)); 350 assert(("first range high value checks out", range->high == 9)); 351 range = lsquic_rechist_next(&rechist); 352 assert(("second range returned correctly", range)); 353 assert(("second range low value checks out", range->low == 3)); 354 assert(("second range high value checks out", range->high == 5)); 355 range = lsquic_rechist_next(&rechist); 356 assert(("third range does not exist", !range)); 357 358 lsquic_rechist_stop_wait(&rechist, 5); 359 360 range = lsquic_rechist_first(&rechist); 361 range = lsquic_rechist_next(&rechist); 362 assert(("second range returned correctly", range)); 363 assert(("second range low value checks out", range->low == 5)); 364 assert(("second range high value checks out", range->high == 5)); 365 range = lsquic_rechist_next(&rechist); 366 assert(("third range does not exist", !range)); 367 368 lsquic_rechist_stop_wait(&rechist, 8); 369 370 range = lsquic_rechist_first(&rechist); 371 assert(("first range returned correctly", range)); 372 assert(("first range low value checks out", range->low == 8)); 373 assert(("first range high value checks out", range->high == 9)); 374 range = lsquic_rechist_next(&rechist); 375 assert(("second range does not exist", !range)); 376 377 lsquic_rechist_cleanup(&rechist); 378 379 test4(); 380 381 test5(); 382 383 for (i = 0; i < 10; ++i) 384 test_rand_sequence(i, 0); 385 386 for (i = 0; i < 10; ++i) 387 test_rand_sequence(i, 111 + i * 3 /* Just something arbitrary */); 388 389 for (i = 0; i < 10; ++i) 390 test_shuffle_1000(i); 391 392 return 0; 393} 394