More filesys tests.
[pintos-anon] / grading / filesys / fslib.c
1 #include "fslib.h"
2 #include <random.h>
3 #include <stdarg.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <syscall.h>
7
8 bool quiet = false;
9
10 static void
11 vmsg (const char *format, va_list args) 
12 {
13   printf ("(%s) ", test_name);
14   vprintf (format, args);
15 }
16
17 void
18 msg (const char *format, ...) 
19 {
20   va_list args;
21
22   if (quiet)
23     return;
24   va_start (args, format);
25   vmsg (format, args);
26   printf ("\n");
27   va_end (args);
28 }
29
30 void
31 fail (const char *format, ...) 
32 {
33   va_list args;
34
35   va_start (args, format);
36   vmsg (format, args);
37   printf (": FAILED\n");
38   va_end (args);
39
40   exit (1);
41 }
42
43 void
44 check (bool success, const char *format, ...) 
45 {
46   va_list args;
47
48   va_start (args, format);
49   if (success) 
50     {
51       if (!quiet) 
52         {
53           vmsg (format, args); 
54           printf ("\n"); 
55         }
56     }
57   else 
58     {
59       vmsg (format, args); 
60       printf (": FAILED\n");
61       exit (1);
62     }
63   va_end (args);
64 }
65
66 void 
67 seq_test (const char *filename, void *buf, size_t size, size_t initial_size,
68           size_t (*block_size_func) (void),
69           void (*check_func) (int fd, long ofs)) 
70 {
71   size_t ofs;
72   int fd;
73   
74   random_bytes (buf, size);
75   check (create (filename, initial_size), "create \"%s\"", filename);
76   check ((fd = open (filename)) > 1, "open \"%s\"", filename);
77
78   ofs = 0;
79   msg ("writing \"%s\"", filename);
80   while (ofs < size) 
81     {
82       size_t block_size = block_size_func ();
83       if (block_size > size - ofs)
84         block_size = size - ofs;
85
86       if (write (fd, buf + ofs, block_size) <= 0)
87         fail ("write %zu bytes at offset %zu in \"%s\" failed",
88               block_size, ofs, filename);
89
90       ofs += block_size;
91       if (check_func != NULL)
92         check_func (fd, ofs);
93     }
94   msg ("close \"%s\"", filename);
95   close (fd);
96   check_file (filename, buf, size);
97 }
98
99 static void
100 swap (void *a_, void *b_, size_t size) 
101 {
102   uint8_t *a = a_;
103   uint8_t *b = b_;
104   size_t i;
105
106   for (i = 0; i < size; i++) 
107     {
108       uint8_t t = a[i];
109       a[i] = b[i];
110       b[i] = t;
111     }
112 }
113
114 void
115 shuffle (void *buf_, size_t cnt, size_t size) 
116 {
117   char *buf = buf_;
118   size_t i;
119
120   for (i = 0; i < cnt; i++)
121     {
122       size_t j = i + random_ulong () % (cnt - i);
123       swap (buf + i * size, buf + j * size, size);
124     }
125 }
126
127 void
128 check_file (const char *filename, const void *buf_, size_t size) 
129 {
130   const char *buf = buf_;
131   size_t ofs;
132   char block[512];
133   int fd;
134
135   check ((fd = open (filename)) > 1, "open \"%s\" for verification", filename);
136
137   ofs = 0;
138   while (ofs < size)
139     {
140       size_t block_size = size - ofs;
141       if (block_size > sizeof block)
142         block_size = sizeof block;
143
144       if (read (fd, block, block_size) <= 0)
145         fail ("read %zu bytes at offset %zu in \"%s\" failed",
146               block_size, ofs, filename);
147
148       if (memcmp (buf + ofs, block, block_size))
149         {
150           if (block_size <= 512) 
151             {
152               printf ("Expected data:\n");
153               hex_dump (ofs, buf + ofs, block_size, false);
154               printf ("Actually read data:\n");
155               hex_dump (ofs, block, block_size, false); 
156             }
157           fail ("%zu bytes at offset %zu differed from expected",
158                 block_size, ofs);
159         }
160
161       ofs += block_size;
162     }
163
164   msg ("close \"%s\"", filename);
165   close (fd);
166 }