root/test/test-shunt-complex-file.c

Revision 82292c9c156aceaf83c236ffeff0fd66fd5d21d3, 20.0 kB (checked in by Hans Petter Jansson <hpj@ubuntu-vm.(none)>, 3 years ago)

Fix bug that would occasionally make test stop reading early and thus fail.

  • Property mode set to 100644
Line 
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
3 /* test-shunt-simple-file.c - FlowShunt simple file test.
4  *
5  * Copyright (C) 2006 Hans Petter Jansson
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 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
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * Authors: Hans Petter Jansson <hpj@copyleft.no>
23  */
24
25 #define TEST_UNIT_NAME "FlowShunt (complex file)"
26 #define TEST_TIMEOUT_S 60
27
28 /* Test variables; adjustable */
29
30 #define BUFFER_SIZE            20000000  /* Amount of data to transfer */
31 #define PACKET_MAX_SIZE        8192      /* Max transfer unit */
32 #define PACKET_MIN_SIZE        1         /* Min transfer unit */
33
34 #define TOTAL_PAUSE_TIME_MS    3000      /* Total time to spend *not* reading or writing */
35 #define PAUSE_MIN_LENGTH_MS    10        /* Min pause unit */
36 #define PAUSE_MAX_LENGTH_MS    200       /* Max pause unit */
37
38 /* Calculations to determine the probability of pausing for
39  * each packet processed. No user serviceable parts inside. */
40
41 #define PROBABILITY_MULTIPLIER 1000000  /* For fixed-point fractions */
42 #define PACKET_AVG_SIZE        (PACKET_MIN_SIZE + ((PACKET_MAX_SIZE - PACKET_MIN_SIZE) / 2))
43 #define PAUSE_AVG_LENGTH_MS    (PAUSE_MIN_LENGTH_MS + ((PAUSE_MAX_LENGTH_MS - PAUSE_MIN_LENGTH_MS) / 2))
44 #define NUM_PAUSES             (TOTAL_PAUSE_TIME_MS / PAUSE_AVG_LENGTH_MS)
45 #define TOTAL_EXPECTED_PACKETS (BUFFER_SIZE / PACKET_AVG_SIZE)
46 #define TOTAL_EXPECTED_EVENTS  (TOTAL_EXPECTED_PACKETS * 2)  /* Account for both reads and writes */
47 #define PAUSE_PROBABILITY      ((NUM_PAUSES * PROBABILITY_MULTIPLIER) / TOTAL_EXPECTED_EVENTS)
48
49 #include "test-common.c"
50
51 static guchar    *pre_buffer;   /* Updated when we send the request */
52 static guchar    *post_buffer;  /* Updated when we receive data */
53 static gint       pre_pos;
54 static gint       post_pos;
55
56 static gint       n_packets_written = 0;
57 static gint       n_segments_remaining = 0;
58
59 static gboolean   finished_writing;
60 static gboolean   quitting_main_loop;
61 static gboolean   writes_are_blocked;
62
63 static gboolean   started_reading;
64 static gboolean   finished_reading;
65 static gboolean   in_segment;
66 static gboolean   reads_are_blocked;
67
68 static FlowShunt *global_shunt;
69
70 static void
71 randomize_buffer (gpointer buf, gint len_bytes)
72 {
73   gint i;
74
75   /* Fill buffer with bytes 0x02 - 0xff */
76
77   for (i = 0; i < len_bytes; )
78   {
79     guchar *p = buf + i;
80
81     if (i < len_bytes - 4)
82     {
83       *((guint32 *) p) = (guint32) g_random_int () | 0x02020202;
84       i += 4;
85     }
86     else
87     {
88       *p = (guchar) g_random_int () | 0x02;
89       i++;
90     }
91   }
92 }
93
94 static guint
95 get_pause_interval_ms (void)
96 {
97   guint n;
98
99   n = g_random_int_range (0, PROBABILITY_MULTIPLIER + 1);
100   if (n < PAUSE_PROBABILITY)
101   {
102     n = g_random_int_range (PAUSE_MIN_LENGTH_MS, PAUSE_MAX_LENGTH_MS + 1);
103     return n;
104   }
105
106   return 0;
107 }
108
109 static gboolean
110 read_pause_ended (FlowShunt *shunt)
111 {
112   test_print ("Resuming reads\n");
113   reads_are_blocked = FALSE;
114   flow_shunt_unblock_reads (shunt);
115   return FALSE;
116 }
117
118 static void
119 read_stream (FlowShunt *shunt, FlowPacket *packet, gpointer data)
120 {
121   guint    packet_size;
122   gpointer packet_data;
123   guint    pause_ms;
124
125   if (reads_are_blocked)
126     test_end (TEST_RESULT_FAILED, "got read while blocked");
127
128   if (data != shunt)
129     test_end (TEST_RESULT_FAILED, "read callback user_data does not match");
130
131   if (finished_reading)
132     test_end (TEST_RESULT_FAILED, "got read callback after end-of-stream");
133
134   if (!packet)
135     test_end (TEST_RESULT_FAILED, "got read with NULL packet");
136
137   packet_data = flow_packet_get_data (packet);
138   if (!packet_data)
139     test_end (TEST_RESULT_FAILED, "got NULL packet data");
140
141   if (flow_packet_get_format (packet) == FLOW_PACKET_FORMAT_OBJECT)
142   {
143     FlowDetailedEvent *detailed_event = packet_data;
144
145     if (FLOW_IS_DETAILED_EVENT (detailed_event))
146     {
147       if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_BEGIN))
148       {
149         test_print ("Read: Beginning of stream marker\n");
150
151         if (started_reading)
152           test_end (TEST_RESULT_FAILED, "got multiple beginning-of-stream markers");
153
154         started_reading = TRUE;
155       }
156       else if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_SEGMENT_BEGIN))
157       {
158         test_print ("Read: Beginning of segment marker\n");
159
160         if (!started_reading)
161           test_end (TEST_RESULT_FAILED, "segment started before stream");
162
163         if (finished_reading)
164           test_end (TEST_RESULT_FAILED, "segment started after stream end");
165
166         if (in_segment)
167           test_end (TEST_RESULT_FAILED, "got nested beginning-of-segment markers");
168
169         in_segment = TRUE;
170       }
171       else if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_END))
172       {
173         test_print ("Read: End of stream marker\n");
174
175         if (!started_reading)
176           test_end (TEST_RESULT_FAILED, "stream ended without starting");
177
178         if (finished_reading)
179           test_end (TEST_RESULT_FAILED, "got multiple end-of-stream markers");
180
181         if (in_segment)
182           test_end (TEST_RESULT_FAILED, "stream ended inside an open segment");
183
184         if (post_pos != BUFFER_SIZE)
185           test_end (TEST_RESULT_FAILED, "did not pass through all the data");
186
187         finished_reading = TRUE;
188       }
189       else if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_SEGMENT_END))
190       {
191         test_print ("Read: End of segment marker\n");
192
193         if (!started_reading)
194           test_end (TEST_RESULT_FAILED, "segment end before stream start");
195
196         if (finished_reading)
197           test_end (TEST_RESULT_FAILED, "segment end after stream end");
198
199         if (!in_segment)
200           test_end (TEST_RESULT_FAILED, "end of segment, but no segment open");
201
202         in_segment = FALSE;
203
204         /* Wait a bit before quitting, so shunts have a chance to generate invalid events */
205         g_timeout_add (1000, (GSourceFunc) test_quit_main_loop, NULL);
206       }
207     }
208     else if (FLOW_IS_POSITION (packet_data))
209     {
210       FlowPosition *position = packet_data;
211
212       if (flow_position_get_anchor (position) != FLOW_OFFSET_ANCHOR_BEGIN)
213         test_end (TEST_RESULT_FAILED, "got relative position from shunt");
214
215       post_pos = flow_position_get_offset (position);
216
217       test_print ("Read: Seek to %d\n", post_pos);
218     }
219     else if (!FLOW_IS_EVENT (detailed_event))
220     {
221       test_end (TEST_RESULT_FAILED, "got a weird object from read shunt");
222     }
223   }
224   else if (flow_packet_get_format (packet) == FLOW_PACKET_FORMAT_BUFFER)
225   {
226     packet_size = flow_packet_get_size (packet);
227     if (packet_size == 0)
228       test_end (TEST_RESULT_FAILED, "got zero-size buffer packet");
229
230     test_print ("Read: %d byte packet at offset %d\n", packet_size, post_pos);
231
232     if (!started_reading)
233       test_end (TEST_RESULT_FAILED, "got data before start of stream");
234
235     if (finished_reading)
236       test_end (TEST_RESULT_FAILED, "got data after end of stream");
237
238     if (!in_segment)
239       test_end (TEST_RESULT_FAILED, "got data outside segment");
240
241     if (post_pos + packet_size > BUFFER_SIZE)
242       test_end (TEST_RESULT_FAILED, "read too much data");
243
244     memcpy ((gchar *) post_buffer + post_pos, packet_data, packet_size);
245     post_pos += packet_size;
246
247     if (post_pos == BUFFER_SIZE)
248     {
249       test_print ("Read: Complete at %d bytes\n", post_pos);
250     }
251   }
252   else
253   {
254     test_end (TEST_RESULT_FAILED, "got unknown packet format");
255   }
256
257   flow_packet_free (packet);
258
259   pause_ms = get_pause_interval_ms ();
260   if (pause_ms > 0)
261   {
262     test_print ("Blocking reads for %.2fs\n", (float) pause_ms / 1000.0);
263     reads_are_blocked = TRUE;
264     flow_shunt_block_reads (shunt);
265     g_timeout_add (pause_ms, (GSourceFunc) read_pause_ended, shunt);
266   }
267 }
268
269 static gboolean
270 write_pause_ended (FlowShunt *shunt)
271 {
272   if (finished_writing)
273     return FALSE;
274
275   test_print ("Resuming writes\n");
276   writes_are_blocked = FALSE;
277   flow_shunt_unblock_writes (shunt);
278   return FALSE;
279 }
280
281 static FlowPacket *
282 write_stream (FlowShunt *shunt, gpointer data)
283 {
284   FlowPacket *packet = NULL;
285   guint       pause_ms;
286   guint       len;
287
288   if (writes_are_blocked)
289     test_end (TEST_RESULT_FAILED, "got write while blocked");
290
291   if (data != shunt)
292     test_end (TEST_RESULT_FAILED, "write callback user_data does not match");
293
294   if (finished_writing)
295     test_end (TEST_RESULT_FAILED, "got write callback after sending end-of-stream");
296
297   len = g_random_int_range (PACKET_MIN_SIZE, PACKET_MAX_SIZE + 1);
298   if (pre_pos + len > BUFFER_SIZE)
299     len = BUFFER_SIZE - pre_pos;
300
301   packet = flow_packet_new (FLOW_PACKET_FORMAT_BUFFER, pre_buffer + pre_pos, len);
302   if (!packet)
303     test_end (TEST_RESULT_FAILED, "failed to create a packet");
304
305   test_print ("Write: %d byte packet at offset %d\n", len, pre_pos);
306
307   pre_pos += len;
308
309   if (pre_pos == BUFFER_SIZE)
310   {
311     finished_writing = TRUE;
312     test_print ("Write: File creation complete\n");
313
314     flow_shunt_block_writes (shunt);
315
316     /* Wait a bit before quitting, so shunts have a chance to generate invalid events */
317     g_timeout_add (1000, (GSourceFunc) test_quit_main_loop, NULL);
318   }
319
320   if (!finished_writing)
321   {
322     pause_ms = get_pause_interval_ms ();
323     if (pause_ms > 0)
324     {
325       test_print ("Blocking writes for %.2fs\n", (float) pause_ms / 1000.0);
326       writes_are_blocked = TRUE;
327       flow_shunt_block_writes (shunt);
328       g_timeout_add (pause_ms, (GSourceFunc) write_pause_ended, shunt);
329     }
330   }
331
332   return packet;
333 }
334
335 static FlowPacket *
336 write_random (FlowShunt *shunt, gpointer data)
337 {
338   FlowPacket *packet;
339   gint        r;
340
341   r = g_random_int_range (0, PROBABILITY_MULTIPLIER);
342
343   if (pre_pos > BUFFER_SIZE || r < PROBABILITY_MULTIPLIER / 3)
344   {
345     /* Seek to a random position */
346
347     r = g_random_int_range (0, BUFFER_SIZE);
348     packet = flow_packet_new_take_object (flow_position_new (FLOW_OFFSET_ANCHOR_BEGIN, r), 0);
349     pre_pos = r;
350
351     test_print ("Write: Seek to offset %d\n", r);
352   }
353   else if (pre_pos == BUFFER_SIZE || r < (PROBABILITY_MULTIPLIER * 2) / 3)
354   {
355     /* Request a read */
356
357     r = g_random_int_range (1, PACKET_MAX_SIZE);
358     memset (post_buffer + pre_pos, 1, MIN (r, BUFFER_SIZE - pre_pos));  /* To-be-synced segment */
359     packet = flow_packet_new_take_object (flow_segment_request_new (r), 0);
360     pre_pos += MIN (r, BUFFER_SIZE - pre_pos);
361
362     n_segments_remaining++;
363
364     test_print ("Write: Request %d bytes\n", r);
365   }
366   else
367   {
368     /* Write some data */
369
370     r = g_random_int_range (1, PACKET_MAX_SIZE);
371     r = MIN (r, BUFFER_SIZE - pre_pos);
372
373     g_assert (r > 0);
374
375     randomize_buffer (pre_buffer + pre_pos, r);
376     memset (post_buffer + pre_pos, 0, r);  /* Out-of-sync segment */
377     packet = flow_packet_new (FLOW_PACKET_FORMAT_BUFFER, pre_buffer + pre_pos, r);
378     pre_pos += r;
379
380     test_print ("Write: Write %d bytes\n", r);
381
382     n_packets_written++;
383
384     test_print ("Write: %d / %d packets\n", n_packets_written, TOTAL_EXPECTED_PACKETS);
385
386     if (n_packets_written >= TOTAL_EXPECTED_PACKETS)
387     {
388       /* Done writing */
389
390       test_print ("Done writing.");
391       flow_shunt_block_writes (shunt);
392       finished_writing = TRUE;
393
394       if (n_segments_remaining == 0 && !quitting_main_loop)
395       {
396         test_print (" No outstanding requests - quitting after short delay...\n");
397         quitting_main_loop = TRUE;
398         g_timeout_add (1000, (GSourceFunc) test_quit_main_loop, NULL);
399       }
400       else
401       {
402         test_print ("\n");
403       }
404     }
405   }
406
407   return packet;
408 }
409
410 static void
411 memcpy_to_be_synced_only (guchar *dest, const guchar *src, gint n)
412 {
413   gint i;
414
415   for (i = 0; i < n; i++)
416   {
417     if (*dest == 1)
418       *dest = *src;
419
420     src++;
421     dest++;
422   }
423 }
424
425 static void
426 read_random (FlowShunt *shunt, FlowPacket *packet, gpointer data)
427 {
428   guint    packet_size;
429   gpointer packet_data;
430
431   if (data != shunt)
432     test_end (TEST_RESULT_FAILED, "read callback user_data does not match");
433
434   if (!packet)
435     test_end (TEST_RESULT_FAILED, "got read with NULL packet");
436
437   packet_data = flow_packet_get_data (packet);
438   if (!packet_data)
439     test_end (TEST_RESULT_FAILED, "got NULL packet data");
440
441   if (flow_packet_get_format (packet) == FLOW_PACKET_FORMAT_OBJECT)
442   {
443     if (FLOW_IS_DETAILED_EVENT (packet_data))
444     {
445       FlowDetailedEvent *detailed_event = packet_data;
446
447       if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_BEGIN))
448       {
449         test_print ("Read: Beginning of stream marker\n");
450
451         if (started_reading)
452           test_end (TEST_RESULT_FAILED, "got multiple beginning-of-stream markers");
453
454         started_reading = TRUE;
455       }
456       else if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_SEGMENT_BEGIN))
457       {
458         test_print ("Read: Beginning of segment marker\n");
459
460         if (!started_reading)
461           test_end (TEST_RESULT_FAILED, "segment started before stream");
462
463         if (finished_reading)
464           test_end (TEST_RESULT_FAILED, "segment started after stream end");
465
466         if (in_segment)
467           test_end (TEST_RESULT_FAILED, "got nested beginning-of-segment markers");
468
469         in_segment = TRUE;
470       }
471       else if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_END))
472       {
473         test_print ("Read: End of stream marker\n");
474
475         if (!started_reading)
476           test_end (TEST_RESULT_FAILED, "stream ended without starting");
477
478         if (finished_reading)
479           test_end (TEST_RESULT_FAILED, "got multiple end-of-stream markers");
480
481         if (in_segment)
482           test_end (TEST_RESULT_FAILED, "stream ended inside an open segment");
483       }
484       else if (flow_detailed_event_matches (detailed_event, FLOW_STREAM_DOMAIN, FLOW_STREAM_SEGMENT_END))
485       {
486         test_print ("Read: End of segment marker\n");
487
488         if (!started_reading)
489           test_end (TEST_RESULT_FAILED, "segment end before stream start");
490
491         if (finished_reading)
492           test_end (TEST_RESULT_FAILED, "segment end after stream end");
493
494         if (!in_segment)
495           test_end (TEST_RESULT_FAILED, "end of segment, but no segment open");
496
497         in_segment = FALSE;
498         n_segments_remaining--;
499       }
500     }
501     else if (FLOW_IS_POSITION (packet_data))
502     {
503       FlowPosition *position = packet_data;
504
505       if (flow_position_get_anchor (position) != FLOW_OFFSET_ANCHOR_BEGIN)
506         test_end (TEST_RESULT_FAILED, "got relative position from shunt");
507
508       post_pos = flow_position_get_offset (position);
509
510       test_print ("Read: Seek to %d\n", post_pos);
511     }
512     else if (!FLOW_IS_EVENT (packet_data))
513     {
514       test_end (TEST_RESULT_FAILED, "got a weird object from read shunt");
515     }   
516   }
517   else if (flow_packet_get_format (packet) == FLOW_PACKET_FORMAT_BUFFER)
518   {
519     packet_size = flow_packet_get_size (packet);
520     if (packet_size == 0)
521       test_end (TEST_RESULT_FAILED, "got zero-size buffer packet");
522
523     test_print ("Read: %d byte packet at offset %d\n", packet_size, post_pos);
524
525     if (!started_reading)
526       test_end (TEST_RESULT_FAILED, "got data before start of stream");
527
528     if (finished_reading)
529       test_end (TEST_RESULT_FAILED, "got data after end of stream");
530
531     if (!in_segment)
532       test_end (TEST_RESULT_FAILED, "got data outside segment");
533
534     if (post_pos + packet_size > BUFFER_SIZE)
535       test_end (TEST_RESULT_FAILED, "read out of bounds data");
536
537     memcpy_to_be_synced_only ((guchar *) post_buffer + post_pos, packet_data, packet_size);
538     post_pos += packet_size;
539   }
540   else
541   {
542     test_end (TEST_RESULT_FAILED, "got unknown packet format");
543   }
544
545   if (finished_writing && n_segments_remaining == 0 && !quitting_main_loop)
546   {
547     /* Done reading. Wait a little bit to see if shunt will generate any bogus events. */
548
549     test_print ("Done reading. Quitting after short delay...\n");
550     quitting_main_loop = TRUE;
551     g_timeout_add (1000, (GSourceFunc) test_quit_main_loop, NULL);
552   }
553
554   flow_packet_free (packet);
555 }
556
557 static FlowPacket *
558 write_full_request (FlowShunt *shunt, gpointer data)
559 {
560   FlowPacket      *packet;
561   static gboolean  wrote_seek = FALSE;
562
563   if (!wrote_seek)
564   {
565     /* 1. Seek to beginning of file */
566     packet = flow_packet_new_take_object (flow_position_new (FLOW_OFFSET_ANCHOR_BEGIN, 0), 0);
567     wrote_seek = TRUE;
568   }
569   else
570   {
571     /* 2. Request read-to-EOF, no more writes */
572     packet = flow_packet_new_take_object (flow_segment_request_new (-1), 0);
573     flow_shunt_set_write_func (shunt, NULL, NULL);
574   }
575
576   return packet;
577 }
578
579 static void
580 verify_buffer_sparse (gconstpointer pre_buf, gconstpointer post_buf, gint len_bytes)
581 {
582   gint i;
583   gint n_similar = 0;
584
585   for (i = 0; i < len_bytes; i++)
586   {
587     const guchar *p0 = pre_buf + i;
588     const guchar *p1 = post_buf + i;
589
590     if (*p1 == 0)
591     {
592       /* Known out of sync segment */
593     }
594     else if (*p1 == 1)
595     {
596       /* To be synced segment - this means we didn't process a read */
597       test_print ("Sparse verify: Incomplete read starting at %d\n", i);
598       test_end (TEST_RESULT_FAILED, "missed one or more reads");
599     }
600     else
601     {
602       if (*p0 != *p1)
603       {
604         test_print ("Sparse verify: Differing data starting at %d\n", i);
605         test_end (TEST_RESULT_FAILED, "corrupt post-I/O data (sparse)");
606       }
607
608       n_similar++;
609     }
610   }
611
612   test_print ("Similar bytes after random I/O: %d out of %d\n", n_similar, len_bytes);
613 }
614
615 static void
616 verify_buffer_full (gconstpointer pre_buf, gconstpointer post_buf, gint len_bytes)
617 {
618   gint i;
619
620   for (i = 0; i < len_bytes; i++)
621   {
622     const gchar *p0 = pre_buf + i;
623     const gchar *p1 = post_buf + i;
624
625     if (*p0 != *p1)
626     {
627       test_print ("Full verify: Differing data starting at %d\n", i);
628       test_end (TEST_RESULT_FAILED, "corrupt post-I/O data (full)");
629     }
630   }
631 }
632
633 static void
634 test_run (void)
635 {
636   gchar *test_file_name;
637
638   g_random_set_seed (time (NULL));
639
640   /* Set up a buffer with random data */
641
642   pre_buffer = g_malloc (BUFFER_SIZE);
643   randomize_buffer (pre_buffer, BUFFER_SIZE);
644
645   post_buffer = g_malloc0 (BUFFER_SIZE);
646
647   test_print ("Probability of pause is %d out of %d\n", PAUSE_PROBABILITY, PROBABILITY_MULTIPLIER);
648
649   /* Create and write out scratch file */
650
651   pre_pos            = 0;
652   finished_reading   = FALSE;
653   finished_writing   = FALSE;
654   reads_are_blocked  = FALSE;
655   writes_are_blocked = FALSE;
656
657   test_file_name = g_strdup_printf ("test-shunt-data-%08x", g_random_int ());
658
659   global_shunt = flow_create_file (test_file_name, FLOW_READ_ACCESS | FLOW_WRITE_ACCESS, TRUE,
660                                    FLOW_READ_ACCESS | FLOW_WRITE_ACCESS,
661                                    FLOW_NO_ACCESS,
662                                    FLOW_NO_ACCESS);
663
664   flow_shunt_set_write_func (global_shunt, write_stream, global_shunt);
665
666   test_run_main_loop ();
667
668   /* Do random I/O on file and validate results */
669
670   finished_reading = FALSE;
671   finished_writing = FALSE;
672   pre_pos  = BUFFER_SIZE;
673   post_pos = BUFFER_SIZE;
674   flow_shunt_set_read_func  (global_shunt, read_random,  global_shunt);
675   flow_shunt_set_write_func (global_shunt, write_random, global_shunt);
676   flow_shunt_unblock_writes (global_shunt);
677
678   test_run_main_loop ();
679
680   verify_buffer_sparse (pre_buffer, post_buffer, BUFFER_SIZE);
681
682   /* Re-read entire file and validate results */
683
684   finished_reading = FALSE;
685   finished_writing = FALSE;
686   pre_pos  = BUFFER_SIZE;
687   post_pos = BUFFER_SIZE;
688   flow_shunt_set_read_func  (global_shunt, read_stream,        global_shunt);
689   flow_shunt_set_write_func (global_shunt, write_full_request, global_shunt);
690   flow_shunt_unblock_writes (global_shunt);
691
692   test_run_main_loop ();
693
694   verify_buffer_full (pre_buffer, post_buffer, BUFFER_SIZE);
695
696   /* Cleanup */
697
698   flow_shunt_destroy (global_shunt);
699   unlink (test_file_name);
700   g_free (test_file_name);
701   g_free (pre_buffer);
702   g_free (post_buffer);
703 }
Note: See TracBrowser for help on using the browser.