Subversion Repositories DevTools

Rev

Rev 5035 | Rev 6177 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4778 dpurdie 1
########################################################################
2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
3
#
4
# Module name   : jats_runutf.pm
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : JATS Make Time Test Harness Support
10
#                 This package contains fucntions that will be used by JATS
11
#                 to invoke the tests.
12
#
13
#                 This is more powerful that the previous shell-based solution
14
#                 that had problems under windows.
15
#
16
#                 The functions are designed to be invoked as:
17
#                   $(GBE_PERL) -Mjats_runutf -e <function> -- <args>+
18
#
19
#                 The functions in this packages are designed to take parameters
20
#                 from @ARVG as this makes the interface easier to read.
21
#
22
# Usage         : See POD at the end of this file
23
#
24
#......................................................................#
25
 
26
require 5.008_002;
27
use strict;
28
use warnings;
29
 
30
package jats_runutf;
31
 
32
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
33
use Exporter;
34
use JatsError qw(:name=jats_runutf);
4780 dpurdie 35
use Pod::Usage;                             # required for help support
4778 dpurdie 36
use Getopt::Long;
37
use File::Spec;
5035 dpurdie 38
use XML::Simple;
4778 dpurdie 39
 
40
$VERSION = 1.00;
41
@ISA = qw(Exporter);
42
 
43
# Symbols to autoexport (:DEFAULT tag)
4780 dpurdie 44
@EXPORT = qw( processUtf help man );
4778 dpurdie 45
 
46
#
47
#   Global Variables
48
#
49
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
4780 dpurdie 50
my $opt_help = 0;
4778 dpurdie 51
 
52
#   Data to be passed into the filter function
53
#   Defined values are:
4781 dpurdie 54
#       ARGS            - An hash of user arguments
55
#       DIR             - Optional. Name of test subdir
4778 dpurdie 56
#       FILTER          - Name of the filter 
4781 dpurdie 57
#       IDIR            - Path to original directory
4778 dpurdie 58
#       INTERFACE       - Abs Path to Interface directory
59
#       LOCAL           - Abs Path to Local directory
60
#       OUTDIR          - Abs Path to output directory
4780 dpurdie 61
#       OUTFILE         - Abs Path to suggested output file
4778 dpurdie 62
#       PKGDIR          - Abs Path to Packaging directory
63
#       ROOT            - Abs Path to Root of the build
64
#       TARGET          - Current make target
65
#       TYPE            - Built type P or D
5387 dpurdie 66
#       UTFUID          - Unique Test Identifier
4781 dpurdie 67
#       UTFNAME         - Test Name
5035 dpurdie 68
#       UTFRC           - Result Code from Unit Test run
4778 dpurdie 69
#
4780 dpurdie 70
our %filterData;
4778 dpurdie 71
 
4780 dpurdie 72
#-------------------------------------------------------------------------------
73
# Function        : help
74
#                   man 
75
#
76
# Description     : Utility functions to make is easier for users to get POD
77
#                   from this module
78
#
79
# Inputs          : 
80
#
81
# Returns         : 
82
#
4778 dpurdie 83
 
4780 dpurdie 84
sub help
85
{
86
    pod2usage(-verbose => 0, -input =>  __FILE__);
87
}
88
 
89
sub man
90
{
91
    pod2usage(-verbose => 2, -input =>  __FILE__);
92
}
93
 
4778 dpurdie 94
#-------------------------------------------------------------------------------
95
# Function        : processUtf  
96
#
97
# Description     : Main function to process UTF results
4787 dpurdie 98
#                   This function will locate a suitable filter process and invoke
99
#                   it to process the results
4778 dpurdie 100
#
4787 dpurdie 101
#                   The filter process will be provided in a Perl Module
4778 dpurdie 102
#                   It may be a part of JATS or an external modules provided
4787 dpurdie 103
#                   within an external package. ie(utf may provide its own filter)
4778 dpurdie 104
#
4787 dpurdie 105
#
4778 dpurdie 106
# Inputs          : None. Parameters are passed via @ARGV
107
#
108
# Returns         : Nothing
109
#
110
 
