Fix unmatched temporary buffer allocations
[yaffs2.git] / direct / test-framework / stress_tests / stress_tester / yaffs_tester.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2018 Aleph One Ltd.
5  *
6  * Created by Timothy Manning <timothy@yaffs.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 /*
14  * yaffs_tester.c designed to stress test yaffs2 direct.
15  */
16
17
18 #include "yaffs_tester.h"
19 #include "shared.h"
20
21
22
23 int random_seed;
24 int simulate_power_failure = 0;
25
26
27 buffer message_buffer;  /*create  message_buffer */
28
29
30 int main(int argc, char *argv[]){       
31         
32         
33         init(YAFFS_TEST_DIR, YAFFS_MOUNT_DIR, argc, argv);
34         test(YAFFS_TEST_DIR);
35         yaffs_unmount(YAFFS_MOUNT_DIR);
36         return 0;
37 }
38
39
40
41 void init(char *yaffs_test_dir,char *yaffs_mount_dir,int argc, char *argv[]){
42         char output=0;
43         int x=0;
44         int seed=-1;
45         FILE *log_handle;
46         /*these variables are already set to zero, but it is better not to take chances*/
47         message_buffer.head=0;                           
48         message_buffer.tail=0;
49
50
51         log_handle=fopen(LOG_FILE,"w");
52         if (log_handle!=NULL){
53                 fputs("log file for yaffs tester\n",log_handle);
54                 fclose(log_handle);
55         }
56         add_to_buffer(&message_buffer,"welcome to the yaffs tester",MESSAGE_LEVEL_BASIC_TASKS,PRINT);/* print boot up message*/ 
57         yaffs_start_up();
58         yaffs_mount(yaffs_mount_dir);
59         for (x=0;x<argc;x++){
60 //              add_to_buffer(&message_buffer,"argv ",MESSAGE_LEVEL_BASIC_TASKS,PRINT);
61 //              add_to_buffer(&message_buffer,argv[x],MESSAGE_LEVEL_BASIC_TASKS,PRINT);
62                 if (strcmp("-seed",argv[x])==0){                        /*warning only compares the length of the strings, quick fix*/
63                         seed= atoi(argv[x+1]);
64                         /*add_to_buffer(&message_buffer,"setting seed to ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
65                         append_int_to_buffer(&message_buffer,seed,MESSAGE_LEVEL_BASIC_TASKS,NPRINT);                    
66                         append_to_buffer(&message_buffer,"\n",MESSAGE_LEVEL_BASIC_TASKS,PRINT);*/
67                 }
68         }
69         if (seed==-1){
70                 seed=time(NULL);
71                 srand(seed); 
72         }
73         else {
74         srand(seed);
75         }
76         add_to_buffer(&message_buffer,"setting seed to ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
77         append_int_to_buffer(&message_buffer,seed,MESSAGE_LEVEL_BASIC_TASKS,PRINT);/* print boot up message*/   
78
79         if (yaffs_access(yaffs_test_dir,0))     /* if the test folder does not exist then create it */
80         {
81                 add_to_buffer(&message_buffer,"creating dir: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
82                 append_to_buffer(&message_buffer,yaffs_test_dir,MESSAGE_LEVEL_BASIC_TASKS,PRINT);       
83                 output=yaffs_mkdir(yaffs_test_dir,S_IREAD | S_IWRITE);
84                 yaffs_check_for_errors(output, &message_buffer,"could not create dir","created dir\n\n");
85         }
86         
87 }
88
89
90
91 void join_paths(char *path1,char *path2,char *new_path ){
92
93 /*      printf("strlen path1:%d\n",strlen(path1));
94         printf("strlen path2:%d\n",strlen(path2));
95         printf("path1; %s\n",path1);
96 */
97         add_to_buffer(&message_buffer, "joining paths:",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
98         append_to_buffer(&message_buffer,path1,MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
99         append_to_buffer(&message_buffer, " and ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
100         append_to_buffer(&message_buffer, path2,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
101         if ( (path1[(sizeof(path1)/sizeof(char))-2]=='/') && path2[0]!='/') {
102                 /*paths are compatiable. concatanate them. note -2 is because of \0*/  
103                 strcat(new_path,path1);
104                 strcat(new_path,path2);         
105                 //char new_path[(sizeof(path1)/sizeof(char))+(sizeof(path2)/sizeof(char))];
106                 //strcpy(new_path,strcat(path1,path2)); 
107                 //return new_path;
108         }       
109         else if ((path1[(sizeof(path1)/sizeof(char))-2]!='/') && path2[0]=='/') {
110                 /*paths are compatiable. concatanate them*/  
111                 strcat(new_path,path1);
112                 strcat(new_path,path2);         
113                 //char new_path[(sizeof(path1)/sizeof(char))+(sizeof(path2)/sizeof(char))];
114                 //strcpy(new_path,strcat(path1,path2)); 
115                 //return new_path;
116         }
117         else if ((path1[(sizeof(path1)/sizeof(char))-2]!='/') && path2[0]!='/') {
118                         /*need to add a "/". */  
119                 strcat(new_path,path1);
120                 strcat(new_path,"/");
121                 strcat(new_path,path2);
122                 //strcpy(new_path,strcat(path1,strcat("/\0",path2)));
123
124 #if 0
125                 copy_array(path1,new_path,0,0);
126                 copy_array('\0',new_path,0,(sizeof(path1)/sizeof(char)));
127                 copy_array(path2,new_path,0,(sizeof(path1)/sizeof(char))+1);
128  old method now trying to use copy_array
129                 //char new_path[(sizeof(path1)/sizeof(char))+(sizeof(path2)/sizeof(char))+1];
130                 for (x=0;x<=(sizeof(path1)/sizeof(char))-1;x++){ 
131                         new_path[x]=path1[x];
132                 }
133                 new_path[x+1]='/';
134                 for (x=(sizeof(path1)/sizeof(char)) ,i=0 ;i<=(sizeof(path2)/sizeof(char));x++,i++){ 
135                         new_path[x]=path2[i]; 
136                 }
137 #endif
138
139                 //return new_path;
140         }
141         else if ((path1[(sizeof(path1)/sizeof(char))-2]=='/') && path2[0]=='/') {
142                 /*need to remove a "/". */
143                 /*yaffs does not mind the extra slash. */
144                 //char new_path[(sizeof(path1)/sizeof(char))+(sizeof(path2)/sizeof(char))-1];
145                 
146                 strcat(new_path,path1);
147                 strcat(new_path,path2);
148                 //strcpy(new_path,strcat(path1,strncat("",path2,(sizeof(path1)/sizeof(char))-1))); 
149                 //return new_path;
150         } 
151         else{
152                 //error 
153                 //return -1;
154         }
155 }
156
157 void open_random_file(char *yaffs_test_dir, handle_regster *P_open_handles_array){
158         int output=0;
159         int x=0;
160         char name[MAX_FILE_NAME_SIZE+3 ]="apple\0";
161         char path[MAX_FILE_NAME_SIZE+strlen(yaffs_test_dir)];
162         path[0]='\0';// this should clear the path
163         add_to_buffer(&message_buffer,"\n\number of opened handles: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
164         append_int_to_buffer(&message_buffer,P_open_handles_array->number_of_open_handles,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
165         if (P_open_handles_array->number_of_open_handles<MAX_NUMBER_OF_OPENED_HANDLES)
166         {
167                 generate_random_string(name,MAX_FILE_NAME_SIZE);
168                 //printf("before %d %d %d\n",strlen(yaffs_test_dir),strlen(name),strlen(path));
169                 join_paths(yaffs_test_dir,name,path);
170                 //printf("after %d %d %d\n",strlen(yaffs_test_dir),strlen(name),strlen(path));
171                 add_to_buffer(&message_buffer,"trying to open file: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
172                 append_to_buffer(&message_buffer,path,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
173                 if (yaffs_access(path,0)==0){
174                         stat_file(path);
175                 }
176                 else {
177                         add_to_buffer(&message_buffer,"file does not exists, creating file",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
178                 }
179
180                 output=yaffs_open(path,O_CREAT | O_TRUNC| O_RDWR, S_IREAD | S_IWRITE);
181                 x=0;
182                 for (x=0;P_open_handles_array->handle[x]!=-3 && x<MAX_NUMBER_OF_OPENED_HANDLES;x++){}   /*find an empty handle*/         
183
184                 add_to_buffer(&message_buffer,"handle array id ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
185                 append_int_to_buffer(&message_buffer,x,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
186                         
187                 //for (x=0;handle_pointers[x]!=NULL;x++){}
188                 P_open_handles_array->handle[x]=output;
189                 P_open_handles_array->path[x][0]='\0';
190                 strcat(P_open_handles_array->path[x],path);
191                 add_to_buffer(&message_buffer,"yaffs handle: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
192                 append_int_to_buffer(&message_buffer,output,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
193                 add_to_buffer(&message_buffer,"stored handle: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
194         
195                 //yaffs_open will return a null pointer if it cannot open a file. check for errors will not work.                       
196                 yaffs_check_for_errors(output, &message_buffer,"failed to open file","opened file");
197                 
198                 P_open_handles_array->number_of_open_handles++; 
199         }
200         else  close_random_file(P_open_handles_array);
201  
202 }
203
204 void write_to_random_file(handle_regster *P_open_handles_array){
205         int number_of_lines_of_text=0;
206         int length=100;
207         char text[length+1];
208         text[0]='\0';
209         int seek=0;
210         int x=0;
211         int output=0;
212         if (P_open_handles_array->number_of_open_handles>0){
213                 
214                 while (P_open_handles_array->handle[x]==-3){            /*find a random open handle*/
215                         x=rand() % (MAX_NUMBER_OF_OPENED_HANDLES-1);
216                 }
217                 add_to_buffer(&message_buffer,"\n\ntrying to write to ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
218                 append_to_buffer(&message_buffer,P_open_handles_array->path[x],MESSAGE_LEVEL_BASIC_TASKS,PRINT);
219                 
220                 stat_file(P_open_handles_array->path[x]);
221                 number_of_lines_of_text=rand() %1000;
222                 add_to_buffer(&message_buffer,"writing  ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
223                 append_int_to_buffer(&message_buffer,number_of_lines_of_text,MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
224                 append_to_buffer(&message_buffer," lines of text",MESSAGE_LEVEL_BASIC_TASKS,PRINT);
225
226                 
227                 for (;number_of_lines_of_text>0;number_of_lines_of_text--)
228                 {
229                         generate_random_string(text,length);
230                         seek=rand()%1000;
231                         add_to_buffer(&message_buffer,"trying to seek to  ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
232                         append_int_to_buffer(&message_buffer,seek,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
233                         output=yaffs_lseek(P_open_handles_array->handle[x],seek,SEEK_SET);
234                         yaffs_check_for_errors(output, &message_buffer,"failed to seek","seeked file");
235                         add_to_buffer(&message_buffer,"trying to write to file",MESSAGE_LEVEL_BASIC_TASKS,PRINT);
236                         output=yaffs_write(P_open_handles_array->handle[x], text, strlen(text));
237                         yaffs_check_for_errors(output, &message_buffer,"failed to write text","wrote text");
238                                         
239                 }       
240          }
241 }
242
243 void truncate_random_file(handle_regster *P_open_handles_array){
244         int x=0;
245         int truncate_size=0;
246         int output=0;
247         
248         if (P_open_handles_array->number_of_open_handles>0){    
249                 add_to_buffer(&message_buffer,"\n\ntruncate function ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
250                 while (P_open_handles_array->handle[x]==-3){            /*find a random open handle*/
251                         x=rand() % (MAX_NUMBER_OF_OPENED_HANDLES-1);
252                 }
253                 add_to_buffer(&message_buffer,"trying to truncate ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
254                 append_to_buffer(&message_buffer,P_open_handles_array->path[x],MESSAGE_LEVEL_BASIC_TASKS,PRINT);
255                 
256                 stat_file(P_open_handles_array->path[x]);
257                 truncate_size=rand() %10000;
258                 output=yaffs_ftruncate(P_open_handles_array->handle[x], truncate_size);
259                 yaffs_check_for_errors(output, &message_buffer,"failed to truncate file","truncated file");
260         }
261 }
262
263 void close_random_file(handle_regster *P_open_handles_array){
264         /*run out of space on the handle pointer array*/        
265         /*make space*/
266         int x=0;
267         int output=0;
268         int start=0;
269         printf("trying to clear handle");
270         if (P_open_handles_array->number_of_open_handles>0){
271                 start=rand() % (MAX_NUMBER_OF_OPENED_HANDLES-1);
272
273                 for (x=start;(x+1>start ||x<start);){
274                         x++;                    
275                         if (x>MAX_NUMBER_OF_OPENED_HANDLES-1) x=0;
276                         if (P_open_handles_array->handle[x] !=-3 ){
277                                 //the handle is open, so try to close it.
278                                 break;
279                         }
280
281                 }
282                 if (P_open_handles_array->handle[x]!=-3)
283                 {
284                         add_to_buffer(&message_buffer,"\n\ntrying to close file: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
285                         append_to_buffer(&message_buffer,P_open_handles_array->path[x],MESSAGE_LEVEL_BASIC_TASKS,PRINT);
286                         add_to_buffer(&message_buffer,"file handle: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
287                         append_int_to_buffer(&message_buffer,P_open_handles_array->handle[x],MESSAGE_LEVEL_BASIC_TASKS,PRINT);
288         
289                         stat_file(P_open_handles_array->path[x]);
290                         output=yaffs_close(P_open_handles_array->handle[x]);
291
292                         if (output==-1) yaffs_check_for_errors(output, &message_buffer,"failed to close file","closed file");
293                         else {
294                                 yaffs_check_for_errors(output, &message_buffer,"failed to close file","closed file");
295                                 P_open_handles_array->handle[x]=-3;
296                                 P_open_handles_array->path[x][0]='\0';
297                                 P_open_handles_array->number_of_open_handles--;
298                         }
299                 }
300                 else {
301                         add_to_buffer(&message_buffer,"\n\ntried to close file but could not find a open file ",MESSAGE_LEVEL_BASIC_TASKS,PRINT);       
302                 }       
303         }
304 }
305
306 void stat_file(char *path){
307         int output=0;
308         struct yaffs_stat stat;
309         if (yaffs_access(path,0)==0){
310                 add_to_buffer(&message_buffer,"file exists, trying to stat: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
311                 add_to_buffer(&message_buffer,path,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
312                 output=yaffs_lstat(path,&stat);
313                 yaffs_check_for_errors(output, &message_buffer,"failed to stat file","statted file");
314                 //stat.st_ino,(int)stat.st_size,stat.st_mode
315                 add_to_buffer(&message_buffer,"yaffs inode: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
316                 append_int_to_buffer(&message_buffer,stat.st_ino,MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
317                 append_to_buffer(&message_buffer," file size: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
318                 append_int_to_buffer(&message_buffer,(int)stat.st_size,MESSAGE_LEVEL_BASIC_TASKS,NPRINT);                       
319                 append_to_buffer(&message_buffer," file mode: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
320                 append_int_to_buffer(&message_buffer,stat.st_mode,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
321         }
322         else{
323                 add_to_buffer(&message_buffer,path,MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
324                 append_to_buffer(&message_buffer," does not exist,could not stat",MESSAGE_LEVEL_BASIC_TASKS,PRINT);
325         }
326 }
327
328 void test(char*yaffs_test_dir){
329
330         //char name[MAX_FILE_NAME_SIZE+3 ]="apple\0";
331         //char path[MAX_FILE_NAME_SIZE];
332         handle_regster open_handles_array;
333         //int handle_pointers[MAX_NUMBER_OF_OPENED_HANDLES];
334         //int number_of_opened_handles=0;
335         int x=0;
336         
337                 
338         open_handles_array.number_of_open_handles=0;
339         for (x=0;x<MAX_NUMBER_OF_OPENED_HANDLES;x++){
340                 open_handles_array.handle[x]=-3;
341                 open_handles_array.path[x][0]='\0';
342
343         }
344
345         while(1)
346         {
347
348                 x=rand() % 3;
349                 printf("running test: %d",x);
350                 switch(x){
351                         case 0 :open_random_file(yaffs_test_dir,&open_handles_array);break;
352                         case 3 :write_to_random_file(&open_handles_array);break;
353 //                      case 1 :close_random_file(&open_handles_array);break;
354                         case 2 :truncate_random_file(&open_handles_array);break;
355                 }
356         }
357 }
358 void  generate_random_string(char *ptr,int length_of_str){
359         unsigned int x;
360         unsigned int length=((rand() %length_of_str)+1);        /*creates a int with the number of charecters been between 1 and 51*/           
361         char letter='\0';
362
363         //printf("generating string\n");
364         //printf("string length is %d\n",length);
365         for (x=0; x <= (length-2) &&length>2 ; x++)
366         {
367                 //printf("x=%d\n",x);   
368                 /* keep generating a charecter until the charecter is legal*/
369                 while((letter=='\0' )||(letter=='/')||(letter=='\\')){
370                         letter=(rand() % 126-32)+32;    /*generate a number between 32 and 126 and uses it as a charecter (letter) */
371                 }       
372                 ptr[x]=letter;
373                 //printf("charecter generated is %c\n",ptr[x]);
374         }
375         ptr[x+1]='\0';  /*adds NULL charecter to turn it into a string*/
376         
377 }
378