⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.pl

📁 ICS 课程的Lab8
💻 PL
字号:
#!/usr/bin/perluse strict;use LWP;use HTML::LinkExtor;use URI::URL;use File::Copy;use FileHandle;use Socket;use POSIX qw(ctime);use POSIX qw(mktime);use POSIX qw(strftime);use POSIX qw(ceil);use POSIX ":sys_wait_h";#### Declarations and Initializationmy $CLASS_HOME = "/afs/cs.cmu.edu/academic/class/15213-s02/";my $ASSN_HOME = "$CLASS_HOME/labs/L7/";my $TESTS_HOME = "$ASSN_HOME/tests/";my $PROXY_LOGFILE;my $PROXY_FILTER = "proxy.filter";my $PROXY_FORWARD = "$TESTS_HOME/proxy.forward";my $PROXY_TEST = "proxy.test";my @filter_tests = ();my @forward_tests = ();my $PORT = 3128;my $PWD = `pwd`;my $MYLOG;my $current_time = time;my ($i, @ctests);my %options = ('debug' => 1);my $PID;my $PART1 = 0;my $PART2 = 0;my $correctness_score;my $threading_score;my $cmd;my $testcase;#### Objectsmy $UA = new LWP::UserAgent;my $LE = HTML::LinkExtor->new();$UA->agent("Mozilla/8.0");$UA->timeout(60);#### Print usage informationsub print_usage {    die "usage: ./driver.pl [port_number] [proxy-log] [lab-part]\n";}#### Reads an entire file.sub read_file {    my $file = shift;    my $contents;    open MYFILE, "< $file" or return undef;    $contents = "";    while (<MYFILE>) {	$contents .= $_;    }    close MYFILE;    return $contents;}#### partners()## Returns the Andrew IDs of the two students specified as partners in proxy.c# Also returns the team namesub team {    my $dir = shift;    my $team = "";    my ($latest_file, $file, $file_contents, $temp, $temp2);    $file_contents = read_file("proxy.c");    $temp = index $file_contents, "{", (index $file_contents, "team_struct");    $temp2 = substr $file_contents, $temp + 1, ((index $file_contents, "}", $temp) - $temp - 1);    my @struct_lines = split /\n/, $temp2;    $temp = 0;    foreach $temp2 (@struct_lines) {	chomp $temp2;	if ($temp2 =~ /\"(.*)\"(,|;)?/) {	    ++$temp;	    if ($temp == 2) {		$team = $1;	    }	    if ($temp == 4) {		$team .= "+";		$team .= $1;	    }	}    }    return $team;}sub gradeof {    my ($crashes, $total) = @_;    return $total - $crashes;}sub run_proxy {    my $x;    ###    # Remove the logfile    unlink $PROXY_LOGFILE;    ###    # Set up the UA correctly    $UA->proxy('http', "http://localhost:$PORT/");    ###    # Run the proxy    my $pid = fork;    return -1 if(!defined $pid);    if (!$pid) {	print "./proxy $PORT\n";	exec ("./proxy $PORT");	exit 10;    } else {	# Wait a little while and make sure it didn't crash up front	sleep 3;	$x = waitpid(-1, &WNOHANG);	if ($x == $pid) {	    print "Oops, proxy crashed! exit this test...\n";	    return -1;	}    }    return $pid;}sub parse_test {    my $file = shift;    my $url;    my $method;    my @headers = ();    open FILE, "< $file";    while (<FILE>) {	chomp;	last if($_ eq "");	if ($_ =~ /(\S+):\s+(.*)/) {	    push @headers, ($1 => $2);	} elsif ($_ =~ /(\S+)\s+(\S+)(\s+.*)?$/) {	    $method = $1;	    $url = $2;	} else {	    die ("Invalid line: $_");	}    }    close FILE;    return ($method, $url, @headers);}sub check_log_entry {    my $log_entry = shift;    my $url = shift;    return 1 if ($log_entry =~ /(\d+\.\d+\.\d+\.\d+)\s+$url\s+\d+/);    return 0;}sub do_request {    my $url = shift;    # Send the request    my $headerobj = new HTTP::Headers();    my $response = $UA->request(HTTP::Request->new("GET" => $url, $headerobj));    my $reply = $response->content();    return $reply;}sub test_filtering {    my $needed = shift;    my $passed;    my ($tests, $tried);    my $random = rand(20000) % 6;    @filter_tests = ();    open FILTER_FILE, $PROXY_FILTER;    while (<FILTER_FILE>) {	chomp;	$tests++;	if ($tests % 10 == $random) {	    push @filter_tests, $_;	    print "\t Request $_ ...\n";	    my $reply = do_request $_;	    if ($reply =~ /Forbidden/i || $reply =~ /Error/i) {		$passed++;		print "\t \t passed\n";	    }	    else {		print "\t \t did not pass\n";	    }	    $tried++;	    last if ($tried == $needed);	}    }    close FILTER_FILE;    return $passed;}sub test_forwarding {    my $needed = shift;    my ($passed, $tried);    my $random = rand(20000) % 10;    @forward_tests = ();    open FORWARD_FILE, $PROXY_FORWARD;    while (<FORWARD_FILE>) {	chomp;	my ($url, $filename) = split;	push @forward_tests, $url;	print "\t Request $url ...\n";	my $reply = do_request($url);	my $expected = read_file $TESTS_HOME.$filename;	if ($reply ne $expected) {	    print "\t \t did not pass\n";	}	else {	    $passed++;	    print "\t \t passed\n";	}	$tried++;	last if ($tried == $needed);    }    close FORWARD_FILE;    return $passed;}sub test_logfile {    my $score;    sleep(2);    my $existlog = 1;    open(LOG, "< $PROXY_LOGFILE") or $existlog = 0;    if ($existlog == 0) {	print "\t \t did not pass not exist\n";    }    else {	# Just checking the last line should be good enough...	my @lines = <LOG>;	if (check_log_entry($lines[$#lines], $forward_tests[$#forward_tests])) {	    $score += 3;	    print "\t \t passed\n";	} else {	    $score += 2;	    print "\t \t did not pass the last line wrong\n";	}    }    close LOG;    return $score;}############################################################## PART I: test correctness##    Grading criteria for correctness (total 15)#       5   filtering#       5   forwarding#       3   logging#       2   SIGPIPE handling############################################################sub test_correctness {    $PID = run_proxy();    return -1 if($PID == -1);    print "\nTesting Correctness...\n" if($options{'debug'});    print "\n  1. Testing filtering...\n" if($options{'debug'});    my $score = test_filtering(5);    print "\n  2. Testing forwarding...\n" if($options{'debug'});    $score += test_forwarding(5);    print "\n  3. Testing crashing...\n" if ($options{'debug'});    my $temp = waitpid(-1, &WNOHANG);    if ($temp == $PID) {	$PORT ++;	print "Oops, proxy crashed! restarting...\n";	last if($PID == -1);	print "\t \t did not pass\n" if ($options{'debug'});    }    else {	print "\t \t passed\n" if($options{'debug'});    }    return -1 if($PID == -1);    print "\n  4. Testing log file...\n";    $score += test_logfile;	    print "\n  5. Testing SIGPIPE signal handling ...\n";    socket SOCK, AF_INET, SOCK_STREAM, getprotobyname('tcp');    my $addr = sockaddr_in($PORT, inet_aton("127.0.0.1"));    connect SOCK, $addr;    print SOCK "GET http://www.ietf.org/rfc/rfc2068.txt HTTP/1.0\r\n\r\n";    close SOCK;    sleep(5);    # Test crash?    $temp = waitpid(-1, &WNOHANG);    if ($temp == $PID) {	$PORT ++;	print "\t \t Oops, proxy crashed! did not pass\n";    } else {	$score += 2;	kill 9, $PID;	print "\t \t passed\n";    }    $PORT++;    return $score;}############################################################## PART II: test threading##   Grading criteria for threading#       2  filtering#       2  forwarding#       6  concurrency handling#############################################################sub test_threading {    $PID = run_proxy();    return -1 if($PID == -1);    print "\nTesting Threading... " if($options{'debug'});    ###    # Connect to the proxy, print a little, but not all of what we want    socket SOCK, AF_INET, SOCK_STREAM, getprotobyname('tcp');    my $addr = sockaddr_in($PORT, inet_aton("127.0.0.1"));    connect SOCK, $addr;    print SOCK "GET ";    my $passed = test_filtering(2);    $passed += test_forwarding(2);    # Test crash?    my $temp = waitpid(-1, &WNOHANG);    if ($temp == $PID) {	print "\t \t Oops, proxy crashed!\n";	close SOCK;    } else {	###	# finish our first request	###	print SOCK "http://www.google.com HTTP/1.0\r\n\r\n";	sleep(3);	close SOCK;	$passed += 6;	kill 9, $PID;    }    return $passed;}#### Main programif ($#ARGV < 2) {    print_usage();}$PORT = $ARGV[0];if ($ARGV[2] eq "part1") {    $PART1 = 1;} else {    if ($ARGV[2] eq "part2") {	$PART2 = 1;    } else {	if ($ARGV[2] eq "all") {	    $PART1 = 1;	    $PART2 = 1;	} else {	    print_usage();	}    }}$PROXY_LOGFILE = $ARGV[1];chomp $PWD;autoflush STDOUT 1;my $team = team();# test the correctnessif ($PART1 == 1) {    $correctness_score = test_correctness();}if ($PART2 == 1) {    $threading_score = test_threading();}if ($PART1 == 1) {    print "$team:\tcorrectness_score = $correctness_score\n";}if ($PART2 == 1) {    print "$team:\tthreading_score = $threading_score\n";}#open WEB, ">> $WEBLOG";#print  WEB "$current_time <tr> <td bgcolor=#EEEEEE> $team </td> ";#print  WEB "$current_time <tr> <td bgcolor=#EEEEEE> </td> ";#print  WEB "<td bgcolor=#EEEEEE> $correctness_score </td> ";#print  WEB "<td bgcolor=#EEEEEE> $threading_score </td> ";#printf WEB "<td bgcolor=#EEEEEE> %.4f </td> </tr>\n", $cacheing_score*100;#close WEB;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -