1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2de46bf2fSDmitri Tikhonov/* Test ACK merge */ 3de46bf2fSDmitri Tikhonov 4de46bf2fSDmitri Tikhonov#include <assert.h> 5de46bf2fSDmitri Tikhonov#include <regex.h> 6de46bf2fSDmitri Tikhonov#include <stdlib.h> 7de46bf2fSDmitri Tikhonov#include <string.h> 8de46bf2fSDmitri Tikhonov 9de46bf2fSDmitri Tikhonov#include "lsquic.h" 10de46bf2fSDmitri Tikhonov#include "lsquic_types.h" 11de46bf2fSDmitri Tikhonov#include "lsquic_int_types.h" 12de46bf2fSDmitri Tikhonov#include "lsquic_sizes.h" 13de46bf2fSDmitri Tikhonov#include "lsquic_parse.h" 14de46bf2fSDmitri Tikhonov 15de46bf2fSDmitri Tikhonovstruct test 16de46bf2fSDmitri Tikhonov{ 17de46bf2fSDmitri Tikhonov int lineno; 18de46bf2fSDmitri Tikhonov int expect_failure; 19de46bf2fSDmitri Tikhonov char a[MAX_ACKI_STR_SZ]; 20de46bf2fSDmitri Tikhonov char b[MAX_ACKI_STR_SZ]; 21de46bf2fSDmitri Tikhonov char result[MAX_ACKI_STR_SZ]; 22de46bf2fSDmitri Tikhonov}; 23de46bf2fSDmitri Tikhonov 24de46bf2fSDmitri Tikhonov 25de46bf2fSDmitri Tikhonovstatic const struct test tests[] = 26de46bf2fSDmitri Tikhonov{ 27de46bf2fSDmitri Tikhonov 28de46bf2fSDmitri Tikhonov { 29de46bf2fSDmitri Tikhonov .lineno = __LINE__, 30de46bf2fSDmitri Tikhonov .expect_failure = 1, 31de46bf2fSDmitri Tikhonov .a = "", 32de46bf2fSDmitri Tikhonov .b = "[3-3]", 33de46bf2fSDmitri Tikhonov }, 34de46bf2fSDmitri Tikhonov 35de46bf2fSDmitri Tikhonov { 36de46bf2fSDmitri Tikhonov .lineno = __LINE__, 37de46bf2fSDmitri Tikhonov .expect_failure = 1, 38de46bf2fSDmitri Tikhonov .a = "", 39de46bf2fSDmitri Tikhonov .b = "", 40de46bf2fSDmitri Tikhonov }, 41de46bf2fSDmitri Tikhonov 42de46bf2fSDmitri Tikhonov { 43de46bf2fSDmitri Tikhonov .lineno = __LINE__, 44de46bf2fSDmitri Tikhonov .a = "[3-3]", 45de46bf2fSDmitri Tikhonov .b = "[3-3]", 46de46bf2fSDmitri Tikhonov .result = "[3-3]", 47de46bf2fSDmitri Tikhonov }, 48de46bf2fSDmitri Tikhonov 49de46bf2fSDmitri Tikhonov { 50de46bf2fSDmitri Tikhonov .lineno = __LINE__, 51de46bf2fSDmitri Tikhonov .a = "[3-2]", 52de46bf2fSDmitri Tikhonov .b = "[1-1]", 53de46bf2fSDmitri Tikhonov .result = "[3-1]", 54de46bf2fSDmitri Tikhonov }, 55de46bf2fSDmitri Tikhonov 56de46bf2fSDmitri Tikhonov { 57de46bf2fSDmitri Tikhonov .lineno = __LINE__, 58de46bf2fSDmitri Tikhonov .a = "[15-15][3-2]", 59de46bf2fSDmitri Tikhonov .b = "[1-1]", 60de46bf2fSDmitri Tikhonov .result = "[15-15][3-1]", 61de46bf2fSDmitri Tikhonov }, 62de46bf2fSDmitri Tikhonov 63de46bf2fSDmitri Tikhonov { 64de46bf2fSDmitri Tikhonov .lineno = __LINE__, 65de46bf2fSDmitri Tikhonov .a = "[15-10][5-2]", 66de46bf2fSDmitri Tikhonov .b = "[9-6][1-1]", 67de46bf2fSDmitri Tikhonov .result = "[15-1]", 68de46bf2fSDmitri Tikhonov }, 69de46bf2fSDmitri Tikhonov 70de46bf2fSDmitri Tikhonov { 71de46bf2fSDmitri Tikhonov .lineno = __LINE__, 72de46bf2fSDmitri Tikhonov .a = "[15-10][5-2]", 73de46bf2fSDmitri Tikhonov .b = "[15-10][5-2]", 74de46bf2fSDmitri Tikhonov .result = "[15-10][5-2]", 75de46bf2fSDmitri Tikhonov }, 76de46bf2fSDmitri Tikhonov 77de46bf2fSDmitri Tikhonov { 78de46bf2fSDmitri Tikhonov .lineno = __LINE__, 79de46bf2fSDmitri Tikhonov .a = "[33803-33803][33800-33800][33788-33788][33775-33775][33759-33759][33744-33744][33732-33732][33717-33717][33706-33706][33691-33691][33679-33679][33664-33664][33649-33649][33638-33638][33622-33622][33613-33613][33585-33585][33574-33574][33562-33562][33546-33546][33531-33531][33516-33516][33504-33504][33490-33490][33483-33483][33481-32910][32906-32906][32894-32894][32880-32880][32869-32869][32854-32854][32844-32844][32817-32817][32806-32806][32791-32791][32780-32780][32766-32766][32752-32752][32741-32741][32726-32726][32716-32716][32702-32702][32697-32697][32682-32682][32672-32672][32657-32657][32651-32651][32636-32636][32626-32626][32611-32611][32600-32600][32589-32589][32574-32574][32564-32564][32551-32551][32536-32536][32525-32525][32511-32511][32500-32500][32485-32485][32475-32475][32460-32460][32449-32449][32438-32438][32423-32423][32412-32412][32399-32399][32385-32385][32375-32375][32360-32360][32349-32349][32334-32334][32326-32326][32312-32312][32302-32302][32287-32287][32277-32277][32262-32262][32252-32252][32239-32239][32224-32224][32214-32214][32200-32200][32190-32190][32175-32175][32161-32161][32151-32151][32136-32136][32126-32126][32111-32111][32103-32103][32090-32090][32080-32080][32069-32033][32008-30698][30696-30467]", 80de46bf2fSDmitri Tikhonov .b = "[33480-32910][32906-32906][32894-32894][32880-32880][32869-32869][32854-32854][32844-32844][32817-32817][32806-32806][32791-32791][32780-32780][32766-32766][32752-32752][32741-32741][32726-32726][32716-32716][32702-32702][32697-32697][32682-32682][32672-32672][32657-32657][32651-32651][32636-32636][32626-32626][32611-32611][32600-32600][32589-32589][32574-32574][32564-32564][32551-32551][32536-32536][32525-32525][32511-32511][32500-32500][32485-32485][32475-32475][32460-32460][32449-32449][32438-32438][32423-32423][32412-32412][32399-32399][32385-32385][32375-32375][32360-32360][32349-32349][32334-32334][32326-32326][32312-32312][32302-32302][32287-32287][32277-32277][32262-32262][32252-32252][32239-32239][32224-32224][32214-32214][32200-32200][32190-32190][32175-32175][32161-32161][32151-32151][32136-32136][32126-32126][32111-32111][32103-32103][32090-32090][32080-32080][32069-32033][32008-30698][30696-30467]", 81de46bf2fSDmitri Tikhonov .result = "[33803-33803][33800-33800][33788-33788][33775-33775][33759-33759][33744-33744][33732-33732][33717-33717][33706-33706][33691-33691][33679-33679][33664-33664][33649-33649][33638-33638][33622-33622][33613-33613][33585-33585][33574-33574][33562-33562][33546-33546][33531-33531][33516-33516][33504-33504][33490-33490][33483-33483][33481-32910][32906-32906][32894-32894][32880-32880][32869-32869][32854-32854][32844-32844][32817-32817][32806-32806][32791-32791][32780-32780][32766-32766][32752-32752][32741-32741][32726-32726][32716-32716][32702-32702][32697-32697][32682-32682][32672-32672][32657-32657][32651-32651][32636-32636][32626-32626][32611-32611][32600-32600][32589-32589][32574-32574][32564-32564][32551-32551][32536-32536][32525-32525][32511-32511][32500-32500][32485-32485][32475-32475][32460-32460][32449-32449][32438-32438][32423-32423][32412-32412][32399-32399][32385-32385][32375-32375][32360-32360][32349-32349][32334-32334][32326-32326][32312-32312][32302-32302][32287-32287][32277-32277][32262-32262][32252-32252][32239-32239][32224-32224][32214-32214][32200-32200][32190-32190][32175-32175][32161-32161][32151-32151][32136-32136][32126-32126][32111-32111][32103-32103][32090-32090][32080-32080][32069-32033][32008-30698][30696-30467]", 82de46bf2fSDmitri Tikhonov }, 83de46bf2fSDmitri Tikhonov 84de46bf2fSDmitri Tikhonov}; 85de46bf2fSDmitri Tikhonov 86de46bf2fSDmitri Tikhonov 87de46bf2fSDmitri Tikhonovstatic regex_t re; 88de46bf2fSDmitri Tikhonov 89de46bf2fSDmitri Tikhonov 90de46bf2fSDmitri Tikhonovstatic void 91de46bf2fSDmitri Tikhonovinit_ranges (struct ack_info *a, const char *s) 92de46bf2fSDmitri Tikhonov{ 93de46bf2fSDmitri Tikhonov regmatch_t m[3]; 94de46bf2fSDmitri Tikhonov 95de46bf2fSDmitri Tikhonov while (0 == regexec(&re, s, sizeof(m) / sizeof(m[0]), m, 0)) 96de46bf2fSDmitri Tikhonov { 97de46bf2fSDmitri Tikhonov a->ranges[a->n_ranges].high = atoi(s + m[1].rm_so); 98de46bf2fSDmitri Tikhonov a->ranges[a->n_ranges].low = atoi(s + m[2].rm_so); 99de46bf2fSDmitri Tikhonov /* Self-check: */ 100de46bf2fSDmitri Tikhonov assert(a->ranges[a->n_ranges].high >= a->ranges[a->n_ranges].low); 101de46bf2fSDmitri Tikhonov ++a->n_ranges; 102de46bf2fSDmitri Tikhonov s += m[0].rm_eo; 103de46bf2fSDmitri Tikhonov } 104de46bf2fSDmitri Tikhonov} 105de46bf2fSDmitri Tikhonov 106de46bf2fSDmitri Tikhonov 107de46bf2fSDmitri Tikhonovstatic void 108de46bf2fSDmitri Tikhonovrun_test_ext (const struct test *test, const char *a_str, const char *b_str) 109de46bf2fSDmitri Tikhonov{ 110de46bf2fSDmitri Tikhonov struct ack_info a, b; 111de46bf2fSDmitri Tikhonov int s; 112de46bf2fSDmitri Tikhonov char ack_str[MAX_ACKI_STR_SZ]; 113de46bf2fSDmitri Tikhonov 114de46bf2fSDmitri Tikhonov memset(&a, 0, sizeof(a)); 115de46bf2fSDmitri Tikhonov memset(&b, 0, sizeof(b)); 116de46bf2fSDmitri Tikhonov 117de46bf2fSDmitri Tikhonov init_ranges(&a, a_str); 118de46bf2fSDmitri Tikhonov init_ranges(&b, b_str); 119de46bf2fSDmitri Tikhonov 120de46bf2fSDmitri Tikhonov s = lsquic_merge_acks(&a, &b); 121de46bf2fSDmitri Tikhonov if (test->expect_failure) 122de46bf2fSDmitri Tikhonov { 123de46bf2fSDmitri Tikhonov assert(s != 0); 124de46bf2fSDmitri Tikhonov return; 125de46bf2fSDmitri Tikhonov } 126de46bf2fSDmitri Tikhonov 127de46bf2fSDmitri Tikhonov assert(s == 0); 128de46bf2fSDmitri Tikhonov lsquic_acki2str(&a, ack_str, sizeof(ack_str)); 129de46bf2fSDmitri Tikhonov assert(0 == strcmp(ack_str, test->result)); 130de46bf2fSDmitri Tikhonov} 131de46bf2fSDmitri Tikhonov 132de46bf2fSDmitri Tikhonov 133de46bf2fSDmitri Tikhonovstatic void 134de46bf2fSDmitri Tikhonovrun_test (const struct test *test) 135de46bf2fSDmitri Tikhonov{ 136de46bf2fSDmitri Tikhonov run_test_ext(test, test->a, test->b); 137de46bf2fSDmitri Tikhonov /* If flipped result should be the same: */ 138de46bf2fSDmitri Tikhonov run_test_ext(test, test->b, test->a); 139de46bf2fSDmitri Tikhonov} 140de46bf2fSDmitri Tikhonov 141de46bf2fSDmitri Tikhonov 142de46bf2fSDmitri Tikhonovstatic void 143de46bf2fSDmitri Tikhonovtest_out_of_ranges (int success) 144de46bf2fSDmitri Tikhonov{ 145de46bf2fSDmitri Tikhonov struct ack_info a, b; 146de46bf2fSDmitri Tikhonov int i, s; 147de46bf2fSDmitri Tikhonov 148de46bf2fSDmitri Tikhonov memset(&a, 0, sizeof(a)); 149de46bf2fSDmitri Tikhonov memset(&b, 0, sizeof(b)); 150de46bf2fSDmitri Tikhonov 151de46bf2fSDmitri Tikhonov for (i = 0; i < 129 - success; ++i) 152de46bf2fSDmitri Tikhonov { 153de46bf2fSDmitri Tikhonov a.ranges[i].high = a.ranges[i].low = 100000 - i * 10; 154de46bf2fSDmitri Tikhonov b.ranges[i].high = b.ranges[i].low = 100000 - 5 - i * 10; 155de46bf2fSDmitri Tikhonov } 156de46bf2fSDmitri Tikhonov a.n_ranges = i; 157de46bf2fSDmitri Tikhonov b.n_ranges = i; 158de46bf2fSDmitri Tikhonov 159de46bf2fSDmitri Tikhonov s = lsquic_merge_acks(&a, &b); 160de46bf2fSDmitri Tikhonov if (success) 161de46bf2fSDmitri Tikhonov assert(s == 0); 162de46bf2fSDmitri Tikhonov else 163de46bf2fSDmitri Tikhonov assert(s != 0); 164de46bf2fSDmitri Tikhonov} 165de46bf2fSDmitri Tikhonov 166de46bf2fSDmitri Tikhonov 167de46bf2fSDmitri Tikhonovint 168de46bf2fSDmitri Tikhonovmain (void) 169de46bf2fSDmitri Tikhonov{ 170de46bf2fSDmitri Tikhonov const struct test *test; 171de46bf2fSDmitri Tikhonov int s; 172de46bf2fSDmitri Tikhonov 173de46bf2fSDmitri Tikhonov s = regcomp(&re, "\\[([0-9][0-9]*)-([0-9][0-9]*)\\]", REG_EXTENDED); 174de46bf2fSDmitri Tikhonov assert(s == 0); 175de46bf2fSDmitri Tikhonov 176de46bf2fSDmitri Tikhonov for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test) 177de46bf2fSDmitri Tikhonov run_test(test); 178de46bf2fSDmitri Tikhonov 179de46bf2fSDmitri Tikhonov test_out_of_ranges(0); 180de46bf2fSDmitri Tikhonov test_out_of_ranges(1); 181de46bf2fSDmitri Tikhonov 182de46bf2fSDmitri Tikhonov regfree(&re); 183de46bf2fSDmitri Tikhonov 184de46bf2fSDmitri Tikhonov return 0; 185de46bf2fSDmitri Tikhonov} 186