111
sub processUtf
112
{
4780 dpurdie 113
    my $argCount = scalar @ARGV;
4778 dpurdie 114
    my $result = GetOptions (
4780 dpurdie 115
                    "help|h:+"      => \$opt_help,
116
                    "manual:3"      => \$opt_help,
4778 dpurdie 117
                    "verbose:+"     => \$opt_verbose,       # Only set to to 0,1 or 3
4780 dpurdie 118
                    "root=s"        => \$filterData{ROOT},
119
                    "filter=s"      => \$filterData{FILTER},
120
                    "interface=s"   => \$filterData{INTERFACE},
121
                    "local=s"       => \$filterData{LOCAL},
122
                    "target=s"      => \$filterData{TARGET},
123
                    "pkgdir=s"      => \$filterData{PKGDIR},
124
                    "type=s"        => \$filterData{TYPE},
4781 dpurdie 125
                    "dir=s"         => \$filterData{DIR},
126
                    "arg=s"         => sub {my ( $key, $value) = split('=', $_[1], 2); $filterData{ARGS}{$key} = $value;},
4778 dpurdie 127
                    );
128
 
4780 dpurdie 129
    pod2usage(-verbose => 0, -input =>  __FILE__) if ($opt_help == 1 || ! $result || $argCount < 1);
130
    pod2usage(-verbose => 1, -input =>  __FILE__) if ($opt_help == 2 );
131
    pod2usage(-verbose => 2, -input =>  __FILE__) if ($opt_help  > 2);
132
 
4778 dpurdie 133
    #   Reconfigure the verbosity level
134
    ErrorConfig( 'verbose', $opt_verbose);
4780 dpurdie 135
    Error("Internal: No Filter specified") unless defined $filterData{FILTER};
136
    Error("Internal: No PkgDir specified") unless defined $filterData{PKGDIR};
4778 dpurdie 137
 
138
    #
139
    #   Locate the required filter module
140
    #   Filter modules have a name of the form:
141
    #       UtfFilter_<FilterName>.pm
142
    #   And can be located:
143
    #       within JATS
144
    #           in 'TOOLS/LIB'
145
    #       within a Package declared
146
    #           with a BuildPkgArchive or a LinkPkgArchive
147
    #           within the packages 'tools/scripts' subdirectory
148
    #       within the current package
4996 dpurdie 149
    #           Perl modules with ROOT/gbe/utfFilters
4778 dpurdie 150
    #                         or in the current directory
151
 
4787 dpurdie 152
    my $module_name = join('_','UtfFilter', lc $filterData{FILTER});
4778 dpurdie 153
    Verbose("Filter Module: $module_name");
154
 
155
    #   Extend Perl Module search path for package-local filters
156
    #   Check the current directory
157
    #       The current directory is also within @INC, but it is at the end
158
    #       thus local filter will not override external filters. Place the
159
    #       current directory first - if it conatins a filter.
160
 
161
    if (-f "$module_name.pm" )
162
    {
163
        Verbose("Extend the filter module search path: Current Directory");
164
        unshift @INC, '.';
165
    }
166
    else
167
    {
168
        #
169
        #   Check package-local directory
170
        #       <root>/gbe/utfFilters
171
        #
4780 dpurdie 172
        my $localUtfPath = File::Spec->catfile($filterData{ROOT}, 'gbe', 'utfFilters');
4778 dpurdie 173
        if ( -f( "$localUtfPath/$module_name.pm") )
174
        {
175
            Verbose("Extend the filter module search path: $localUtfPath");
176
            unshift @INC, $localUtfPath;
177
        }
178
    }
179
 
180
    #
181
    #   Locate a Perl Module of the required name
182
    #
183
    eval "require $module_name";
184
    if ($@)
185
    {
186
        Error ("Could not load required filter module: $module_name");
187
    }
188
 
189
    #
190
    #   Ensure that the filter contains the required interface methods
191
    #
192
    foreach my $fname ( qw(processUtf))
193
    {
194
        ReportError("Required function DOES NOT exist: $fname")
195
            unless (defined($module_name->can($fname)));
196
    }
197
    ErrorDoExit();
198
 
199
    #
200
    #   Convert potentially local paths to absolute paths
201
    #       Simplifies use when the CWD is changed
202
    #
203
    foreach my $entry ( qw(INTERFACE LOCAL PKGDIR ROOT))
204
    {
4780 dpurdie 205
        $filterData{$entry}  = File::Spec->rel2abs($filterData{$entry} );
4778 dpurdie 206
    }
207
 
208
    #
209
    #   Add in known values from the environment
210
    #
4780 dpurdie 211
    $filterData{TYPE} = $ENV{'GBE_MAKE_TYPE'};
212
    Error("Internal: EnvVar 'GBE_MAKE_TYPE' not specified") unless $filterData{TYPE};
4778 dpurdie 213
 
5387 dpurdie 214
    $filterData{UTFUID} = $ENV{'GBE_UTFUID'};
215
    Error("Internal: EnvVar 'GBE_UTFUID' not specified") unless $filterData{UTFUID};
4781 dpurdie 216
 
217
    $filterData{UTFNAME} = $ENV{'GBE_UTFNAME'};
218
    Error("Internal: EnvVar 'GBE_UTFNAME' not specified") unless $filterData{UTFNAME};
219
 
4996 dpurdie 220
    $filterData{OUTFILE} = $ENV{'GBE_UTFFILE'};
221
    Error("Internal: EnvVar 'GBE_UTFFILE' not specified") unless $filterData{OUTFILE};
222
 
4781 dpurdie 223
    $filterData{IDIR} = File::Spec->rel2abs('.');
224
 
4778 dpurdie 225
    #
4996 dpurdie 226
    # The environment provides a recommended (unqiue) output file
227
    #   Extact the directory part and ensure that it exists
228
    #   Brute file filename chop
4778 dpurdie 229
    #
4996 dpurdie 230
    $filterData{OUTDIR} = $filterData{OUTFILE};
231
    $filterData{OUTDIR} =~ s~/[^/]*$~~;
232
    Error("Internal: OUTDIR is empty") unless (length($filterData{OUTDIR}) > 1);
4778 dpurdie 233
 
4996 dpurdie 234
    mkdir $filterData{OUTDIR};
235
    Error("Creating utfResults directory", "Path: $filterData{OUTDIR}") unless -d $filterData{OUTDIR};
236
 
4781 dpurdie 237
    #   Allow the output file to be used
238
    #       Not in the build system, but in a user development area
4996 dpurdie 239
    #
240
    my $filename = $filterData{OUTFILE};
4781 dpurdie 241
    unlink $filename if -e $filename;
4996 dpurdie 242
    Error("Output file: Cannot delete $filename: $!") if -e $filename;
243
    Verbose("Writing output to: $filename");
4778 dpurdie 244
 
245
    #
4781 dpurdie 246
    #   Change to the test directory
247
    #       Only if required
248
    #       Ensure that the specified directory exists
249
    #
250
    if (defined $filterData{DIR})
251
    {
5035 dpurdie 252
        Verbose("Change directory:", $filterData{DIR});
4781 dpurdie 253
        Error("Internal: Test directory does not exist: $filterData{DIR}")
254
            unless (-d $filterData{DIR});
255
        chdir $filterData{DIR} || Error("Internal: Could not chdir to: $filterData{DIR}");
256
    }
257
 
258
    #
5035 dpurdie 259
    #   Recover the result code of the unit test run
260
    #
5387 dpurdie 261
    my $rcFile = join ('.', 'utf', $filterData{UTFUID}, 'rc');
5035 dpurdie 262
    Verbose("Result Code File:", $rcFile);
263
    if (-f $rcFile)
264
    {
265
        open( my $rcFile, '<', $rcFile) || Error ("Cannot open file : $!");
266
        $filterData{UTFRC} = <$rcFile>;
267
        $filterData{UTFRC} =~ s~\s+$~~;
268
        $filterData{UTFRC} =~ s~^\s+~~;
269
        Verbose("Recover Result Code: ", $filterData{UTFRC});
270
        close $rcFile;
271
    }
272
    #
4780 dpurdie 273
    #   Diagnostics
274
    #
275
    if (IsVerbose(1))
276
    {
277
        DebugDumpData("Filter Parameters", \%filterData);
278
    }
279
 
280
    #
4778 dpurdie 281
    #   Invoke the process method
282
    #   If it has a problem it should use 'Error(...)' to report it
4996 dpurdie 283
    #   There is no exit code processing, but if there is - needs to be false
4778 dpurdie 284
    #
4780 dpurdie 285
    Message("Processing UTF test results using filter: $filterData{FILTER}");
4996 dpurdie 286
    my $rv = $module_name->processUtf(\%filterData);
287
    Error ("Unit Test Failure: Errors detected in the result set")
288
        if ( defined($rv) && ! $rv );
4778 dpurdie 289
}
290
 
