2 Star 2 Fork 1

Ethan Tang / WorkScripts

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
rtNatty.pl 21.29 KB
一键复制 编辑 原始数据 按行查看 历史
Ethan Tang 提交于 2014-08-08 15:08 . A tool to provide better RT result
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
#!/usr/bin/perl
# This script aims to provide a better rt tool with following features:
# 1. Run rt with a user-defined baseline.
# Run a 'RT' with my code without fix as baseline,
# so we will not be bothered by the diffs caused by other guys
# 2. Provide better analysis of diffs,
# 3. Provide backward compatibility with old rt tools
# 4. Provide faster RT by using parallel method and user-defined plan mode restrictions
use strict;
#use warnings;
# Columns below start from 0.
use constant COL_EDD => 116;
use constant COL_ECC => 117;
use constant COL_CS_MODE => 181;
use constant DATA_121 => '/mrpdev/msc/psldevrt/';
use constant DATA_122 => '/mrpdev/msc/psmdevrt/';
# No longer used
use constant LIST_121_QA => '/home/yantang/rt_natty/121_QA.list';
use constant LIST_121_UT => '/home/yantang/rt_natty/121_UT.list';
use constant LIST_122_QA => '/home/yantang/rt_natty/122_QA.list';
use constant LIST_122_UT => '/home/yantang/rt_natty/122_UT.list';
my %modeExclude;
my %modeInclude;
my $isEdd;
my $fromRTTxt;
my $exeA;
my $exeB;
my $mailAddr; # When RT ended, report result to this mail address if defined
my $rtDataDir;
my @QAList;
my @UTList;
# load: loadColumnNamesMap
# find: getColumnNameFromIndex
my %columnNamesMap; # MSLDXXX.dat => [ col1,col2,col3 ]
# A list of plans that will be run in the final.
my @planToRunList; # [data location (UT/QA), planName, csMode, ecc|edd ]
my $startTime = time;
#main
&processArgs();
&getRTDataDir();
&filterRTPlans($fromRTTxt,\%modeInclude,\%modeExclude,$isEdd);
my $allPlanNum = $#QAList + $#UTList + 2;
my $planToRunNum = $#planToRunList + 1;
print "There are $allPlanNum in all. Plans to run in total: $planToRunNum\n";
my $maxProcess = 4;
my $child;
for( $child = 0; $child<$maxProcess; $child++ )
{
print "Forking child $child...\n";
my $pid = fork;
if( $pid == 0 )
{
open LOG, ">rt_natty.$child" or die "Unable to open rt_natty.$child as log output:$!\n";
my $failCnt = 0;
my $diffCnt = 0;
for( my $i=$child; $i<=$#planToRunList; $i+=$maxProcess )
{
my $plan = $planToRunList[$i];
my $location = $plan->[0];
my $planName = $plan->[1];
my $log = &runWorkUnit( $location, $planName, $exeA, $exeB );
print LOG $log."\n";
print "#$child $log\n";
$failCnt++ if( $log =~ /FAIL/ );
$diffCnt++ if( $log =~ /DIFF/ );
}
# Write such line as end of current log
print LOG "LOG_END#DIFF=$diffCnt,FAIL=$failCnt\n";
close LOG;
exit 0; #Quit fork process in child process
}
}
while( wait != -1 ){};
print "All processes finished successfully\n";
#Merge Log
my $totalFail = 0;
my $totalDiff = 0;
open LOG, ">rt_natty.txt" or die "Unable to open rt_natty.txt as log output:$!\n";
my $declaration = <<END;
This file is the RT result generated by rtNatty.pl ( /home/yantang/tools/rtNatty.pl )
Arguments taken: @ARGV
Total: $allPlanNum To Run: $planToRunNum\n\n
END
print LOG $declaration;
for( $child = 0; $child<$maxProcess; $child++ )
{
open CHILD_LOG, "rt_natty.$child" or die "Unable to open rt_natty.$child for reading:$!\n";
while( <CHILD_LOG> )
{
if( /LOG_END#DIFF=(\d+),FAIL=(\d+)/ )
{
$totalDiff += $1;
$totalFail += $2;
last; #This is the last line.
}
else{
print LOG $_;
}
}
close CHILD_LOG;
system "rm -rf rt_natty.$child"; #Delete child log
}
my $endTime = time;
my $timeInterval = ($endTime - $startTime);
print LOG "\n\nFail: $totalFail Diff:$totalDiff\n";
print LOG "Time taken = $timeInterval seconds\n";
print "Fail: $totalFail Diff:$totalDiff\n";
close LOG;
print "Log has been saved as rt_natty.txt\n";
if( defined $mailAddr )
{
&reportResult( $mailAddr );
}
print "Job Complete! Time taken= $timeInterval\n";
sub printUsage
{
my $usage = <<END;
rtNatty.pl msonew1 [msonew2] [mode!=(1-3)] [mode=(1-3)] [ecc|edd] [rt_result.txt]
Run a default RT: selfrt.pl msonew
Compare rt results of two exe: selfrt.pl msonew1 msonew2
rtNatty.pl update
Reserved option, I use this to update detail list of plans
END
print $usage;
exit 0;
}
# Process args
sub processArgs
{
if( $#ARGV == -1 ) {
&printUsage;
}
foreach my $arg( @ARGV )
{
if( $arg =~ /.txt/ ) {
$fromRTTxt = $arg;
}
elsif( $arg eq 'update' ) {
&updatePlanList();
exit 0;
}
elsif( $arg =~ /mode=(\d)/ ) {
$modeInclude{$1}=1;
}
elsif( $arg =~ /mode!=(\d)/ ) {
$modeExclude{$1}=1;
}
elsif( $arg =~ /(ecc|edd)/ ) {
$isEdd = ($1 eq 'edd')?1:0;
}
elsif( $arg =~ /@/ ) {
$mailAddr = $arg;
}
else{
die "Executable doesn't exist or wrong argument:$arg\n" unless -e $arg;
die "Unknow argument:$arg\n" unless not defined $exeB;
if( defined $exeA )
{
$exeB = $arg;
}else{
$exeA = $arg;
}
}
}
# Debug
print "Use exe: $exeA $exeB\n" unless not defined $exeB;
print "Default RT using $exeA\n" unless defined $exeB;
print "Probe plan diffs in file: $fromRTTxt\n" if defined $fromRTTxt;
print "Include these modes:";
foreach my $incMode(keys %modeInclude)
{
print "$incMode\t";
}
print "\n";
print "Except these modes:";
foreach my $expMode(keys %modeExclude)
{
print "$expMode\t";
}
print "\n";
print "IsEDD: $isEdd\n" if defined $isEdd;
}
# Get the branch env, and decide which rt data directory to use
# Die when it's not available
# return: RT data path
sub getRTDataDir
{
my $mso_top = $ENV{'MSO_TOP'};
if( defined $mso_top and $mso_top =~ /(121|122)/ )
{
my $branch = $1;
if( $branch eq '121' ) {
$rtDataDir = DATA_121;
@QAList = readListFromFile( LIST_121_QA );
@UTList = readListFromFile( LIST_121_UT );
&loadColumnNamesMap( '/home/yantang/rt_natty/121.ColumnNames' );
}
if( $branch eq '122' ) {
$rtDataDir = DATA_122;
@QAList = readListFromFile( LIST_122_QA );
@UTList = readListFromFile( LIST_122_UT );
&loadColumnNamesMap( '/home/yantang/rt_natty/122.ColumnNames' );
}
}else{
die "Unrecognized branch or env MSO_TOP not set";
}
}
# Load all column name files into map columnNamesMap
# p0: ColumnNames dir to read from
sub loadColumnNamesMap
{
my $columnDir = $_[0];
print "Loading column names from $columnDir\n";
foreach my $file ( glob $columnDir.'/*.dat' )
{
$file =~ /\/(MSLD.*\.dat)/;
my $shortName = $1;
my @columns;
open COL, $file or die "Unable to open $file for reading:$!\n";
while( <COL> )
{
chomp;
if( /([0-9]+)\s+(.*)$/ )
{
@columns[ $1-1 ] = $2;
#print "$1\t$2\n";
}
}
close COL;
$columnNamesMap{ $shortName } = \@columns;
#print "#Loaded $#columns from $shortName\n";
}
}
# Get the column name from index given ( 0-N )
# p0: flat file name
# p1: index
# return: column name string
sub getColumnNameFromIndex
{
my $file = $_[0];
my $index = $_[1];
my $ret = "unknown";
if( $file =~ /\// ) {
$file =~ /\/(MSLD.*\.dat)/ ;
$file = $1;
}
if( exists $columnNamesMap{ $file } )
{
my $columns = $columnNamesMap{ $file };
if( defined $columns->[ $index ] )
{
$ret = $columns->[ $index ];
}
}
$ret;
}
# Filter the plans so we can decide which plan to use
# p0: rt_text
# p1: hash ref of plan modes that includes
# p2: hash ref of plan modes that excludes
# p3: ecc|edd plan
# return: a list of plans that to be running
sub filterRTPlans
{
my $fromRTTxt = $_[0];
my $incRef = $_[1];
my $excRef = $_[2];
my %modeInclude = %$incRef;
my %modeExclude = %$excRef;
my $planType = $_[3];
# filter plans by a rt_result.txt, this will shields all other options
if( defined $fromRTTxt ) {
open RT_DIFF, '<'.$fromRTTxt or die "Unable to open $fromRTTxt to read:$!\n";
while( <RT_DIFF> )
{
chomp;
if( /(.*)\s=\sDIFF/ ) {
if( -d $rtDataDir.'UT/'.$1 ) {
push @planToRunList, [$rtDataDir."UT/$1",$1];
}elsif( -d $rtDataDir.'QA/'.$1 ) {
push @planToRunList, [$rtDataDir."QA/$1",$1];
}
}
}
} else {
# Filter plans by only allowing mode that matches
my @kInclude = keys %modeInclude;
my @kExclude = keys %modeExclude;
my $i;
for( $i=0; $i<=$#QAList; $i++ )
{
my $plan = $QAList[$i];
if( $#kInclude != -1 and not exists $modeInclude{$plan->[1]} )
{
undef $QAList[$i];
}
if( $#kExclude != -1 and exists $modeExclude{$plan->[1]} )
{
undef $QAList[$i];
}
if( defined $isEdd and $plan->[2] != 1 )
{
undef $QAList[$i];
}
if( defined $QAList[$i] )
{
push @planToRunList, [ $rtDataDir."QA/$plan->[0]",$plan->[0] ];
}
}
for( $i=0; $i<=$#UTList; $i++ )
{
my $plan = $UTList[$i];
if( $#kInclude != -1 and not exists $modeInclude{$plan->[1]} )
{
undef $UTList[$i];
}
if( $#kExclude != -1 and exists $modeExclude{$plan->[1]} )
{
undef $UTList[$i];
}
if( defined $isEdd and $plan->[2] != 1 )
{
undef $UTList[$i];
}
if( defined $UTList[$i] )
{
push @planToRunList, [ $rtDataDir."UT/$plan->[0]",$plan->[0] ];
}
}
}
}
# helps to refresh plan list file so we can save much time in searching plan type/cs mode
# create plan list of all plans of 121/122 RT , and save them in
# ~yantang/rt_natty/, named 121_QA.list 121_UT.list, 122_QA.list,122_UT.list respectively
sub updatePlanList
{
print "Updating file list of 121/122 RT plans...\n";
my @planList;
#@planList = probeDirForPlanList( DATA_121.'QA' );
@planList = readListFromRTSuite( DATA_121.'QA/list' );
writeListToFile( \@planList, LIST_121_QA );
#@planList = probeDirForPlanList( DATA_121.'UT' );
@planList = readListFromRTSuite( DATA_121.'UT/list' );
writeListToFile( \@planList, LIST_121_UT );
#@planList = probeDirForPlanList( DATA_122.'QA' );
@planList = readListFromRTSuite( DATA_122.'QA/list' );
writeListToFile( \@planList, LIST_122_QA );
#@planList = probeDirForPlanList( DATA_122.'UT' );
@planList = readListFromRTSuite( DATA_122.'UT/list' );
writeListToFile( \@planList, LIST_122_UT );
print "Jobs done!\n";
}
# Read plan list from suite file, and probe the plan content
sub readListFromRTSuite
{
my $suiteList = $_[0];
my @planList;
open SUITE_LIST, $suiteList or die "Unable to open $suiteList for reading:$!\n";
$suiteList =~ /(.*)list$/;
my $dataPath = $1;
my %colMap = ( 'constrained_mode' => 1,
'enforce_dem_due_dates' => 1,
'enforce_cap_constraints' => 1,
'daily_material_constraints' => 1,
'weekly_material_constraints' => 1,
'period_material_constraints' => 1,
'daily_resource_constraints' => 1,
'weekly_resource_constraints' => 1,
'period_resource_constraints' => 1 );
my $neededColumns = 'constrained_mode,enforce_dem_due_dates,enforce_cap_constraints,daily_material_constraints,weekly_material_constraints,period_material_constraints,daily_resource_constraints,weekly_resource_constraints,period_resource_constraints';
while( <SUITE_LIST> )
{
chomp;
next if( /#/ );
next if( /^[^\d\w]+$/ ); #Skip that do not likely to be a plan record
my $entry = $_;
my $flatPlan = $dataPath.$entry.'/mbpoutput/MSLD_FLAT_PLAN.dat';
if( $colMap{'constrained_mode'} == 1 ) {
%colMap = &getColumnIndexHash( $flatPlan );
}
if( -e $flatPlan )
{
open FLAT_PLAN, $flatPlan or die "Unable to open $entry for reading:$!\n";
my @lines = <FLAT_PLAN>;
chomp $lines[0];
my @values = split( //,$lines[0]);
if( $#values > COL_CS_MODE )
{
my $isEdd = ($values[$colMap{'enforce_dem_due_dates'}]==1)?1:0;
my $csMode = $values[$colMap{'constrained_mode'}];
###########################################################################
# Thanks to damn mbp, I have to add more than 100 lines for their damn code
# when constrained_mode = -23453, we have to deal with its 'real' mode.
# Logic taken from mslflt.ppc in patch 17484362_R12.MSC.B
###########################################################################
if( $csMode == -23453 ) {
if( $values[ $colMap{'daily_material_constraints'} ] == 2 and
$values[ $colMap{'weekly_material_constraints'} ] == 2 and
$values[ $colMap{'period_material_constraints'} ] == 2 and
$values[ $colMap{'daily_resource_constraints'} ] == 2 and
$values[ $colMap{'weekly_resource_constraints'} ] == 2 and
$values[ $colMap{'period_resource_constraints'} ] == 2
){
$csMode = 0;
}else{
$csMode = 1;
}
print "Adding $entry with cs mode -23453 as $csMode\n";
}
#print "#Adding $entry\n";
push @planList, "$entry,$csMode,$isEdd";
}else{
print "No enough columns in $flatPlan: $#values columns given ( start from 0 )\n";
}
close FLAT_PLAN;
}else{
print "$entry doest exist, skip\n";
}
}
close SUITE_LIST;
@planList;
}
# To find all plans under given directory and load them into a list
# p0: data to probe
# return: plan list : [planName, constrained Mode, isEdd]
sub probeDirForPlanList
{
my $dirName = $_[0];
my @planList; #[planName, constrained Mode, isEdd]
opendir DIR, $dirName or die "Unable to open directory $dirName:$!\n";
my @files = readdir DIR;
foreach my $entry (@files)
{
next if( $entry =~ /\./ ); #Skip dir contains dot
next unless ( -d $dirName.'/'.$entry ); #Skip non-dir entries
my $flatPlan = $dirName.'/'.$entry.'/mbpoutput/MSLD_FLAT_PLAN.dat';
if( -e $flatPlan )
{
open FLAT_PLAN, $flatPlan or die "Unable to open $entry for reading:$!\n";
my @lines = <FLAT_PLAN>;
chomp $lines[0];
my @values = split( //,$lines[0]);
if( $#values > COL_CS_MODE )
{
my $ecc = $values[COL_ECC];
my $isEdd = ($values[COL_EDD]==1)?1:0;
my $csMode = $values[COL_CS_MODE];
#print "#Adding $entry\n";
push @planList, "$entry,$csMode,$isEdd";
}else{
print "No enough columns in $flatPlan: $#values columns given ( start from 0 )\n";
}
close FLAT_PLAN;
}else{
print "$entry doest exist, skip\n";
}
}
closedir DIR;
@planList;
}
# write a plan list to given file, clear original content if exists
# format: planName,csmode,isEdd
# p0: array ref of plan listm
# p1: file to write
sub writeListToFile
{
my $refPlanList = $_[0];
my $fileName = $_[1];
open LIST_FILE, '>'.$fileName or die "Unable to open $fileName for writing: $!\n";
foreach my $planRecord ( @$refPlanList )
{
print LIST_FILE "$planRecord\n";
}
close LIST_FILE;
}
# read plan list to be used from given file
# p0: file to use
# return: list from file
sub readListFromFile
{
my $fileName = $_[0];
print "#Reading list from $fileName\n";
my @planList;
open LIST_FILE, $fileName or die "Unable to open $fileName for reading:$!\n";
while( <LIST_FILE> )
{
chomp;
if( /(.*),(.*),(.*)/ ) {
push @planList, [$1,$2,$3];
#print "#read:$_\n";
}
}
close LIST_FILE;
@planList;
}
#Index returned begins from 0, so we can use to array easily
# It gets columnname hash from column files in /home/yantang/rt_natty/ by default
# If not found, take columns from MSC_TOP
sub getColumnIndexHash
{
my %colIndex;
my $fileName = $_[0];
my $branch = '121';
if( $fileName =~ /psl/ ) {
$branch = '121'
}elsif( $fileName =~ /psm/ ) {
$branch = '122';
}elsif( defined $_[1] ) {
$branch = $_[1];
}
$fileName =~ /([^\/]+)$/;
my $shortName =$1;
my $columnFile = '/home/yantang/rt_natty/'.$branch.'.ColumnNames/$shortName';
if( not -e $columnFile )
{
my $msc_top = $ENV{'MSC_TOP'};
die "No env var MSC_TOP found while columns not available" unless ( defined $msc_top );
$columnFile = $msc_top."/ColumnNames/$shortName";
#Output load schema info so usr will know
die "Cannot find schema for $shortName" if( not -e $columnFile );
}
#Comment this to make output cleaner
#print "Load schema from $columnFile\n";
open COL_FILE , $columnFile or die "##getColumnIndexHash:Unable to open $columnFile :$!\n";
my $index = 0;
while( <COL_FILE> )
{
chomp;
if( /([0-9]+)\s+(.*)$/ )
{
$colIndex{$2} = $1;
#print "$1\t$2\n";
}
}
close COL_FILE;
return %colIndex;
}
# Get a index-columnName table, start from 0
sub getIndexColumnTable
{
}
# a awk utility directly inserted into perl so we don't need to create PIPES to call tak
#param0: condition in text format
#param1: columns to get, split by comma
#param2: flat file to be explored
#return: an reference to a double-direction array containing columns expected.
#Errors: when no records found or
sub pawk
{
my $condition = $_[0];
my $action = $_[1];
my $fileName = $_[2];
my @dblArray;
my %colIndex = &getColumnIndexHash($fileName);
# /g returns results of an array matching reg
foreach my $key( $condition =~ /([a-zA-Z_]+)[+-~=><& ]/g )
{
if( exists $colIndex{$key} )
{
my $index = $colIndex{$key};
$condition =~ s/$key/\$$index/;
}
}
my $colCount = 0;
$colCount++ while( $action =~ /,/g );
foreach my $key( $action =~ /([a-zA-Z_]+)/g )
{
if( exists $colIndex{$key} )
{
my $index = $colIndex{$key};
$action =~ s/$key/\$$index/;
}
}
my $command = 'awk -F '. '\'{ if('. $condition . ') print '. $action .'}\' ' . $fileName;
#print "Command:$command\n";
unless ( open PIPE, "-|" )
{
exec $command;
exit;
}
my $recordCount = 0;
while( <PIPE> )
{
my @values = split( /\s/, $_ );
#If we encountered error, tell us what awk command we used, and the output as well
die "##pawk: awk execution error\n##Command:$command\n##Output:$_\n" unless ($#values eq $colCount);
push @dblArray, [@values];
++$recordCount;
}
print STDERR "No output from awk on file $fileName \n" unless ( $recordCount ne 0 );
close PIPE;
\@dblArray;
}
# This functions complete a 'work unit' that will be done in one of the processes
# When running classic RT ( Only one exe specified in argument and compares output with RT mbpoutput_reference ),
# we take such a single exe running/diff as a 'work unit'.
# When running our self-defined RT , with two exe given and user want to compare their RT results,
# we take the running process of two exe and their diff as a 'work unit'
# p0: location of the plan data dir
# p1: planName
# p2: exeA
# p3: exeB
# return: a multi-line string that can be used in the log directly.
sub runWorkUnit
{
my $dataLocation = $_[0];
my $planName = $_[1];
my $exeA = $_[2];
my $exeB;
$exeB = $_[3] if( defined $_[3] );
my $log = "$planName ";
if( -d $planName ) {
system "rm -rf $planName >/dev/null";
}
mkdir $planName;
chdir $planName;
### Operate on under $planName ###
mkdir 'data';
#`ln -s $dataLocation/mbpinput data/mbpinput`;
system "cp -r $dataLocation/mbpinput data/";
mkdir 'data/mbpoutput';
system "cp $dataLocation/mbpoutput/*.dat data/mbpoutput";
system "../$exeA flatfile 0 Y 0 >logA";
my $retA = system "grep \"Flat file Success\" logA >/dev/null";
$retA = $retA >> 8;
if( $retA != 0 ) {
$log .= " FAIL:$exeA ";
}
my $refDir = 'data/mbpoutput_reference';
my $retB = 0;
if( defined $exeB ) {
$refDir = 'data/mbpoutput_reference';
system "cp -r data/mbpoutput $refDir >/dev/null";
system "../$exeB flatfile 0 Y 0 >logB";
$retB = system "grep \"Flat file Success\" logB >/dev/null";
$retB = $retB >> 8;
if( $retB != 0 ) {
$log .= " FAIL:$exeB ";
}
}
else{
if( -e $dataLocation.'/mbpoutput_reference.zip' ) {
my $unzipCommand = "unzip -o -q $dataLocation/mbpoutput_reference.zip -d data/ >/dev/null";
#print "Command=$unzipCommand\n";
system $unzipCommand;
die "Unable to unzip mbpoutput_reference.zip for $planName\n" unless ( -e 'data/mbpoutput_reference' );
}
else{
print "Error: Unable to find mbpoutput_reference.zip for $planName, SKIP\n";
return;
}
}
my $hasDiff = 0;
# Run diff on plans that donot fail
if( $retA == 0 and $retB == 0 )
{
my $retLog = &diffOutput( $refDir ,'data/mbpoutput' );
if( $retLog ne "" )
{
$log .= $retLog;
$hasDiff = 1;
}
}
else{
$hasDiff = 1;
}
chdir '..';
# Clear up remains if there's no diff
if( not $hasDiff ) {
system "rm -rf $planName";
}
### Leave dir $planName
$log;
}
# Compare .dat files under two mbpoutput dir
# p0: output1
# p1: output2
# return: a string contains the diff content. empty otherwise
sub diffOutput
{
my $outA = $_[0];
my $outB = $_[1];
my $log = "";
foreach my $file (glob $outA.'/*.dat')
{
next unless $file =~ /(MSLD.*\.dat)/;
if( -e "$outB/$1" )
{
$log .= &compareFile( $file, "$outB/$1" );
}else{
$log .= "DIFF $file: Doesn't exist in $outB/$1\n";
}
}
#print $log;
$log;
}
# Compare two files. If it's not the same, we will analyze the columns with diff
# But we only analyze first diff line to save time!
# p0: 1st file
# p1: 2st file
# return: a string contains the diff analyzation. empty otherwise
sub compareFile
{
my $diffRet = "";
$_[0] =~ /(MSLD.*)\.dat$/;
my $shortName = $1;
open FA, $_[0] or die "Unable to open $_[0] for reading!\n";
open FB, $_[1] or die "Unable to open $_[1] for reading!\n";
my @linesA = <FA>;
my @linesB = <FB>;
if( $#linesA != $#linesB ) {
$diffRet .= "DIFF $shortName: lines donot match: $#linesA $#linesB\n";
}
for( my $i=0;$i<=$#linesA and $i<=$#linesB ;$i++ )
{
if( $linesA[$i] ne $linesB[$i] )
{
$diffRet .= "DIFF $shortName at line $i:";
my @va = split( //, $linesA[$i] );
my @vb = split( //, $linesB[$i] );
$diffRet .= "columns donot match $#va $#vb " if( $#va != $#vb );
for( my $i=0;$i<=$#va and $i<=$#vb; $i++ )
{
if( $va[$i] ne $vb[$i] )
{
my $diffColName = &getColumnNameFromIndex( $_[0], $i );
$diffRet .= $diffColName."($i) ";
}
}
last;
}
}
close FA;
close FB;
#print $diffRet;
$diffRet;
}
# Report rt result to specified mail address
# p0: mail address
sub reportResult
{
my $mailAddr = $_[0];
my $subject = '#RT Natty Report#';
print "Sending report to $mailAddr\n";
my $command = 'mail -s "'.$subject.'" '.$mailAddr.'<rt_natty.txt';
system( $command );
}
Perl
1
https://gitee.com/stargate/WorkScripts.git
git@gitee.com:stargate/WorkScripts.git
stargate
WorkScripts
WorkScripts
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891