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