1 #include "test_pbuf.h" 2 3 #include "lwip/pbuf.h" 4 #include "lwip/stats.h" 5 6 #if !LWIP_STATS || !MEM_STATS ||!MEMP_STATS 7 #error "This tests needs MEM- and MEMP-statistics enabled" 8 #endif 9 #if LWIP_DNS 10 #error "This test needs DNS turned off (as it mallocs on init)" 11 #endif 12 #if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !LWIP_WND_SCALE 13 #error "This test needs TCP OOSEQ queueing and window scaling enabled" 14 #endif 15 16 /* Setups/teardown functions */ 17 18 static void 19 pbuf_setup(void) 20 { 21 } 22 23 static void 24 pbuf_teardown(void) 25 { 26 } 27 28 29 #define TESTBUFSIZE_1 65535 30 #define TESTBUFSIZE_2 65530 31 #define TESTBUFSIZE_3 50050 32 static u8_t testbuf_1[TESTBUFSIZE_1]; 33 static u8_t testbuf_1a[TESTBUFSIZE_1]; 34 static u8_t testbuf_2[TESTBUFSIZE_2]; 35 static u8_t testbuf_2a[TESTBUFSIZE_2]; 36 static u8_t testbuf_3[TESTBUFSIZE_3]; 37 static u8_t testbuf_3a[TESTBUFSIZE_3]; 38 39 /* Test functions */ 40 41 /** Call pbuf_copy on a pbuf with zero length */ 42 START_TEST(test_pbuf_copy_zero_pbuf) 43 { 44 struct pbuf *p1, *p2, *p3; 45 err_t err; 46 LWIP_UNUSED_ARG(_i); 47 48 fail_unless(lwip_stats.mem.used == 0); 49 fail_unless(MEMP_STATS_GET(used, MEMP_PBUF_POOL) == 0); 50 51 p1 = pbuf_alloc(PBUF_RAW, 1024, PBUF_RAM); 52 fail_unless(p1 != NULL); 53 fail_unless(p1->ref == 1); 54 55 p2 = pbuf_alloc(PBUF_RAW, 2, PBUF_POOL); 56 fail_unless(p2 != NULL); 57 fail_unless(p2->ref == 1); 58 p2->len = p2->tot_len = 0; 59 60 pbuf_cat(p1, p2); 61 fail_unless(p1->ref == 1); 62 fail_unless(p2->ref == 1); 63 64 p3 = pbuf_alloc(PBUF_RAW, p1->tot_len, PBUF_POOL); 65 err = pbuf_copy(p3, p1); 66 fail_unless(err == ERR_VAL); 67 68 pbuf_free(p1); 69 pbuf_free(p3); 70 fail_unless(lwip_stats.mem.used == 0); 71 72 fail_unless(lwip_stats.mem.used == 0); 73 fail_unless(MEMP_STATS_GET(used, MEMP_PBUF_POOL) == 0); 74 } 75 END_TEST 76 77 START_TEST(test_pbuf_split_64k_on_small_pbufs) 78 { 79 struct pbuf *p, *rest=NULL; 80 LWIP_UNUSED_ARG(_i); 81 82 p = pbuf_alloc(PBUF_RAW, 1, PBUF_POOL); 83 pbuf_split_64k(p, &rest); 84 fail_unless(p->tot_len == 1); 85 pbuf_free(p); 86 } 87 END_TEST 88 89 START_TEST(test_pbuf_queueing_bigger_than_64k) 90 { 91 int i; 92 err_t err; 93 struct pbuf *p1, *p2, *p3, *rest2=NULL, *rest3=NULL; 94 LWIP_UNUSED_ARG(_i); 95 96 for(i = 0; i < TESTBUFSIZE_1; i++) { 97 testbuf_1[i] = (u8_t)rand(); 98 } 99 for(i = 0; i < TESTBUFSIZE_2; i++) { 100 testbuf_2[i] = (u8_t)rand(); 101 } 102 for(i = 0; i < TESTBUFSIZE_3; i++) { 103 testbuf_3[i] = (u8_t)rand(); 104 } 105 106 p1 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_1, PBUF_POOL); 107 fail_unless(p1 != NULL); 108 p2 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_2, PBUF_POOL); 109 fail_unless(p2 != NULL); 110 p3 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_3, PBUF_POOL); 111 fail_unless(p3 != NULL); 112 err = pbuf_take(p1, testbuf_1, TESTBUFSIZE_1); 113 fail_unless(err == ERR_OK); 114 err = pbuf_take(p2, testbuf_2, TESTBUFSIZE_2); 115 fail_unless(err == ERR_OK); 116 err = pbuf_take(p3, testbuf_3, TESTBUFSIZE_3); 117 fail_unless(err == ERR_OK); 118 119 pbuf_cat(p1, p2); 120 pbuf_cat(p1, p3); 121 122 pbuf_split_64k(p1, &rest2); 123 fail_unless(p1->tot_len == TESTBUFSIZE_1); 124 fail_unless(rest2->tot_len == (u16_t)((TESTBUFSIZE_2+TESTBUFSIZE_3) & 0xFFFF)); 125 pbuf_split_64k(rest2, &rest3); 126 fail_unless(rest2->tot_len == TESTBUFSIZE_2); 127 fail_unless(rest3->tot_len == TESTBUFSIZE_3); 128 129 pbuf_copy_partial(p1, testbuf_1a, TESTBUFSIZE_1, 0); 130 pbuf_copy_partial(rest2, testbuf_2a, TESTBUFSIZE_2, 0); 131 pbuf_copy_partial(rest3, testbuf_3a, TESTBUFSIZE_3, 0); 132 for(i = 0; i < TESTBUFSIZE_1; i++) 133 fail_unless(testbuf_1[i] == testbuf_1a[i]); 134 for(i = 0; i < TESTBUFSIZE_2; i++) 135 fail_unless(testbuf_2[i] == testbuf_2a[i]); 136 for(i = 0; i < TESTBUFSIZE_3; i++) 137 fail_unless(testbuf_3[i] == testbuf_3a[i]); 138 139 pbuf_free(p1); 140 pbuf_free(rest2); 141 pbuf_free(rest3); 142 } 143 END_TEST 144 145 /* Test for bug that writing with pbuf_take_at() did nothing 146 * and returned ERR_OK when writing at beginning of a pbuf 147 * in the chain. 148 */ 149 START_TEST(test_pbuf_take_at_edge) 150 { 151 err_t res; 152 u8_t *out; 153 int i; 154 u8_t testdata[] = { 0x01, 0x08, 0x82, 0x02 }; 155 struct pbuf *p = pbuf_alloc(PBUF_RAW, 1024, PBUF_POOL); 156 struct pbuf *q = p->next; 157 LWIP_UNUSED_ARG(_i); 158 /* alloc big enough to get a chain of pbufs */ 159 fail_if(p->tot_len == p->len); 160 memset(p->payload, 0, p->len); 161 memset(q->payload, 0, q->len); 162 163 /* copy data to the beginning of first pbuf */ 164 res = pbuf_take_at(p, &testdata, sizeof(testdata), 0); 165 fail_unless(res == ERR_OK); 166 167 out = (u8_t*)p->payload; 168 for (i = 0; i < (int)sizeof(testdata); i++) { 169 fail_unless(out[i] == testdata[i], 170 "Bad data at pos %d, was %02X, expected %02X", i, out[i], testdata[i]); 171 } 172 173 /* copy data to the just before end of first pbuf */ 174 res = pbuf_take_at(p, &testdata, sizeof(testdata), p->len - 1); 175 fail_unless(res == ERR_OK); 176 177 out = (u8_t*)p->payload; 178 fail_unless(out[p->len - 1] == testdata[0], 179 "Bad data at pos %d, was %02X, expected %02X", p->len - 1, out[p->len - 1], testdata[0]); 180 out = (u8_t*)q->payload; 181 for (i = 1; i < (int)sizeof(testdata); i++) { 182 fail_unless(out[i-1] == testdata[i], 183 "Bad data at pos %d, was %02X, expected %02X", p->len - 1 + i, out[i-1], testdata[i]); 184 } 185 186 /* copy data to the beginning of second pbuf */ 187 res = pbuf_take_at(p, &testdata, sizeof(testdata), p->len); 188 fail_unless(res == ERR_OK); 189 190 out = (u8_t*)p->payload; 191 for (i = 0; i < (int)sizeof(testdata); i++) { 192 fail_unless(out[i] == testdata[i], 193 "Bad data at pos %d, was %02X, expected %02X", p->len+i, out[i], testdata[i]); 194 } 195 } 196 END_TEST 197 198 /* Verify pbuf_put_at()/pbuf_get_at() when using 199 * offsets equal to beginning of new pbuf in chain 200 */ 201 START_TEST(test_pbuf_get_put_at_edge) 202 { 203 u8_t *out; 204 u8_t testdata = 0x01; 205 u8_t getdata; 206 struct pbuf *p = pbuf_alloc(PBUF_RAW, 1024, PBUF_POOL); 207 struct pbuf *q = p->next; 208 LWIP_UNUSED_ARG(_i); 209 /* alloc big enough to get a chain of pbufs */ 210 fail_if(p->tot_len == p->len); 211 memset(p->payload, 0, p->len); 212 memset(q->payload, 0, q->len); 213 214 /* put byte at the beginning of second pbuf */ 215 pbuf_put_at(p, p->len, testdata); 216 217 out = (u8_t*)q->payload; 218 fail_unless(*out == testdata, 219 "Bad data at pos %d, was %02X, expected %02X", p->len, *out, testdata); 220 221 getdata = pbuf_get_at(p, p->len); 222 fail_unless(*out == getdata, 223 "pbuf_get_at() returned bad data at pos %d, was %02X, expected %02X", p->len, getdata, *out); 224 } 225 END_TEST 226 227 /** Create the suite including all tests for this module */ 228 Suite * 229 pbuf_suite(void) 230 { 231 testfunc tests[] = { 232 TESTFUNC(test_pbuf_copy_zero_pbuf), 233 TESTFUNC(test_pbuf_split_64k_on_small_pbufs), 234 TESTFUNC(test_pbuf_queueing_bigger_than_64k), 235 TESTFUNC(test_pbuf_take_at_edge), 236 TESTFUNC(test_pbuf_get_put_at_edge) 237 }; 238 return create_suite("PBUF", tests, sizeof(tests)/sizeof(testfunc), pbuf_setup, pbuf_teardown); 239 } 240