source: rtems/testsuites/fstests/fsrdwr/init.c @ b16b0aa9

4.115
Last change on this file since b16b0aa9 was b16b0aa9, checked in by Sebastian Huber <sebastian.huber@…>, on 05/11/12 at 11:19:45

fstests/fsrdwr: Add block read/write test case

  • Property mode set to 100644
File size: 16.4 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2011.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
8 *
9 *  $Id$
10 */
11
12#ifdef HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16#include <sys/stat.h>
17#include <string.h>
18#include <stdlib.h>
19#include <fcntl.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdint.h>
23#include <memory.h>
24#include <unistd.h>
25
26#include "fstest.h"
27#include "pmacros.h"
28
29static const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
30
31static const char databuf [] =
32  "Happy days are here again.  Happy days are here again.1Happy "
33  "days are here again.2Happy days are here again.3Happy days are here again."
34  "4Happy days are here again.5Happy days are here again.6Happy days are here "
35  "again.7Happy days are here again.";
36
37static const size_t len = sizeof (databuf) - 1;
38
39static void
40test_case_enter (const char *wd)
41{
42  int status;
43
44  printf ("test case: %s\n", wd);
45
46  status = mkdir (wd, mode);
47  rtems_test_assert (status == 0);
48
49  status = chdir (wd);
50  rtems_test_assert (status == 0);
51}
52
53static void
54test_case_leave (void)
55{
56  int status;
57
58  status = chdir ("..");
59  rtems_test_assert (status == 0);
60}
61
62static void
63read_write_test (void)
64{
65
66  int fd;
67  int status;
68  char *name01 = "name01";
69  char *name02 = "name02";
70  struct stat statbuf;
71  char *readbuf;
72  off_t pos = 0;
73
74  int n;
75
76  test_case_enter (__func__);
77
78  /*
79   * Create an empty file
80   */
81  fd = open (name01, O_CREAT | O_WRONLY, mode);
82  status = close (fd);
83  rtems_test_assert (status == 0);
84  /*
85   * Verify the empty file
86   */
87  status = stat (name01, &statbuf);
88  rtems_test_assert (status == 0);
89
90  rtems_test_assert (S_ISREG (statbuf.st_mode));
91  rtems_test_assert (statbuf.st_size == 0);
92
93  /*
94   * Write data to the empty file
95   */
96  fd = open (name01, O_WRONLY);
97  rtems_test_assert (fd >= 0);
98
99  n = write (fd, databuf, len);
100  rtems_test_assert (n == len);
101  status = close (fd);
102  rtems_test_assert (status == 0);
103
104  status = stat (name01, &statbuf);
105  rtems_test_assert (status == 0);
106  rtems_test_assert (S_ISREG (statbuf.st_mode));
107  rtems_test_assert (statbuf.st_size == len);
108
109  /*
110   * Read the data from the file
111   */
112  readbuf = (char *) malloc (len + 1);
113  rtems_test_assert (readbuf);
114
115  fd = open (name01, O_RDONLY);
116  rtems_test_assert (fd >= 0);
117  n = read (fd, readbuf, len);
118  rtems_test_assert (n == len);
119  rtems_test_assert (!strncmp (databuf, readbuf, len));
120  status = close (fd);
121  rtems_test_assert (status == 0);
122
123  /*
124   * Open the file using O_APPEND and write the data
125   */
126  memset (readbuf, 0, len + 1);
127  fd = open (name01, O_WRONLY | O_APPEND);
128  n = write (fd, databuf, len);
129  rtems_test_assert (n == len);
130  pos = lseek (fd, 0, SEEK_CUR);
131  rtems_test_assert (pos == 2 * len);
132  pos = lseek (fd, 0, SEEK_SET);
133  rtems_test_assert (pos == 0);
134  n = write (fd, databuf, len);
135  rtems_test_assert (n == len);
136  pos = lseek (fd, 0, SEEK_CUR);
137  rtems_test_assert (pos == 3 * len);
138  status = close (fd);
139  rtems_test_assert (status == 0);
140
141  /*
142   * Read the data and verify it
143   */
144  fd = open (name01, O_RDONLY);
145  rtems_test_assert (fd >= 0);
146  n = read (fd, readbuf, len);
147  rtems_test_assert (n == len);
148  rtems_test_assert (!strncmp (databuf, readbuf, len));
149  n = read (fd, readbuf, len);
150  rtems_test_assert (n == len);
151  rtems_test_assert (!strncmp (databuf, readbuf, len));
152  n = read (fd, readbuf, len);
153  rtems_test_assert (n == len);
154  rtems_test_assert (!strncmp (databuf, readbuf, len));
155  status = close (fd);
156  rtems_test_assert (status == 0);
157
158  /*
159   * Open the file using O_RDWR
160   */
161  memset (readbuf, 0, len + 1);
162
163  fd = open (name01, O_RDWR);
164  n = write (fd, databuf, len);
165  rtems_test_assert (n == len);
166  pos = lseek (fd, 0, SEEK_CUR);
167  rtems_test_assert (pos == len);
168  n = read (fd, readbuf, len);
169  rtems_test_assert (n == len);
170  rtems_test_assert (!strncmp (databuf, readbuf, len));
171  pos = lseek (fd, 0, SEEK_CUR);
172  rtems_test_assert (pos == 2 * len);
173  status = close (fd);
174  rtems_test_assert (status == 0);
175
176  /*
177   * Open the file using O_TRUNC
178   */
179
180  fd = open (name01, O_WRONLY | O_TRUNC);
181  status = close (fd);
182  rtems_test_assert (status == 0);
183
184  /*
185   * Verify if the length is zero
186   */
187  status = stat (name01, &statbuf);
188  rtems_test_assert (status == 0);
189  rtems_test_assert (S_ISREG (statbuf.st_mode));
190  rtems_test_assert (statbuf.st_size == 0);
191
192  /*
193   * Open a directory
194   */
195  status = mkdir (name02, mode);
196  rtems_test_assert (status == 0);
197  fd = open (name02, O_RDONLY);
198  rtems_test_assert (fd >= 0);
199
200  status = close (fd);
201  rtems_test_assert (status == 0);
202
203  free (readbuf);
204
205  test_case_leave ();
206}
207
208static void
209truncate_test03 (void)
210{
211
212  int fd;
213  int status;
214  char *name01 = "name01";
215  struct stat statbuf;
216
217  char data;
218  int n;
219  int i;
220
221  char *readbuf;
222  off_t good_size = 100;
223
224  test_case_enter (__func__);
225
226  /*
227   * Create an empty file
228   */
229  fd = creat (name01, mode);
230  status = close (fd);
231  rtems_test_assert (status == 0);
232
233
234  /*
235   * Truncate it to a valid size
236   */
237  status = truncate (name01, good_size);
238  rtems_test_assert (status == 0);
239  /*
240   * Verify the size and the data
241   */
242  status = stat (name01, &statbuf);
243  rtems_test_assert (status == 0);
244  rtems_test_assert (good_size == statbuf.st_size);
245
246  fd = open (name01, O_RDONLY);
247  while ((n = read (fd, &data, 1)) > 0) {
248    rtems_test_assert (data == 0);
249  }
250
251  status = close (fd);
252  rtems_test_assert (status == 0);
253
254  /*
255   * Fill a file with data
256   */
257  fd = open (name01, O_WRONLY);
258  rtems_test_assert (fd >= 0);
259  n = write (fd, databuf, len);
260  rtems_test_assert (n == len);
261
262  /*
263   * Truncate it to the half size
264   */
265
266  status = truncate (name01, len / 2);
267  status = truncate (name01, len);
268
269  /*
270   * verify the data
271   */
272  readbuf = (char *) malloc (len / 2);
273  rtems_test_assert (readbuf);
274  fd = open (name01, O_RDONLY);
275  rtems_test_assert (fd >= 0);
276  n = read (fd, readbuf, len / 2);
277  rtems_test_assert (n == len / 2);
278  rtems_test_assert (!strncmp (databuf, readbuf, len / 2));
279  n = read (fd, readbuf, len / 2);
280  rtems_test_assert (n == len / 2);
281  for (i = 0; i < len / 2; i++) {
282    rtems_test_assert (readbuf[i] == 0);
283  }
284  status = close (fd);
285  rtems_test_assert (status == 0);
286
287  /*
288   * Go back to parent directory
289   */
290  status = chdir ("..");
291  rtems_test_assert (status == 0);
292}
293
294static void
295lseek_test (void)
296{
297  int fd;
298  int status;
299  const char *name01 = "test_name01";
300  struct stat statbuf;
301
302  ssize_t n;
303  int i;
304
305  off_t pos;
306  ssize_t total_written = 0;
307
308  char *readbuf;
309
310  test_case_enter (__func__);
311
312  /*
313   * Create a file and fill with the data.
314   */
315  puts ("Create a new file");
316  fd = creat (name01, mode);
317  rtems_test_assert (fd >= 0);
318
319  pos = lseek (fd, 0, SEEK_CUR);
320  rtems_test_assert (pos == 0);
321
322  pos = lseek (fd, 0, SEEK_END);
323  rtems_test_assert (pos == 0);
324
325  pos = lseek (fd, 0, SEEK_SET);
326  rtems_test_assert (pos == 0);
327
328
329  printf ("Writing %zd bytes to file\n", len * 10);
330  for (i = 0; i < 10; i++) {
331    n = write (fd, databuf, len);
332    rtems_test_assert (n == (ssize_t) len);
333    total_written += n;
334  }
335  printf ("Successfully wrote %d\n", total_written);
336
337  /*
338   * Check the current position
339   */
340  puts ("Check the current position");
341  pos = lseek (fd, 0, SEEK_CUR);
342  rtems_test_assert (pos == total_written);
343
344  pos = lseek (fd, 0, SEEK_END);
345  rtems_test_assert (pos == total_written);
346
347  /*
348   * ftruncate shall not change the posistion
349   */
350  status = ftruncate (fd, total_written + 1);
351  rtems_test_assert (status == 0);
352
353  pos = lseek (fd, 0, SEEK_CUR);
354  rtems_test_assert (pos == total_written);
355
356  pos = lseek (fd, 0, SEEK_END);
357  printf ("%jd\n", (intmax_t) pos);
358  rtems_test_assert (pos == total_written + 1);
359
360  status = ftruncate (fd, total_written);
361  rtems_test_assert (status == 0);
362
363  pos = lseek (fd, 0, SEEK_CUR);
364  rtems_test_assert (pos == total_written + 1);
365
366  /*
367   * Check the file size
368   */
369  status = fstat (fd, &statbuf);
370  rtems_test_assert (status == 0);
371  rtems_test_assert (statbuf.st_size == total_written);
372
373  status = ftruncate (fd, total_written);
374  rtems_test_assert (status == 0);
375
376  status = close (fd);
377  rtems_test_assert (status == 0);
378
379  /*
380   * Open the file with O_RDONLY and check the lseek
381   */
382  readbuf = (char *) malloc (len);
383  fd = open (name01, O_RDONLY);
384  pos = lseek (fd, len, SEEK_CUR);
385  rtems_test_assert (pos == len);
386  n = read (fd, readbuf, len);
387  rtems_test_assert (n == len);
388  rtems_test_assert (!strncmp (databuf, readbuf, len));
389
390  pos = lseek (fd, len, SEEK_CUR);
391  rtems_test_assert (pos == 3 * len);
392  n = read (fd, readbuf, len);
393  rtems_test_assert (n == len);
394  rtems_test_assert (!strncmp (databuf, readbuf, len));
395
396  pos = lseek (fd, -(off_t) len, SEEK_CUR);
397  rtems_test_assert (pos == 3 * len);
398  n = read (fd, readbuf, len);
399  rtems_test_assert (n == len);
400  rtems_test_assert (!strncmp (databuf, readbuf, len));
401
402  pos = lseek (fd, 4 * len, SEEK_SET);
403  n = read (fd, readbuf, len);
404  rtems_test_assert (n == len);
405  rtems_test_assert (!strncmp (databuf, readbuf, len));
406
407
408  pos = lseek (fd, 10, SEEK_SET);
409  n = read (fd, readbuf, len);
410  rtems_test_assert (n == len);
411  rtems_test_assert (strncmp (databuf, readbuf, len) != 0);
412
413  pos = lseek (fd, -(off_t) len, SEEK_END);
414  n = read (fd, readbuf, 2 * len);
415  rtems_test_assert (n == len);
416  rtems_test_assert (!strncmp (databuf, readbuf, len));
417
418  status = close (fd);
419  rtems_test_assert (status == 0);
420
421  /*
422   * Open the file withe O_RDWR and check the lseek
423   */
424
425  fd = open (name01, O_RDWR);
426
427  pos = lseek (fd, len, SEEK_CUR);
428  rtems_test_assert (pos == len);
429  n = read (fd, readbuf, len);
430  rtems_test_assert (n == len);
431  rtems_test_assert (!strncmp (databuf, readbuf, len));
432
433  pos = lseek (fd, len, SEEK_CUR);
434  rtems_test_assert (pos == 3 * len);
435  n = read (fd, readbuf, len);
436  rtems_test_assert (n == len);
437  rtems_test_assert (!strncmp (databuf, readbuf, len));
438
439  pos = lseek (fd, -(off_t) len, SEEK_CUR);
440  rtems_test_assert (pos == 3 * len);
441  n = read (fd, readbuf, len);
442  rtems_test_assert (n == len);
443  rtems_test_assert (!strncmp (databuf, readbuf, len));
444
445  pos = lseek (fd, 4 * len, SEEK_SET);
446  n = read (fd, readbuf, len);
447  rtems_test_assert (n == len);
448  rtems_test_assert (!strncmp (databuf, readbuf, len));
449
450  /*
451   * Go to the wrong position, so the data is not the same
452   */
453  pos = lseek (fd, 10, SEEK_SET);
454  n = read (fd, readbuf, len);
455  rtems_test_assert (n == len);
456  rtems_test_assert (strncmp (databuf, readbuf, len) != 0);
457
458  /*
459   * Use SEEK_END
460   */
461  pos = lseek (fd, -(off_t) len, SEEK_END);
462  n = read (fd, readbuf, 2 * len);
463  rtems_test_assert (n == len);
464  rtems_test_assert (!strncmp (databuf, readbuf, len));
465
466  memset (readbuf, 0, len);
467
468  /*
469   * Write the zero to the end of file.
470   */
471  pos = lseek (fd, -(off_t) len, SEEK_END);
472  rtems_test_assert (pos == (off_t) total_written - (off_t) len);
473  n = write (fd, readbuf, len);
474  rtems_test_assert (n == len);
475  /*
476   * Verify it
477   */
478  pos = lseek (fd, (off_t) total_written - (off_t) len, SEEK_SET);
479  n = read (fd, readbuf, len);
480  rtems_test_assert (n == len);
481  for (i = 0; i < n; i++) {
482    rtems_test_assert (readbuf[i] == 0);
483  }
484
485  /*
486   * Write the zero to the beginning of file.
487   */
488  pos = lseek (fd, -(off_t) total_written, SEEK_END);
489  rtems_test_assert (pos == 0);
490  n = write (fd, readbuf, len);
491  rtems_test_assert (n == len);
492
493  /*
494   * Verify it
495   */
496
497  pos = lseek (fd, 0, SEEK_SET);
498  n = read (fd, readbuf, len);
499  rtems_test_assert (n == len);
500  for (i = 0; i < n; i++) {
501    rtems_test_assert (readbuf[i] == 0);
502  }
503
504  n = read (fd, readbuf, len);
505  rtems_test_assert (n == len);
506  rtems_test_assert (strncmp (databuf, readbuf, len) == 0);
507  /*
508   * Call ftruncate to decrease the file and the position not change
509   */
510  status = ftruncate (fd, len);
511  rtems_test_assert (status == 0);
512  pos = lseek (fd, 0, SEEK_CUR);
513  rtems_test_assert (pos == len * 2);
514
515  status = close (fd);
516  rtems_test_assert (status == 0);
517
518  test_case_leave ();
519}
520
521static void
522truncate_to_zero (void)
523{
524  int fd;
525  ssize_t n;
526  int status;
527  off_t pos;
528
529  test_case_enter (__func__);
530
531  fd = creat ("file", mode);
532  rtems_test_assert (fd >= 0);
533
534  n = write (fd, databuf, len);
535  rtems_test_assert (n == (ssize_t) len);
536
537  pos = lseek (fd, 0, SEEK_END);
538  rtems_test_assert (pos == len);
539
540  status = ftruncate (fd, 0);
541  rtems_test_assert (status == 0);
542
543  pos = lseek (fd, 0, SEEK_END);
544  rtems_test_assert (pos == 0);
545
546  status = close (fd);
547  rtems_test_assert (status == 0);
548
549  test_case_leave ();
550}
551
552static void
553random_fill (char *dst, size_t n)
554{
555  static uint32_t u = 0x12345678;
556  uint32_t v = u;
557  uint32_t w;
558  size_t i = 0;
559  int j = 0;
560
561  while (i < n) {
562    if (j == 0) {
563      v *= 1664525;
564      v += 1013904223;
565      w = v;
566    } else {
567      w >>= 8;
568    }
569
570    dst [i] = (char) w;
571
572    ++i;
573    j = (j + 1) % 4;
574  }
575
576  u = v;
577}
578
579static void
580block_rw_lseek (int fd, size_t pos)
581{
582  off_t actual;
583
584  actual = lseek (fd, pos, SEEK_SET);
585  rtems_test_assert (actual == pos);
586}
587
588static void
589block_rw_write (int fd, char *out, size_t pos, size_t size)
590{
591  ssize_t n;
592
593  random_fill (out + pos, size);
594
595  block_rw_lseek (fd, pos);
596
597  n = write (fd, out + pos, size);
598  rtems_test_assert (n == (ssize_t) size);
599}
600
601static void
602block_rw_write_cont (int fd, char *out, size_t *pos, size_t size)
603{
604  ssize_t n;
605
606  random_fill (out + *pos, size);
607
608  n = write (fd, out + *pos, size);
609  rtems_test_assert (n == (ssize_t) size);
610
611  *pos += size;
612}
613
614static void
615block_rw_check (int fd, const char *out, char *in, size_t size)
616{
617  ssize_t n;
618  off_t file_size;
619
620  file_size = lseek (fd, 0, SEEK_END);
621  rtems_test_assert (file_size == size);
622
623  block_rw_lseek (fd, 0);
624
625  n = read (fd, in, size);
626  rtems_test_assert (n == (ssize_t) size);
627
628  rtems_test_assert (memcmp (out, in, size) == 0);
629}
630
631static void
632block_rw_prepare (const char *t, int fd, char *out, size_t size)
633{
634  int status;
635
636  printf ("test case: %s\n", t);
637
638  memset (out, 0, size);
639
640  status = ftruncate (fd, 0);
641  rtems_test_assert (status == 0);
642
643  block_rw_lseek (fd, 0);
644}
645
646static void
647block_rw_case_0 (int fd, size_t block_size, char *out, char *in)
648{
649  const size_t size = 3 * block_size + 1;
650
651  block_rw_prepare (__func__, fd, out, size);
652  block_rw_write (fd, out, 0, size);
653  block_rw_check (fd, out, in, size);
654}
655
656static void
657block_rw_case_1 (int fd, size_t block_size, char *out, char *in)
658{
659  const size_t size = 2 * block_size;
660
661  block_rw_prepare (__func__, fd, out, size);
662  block_rw_write (fd, out, block_size, block_size);
663  block_rw_check (fd, out, in, size);
664}
665
666static void
667block_rw_case_2 (int fd, size_t block_size, char *out, char *in)
668{
669  const size_t size = (5 * block_size) / 2;
670
671  block_rw_prepare (__func__, fd, out, size);
672  block_rw_write (fd, out, (3 * block_size) / 2, block_size);
673  block_rw_check (fd, out, in, size);
674}
675
676static void
677block_rw_case_3 (int fd, size_t block_size, char *out, char *in)
678{
679  const size_t size = 2 * block_size;
680
681  block_rw_prepare (__func__, fd, out, size);
682  block_rw_write (fd, out, block_size, block_size / 3);
683  block_rw_write (fd, out, 2 * block_size - block_size / 3, block_size / 3);
684  block_rw_check (fd, out, in, size);
685}
686
687static void
688block_rw_case_4 (int fd, size_t block_size, char *out, char *in)
689{
690  const size_t size = 3 * block_size + 1;
691  size_t pos = 0;
692
693  block_rw_prepare (__func__, fd, out, size);
694  block_rw_write_cont (fd, out, &pos, block_size);
695  block_rw_write_cont (fd, out, &pos, block_size / 2);
696  block_rw_write_cont (fd, out, &pos, block_size);
697  block_rw_write_cont (fd, out, &pos, block_size / 2);
698  block_rw_write_cont (fd, out, &pos, 1);
699  block_rw_check (fd, out, in, size);
700}
701
702static void
703block_read_and_write (void)
704{
705  int fd;
706  struct stat st;
707  int status;
708  size_t block_size;
709  size_t size;
710  char *out;
711  char *in;
712
713  test_case_enter (__func__);
714
715  fd = open ("file", O_RDWR | O_CREAT | O_TRUNC, mode);
716  rtems_test_assert (fd >= 0);
717
718  status = fstat (fd, &st);
719  rtems_test_assert (status == 0);
720
721  block_size = st.st_blksize;
722  size = 3 * block_size + 1;
723
724  out = malloc (size);
725  rtems_test_assert (out != NULL);
726
727  in = malloc (size);
728  rtems_test_assert (in != NULL);
729
730  block_rw_case_0 (fd, block_size, out, in);
731  block_rw_case_1 (fd, block_size, out, in);
732  block_rw_case_2 (fd, block_size, out, in);
733  block_rw_case_3 (fd, block_size, out, in);
734  block_rw_case_4 (fd, block_size, out, in);
735
736  status = close (fd);
737  rtems_test_assert (status == 0);
738
739  free (out);
740  free (in);
741
742  test_case_leave ();
743}
744
745void
746test (void)
747{
748  read_write_test ();
749  lseek_test ();
750  truncate_test03 ();
751  truncate_to_zero ();
752  block_read_and_write ();
753}
Note: See TracBrowser for help on using the repository browser.