5035 dpurdie 291
#-------------------------------------------------------------------------------
292
# Function        : Write XML 
293
#
294
# Description     : Write user XML results to file
295
#                   Will insert standard data
296
#
297
# Inputs          : $options    - Ref to a hash of options
298
#                   $results    - Ref to an array of results
299
#                                 Expect a ref to an array of Hash Values
300
#
301
# Returns         : Nothing 
302
#
303
sub writeXmlResults
304
{
305
    my ($options, $results) = @_;
306
    #
307
    #   Create a data structure to contain the dummy test result
308
    #   Insert TARGET and TYPE attributes
309
    #
310
    my %xml;
311
    $xml{TestResults}{TARGET} = $options->{TARGET};
312
    $xml{TestResults}{TYPE} = $options->{TYPE};
313
 
314
    @{$xml{TestResults}{TestResult}} = @$results;
315
 
316
    #   The 'MESSAGE' key for failed tests forms the content of the
317
    #   <TestResult> element. Other keys are converted to attributes.
318
    #   Assign <TestResults> as the root XML node.
319
    my $xmlData = XMLout(\%xml, ContentKey => 'MESSAGE', RootName => 'TestResults', KeepRoot => 1);
320
 
321
    #   Write the data to the XML file.
322
    my $filename = $options->{OUTFILE};
323
    open ( my $outFile, ">", $filename)
324
        || Error(" Cannot open results file:$filename for writing: $!\n");
325
    print $outFile $xmlData;
326
    close $outFile;
327
}
328
 
