PERL - traverse sub directories and get test case results

Hello,

I need help in creating a PERL script for parsing test result files to get the results (pass or fail). Each test case execution generates a directory with few files among which we are interested in .result file.

Lets say Testing is home directory. If i executed 2 test cases. It will create case1, case2 under Testing directory. Below is sample content of .result files present in case directories.

Testing/case1/file1.result

test case name:    testcase1.txt
passed:           1
failed:           0

Trial    Trial Start Time             Result
1    20110106 06:15:19.044 PST    PASSED

Testing/case2/file2.result

test case name:    testcase2.txt
passed:           1
failed:           0

Trial    Trial Start Time             Result
1    20110106 06:15:19.044 PST    FAILED

Script should traverse through sub directories, read .result file, get the last word in last line (1st file contains PASSED, 2nd contains FAILED). Now this result should be updated in testing XL based on test case name. Below is content of testing XL.

contents of XL before running script

S.No    TestCaseName    Result
1    testcase1.txt    
2    testcase2.txt    

contents of XL after running script

S.No    TestCaseName    Result
1    testcase1.txt    PASSED
2    testcase2.txt    FAILED

Appreciate your help on this.

While I am the first to work with PERL, I would turn to find and awk:

find "${@}" -type f -name .results -print | xargs awk '/^test case name:/ { testcase = $NF; } NR == FNR { printf "%-30s  %s\n", testcase, $NF; }'

but with PERL

use strict;
use warnings;

$\ = "\n";
$, = '';

my @FILELIST = ();
my @DIRLIST  = qw{ . };

# search the current directory and all subdirectories for result files

while (0 < @DIRLIST) {

    my $dir = shift @DIRLIST;

    unless (opendir DH, $dir) {
        print STDERR $dir, ': ', $!;
        next;
    }

    my @DL = readdir DH;
    close DH;

    for (@DL) {
        next if /^\./;

        my $entry = $dir . '/' . $_;

        if (m{\.results$}) {
            push @FILELIST, $entry;
            next;
        }
          
        if (-d $entry) {
            push @DIRLIST, $entry;
        }
    }

    closedir DH;
}

undef $/;
 
my %T = ();

# parse all result files

foreach my $file (@FILELIST) {
       
    unless (open FH, '<', $file) {
        print STDERR $file, ': ', $!;
        next;
    }

    $_ = <FH>;
    close FH;

    my ($testcase) = m{^test case name:\s+(\S+)\s*$}m;
    my ($status)   = m{(PASSED|FAILED)\s*$}m;

    unless (defined $testcase and defined $status) {
        print STDERR $file, ': not a results file';
        next;
    }

    if (defined $T{$testcase}) {
        print STDERR $file, ': duplicate testcase - ', $testcase, ' (', $status, ')';
        next;
    }
       
    $T{$testcase} = $status
}

$/ = "\n";

$_ = <>;
chomp;
print $_;

while (<>) {
    chomp;
    my ($sno, $testcase) = m{^\s*(\d+)\s+(\S+)\s*$};

    unless (defined $testcase) {
        print STDERR $ARGV, '(', $., '): malformed line - ', $_;
        next;
    }

    $T{$testcase} = 'UNDEFINED' unless defined $T{$testcase};
    printf "\%-4d \%-19s \%s\n", $sno, $testcase, $T{$testcase};
}

on a side note Perl is the proper way to reference the language.

I thought it would be man perl (linux). :slight_smile:

nope - perl is the interpreter.