Back to index

avfs  1.0.1
runtest.c
Go to the documentation of this file.
00001 /*  
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 1998  Miklos Szeredi <miklos@szeredi.hu>
00004     
00005     This program can be distributed under the terms of the GNU GPL.
00006     See the file COPYING.
00007 */
00008 
00009 #include "virtual.h"
00010 
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #include <unistd.h>
00015 #include <fcntl.h>
00016 
00017 #define TESTDIR "/tmp/avfstest"
00018 
00019 typedef int (*testfunc) (void *);
00020 
00021 struct test {
00022     char *name;
00023     struct test *next;
00024 
00025     struct test *sub;
00026     void *data;
00027     testfunc func;
00028 };
00029 
00030 
00031 #define TESTFILESIZE 102400
00032 struct filetest {
00033     const char *filename;
00034     unsigned char data[TESTFILESIZE];
00035 };
00036 
00037 static struct test *test_new(struct test *tg, const char *name)
00038 {
00039     struct test *ng;
00040     struct test **tgp;
00041 
00042     for(tgp = &tg->sub; *tgp != NULL; tgp = &(*tgp)->next);
00043 
00044     ng = malloc(sizeof(*ng));
00045     ng->sub = NULL;
00046     ng->next = NULL;
00047     ng->name = strdup(name);
00048     ng->data = NULL;
00049     ng->func = NULL;
00050     
00051     *tgp = ng;
00052 
00053     return ng;
00054 }
00055 
00056 static void test_add(struct test *tg, const char *name, void *data,
00057                      testfunc func)
00058 {
00059     struct test *tc;
00060 
00061     tc = test_new(tg, name);
00062     tc->data = data;
00063     tc->func = func;
00064 }
00065 
00066 static void tab(int i)
00067 {
00068     for(; i > 0; i--)
00069         putchar(' ');
00070 }
00071 
00072 static int test_run_path(struct test *tg, const char *path)
00073 {
00074     int ok;
00075     int res;
00076     char *newpath;
00077 
00078     if(tg == NULL)
00079         return 0;
00080 
00081     newpath = malloc(strlen(path) + 1 + strlen(tg->name) + 1);
00082 
00083     sprintf(newpath, "%s.%s", path, tg->name);
00084     ok = test_run_path(tg->sub, newpath);
00085     if(tg->func != NULL) {
00086         int len = printf("%s:", newpath);
00087         tab(60 - len);
00088         
00089         res = tg->func(tg->data);
00090         printf("%s\n", res ? "OK" : "FAILED");
00091         if(!res)
00092             ok = 0;
00093     }
00094 
00095     free(newpath);
00096 
00097     res = test_run_path(tg->next, path);
00098     if(!res)
00099         ok = 0;
00100 
00101     return ok;
00102 }
00103 
00104 static int test_run(struct test *tg)
00105 {
00106     return test_run_path(tg, "");
00107 }
00108 
00109 static int test_rmr(const char *file)
00110 {
00111     int res;
00112     DIR *dirp;
00113     struct dirent *ent;
00114     char *name;
00115 
00116     res = unlink(file);
00117     if(res == 0)
00118         return 0;
00119 
00120     res = rmdir(file);
00121     if(res == 0)
00122         return 0;
00123 
00124     dirp = opendir(file);
00125     if(dirp == NULL)
00126         return -1;
00127 
00128     while((ent = readdir(dirp)) != NULL) {
00129         name = ent->d_name;
00130     
00131         if(name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))) {
00132             char *newname;
00133 
00134             newname = malloc(strlen(file) + 1 + strlen(name) + 1);
00135             sprintf(newname, "%s/%s", file, name);
00136             test_rmr(newname);
00137             free(newname);
00138         }
00139     }
00140     closedir(dirp);
00141 
00142     return rmdir(file);
00143 }
00144 
00145 static void test_init()
00146 {
00147     test_rmr(TESTDIR);
00148     mkdir(TESTDIR, 0777);
00149 }
00150 
00151 static char *test_file(const char *name)
00152 {
00153     char *fullname = malloc(strlen(TESTDIR) + 1 + strlen(name) + 1);
00154 
00155     sprintf(fullname, "%s/%s", TESTDIR, name);
00156 
00157     return fullname;
00158 }
00159 
00160 static int file_create(struct filetest *ft)
00161 {
00162     int res;
00163     int fd;
00164     off_t off;
00165     size_t size;
00166 
00167     res = virt_open(ft->filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
00168     if(res == -1)
00169         return 0;
00170 
00171     fd = res;
00172     for(off = 0; off < TESTFILESIZE; off += size) {
00173         size = rand() % TESTFILESIZE / 2;
00174 
00175         if(off + size > TESTFILESIZE)
00176             size = TESTFILESIZE - off;
00177         
00178         res = virt_write(fd, ft->data + off, size);
00179         if(res != size)
00180             return 0;
00181     }
00182 
00183     res = virt_close(fd);
00184     if(res == -1)
00185         return 0;
00186 
00187     return 1;
00188 }
00189 
00190 static int flush_cache()
00191 {
00192     int res;
00193     int fd;
00194 
00195     fd = virt_open("/#avfsstat/cache/clear", O_WRONLY, 0);
00196     if(fd == -1)
00197         return -1;
00198 
00199     res = virt_write(fd, "1", 1);
00200     if(res == -1)
00201         return -1;
00202 
00203     res = virt_close(fd);
00204     if(res == -1)
00205         return -1;
00206 
00207     return 0;
00208 }
00209 
00210 static int file_contents(struct filetest *ft)
00211 {
00212     int res;
00213     int fd;
00214     off_t off;
00215     size_t size;
00216     char buf[TESTFILESIZE / 2];
00217 
00218     res = flush_cache();
00219     if(res == -1)
00220         return 0;
00221 
00222     res = virt_open(ft->filename, O_RDONLY, 0);
00223     if(res == -1)
00224         return 0;
00225 
00226     fd = res;
00227     for(off = 0; off < TESTFILESIZE; off += size) {
00228         size = rand() % TESTFILESIZE / 2;
00229 
00230         res = virt_read(fd, buf, size);
00231 
00232         if(off + size > TESTFILESIZE)
00233             size = TESTFILESIZE - off;
00234 
00235         if(res != size)
00236             return 0;
00237 
00238         if(memcmp(ft->data + off, buf, size) != 0)
00239             return 0;
00240     }
00241     
00242     res = virt_read(fd, buf, 100);
00243     if(res != 0)
00244         return 0;
00245 
00246     res = virt_close(fd);
00247     if(res == -1)
00248         return 0;
00249 
00250     return 1;
00251 }
00252 
00253 
00254 
00255 static void add_filetest(struct test *tg, const char *testname,
00256                          const char *filename)
00257 {
00258     struct filetest *ft;
00259     struct test *ftg;
00260     int i;
00261 
00262     srand(1);
00263     ft = (struct filetest *) malloc(sizeof(*ft));
00264 
00265     ftg = test_new(tg, testname);
00266 
00267     ft->filename = filename;
00268     for(i = 0; i < TESTFILESIZE; i++)
00269         ft->data[i] = (i + (!(rand() % 30) ? rand() : 0)) % 0x100;
00270 
00271     test_add(ftg, "create", ft, (testfunc) file_create);
00272     test_add(ftg, "contents", ft, (testfunc) file_contents);
00273 }
00274 
00275 
00276 int main(int argc, char *argv[])
00277 {
00278     int res;
00279     struct test root;
00280     struct test *tg;
00281 
00282     test_init();
00283 
00284     root.sub = NULL;
00285     tg = test_new(&root, "filetest");
00286     add_filetest(tg, "ugzip", test_file("t.gz#ugzip"));
00287     add_filetest(tg, "ubzip2", test_file("t.bz2#ubzip2"));
00288     add_filetest(tg, "volatile", "/#volatile/testfile");
00289     
00290     res = test_run(tg);
00291 
00292     if(res == 0)
00293         return 1;
00294     else
00295         return 0;
00296 }