329
 
4780 dpurdie 330
=pod 1
4778 dpurdie 331
 
4780 dpurdie 332
=for htmltoc    SYSUTIL::
333
 
334
=head1 NAME
335
 
336
jats_runutf - Post Process UTF results for build system
337
 
338
=head1 SYNOPSIS
339
 
340
  $(GBE_PERL) -Mjats_runutf -e processUtf -- <args>
341
 
342
 Options:
343
    -help[=n]       - Brief help message
344
    -help -help     - Detailed help message
345
    -man            - Full documentation
346
    -verbose[=n]    - Verbose operation
347
    -filter=name    - Name of the required processing filter
348
    -target=name    - Current build target
349
    -root=path      - Path to the root of the build
350
    -pkgdir=path    - Path to the packaging directory
351
    -interface=path - Path to the build interface directory
352
    -local=path     - Path to the local build directory
4781 dpurdie 353
    -dir=path       - Path to test directory
4780 dpurdie 354
 
355
=head1 OPTIONS
356
 
357
=over 8
358
 
359
=item B<-help>
360
 
361
Print a brief help message and exits.
362
 
363
=item B<-help -help>
364
 
365
Print a detailed help message with an explanation for each option.
366
 
367
=item B<-man>
368
 
369
Prints the manual page and exits.
370
 
