test_rechist.c revision b62ec17f
1/* Copyright (c) 2017 - 2020 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); 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 120test5 (void) 121{ 122 lsquic_rechist_t rechist; 123 char buf[100]; 124 125 lsquic_rechist_init(&rechist, 0); 126 127 lsquic_rechist_received(&rechist, 1, 0); 128 /* Packet 2 omitted because it could not be decrypted */ 129 lsquic_rechist_received(&rechist, 3, 0); 130 lsquic_rechist_received(&rechist, 12, 0); 131 132 rechist2str(&rechist, buf, sizeof(buf)); 133 assert(0 == strcmp(buf, "[12-12][3-3][1-1]")); 134 135 lsquic_rechist_received(&rechist, 4, 0); 136 lsquic_rechist_received(&rechist, 10, 0); 137 138 rechist2str(&rechist, buf, sizeof(buf)); 139 assert(0 == strcmp(buf, "[12-12][10-10][4-3][1-1]")); 140 141 lsquic_rechist_received(&rechist, 6, 0); 142 143 rechist2str(&rechist, buf, sizeof(buf)); 144 assert(0 == strcmp(buf, "[12-12][10-10][6-6][4-3][1-1]")); 145 146 lsquic_rechist_received(&rechist, 7, 0); 147 lsquic_rechist_received(&rechist, 8, 0); 148 149 rechist2str(&rechist, buf, sizeof(buf)); 150 assert(0 == strcmp(buf, "[12-12][10-10][8-6][4-3][1-1]")); 151 152 lsquic_rechist_received(&rechist, 9, 0); 153 154 rechist2str(&rechist, buf, sizeof(buf)); 155 assert(0 == strcmp(buf, "[12-12][10-6][4-3][1-1]")); 156 157 lsquic_rechist_received(&rechist, 5, 0); 158 lsquic_rechist_received(&rechist, 11, 0); 159 160 rechist2str(&rechist, buf, sizeof(buf)); 161 assert(0 == strcmp(buf, "[12-3][1-1]")); 162 163 lsquic_rechist_cleanup(&rechist); 164} 165 166 167static void 168test_rand_sequence (unsigned seed) 169{ 170 struct lsquic_rechist rechist; 171 const struct lsquic_packno_range *range; 172 lsquic_packno_t prev_low; 173 enum received_st st; 174 unsigned i; 175 176 lsquic_rechist_init(&rechist, 1); 177 srand(seed); 178 179 for (i = 0; i < 10000; ++i) 180 { 181 st = lsquic_rechist_received(&rechist, (unsigned) rand(), 0); 182 assert(st == REC_ST_OK || st == REC_ST_DUP); 183 } 184 185 range = lsquic_rechist_first(&rechist); 186 assert(range); 187 assert(range->high >= range->low); 188 prev_low = range->low; 189 190 while (range = lsquic_rechist_next(&rechist), range != NULL) 191 { 192 assert(range->high >= range->low); 193 assert(range->high < prev_low); 194 prev_low = range->low; 195 } 196 197 lsquic_rechist_cleanup(&rechist); 198} 199 200 201struct shuffle_elem { 202 unsigned packno; 203 int rand; 204}; 205 206 207static int 208comp_els (const void *a_p, const void *b_p) 209{ 210 const struct shuffle_elem *a = a_p, *b = b_p; 211 if (a->rand < b->rand) 212 return -1; 213 if (a->rand > b->rand) 214 return 1; 215 return (a->packno > b->packno) - (b->packno > a->packno); 216} 217 218 219static void 220test_shuffle_1000 (unsigned seed) 221{ 222 struct lsquic_rechist rechist; 223 const struct lsquic_packno_range *range; 224 enum received_st st; 225 unsigned i; 226 struct shuffle_elem *els; 227 228 els = malloc(sizeof(els[0]) * 10000); 229 lsquic_rechist_init(&rechist, 1); 230 srand(seed); 231 232 for (i = 0; i < 10000; ++i) 233 { 234 els[i].packno = i; 235 els[i].rand = rand(); 236 } 237 238 qsort(els, 10000, sizeof(els[0]), comp_els); 239 240 for (i = 0; i < 10000; ++i) 241 { 242 st = lsquic_rechist_received(&rechist, els[i].packno, 0); 243 assert(st == REC_ST_OK || st == REC_ST_DUP); 244 } 245 246 range = lsquic_rechist_first(&rechist); 247 assert(range); 248 assert(range->high == 9999); 249 assert(range->low == 0); 250 range = lsquic_rechist_next(&rechist); 251 assert(!range); 252 253 lsquic_rechist_cleanup(&rechist); 254 free(els); 255} 256 257 258int 259main (void) 260{ 261 enum received_st st; 262 lsquic_rechist_t rechist; 263 unsigned i; 264 const struct lsquic_packno_range *range; 265 266 lsquic_rechist_init(&rechist, 0); 267 268 lsquic_time_t now = 1234; 269 st = lsquic_rechist_received(&rechist, 0, now); 270 assert(("inserting packet number zero results in error", st == REC_ST_ERR)); 271 272 st = lsquic_rechist_received(&rechist, 1, now); 273 assert(("inserting packet number one is successful", st == REC_ST_OK)); 274 275 st = lsquic_rechist_received(&rechist, 1, now); 276 assert(("inserting packet number one again results in duplicate error", 277 st == REC_ST_DUP)); 278 279 range = lsquic_rechist_first(&rechist); 280 assert(("first range returned correctly", range)); 281 assert(("first range low value checks out", range->low == 1)); 282 assert(("first range high value checks out", range->high == 1)); 283 range = lsquic_rechist_next(&rechist); 284 assert(("second range does not exist", !range)); 285 286 for (i = 3; i <= 5; ++i) 287 { 288 st = lsquic_rechist_received(&rechist, i, now); 289 assert(("inserting packet", st == REC_ST_OK)); 290 } 291 292 range = lsquic_rechist_first(&rechist); 293 assert(("first range returned correctly", range)); 294 assert(("first range low value checks out", range->low == 3)); 295 assert(("first range high value checks out", range->high == 5)); 296 range = lsquic_rechist_next(&rechist); 297 assert(("second range returned correctly", range)); 298 assert(("second range low value checks out", range->low == 1)); 299 assert(("second range high value checks out", range->high == 1)); 300 range = lsquic_rechist_next(&rechist); 301 assert(("third range does not exist", !range)); 302 303 lsquic_rechist_stop_wait(&rechist, 3); 304 305 st = lsquic_rechist_received(&rechist, 1, now); 306 assert(("inserting packet number one is unsuccessful after cutoff 3", 307 st == REC_ST_DUP)); 308 309 range = lsquic_rechist_first(&rechist); 310 assert(("first range returned correctly", range)); 311 assert(("first range low value checks out", range->low == 3)); 312 assert(("first range high value checks out", range->high == 5)); 313 range = lsquic_rechist_next(&rechist); 314 assert(("second range does not exist", !range)); 315 316 for (i = 9; i >= 7; --i) 317 { 318 st = lsquic_rechist_received(&rechist, i, now); 319 assert(("inserting packet", st == REC_ST_OK)); 320 } 321 322 range = lsquic_rechist_first(&rechist); 323 assert(("first range returned correctly", range)); 324 assert(("first range low value checks out", range->low == 7)); 325 assert(("first range high value checks out", range->high == 9)); 326 range = lsquic_rechist_next(&rechist); 327 assert(("second range returned correctly", range)); 328 assert(("second range low value checks out", range->low == 3)); 329 assert(("second range high value checks out", range->high == 5)); 330 range = lsquic_rechist_next(&rechist); 331 assert(("third range does not exist", !range)); 332 333 lsquic_rechist_stop_wait(&rechist, 5); 334 335 range = lsquic_rechist_first(&rechist); 336 range = lsquic_rechist_next(&rechist); 337 assert(("second range returned correctly", range)); 338 assert(("second range low value checks out", range->low == 5)); 339 assert(("second range high value checks out", range->high == 5)); 340 range = lsquic_rechist_next(&rechist); 341 assert(("third range does not exist", !range)); 342 343 lsquic_rechist_stop_wait(&rechist, 8); 344 345 range = lsquic_rechist_first(&rechist); 346 assert(("first range returned correctly", range)); 347 assert(("first range low value checks out", range->low == 8)); 348 assert(("first range high value checks out", range->high == 9)); 349 range = lsquic_rechist_next(&rechist); 350 assert(("second range does not exist", !range)); 351 352 lsquic_rechist_cleanup(&rechist); 353 354 test4(); 355 356 test5(); 357 358 for (i = 0; i < 10; ++i) 359 test_rand_sequence(i); 360 361 for (i = 0; i < 10; ++i) 362 test_shuffle_1000(i); 363 364 return 0; 365} 366