package Test::AutomationFramework; use 5.010001; use strict; use warnings; use Date::Manip; use File::Path; #use Test::More; use Getopt::Long; use File::Copy; use File::Copy::Recursive qw(fcopy rcopy dircopy fmove rmove dirmove); use File::Find; use Regexp::Assemble; use Cwd; use IO::Socket; # might not work in http mode #if ($^O =~ /win32/i) { use Term::ReadKey; } use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); $| = 1; require Exporter; our @ISA = qw(Exporter); our %EXPORT_TAGS = ( 'all' => [ qw( ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( help processTCs processTC processProperty genDriver_taf_pl genDriver_taf_cgi genDriver_taf_svr initTAF printVersion printTAFVersion printOSVersion fetchmail installTestbed deleteTestbed ); our $VERSION = '0.060.05'; ###################### TAF Global Variables ############################### my %tsProperty ; my %tsPropertyRoot; my %tafProperty ; my %tafPropertyRev; my $propertyOp=''; my $regression=0; my $help=0; my $sleep4Display = 1; my $notUsegetTCName= 0; my %recordTags=(); my $tcIdCtr=0 ; my $tsDriver = "null" ; # cmd-line-overwrite $testDriverName (generated by -e .. index.pl or index.ps1) my $pr2Screen = 1 ; my $tcIdMin= 0 ; my $reportHtmlSummaryStr = ''; # String for mouse-over display TC summary my $Execution_24_7 = "n"; my $Execution_24_7_title= "y"; my $Execution_local_only= "n"; my $Execution_from_cgi = "n"; my $NofExecution = "1"; my $NofExecutionCtr=0; my $NofExecutionCtrExec=0; my $ExecutionLength = "10000 hour"; my $ExecutionType = '>'; my @tcDesc; my $tsFilter=".*"; my $exitTAFTCId ; my $tcComment1 ="Comment1"; my $tcComment2 ="PlaceHolderforComment2"; my $MaxTCExecTime = 10 ; my $NofPropertyExecCtr = 0 ; my $NofPropertyExec = 0 ; my $tags ="_full_,_smoke_,_smoketest_,_regression_,_regressiontest_,_bat_,_32bit_,_64bit_,_list_,_load_,_erase_,_install_"; my $TSHookIsPerl = "n"; my $outputFormat = "text"; # noOutput my $htmlRefreshRate = 200; my $htmlRefreshRateWebUI= 200; my $htmlRefreshRateLogUI= 200; my $createOrAppendTS = "create"; #"append"; # create my $outputPause = 0; my $titleStatus = ""; my $perl = $^X; $perl =~ s/\\/\\\//g; # todo3 \\ linux my $perl_ = $^X; $perl_=~ s/\\/\//g; # todo3 \\ my $listAll_var =""; ###################### TAF Generated Variables ############################### my $scriptName = $0; $scriptName =~ s/\\/\//g; # linux my $workingDir = getcwd(); my $TSHookName = "index.pl"; my $TSHookNameParent = "indexindex.pl"; my $TSHookNameGenerated = "index.pl"; my $createTS_index = "createTS_index.pl"; my $createTS_indexindex = "createTS_indexindex.pl"; ###################### TAF Default Variables ############################### my $overWriteTC = "y"; my $interact = "n"; my $tcPropertyPatternName = "tcRunResult"; my $tcPropertyPatternPattern = ".*"; my $tcPropertyPatternName1 = "tcRunResult"; my $tcPropertyPatternPattern1 = ".*"; my $tcPropertyPatternName2 = "tcRunResult"; my $tcPropertyPatternPattern2 = ".*"; my $tcPropertyPatternName3 = "tcRunResult"; my $tcPropertyPatternPattern3 = ".*"; my $tcPropertyName = "all"; my $tcPropertyPattern = Regexp::Assemble->new; my $tcNamePattern = "TC*"; my $tcOp = 'list'; my $tcCtr = 0; my $tcDelta = 20; my $markSymbol = '|'; my $cgi_bin = "/"; if ( $^O =~ /MSWin32/ ) {; } elsif ($^O =~ /linux/i) { $cgi_bin = "/" ; } my $c = "c:"; if ( $^O =~ /MSWin32/ ) {; } elsif ($^O =~ /linux/i) { $c= "/tmp/var/www/cgi-bin" ; } my $ping = "C:/Windows/System32/ping.exe -n 1 "; if ( $^O =~ /MSWin32/ ) {; } elsif ($^O =~ /linux/i) { $ping = "/bin/ping -c 1 " ; } my $deli = ";"; if ( $^O =~ /MSWin32/ ) {; } elsif ($^O =~ /linux/i) { $deli = '~' ; } my $copy = "copy"; if ( $^O =~ /MSWin32/ ) {; } elsif ($^O =~ /linux/i) { $copy= 'copy' ; } my $http_port = ":8080"; if ( $^O =~ /MSWin32/ ) {; } elsif ($^O =~ /linux/i) { $http_port= ":1234" ; } my $_realSemi_ = ";"; if ( $^O =~ /MSWin32/ ) {; } elsif ($^O =~ /linux/i) { $_realSemi_ = '&' ; } my $taf = "taf.pl"; my $tafCGI = "taf.cgi"; my $SUTSymbol = "_"; my $tsFilterDefault = "_"; my $tcFilterDefault = ".*"; my $_TAF = "_TAF"; # very useful variable my $NofTCinTSTemplate = -1; # very useful variable my $SvrDrive = $c.'/'.$_TAF; # *:will be reset later in generated variable section my $SvrProjName = '_testsuite1_'; my $SvrProjNameSub = ''; my $SvrTCName = '_testcase1_'; my $SvrTCNamePattern = "*"; my $SvrPropNamePattern = '.*'; my $SvrPropValuePattern = ".*"; my $SvrTCNameExecPattern = ".".$SvrTCNamePattern; # * my $SvrLogDir = ''.$SvrProjName.''; # * my $ps1_args = "-ps1_args___powershell_args"; # should not include -ps1_args my $exitTAFGracefullyLock = $c.'/'.$_TAF.'/'."_exitTAFGracefully_.txt"; # * my $exitTAFGracefullyString = 1; my $performanceMode = "slow4webUI"; # fast4cmd my $generateTestsuiteBAT = $c.'/'.$_TAF."/taf_generateTestsuite.bat"; # * my $tsFrom =""; my $tsTo =""; my $resetTSFileName =""; my $externalLogName ="$c/$_TAF/externalLog.txt"; # * my $commandLogName ="$c/$_TAF/_cmdLogs.txt"; # * my $commandLogLifeSpan = "-3 days"; my $queueSizeLimit = 10000; ###################### TAF WebUI Default Settings ############################### my $webUITreeViewLevel = 20; my $excelReportColumnWidth = 9; my $AutomationtsName ="Automation_MVSDK"; my $makeMark = 'n'; my $makeMarkComment = ''; my $makeMarkLastDay = &getExecDay(); my $web_ui_title ="Test Automation Framework"; my $webUI_TCDescWidth = 120; # <<<<<<<<<<<<<< my $scrollAmount = 0; my $borderWidth = 0; my $borderStyle = "SOLID"; my $passFailDisplayWidth = 8; # TS Variable. Should be reset for each TS execution my $maxPassFailDisplayWidth = 40; my $reportHtmlSummaryScale = 3600; # in seconds my $reportHtmlSummaryScaleMajor = 12; # in seconds my $tsProperty = 'tsProperty.txt'; my $tsPropertyWidth = 150; # <<<<<<<<<<<<<<<<< my $testcaseNode = "testcase" ; my $testType = "ts"; # ts for testsuite my $reportHtml = 'index.htm'; my $reportHtml1 = '_tcReport_.html'; my $reportHtmlHistory = '_tcReportHistory_.html'; my $reportHtmlSummary = '_tcReportSummary_.html'; my $tc_pl = "tc.pl"; my $reportHtml_http = 'index_http.htm'; # $reportHtml."_http"; my $reportHtml1_http = '_tcReport_.html'."_http"; my $reportHtmlHistory_http = '_tcReportHistory_.html'."_http"; my $web_ui_title_tip = "Run TAF-Team Version based on IIS/httpd"; my $hostname = "localhost"; my $ip = "127.0.0.1"; my $rst = `$ping $hostname`; if ($rst =~ /Ping request could not/i) { $web_ui_title_tip = "Click to update every TAF testsuites";} elsif ($rst =~ /unknown/i) { $web_ui_title_tip = "Click to update every TAF testsuites";} else { $hostname = `hostname`; chop $hostname; $ip = inet_ntoa((gethostbyname($hostname))[4]); } my $queueFName = "taf.queue"; my $lockFName = "$c/$_TAF/taf.lock"; my $url = 'file:///'.$SvrDrive; # will be updated in the sub-processTCs my $urlHttp = 'http://'.$ip.$http_port; # will be updated in the sub-processTCs my $indexTitleRefresh = sprintf(" "); my $indexTitleRefreshCGI= sprintf(" "); my $indexTitleRefreshRoot = sprintf(" "); my $indexTitleRefreshCGIRoot= sprintf(" "); if (-e "$c/$_TAF/_tafGlobalVars.txt") { &readTAFGlobalVars(); } else { &printTAFGlobalVars();} # Global Variables ######### Generated Variables $SvrDrive = $c.'/'.$_TAF; $exitTAFGracefullyLock = $c.'/'.$_TAF.'/'."_exitTAFGracefully_.txt"; $SvrTCNameExecPattern = ".".$SvrTCNamePattern; # * $SvrLogDir = ''.$SvrProjName.''; # * $generateTestsuiteBAT = $c.'/'.$_TAF."/taf_generateTestsuite.bat"; # * $externalLogName ="$c/$_TAF/externalLog.txt"; # * $commandLogName ="$c/$_TAF/_cmdLogs.txt"; # * sub new { my $package = shift; return bless({}, $package); } sub tcLoop { ###### Testsuite Loop ##### my $returnValue; if (-e "$c/$_TAF/$SvrProjName/_tafGlobalVars.txt") { &readTAFTSVars();} # TS Global Variables will overwrite TAF Global Variables while ((($Execution_24_7 eq 'y') || ($NofExecution > $NofExecutionCtr)) && ($NofPropertyExec >= $NofPropertyExecCtr )) { &markDaily(); $NofExecutionCtr++; my $tcOp_ = $tcOp; if ($tcOp_ =~ /list/) {$tcOp_ = "list & update";} my $currentTime = &UnixDate( "now", "%m/%d/%Y %H:%M:%S %Z" ); if ($pr2Screen == 1) { if (($NofExecution == 1) && ($Execution_24_7 ne 'y')){ print "Processing $c/$_TAF/$SvrProjName ($tcOp_) <- Testsuite \n" if ($outputFormat =~ /text/i) ; } else {print "Processing ($NofExecutionCtrExec\/$NofExecution) ......\n" ; } } else { print "";} if (($propertyOp =~ /^\s*$/) || ($propertyOp =~ /tcDescAuto/i)) { $NofExecutionCtrExec++; &tcPre(); &tcMain_(); &tcPost(); } else { #&xtcMain_(); if ($NofPropertyExec =~ /y/i) { $propertyExecCtrEqZero = "y"; $propertyOp = ""; } else {$NofPropertyExecCtr++;} &tcMain_(); $NofPropertyExecCtr++; } # TC Property Process #### uncomment for debugging if ($pr2Screen==1) { if ($propertyOp) { print " -> $SvrDrive/$SvrProjName/_${propertyOp}.txt\n"; } print " - Completed -\n"; } else { print "";} } return $returnValue; } sub tcPre { # if (-e $SvrDrive.'/'.$SvrProjName) {;} else { print "$SvrDrive/$SvrProjName doesn't exist.\n"; exit; } # Fix 2013/04/13 ##################### PrePRocessor ##################### if ($tcOp =~ /create/i) { if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1,"
") }; if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http,"--- _tcReport_.htm will be available after list/update operation ---") }; if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary,"--- summary file will be available after list/update operation ---") }; if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory) {;} else { &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"--- history file will be available after list/update operation ---") }; } &readTestSuitProperty(); ######################################################## } sub tcMain_ { $notUsegetTCName= 1; find( {preprocess=>sub {return sort @_;}, wanted=>\&recursiveSearchtcMain}, $SvrDrive); } sub recursiveSearchtcMain() { my $returnValue =''; if ($SvrTCNamePattern eq '*') { $SvrTCNamePattern = '.*';} if (($File::Find::name =~ /tc.pl\s*$/) && ($File::Find::name =~ /$SvrDrive\/$SvrProjName\/$testcaseNode/i) && ($File::Find::name =~ /$SvrTCNamePattern/i)) # TC Filter { $tcIdCtr++; my $eachTC = &getRoot($File::Find::name); $SvrTCName = &getDir ($File::Find::name); $eachTC = &getRoot($eachTC); if (-e "$SvrTCName/_tafGlobalVars.txt") { &readTAFTCVars();} # TC Global Variables will overwrite TAF Global Variables &getWeb_($eachTC) =~ /scrollAmount\s*=\s*(\d+)/; $scrollAmount = $1; if ($scrollAmount) {;} else {$scrollAmount =0;} &getWeb_($eachTC) =~ /borderWidth\s*=\s*(\d+)/ ; $borderWidth = $1; if ($borderWidth) {;} else {$borderWidth=0;} &getWeb_($eachTC) =~ /borderStyle\s*=\s*(.+)/ ; $borderStyle = $1; if ($borderStyle) {;} else {$borderStyle=0;} if ( ($tcOp !~ /^\s*$/)&&($SvrTCName =~/$SvrTCNameExecPattern/)&&($tcIdCtr >= $tcIdMin) && (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName, "value") =~ /$tcPropertyPatternPattern/i) && (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName1, "value") =~ /$tcPropertyPatternPattern1/i) && (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName2, "value") =~ /$tcPropertyPatternPattern2/i) && (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName3, "value") =~ /$tcPropertyPatternPattern3/i) ) { # Property/testcaseExec Filter if ($propertyOp) { # Property Processor ##################### Property OPeration Start #################### if ($propertyOp =~ /tcDescAuto/) { # add tcDesc when generateTestsuite my $tcDescAuto=""; if ($#tcDesc eq 0 ) {;} else { $tcDescAuto = "add=tcDesc:".shift @tcDesc; } my $tcDescAuto_ = $tcDescAuto; $tcDescAuto =~ s/_space_/ /g; $tcDescAuto =~ s/_column_/:/g; $tcDescAuto =~ s/_eq_/=/g; printf "%-20s %s %s\n", "processProperty:", &getTCName($File::Find::name),$tcDescAuto; &processProperty("",&getTCName($File::Find::name), $tcDescAuto_); } elsif (($propertyOp =~ /_doit_/i) || ($propertyOp =~ /^\s*_?get_/i) || ($propertyOp =~ /^\s*_?list_/i)) { # property Operation (_doit_) my $propertyOp_ = $propertyOp; $propertyOp_ =~ s/_doit_//g; my $rst = &processProperty("",&getTCName($File::Find::name), $propertyOp_); my $File_Find_name = $File::Find::name; $File_Find_name =~ s/\/$tc_pl//g; if ($rst =~ /\n/) { &appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'."_$propertyOp_.txt","$File_Find_name\t$propertyOp_=\n$rst\n") ; } else { &appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'."_$propertyOp_.txt","$File_Find_name\t$propertyOp_=$rst\n") ; } } else { print "[TS/TC=$File::Find::name] propertyOp=$propertyOp _doit_\n"; # property Operation (print it) } ##################### Property OPeration End #################### } # else if (($propertyOp =~ /tcDescAuto/i) || ($propertyOp =~ /^\s*$/)) { # TC Exec Processor ##################### TC Operation Start ###################### if ($scrollAmount ==0 and $borderWidth ==0) { # TC Execution my $scrollAmount_ = 1 ; if ($tcOp =~ /list/) { $scrollAmount_ = 0; } if ($tcOp =~ /exec/i) { &updateWeb_(&getDir($File::Find::name),$scrollAmount_, $borderWidth, "SOLID", $ExecutionType); &generateRootIndex () ; } # update RootIndex $returnValue = $returnValue. &processTC("","$tcOp=$eachTC",$pr2Screen)."\n"; &logTC($eachTC); # TC Logging -> tesesuite\testcase\_tcLog.html if ($performanceMode =~ /slow4WebUI/i) { &reportTCHistory($eachTC); # TC ReporHistory -> testsuite\_tcReportHistory_.html &reportTCSummary (); &updateTestsuitePassFail () ; &Queue("updateQueue"); } &updateWeb_(&getDir($File::Find::name),0, $borderWidth, "SOLID"); if (($tcOp !~ /list/) && ($tcOp !~ /mark/)) { sleep $sleep4Display;} } elsif ( $scrollAmount != 0 ) { # Handle different TC exec state - handle concurrency if (($scrollAmount != 0 and $borderWidth== 0 )) { $borderWidth = 1; $borderStyle = "DOTTED"; } elsif (($scrollAmount != 0 and $borderStyle =~ /DOTTED/i)) {$borderWidth =1; $borderStyle = "SOLID"; } elsif (($scrollAmount != 0 and $borderStyle =~ /SOLID/i)) {$scrollAmount=0; $borderWidth =0; $borderStyle = "SOLID"; } &logTC($eachTC); # TC Logging -> tesesuite\testcase\_tcLog.html if ($performanceMode =~ /slow4WebUI/i) { #### &reportTCHistory($eachTC); # TC ReporHistory -> testsuite\_tcReportHistory_.html &reportTCSummary (); &updateWeb_(&getDir($File::Find::name),$scrollAmount, $borderWidth, $borderStyle); } } ##################### TC Operation End ###################### if ((&getExitTAFGracefullyLock() eq &getRoot_2($File::Find::name)) || (&getExitTAFGracefullyLock() eq "exitTAF" ) ) { print "TAF exited gracefully\n"; &tcPost(); &releaseExitTAFGracefullyLock(); exit; } # &generateRootIndex () ; } } else { # to handle no-run execution add to ts/tc/thProperty.txt &dumyTC_ (); } $scrollAmount = 0; $borderWidth = 0; $borderStyle = "SOLID"; #} # Property Filter # Passing $scrollAmount, $borderWidth, $borderStyle, } # TC Filter } sub tcPost { ##################### Post PRocessor ################### if (-e $SvrDrive.'/'.$SvrProjName ) { # fix 2013/04/13 &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"") ; &reportTCHistory("null"); # TC ReporHistory -> testsuite\_tcReportHistory_.html &appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"\n") ; &appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"\n") ; &mergeFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1) ; &mergeFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http) ; &prHtml1() ; &appendtoFileFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) ; &appendtoFileFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml1_http, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http); &prHtml2() ; &reportTCSummary (); &generateRootIndex () ; &updateTestsuiteHTA () ; &updateTestsuitePassFail() ; $AutomationtsName = "$SvrProjName"; &generateExcelReport () ; &sortCmdLog(); } sleep $outputPause; ######################################################## } sub printVersion { printf "%s\n",$VERSION ; } sub printTAFVersion { printf "%s\n",$VERSION ; } sub printOSVersion { printf "%s\n",$^O; } sub heartBeat { print "This is heartBeat\n";} # sub heartBeat { goto &fetchmail} sub fetchmail { # this is window version my $WinUser = "w"; # window user name is the cygwin user name my $gmail = "wripcity\@gmail.com"; # gmail address my $GmailPassword = "beaverton"; # gmail password my $tcId = 1; $tcId = shift if @_; my $fetchMailDate =""; my $fetchMailChmodFName = "c:/cygwin/home/$WinUser/fetchmailChmod.bat" ; my $fetchMailBATFName = "c:/cygwin/home/$WinUser/fetchmail.bat" ; my $fetchMailRCFName = "c:/cygwin/home/$WinUser/.fetchmailrc" ; my $str="poll pop.gmail.com with proto POP3 and options no dns user '$gmail' there with password '$GmailPassword' is '$WinUser' here options ssl"; mkpath "c:/cygwin/home/$WinUser"; open Fout, ">$fetchMailRCFName"; print Fout $str; close Fout; #print " -> $fetchMailRCFName\n"; $str="/usr/bin/fetchmail.exe -vk"; open Fout, ">$fetchMailBATFName"; print Fout $str; close Fout; # print " -> $fetchMailBATFName\n"; $str= "chmod 0600 /home/$WinUser/.fetchmailrc"; open Fout, ">$fetchMailChmodFName"; print Fout $str; close Fout; # print " -> $fetchMailChmodFName\n"; my $cmd = 'c:\cygwin\bin\bash.exe -l /home/'.$WinUser.'/fetchmailChmod.bat'; my $rst = `$cmd 2>&1`; $cmd = 'c:\cygwin\bin\bash.exe -l /home/'.$WinUser.'/fetchmail.bat'; $rst = `$cmd 2>&1`; foreach my $each (split /\n/, $rst) { if ($each =~ /protocol POP3\) at\s*(.+): poll completed/) { $fetchMailDate = $1; } } copy ('c:/cygwin/var/spool/mail/'.$WinUser, 'c:/_TAF/_gmail_.txt'); $rst = "log is skipped\n"; return "---------- Start ".(caller(0))[3]."-----------\n$cmd\n".$rst."---------- End ". (caller(0))[3]. "-----------\n"; } sub getTAFArgsFromFile { my $fname = "$c/$_TAF/_tafArgs.txt"; my $return=""; if (-e $fname) { open Fin, $fname; while ($_ =
$web_ui_title ${indexTitleRefreshRoot}${indexTitleRefresh}${queueSizeUI}
$web_ui_title ${indexTitleRefreshCGIRoot}$indexTitleRefreshCGI (Automation host: $hostname/$ip)${queueSizeUICGI}