371
=item B<-verbose>
372
 
373
This option will display progress information as the program executes.
374
 
375
=item B<-filter=name>
376
 
377
Name of the required processing filter.
378
 
379
=item B<-target=name>
380
 
381
The current build target.
382
 
383
=item B<-root=path>
384
 
385
The path to the root of the current build.
386
 
387
=item B<-pkgdir=path>
388
 
389
The path to the packaging directory
390
 
391
=item B<-interface=path>
392
 
393
The path to the build interface directory
394
 
395
=item B<-local=path>
396
 
397
The path to the local build directory
398
 
4781 dpurdie 399
=item B<-dir=path>
400
 
401
The path to the directory in which the test was run.
402
 
403
This is optional. If provided the filter will be invoked with the 
404
current working directory
405
 
4780 dpurdie 406
=back
407
 
408
=head1 DESCRIPTION
409
 
410
This tool is not designed to be run directly by users. It is intended to be run by the 
411
JATS generated makefiles in conjunction with unit tests to process the output from a unit 
412
test to provide a common output format to be passed on the build system.
413
 
414
Normally this process only occurs with the Auto BuildTool environment.
415
 
416
The tool provides the following operations:
417
 
418
=over 4
419
 
420
=item *
421
 
422
Sanitize environment
423
 
424
The environment passed to the filter processing module will be verified. 
425
The path to the output directory will be created if required. All paths will be absolute.
426
 
427
=item *
428
 
429
Locate the required filter processing module. The module must be a Perl Module with a name of the form 'UtfFilter_<name>'
430
 
431
=item *
432
 
433
Invoke the required filter module.
434
 
435
=back
436
 
437
=head2 Locating the Filter Module
438
 
439
The filter module may be located, in order of precedence, within:
440
 
441
=over 4
442
 
443
=item *
444
 
445
The package currently being built.
446
 
447
The package may provide its own UTF post processing module. This is not encouraged.
448
 
449
The following locations will be examined for a suitable module:
450
 
451
=over 4
452
 
453
=item *
454
 
455
The current directory. The directory of the makefile.pl that is running the unit test.
456
 
457
=item *
458
 
459
A directory in the Build Root called 'gbe/UtfFilters'
460
 
461
=back
462
 
463
=item *
464
 
465
An external Package, within the gbe/scripts directory.
466
 
467
The package can be specified with either LinkPkgArchive or BuildPkgArchive directive 
468
within the current packages build.pl file.
469
 
470
=item *
471
 
472
Within JATS.
473
 
474
Jats may provide useful filter modules.
475
 
476
=back
477
 
478
=head2 Filter Module Interface
479
 
480
The filter module Interface consists of four items:
481
 
482
=over 4
483
 
484
=item 1 The name of the Package
485
 
486
=item 1 The named function with the package
487
 
488
=item 1 Arguments passed to the named function
489
 
490
=item 1 The processing expected to be done by the named function
491
 
492
=item 1 The Output Format
493
 
494
=back
495
 
496
=head3 The name of the Package
497
 
498
Each filter function is in its own package. The package name is created by concatenating the 
499
text 'UtfFilter_' with the name of the required filter. 
500
 
501
ie: If the required filter is 'junit4', then the name of the filter package must 
502
be UtfFilter_junit4 and it will be held in a file named UtfFilter_junit4.pm.
503
 
504
=head3 The named function with the package
505
 
506
The filter package must provide a function called 'processUtf'
507
 
508
=head3 Arguments passed to the named function
509
 
510
The processing function 'processUtf' is called with two arguments:
511
 
512
=over 4
513
 
514
=item 1
515
 
516
The name of the package
517
 
518
=item 2
519
 
4787 dpurdie 520
A reference to a Perl hash. The hash will contain the following named items:
4780 dpurdie 521
 
522
=over 4
523
 
4781 dpurdie 524
=item       ARGS          
525
 
