#!/usr/local/bin/perl -w use strict; my $DOC = <<"EOF"; Usage: $0 Run first: - faults - steps Args: -
- , contains packages processed by oracle_package - , , package/suite numbers such that packages/suites /.zip through /.zip will be processed by this script Constants: - Affects: -
/fault_cov_instances.txt Header: - SuiteNum, >= 1 - TstNum, >= 0 - StepNum, >= 1 - FaultNum, >= 1 - TimesExec, # times faulty line executed at SuiteNum:TstNum:StepNum for clean version (1 if faults.InMethod=0 for FaultNum) Lists each instance in which the line where fault FaultNum is located is covered by some test case in the pool (not just in the suite with SuiteNum=FaultNum). When faults.InMethod=0 for FaultNum, only the _earliest_ step of each test case where some line of the fault's java file is covered is included in this list. This is different from how steps.Cov is calculated! For steps.Cov, _every_ step of the test case where some line of the fault's java file is covered has steps.Cov=1. This script uses a ton of memory. It can crash if you try to process too many packages. EOF ; if (@ARGV != 4) { print $DOC; exit 1; } my ($table_dir, $pkg_dir, $first, $last) = @ARGV; $table_dir =~ s|/$||; $pkg_dir =~ s|/$||; my $out_file = "$table_dir/fault_cov_instances.txt_$first-$last"; if (-e $out_file) { die "$out_file already exists\n"; } my $TMP = '/tmp/strecker'; my %faults; # key = FaultNum my %faults_at_line; # key = Line, value = array of FaultNums with InMethod=1 my %faults_at_file; # key = Line, value = array of FaultNums with InMethod=0 my $faults_file = "$table_dir/faults.txt"; open(FAULTS, $faults_file) or die "Couldn't read $faults_file\n"; my $head = ; while () { chomp; my ($fault_num, $line, $mut_type, $in_method) = split; $faults{$fault_num}{'Line'} = $line; $faults{$fault_num}{'InMethod'} = $in_method; if ($in_method) { if (! defined $faults_at_line{$line}) { $faults_at_line{$line} = []; } push @{$faults_at_line{$line}}, $fault_num; } else { my ($file) = split(/:/, $line); if (! defined $faults_at_file{$file}) { $faults_at_file{$file} = []; } push @{$faults_at_file{$file}}, $fault_num; } } close(FAULTS); my %steps; # key = SuiteNum x TstNum x StepNum, value = 1 my %tst_lens; # key = SuiteNum, value = max(StepNum) for SuiteNum my %max_tst_nums; # key = SuiteNum, value = max(TstNum) for SuiteNum my $steps_file = "$table_dir/steps.txt"; open(STEPS, $steps_file) or die "Couldn't read $steps_file\n"; $head = ; while () { chomp; my ($suite_num, $tst_num, $step_num) = split; if ($first <= $suite_num && $suite_num <= $last) { $steps{$suite_num}{$tst_num}{$step_num} = 1; if (! defined $tst_lens{$suite_num} || $tst_lens{$suite_num} < $step_num) { $tst_lens{$suite_num} = $step_num; } if (! defined $max_tst_nums{$suite_num} || $max_tst_nums{$suite_num} < $tst_num) { $max_tst_nums{$suite_num} = $tst_num; } } } close(STEPS); my %fault_cov_instances; # key = FaultNum x SuiteNum x TstNum x StepNum for (my $pkg_num = $first; $pkg_num <= $last; $pkg_num++) { if (-e "$TMP/$pkg_num") { `chmod -R u+w $TMP/$pkg_num`; `rm -r $TMP/$pkg_num`; if ($?) { die "Couldn't do rm -r $TMP/$pkg_num\n"; } } `unzip -q -d $TMP $pkg_dir/$pkg_num.zip "$pkg_num/cov-cln/*.txt*"`; my $cov_cln_dir = "$TMP/$pkg_num/cov-cln"; my $suite_num = $pkg_num; my $tst_len = $tst_lens{$suite_num}; for (my $tst_num = 0; $tst_num <= $max_tst_nums{$suite_num}; $tst_num++) { my %faults_at_prev_steps; # only includes faults with InMethod=0 ### BEGIN cloned from steps ### my $tmp_file = "$TMP/last_step_cov.txt"; for (my $step_num = 1; $step_num <= $tst_len; $step_num++) { my $cov_cln_file; if ($step_num < $tst_len) { $cov_cln_file = "$cov_cln_dir/$tst_num.txt-$step_num"; } else { my $existing_files = ''; foreach my $f (("$cov_cln_dir/$tst_num.txt-$tst_len", "$cov_cln_dir/$tst_num.txt", "$cov_cln_dir/$tst_num.txt-final")) { $existing_files .= "$f " if (-e $f); } `cat $existing_files > $tmp_file`; if ($?) { die "Couldn't do cat $existing_files > $tmp_file: error $?\n"; } $cov_cln_file = $tmp_file; } my @faults_at_step; open(COVCLN, $cov_cln_file) or die "Couldn't read $cov_cln_file\n"; while () { chomp; if (m/^(.+)\s+(\d+)\s+(\d+)$/) { my ($file, $line, $times) = ($1, $2, $3); foreach my $fault_num (@{$faults_at_line{"$file:$line"}}) { if (! defined $fault_cov_instances{$fault_num}{$suite_num}{$tst_num}{$step_num}{'TimesExec'}) { $fault_cov_instances{$fault_num}{$suite_num}{$tst_num}{$step_num}{'TimesExec'} = 0; } $fault_cov_instances{$fault_num}{$suite_num}{$tst_num}{$step_num}{'TimesExec'} += $times; push @faults_at_step, $fault_num; } foreach my $fault_num (@{$faults_at_file{$file}}) { if (! $faults_at_prev_steps{$fault_num}) { $fault_cov_instances{$fault_num}{$suite_num}{$tst_num}{$step_num}{'TimesExec'} = 1; push @faults_at_step, $fault_num; $faults_at_prev_steps{$fault_num} = 1; } } } } close(COVCLN); if ($step_num == $tst_len) { `rm $tmp_file`; } } ### END cloned from steps ### } `chmod -R u+w $TMP/$pkg_num`; `rm -r $TMP/$pkg_num`; if ($?) { die "Couldn't do rm -r $TMP/$pkg_num\n"; } } open(OUT, ">$out_file") or die "Couldn't write to $out_file\n"; print OUT "SuiteNum TstNum StepNum FaultNum TimesExec\n"; my @sorted_faults = sort {$a <=> $b} keys %fault_cov_instances; my @sorted_suites = sort {$a <=> $b} keys %steps; for (my $suite_ind = 0; $suite_ind <= $#sorted_suites; $suite_ind++) { my $suite_num = $sorted_suites[$suite_ind]; my @sorted_tsts = sort {$a <=> $b} keys %{$steps{$suite_num}}; for (my $tst_ind = 0; $tst_ind <= $#sorted_tsts; $tst_ind++) { my $tst_num = $sorted_tsts[$tst_ind]; my @sorted_steps = sort {$a <=> $b} keys %{$steps{$suite_num}{$tst_num}}; for (my $step_ind = 0; $step_ind <= $#sorted_steps; $step_ind++) { my $step_num = $sorted_steps[$step_ind]; for (my $fault_ind = 0; $fault_ind <= $#sorted_faults; $fault_ind++) { my $fault_num = $sorted_faults[$fault_ind]; if (defined $fault_cov_instances{$fault_num}{$suite_num}{$tst_num}{$step_num}) { print OUT "$suite_num $tst_num $step_num $fault_num $fault_cov_instances{$fault_num}{$suite_num}{$tst_num}{$step_num}{'TimesExec'}\n"; } } } } } close(OUT); print "Finished!\n"; exit 0;