~ubuntu-branches/ubuntu/precise/libpgm/precise

« back to all changes in this revision

Viewing changes to openpgm/pgm/.svn/text-base/rxw_unittest.c.svn-base

  • Committer: Bazaar Package Importer
  • Author(s): Gabriel de Perthuis
  • Date: 2011-04-07 16:48:52 UTC
  • Revision ID: james.westby@ubuntu.com-20110407164852-8uamem42ojeptj6l
Tags: upstream-5.1.116~dfsg
ImportĀ upstreamĀ versionĀ 5.1.116~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* vim:ts=8:sts=8:sw=4:noai:noexpandtab
 
2
 *
 
3
 * unit tests for receive window.
 
4
 *
 
5
 * Copyright (c) 2009-2010 Miru Limited.
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 */
 
21
 
 
22
#include <signal.h>
 
23
#include <stdbool.h>
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <check.h>
 
27
#include <glib.h>
 
28
 
 
29
#ifdef _WIN32
 
30
#       define PGM_CHECK_NOFORK         1
 
31
#endif
 
32
 
 
33
 
 
34
/* mock global */
 
35
 
 
36
 
 
37
#define pgm_histogram_add               mock_pgm_histogram_add
 
38
#define pgm_time_now                    mock_pgm_time_now
 
39
#define pgm_rs_create                   mock_pgm_rs_create
 
40
#define pgm_rs_destroy                  mock_pgm_rs_destroy
 
41
#define pgm_rs_decode_parity_appended   mock_pgm_rs_decode_parity_appended
 
42
#define pgm_histogram_init              mock_pgm_histogram_init
 
43
 
 
44
#define RXW_DEBUG
 
45
#include "rxw.c"
 
46
 
 
47
#ifdef PGM_DISABLE_ASSERT
 
48
#       error "PGM_DISABLE_ASSERT set"
 
49
#endif
 
50
 
 
51
static pgm_time_t mock_pgm_time_now = 0x1;
 
52
 
 
53
 
 
54
/* mock functions for external references */
 
55
 
 
56
size_t
 
57
pgm_pkt_offset (
 
58
        const bool                      can_fragment,
 
59
        const sa_family_t               pgmcc_family    /* 0 = disable */
 
60
        )
 
61
{
 
62
        return 0;
 
63
}
 
64
 
 
65
PGM_GNUC_INTERNAL
 
66
int
 
67
pgm_get_nprocs (void)
 
68
{
 
69
        return 1;
 
70
}
 
71
 
 
72
/** reed-solomon module */
 
73
void
 
74
mock_pgm_rs_create (
 
75
        pgm_rs_t*               rs,
 
76
        uint8_t                 n,
 
77
        uint8_t                 k
 
78
        )
 
79
{
 
80
}
 
81
 
 
82
void
 
83
mock_pgm_rs_destroy (
 
84
        pgm_rs_t*               rs
 
85
        )
 
86
{
 
87
}
 
88
 
 
89
void
 
90
mock_pgm_rs_decode_parity_appended (
 
91
        pgm_rs_t*               rs,
 
92
        pgm_gf8_t**             block,
 
93
        const uint8_t*          offsets,
 
94
        uint16_t                len
 
95
        )
 
96
{
 
97
// null
 
98
}
 
99
 
 
100
void
 
101
mock_pgm_histogram_init (
 
102
        pgm_histogram_t*        histogram
 
103
        )
 
104
{
 
105
}
 
106
 
 
107
void
 
108
mock_pgm_histogram_add (
 
109
        pgm_histogram_t*        histogram,
 
110
        int                     value
 
111
        )
 
112
{
 
113
}
 
114
 
 
115
 
 
116
/* generate valid skb, data pointer pointing to PGM payload
 
117
 */
 
118
static
 
119
struct pgm_sk_buff_t*
 
120
generate_valid_skb (void)
 
121
{
 
122
        const pgm_tsi_t tsi = { { 200, 202, 203, 204, 205, 206 }, 2000 };
 
123
        const guint16 tsdu_length = 1000;
 
124
        const guint16 header_length = sizeof(struct pgm_header) + sizeof(struct pgm_data);
 
125
        struct pgm_sk_buff_t* skb = pgm_alloc_skb (1500);
 
126
        memcpy (&skb->tsi, &tsi, sizeof(tsi));
 
127
/* fake but valid socket and timestamp */
 
128
        skb->sock = (pgm_sock_t*)0x1;
 
129
        skb->tstamp = pgm_time_now;
 
130
/* header */
 
131
        pgm_skb_reserve (skb, header_length);
 
132
        memset (skb->head, 0, header_length);
 
133
        skb->pgm_header = (struct pgm_header*)skb->head;
 
134
        skb->pgm_data   = (struct pgm_data*)(skb->pgm_header + 1);
 
135
        skb->pgm_header->pgm_type = PGM_ODATA;
 
136
        skb->pgm_header->pgm_tsdu_length = g_htons (tsdu_length);
 
137
/* DATA */
 
138
        pgm_skb_put (skb, tsdu_length);
 
139
        return skb;
 
140
}
 
141
 
 
142
/* target:
 
143
 *      pgm_rxw_t*
 
144
 *      pgm_rxw_create (
 
145
 *              const pgm_tsi_t*        tsi,
 
146
 *              const uint16_t          tpdu_size,
 
147
 *              const unsigned          sqns,
 
148
 *              const unsigned          secs,
 
149
 *              const ssize_t           max_rte,
 
150
 *              const uint32_t          ack_c_p
 
151
 *              )
 
152
 */
 
153
 
 
154
/* vanilla sequence count window */
 
155
START_TEST (test_create_pass_001)
 
156
{
 
157
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
158
        const uint32_t ack_c_p = 500;
 
159
        fail_if (NULL == pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p), "create failed");
 
160
}
 
161
END_TEST
 
162
 
 
163
/* vanilla time based window */
 
164
START_TEST (test_create_pass_002)
 
165
{
 
166
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
167
        const uint32_t ack_c_p = 500;
 
168
        fail_if (NULL == pgm_rxw_create (&tsi, 1500, 0, 60, 800000, ack_c_p), "create failed");
 
169
}
 
170
END_TEST
 
171
 
 
172
/* jumbo frame */
 
173
START_TEST (test_create_pass_003)
 
174
{
 
175
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
176
        const uint32_t ack_c_p = 500;
 
177
        fail_if (NULL == pgm_rxw_create (&tsi, 9000, 0, 60, 800000, ack_c_p), "create failed");
 
178
}
 
179
END_TEST
 
180
 
 
181
/* max frame */
 
182
START_TEST (test_create_pass_004)
 
183
{
 
184
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
185
        const uint32_t ack_c_p = 500;
 
186
        fail_if (NULL == pgm_rxw_create (&tsi, UINT16_MAX, 0, 60, 800000, ack_c_p), "create failed");
 
187
}
 
188
END_TEST
 
189
 
 
190
/* invalid tsi pointer */
 
191
START_TEST (test_create_fail_001)
 
192
{
 
193
        const uint32_t ack_c_p = 500;
 
194
        pgm_rxw_t* window = pgm_rxw_create (NULL, 1500, 100, 0, 0, ack_c_p);
 
195
        fail ("reached");
 
196
}
 
197
END_TEST
 
198
 
 
199
/* invalid tpdu size */
 
200
START_TEST (test_create_fail_002)
 
201
{
 
202
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
203
        const uint32_t ack_c_p = 500;
 
204
        fail_if (NULL == pgm_rxw_create (&tsi, 0, 100, 0, 0, ack_c_p), "create failed");
 
205
}
 
206
END_TEST
 
207
 
 
208
START_TEST (test_create_fail_003)
 
209
{
 
210
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
211
        const uint32_t ack_c_p = 500;
 
212
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 0, 0, 60, 800000, ack_c_p);
 
213
        fail ("reached");
 
214
}
 
215
END_TEST
 
216
 
 
217
/* no specified sequence count or time value */
 
218
START_TEST (test_create_fail_004)
 
219
{
 
220
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
221
        const uint32_t ack_c_p = 500;
 
222
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 0, 0, 0, 800000, ack_c_p);
 
223
        fail ("reached");
 
224
}
 
225
END_TEST
 
226
 
 
227
/* no specified rate */
 
228
START_TEST (test_create_fail_005)
 
229
{
 
230
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
231
        const uint32_t ack_c_p = 500;
 
232
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 0, 0, 60, 0, ack_c_p);
 
233
        fail ("reached");
 
234
}
 
235
END_TEST
 
236
 
 
237
/* all invalid */
 
238
START_TEST (test_create_fail_006)
 
239
{
 
240
        pgm_rxw_t* window = pgm_rxw_create (NULL, 0, 0, 0, 0, 0);
 
241
        fail ("reached");
 
242
}
 
243
END_TEST
 
244
 
 
245
/* target:
 
246
 *      void
 
247
 *      pgm_rxw_destroy (
 
248
 *              pgm_rxw_t* const        window
 
249
 *              )
 
250
 */
 
251
 
 
252
START_TEST (test_destroy_pass_001)
 
253
{
 
254
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
255
        const uint32_t ack_c_p = 500;
 
256
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
257
        fail_if (NULL == window, "create failed");
 
258
        pgm_rxw_destroy (window);
 
259
}
 
260
END_TEST
 
261
 
 
262
START_TEST (test_destroy_fail_001)
 
263
{
 
264
        pgm_rxw_destroy (NULL);
 
265
        fail ("reached");
 
266
}
 
267
END_TEST
 
268
 
 
269
/* target:
 
270
 *      int
 
271
 *      pgm_rxw_add (
 
272
 *              pgm_rxw_t* const                window,
 
273
 *              struct pgm_sk_buff_t* const     skb,
 
274
 *              const pgm_time_t                now,
 
275
 *              const pgm_time_t                nak_rb_expiry
 
276
 *              )
 
277
 * failures raise assert errors and stop process execution.
 
278
 */
 
279
 
 
280
START_TEST (test_add_pass_001)
 
281
{
 
282
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
283
        const uint32_t ack_c_p = 500;
 
284
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
285
        fail_if (NULL == window, "create failed");
 
286
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
287
        fail_if (NULL == skb, "generate_valid_skb failed");
 
288
        skb->pgm_data->data_sqn = g_htonl (0);
 
289
        const pgm_time_t now = 1;
 
290
        const pgm_time_t nak_rb_expiry = 2;
 
291
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
292
        pgm_rxw_destroy (window);
 
293
}
 
294
END_TEST
 
295
 
 
296
/* missing + inserted */
 
297
START_TEST (test_add_pass_002)
 
298
{
 
299
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
300
        const uint32_t ack_c_p = 500;
 
301
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
302
        fail_if (NULL == window, "create failed");
 
303
/* #1 */
 
304
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
305
        fail_if (NULL == skb, "generate_valid_skb failed");
 
306
        skb->pgm_data->data_sqn = g_htonl (0);
 
307
        const pgm_time_t now = 1;
 
308
        const pgm_time_t nak_rb_expiry = 2;
 
309
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
310
/* #2 with jump */
 
311
        skb = generate_valid_skb ();
 
312
        fail_if (NULL == skb, "generate_valid_skb failed");
 
313
        skb->pgm_data->data_sqn = g_htonl (2);
 
314
        fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not missing");
 
315
/* #3 to fill in gap */
 
316
        skb = generate_valid_skb ();
 
317
        fail_if (NULL == skb, "generate_valid_skb failed");
 
318
        skb->pgm_data->data_sqn = g_htonl (1);
 
319
        fail_unless (PGM_RXW_INSERTED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not inserted");
 
320
        pgm_rxw_destroy (window);
 
321
}
 
322
END_TEST
 
323
 
 
324
/* duplicate + append */
 
325
START_TEST (test_add_pass_003)
 
326
{
 
327
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
328
        const uint32_t ack_c_p = 500;
 
329
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
330
        fail_if (NULL == window, "create failed");
 
331
/* #1 */
 
332
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
333
        fail_if (NULL == skb, "generate_valid_skb failed");
 
334
        skb->pgm_data->data_sqn = g_htonl (0);
 
335
        const pgm_time_t now = 1;
 
336
        const pgm_time_t nak_rb_expiry = 2;
 
337
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
338
/* #2 repeat sequence  */
 
339
        skb = generate_valid_skb ();
 
340
        fail_if (NULL == skb, "generate_valid_skb failed");
 
341
        skb->pgm_data->data_sqn = g_htonl (0);
 
342
        fail_unless (PGM_RXW_DUPLICATE == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not duplicate");
 
343
/* #3 append */
 
344
        skb = generate_valid_skb ();
 
345
        fail_if (NULL == skb, "generate_valid_skb failed");
 
346
        skb->pgm_data->data_sqn = g_htonl (1);
 
347
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
348
        pgm_rxw_destroy (window);
 
349
}
 
350
END_TEST
 
351
 
 
352
/* malformed: tpdu too long */
 
353
START_TEST (test_add_pass_004)
 
354
{
 
355
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
356
        const uint32_t ack_c_p = 500;
 
357
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
358
        fail_if (NULL == window, "create failed");
 
359
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
360
        fail_if (NULL == skb, "generate_valid_skb failed"); 
 
361
        skb->pgm_header->pgm_tsdu_length = g_htons (65535);
 
362
        skb->pgm_data->data_sqn = g_htonl (0);
 
363
        const pgm_time_t now = 1;
 
364
        const pgm_time_t nak_rb_expiry = 2;
 
365
        fail_unless (PGM_RXW_MALFORMED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not malformed");
 
366
}
 
367
END_TEST
 
368
 
 
369
/* bounds + append */
 
370
START_TEST (test_add_pass_005)
 
371
{
 
372
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
373
        const uint32_t ack_c_p = 500;
 
374
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
375
        fail_if (NULL == window, "create failed");
 
376
/* #1 */
 
377
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
378
        fail_if (NULL == skb, "generate_valid_skb failed"); 
 
379
        skb->pgm_data->data_sqn = g_htonl (0);
 
380
        skb->pgm_data->data_trail = g_htonl (-10);
 
381
        const pgm_time_t now = 1;
 
382
        const pgm_time_t nak_rb_expiry = 2;
 
383
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
384
/* #2 jump backwards  */
 
385
        skb = generate_valid_skb ();
 
386
        fail_if (NULL == skb, "generate_valid_skb failed");
 
387
        skb->pgm_data->data_sqn = g_htonl (-1);
 
388
        skb->pgm_data->data_trail = g_htonl (-10);
 
389
        fail_unless (PGM_RXW_BOUNDS == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not bounds");
 
390
/* #3 append */
 
391
        skb = generate_valid_skb ();
 
392
        fail_if (NULL == skb, "generate_valid_skb failed");
 
393
        skb->pgm_data->data_sqn = g_htonl (1);
 
394
        skb->pgm_data->data_trail = g_htonl (-10);
 
395
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
396
/* #4 jump forward */
 
397
        skb = generate_valid_skb ();
 
398
        fail_if (NULL == skb, "generate_valid_skb failed");
 
399
        skb->pgm_data->data_sqn = g_htonl (100 + (UINT32_MAX / 2));
 
400
        skb->pgm_data->data_trail = g_htonl (UINT32_MAX / 2);
 
401
        fail_unless (PGM_RXW_BOUNDS == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not bounds");
 
402
/* #5 append */
 
403
        skb = generate_valid_skb ();
 
404
        fail_if (NULL == skb, "generate_valid_skb failed");
 
405
        skb->pgm_data->data_sqn = g_htonl (2);
 
406
        skb->pgm_data->data_trail = g_htonl (-10);
 
407
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
408
        pgm_rxw_destroy (window);
 
409
}
 
410
END_TEST
 
411
 
 
412
/* null skb */
 
413
START_TEST (test_add_fail_001)
 
414
{
 
415
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
416
        const uint32_t ack_c_p = 500;
 
417
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
418
        fail_if (NULL == window, "create failed");
 
419
        const pgm_time_t now = 1;
 
420
        const pgm_time_t nak_rb_expiry = 2;
 
421
        int retval = pgm_rxw_add (window, NULL, now, nak_rb_expiry);
 
422
        fail ("reached");
 
423
}
 
424
END_TEST
 
425
 
 
426
/* null window */
 
427
START_TEST (test_add_fail_002)
 
428
{
 
429
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
430
        fail_if (NULL == skb, "generate_valid_skb failed");
 
431
        skb->pgm_data->data_sqn = g_htonl (0);
 
432
        const pgm_time_t now = 1;
 
433
        const pgm_time_t nak_rb_expiry = 2;
 
434
        int retval = pgm_rxw_add (NULL, skb, now, nak_rb_expiry);
 
435
        fail ("reached");
 
436
}
 
437
END_TEST
 
438
 
 
439
/* null skb content */
 
440
START_TEST (test_add_fail_003)
 
441
{
 
442
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
443
        const uint32_t ack_c_p = 500;
 
444
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
445
        fail_if (NULL == window, "create failed");
 
446
        char buffer[1500];
 
447
        memset (buffer, 0, sizeof(buffer));
 
448
        const pgm_time_t now = 1;
 
449
        const pgm_time_t nak_rb_expiry = 2;
 
450
        int retval = pgm_rxw_add (window, (struct pgm_sk_buff_t*)buffer, now, nak_rb_expiry);
 
451
        fail ("reached");
 
452
}
 
453
END_TEST
 
454
 
 
455
/* 0 nak_rb_expiry */
 
456
START_TEST (test_add_fail_004)
 
457
{
 
458
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
459
        const uint32_t ack_c_p = 500;
 
460
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
461
        fail_if (NULL == window, "create failed");
 
462
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
463
        fail_if (NULL == skb, "generate_valid_skb failed");
 
464
        skb->pgm_data->data_sqn = g_htonl (0);
 
465
        const pgm_time_t now = 1;
 
466
        int retval = pgm_rxw_add (window, skb, now, 0);
 
467
        fail ("reached");
 
468
}
 
469
END_TEST
 
470
 
 
471
/* target:
 
472
 *      struct pgm_sk_buff_t*
 
473
 *      pgm_rxw_peek (
 
474
 *              pgm_rxw_t* const        window,
 
475
 *              const uint32_t          sequence
 
476
 *              )
 
477
 */
 
478
 
 
479
START_TEST (test_peek_pass_001)
 
480
{
 
481
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
482
        const uint32_t ack_c_p = 500;
 
483
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
484
        fail_if (NULL == window, "create failed");
 
485
        fail_unless (NULL == pgm_rxw_peek (window, 0), "peek failed");
 
486
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
487
        fail_if (NULL == skb, "generate_valid_skb failed");
 
488
        skb->pgm_data->data_sqn = g_htonl (0);
 
489
        const pgm_time_t now = 1;
 
490
        const pgm_time_t nak_rb_expiry = 2;
 
491
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
492
        fail_unless (skb == pgm_rxw_peek (window, 0), "peek failed");
 
493
        fail_unless (NULL == pgm_rxw_peek (window, 1), "peek failed");
 
494
        fail_unless (NULL == pgm_rxw_peek (window, -1), "peek failed");
 
495
        pgm_rxw_destroy (window);
 
496
}
 
497
END_TEST
 
498
 
 
499
/* null window */
 
500
START_TEST (test_peek_fail_001)
 
501
{
 
502
        struct pgm_sk_buff_t* skb = pgm_rxw_peek (NULL, 0);
 
503
        fail ("reached");
 
504
}
 
505
END_TEST
 
506
 
 
507
/** inline function tests **/
 
508
/* pgm_rxw_max_length () 
 
509
 */
 
510
START_TEST (test_max_length_pass_001)
 
511
{
 
512
        const guint window_length = 100;
 
513
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
514
        const uint32_t ack_c_p = 500;
 
515
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, window_length, 0, 0, ack_c_p);
 
516
        fail_if (NULL == window, "create failed");
 
517
        fail_unless (window_length == pgm_rxw_max_length (window), "max_length failed");
 
518
        pgm_rxw_destroy (window);
 
519
}
 
520
END_TEST
 
521
 
 
522
START_TEST (test_max_length_fail_001)
 
523
{
 
524
        const unsigned len = pgm_rxw_max_length (NULL);
 
525
        fail ("reached");
 
526
}
 
527
END_TEST
 
528
 
 
529
/* pgm_rxw_length () 
 
530
 */
 
531
START_TEST (test_length_pass_001)
 
532
{
 
533
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
534
        const uint32_t ack_c_p = 500;
 
535
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
536
        fail_if (NULL == window, "create failed");
 
537
        fail_unless (0 == pgm_rxw_length (window), "length failed");
 
538
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
539
        fail_if (NULL == skb, "generate_valid_skb failed");
 
540
        skb->pgm_data->data_sqn = g_htonl (0);
 
541
        const pgm_time_t now = 1;
 
542
        const pgm_time_t nak_rb_expiry = 2;
 
543
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
544
        fail_unless (1 == pgm_rxw_length (window), "length failed");
 
545
/* #2 */
 
546
        skb = generate_valid_skb ();
 
547
        fail_if (NULL == skb, "generate_valid_skb failed");
 
548
        skb->pgm_data->data_sqn = g_htonl (1);
 
549
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
550
        fail_unless (2 == pgm_rxw_length (window), "length failed");
 
551
        pgm_rxw_destroy (window);
 
552
}
 
553
END_TEST
 
554
 
 
555
START_TEST (test_length_fail_001)
 
556
{
 
557
        const uint32_t answer = pgm_rxw_length (NULL);
 
558
        fail ("reached");
 
559
}
 
560
END_TEST
 
561
 
 
562
/* pgm_rxw_size () 
 
563
 */
 
564
START_TEST (test_size_pass_001)
 
565
{
 
566
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
567
        const uint32_t ack_c_p = 500;
 
568
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
569
        fail_if (NULL == window, "create failed");
 
570
        fail_unless (0 == pgm_rxw_size (window), "size failed");
 
571
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
572
        fail_if (NULL == skb, "generate_valid_skb failed");
 
573
        skb->pgm_data->data_sqn = g_htonl (0);
 
574
        const pgm_time_t now = 1;
 
575
        const pgm_time_t nak_rb_expiry = 2;
 
576
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
577
        fail_unless (1000 == pgm_rxw_size (window), "size failed");
 
578
/* #2 */
 
579
        skb = generate_valid_skb ();
 
580
        fail_if (NULL == skb, "generate_valid_skb failed");
 
581
        skb->pgm_data->data_sqn = g_htonl (1);
 
582
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
583
        fail_unless (2000 == pgm_rxw_size (window), "size failed");
 
584
        pgm_rxw_destroy (window);
 
585
}
 
586
END_TEST
 
587
 
 
588
START_TEST (test_size_fail_001)
 
589
{
 
590
        const size_t answer = pgm_rxw_size (NULL);
 
591
        fail ("reached");
 
592
}
 
593
END_TEST
 
594
 
 
595
/* pgm_rxw_is_empty
 
596
 */
 
597
START_TEST (test_is_empty_pass_001)
 
598
{
 
599
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
600
        const uint32_t ack_c_p = 500;
 
601
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
602
        fail_if (NULL == window, "create failed");
 
603
        fail_unless (pgm_rxw_is_empty (window), "is_empty failed");
 
604
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
605
        fail_if (NULL == skb, "generate_valid_skb failed");
 
606
        skb->pgm_data->data_sqn = g_htonl (0);
 
607
        const pgm_time_t now = 1;
 
608
        const pgm_time_t nak_rb_expiry = 2;
 
609
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
610
        fail_if (pgm_rxw_is_empty (window), "is_empty failed");
 
611
        pgm_rxw_destroy (window);
 
612
}
 
613
END_TEST
 
614
 
 
615
START_TEST (test_is_empty_fail_001)
 
616
{
 
617
        const bool answer = pgm_rxw_is_empty (NULL);
 
618
        fail ("reached");
 
619
}
 
620
END_TEST
 
621
 
 
622
/* pgm_rxw_is_full
 
623
 */
 
624
START_TEST (test_is_full_pass_001)
 
625
{
 
626
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
627
        const uint32_t ack_c_p = 500;
 
628
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 1, 0, 0, ack_c_p);
 
629
        fail_if (NULL == window, "create failed");
 
630
        fail_if (pgm_rxw_is_full (window), "is_full failed");
 
631
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
632
        fail_if (NULL == skb, "generate_valid_skb failed");
 
633
        skb->pgm_data->data_sqn = g_htonl (0);
 
634
        const pgm_time_t now = 1;
 
635
        const pgm_time_t nak_rb_expiry = 2;
 
636
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
637
        fail_unless (pgm_rxw_is_full (window), "is_full failed");
 
638
        pgm_rxw_destroy (window);
 
639
}
 
640
END_TEST
 
641
 
 
642
START_TEST (test_is_full_fail_001)
 
643
{
 
644
        const bool answer = pgm_rxw_is_full (NULL);
 
645
        fail ("reached");
 
646
}
 
647
END_TEST
 
648
 
 
649
/* pgm_rxw_lead
 
650
 */
 
651
START_TEST (test_lead_pass_001)
 
652
{
 
653
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
654
        const uint32_t ack_c_p = 500;
 
655
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
656
        fail_if (NULL == window, "create failed");
 
657
        guint32 lead = pgm_rxw_lead (window);
 
658
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
659
        fail_if (NULL == skb, "generate_valid_skb failed");
 
660
        skb->pgm_data->data_sqn = g_htonl (0);
 
661
        const pgm_time_t now = 1;
 
662
        const pgm_time_t nak_rb_expiry = 2;
 
663
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
664
        fail_unless (lead + 1 == pgm_rxw_lead (window), "lead failed");
 
665
        pgm_rxw_destroy (window);
 
666
}
 
667
END_TEST
 
668
 
 
669
START_TEST (test_lead_fail_001)
 
670
{
 
671
        const uint32_t answer = pgm_rxw_lead (NULL);
 
672
        fail ("reached");
 
673
}
 
674
END_TEST
 
675
 
 
676
/* pgm_rxw_next_lead
 
677
 */
 
678
START_TEST (test_next_lead_pass_001)
 
679
{
 
680
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
681
        const uint32_t ack_c_p = 500;
 
682
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
683
        fail_if (NULL == window, "create failed");
 
684
        guint32 next_lead = pgm_rxw_next_lead (window);
 
685
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
686
        fail_if (NULL == skb, "generate_valid_skb failed");
 
687
        skb->pgm_data->data_sqn = g_htonl (0);
 
688
        const pgm_time_t now = 1;
 
689
        const pgm_time_t nak_rb_expiry = 2;
 
690
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
691
        fail_unless (next_lead == pgm_rxw_lead (window), "lead failed");
 
692
        pgm_rxw_destroy (window);
 
693
}
 
694
END_TEST
 
695
 
 
696
START_TEST (test_next_lead_fail_001)
 
697
{
 
698
        const uint32_t answer = pgm_rxw_next_lead (NULL);
 
699
        fail ("reached");
 
700
}
 
701
END_TEST
 
702
 
 
703
/* target:
 
704
 *      ssize_t
 
705
 *      pgm_rxw_readv (
 
706
 *              pgm_rxw_t* const        window,
 
707
 *              struct pgm_msgv_t**     pmsg,
 
708
 *              const unsigned          msg_len
 
709
 *              )
 
710
 */
 
711
 
 
712
START_TEST (test_readv_pass_001)
 
713
{
 
714
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
715
        const uint32_t ack_c_p = 500;
 
716
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
717
        fail_if (NULL == window, "create failed");
 
718
        struct pgm_msgv_t msgv[2], *pmsg;
 
719
/* #1 empty */
 
720
        pmsg = msgv;
 
721
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
722
/* #2 single TPDU-APDU */
 
723
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
724
        fail_if (NULL == skb, "generate_valid_skb failed");
 
725
        skb->pgm_data->data_sqn = g_htonl (0);
 
726
        const pgm_time_t now = 1;
 
727
        const pgm_time_t nak_rb_expiry = 2;
 
728
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
729
        pmsg = msgv;
 
730
        fail_unless (1000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
731
        pmsg = msgv;
 
732
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
733
/* #3,4 two APDUs */
 
734
        skb = generate_valid_skb ();
 
735
        fail_if (NULL == skb, "generate_valid_skb failed");
 
736
        skb->pgm_data->data_sqn = g_htonl (1);
 
737
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
738
        skb = generate_valid_skb ();
 
739
        fail_if (NULL == skb, "generate_valid_skb failed");
 
740
        skb->pgm_data->data_sqn = g_htonl (2);
 
741
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
742
        pmsg = msgv;
 
743
        fail_unless (2000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
744
/* #5,6 skip and repair APDU */
 
745
        pmsg = msgv;
 
746
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
747
        skb = generate_valid_skb ();
 
748
        fail_if (NULL == skb, "generate_valid_skb failed");
 
749
        skb->pgm_data->data_sqn = g_htonl (4);
 
750
        fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not missing");
 
751
        pmsg = msgv;
 
752
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
753
        skb = generate_valid_skb ();
 
754
        fail_if (NULL == skb, "generate_valid_skb failed");
 
755
        skb->pgm_data->data_sqn = g_htonl (3);
 
756
        fail_unless (PGM_RXW_INSERTED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not inserted");
 
757
        pmsg = msgv;
 
758
        fail_unless (2000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
759
        pmsg = msgv;
 
760
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
761
        pgm_rxw_destroy (window);
 
762
}
 
763
END_TEST
 
764
 
 
765
/* zero-length */
 
766
START_TEST (test_readv_pass_002)
 
767
{
 
768
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
769
        const uint32_t ack_c_p = 500;
 
770
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
771
        fail_if (NULL == window, "create failed");
 
772
        struct pgm_msgv_t msgv[2], *pmsg;
 
773
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
774
        fail_if (NULL == skb, "generate_valid_skb failed");
 
775
        skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
776
        skb->tail = (guint8*)skb->tail - skb->len;
 
777
        skb->len = 0;
 
778
        skb->pgm_data->data_sqn = g_htonl (0);
 
779
        const pgm_time_t now = 1;
 
780
        const pgm_time_t nak_rb_expiry = 2;
 
781
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
782
        pmsg = msgv;
 
783
        fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
784
        pmsg = msgv;
 
785
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
786
        pgm_rxw_destroy (window);
 
787
}
 
788
END_TEST
 
789
 
 
790
/* full window */
 
791
START_TEST (test_readv_pass_003)
 
792
{
 
793
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
794
        const uint32_t ack_c_p = 500;
 
795
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
796
        fail_if (NULL == window, "create failed");
 
797
        struct pgm_msgv_t msgv[1], *pmsg;
 
798
        struct pgm_sk_buff_t* skb;
 
799
        for (unsigned i = 0; i < 100; i++)
 
800
        {
 
801
                skb = generate_valid_skb ();
 
802
                fail_if (NULL == skb, "generate_valid_skb failed");
 
803
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
804
                skb->tail = (guint8*)skb->tail - skb->len;
 
805
                skb->len = 0;
 
806
                skb->pgm_data->data_sqn = g_htonl (i);
 
807
                const pgm_time_t now = 1;
 
808
                const pgm_time_t nak_rb_expiry = 2;
 
809
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
810
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
811
        }
 
812
        fail_unless (pgm_rxw_is_full (window), "is_full failed");
 
813
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
814
        for (unsigned i = 0; i < 100; i++)
 
815
        {
 
816
                pmsg = msgv;
 
817
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
818
                fail_unless ((1 + i) == _pgm_rxw_commit_length (window), "commit_length failed");
 
819
        }
 
820
        fail_unless (pgm_rxw_length (window) == _pgm_rxw_commit_length (window), "commit_length failed");
 
821
        pmsg = msgv;
 
822
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
823
        pgm_rxw_destroy (window);
 
824
}
 
825
END_TEST
 
826
 
 
827
/* full + 1 window */
 
828
START_TEST (test_readv_pass_004)
 
829
{
 
830
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
831
        const uint32_t ack_c_p = 500;
 
832
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
833
        fail_if (NULL == window, "create failed");
 
834
        struct pgm_msgv_t msgv[1], *pmsg;
 
835
        struct pgm_sk_buff_t* skb;
 
836
        for (unsigned i = 0; i < 101; i++)
 
837
        {
 
838
                skb = generate_valid_skb ();
 
839
                fail_if (NULL == skb, "generate_valid_skb failed");
 
840
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
841
                skb->tail = (guint8*)skb->tail - skb->len;
 
842
                skb->len = 0;
 
843
                skb->pgm_data->data_sqn = g_htonl (i);
 
844
                const pgm_time_t now = 1;
 
845
                const pgm_time_t nak_rb_expiry = 2;
 
846
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
847
                fail_unless (MIN(100, 1 + i) == pgm_rxw_length (window), "length failed");
 
848
        }
 
849
        fail_unless (pgm_rxw_is_full (window), "is_full failed");
 
850
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
851
        for (unsigned i = 0; i < 100; i++)
 
852
        {
 
853
                pmsg = msgv;
 
854
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
855
                fail_unless ((1 + i) == _pgm_rxw_commit_length (window), "commit_length failed");
 
856
        }
 
857
        fail_unless (pgm_rxw_length (window) == _pgm_rxw_commit_length (window), "commit_length failed");
 
858
        pmsg = msgv;
 
859
        fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
860
        pgm_rxw_destroy (window);
 
861
}
 
862
END_TEST
 
863
 
 
864
/* full - 2 lost last in window */
 
865
START_TEST (test_readv_pass_005)
 
866
{
 
867
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
868
        const uint32_t ack_c_p = 500;
 
869
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
870
        fail_if (NULL == window, "create failed");
 
871
        struct pgm_msgv_t msgv[1], *pmsg;
 
872
        struct pgm_sk_buff_t* skb;
 
873
        for (unsigned i = 0; i < 98; i++)
 
874
        {
 
875
                skb = generate_valid_skb ();
 
876
                fail_if (NULL == skb, "generate_valid_skb failed");
 
877
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
878
                skb->tail = (guint8*)skb->tail - skb->len;
 
879
                skb->len = 0;
 
880
                skb->pgm_data->data_sqn = g_htonl (i);
 
881
                const pgm_time_t now = 1;
 
882
                const pgm_time_t nak_rb_expiry = 2;
 
883
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
884
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
885
        }
 
886
        fail_if (pgm_rxw_is_full (window), "is_full failed");
 
887
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
888
        {
 
889
                unsigned i = 99;
 
890
                skb = generate_valid_skb ();
 
891
                fail_if (NULL == skb, "generate_valid_skb failed");
 
892
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
893
                skb->tail = (guint8*)skb->tail - skb->len;
 
894
                skb->len = 0;
 
895
                skb->pgm_data->data_sqn = g_htonl (i);
 
896
                const pgm_time_t now = 1;
 
897
                const pgm_time_t nak_rb_expiry = 2;
 
898
                fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not missing");
 
899
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
900
        }
 
901
        fail_unless (pgm_rxw_is_full (window), "is_full failed");
 
902
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
903
        for (unsigned i = 0; i < 98; i++)
 
904
        {
 
905
                pmsg = msgv;
 
906
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
907
                fail_unless ((1 + i) == _pgm_rxw_commit_length (window), "commit_length failed");
 
908
        }
 
909
        fail_unless (pgm_rxw_length (window) == (2 + _pgm_rxw_commit_length (window)), "commit_length failed");
 
910
/* read end-of-window */
 
911
        {
 
912
                pmsg = msgv;
 
913
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
914
        }
 
915
        pgm_rxw_destroy (window);
 
916
}
 
917
END_TEST
 
918
 
 
919
/* add full window, readv 1 skb, add 1 more */
 
920
START_TEST (test_readv_pass_006)
 
921
{
 
922
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
923
        const uint32_t ack_c_p = 500;
 
924
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
925
        fail_if (NULL == window, "create failed");
 
926
        struct pgm_msgv_t msgv[1], *pmsg;
 
927
        struct pgm_sk_buff_t* skb;
 
928
        for (unsigned i = 0; i < 100; i++)
 
929
        {
 
930
                skb = generate_valid_skb ();
 
931
                fail_if (NULL == skb, "generate_valid_skb failed");
 
932
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
933
                skb->tail = (guint8*)skb->tail - skb->len;
 
934
                skb->len = 0;
 
935
                skb->pgm_data->data_sqn = g_htonl (i);
 
936
                const pgm_time_t now = 1;
 
937
                const pgm_time_t nak_rb_expiry = 2;
 
938
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
939
                fail_unless (MIN(100, 1 + i) == pgm_rxw_length (window), "length failed");
 
940
        }
 
941
        fail_unless (pgm_rxw_is_full (window), "is_full failed");
 
942
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
943
/* read one skb */
 
944
        {
 
945
                pmsg = msgv;
 
946
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
947
                fail_unless (1 == _pgm_rxw_commit_length (window), "commit_length failed");
 
948
        }
 
949
/* add one more new skb */
 
950
        {
 
951
                unsigned i = 100;
 
952
                skb = generate_valid_skb ();
 
953
                fail_if (NULL == skb, "generate_valid_skb failed");
 
954
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
955
                skb->tail = (guint8*)skb->tail - skb->len;
 
956
                skb->len = 0;
 
957
                skb->pgm_data->data_sqn = g_htonl (i);
 
958
                const pgm_time_t now = 1;
 
959
                const pgm_time_t nak_rb_expiry = 2;
 
960
                fail_unless (PGM_RXW_BOUNDS == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not bounds");
 
961
                fail_unless (MIN(100, 1 + i) == pgm_rxw_length (window), "length failed");
 
962
        }
 
963
/* read off 99 more skbs */
 
964
        for (unsigned i = 0; i < 99; i++)
 
965
        {
 
966
                pmsg = msgv;
 
967
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
968
                fail_unless ((2 + i) == _pgm_rxw_commit_length (window), "commit_length failed");
 
969
        }
 
970
/* read end-of-window */
 
971
        {
 
972
                pmsg = msgv;
 
973
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
974
        }
 
975
        pgm_rxw_destroy (window);
 
976
}
 
977
END_TEST
 
978
 
 
979
/* NULL window */
 
980
START_TEST (test_readv_fail_001)
 
981
{
 
982
        struct pgm_msgv_t msgv[1], *pmsg = msgv;
 
983
        gssize len = pgm_rxw_readv (NULL, &pmsg, G_N_ELEMENTS(msgv));
 
984
        fail ("reached");
 
985
}
 
986
END_TEST
 
987
 
 
988
/* NULL pmsg */
 
989
START_TEST (test_readv_fail_002)
 
990
{
 
991
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
992
        const uint32_t ack_c_p = 500;
 
993
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
994
        fail_if (NULL == window, "create failed");
 
995
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
996
        fail_if (NULL == skb, "generate_valid_skb failed");
 
997
        skb->pgm_data->data_sqn = g_htonl (0);
 
998
        const pgm_time_t now = 1;
 
999
        const pgm_time_t nak_rb_expiry = 2;
 
1000
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1001
        struct pgm_msgv_t msgv[1], *pmsg = msgv;
 
1002
        gssize len = pgm_rxw_readv (window, NULL, G_N_ELEMENTS(msgv));
 
1003
        fail ("reached");
 
1004
}
 
1005
END_TEST
 
1006
 
 
1007
/* 0 msg-len */
 
1008
START_TEST (test_readv_fail_003)
 
1009
{
 
1010
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1011
        const uint32_t ack_c_p = 500;
 
1012
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1013
        fail_if (NULL == window, "create failed");
 
1014
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1015
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1016
        skb->pgm_data->data_sqn = g_htonl (0);
 
1017
        const pgm_time_t now = 1;
 
1018
        const pgm_time_t nak_rb_expiry = 2;
 
1019
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1020
        struct pgm_msgv_t msgv[1], *pmsg = msgv;
 
1021
        gssize len = pgm_rxw_readv (window, &pmsg, 0);
 
1022
        fail ("reached");
 
1023
}
 
1024
END_TEST
 
1025
 
 
1026
/* target:
 
1027
 *
 
1028
 *      void
 
1029
 *      pgm_rxw_remove_commit (
 
1030
 *              pgm_rxw_t* const        window
 
1031
 *              )
 
1032
 */
 
1033
 
 
1034
/* full - 2 lost last in window */
 
1035
START_TEST (test_remove_commit_pass_001)
 
1036
{
 
1037
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1038
        const uint32_t ack_c_p = 500;
 
1039
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1040
        fail_if (NULL == window, "create failed");
 
1041
        struct pgm_msgv_t msgv[1], *pmsg;
 
1042
        struct pgm_sk_buff_t* skb;
 
1043
        for (unsigned i = 0; i < 98; i++)
 
1044
        {
 
1045
                skb = generate_valid_skb ();
 
1046
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1047
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1048
                skb->tail = (guint8*)skb->tail - skb->len;
 
1049
                skb->len = 0;
 
1050
                skb->pgm_data->data_sqn = g_htonl (i);
 
1051
                const pgm_time_t now = 1;
 
1052
                const pgm_time_t nak_rb_expiry = 2;
 
1053
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1054
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
1055
        }
 
1056
        fail_if (pgm_rxw_is_full (window), "is_full failed");
 
1057
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
1058
/* #98 is missing */
 
1059
        {
 
1060
                unsigned i = 99;
 
1061
                skb = generate_valid_skb ();
 
1062
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1063
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1064
                skb->tail = (guint8*)skb->tail - skb->len;
 
1065
                skb->len = 0;
 
1066
                skb->pgm_data->data_sqn = g_htonl (i);
 
1067
                const pgm_time_t now = 1;
 
1068
                const pgm_time_t nak_rb_expiry = 2;
 
1069
                fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1070
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
1071
        }
 
1072
        fail_unless (pgm_rxw_is_full (window), "is_full failed");
 
1073
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty");
 
1074
/* now mark #98 lost */
 
1075
        pgm_rxw_lost (window, 98);
 
1076
        for (unsigned i = 0; i < 98; i++)
 
1077
        {
 
1078
                pmsg = msgv;
 
1079
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1080
                fail_unless ((1 + i) == _pgm_rxw_commit_length (window), "commit_length failed");
 
1081
        }
 
1082
        fail_unless (100 == pgm_rxw_length (window), "length failed");
 
1083
        fail_unless ( 98 == _pgm_rxw_commit_length (window), "commit_length failed");
 
1084
/* read end-of-window */
 
1085
        {
 
1086
                pmsg = msgv;
 
1087
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1088
        }
 
1089
        fail_unless (100 == pgm_rxw_length (window), "length failed");
 
1090
        fail_unless ( 98 == _pgm_rxw_commit_length (window), "commit_length failed");
 
1091
        pgm_rxw_remove_commit (window);
 
1092
/* read lost skb #98 */
 
1093
        {
 
1094
                pmsg = msgv;
 
1095
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1096
        }
 
1097
        pgm_rxw_remove_commit (window);
 
1098
/* read valid skb #99 */
 
1099
        {
 
1100
                pmsg = msgv;
 
1101
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1102
        }
 
1103
/* read end-of-window */
 
1104
        {
 
1105
                pmsg = msgv;
 
1106
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1107
        }
 
1108
        pgm_rxw_destroy (window);
 
1109
}
 
1110
END_TEST
 
1111
 
 
1112
START_TEST (test_remove_commit_fail_001)
 
1113
{
 
1114
        pgm_rxw_remove_commit (NULL);
 
1115
        fail ("reached");
 
1116
}
 
1117
END_TEST
 
1118
 
 
1119
/* target:
 
1120
 *      unsigned
 
1121
 *      pgm_rxw_remove_trail (
 
1122
 *              pgm_rxw_t* const        window
 
1123
 *              )
 
1124
 */
 
1125
 
 
1126
START_TEST (test_remove_trail_pass_001)
 
1127
{
 
1128
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1129
        const uint32_t ack_c_p = 500;
 
1130
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1131
        fail_if (NULL == window, "create failed");
 
1132
        struct pgm_msgv_t msgv[2], *pmsg;
 
1133
        fail_unless (0 == pgm_rxw_remove_trail (window), "remove_trail failed");
 
1134
/* #1,2 two APDUs */
 
1135
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1136
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1137
        skb->pgm_data->data_sqn = g_htonl (1);
 
1138
        const pgm_time_t now = 1;
 
1139
        const pgm_time_t nak_rb_expiry = 2;
 
1140
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1141
        skb = generate_valid_skb ();
 
1142
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1143
        skb->pgm_data->data_sqn = g_htonl (2);
 
1144
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1145
        fail_unless (1 == pgm_rxw_remove_trail (window), "remove_trail failed");
 
1146
        fail_unless (1 == pgm_rxw_length (window), "length failed");
 
1147
        fail_unless (1000 == pgm_rxw_size (window), "size failed");
 
1148
        pmsg = msgv;
 
1149
        fail_unless (1000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1150
        fail_unless (0 == pgm_rxw_remove_trail (window), "remove_trail failed");
 
1151
        pgm_rxw_destroy (window);
 
1152
}
 
1153
END_TEST
 
1154
 
 
1155
START_TEST (test_remove_trail_fail_001)
 
1156
{
 
1157
        guint count = pgm_rxw_remove_trail (NULL);
 
1158
        fail ("reached");
 
1159
}
 
1160
END_TEST
 
1161
 
 
1162
/* target:
 
1163
 *      unsigned
 
1164
 *      pgm_rxw_update (
 
1165
 *              pgm_rxw_t* const        window,
 
1166
 *              const uint32_t          txw_trail,
 
1167
 *              const uint32_t          txw_lead,
 
1168
 *              const pgm_time_t        now,
 
1169
 *              const pgm_time_t        nak_rb_expiry
 
1170
 *              )
 
1171
 */
 
1172
 
 
1173
START_TEST (test_update_pass_001)
 
1174
{
 
1175
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1176
        const uint32_t ack_c_p = 500;
 
1177
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1178
        fail_if (NULL == window, "create failed");
 
1179
        const pgm_time_t now = 1;
 
1180
        const pgm_time_t nak_rb_expiry = 2;
 
1181
        fail_unless (0 == pgm_rxw_update (window, 100, 99, now, nak_rb_expiry), "update failed");
 
1182
/* dupe */
 
1183
        fail_unless (0 == pgm_rxw_update (window, 100, 99, now, nak_rb_expiry), "update failed");
 
1184
/* #1 at 100 */
 
1185
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1186
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1187
        skb->pgm_data->data_sqn = g_htonl (100);
 
1188
        fail_unless (PGM_RXW_BOUNDS == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not bounds");
 
1189
/* #2 at 101 */
 
1190
        skb->pgm_data->data_sqn = g_htonl (101);
 
1191
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1192
        struct pgm_msgv_t msgv[1], *pmsg = msgv;
 
1193
        fail_unless (1000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1194
/* #3 at 102 */
 
1195
        fail_unless (1 == pgm_rxw_update (window, 102, 99, now, nak_rb_expiry), "update failed");
 
1196
        skb = generate_valid_skb ();
 
1197
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1198
        skb->pgm_data->data_sqn = g_htonl (102);
 
1199
        fail_unless (PGM_RXW_INSERTED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not inserted");
 
1200
        pgm_rxw_destroy (window);
 
1201
}
 
1202
END_TEST
 
1203
 
 
1204
START_TEST (test_update_fail_001)
 
1205
{
 
1206
        guint count = pgm_rxw_update (NULL, 0, 0, 0, 0);
 
1207
        fail ("reached");
 
1208
}
 
1209
END_TEST
 
1210
 
 
1211
/* target:
 
1212
 *      int
 
1213
 *      pgm_rxw_confirm (
 
1214
 *              pgm_rxw_t* const        window,
 
1215
 *              const uint32_t          sequence,
 
1216
 *              const pgm_time_t        now,
 
1217
 *              const pgm_time_t        nak_rdata_expiry,
 
1218
 *              const pgm_time_t        nak_rb_expiry
 
1219
 *              )
 
1220
 */
 
1221
 
 
1222
START_TEST (test_confirm_pass_001)
 
1223
{
 
1224
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1225
        const uint32_t ack_c_p = 500;
 
1226
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1227
        fail_if (NULL == window, "create failed");
 
1228
        const pgm_time_t now = 1;
 
1229
        const pgm_time_t nak_rdata_expiry = 2;
 
1230
        const pgm_time_t nak_rb_expiry = 2;
 
1231
        fail_unless (PGM_RXW_BOUNDS == pgm_rxw_confirm (window, 0, now, nak_rdata_expiry, nak_rb_expiry), "confirm not bounds");
 
1232
/* #1 at 100 */
 
1233
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1234
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1235
        skb->pgm_data->data_sqn = g_htonl (100);
 
1236
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1237
        fail_unless (1 == pgm_rxw_length (window), "length failed");
 
1238
        fail_unless (PGM_RXW_BOUNDS == pgm_rxw_confirm (window, 99, now, nak_rdata_expiry, nak_rb_expiry), "confirm not bounds");
 
1239
        fail_unless (PGM_RXW_DUPLICATE == pgm_rxw_confirm (window, 100, now, nak_rdata_expiry, nak_rb_expiry), "confirm not duplicate");
 
1240
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_confirm (window, 101, now, nak_rdata_expiry, nak_rb_expiry), "confirm not appended");
 
1241
        fail_unless (2 == pgm_rxw_length (window), "length failed");
 
1242
        fail_unless (PGM_RXW_UPDATED == pgm_rxw_confirm (window, 101, now, nak_rdata_expiry, nak_rb_expiry), "confirm not updated");
 
1243
/* #2 at 101 */
 
1244
        skb = generate_valid_skb ();
 
1245
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1246
        skb->pgm_data->data_sqn = g_htonl (101);
 
1247
        fail_unless (PGM_RXW_INSERTED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not inserted");
 
1248
        struct pgm_msgv_t msgv[2], *pmsg = msgv;
 
1249
        fail_unless (2000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1250
        pgm_rxw_destroy (window);
 
1251
}
 
1252
END_TEST
 
1253
 
 
1254
/* constrained confirm */
 
1255
START_TEST (test_confirm_pass_002)
 
1256
{
 
1257
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1258
        const uint32_t ack_c_p = 500;
 
1259
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1260
        fail_if (NULL == window, "create failed");
 
1261
        struct pgm_msgv_t msgv[1], *pmsg;
 
1262
        struct pgm_sk_buff_t* skb;
 
1263
        for (unsigned i = 0; i < 100; i++)
 
1264
        {
 
1265
                skb = generate_valid_skb ();
 
1266
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1267
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1268
                skb->tail = (guint8*)skb->tail - skb->len;
 
1269
                skb->len = 0;
 
1270
                skb->pgm_data->data_sqn = g_htonl (i);
 
1271
                const pgm_time_t now = 1;
 
1272
                const pgm_time_t nak_rb_expiry = 2;
 
1273
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1274
                fail_unless (MIN(100, 1 + i) == pgm_rxw_length (window), "length failed");
 
1275
        }
 
1276
        fail_unless (pgm_rxw_is_full (window), "is_full failed");
 
1277
        fail_unless (_pgm_rxw_commit_is_empty (window), "is_empty failed");
 
1278
/* read one skb */
 
1279
        {
 
1280
                pmsg = msgv;
 
1281
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1282
                fail_unless (1 == _pgm_rxw_commit_length (window), "commit_length failed");
 
1283
        }
 
1284
/* confirm next sequence */
 
1285
        const pgm_time_t now = 1;
 
1286
        const pgm_time_t nak_rdata_expiry = 2;
 
1287
        const pgm_time_t nak_rb_expiry = 2;
 
1288
        fail_unless (PGM_RXW_BOUNDS == pgm_rxw_confirm (window, 100, now, nak_rdata_expiry, nak_rb_expiry), "confirm not bounds");
 
1289
/* read off 99 more skbs */
 
1290
        for (unsigned i = 0; i < 99; i++)
 
1291
        {
 
1292
                pmsg = msgv;
 
1293
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1294
                fail_unless ((2 + i) == _pgm_rxw_commit_length (window), "commit_length failed");
 
1295
        }
 
1296
/* read end-of-window */
 
1297
        {
 
1298
                pmsg = msgv;
 
1299
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1300
        }
 
1301
        pgm_rxw_destroy (window);
 
1302
}
 
1303
END_TEST
 
1304
 
 
1305
START_TEST (test_confirm_fail_001)
 
1306
{
 
1307
        int retval = pgm_rxw_confirm (NULL, 0, 0, 0, 0);
 
1308
        fail ("reached");
 
1309
}
 
1310
END_TEST
 
1311
 
 
1312
/* target:
 
1313
 *      void
 
1314
 *      pgm_rxw_lost (
 
1315
 *              pgm_rxw_t* const        window,
 
1316
 *              const uint32_t          sequence
 
1317
 *              )
 
1318
 */
 
1319
 
 
1320
START_TEST (test_lost_pass_001)
 
1321
{
 
1322
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1323
        const uint32_t ack_c_p = 500;
 
1324
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1325
        fail_if (NULL == window, "create failed");
 
1326
        const pgm_time_t now = 1;
 
1327
        const pgm_time_t nak_rdata_expiry = 2;
 
1328
        const pgm_time_t nak_rb_expiry = 2;
 
1329
/* #1 at 100 */
 
1330
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1331
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1332
        skb->pgm_data->data_sqn = g_htonl (100);
 
1333
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1334
        fail_unless (1 == pgm_rxw_length (window), "length failed");
 
1335
        fail_unless (1000 == pgm_rxw_size (window), "size failed");
 
1336
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_confirm (window, 101, now, nak_rdata_expiry, nak_rb_expiry), "confirm not appended");
 
1337
        fail_unless (2 == pgm_rxw_length (window), "length failed");
 
1338
        fail_unless (1000 == pgm_rxw_size (window), "size failed");
 
1339
        pgm_rxw_lost (window, 101);
 
1340
        fail_unless (2 == pgm_rxw_length (window), "length failed");
 
1341
        fail_unless (1000 == pgm_rxw_size (window), "size failed");
 
1342
/* #2 at 101 */
 
1343
        skb = generate_valid_skb ();
 
1344
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1345
        skb->pgm_data->data_sqn = g_htonl (101);
 
1346
        fail_unless (PGM_RXW_INSERTED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not inserted");
 
1347
        fail_unless (2 == pgm_rxw_length (window), "length failed");
 
1348
        fail_unless (2000 == pgm_rxw_size (window), "size failed");
 
1349
        pgm_rxw_destroy (window);
 
1350
}
 
1351
END_TEST
 
1352
 
 
1353
START_TEST (test_lost_fail_001)
 
1354
{
 
1355
        pgm_rxw_lost (NULL, 0);
 
1356
        fail ("reached");
 
1357
}
 
1358
END_TEST
 
1359
 
 
1360
/* target:
 
1361
 *      void
 
1362
 *      pgm_rxw_state (
 
1363
 *              pgm_rxw_t* const        window,
 
1364
 *              struct pgm_sk_buff_t*   skb,
 
1365
 *              int                     new_state
 
1366
 *              )
 
1367
 */
 
1368
 
 
1369
START_TEST (test_state_pass_001)
 
1370
{
 
1371
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1372
        const uint32_t ack_c_p = 500;
 
1373
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1374
        fail_if (NULL == window, "create failed");
 
1375
        const pgm_time_t now = 1;
 
1376
        const pgm_time_t nak_rdata_expiry = 2;
 
1377
        const pgm_time_t nak_rb_expiry = 2;
 
1378
        fail_unless (0 == pgm_rxw_update (window, 100, 99, now, nak_rb_expiry), "update failed");
 
1379
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_confirm (window, 101, now, nak_rdata_expiry, nak_rb_expiry), "confirm not appended");
 
1380
        struct pgm_sk_buff_t* skb = pgm_rxw_peek (window, 101);
 
1381
        pgm_rxw_state (window, skb, PGM_PKT_STATE_WAIT_NCF);
 
1382
        pgm_rxw_state (window, skb, PGM_PKT_STATE_WAIT_DATA);
 
1383
        pgm_rxw_destroy (window);
 
1384
}
 
1385
END_TEST
 
1386
 
 
1387
START_TEST (test_state_fail_001)
 
1388
{
 
1389
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1390
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1391
        skb->pgm_data->data_sqn = g_htonl (0);
 
1392
        pgm_rxw_state (NULL, skb, PGM_PKT_STATE_BACK_OFF);
 
1393
        fail ("reached");
 
1394
}
 
1395
END_TEST
 
1396
 
 
1397
START_TEST (test_state_fail_002)
 
1398
{
 
1399
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1400
        const uint32_t ack_c_p = 500;
 
1401
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1402
        fail_if (NULL == window, "create failed");
 
1403
        pgm_rxw_state (window, NULL, PGM_PKT_STATE_BACK_OFF);
 
1404
        fail ("reached");
 
1405
}
 
1406
END_TEST
 
1407
 
 
1408
START_TEST (test_state_fail_003)
 
1409
{
 
1410
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1411
        const uint32_t ack_c_p = 500;
 
1412
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1413
        fail_if (NULL == window, "create failed");
 
1414
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1415
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1416
        skb->pgm_data->data_sqn = g_htonl (0);
 
1417
        pgm_rxw_state (window, skb, -1);
 
1418
        fail ("reached");
 
1419
}
 
1420
END_TEST
 
1421
 
 
1422
/* pgm_peer_has_pending
 
1423
 */
 
1424
 
 
1425
START_TEST (test_has_pending_pass_001)
 
1426
{
 
1427
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1428
        const uint32_t ack_c_p = 500;
 
1429
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1430
        fail_if (NULL == window, "create failed");
 
1431
/* empty */
 
1432
        fail_unless (0 == window->has_event, "unexpected event");
 
1433
        struct pgm_sk_buff_t* skb = generate_valid_skb ();
 
1434
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1435
        skb->pgm_data->data_sqn = g_htonl (0);
 
1436
        const pgm_time_t now = 1;
 
1437
        const pgm_time_t nak_rdata_expiry = 2;
 
1438
        const pgm_time_t nak_rb_expiry = 2;
 
1439
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not appended");
 
1440
/* 1 sequence */
 
1441
        fail_unless (1 == window->has_event, "no event");
 
1442
        window->has_event = 0;
 
1443
/* jump */
 
1444
        skb = generate_valid_skb ();
 
1445
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1446
        skb->pgm_data->data_sqn = g_htonl (2);
 
1447
        fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not missing");
 
1448
        fail_unless (0 == window->has_event, "unexpected event");
 
1449
/* loss */
 
1450
        pgm_rxw_lost (window, 1);
 
1451
        fail_unless (1 == window->has_event, "no event");
 
1452
        window->has_event = 0;
 
1453
/* insert */
 
1454
        skb = generate_valid_skb ();
 
1455
        fail_if (NULL == skb, "generate_valid_skb failed");
 
1456
        skb->pgm_data->data_sqn = g_htonl (1);
 
1457
        fail_unless (PGM_RXW_INSERTED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add not inserted");
 
1458
        fail_unless (1 == window->has_event, "no event");
 
1459
        window->has_event = 0;
 
1460
/* confirm */
 
1461
        fail_unless (PGM_RXW_APPENDED == pgm_rxw_confirm (window, 3, now, nak_rdata_expiry, nak_rb_expiry), "confirm not appended");
 
1462
        fail_unless (0 == window->has_event, "unexpected event");
 
1463
/* partial read */
 
1464
        struct pgm_msgv_t msgv[2], *pmsg = msgv;
 
1465
        fail_unless (2000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1466
        fail_unless (0 == window->has_event, "unexpected event");
 
1467
/* finish read */
 
1468
        pmsg = msgv;
 
1469
        fail_unless (1000 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1470
        fail_unless (0 == window->has_event, "unexpected event");
 
1471
        pgm_rxw_destroy (window);
 
1472
}
 
1473
END_TEST
 
1474
 
 
1475
static
 
1476
Suite*
 
1477
make_basic_test_suite (void)
 
1478
{
 
1479
        Suite* s;
 
1480
 
 
1481
        s = suite_create ("basic receive window API");
 
1482
 
 
1483
        TCase* tc_create = tcase_create ("create");
 
1484
        suite_add_tcase (s, tc_create);
 
1485
        tcase_add_test (tc_create, test_create_pass_001);
 
1486
        tcase_add_test (tc_create, test_create_pass_002);
 
1487
        tcase_add_test (tc_create, test_create_pass_003);
 
1488
        tcase_add_test (tc_create, test_create_pass_004);
 
1489
#ifndef PGM_CHECK_NOFORK
 
1490
        tcase_add_test_raise_signal (tc_create, test_create_fail_001, SIGABRT);
 
1491
        tcase_add_test_raise_signal (tc_create, test_create_fail_002, SIGABRT);
 
1492
        tcase_add_test_raise_signal (tc_create, test_create_fail_003, SIGABRT);
 
1493
        tcase_add_test_raise_signal (tc_create, test_create_fail_004, SIGABRT);
 
1494
#endif
 
1495
 
 
1496
        TCase* tc_destroy = tcase_create ("destroy");
 
1497
        suite_add_tcase (s, tc_destroy);
 
1498
        tcase_add_test (tc_destroy, test_destroy_pass_001);
 
1499
#ifndef PGM_CHECK_NOFORK
 
1500
        tcase_add_test_raise_signal (tc_destroy, test_destroy_fail_001, SIGABRT);
 
1501
#endif
 
1502
 
 
1503
        TCase* tc_add = tcase_create ("add");
 
1504
        suite_add_tcase (s, tc_add);
 
1505
        tcase_add_test (tc_add, test_add_pass_001);
 
1506
        tcase_add_test (tc_add, test_add_pass_002);
 
1507
        tcase_add_test (tc_add, test_add_pass_003);
 
1508
        tcase_add_test (tc_add, test_add_pass_004);
 
1509
        tcase_add_test (tc_add, test_add_pass_005);
 
1510
#ifndef PGM_CHECK_NOFORK
 
1511
        tcase_add_test_raise_signal (tc_add, test_add_fail_001, SIGABRT);
 
1512
        tcase_add_test_raise_signal (tc_add, test_add_fail_002, SIGABRT);
 
1513
        tcase_add_test_raise_signal (tc_add, test_add_fail_003, SIGABRT);
 
1514
#endif
 
1515
 
 
1516
        TCase* tc_peek = tcase_create ("peek");
 
1517
        suite_add_tcase (s, tc_peek);
 
1518
        tcase_add_test (tc_peek, test_peek_pass_001);
 
1519
#ifndef PGM_CHECK_NOFORK
 
1520
        tcase_add_test_raise_signal (tc_peek, test_peek_fail_001, SIGABRT);
 
1521
#endif
 
1522
 
 
1523
        TCase* tc_max_length = tcase_create ("max-length");
 
1524
        suite_add_tcase (s, tc_max_length);
 
1525
        tcase_add_test (tc_max_length, test_max_length_pass_001);
 
1526
#ifndef PGM_CHECK_NOFORK
 
1527
        tcase_add_test_raise_signal (tc_max_length, test_max_length_fail_001, SIGABRT);
 
1528
#endif
 
1529
 
 
1530
        TCase* tc_length = tcase_create ("length");
 
1531
        suite_add_tcase (s, tc_length);
 
1532
        tcase_add_test (tc_length, test_length_pass_001);
 
1533
#ifndef PGM_CHECK_NOFORK
 
1534
        tcase_add_test_raise_signal (tc_length, test_length_fail_001, SIGABRT);
 
1535
#endif
 
1536
 
 
1537
        TCase* tc_size = tcase_create ("size");
 
1538
        suite_add_tcase (s, tc_size);
 
1539
        tcase_add_test (tc_size, test_size_pass_001);
 
1540
#ifndef PGM_CHECK_NOFORK
 
1541
        tcase_add_test_raise_signal (tc_size, test_size_fail_001, SIGABRT);
 
1542
#endif
 
1543
 
 
1544
        TCase* tc_is_empty = tcase_create ("is-empty");
 
1545
        suite_add_tcase (s, tc_is_empty);
 
1546
        tcase_add_test (tc_is_empty, test_is_empty_pass_001);
 
1547
#ifndef PGM_CHECK_NOFORK
 
1548
        tcase_add_test_raise_signal (tc_is_empty, test_is_empty_fail_001, SIGABRT);
 
1549
#endif
 
1550
 
 
1551
        TCase* tc_is_full = tcase_create ("is-full");
 
1552
        suite_add_tcase (s, tc_is_full);
 
1553
        tcase_add_test (tc_is_full, test_is_full_pass_001);
 
1554
#ifndef PGM_CHECK_NOFORK
 
1555
        tcase_add_test_raise_signal (tc_is_full, test_is_full_fail_001, SIGABRT);
 
1556
#endif
 
1557
 
 
1558
        TCase* tc_lead = tcase_create ("lead");
 
1559
        suite_add_tcase (s, tc_lead);
 
1560
        tcase_add_test (tc_lead, test_lead_pass_001);
 
1561
#ifndef PGM_CHECK_NOFORK
 
1562
        tcase_add_test_raise_signal (tc_lead, test_lead_fail_001, SIGABRT);
 
1563
#endif
 
1564
 
 
1565
        TCase* tc_next_lead = tcase_create ("next-lead");
 
1566
        suite_add_tcase (s, tc_next_lead);
 
1567
        tcase_add_test (tc_next_lead, test_next_lead_pass_001);
 
1568
#ifndef PGM_CHECK_NOFORK
 
1569
        tcase_add_test_raise_signal (tc_next_lead, test_next_lead_fail_001, SIGABRT);
 
1570
#endif
 
1571
 
 
1572
        TCase* tc_readv = tcase_create ("readv");
 
1573
        suite_add_tcase (s, tc_readv);
 
1574
        tcase_add_test (tc_readv, test_readv_pass_001);
 
1575
        tcase_add_test (tc_readv, test_readv_pass_002);
 
1576
        tcase_add_test (tc_readv, test_readv_pass_003);
 
1577
        tcase_add_test (tc_readv, test_readv_pass_004);
 
1578
        tcase_add_test (tc_readv, test_readv_pass_005);
 
1579
        tcase_add_test (tc_readv, test_readv_pass_006);
 
1580
#ifndef PGM_CHECK_NOFORK
 
1581
        tcase_add_test_raise_signal (tc_readv, test_readv_fail_001, SIGABRT);
 
1582
        tcase_add_test_raise_signal (tc_readv, test_readv_fail_002, SIGABRT);
 
1583
        tcase_add_test_raise_signal (tc_readv, test_readv_fail_003, SIGABRT);
 
1584
#endif
 
1585
 
 
1586
        TCase* tc_remove_commit = tcase_create ("remove-commit");
 
1587
        suite_add_tcase (s, tc_remove_commit);
 
1588
        tcase_add_test (tc_remove_commit, test_remove_commit_pass_001);
 
1589
#ifndef PGM_CHECK_NOFORK
 
1590
        tcase_add_test_raise_signal (tc_remove_commit, test_remove_commit_fail_001, SIGABRT);
 
1591
#endif
 
1592
 
 
1593
        TCase* tc_remove_trail = tcase_create ("remove-trail");
 
1594
        TCase* tc_update = tcase_create ("update");
 
1595
        suite_add_tcase (s, tc_update);
 
1596
        tcase_add_test (tc_update, test_update_pass_001);
 
1597
#ifndef PGM_CHECK_NOFORK
 
1598
        tcase_add_test_raise_signal (tc_update, test_update_fail_001, SIGABRT);
 
1599
#endif
 
1600
 
 
1601
        TCase* tc_confirm = tcase_create ("confirm");
 
1602
        suite_add_tcase (s, tc_confirm);
 
1603
        tcase_add_test (tc_confirm, test_confirm_pass_001);
 
1604
        tcase_add_test (tc_confirm, test_confirm_pass_002);
 
1605
#ifndef PGM_CHECK_NOFORK
 
1606
        tcase_add_test_raise_signal (tc_confirm, test_confirm_fail_001, SIGABRT);
 
1607
#endif
 
1608
 
 
1609
        TCase* tc_lost = tcase_create ("lost");
 
1610
        suite_add_tcase (s, tc_lost);
 
1611
        tcase_add_test (tc_lost, test_lost_pass_001);
 
1612
#ifndef PGM_CHECK_NOFORK
 
1613
        tcase_add_test_raise_signal (tc_lost, test_lost_fail_001, SIGABRT);
 
1614
#endif
 
1615
 
 
1616
        TCase* tc_state = tcase_create ("state");
 
1617
        suite_add_tcase (s, tc_state);
 
1618
        tcase_add_test (tc_state, test_state_pass_001);
 
1619
#ifndef PGM_CHECK_NOFORK
 
1620
        tcase_add_test_raise_signal (tc_state, test_state_fail_001, SIGABRT);
 
1621
#endif
 
1622
 
 
1623
        return s;
 
1624
}
 
1625
 
 
1626
/* read through lost packet */
 
1627
START_TEST (test_readv_pass_007)
 
1628
{
 
1629
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1630
        const uint32_t ack_c_p = 500;
 
1631
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1632
        fail_if (NULL == window, "create failed");
 
1633
        struct pgm_msgv_t msgv[1], *pmsg;
 
1634
        struct pgm_sk_buff_t* skb;
 
1635
/* add #0 */
 
1636
        {
 
1637
                unsigned i = 0;
 
1638
                skb = generate_valid_skb ();
 
1639
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1640
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1641
                skb->tail = (guint8*)skb->tail - skb->len;
 
1642
                skb->len = 0;
 
1643
                skb->pgm_data->data_sqn = g_htonl (i);
 
1644
                const pgm_time_t now = 1;
 
1645
                const pgm_time_t nak_rb_expiry = 2;
 
1646
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1647
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
1648
        }
 
1649
/* add # 2 */
 
1650
        {
 
1651
                unsigned i = 2;
 
1652
                skb = generate_valid_skb ();
 
1653
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1654
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1655
                skb->tail = (guint8*)skb->tail - skb->len;
 
1656
                skb->len = 0;
 
1657
                skb->pgm_data->data_sqn = g_htonl (i);
 
1658
                const pgm_time_t now = 1;
 
1659
                const pgm_time_t nak_rb_expiry = 2;
 
1660
                fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1661
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
1662
        }
 
1663
/* lose #1 */
 
1664
        {
 
1665
                pgm_rxw_lost (window, 1);
 
1666
        }
 
1667
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
1668
/* read #0 */
 
1669
        {
 
1670
                pmsg = msgv;
 
1671
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1672
        }
 
1673
/* end-of-window */
 
1674
        {
 
1675
                pmsg = msgv;
 
1676
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1677
        }
 
1678
        pgm_rxw_remove_commit (window);
 
1679
/* read lost skb #1 */
 
1680
        {
 
1681
                pmsg = msgv;
 
1682
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1683
        }
 
1684
        pgm_rxw_remove_commit (window);
 
1685
/* read #2 */
 
1686
        {
 
1687
                pmsg = msgv;
 
1688
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1689
        }
 
1690
/* end-of-window */
 
1691
        {
 
1692
                pmsg = msgv;
 
1693
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1694
        }
 
1695
        pgm_rxw_destroy (window);
 
1696
}
 
1697
END_TEST
 
1698
 
 
1699
/* read through loss extended window */
 
1700
START_TEST (test_readv_pass_008)
 
1701
{
 
1702
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1703
        const uint32_t ack_c_p = 500;
 
1704
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1705
        fail_if (NULL == window, "create failed");
 
1706
        struct pgm_msgv_t msgv[1], *pmsg;
 
1707
        struct pgm_sk_buff_t* skb;
 
1708
/* add #0 */
 
1709
        {
 
1710
                unsigned i = 0;
 
1711
                skb = generate_valid_skb ();
 
1712
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1713
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1714
                skb->tail = (guint8*)skb->tail - skb->len;
 
1715
                skb->len = 0;
 
1716
                skb->pgm_data->data_sqn = g_htonl (i);
 
1717
                const pgm_time_t now = 1;
 
1718
                const pgm_time_t nak_rb_expiry = 2;
 
1719
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1720
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
1721
        }
 
1722
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
1723
/* read #0 */
 
1724
        {
 
1725
                pmsg = msgv;
 
1726
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1727
        }
 
1728
        pgm_rxw_remove_commit (window);
 
1729
/* end-of-window */
 
1730
        {
 
1731
                pmsg = msgv;
 
1732
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1733
        }
 
1734
/* add #100 */
 
1735
        {
 
1736
                unsigned i = 100;
 
1737
                skb = generate_valid_skb ();
 
1738
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1739
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1740
                skb->tail = (guint8*)skb->tail - skb->len;
 
1741
                skb->len = 0;
 
1742
                skb->pgm_data->data_sqn = g_htonl (i);
 
1743
                const pgm_time_t now = 1;
 
1744
                const pgm_time_t nak_rb_expiry = 2;
 
1745
                fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1746
        }
 
1747
/* lose #1-99 */
 
1748
        {
 
1749
                for (unsigned i = 1; i < 100; i++)
 
1750
                        pgm_rxw_lost (window, i);
 
1751
        }
 
1752
/* read #100 */
 
1753
        {
 
1754
                int i = 0;
 
1755
                int bytes_read;
 
1756
                pmsg = msgv;
 
1757
                do {
 
1758
                        bytes_read = pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv));
 
1759
                        pgm_rxw_remove_commit (window);
 
1760
                        i++;
 
1761
                        if (i > 100) break;
 
1762
                } while (-1 == bytes_read);
 
1763
                fail_unless (100 == i, "readv failed");
 
1764
        }
 
1765
/* end-of-window */
 
1766
        {
 
1767
                pmsg = msgv;
 
1768
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1769
        }
 
1770
        pgm_rxw_destroy (window);
 
1771
}
 
1772
END_TEST
 
1773
 
 
1774
/* read through long data-loss */
 
1775
START_TEST (test_readv_pass_009)
 
1776
{
 
1777
        pgm_tsi_t tsi = { { 1, 2, 3, 4, 5, 6 }, 1000 };
 
1778
        const uint32_t ack_c_p = 500;
 
1779
        pgm_rxw_t* window = pgm_rxw_create (&tsi, 1500, 100, 0, 0, ack_c_p);
 
1780
        fail_if (NULL == window, "create failed");
 
1781
        struct pgm_msgv_t msgv[1], *pmsg;
 
1782
        struct pgm_sk_buff_t* skb;
 
1783
/* add #0 */
 
1784
        {
 
1785
                unsigned i = 0;
 
1786
                skb = generate_valid_skb ();
 
1787
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1788
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1789
                skb->tail = (guint8*)skb->tail - skb->len;
 
1790
                skb->len = 0;
 
1791
                skb->pgm_data->data_sqn = g_htonl (i);
 
1792
                const pgm_time_t now = 1;
 
1793
                const pgm_time_t nak_rb_expiry = 2;
 
1794
                fail_unless (PGM_RXW_APPENDED == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1795
                fail_unless ((1 + i) == pgm_rxw_length (window), "length failed");
 
1796
        }
 
1797
        fail_unless (_pgm_rxw_commit_is_empty (window), "commit_is_empty failed");
 
1798
/* read #0 */
 
1799
        {
 
1800
                pmsg = msgv;
 
1801
                fail_unless (0 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1802
        }
 
1803
        pgm_rxw_remove_commit (window);
 
1804
/* end-of-window */
 
1805
        {
 
1806
                pmsg = msgv;
 
1807
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1808
        }
 
1809
/* add #2000 */
 
1810
        {
 
1811
                unsigned i = 2000;
 
1812
                skb = generate_valid_skb ();
 
1813
                fail_if (NULL == skb, "generate_valid_skb failed");
 
1814
                skb->pgm_header->pgm_tsdu_length = g_htons (0);
 
1815
                skb->tail = (guint8*)skb->tail - skb->len;
 
1816
                skb->len = 0;
 
1817
                skb->pgm_data->data_sqn = g_htonl (i);
 
1818
                const pgm_time_t now = 1;
 
1819
                const pgm_time_t nak_rb_expiry = 2;
 
1820
                fail_unless (PGM_RXW_MISSING == pgm_rxw_add (window, skb, now, nak_rb_expiry), "add failed");
 
1821
        }
 
1822
/* lose #1-1999 */
 
1823
        {
 
1824
                for (unsigned i = 1901; i < 2000; i++)
 
1825
                        pgm_rxw_lost (window, i);
 
1826
        }
 
1827
/* read #2000 */
 
1828
        {
 
1829
                int i = 0;
 
1830
                int bytes_read;
 
1831
                pmsg = msgv;
 
1832
                do {
 
1833
                        bytes_read = pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv));
 
1834
                        pgm_rxw_remove_commit (window);
 
1835
                        i++;
 
1836
                        if (i > 100) break;
 
1837
                } while (-1 == bytes_read);
 
1838
                fail_unless (100 == i, "readv failed");
 
1839
        }
 
1840
/* end-of-window */
 
1841
        {
 
1842
                pmsg = msgv;
 
1843
                fail_unless (-1 == pgm_rxw_readv (window, &pmsg, G_N_ELEMENTS(msgv)), "readv failed");
 
1844
        }
 
1845
        pgm_rxw_destroy (window);
 
1846
}
 
1847
END_TEST
 
1848
 
 
1849
/* a.k.a. unreliable delivery
 
1850
 */
 
1851
 
 
1852
static
 
1853
Suite*
 
1854
make_best_effort_test_suite (void)
 
1855
{
 
1856
        Suite* s;
 
1857
 
 
1858
        s = suite_create ("Best effort delivery");
 
1859
 
 
1860
        TCase* tc_readv = tcase_create ("readv");
 
1861
        suite_add_tcase (s, tc_readv);
 
1862
        tcase_add_test (tc_readv, test_readv_pass_007);
 
1863
        tcase_add_test (tc_readv, test_readv_pass_008);
 
1864
        tcase_add_test (tc_readv, test_readv_pass_009);
 
1865
 
 
1866
        return s;
 
1867
}
 
1868
 
 
1869
static
 
1870
Suite*
 
1871
make_master_suite (void)
 
1872
{
 
1873
        Suite* s = suite_create ("Master");
 
1874
        return s;
 
1875
}
 
1876
 
 
1877
int
 
1878
main (void)
 
1879
{
 
1880
        SRunner* sr = srunner_create (make_master_suite ());
 
1881
        srunner_add_suite (sr, make_basic_test_suite ());
 
1882
        srunner_add_suite (sr, make_best_effort_test_suite ());
 
1883
        srunner_run_all (sr, CK_ENV);
 
1884
        int number_failed = srunner_ntests_failed (sr);
 
1885
        srunner_free (sr);
 
1886
        return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 
1887
}
 
1888
 
 
1889
/* eof */