1 #
   2 # CDDL HEADER START
   3 #
   4 # The contents of this file are subject to the terms of the
   5 # Common Development and Distribution License (the "License").
   6 # You may not use this file except in compliance with the License.
   7 #
   8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9 # or http://www.opensolaris.org/os/licensing.
  10 # See the License for the specific language governing permissions
  11 # and limitations under the License.
  12 #
  13 # When distributing Covered Code, include this CDDL HEADER in each
  14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15 # If applicable, add the following below this CDDL HEADER, with the
  16 # fields enclosed by brackets "[]" replaced with your own identifying
  17 # information: Portions Copyright [yyyy] [name of copyright owner]
  18 #
  19 # CDDL HEADER END
  20 #
  21 
  22 #
  23 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24 # Use is subject to license terms.
  25 #
  26 
  27 use lib "$ENV{STF_SUITE}/tests/include";
  28 use piece_types;
  29 use create_piece;
  30 use write_piece;
  31 
  32 use Getopt::Std;
  33 use Class::Struct;
  34 
  35 struct value => { reverse qw{
  36         $ leftside
  37         $ rightside
  38         $ middle
  39 }};
  40 
  41 struct piece => { reverse qw{
  42         $ type
  43         $ ident
  44         $ write
  45         $ close
  46         @ values
  47         @ associations
  48 }};
  49 
  50 #
  51 # Open and initialize the test xml file and then call the recursive
  52 # write_piece() function to work through the piece tree.
  53 #
  54 sub generate_file() {
  55         my $ofile = shift;
  56         open(TESTXML, ">$ofile");
  57 
  58         #
  59         # Write out the basic headers to the file.
  60         #
  61         printf(TESTXML "<?xml version=\"1.0\"?>\n");
  62         printf(TESTXML "<!DOCTYPE service_bundle SYSTEM \"/usr/share/lib/xml/dtd/service_bundle.dtd.1\">\n");
  63         printf(TESTXML "\n\n");
  64 
  65         #
  66         # Now start at the top piece and write out the assocations
  67         # tree.
  68         #
  69         $tablvl = -1;
  70         &write_piece($pieces);
  71 
  72         close(TESTXML);
  73 }
  74 
  75 #
  76 # Associate a piece with its parent piece.
  77 #
  78 sub associate_piece() {
  79         my @args = @_;
  80         my $argc = @args;
  81 
  82         my $asstype = shift;
  83         my $assname = shift;
  84         my $asspiece = shift;
  85 
  86         #
  87         # So go through and look for the associative type.
  88         # When a type that matches is found, then verify
  89         # that the ident matches.  If it matches then insert
  90         # the association into the correct place.
  91         #
  92         if ($argc == 3) {
  93                 @pset = $pieces;
  94         } else {
  95                 @pset = shift;
  96         }
  97 
  98         foreach $assp (@pset) {
  99                 if ($assp->type == $asstype && $assp->ident eq $assname) {
 100                         #
 101                         # Set the assocation and return out.  We need to
 102                         # insert the association in the correct position.
 103                         #
 104                         $c = 0;
 105                         foreach $a (@{$assp->associations}) {
 106                                 if ($asspiece->type < $a->type) {
 107                                         splice(@{$assp->associations}, $c, 0, $asspiece);
 108                                         return (1);
 109                                 }
 110 
 111                                 $c++;
 112                         }
 113                         push(@{$assp->associations}, $asspiece);
 114                 } else {
 115                         foreach $a (@{$assp->associations}) {
 116                                 $x = &associate_piece($asstype, $assname, $p, $a);
 117                                 if ($x == 1) {
 118                                         return (1);
 119                                 }
 120                         }
 121                 }
 122         }
 123 }
 124 
 125 #
 126 # Initialize the pieces array for the manifest.
 127 #
 128 sub initialize_pieces() {
 129 
 130         &SERVICEBUNDLE("type=manifest,name=validate");
 131         &SERVICE("$SERVICEBUNDLE:validate", "name=$def_service_name,type=service,version=1");
 132         &EXECMETHOD("$SERVICE:$def_service_name", "type=method,name=start,exec=:true,timeout_seconds=60");
 133         &EXECMETHOD("$SERVICE:$def_service_name", "type=method,name=stop,exec=:true,timeout_seconds=60");
 134 }
 135 
 136 #
 137 # Generate an xml manifest and error, then start add the test
 138 # assertion to the list of tests.
 139 #
 140 sub generate_test() {
 141         my $test_type = shift;
 142         my $rest = shift;
 143         my ($filename, $errors) = split(/:/, $rest, 2);
 144 
 145         $ofile = "${testdir}/$filename";
 146         &generate_file($ofile);
 147 
 148         if ($errors) {
 149                 $errfile = "${ofile}.errs";
 150                 open (ERRFILE, "> ${errfile}");
 151                 while ($errors) {
 152                         (my $err, $errors) = split(/:/, $errors, 2);
 153                         printf(ERRFILE "%s\n", $err);
 154                 }
 155         } else {
 156                 $errfile = "";
 157         }
 158 
 159         system("stf_addassert -u root -t '$filename' -c 'runtest $ofile $errfile'");
 160 }
 161 
 162 #
 163 # Convert a type into a common usuable value, by removing underscores
 164 # and setting values to caps
 165 #
 166 sub convert_type() {
 167         my $x = shift;
 168 
 169         $x =~ s/_//g;
 170 
 171         $x =~ tr/a-z/A-Z/;
 172 
 173         return ($x);
 174 }
 175 
 176 #
 177 # Process a line of the data_set file
 178 #
 179 sub process_line() {
 180         my $type = shift;
 181         my $rest = shift;
 182 
 183         my $type = &convert_type($type);
 184         my ($asstype, $assname, $values) = split(/:/, $rest, 3);
 185         my $asstype = &convert_type($asstype);
 186         my $rtype = ${$type};
 187 
 188         if ($asstype eq "SERVICE" && $assname == "DEFAULT") {
 189                 $assname = $def_service_name;
 190         }
 191 
 192         #
 193         # Will want to extend this to deal with a service name
 194         # that is not the default.
 195         #
 196         if ($asstype eq "TEMPLATE" && $template_piece == 0) {
 197                 &TEMPLATE("$SERVICE:$def_service_name", "");
 198         }
 199 
 200         if (defined &{$type}) {
 201                 &{$type}("${$asstype}:$assname", $values);
 202         } else {
 203                 if ($type) {
 204                         printf("Unknown type $type\n");
 205                 }
 206         }
 207 }
 208 
 209 #
 210 # Generate the xml manifests to be used during testing
 211 #
 212 sub gen_xml_manifest() {
 213         my $infile = shift;
 214 
 215         our $pieces = "uninitialized";
 216         our $def_service_name="system/template_validate";
 217         &initialize_pieces();
 218 
 219         our $testdir = "/var/tmp/validation_test_manifests";
 220         if ( ! -d $testdir) {
 221                 mkdir($testdir, 0777);
 222         }
 223 
 224         open(INFILE, "< $infile") || die "Unable to open $infile\n";
 225         while (<INFILE>) {
 226                 chop($_);
 227                 my ($type, $rest) = split(/:/, $_, 2);
 228 
 229                 if ($type eq "positive" || $type eq "negative") {
 230                         &generate_test($type, $rest);
 231 
 232                         $pieces = "uninitialized";
 233                         $def_service_name="system/template_validate";
 234                         $template_piece = 0;
 235                         &initialize_pieces();
 236                 } else {
 237                         &process_line($type, $rest);
 238                 }
 239         }
 240 }
 241 return (1);