nfs-ganesha 1.4
|
00001 /* 00002 * @(#)test6.c 1.5 99/08/29 Connectathon Testsuite 00003 * 1.4 Lachman ONC Test Suite source 00004 * 00005 * Test readdir 00006 * 00007 * Uses the following important system/library calls against the server: 00008 * 00009 * chdir() 00010 * mkdir() (for initial directory creation if not -m) 00011 * creat() 00012 * unlink() 00013 * opendir(), rewinddir(), readdir(), closedir() 00014 */ 00015 00016 #if defined (DOS) || defined (WIN32) 00017 /* If Dos, Windows or Win32 */ 00018 #define DOSorWIN32 00019 #endif 00020 00021 #ifndef DOSorWIN32 00022 #include <sys/param.h> 00023 #include <unistd.h> 00024 #include <string.h> 00025 #ifdef use_directs 00026 #include <sys/dir.h> 00027 #else 00028 #include <dirent.h> 00029 #endif 00030 #endif /* DOSorWIN32 */ 00031 00032 #include <sys/types.h> 00033 #include <sys/stat.h> 00034 #ifdef DOSorWIN32 00035 #include <time.h> 00036 #else 00037 #include <sys/time.h> 00038 #endif 00039 #include <stdio.h> 00040 #include <stdlib.h> 00041 00042 #include "tests.h" 00043 #include "Connectathon_config_parsing.h" 00044 00045 static int Tflag = 0; /* print timing */ 00046 static int Fflag = 0; /* test function only; set count to 1, negate -t */ 00047 static int Nflag = 0; /* Suppress directory operations */ 00048 static int Iflag = 0; /* Ignore non-test files dir entries */ 00049 00050 #define MAXFILES 512 /* maximum files allowed for this test */ 00051 #define BITMOD 8 /* bits per u_char */ 00052 static unsigned char bitmap[MAXFILES / BITMOD]; 00053 00054 #define BIT(x) (bitmap[(x) / BITMOD] & (1 << ((x) % BITMOD)) ) 00055 #define SETBIT(x) (bitmap[(x) / BITMOD] |= (1 << ((x) % BITMOD)) ) 00056 #define CLRBIT(x) (bitmap[(x) / BITMOD] &= ~(1 << ((x) % BITMOD)) ) 00057 00058 static void usage() 00059 { 00060 fprintf(stdout, "usage: %s [-htfni] <config_file>\n", Myname); 00061 fprintf(stdout, " Flags: h Help - print this usage info\n"); 00062 fprintf(stdout, " t Print execution time statistics\n"); 00063 fprintf(stdout, " f Test function only (negate -t)\n"); 00064 fprintf(stdout, " n Suppress test directory create operations\n"); 00065 fprintf(stdout, " i Ignore non-test files dir entries\n"); 00066 } 00067 00068 int main(int argc, char *argv[]) 00069 { 00070 #ifdef use_directs 00071 struct direct *dp; 00072 #else 00073 struct dirent *dp; 00074 #endif 00075 char *fname; 00076 char *dname; 00077 int files; /* number of files in each dir */ 00078 int fi; 00079 int count; /* times to read dir */ 00080 int ct; 00081 int entries = 0; 00082 int totfiles = 0; 00083 int totdirs = 0; 00084 DIR *dir; 00085 struct timeval time; 00086 char *p, str[MAXPATHLEN]; 00087 char *opts; 00088 int err, dot, dotdot; 00089 unsigned int i; 00090 int nmoffset; 00091 struct testparam *param; 00092 struct btest *b; 00093 char *config_file; 00094 char *test_dir; 00095 char *log_file; 00096 FILE *log; 00097 00098 umask(0); 00099 setbuf(stdout, NULL); 00100 Myname = *argv++; 00101 argc--; 00102 while(argc && **argv == '-') 00103 { 00104 for(opts = &argv[0][1]; *opts; opts++) 00105 { 00106 switch (*opts) 00107 { 00108 case 'h': /* help */ 00109 usage(); 00110 exit(1); 00111 break; 00112 00113 case 't': /* time */ 00114 Tflag++; 00115 break; 00116 00117 case 'f': /* funtionality */ 00118 Fflag++; 00119 break; 00120 00121 case 'n': /* No Test Directory create */ 00122 Nflag++; 00123 break; 00124 00125 case 'i': /* ignore spurious files */ 00126 Iflag++; 00127 break; 00128 00129 default: 00130 error("unknown option '%c'", *opts); 00131 usage(); 00132 exit(1); 00133 } 00134 } 00135 argc--; 00136 argv++; 00137 } 00138 00139 if(argc) 00140 { 00141 config_file = *argv; 00142 argc--; 00143 argv++; 00144 } 00145 else 00146 { 00147 fprintf(stderr, "Missing config_file"); 00148 exit(1); 00149 } 00150 00151 if(argc != 0) 00152 { 00153 fprintf(stderr, "too many parameters"); 00154 usage(); 00155 exit(1); 00156 } 00157 00158 param = readin_config(config_file); 00159 if(param == NULL) 00160 { 00161 fprintf(stderr, "Nothing built\n"); 00162 exit(1); 00163 } 00164 00165 b = get_btest_args(param, SIX); 00166 if(b == NULL) 00167 { 00168 fprintf(stderr, "Missing basic test number 6 in the config file '%s'\n", 00169 config_file); 00170 free_testparam(param); 00171 exit(1); 00172 } 00173 00174 if(b->files == -1) 00175 { 00176 fprintf(stderr, 00177 "Missing 'files' parameter in the config file '%s' for the basic test number 6\n", 00178 config_file); 00179 free_testparam(param); 00180 exit(1); 00181 } 00182 if(b->count == -1) 00183 { 00184 fprintf(stderr, 00185 "Missing 'count' parameter in the config file '%s' for the basic test number 6\n", 00186 config_file); 00187 free_testparam(param); 00188 exit(1); 00189 } 00190 count = b->count; 00191 files = b->files; 00192 fname = b->fname; 00193 dname = b->dname; 00194 test_dir = get_test_directory(param); 00195 log_file = get_log_file(param); 00196 00197 free_testparam(param); 00198 00199 nmoffset = strlen(fname); 00200 00201 if(!Fflag) 00202 { 00203 Tflag = 0; 00204 count = 1; 00205 } 00206 00207 if(count > files) 00208 { 00209 fprintf(stderr, "count (%d) can't be greater than files (%d)", count, files); 00210 exit(1); 00211 } 00212 00213 if(files > MAXFILES) 00214 { 00215 fprintf(stderr, "too many files requested (max is %d)", MAXFILES); 00216 exit(1); 00217 } 00218 00219 fprintf(stdout, "%s: readdir\n", Myname); 00220 00221 if(!Nflag) 00222 testdir(test_dir); 00223 else 00224 mtestdir(test_dir); 00225 00226 dirtree(1, files, 0, fname, dname, &totfiles, &totdirs); 00227 00228 starttime(); 00229 if((dir = opendir(".")) == NULL) 00230 { 00231 error("can't opendir %s", "."); 00232 exit(1); 00233 } 00234 00235 for(ct = 0; ct < count; ct++) 00236 { 00237 rewinddir(dir); 00238 dot = 0; 00239 dotdot = 0; 00240 err = 0; 00241 for(i = 0; i < sizeof(bitmap); i++) 00242 bitmap[i] = 0; 00243 while((dp = readdir(dir)) != NULL) 00244 { 00245 entries++; 00246 if(strcmp(".", dp->d_name) == 0) 00247 { 00248 if(dot) 00249 { 00250 /* already read dot */ 00251 error("'.' dir entry read twice"); 00252 exit(1); 00253 } 00254 dot++; 00255 continue; 00256 } 00257 else if(strcmp("..", dp->d_name) == 0) 00258 { 00259 if(dotdot) 00260 { 00261 /* already read dotdot */ 00262 error("'..' dir entry read twice"); 00263 exit(1); 00264 } 00265 dotdot++; 00266 continue; 00267 } 00268 00269 /* 00270 * at this point, should have entry of the form 00271 * fname%d 00272 */ 00273 /* If we don't have our own directory, ignore 00274 such errors (if Iflag set). */ 00275 if(strncmp(dp->d_name, fname, nmoffset)) 00276 { 00277 if(Iflag) 00278 continue; 00279 else 00280 { 00281 error("unexpected dir entry '%s'", dp->d_name); 00282 exit(1); 00283 } 00284 } 00285 00286 /* get ptr to numeric part of name */ 00287 p = dp->d_name + nmoffset; 00288 fi = atoi(p); 00289 if(fi < 0 || fi >= MAXFILES) 00290 { 00291 error("unexpected dir entry '%s'", dp->d_name); 00292 exit(1); 00293 } 00294 if(BIT(fi)) 00295 { 00296 error("duplicate '%s' dir entry read", dp->d_name); 00297 err++; 00298 } 00299 else 00300 SETBIT(fi); 00301 } /* end readdir loop */ 00302 if(!dot) 00303 { 00304 error("didn't read '.' dir entry, pass %d", ct); 00305 err++; 00306 } 00307 if(!dotdot) 00308 { 00309 error("didn't read '..' dir entry, pass %d", ct); 00310 err++; 00311 } 00312 for(fi = 0; fi < ct; fi++) 00313 { 00314 if(BIT(fi)) 00315 { 00316 sprintf(str, "%s%d", fname, fi); 00317 error("unlinked '%s' dir entry read pass %d", str, ct); 00318 err++; 00319 } 00320 } 00321 for(fi = ct; fi < files; fi++) 00322 { 00323 if(!BIT(fi)) 00324 { 00325 sprintf(str, "%s%d", fname, fi); 00326 error("\ 00327 didn't read expected '%s' dir entry, pass %d", str, ct); 00328 err++; 00329 } 00330 } 00331 if(err) 00332 { 00333 error("Test failed with %d errors", err); 00334 exit(1); 00335 } 00336 sprintf(str, "%s%d", fname, ct); 00337 if(unlink(str) < 0) 00338 { 00339 error("can't unlink %s", str); 00340 exit(1); 00341 } 00342 } 00343 00344 closedir(dir); 00345 endtime(&time); 00346 00347 fprintf(stdout, "\t%d entries read, %d files", entries, files); 00348 if(Tflag) 00349 { 00350 fprintf(stdout, " in %ld.%02ld seconds", 00351 (long)time.tv_sec, (long)time.tv_usec / 10000); 00352 } 00353 fprintf(stdout, "\n"); 00354 00355 rmdirtree(1, files, 0, fname, dname, &totfiles, &totdirs, 1); 00356 00357 if((log = fopen(log_file, "a")) == NULL) 00358 { 00359 printf("Enable to open the file '%s'\n", log_file); 00360 complete(); 00361 } 00362 fprintf(log, "b6\t%d\t%d\t%ld.%02ld\n", entries, files, (long)time.tv_sec, 00363 (long)time.tv_usec / 10000); 00364 fclose(log); 00365 00366 complete(); 00367 }