Commit 0732149d authored by Anjo Vahldiek's avatar Anjo Vahldiek
Browse files

added test scripts

parent 657df8f5
#!/usr/bin/perl -w
sub oops {
my($msg) = @_;
print STDERR "test-lab-4-a.pl error: $msg : $!\n";
exit(1);
}
sub oops1 {
my($msg) = @_;
print STDERR "test-lab-4-a.pl error: $msg\n";
exit(1);
}
if($#ARGV != 0){
print STDERR "Usage: test-lab-4-a.pl directory\n";
exit(1);
}
my $seq = 0;
my $root = $ARGV[0];
my $dir = $root . "/d" . $$;
print "mkdir $dir\n";
if(mkdir($dir, 0777) == 0){
oops("mkdir $dir");
}
my $files = { };
my @dead;
createone();
deleteone();
createone();
checkmtime();
checkdirmtime();
for($iters = 0; $iters < 10; $iters++){
createone();
}
for($iters = 0; $iters < 50; $iters++){
if(rand() < 0.2){
deadcheck();
}
if(rand() < 0.2){
livecheck();
}
if(rand() < 0.02){
dircheck();
}
if(rand() < 0.1){
checkdirmtime();
}
if(rand() < 0.1){
checkmtime();
}
if(rand() < 0.5){
createone();
}
if(rand() < 0.5){
deleteone();
}
}
dircheck();
cleanup();
dircheck();
printf "Passed all tests!\n";
exit(0);
sub createone {
my $name = "x-" . $seq;
$seq = $seq + 1;
my $contents = rand();
print "create $name\n";
if(!open(F, ">$dir/$name")){
oops("cannot create $name");
}
print F "$contents";
close(F);
$files->{$name} = $contents;
}
# make sure all the live files are there,
# and that all the dead files are not there.
sub dircheck {
print "dircheck\n";
opendir(D, $dir);
my %h;
my $f;
while(defined($f = readdir(D))){
if(defined($h{$f})){
oops1("$f occurs twice in directory");
}
$h{$f} = 1;
}
closedir(D);
foreach $f (keys(%$files)){
if(!defined($h{$f})){
oops1("$f is not in directory listing");
}
}
foreach $f (@dead){
if(defined($h{$f})){
oops1("$f was removed but is in directory listing");
}
}
foreach $f (keys(%h)){
next if ($f eq "." or $f eq "..");
if(!defined($files->{$f})){
oops1("unexpected file $f in directory listing");
}
}
}
sub livecheck {
my @a = keys(%$files);
return if $#a < 0;
my $i = int(rand($#a + 1));
my $k = $a[$i];
print "livecheck $k\n";
oops("cannot open $k") if !open(F, "$dir/$k");
my $z = <F>;
if($z ne $files->{$k}){
oops1("file $k wrong contents");
}
close(F);
}
sub deadcheck {
return if $#dead < 0;
my $i = int(rand($#dead + 1));
my $k = $dead[$i];
return if defined($files->{$k}); # ???
print "deadcheck $k\n";
if(rand(1.0) < 0.5){
if(open(F, $dir . "/" . $k)){
oops1("dead file $k is readable");
}
} else {
if(unlink($dir . "/" . $k)){
oops1("dead file $k was removable");
}
}
}
sub deleteone {
my @a = keys(%$files);
return 0 if $#a < 0;
my $i = int(rand($#a + 1));
my $k = $a[$i];
print "delete $k\n";
if(unlink($dir . "/" . $k) == 0){
oops("unlink $k failed");
}
delete $files->{$k};
push(@dead, $k);
return 1;
}
sub checkdirmtime {
print "checkdirmtime\n";
opendir(D, $dir);
closedir(D);
my @st1 = stat($dir . "/.");
sleep(2);
my $op;
if(rand() < 0.75){
return if deleteone() == 0;
$op = "delete";
} else {
createone();
$op = "create";
}
opendir(D, $dir);
closedir(D);
my @st2 = stat($dir . "/.");
if($st1[9] == $st2[9]){
print $st2[9], " ", $st2[9], "\n";
oops1("$op did not change directory mtime");
}
if($st1[10] == $st2[10]){
oops1("$op did not change directory ctime");
}
}
sub checkmtime {
my @a = keys(%$files);
return if $#a < 0;
my $i = int(rand($#a + 1));
my $k = $a[$i];
print "checkmtime $k\n";
my @st1 = stat("$dir/$k");
sleep(2);
if(!open(F, ">$dir/$k")){
oops("cannot re-create $dir/$k");
}
my @st2 = stat("$dir/$k");
sleep(2);
print F $files->{$k};
close(F);
if(!open(F, "$dir/$k")){
oops("cannot open $dir/$k");
}
close(F);
my @st3 = stat("$dir/$k");
if($st1[9] == $st2[9]){
oops1("CREATE did not change mtime");
}
if($st2[9] == $st3[9]){
oops1("WRITE did not change mtime");
}
}
sub cleanup {
while(deleteone()){
}
}
/*
* test-lab-4-b /classfs/dir1 /classfs/dir2
*
* Test correctness of locking and cache coherence by creating
* and deleting files in the same underlying directory
* via two different ccfs servers.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
char d1[512], d2[512];
extern int errno;
char big[20001];
void
create1(const char *d, const char *f, const char *in)
{
int fd;
char n[512];
/*
* The FreeBSD NFS client only invalidates its caches
* cache if the mtime changes by a whole second.
*/
sleep(1);
sprintf(n, "%s/%s", d, f);
fd = creat(n, 0666);
if(fd < 0){
fprintf(stderr, "test-lab-4-b: create(%s): %s\n",
n, strerror(errno));
exit(1);
}
if(write(fd, in, strlen(in)) != strlen(in)){
fprintf(stderr, "test-lab-4-b: write(%s): %s\n",
n, strerror(errno));
exit(1);
}
if(close(fd) != 0){
fprintf(stderr, "test-lab-4-b: close(%s): %s\n",
n, strerror(errno));
exit(1);
}
}
void
check1(const char *d, const char *f, const char *in)
{
int fd, cc;
char n[512], buf[21000];
sprintf(n, "%s/%s", d, f);
fd = open(n, 0);
if(fd < 0){
fprintf(stderr, "test-lab-4-b: open(%s): %s\n",
n, strerror(errno));
exit(1);
}
errno = 0;
cc = read(fd, buf, sizeof(buf) - 1);
if(cc != strlen(in)){
fprintf(stderr, "test-lab-4-b: read(%s) returned too little %d%s%s\n",
n,
cc,
errno ? ": " : "",
errno ? strerror(errno) : "");
exit(1);
}
close(fd);
buf[cc] = '\0';
if(strncmp(buf, in, strlen(n)) != 0){
fprintf(stderr, "test-lab-4-b: read(%s) got \"%s\", not \"%s\"\n",
n, buf, in);
exit(1);
}
}
void
unlink1(const char *d, const char *f)
{
char n[512];
sleep(1);
sprintf(n, "%s/%s", d, f);
if(unlink(n) != 0){
fprintf(stderr, "test-lab-4-b: unlink(%s): %s\n",
n, strerror(errno));
exit(1);
}
}
void
checknot(const char *d, const char *f)
{
int fd;
char n[512];
sprintf(n, "%s/%s", d, f);
fd = open(n, 0);
if(fd >= 0){
fprintf(stderr, "test-lab-4-b: open(%s) succeeded for deleted file\n", n);
exit(1);
}
}
void
append1(const char *d, const char *f, const char *in)
{
int fd;
char n[512];
sleep(1);
sprintf(n, "%s/%s", d, f);
fd = open(n, O_WRONLY|O_APPEND);
if(fd < 0){
fprintf(stderr, "test-lab-4-b: append open(%s): %s\n",
n, strerror(errno));
exit(1);
}
if(write(fd, in, strlen(in)) != strlen(in)){
fprintf(stderr, "test-lab-4-b: append write(%s): %s\n",
n, strerror(errno));
exit(1);
}
if(close(fd) != 0){
fprintf(stderr, "test-lab-4-b: append close(%s): %s\n",
n, strerror(errno));
exit(1);
}
}
void
createn(const char *d, const char *prefix, int nf)
{
int fd, i;
char n[512];
/*
* The FreeBSD NFS client only invalidates its caches
* cache if the mtime changes by a whole second.
*/
sleep(1);
for(i = 0; i < nf; i++){
sprintf(n, "%s/%s-%d", d, prefix, i);
fd = creat(n, 0666);
if(fd < 0){
fprintf(stderr, "test-lab-4-b: create(%s): %s\n",
n, strerror(errno));
exit(1);
}
if(write(fd, &i, sizeof(i)) != sizeof(i)){
fprintf(stderr, "test-lab-4-b: write(%s): %s\n",
n, strerror(errno));
exit(1);
}
if(close(fd) != 0){
fprintf(stderr, "test-lab-4-b: close(%s): %s\n",
n, strerror(errno));
exit(1);
}
}
}
void
checkn(const char *d, const char *prefix, int nf)
{
int fd, i, cc, j;
char n[512];
for(i = 0; i < nf; i++){
sprintf(n, "%s/%s-%d", d, prefix, i);
fd = open(n, 0);
if(fd < 0){
fprintf(stderr, "test-lab-4-b: open(%s): %s\n",
n, strerror(errno));
exit(1);
}
j = -1;
cc = read(fd, &j, sizeof(j));
if(cc != sizeof(j)){
fprintf(stderr, "test-lab-4-b: read(%s) returned too little %d%s%s\n",
n,
cc,
errno ? ": " : "",
errno ? strerror(errno) : "");
exit(1);
}
if(j != i){
fprintf(stderr, "test-lab-4-b: checkn %s contained %d not %d\n",
n, j, i);
exit(1);
}
close(fd);
}
}
void
unlinkn(const char *d, const char *prefix, int nf)
{
char n[512];
int i;
sleep(1);
for(i = 0; i < nf; i++){
sprintf(n, "%s/%s-%d", d, prefix, i);
if(unlink(n) != 0){
fprintf(stderr, "test-lab-4-b: unlink(%s): %s\n",
n, strerror(errno));
exit(1);
}
}
}
int
compar(const void *xa, const void *xb)
{
char *a = *(char**)xa;
char *b = *(char**)xb;
return strcmp(a, b);
}
void
dircheck(const char *d, int nf)
{
DIR *dp;
struct dirent *e;
char *names[1000];
int nnames = 0, i;
dp = opendir(d);
if(dp == 0){
fprintf(stderr, "test-lab-4-b: opendir(%s): %s\n", d, strerror(errno));
exit(1);
}
while((e = readdir(dp))){
if(e->d_name[0] != '.'){
if(nnames >= sizeof(names)/sizeof(names[0])){
fprintf(stderr, "warning: too many files in %s\n", d);
}
names[nnames] = (char *) malloc(strlen(e->d_name) + 1);
strcpy(names[nnames], e->d_name);
nnames++;
}
}
closedir(dp);
if(nf != nnames){
fprintf(stderr, "test-lab-4-b: wanted %d dir entries, got %d\n", nf, nnames);
exit(1);
}
/* check for duplicate entries */
qsort(names, nnames, sizeof(names[0]), compar);
for(i = 0; i < nnames-1; i++){
if(strcmp(names[i], names[i+1]) == 0){
fprintf(stderr, "test-lab-4-b: duplicate directory entry for %s\n", names[i]);
exit(1);
}
}
for(i = 0; i < nnames; i++)
free(names[i]);
}
void
reap (int pid)
{
int wpid, status;
wpid = waitpid (pid, &status, 0);
if (wpid < 0) {
perror("waitpid");
exit(1);
}
if (wpid != pid) {
fprintf(stderr, "unexpected pid reaped: %d\n", wpid);
exit(1);
}
if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
fprintf(stderr, "child exited unhappily\n");
exit(1);
}
}
int
main(int argc, char *argv[])
{
int pid, i;
if(argc != 3){
fprintf(stderr, "Usage: test-lab-4-b dir1 dir2\n");
exit(1);
}
sprintf(d1, "%s/d%d", argv[1], getpid());
if(mkdir(d1, 0777) != 0){
fprintf(stderr, "test-lab-4-b: failed: mkdir(%s): %s\n",
d1, strerror(errno));
exit(1);
}
sprintf(d2, "%s/d%d", argv[2], getpid());
if(access(d2, 0) != 0){
fprintf(stderr, "test-lab-4-b: failed: access(%s) after mkdir %s: %s\n",
d2, d1, strerror(errno));
exit(1);
}
setbuf(stdout, 0);
for(i = 0; i < sizeof(big)-1; i++)
big[i] = 'x';
printf("Create then read: ");
create1(d1, "f1", "aaa");
check1(d2, "f1", "aaa");
check1(d1, "f1", "aaa");
printf("OK\n");
printf("Unlink: ");
unlink1(d2, "f1");
create1(d1, "fx1", "fxx"); /* checknot f1 fails w/o these */
unlink1(d1, "fx1");
checknot(d1, "f1");
checknot(d2, "f1");
create1(d1, "f2", "222");
unlink1(d2, "f2");
checknot(d1, "f2");
checknot(d2, "f2");
create1(d1, "f3", "333");
check1(d2, "f3", "333");
check1(d1, "f3", "333");
unlink1(d1, "f3");
create1(d2, "fx2", "22"); /* checknot f3 fails w/o these */
unlink1(d2, "fx2");
checknot(d2, "f3");
checknot(d1, "f3");
printf("OK\n");
printf("Append: ");
create1(d2, "f1", "aaa");
append1(d1, "f1", "bbb");
append1(d2, "f1", "ccc");
check1(d1, "f1", "aaabbbccc");
check1(d2, "f1", "aaabbbccc");
printf("OK\n");
printf("Readdir: ");
dircheck(d1, 1);
dircheck(d2, 1);
unlink1(d1, "f1");
dircheck(d1, 0);
dircheck(d2, 0);
create1(d2, "f2", "aaa");
create1(d1, "f3", "aaa");
dircheck(d1, 2);
dircheck(d2, 2);
unlink1(d2, "f2");
dircheck(d2, 1);
dircheck(d1, 1);
unlink1(d2, "f3");
dircheck(d1, 0);
dircheck(d2, 0);
printf("OK\n");
printf("Many sequential creates: ");
createn(d1, "aa", 10);
createn(d2, "bb", 10);
dircheck(d2, 20);
checkn(d2, "bb", 10);
checkn(d2, "aa", 10);
checkn(d1, "aa", 10);
checkn(d1, "bb", 10);
unlinkn(d1, "aa", 10);
unlinkn(d2, "bb", 10);
printf("OK\n");
printf("Write 20000 bytes: ");
create1(d1, "bf", big);
check1(d1, "bf", big);
check1(d2, "bf", big);
unlink1(d1, "bf");
printf("OK\n");
printf("Concurrent creates: ");
pid = fork();
if(pid < 0){