Tweak tests
[yaffs2.git] / direct / tests / nor_stress.c
1 #include "nor_stress.h"
2
3
4 #include "yaffsfs.h"
5 #include "yaffs_fsx.h"
6
7 #include <stdio.h>
8
9
10
11 #if 1
12 #define FSX_INIT(mount_pt) do{ if(interleave_fsx) yaffs_fsx_init(mount_pt); } while(0)
13 #define FSX_COMPLETE() do { if(interleave_fsx) yaffs_fsx_complete(); } while (0)
14
15 #define FSX() \
16 do { \
17   if((myrand() & 0x1) == 0){\
18      if(interleave_fsx) \
19         yaffs_fsx_do_op(); \
20   } \
21 } while(0)
22
23 #else
24 #define FSX_INIT(mount_point) do { } while(0)
25 #define FSX_COMPLETE() do { } while(0)
26 #define FSX() do { } while(0)
27 #endif
28
29
30 static unsigned powerUps;
31 static unsigned cycleStarts;
32 static unsigned cycleEnds;
33
34 static int interleave_fsx;
35
36 char fullPathName[100];
37 char fullPowerUpName[100];
38 char fullStartName[100];
39 char fullEndName[100];
40 char fullMainName[100];
41 char fullTempMainName[100];
42 char fullTempCounterName[100];
43
44
45 extern int random_seed;
46
47 int myrand(void) {
48   random_seed = random_seed * 1103515245 + 12345;
49   return((unsigned)(random_seed/65536) % 32768);
50 }
51
52 void MakeName(char *fullName,const char *prefix, const char *name)
53 {
54   strcpy(fullName,prefix);
55   strcat(fullName,"/");
56   strcat(fullName,name);
57 }
58
59
60 void MakeFullNames(const char *prefix)
61 {
62   MakeName(fullPathName,prefix,"");
63   MakeName(fullPowerUpName,prefix,"powerUps");
64   MakeName(fullStartName,prefix,"starts");
65   MakeName(fullEndName,prefix,"ends");
66   MakeName(fullMainName,prefix,"main");
67   MakeName(fullTempCounterName,prefix,"tmp-counter");
68   MakeName(fullTempMainName,prefix,"tmp-main");
69 }
70
71 static void FatalError(void)
72 {
73   printf("Integrity error\n");
74   while(1){
75    sleep(1);
76   }
77 }
78
79 static void UpdateCounter(const char *name, unsigned *val,  int initialise)
80 {
81   int inh=-1;
82   int outh=-1;
83   unsigned x[2];
84   int nread = 0;
85   int nwritten = 0;
86   
87   x[0] = x[1] = 0;
88   
89   if(initialise){
90     x[0] = 0; 
91     x[1] = 1;
92   } else {
93     inh = yaffs_open(name,O_RDONLY, S_IREAD | S_IWRITE);
94     if(inh >= 0){
95       nread = yaffs_read(inh,x,sizeof(x));
96       yaffs_close(inh);
97     }
98
99     if(nread != sizeof(x) ||
100        x[0] + 1 != x[1]){
101       printf("Error reading counter %s handle %d, x[0] %u x[1] %u last error %d\n",
102               name, inh, x[0], x[1],yaffsfs_GetLastError());
103       FatalError();
104               
105     }
106     x[0]++;
107     x[1]++;
108   }
109   
110   FSX();
111   outh = yaffs_open(fullTempCounterName, O_RDWR | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
112   if(outh >= 0){
113    FSX(); 
114     nwritten = yaffs_write(outh,x,sizeof(x));
115     FSX();
116     yaffs_close(outh);
117     FSX();
118     yaffs_rename(fullTempCounterName,name);
119     FSX();
120   }
121   
122   if(nwritten != sizeof(x)){
123       printf("Error writing counter %s handle %d, x[0] %u x[1] %u\n",
124               name, inh, x[0], x[1]);
125       FatalError();
126   }
127   
128   *val = x[0];
129   
130   printf("##\n"
131          "## Set counter %s to %u\n"
132          "##\n", name,x[0]);
133 }
134
135
136 static void dump_directory_tree_worker(const char *dname,int recursive)
137 {
138         yaffs_DIR *d;
139         yaffs_dirent *de;
140         struct yaffs_stat s;
141         char str[1000];
142                         
143         d = yaffs_opendir(dname);
144         
145         if(!d)
146         {
147                 printf("opendir failed\n");
148         }
149         else
150         {
151                 while((de = yaffs_readdir(d)) != NULL)
152                 {
153                         strcpy(str,dname);
154                         strcat(str,"/");
155                         strcat(str,de->d_name);
156                         
157                         yaffs_lstat(str,&s);
158                         
159                         printf("%s inode %d obj %x length %d mode %X ",str,s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);
160                         switch(s.st_mode & S_IFMT)
161                         {
162                                 case S_IFREG: printf("data file"); break;
163                                 case S_IFDIR: printf("directory"); break;
164                                 case S_IFLNK: printf("symlink -->");
165                                                           if(yaffs_readlink(str,str,100) < 0)
166                                                                 printf("no alias");
167                                                           else
168                                                                 printf("\"%s\"",str);    
169                                                           break;
170                                 default: printf("unknown"); break;
171                         }
172                         
173                         printf("\n");
174
175                         if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
176                                 dump_directory_tree_worker(str,1);
177                                 
178                         if(s.st_ino > 10000)
179                           FatalError();
180                                                         
181                 }
182                 
183                 yaffs_closedir(d);
184         }
185
186 }
187
188 static void dump_directory_tree(const char *dname)
189 {
190         dump_directory_tree_worker(dname,1);
191         printf("\n");
192         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
193 }
194
195
196
197
198 #define XX_SIZE 500
199
200 static unsigned xx[XX_SIZE];
201
202 static int yWriteFile(const char *fname, unsigned sz32)
203 {
204         int h;
205         int r;
206         int i;
207         unsigned checksum = 0;
208         
209         printf("Writing file %s\n",fname);
210
211         FSX();
212         h = yaffs_open(fname,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
213         FSX();
214
215         if(h < 0){
216                 printf("could not open file %s\n",fname);
217                 return h;
218         }
219
220         xx[0] = sz32;
221         checksum ^= xx[0];
222
223         if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
224                 goto WRITE_ERROR;
225         }
226         FSX();
227         while(sz32> 0){
228                 for(i = 0; i < XX_SIZE; i++){
229                   xx[i] = sz32 + i;
230                   checksum ^= xx[i];
231                 }
232                 
233                 FSX();
234                 if((r = yaffs_write(h,xx,sizeof(xx))) != sizeof(xx)){
235                         goto WRITE_ERROR;
236                 }
237                 sz32--;
238         }
239
240         xx[0] = checksum;
241         FSX();
242         if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
243                 goto WRITE_ERROR;
244         }
245         
246         FSX();
247         yaffs_close(h);
248         return 0;
249
250 WRITE_ERROR:
251         printf("ywrite error at position %d\n",(int)yaffs_lseek(h,0,SEEK_END));
252         yaffs_close(h);
253         return -1;
254         
255 }
256
257 static int yVerifyFile(const char *fName)
258 {
259         unsigned checksum = 0;
260         unsigned totalSize;
261         unsigned sz32;
262         unsigned recordedSize = 0;
263         int r;
264         int h;
265         int i;
266         int retval = 0;
267
268
269         printf("Verifying file %s\n",fName);
270                 
271         h = yaffs_open(fName, O_RDONLY,S_IREAD | S_IWRITE);
272
273         if(h < 0){
274                 printf("could not open file %s\n",fName);
275                 return -1;
276         }
277
278         totalSize = yaffs_lseek(h,0,SEEK_END);
279         yaffs_lseek(h,0,SEEK_SET);
280
281         r = yaffs_read(h,&sz32,sizeof(sz32));
282
283         if(r != sizeof(sz32)){
284                 printf("reading size failed ... returned %d\n",r);
285                 yaffs_close(h);
286                 return -1;
287         }
288         
289         recordedSize = sz32 * sizeof(xx) + 8;
290
291         printf("verify %s: file size is %d, recorded size is %d\n", fName, totalSize, recordedSize);
292         if(totalSize != recordedSize){
293                 printf("!!!!!!!!!!!!!!!!!!!!!!!!file size is wrong, should be %d, is %d\n", recordedSize,totalSize);
294                 yaffs_close(h);
295                 return -1;
296         }
297
298         checksum ^= sz32;
299
300
301         while(sz32 > 0){
302                 r = yaffs_read(h,xx,sizeof(xx));
303                 if(r != sizeof(xx)){
304                         printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
305                         yaffs_close(h);
306                         return -1;
307                 }
308                 for(i = 0; i < XX_SIZE; i++)
309                   checksum ^= xx[i];
310                 sz32--;
311         }
312         r = yaffs_read(h,xx,sizeof(xx[0]));
313         if(r != sizeof(xx[0])){
314                 printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
315                 yaffs_close(h);
316                 return -1;
317         }
318         
319         checksum ^= xx[0];
320
321         if(checksum != 0){
322                 printf("!!!!!!!!!!!!!!!!!!!!! checksum failed\n");
323                 retval = -1;
324         } else
325                 printf("verified ok\n");
326         yaffs_close(h);
327
328         return retval;
329 }
330
331
332 static void DoUpdateMainFile(void)
333 {
334         int result;
335         int sz32;
336         sz32 = (myrand() % 1000)   + 20;
337         
338         result = yWriteFile(fullTempMainName,sz32);
339         FSX();
340         if(result)
341             FatalError();
342         yaffs_rename(fullTempMainName,fullMainName);
343         FSX();
344 }
345
346 static void DoVerifyMainFile(void)
347 {
348         int result;
349         result = yVerifyFile(fullMainName);
350         if(result)
351             FatalError();
352
353 }
354
355
356 void NorStressTestInitialise(const char *prefix)
357 {
358   MakeFullNames(prefix);
359   
360   UpdateCounter(fullPowerUpName,&powerUps,1);
361   UpdateCounter(fullStartName,&cycleStarts,1);
362   UpdateCounter(fullEndName,&cycleEnds,1);
363   UpdateCounter(fullPowerUpName,&powerUps,1);
364   DoUpdateMainFile();
365   DoVerifyMainFile();
366 }
367
368
369 void NorStressTestRun(const char *prefix, int n_cycles, int do_fsx)
370 {
371   interleave_fsx = do_fsx;
372   MakeFullNames(prefix);
373   FSX_INIT(prefix);
374     
375   dump_directory_tree(fullPathName);
376   
377   UpdateCounter(fullPowerUpName,&powerUps,0);
378   dump_directory_tree(fullPathName);
379   
380   while(n_cycles < 0 || n_cycles > 0){
381     if(n_cycles > 0)
382       n_cycles--;
383     UpdateCounter(fullStartName, &cycleStarts,0);
384     dump_directory_tree(fullPathName);
385     DoVerifyMainFile();
386     DoUpdateMainFile();
387     dump_directory_tree(fullPathName);
388   
389     UpdateCounter(fullEndName,&cycleEnds,0);
390     dump_directory_tree(fullPathName);
391   }
392   FSX_COMPLETE();
393 }