Subversion Repositories DevTools

Rev

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

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