526
Optional. A hash of User Arguments passed into the filter. Use of these is filter specific.
527
 
528
Arguments of the form '--UtfArg=UserArg1=Value1' will be stored with a key of 'UserArg1 and a value of 'Value1'.
529
 
530
Arguments of the form '--UtfArg=UserArg2' will be stored with a key of 'UserArg2' and an undefined value.
531
 
532
=item       DIR          
533
 
534
Optional. If the Unit Test is executed in a subdirectory of the current build 
535
location, then DIR will be set to the name of the subdirectory. 
536
 
537
The current working directory will be changed to DIR before the filter function is invoked. 
538
 
539
This item will aways exist, but it may not be defined.
540
 
4780 dpurdie 541
=item       FILTER          
542
 
543
The Name of the filter 
544
 
4781 dpurdie 545
=item       IDIR
546
 
547
The absolute path to the working directory, when the module is invoked, before the working
4996 dpurdie 548
directory has been changed to 'DIR'.
4781 dpurdie 549
 
4780 dpurdie 550
=item       INTERFACE       
551
 
4781 dpurdie 552
The absolute path to Interface directory
4780 dpurdie 553
 
554
=item       LOCAL
555
 
4781 dpurdie 556
The absolute path to Local directory
4780 dpurdie 557
 
558
=item       OUTDIR
559
 
4781 dpurdie 560
The absolute path to output directory
4780 dpurdie 561
 
562
=item       OUTFILE
563
 
4781 dpurdie 564
The absolute path to suggested output file. The user does not need to use this name. It is 
4780 dpurdie 565
provided to remove the need for each filter to create a unique name.
566
 
567
This file will not exist.
568
 
569
=item       PKGDIR
570
 
4781 dpurdie 571
The absolute path to Packaging directory. This directory will exist.
4780 dpurdie 572
 
573
=item       ROOT
574
 
4781 dpurdie 575
The absolute path to Root of the build
4780 dpurdie 576
 
577
=item       TARGET
578
 
579
The current make target
580
 
581
=item       TYPE
582
 
583
The build type P or D
584
 
4781 dpurdie 585
=item       UTFNAME
586
 
587
The name of the test.
588
 
589
This may be provided by the user, or it may be system generated. Intended to be used by 
590
test filters that do not have test names generated as a part of the test
591
 
592
=item       UTFUID
593
 
594
A unique test identifier. This is unique with the build and is intended to:
595
 
596
=over 4
597
 
598
=item   *
599
 
600
Allow the generation of test-unique file names for the storage of results.
601
 
602
=item *
603
 
604
Allow the reuse of output file names.
605
 
4780 dpurdie 606
=back
607
 
5035 dpurdie 608
=item       UTFRC
609
 
610
The result code from the unit test run.
611
 
612
This will only be defined for JATS run unit tests.
613
 
4781 dpurdie 614
=back
615
 
4787 dpurdie 616
The return value from the function 'processUtf' is ignored. If the function encounters 
617
any error it should use the Jats 'Error' function to report the error.
4780 dpurdie 618
 
619
=back
620
 
621
=head3 The processing expected to be done by the named function
622
 
4787 dpurdie 623
The processing function is expected to transform the results of a unit test into 
624
a constient form so that they can be processed by the remainder of the build tool.
4780 dpurdie 625
 
626
The processing should:
627
 
628
=over 4
629
 
630
=item *
631
 
632
Create information in the OUTDIR directory. 
633
 
634
The filter may create a new file or insert information into an existing file. 
635
 
636
The user may make use of the OUTFILE path, but this is not mandatory.
637
 
638
=item *
639
 
640
Report errors by calling the Jats 'Error' function. This will terminate processing.
641
 
642
=back
643
 
644
=head3 The Output Format
645
 
646
Yet to be defined.
647
 
4781 dpurdie 648
The output format is known to the build system. It should not be 
649
changed without also chnaging it for the consuming tools.
650
 
4780 dpurdie 651
=cut
652
 
653
 
4778 dpurdie 654
1;