Sweet! I guess the only ''drawback'' is the meta-data is
only accessable to perl, but who cares. I bet this fix will
make #118 easier.

http://svn.open-mpi.org/trac/mtt/ticket/118
  "Slim down result submissions to the bare essentials"


On Thu, Nov/30/2006 07:55:14AM, jsquy...@osl.iu.edu wrote:
> Author: jsquyres
> Date: 2006-11-30 07:55:07 EST (Thu, 30 Nov 2006)
> New Revision: 461
> 
> Removed:
>    trunk/lib/XML/
> Modified:
>    trunk/lib/MTT/Files.pm
>    trunk/lib/MTT/MPI.pm
>    trunk/lib/MTT/Test.pm
>    trunk/lib/MTT/Test/RunEngine.pm
> 
> Log:
> Fixes #144
> 
> This commit is a bunch of things to improve the meta data handling and
> storage in the MTT client:
> 
>  * Remove the use of XML::Simple and use Data::Dumper instead.  This
>    allows us to remove the costly/slow (and error-prone when coding up
>    new data layers) data transformation for each of the datasets that
>    were saved out to disk.  The output data is about the same size,
>    but we avoid the [potentially] huge memory transformation before
>    the write, and for large data sets (e.g., Test run data), can save
>    quite a bit of time (e.g., ~3 seconds with Data::Dumper vs. ~10
>    seconds with XML::Simple).
>  * Split the Test run data up into multiple files instead of one huge
>    file.  This allows us to write only the new data after tests have
>    run rather than having to write ''all'' the data ''every'' time.
>    It makes the reading and writing of the test run data a little more
>    complex, but the performance win is worth it.
>  * Write the Test Run data [slightly] less frequently -- i.e., write
>    out a [small] batch of new Test Run data periodically rather than
>    writing after ''every'' test.
> 
> 
> Modified: trunk/lib/MTT/Files.pm
> ==============================================================================
> --- trunk/lib/MTT/Files.pm    (original)
> +++ trunk/lib/MTT/Files.pm    2006-11-30 07:55:07 EST (Thu, 30 Nov 2006)
> @@ -40,8 +40,15 @@
>  
>  #--------------------------------------------------------------------------
>  
> -sub mkdir {
> +sub safe_mkdir {
>      my ($dir) = @_;
> +    MTT::Files::mkdir($dir, 1);
> +}
> +
> +#--------------------------------------------------------------------------
> +
> +sub mkdir {
> +    my ($dir, $safe) = @_;
>  
>      my $c = cwd();
>      Debug("Making dir: $dir (cwd: $c)\n");
> @@ -58,6 +65,9 @@
>      foreach my $p (@parts) {
>          next if (! $p);
>  
> +        $p = make_safe_filename($p)
> +            if ($safe);
> +
>          $str .= "$p";
>          if (! -d $str) {
>              Debug("$str does not exist -- creating\n");
> @@ -402,6 +412,8 @@
>      return 1;
>  }
>  
> +#--------------------------------------------------------------------------
> +
>  # Copy infile or stdin to a unique file in /tmp
>  sub copyfile {
>  
> @@ -432,4 +444,64 @@
>      return $outfile;
>  }
>  
> +#--------------------------------------------------------------------------
> +
> +sub load_dumpfile {
> +    my ($filename, $data) = @_;
> +
> +    # Check that the file is there
> +    return
> +        if (! -r $filename);
> +
> +    # Get the file size
> +    my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
> +        $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
> +
> +    # Read it in
> +    open IN, $filename;
> +    my $tmp;
> +    read(IN, $tmp, $size);
> +    close IN;
> +    
> +    # It's in Dumper format.  How many $VARx's are there?
> +    return
> +        if (! $tmp =~ m/\$VAR[0-9]+/g);
> +    my $count = 0;
> +    ++$count
> +        while ($tmp =~ m/\$VAR[0-9]+/g);
> +
> +    # We know how many $VARx's there are.  Build up a string to eval.
> +    my $str;
> +    my $var_num = 1;
> +    while ($var_num <= $count) {
> +        $str .= "my \$VAR$var_num;\n";
> +        ++$var_num;
> +    }
> +    $str .= "eval \$tmp;\n";
> +    my $var_num = 1;
> +    while ($var_num <= $count) {
> +        $str .= "\$\$data->{VAR$var_num} = \$VAR$var_num;\n";
> +        ++$var_num;
> +    }
> +    eval $str;
> +}
> +
> +#--------------------------------------------------------------------------
> +
> +sub save_dumpfile {
> +    my ($filename) = @_;
> +    shift;
> +
> +    # Serialize
> +    my $d = new Data::Dumper([@_]);
> +    $d->Purity(1)->Indent(1);
> +
> +    open FILE, ">$filename.new";
> +    print FILE $d->Dump;
> +    close FILE;
> +
> +    # Atomically move it onto the old file
> +    rename("$filename.new", $filename);
> +}
> +
>  1;
> 
> Modified: trunk/lib/MTT/MPI.pm
> ==============================================================================
> --- trunk/lib/MTT/MPI.pm      (original)
> +++ trunk/lib/MTT/MPI.pm      2006-11-30 07:55:07 EST (Thu, 30 Nov 2006)
> @@ -15,10 +15,9 @@
>  package MTT::MPI;
>  
>  use strict;
> -use XML::Simple qw(:strict);
>  use MTT::MPI::Get;
>  use MTT::MPI::Install;
> -use Data::Dumper;
> +use MTT::Files;
>  
>  #--------------------------------------------------------------------------
>  
> @@ -31,16 +30,10 @@
>  #--------------------------------------------------------------------------
>  
>  # Filename where list of MPI sources is kept
> -my $sources_data_filename = "mpi_sources.xml";
> -
> -# XML options for the MPI sources
> -my $sources_xs;
> +my $sources_data_filename = "mpi_sources.dump";
>  
>  # Filename where list of MPI installs is kept
> -my $installs_data_filename = "mpi_installs.xml";
> -
> -# XML options for the MPI installs
> -my $installs_xs;
> +my $installs_data_filename = "mpi_installs.dump";
>  
>  #--------------------------------------------------------------------------
>  
> @@ -60,65 +53,17 @@
>  
>  #--------------------------------------------------------------------------
>  
> -sub _scrub {
> -    my $h = shift;
> -
> -    foreach my $k (keys(%$h)) {
> -        if (ref($h->{$k}) eq "") {
> -            # Remove bad characters
> -            $h->{$k} =~ s/\000/<NULL>/g;
> -        } else {
> -            _scrub($h->{$k});
> -        }
> -    }
> -}
> -
> -#--------------------------------------------------------------------------
> -
> -sub _setup_sources_xml {
> -    $sources_xs = new XML::Simple(KeyAttr => { mpi_get => 
> "simple_section_name",
> -                                               mpi_version => "version",
> -                                           },
> -                                  ForceArray => [ "mpi_get", 
> -                                                  "mpi_version",
> -                                                  ],
> -                                  AttrIndent => 1,
> -                                  RootName => "mpi_sources",
> -                                  );
> -}
> -
> -#--------------------------------------------------------------------------
> -
> +use Data::Dumper;
>  sub LoadSources {
>      my ($dir) = @_;
>  
>      # Explicitly delete anything that was there
>      $MTT::MPI::sources = undef;
>  
> -    _setup_sources_xml()
> -        if (!$sources_xs);
> -    
>      # If the file exists, read it in
> -    if (-f "$dir/$sources_data_filename") {
> -        my $in = $sources_xs->XMLin("$dir/$sources_data_filename");
> -
> -        # Now transform this to the form suitable for
> -        # $MTT::MPI::sources (see comment in SaveSources)
> -
> -        # For each MPI get section
> -        foreach my $mpi_get_key (keys(%{$in->{mpi_get}})) {
> -            my $mpi_get = $in->{mpi_get}->{$mpi_get_key};
> -
> -            # For each version
> -            foreach my $mpi_version_key (keys(%{$mpi_get->{mpi_version}})) {
> -                my $mpi_version = 
> $mpi_get->{mpi_version}->{$mpi_version_key};
> -                
> -                $MTT::MPI::sources->{$mpi_get_key}->{$mpi_version_key} = 
> $mpi_version;
> -                
> $MTT::MPI::sources->{$mpi_get_key}->{$mpi_version_key}->{simple_section_name} 
> = $mpi_get_key;
> -                
> $MTT::MPI::sources->{$mpi_get_key}->{$mpi_version_key}->{version} = 
> $mpi_version_key;
> -            }
> -        }
> -    }
> +    my $data;
> +    MTT::Files::load_dumpfile("$dir/$sources_data_filename", \$data);
> +    $MTT::MPI::sources = $data->{VAR1};
>  }
>  
>  #--------------------------------------------------------------------------
> @@ -126,54 +71,8 @@
>  sub SaveSources {
>      my ($dir) = @_;
>  
> -    _setup_sources_xml()
> -        if (!$sources_xs);
> -
> -    # Transform $MTT::MPI::sources to something XML::Simple can write
> -    # into valid XML (since our values can [and will] contain :'s,
> -    # which are the namespace identifiers in XML)
> -    my $transformed;
> -
> -    # For each MPI get section
> -    foreach my $mpi_get_key (keys(%$MTT::MPI::sources)) {
> -        my $mpi_get = $MTT::MPI::sources->{$mpi_get_key};
> -
> -        # For each version
> -        foreach my $mpi_version_key (keys(%$mpi_get)) {
> -            my $mpi_version = $mpi_get->{$mpi_version_key};
> -
> -            # Deep copy and scrub
> -            my $h;
> -            %$h = %$mpi_version;
> -            _scrub($h);
> -
> -            
> $transformed->{mpi_get}->{$mpi_get_key}->{mpi_version}->{$mpi_version_key} = 
> $h;
> -        }
> -    }
> -
> -    # Write out the file
> -    my $xml = $sources_xs->XMLout($transformed);
> -    my $file = "$dir/$sources_data_filename";
> -    open(FILE, ">$file.new");
> -    print FILE $xml;
> -    close(FILE);
> -    system("mv $file.new $file");
> -}
> -
> -#--------------------------------------------------------------------------
> -
> -sub _setup_installs_xml {
> -    $installs_xs = new XML::Simple(KeyAttr => { mpi_get => 
> "simple_section_name",
> -                                                mpi_version => "version",
> -                                                mpi_install => 
> "simple_section_name",
> -                                            },
> -                                   ForceArray => [ "mpi_get", 
> -                                                   "mpi_version",
> -                                                   "mpi_install",
> -                                                   ],
> -                                   AttrIndent => 1,
> -                                   RootName => "mpi_installs",
> -                                   );
> +    MTT::Files::save_dumpfile("$dir/$sources_data_filename", 
> +                              $MTT::MPI::sources);
>  }
>  
>  #--------------------------------------------------------------------------
> @@ -184,33 +83,10 @@
>      # Explicitly delete anything that was there
>      $MTT::MPI::installs = undef;
>  
> -    _setup_installs_xml()
> -        if (!$installs_xs);
> -    
>      # If the file exists, read it in
> -    if (-f "$dir/$installs_data_filename") {
> -        my $in = $installs_xs->XMLin("$dir/$installs_data_filename");
> -
> -        # Now transform this to the form suitable for
> -        # $MTT::MPI::installs (see comment in SaveSources).  Wow.
> -
> -        # For each MPI get section
> -        foreach my $mpi_get_key (keys(%{$in->{mpi_get}})) {
> -            my $mpi_get = $in->{mpi_get}->{$mpi_get_key};
> -
> -            # For each version of each MPI get
> -            foreach my $mpi_version_key (keys(%{$mpi_get->{mpi_version}})) {
> -                my $mpi_version = 
> $mpi_get->{mpi_version}->{$mpi_version_key};
> -
> -                # For each MPI install section
> -                foreach my $mpi_install_key 
> (keys(%{$mpi_version->{mpi_install}})) {
> -                    
> $MTT::MPI::installs->{$mpi_get_key}->{$mpi_version_key}->{$mpi_install_key} = 
> -                        
> $in->{mpi_get}->{$mpi_get_key}->{mpi_version}->{$mpi_version_key}->{mpi_install}->{$mpi_install_key};
> -                    
> $MTT::MPI::installs->{$mpi_get_key}->{$mpi_version_key}->{$mpi_install_key}->{simple_section_name}
>  = $mpi_install_key;
> -                }
> -            }
> -        }
> -    }
> +    my $data;
> +    MTT::Files::load_dumpfile("$dir/$installs_data_filename", \$data);
> +    $MTT::MPI::installs = $data->{VAR1};
>  }
>  
>  #--------------------------------------------------------------------------
> @@ -218,42 +94,8 @@
>  sub SaveInstalls {
>      my ($dir) = @_;
>  
> -    _setup_installs_xml()
> -        if (!$installs_xs);
> -
> -    # Transform $MTT::MPI::installs to something XML::Simple can write
> -    # into valid XML (see comment in SaveSources).  Wow.
> -    my $transformed;
> -
> -    # For each MPI get section
> -    foreach my $mpi_get_key (keys(%{$MTT::MPI::installs})) {
> -        my $mpi_get = $MTT::MPI::installs->{$mpi_get_key};
> -        
> -        # For each version of that get
> -        foreach my $mpi_version_key (keys(%{$mpi_get})) {
> -            my $mpi_version = $mpi_get->{$mpi_version_key};
> -
> -            # For each MPI install action
> -            foreach my $mpi_install_key (keys(%{$mpi_version})) {
> -                my $mpi_install = $mpi_version->{$mpi_install_key};
> -
> -                # Deep copy and scrub
> -                my $h;
> -                %$h = %$mpi_install;
> -                _scrub($h);
> -
> -                
> $transformed->{mpi_get}->{$mpi_get_key}->{mpi_version}->{$mpi_version_key}->{mpi_install}->{$mpi_install_key}
>  = $h;
> -            }
> -        }
> -    }
> -
> -    # Write out the file
> -    my $xml = $installs_xs->XMLout($transformed);
> -    my $file = "$dir/$installs_data_filename";
> -    open(FILE, ">$file.new");
> -    print FILE $xml;
> -    close(FILE);
> -    system("mv $file.new $file");
> +    MTT::Files::save_dumpfile("$dir/$installs_data_filename", 
> +                              $MTT::MPI::installs);
>  }
>  
>  1;
> 
> Modified: trunk/lib/MTT/Test.pm
> ==============================================================================
> --- trunk/lib/MTT/Test.pm     (original)
> +++ trunk/lib/MTT/Test.pm     2006-11-30 07:55:07 EST (Thu, 30 Nov 2006)
> @@ -13,11 +13,11 @@
>  package MTT::Test;
>  
>  use strict;
> +use File::Find;
>  use MTT::Test::Get;
>  use MTT::Test::Build;
>  use MTT::Test::Run;
> -use XML::Simple;
> -use Data::Dumper;
> +use MTT::Files;
>  
>  #--------------------------------------------------------------------------
>  
> @@ -29,26 +29,24 @@
>  
>  # Exported run tests handle
>  our $runs;
> +our $runs_to_be_saved;
>  
>  #--------------------------------------------------------------------------
>  
>  # Filename where list of test sources information is kept
> -my $sources_data_filename = "test_sources.xml";
> -
> -# XML options for the test builds
> -my $sources_xs;
> +my $sources_data_filename = "test_sources.dump";
>  
>  # Filename where list of test build information is kept
> -my $builds_data_filename = "test_builds.xml";
> +my $builds_data_filename = "test_builds.dump";
>  
> -# XML options for the test builds
> -my $builds_xs;
> +# Subdir where test runs are kept
> +my $runs_subdir = "test_runs";
>  
>  # Filename where list of test run information is kept
> -my $runs_data_filename = "test_runs.xml";
> +my $runs_data_filename = "test_runs.dump";
>  
> -# XML options for the test runs
> -my $runs_xs;
> +# Helper variable for when we're loading test run data
> +my $load_run_file_start_dir;
>  
>  #--------------------------------------------------------------------------
>  
> @@ -76,57 +74,16 @@
>  
>  #--------------------------------------------------------------------------
>  
> -sub _scrub {
> -    my $h = shift;
> -
> -    foreach my $k (keys(%$h)) {
> -        if (ref($h->{$k}) eq "") {
> -            # Remove bad characters
> -            $h->{$k} =~ s/\000/<NULL>/g;
> -        } else {
> -            _scrub($h->{$k});
> -        }
> -    }
> -}
> -
> -#--------------------------------------------------------------------------
> -
> -sub _setup_sources_xml {
> -    $sources_xs = new XML::Simple(KeyAttr => { test_get => 
> "simple_section_name",
> -                                           },
> -                                  ForceArray => [ "test_get", 
> -                                                  ],
> -                                  AttrIndent => 1,
> -                                  RootName => "test_sources",
> -                                  );
> -}
> -
> -#--------------------------------------------------------------------------
> -
>  sub LoadSources {
>      my ($dir) = @_;
>  
>      # Explicitly delete anything that was there
>      $MTT::Test::sources = undef;
>  
> -    _setup_sources_xml()
> -        if (!$sources_xs);
> -    
>      # If the file exists, read it in
> -    if (-f "$dir/$sources_data_filename") {
> -        my $in = $sources_xs->XMLin("$dir/$sources_data_filename");
> -
> -        # Now transform this to the form suitable for
> -        # $MTT::Test::sources (see comment in SaveSources)
> -
> -        # For each Test get section
> -        foreach my $test_get_key (keys(%{$in->{test_get}})) {
> -            my $test_get = $in->{test_get}->{$test_get_key};
> -
> -            $MTT::Test::sources->{$test_get_key} = $test_get;
> -            $MTT::Test::sources->{$test_get_key}->{simple_section_name} = 
> $test_get_key;
> -        }
> -    }
> +    my $data;
> +    MTT::Files::load_dumpfile("$dir/$sources_data_filename", \$data);
> +    $MTT::Test::sources = $data->{VAR1};
>  }
>  
>  #--------------------------------------------------------------------------
> @@ -134,51 +91,8 @@
>  sub SaveSources {
>      my ($dir) = @_;
>  
> -    _setup_sources_xml()
> -        if (!$sources_xs);
> -
> -    # Transform $MTT::Test::sources to something XML::Simple can write
> -    # into valid XML (since our values can [and will] contain :'s,
> -    # which are the namespace identifiers in XML)
> -    my $transformed;
> -
> -    # For each Test get section
> -    foreach my $test_get_key (keys(%$MTT::Test::sources)) {
> -        my $test_get = $MTT::Test::sources->{$test_get_key};
> -
> -        # Deep copy and scrub
> -        my $h;
> -        %$h = %$test_get;
> -        _scrub($h);
> -
> -        $transformed->{test_get}->{$test_get_key} = $h;
> -    }
> -
> -    # Write out the file
> -    my $xml = $sources_xs->XMLout($transformed);
> -    my $file = "$dir/$sources_data_filename";
> -    open(FILE, ">$file.new");
> -    print FILE $xml;
> -    close(FILE);
> -    system("mv $file.new $file");
> -}
> -
> -#--------------------------------------------------------------------------
> -
> -sub _setup_builds_xml {
> -    $builds_xs = new XML::Simple(KeyAttr => { mpi_get => 
> "simple_section_name",
> -                                              mpi_version => "version",
> -                                              mpi_install => 
> "simple_section_name",
> -                                              test_build => 
> "simple_section_name",
> -                                            },
> -                                   ForceArray => [ "mpi_get", 
> -                                                   "mpi_version",
> -                                                   "mpi_install",
> -                                                   "test_build",
> -                                                   ],
> -                                   AttrIndent => 1,
> -                                   RootName => "test_builds",
> -                                   );
> +    MTT::Files::save_dumpfile("$dir/$sources_data_filename", 
> +                              $MTT::Test::sources);
>  }
>  
>  #--------------------------------------------------------------------------
> @@ -189,39 +103,10 @@
>      # Explicitly delete anything that was there
>      $MTT::Test::builds = undef;
>  
> -    _setup_builds_xml()
> -        if (!$builds_xs);
> -    
>      # If the file exists, read it in
> -    if (-f "$dir/$builds_data_filename") {
> -        my $in = $builds_xs->XMLin("$dir/$builds_data_filename");
> -
> -        # Now transform this to the form suitable for
> -        # $MTT::Test::builds (see comment in SaveSources).  Wow.
> -        # For each MPI get section
> -        foreach my $mpi_get_key (keys(%{$in->{mpi_get}})) {
> -            my $mpi_get = $in->{mpi_get}->{$mpi_get_key};
> -
> -            # For each version of that MPI
> -            foreach my $mpi_version_key (keys(%{$mpi_get->{mpi_version}})) {
> -                my $mpi_version = 
> $mpi_get->{mpi_version}->{$mpi_version_key};
> -
> -                # For each MPI install section
> -                foreach my $mpi_install_key 
> (keys(%{$mpi_version->{mpi_install}})) {
> -                    my $mpi_install = 
> $mpi_version->{mpi_install}->{$mpi_install_key};
> -                    
> -                    # For each test build section
> -                    foreach my $test_build_key 
> (keys(%{$mpi_install->{test_build}})) {
> -                        my $test_build = 
> $mpi_install->{test_build}->{$test_build_key};
> -                        
> -                        
> $MTT::Test::builds->{$mpi_get_key}->{$mpi_version_key}->{$mpi_install_key}->{$test_build_key}
>  = 
> -                            
> $in->{mpi_get}->{$mpi_get_key}->{mpi_version}->{$mpi_version_key}->{mpi_install}->{$mpi_install_key}->{test_build}->{$test_build_key};
> -                        
> $MTT::Test::builds->{$mpi_get_key}->{$mpi_version_key}->{$mpi_install_key}->{$test_build_key}->{simple_section_name}
>  = $test_build_key;
> -                    }
> -                }
> -            }
> -        }
> -    }
> +    my $data;
> +    MTT::Files::load_dumpfile("$dir/$builds_data_filename", \$data);
> +    $MTT::Test::builds = $data->{VAR1};
>  }
>  
>  #--------------------------------------------------------------------------
> @@ -229,135 +114,48 @@
>  sub SaveBuilds {
>      my ($dir) = @_;
>  
> -    _setup_builds_xml()
> -        if (!$builds_xs);
> -
> -    # Transform $MTT::Test::builds to something XML::Simple can write
> -    # into valid XML (see comment in SaveSources).  Wow.
> -    my $transformed;
> -
> -    # For each MPI get section
> -    foreach my $mpi_get_key (keys(%{$MTT::Test::builds})) {
> -        my $mpi_get = $MTT::Test::builds->{$mpi_get_key};
> -
> -        # For each version of that MPI
> -        foreach my $mpi_version_key (keys(%{$mpi_get})) {
> -            my $mpi_version = $mpi_get->{$mpi_version_key};
> -            
> -            # For each MPI install section
> -            foreach my $mpi_install_key (keys(%{$mpi_version})) {
> -                my $mpi_install = $mpi_version->{$mpi_install_key};
> -            
> -                # For each test build section
> -                foreach my $test_build_key (keys(%{$mpi_install})) {
> -                    my $test_build = $mpi_install->{$test_build_key};
> -                    
> -                    # Deep copy and scrub
> -                    my $h;
> -                    %$h = %$test_build;
> -                    _scrub($h);
> -
> -                    
> $transformed->{mpi_get}->{$mpi_get_key}->{mpi_version}->{$mpi_version_key}->{mpi_install}->{$mpi_install_key}->{test_build}->{$test_build_key}
>  = $h;
> -                }
> -            }
> -        }
> -    }
> -
> -    # Write out the file
> -    my $xml = $builds_xs->XMLout($transformed);
> -    my $file = "$dir/$builds_data_filename";
> -    open(FILE, ">$file.new");
> -    print FILE $xml;
> -    close(FILE);
> -    system("mv $file.new $file");
> -}
> -
> -#--------------------------------------------------------------------------
> -
> -sub _setup_runs_xml {
> -    $runs_xs = new XML::Simple(KeyAttr => { mpi_get => "simple_section_name",
> -                                            mpi_version => "version",
> -                                            mpi_install => 
> "simple_section_name",
> -                                            test_build => 
> "simple_section_name",
> -                                            test_run => 
> "simple_section_name",
> -                                            test_name => "name",
> -                                            test_np => "nprocs",
> -                                            test_cmd => "argv",
> -                                        },
> -                               ForceArray => [ "mpi_get", 
> -                                               "mpi_version",
> -                                               "mpi_install",
> -                                               "test_build",
> -                                               "test_run",
> -                                               "test_name",
> -                                               "test_np",
> -                                               "test_cmd",
> -                                               ],
> -                               AttrIndent => 1,
> -                               RootName => "test_runs",
> -                               );
> +    MTT::Files::save_dumpfile("$dir/$builds_data_filename", 
> +                              $MTT::Test::builds);
>  }
>  
>  #--------------------------------------------------------------------------
>  
> +use Data::Dumper;
>  sub LoadRuns {
>      my ($dir) = @_;
>  
>      # Explicitly delete anything that was there
>      $MTT::Test::runs = undef;
>  
> -    _setup_runs_xml()
> -        if (!$runs_xs);
> -    
> -    # If the file exists, read it in
> -    if (-f "$dir/$runs_data_filename") {
> -        my $in = $runs_xs->XMLin("$dir/$runs_data_filename");
> -
> -        # Now transform this to the form suitable for
> -        # $MTT::Test::runs (see comment in SaveSources).  Wow.
> -        # For each MPI get section
> -        foreach my $mpi_get_key (keys(%{$in->{mpi_get}})) {
> -            my $mpi_get = $in->{mpi_get}->{$mpi_get_key};
> -
> -            # For each MPI source
> -            foreach my $mpi_version_key (keys(%{$mpi_get->{mpi_version}})) {
> -                my $mpi_version = 
> $mpi_get->{mpi_version}->{$mpi_version_key};
> -
> -                # For each MPI install section
> -                foreach my $mpi_install_key 
> (keys(%{$mpi_version->{mpi_install}})) {
> -                    my $mpi_install = 
> $mpi_version->{mpi_install}->{$mpi_install_key};
> -
> -                    # For each test build section
> -                    foreach my $test_build_key 
> (keys(%{$mpi_install->{test_build}})) {
> -                        my $test_build = 
> $mpi_install->{test_build}->{$test_build_key};
> -                        
> -                        # For each test run section
> -                        foreach my $test_run_key 
> (keys(%{$test_build->{test_run}})) {
> -                            my $test_run = 
> $test_build->{test_run}->{$test_run_key};
> -                            
> -                            # For each test name
> -                            foreach my $test_name_key 
> (keys(%{$test_run->{test_name}})) {
> -                                my $test_name = 
> $test_run->{test_name}->{$test_name_key};
> -                                
> -                                # For each np
> -                                foreach my $test_np_key 
> (keys(%{$test_name->{test_np}})) {
> -                                    my $test_np = 
> $test_name->{test_np}->{$test_np_key};
> -                                    
> -                                    # For each test command
> -                                    foreach my $test_cmd_key 
> (keys(%{$test_np->{test_cmd}})) {
> -                                        my $test_cmd = 
> $test_np->{test_cmd}->{$test_cmd_key};
> -                                        
> -                                        
> $MTT::Test::runs->{$mpi_get_key}->{$mpi_version_key}->{$mpi_install_key}->{$test_build_key}->{$test_run_key}->{$test_name_key}->{$test_np_key}->{$test_cmd_key}
>  = 
> -                                            
> $in->{mpi_get}->{$mpi_get_key}->{mpi_version}->{$mpi_version_key}->{mpi_install}->{$mpi_install_key}->{test_build}->{$test_build_key}->{test_run}->{$test_run_key}->{test_name}->{$test_name_key}->{test_np}->{$test_np_key}->{test_cmd}->{$test_cmd_key};
> -                                    }
> -                                }
> -                            }
> -                        }
> -                    }
> -                }
> -            }
> -        }
> -    }
> +    # See SaveRuns, below, for an explanation.  We traverse
> +    # directories looking for dump files and read them into the
> +    # appropriate section of the $MTT::Test::runs hash.
> +
> +    $load_run_file_start_dir = "$dir/$runs_subdir";
> +    find(\&load_run_file, $load_run_file_start_dir)
> +        if (-d $load_run_file_start_dir);
> +}
> +
> +sub load_run_file {
> +    # We only want files named $runs_data_filename
> +    return 0
> +        if (! -f $_ || $runs_data_filename ne $_);
> +
> +    # Read in the file
> +    my $data;
> +    MTT::Files::load_dumpfile($File::Find::name, \$data);
> +
> +    # Put the loaded data in the hash in the right place.  Per
> +    # SaveRuns(), below, we look at the key values in $data->{VAR1} to
> +    # know where to put $data->{VAR2} in the $MTT::Test::runs hash.
> +    my $str = "\$MTT::Test::runs";
> +    my $k = 1;
> +    do {
> +        $str .= "->{\"" . $data->{VAR1}->{$k} . "\"}";
> +        ++$k;
> +    } while (exists($data->{VAR1}->{$k}));
> +    $str .= " = \$data->{VAR2}";
> +    eval $str;
>  }
>  
>  #--------------------------------------------------------------------------
> @@ -365,15 +163,25 @@
>  sub SaveRuns {
>      my ($dir) = @_;
>  
> -    _setup_runs_xml()
> -        if (!$runs_xs);
> +    # Because test run data can get very, very large, we break it up
> +    # and store it in lots of smaller files so that we can write out
> +    # to disk in small portions.
> +
> +    # Test runs are stored in the hash with this order of keys:
> +
> +    # mpi_get_simple_section_name
> +    # mpi_version
> +    # mpi_install_simple_section_name
> +    # test_build_simple_section_name
> +    # test_run_simple_section_name
> +    # test_name
> +    # np
> +    # command
>  
> -    # Transform $MTT::Test::runs to something XML::Simple can write
> -    # into valid XML (see comment in SaveSources).  Wow.
> -    my $transformed;
> +    # We save from test_name and down in a single file.
>  
>      # For each MPI get section
> -    foreach my $mpi_get_key (keys(%{$MTT::Test::runs})) {
> +    foreach my $mpi_get_key (keys(%{$MTT::Test::runs_to_be_saved})) {
>          my $mpi_get = $MTT::Test::runs->{$mpi_get_key};
>  
>          # For each source of that MPI
> @@ -395,23 +203,22 @@
>                          # For each test name
>                          foreach my $test_name_key (keys(%{$test_run})) {
>                              my $test_name = $test_run->{$test_name_key};
> -                            
> -                            # For each np
> -                            foreach my $test_np_key (keys(%{$test_name})) {
> -                                my $test_np = $test_name->{$test_np_key};
> -                                
> -                                # For each cmd
> -                                foreach my $test_cmd_key (keys(%{$test_np})) 
> {
> -                                    my $test_cmd = $test_np->{$test_cmd_key};
> -                                    
> -                                    # Deep copy and scrub
> -                                    my $h;
> -                                    %$h = %$test_cmd;
> -                                    _scrub($h);
> -
> -                                    
> $transformed->{mpi_get}->{$mpi_get_key}->{mpi_version}->{$mpi_version_key}->{mpi_install}->{$mpi_install_key}->{test_build}->{$test_build_key}->{test_run}->{$test_run_key}->{test_name}->{$test_name_key}->{test_np}->{$test_np_key}->{test_cmd}->{$test_cmd_key}
>  = $h;
> -                                }
> -                            }
> +
> +                            my $file = 
> MTT::Files::safe_mkdir("$dir/$runs_subdir/$mpi_get_key/$mpi_version_key/$mpi_install_key/$test_build_key/$test_run_key/$test_name_key")
>  . "/$runs_data_filename";
> +
> +                            # We need to save two items in test run
> +                            # data files -- the actual data and where
> +                            # it belongs in the $MTT::Test::runs hash.
> +                            my $hashname = {
> +                                1 => $mpi_get_key,
> +                                2 => $mpi_version_key,
> +                                3 => $mpi_install_key,
> +                                4 => $test_build_key,
> +                                5 => $test_run_key,
> +                                6 => $test_name_key,
> +                            };
> +                            MTT::Files::save_dumpfile($file, $hashname, 
> +                                                      $test_name);
>                          }
>                      }
>                  }
> @@ -419,13 +226,8 @@
>          }
>      }
>  
> -    # Write out the file
> -    my $xml = $runs_xs->XMLout($transformed);
> -    my $file = "$dir/$runs_data_filename";
> -    open(FILE, ">$file.new");
> -    print FILE $xml;
> -    close(FILE);
> -    system("mv $file.new $file");
> +    # Explicitly reset the test runs to be saved
> +    $MTT::Test::runs_to_be_saved = undef;
>  }
>  
>  1;
> 
> Modified: trunk/lib/MTT/Test/RunEngine.pm
> ==============================================================================
> --- trunk/lib/MTT/Test/RunEngine.pm   (original)
> +++ trunk/lib/MTT/Test/RunEngine.pm   2006-11-30 07:55:07 EST (Thu, 30 Nov 
> 2006)
> @@ -67,6 +67,9 @@
>              }
>          }
>          ++$count;
> +
> +        # Write out the "to be saved" test run results
> +        MTT::Test::SaveRuns($top_dir);
>          
>          # Output a progress bar
>          if ($verbose_out > 50) {
> @@ -189,8 +192,21 @@
>      # Assume that the Analyze module will output one line
>      ++$verbose_out;
>  
> -    
> $MTT::Test::runs->{$mpi_details->{mpi_get_simple_section_name}}->{$mpi_details->{version}}->{$mpi_details->{mpi_install_simple_section_name}}->{$run->{test_build_simple_section_name}}->{$run->{simple_section_name}}->{$name}->{$MTT::Test::Run::test_np}->{$cmd}
>  = $report;
> -    MTT::Test::SaveRuns($top_dir);
> +    # For Test Runs data, we have two datasets: the "to be saved" set
> +    # and the "all results" set.  The "to be saved" set is a
> +    # relatively small set of data that is written out to disk
> +    # periodically (i.e., augmenting what has already been written
> +    # out).  The "all results" set is everything that has occurred so
> +    # far.  We do this because the "all results" set can get *very*
> +    # large, so we don't want to write out the whole thing every time
> +    # we save the results to disk.
> +
> +    # So save this new result in both the "to be saved" and "all
> +    # results" sets.  We'll write out the "to be saved" results
> +    # shortly.
> +
> +    
> $MTT::Test::runs_to_be_saved->{$mpi_details->{mpi_get_simple_section_name}}->{$mpi_details->{version}}->{$mpi_details->{mpi_install_simple_section_name}}->{$run->{test_build_simple_section_name}}->{$run->{simple_section_name}}->{$name}->{$MTT::Test::Run::test_np}->{$cmd}
>  = 
> +        
> $MTT::Test::runs->{$mpi_details->{mpi_get_simple_section_name}}->{$mpi_details->{version}}->{$mpi_details->{mpi_install_simple_section_name}}->{$run->{test_build_simple_section_name}}->{$run->{simple_section_name}}->{$name}->{$MTT::Test::Run::test_np}->{$cmd}
>  = $report;
>      MTT::Reporter::QueueAdd("Test Run", $run->{simple_section_name}, 
> $report);
>  
>      # If there is an after_each step, run it
> _______________________________________________
> mtt-svn mailing list
> mtt-...@open-mpi.org
> http://www.open-mpi.org/mailman/listinfo.cgi/mtt-svn

-- 
-Ethan

Reply via email to