os161-1.99
 All Data Structures
f_test.c
00001 /*
00002  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 /*
00031  * Razvan Surdulescu
00032  * abhi shelat
00033  * April 28 1997
00034  * 
00035  * Test suite for Nachos HW4--The Filesystem
00036  *
00037  * Modified by dholland 1/31/2001 for OS/161
00038  *
00039  * This should run successfully (on SFS) when the file system
00040  * assignment is complete.
00041  */
00042 
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <stdio.h>
00046 #include <string.h>
00047 #include <unistd.h>
00048 #include <err.h>
00049 #include "f_hdr.h"
00050 
00051 #define SECTOR_SIZE  512
00052 
00053 
00054 #define BUFFER_SIZE  (2 * SECTOR_SIZE + 1)
00055 #define BIGFILE_SIZE (270 * BUFFER_SIZE)
00056 #define BIGFILE_NAME "large-f"
00057 
00058 #define LETTER(x) ('a' + (x % 31))
00059 
00060 char fbuffer[BUFFER_SIZE];
00061 char ibuffer[32];
00062 
00063 
00064 #define DIR_DEPTH      8
00065 #define DIR_NAME       "/t"
00066 #define DIRFILE_NAME   "a"
00067 
00068 
00069 #define FNAME        "f-testfile"
00070 #define TMULT        50
00071 #define FSIZE        ((SECTOR_SIZE + 1) * TMULT)
00072 
00073 #define READCHAR     'r'
00074 #define WRITECHAR    'w'
00075 
00076 char cbuffer[SECTOR_SIZE + 1];
00077 
00078 
00079 /* ===================================================
00080 
00081  */
00082 
00083 static
00084 pid_t
00085 forkoff(void (*func)(void))
00086 {
00087         pid_t pid = fork();
00088         switch (pid) {
00089             case -1:
00090                 warn("fork");
00091                 return -1;
00092             case 0: 
00093                 func();
00094                 _exit(0);
00095             default: break;
00096         }
00097         return pid;
00098 }
00099 
00100 static
00101 void
00102 dowait(int pid)
00103 {
00104         int status;
00105 
00106         if (waitpid(pid, &status, 0)<0) {
00107                 warn("waitpid for %d", pid);
00108         }
00109         else if (WIFSIGNALED(status)) {
00110                 warnx("pid %d: signal %d", pid, WTERMSIG(status));
00111         }
00112         else if (WEXITSTATUS(status) != 0) {
00113                 warnx("pid %d: exit %d", pid, WEXITSTATUS(status));
00114         }
00115 }
00116 
00117 /* ===================================================
00118         
00119  */
00120 
00121 static
00122 void
00123 big_file(int size)
00124 {
00125         int i, j, fileid;
00126         
00127         printf("[BIGFILE] test starting :\n");
00128         printf("\tCreating a file of size: %d\n", size);
00129         
00130         fileid = open(BIGFILE_NAME, O_WRONLY|O_CREAT|O_TRUNC, 0664);
00131         if (fileid < 0) {
00132                 err(1, "[BIGFILE]: %s: open for write", BIGFILE_NAME);
00133         }       
00134         
00135         for(i = 0; i < BUFFER_SIZE; i++) {
00136                 fbuffer[i] = LETTER(i);
00137         }
00138 
00139         printf("\tWriting to file.\n");
00140         for (i = 0; i < size; i += BUFFER_SIZE) {
00141                 write(fileid, fbuffer, BUFFER_SIZE);
00142 
00143                 if (!(i % (10 * BUFFER_SIZE))) {
00144                         printf("\rBW : %d", i);
00145                 }
00146         }
00147 
00148         printf("\n\tReading from file.\n");
00149         close(fileid);
00150 
00151         fileid = open(BIGFILE_NAME, O_RDONLY);
00152         if (fileid < 0) {
00153                 err(1, "[BIGFILE]: %s: open for read", BIGFILE_NAME);
00154         }
00155         
00156         for (i = 0; i < size; i += BUFFER_SIZE) {
00157                 j = read(fileid, fbuffer, BUFFER_SIZE);
00158                 if (j<0) {
00159                         err(1, "[BIGFILE]: read");
00160                 }
00161                 if (j != BUFFER_SIZE) {
00162                         errx(1, "[BIGFILE]: read: only %d bytes", j);
00163                 }
00164         }
00165 
00166         if (!(i % (10 * BUFFER_SIZE))) {
00167                 printf("\rBR : %d", i);
00168         }
00169 
00170         /* Check to see that the data is consistent : */
00171         for (j = 0; j < BUFFER_SIZE; j++) {
00172                 if (fbuffer[j] != LETTER(j)) {
00173                         errx(1, "[BIGFILE] : Failed read check : "
00174                              "inconsistent data read: %d", i+j);
00175                 }
00176         }
00177 
00178 
00179         close(fileid);
00180         if (remove(BIGFILE_NAME)) {
00181                 err(1, "[BIGFILE]: %s: remove", BIGFILE_NAME);
00182         }
00183 
00184         printf("\n[BIGFILE] : Success!\n");
00185 }
00186 
00187 /* ===================================================
00188 
00189  */
00190 
00191 static
00192 void
00193 concur(void)
00194 {
00195         int i, fd;
00196         int r1, r2, w1;
00197 
00198         printf("Spawning 2 readers, 1 writer.\n");
00199 
00200 
00201         fd = open(FNAME, O_WRONLY|O_CREAT|O_TRUNC, 0664);
00202         if (fd < 0) {
00203                 err(1, "[CONCUR]: %s: open", FNAME);
00204         }
00205 
00206         printf("Initializing test file: ");
00207 
00208         for (i = 0; i < SECTOR_SIZE + 1; i++) {
00209                 cbuffer[i] = READCHAR;
00210         }
00211 
00212         for (i = 0; i < TMULT; i++) {
00213                 write(fd, cbuffer, SECTOR_SIZE + 1);
00214         }
00215 
00216 
00217         close(fd);
00218 
00219         printf("Done initializing. Starting processes...\n");
00220 
00221         r1 = forkoff(subproc_read);
00222         w1 = forkoff(subproc_write);
00223         r2 = forkoff(subproc_read);
00224 
00225         printf("Waiting for processes.\n");
00226 
00227         dowait(r1);
00228         dowait(r2);
00229         dowait(w1);
00230 
00231         if (remove(FNAME)) {
00232                 err(1, "[CONCUR]: %s: remove", FNAME);
00233         }
00234          
00235         printf("[CONCUR] Done!\n");
00236 }
00237 
00238 /* ===================================================
00239         
00240  */
00241 
00242 static
00243 void
00244 dir_test(int depth)
00245 {
00246         int i, fd;
00247         char tmp[] = DIR_NAME;
00248         char fmp[] = DIRFILE_NAME;
00249         char dirname[64];
00250 
00251         strcpy(dirname, ".");
00252 
00253         for (i = 0; i < depth; i++) {
00254                 strcat(dirname, tmp);
00255                 
00256                 printf("\tCreating dir : %s\n", dirname);
00257 
00258                 if (mkdir(dirname, 0775) < 0) {
00259                         err(1, "[DIRTEST]: %s: mkdir", dirname);
00260                 }
00261 
00262                 strcat(dirname, fmp);
00263                 printf("\tCreating file: %s\n", dirname);
00264 
00265                 fd = open(dirname, O_WRONLY|O_CREAT|O_TRUNC, 0664);
00266                 if (fd<0) {
00267                         err(1, "[DIRTEST]: %s: open", dirname);
00268                 }
00269 
00270                 dirname[strlen(dirname) - strlen(fmp)] = '\0';
00271         }
00272 
00273         printf("[DIRTEST] : Passed directory creation test.\n");
00274 
00275         for (i = 0; i < depth; i++) {
00276                 strcat(dirname, fmp);
00277 
00278                 printf("\tDeleting file: %s\n", dirname);
00279                   
00280                 if (remove(dirname)) {
00281                          err(1, "[DIRTEST]: %s: remove", dirname);
00282                 }
00283 
00284                 dirname[strlen(dirname) - strlen(fmp)] = '\0';
00285                 printf("\tRemoving dir : %s\n", dirname);
00286 
00287                 if (rmdir(dirname)) {
00288                         err(1, "[DIRTEST]: %s: rmdir", dirname);
00289                 }
00290 
00291                 dirname[strlen(dirname) - strlen(tmp)] = '\0';
00292         }
00293 
00294         printf("[DIRTEST] : Passed directory removal test.\n");
00295         printf("[DIRTEST] : Success!\n");
00296 }
00297 
00298 /* ===================================================
00299 
00300  */
00301 
00302 #define   RUNBIGFILE  0x1
00303 #define   RUNDIRTEST  0x2
00304 #define   RUNCONCUR   0x4
00305 #define   RUNTHEMALL  (RUNBIGFILE | RUNDIRTEST | RUNCONCUR) 
00306 
00307 int
00308 main(int argc, char * argv[])
00309 {
00310         int tv = 0;
00311 
00312         if (argc > 1) {
00313                 if (*argv[1]=='1') {
00314                         tv = RUNBIGFILE;
00315                 }
00316                 else if (*argv[1]=='2') {
00317                         tv = RUNDIRTEST;
00318                 }
00319                 else if (*argv[1]=='3') {
00320                         tv = RUNCONCUR;
00321                 }
00322         } 
00323         else {
00324                 tv = RUNTHEMALL;
00325         }
00326          
00327         if (tv & RUNBIGFILE) {
00328                 printf("[BIGFILE] : Run #1\n");
00329                 big_file(BIGFILE_SIZE); 
00330                 printf("[BIGFILE] : Run #2\n");
00331                 big_file(BIGFILE_SIZE);
00332         }
00333          
00334         if (tv & RUNDIRTEST) {
00335                 printf("[DIRTEST] : Run #1\n");
00336                 dir_test(DIR_DEPTH);
00337                 printf("[DIRTEST] : Run #2\n");
00338                 dir_test(DIR_DEPTH);
00339         }
00340          
00341         if (tv & RUNCONCUR) {
00342                 printf("[CONCUR]\n");
00343                 concur();
00344         }
00345         return 0;
00346 }
00347 
00348 
 All Data Structures