From 2d10b19f1562d9b9e3fa51683131a631431187ed Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Fri, 17 May 2019 11:25:28 -0400 Subject: [PATCH 1/5] Switch staging-common to a Python test script (eliminating /bin/bash and perl). Add KillWriters test --- .../engine/staging-common/CMakeLists.txt | 12 +- .../engine/staging-common/TestSupp.cmake | 71 +++--- .../engine/staging-common/run_multi_test.in | 171 -------------- .../engine/staging-common/run_staging_test.in | 172 -------------- .../adios2/engine/staging-common/run_test.in | 216 ++++++++++++++++++ 5 files changed, 255 insertions(+), 387 deletions(-) delete mode 100755 testing/adios2/engine/staging-common/run_multi_test.in delete mode 100755 testing/adios2/engine/staging-common/run_staging_test.in create mode 100755 testing/adios2/engine/staging-common/run_test.in diff --git a/testing/adios2/engine/staging-common/CMakeLists.txt b/testing/adios2/engine/staging-common/CMakeLists.txt index a8af36fd20..ca1e793a96 100644 --- a/testing/adios2/engine/staging-common/CMakeLists.txt +++ b/testing/adios2/engine/staging-common/CMakeLists.txt @@ -84,14 +84,8 @@ if(ADIOS2_HAVE_MPI) endif() configure_file( - run_staging_test.in - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/run_staging_test - @ONLY -) - -configure_file( - run_multi_test.in - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/run_multi_test + run_test.in + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/run_test.py @ONLY ) @@ -102,7 +96,7 @@ set (FORTRAN_TESTS "") if(ADIOS2_HAVE_Fortran) set (FORTRAN_TESTS "FtoC.1x1;CtoF.1x1;FtoF.1x1") endif() -set (SPECIAL_TESTS "KillReadersSerialized;KillReaders3Max;TimeoutReader;LatestReader;DiscardWriter;PreciousTimestep;PreciousTimestepDiscard") +set (SPECIAL_TESTS "KillReadersSerialized;KillReaders3Max;TimeoutReader;KillWriter_2x2;KillWriterTimeout_2x2;LatestReader;DiscardWriter;PreciousTimestep;PreciousTimestepDiscard") set (MPI_TESTS "") set (MPI_FORTRAN_TESTS "") diff --git a/testing/adios2/engine/staging-common/TestSupp.cmake b/testing/adios2/engine/staging-common/TestSupp.cmake index 4151157d9a..3bfa2fde93 100644 --- a/testing/adios2/engine/staging-common/TestSupp.cmake +++ b/testing/adios2/engine/staging-common/TestSupp.cmake @@ -28,7 +28,7 @@ # add_common_test(1x1 SST) ends up doing: # # add_test(NAME "Staging.1x1.SST" -# COMMAND "run_staging_test -e SST -f Staging.1x1.SST -nw 1 -nr 1 -v -p TestCommon") +# COMMAND "run_staging_test -e SST -f Staging.1x1.SST -nw 1 -nr 1") # set_tests_properties(${testname} PROPERTIES TIMEOUT 30 RUN_SERIAL 1) # # RUNNING TESTS WITH DIFFERENT ENGINE PARAMETERS @@ -37,6 +37,7 @@ # with different engine parameters, *_CMD strings can also contain the # string "ENGINE_PARAMS". This string is treated specially by the # function MutateTestSet(). This function is takes a list of tests + # (I.E. things with _CMD strings defined like above) and creates a new # set of tests where a specified engine parameter gets added to the in # the location of the ENGINE_PARAMS string. MutateTestSet takes 4 parameters: @@ -58,75 +59,76 @@ # set (STAGING_COMMON_TEST_SUPP_VERBOSE OFF) -set (1x1_CMD "run_staging_test -nw 1 -nr 1 -v -p TestCommon -arg ENGINE_PARAMS") -set (2x1_CMD "run_staging_test -nw 2 -nr 1 -v -p TestCommon -arg ENGINE_PARAMS") -set (1x2_CMD "run_staging_test -nw 1 -nr 2 -v -p TestCommon -arg ENGINE_PARAMS") -set (3x5_CMD "run_staging_test -nw 3 -nr 5 -v -p TestCommon -arg ENGINE_PARAMS") -set (5x3_CMD "run_staging_test -nw 5 -nr 3 -v -p TestCommon -arg ENGINE_PARAMS") -set (1x1.Local_CMD "run_staging_test -nw 1 -nr 1 -v -w TestCommonWriteLocal -r TestCommonReadLocal -arg ENGINE_PARAMS") -set (2x1.Local_CMD "run_staging_test -nw 2 -nr 1 -v -w TestCommonWriteLocal -r TestCommonReadLocal -arg ENGINE_PARAMS") -set (1x2.Local_CMD "run_staging_test -nw 1 -nr 2 -v -w TestCommonWriteLocal -r TestCommonReadLocal -arg ENGINE_PARAMS") -set (3x5.Local_CMD "run_staging_test -nw 3 -nr 5 -v -w TestCommonWriteLocal -r TestCommonReadLocal -arg ENGINE_PARAMS") -set (5x3.Local_CMD "run_staging_test -nw 5 -nr 3 -v -w TestCommonWriteLocal -r TestCommonReadLocal -arg ENGINE_PARAMS") -set (DelayedReader_3x5_CMD "run_staging_test -rd 5 -nw 3 -nr 5 -p TestCommon -arg ENGINE_PARAMS") -set (FtoC.3x5_CMD "run_staging_test -nw 3 -nr 5 -v -w TestCommonWrite_f -r TestCommonRead -arg ENGINE_PARAMS") -set (FtoF.3x5_CMD "run_staging_test -nw 3 -nr 5 -v -w TestCommonWrite_f -r TestCommonRead_f -arg ENGINE_PARAMS") +set (1x1_CMD "run_test.py -nw 1 -nr 1 --warg=ENGINE_PARAMS") +set (2x1_CMD "run_test.py -nw 2 -nr 1 --warg=ENGINE_PARAMS") +set (1x2_CMD "run_test.py -nw 1 -nr 2 --warg=ENGINE_PARAMS") +set (3x5_CMD "run_test.py -nw 3 -nr 5 --warg=ENGINE_PARAMS") +set (5x3_CMD "run_test.py -nw 5 -nr 3 --warg=ENGINE_PARAMS") +set (1x1.Local_CMD "run_test.py -nw 1 -nr 1 -w TestCommonWriteLocal -r TestCommonReadLocal --warg=ENGINE_PARAMS") +set (2x1.Local_CMD "run_test.py -nw 2 -nr 1 -w TestCommonWriteLocal -r TestCommonReadLocal --warg=ENGINE_PARAMS") +set (1x2.Local_CMD "run_test.py -nw 1 -nr 2 -w TestCommonWriteLocal -r TestCommonReadLocal --warg=ENGINE_PARAMS") +set (3x5.Local_CMD "run_test.py -nw 3 -nr 5 -w TestCommonWriteLocal -r TestCommonReadLocal --warg=ENGINE_PARAMS") +set (5x3.Local_CMD "run_test.py -nw 5 -nr 3 -w TestCommonWriteLocal -r TestCommonReadLocal --warg=ENGINE_PARAMS") +set (DelayedReader_3x5_CMD "run_test.py -rd 5 -nw 3 -nr 5 --warg=ENGINE_PARAMS") +set (FtoC.3x5_CMD "run_test.py -nw 3 -nr 5 -w TestCommonWrite_f -r TestCommonRead --warg=ENGINE_PARAMS") +set (FtoF.3x5_CMD "run_test.py -nw 3 -nr 5 -w TestCommonWrite_f -r TestCommonRead_f --warg=ENGINE_PARAMS") # NoReaderNoWait runs a writer with the RendezvousReaderCount = 0 and then never spawns a reader. The test should run to termination and execute cleanly -set (NoReaderNoWait_CMD "run_staging_test -nw 1 -nr 0 -v -p TestCommon -arg RendezvousReaderCount:0,QueueLimit:3,QueueFullPolicy:discard,ENGINE_PARAMS") +set (NoReaderNoWait_CMD "run_test.py -nw 1 -nr 0 --warg=RendezvousReaderCount:0,QueueLimit:3,QueueFullPolicy:discard,ENGINE_PARAMS") # The Modes test checks to see that we can mix and match Put Sync and Deferred modes and still get good data -set (Modes_CMD "run_staging_test -nw 1 -nr 1 -v -w TestCommonWriteModes -r TestCommonRead -arg ENGINE_PARAMS") +set (Modes_CMD "run_test.py -nw 1 -nr 1 -w TestCommonWriteModes -r TestCommonRead --warg=ENGINE_PARAMS") # 1x1.Attrs tests writing and reading of attributes defined before Open -set (1x1.Attrs_CMD "run_staging_test -nw 1 -nr 1 -v -w TestCommonWriteAttrs -r TestCommonReadAttrs -arg ENGINE_PARAMS") +set (1x1.Attrs_CMD "run_test.py -nw 1 -nr 1 -w TestCommonWriteAttrs -r TestCommonReadAttrs --warg=ENGINE_PARAMS") # Basic Fortran tests, Fortran to C, C to Fortran and Fortran to Fortran -set (FtoC.1x1_CMD "run_staging_test -nw 1 -nr 1 -v -w TestCommonWrite_f -r TestCommonRead -arg ENGINE_PARAMS") -set (CtoF.1x1_CMD "run_staging_test -nw 1 -nr 1 -v -w TestCommonWrite -r TestCommonRead_f -arg ENGINE_PARAMS") -set (FtoF.1x1_CMD "run_staging_test -nw 1 -nr 1 -v -w TestCommonWrite_f -r TestCommonRead_f -arg ENGINE_PARAMS") +set (FtoC.1x1_CMD "run_test.py -nw 1 -nr 1 -w TestCommonWrite_f -r TestCommonRead --warg=ENGINE_PARAMS") +set (CtoF.1x1_CMD "run_test.py -nw 1 -nr 1 -w TestCommonWrite -r TestCommonRead_f --warg=ENGINE_PARAMS") +set (FtoF.1x1_CMD "run_test.py -nw 1 -nr 1 -w TestCommonWrite_f -r TestCommonRead_f --warg=ENGINE_PARAMS") # Tests for ZFP compression (where supported by an engine param) -set (ZFPCompression.1x1_CMD "run_staging_test -nw 1 -nr 1 -v -p TestCommon -arg CompressionMethod:zfp,ENGINE_PARAMS" ) -set (ZFPCompression.3x5_CMD "run_staging_test -nw 3 -nr 5 -v -p TestCommon -arg CompressionMethod:zfp,ENGINE_PARAMS" ) +set (ZFPCompression.1x1_CMD "run_test.py -nw 1 -nr 1 --warg=CompressionMethod:zfp,ENGINE_PARAMS" ) +set (ZFPCompression.3x5_CMD "run_test.py -nw 3 -nr 5 --warg=CompressionMethod:zfp,ENGINE_PARAMS" ) # Test if writer will survive readers departing unexpectedly -set (KillReadersSerialized_CMD "run_multi_test -test_protocol kill_readers -verbose -nw 3 -nr 2 -max_readers 1 -warg RendezvousReaderCount:0,ENGINE_PARAMS -rarg --ignore_time_gap") +set (KillReadersSerialized_CMD "run_test.py --test_protocol kill_readers -nw 3 -nr 2 --max_readers 1 --warg=RendezvousReaderCount:0,ENGINE_PARAMS --rarg=--ignore_time_gap") set (KillReadersSerialized_TIMEOUT "300") set (KillReadersSerialized_PROPERTIES "RUN_SERIAL;1") -set (KillReaders3Max_CMD "run_multi_test -test_protocol kill_readers -verbose -nw 3 -nr 2 -max_readers 3 -warg RendezvousReaderCount:0,ENGINE_PARAMS -rarg --ignore_time_gap") +set (KillReaders3Max_CMD "run_test.py --test_protocol kill_readers -nw 3 -nr 2 --max_readers 3 --warg=RendezvousReaderCount:0,ENGINE_PARAMS --rarg=--ignore_time_gap") set (KillReaders3Max_TIMEOUT "300") set (KillReaders3Max_PROPERTIES "RUN_SERIAL;1") -set (KillWriter_1x2_CMD "run_multi_test -test_protocol kill_writer -verbose -nw 1 -nr 2 -interval 2 -warg RendezvousReaderCount:1,ENGINE_PARAMS -rarg --expect_writer_failure -rarg --num_steps --rarg 1000") -set (KillWriterTimeout_1x2_CMD "run_multi_test -test_protocol kill_writer -verbose -nw 1 -nr 2 -interval 2 -warg RendezvousReaderCount:1,ENGINE_PARAMS -rarg --expect_writer_failure -rarg --num_steps --rarg 1000 --rarg --non_blocking") +set (KillWriter_2x2_CMD "run_test.py --test_protocol kill_writer -nw 2 -nr 2 --interval 2 --warg=RendezvousReaderCount:1,ENGINE_PARAMS --rarg=--expect_writer_failure --rarg=--num_steps --rarg=1000") +set (KillWriterTimeout_2x2_CMD "run_test.py --test_protocol kill_writer -nw 2 -nr 2 --interval 2 --warg=RendezvousReaderCount:1,ENGINE_PARAMS --rarg=--expect_writer_failure --rarg=--num_steps --rarg=1000 --rarg=--non_blocking") + +set (PreciousTimestep_CMD "run_test.py --test_protocol kill_readers -nw 3 -nr 2 --max_readers 2 --warg=FirstTimestepPrecious:true,RendezvousReaderCount:0,ENGINE_PARAMS --rarg=--ignore_time_gap --rarg=--precious_first") -set (PreciousTimestep_CMD "run_multi_test -test_protocol kill_readers -verbose -nw 3 -nr 2 -max_readers 2 -warg FirstTimestepPrecious:true,RendezvousReaderCount:0,ENGINE_PARAMS -rarg --ignore_time_gap -rarg --precious_first") set (PreciousTimestep_TIMEOUT "300") set (PreciousTimestep_PROPERTIES "RUN_SERIAL;1") -set (PreciousTimestepDiscard_CMD "run_multi_test -test_protocol kill_readers -verbose -nw 3 -nr 2 -max_readers 2 -warg FirstTimestepPrecious:true,RendezvousReaderCount:0,QueueLimit:3,QueueFullPolicy:discard,ENGINE_PARAMS -rarg --ignore_time_gap -rarg --precious_first -rarg --discard -warg --ms_delay -warg 500") +set (PreciousTimestepDiscard_CMD "run_test.py --test_protocol kill_readers -nw 3 -nr 2 --max_readers 2 --warg=FirstTimestepPrecious:true,RendezvousReaderCount:0,QueueLimit:3,QueueFullPolicy:discard,ENGINE_PARAMS --rarg=--ignore_time_gap --rarg=--precious_first --rarg=--discard --warg=--ms_delay --warg=500") set (PreciousTimestepDiscard_TIMEOUT "300") set (PreciousTimestepDiscard_PROPERTIES "RUN_SERIAL;1") # Readers using BeginStep with timeout. Here we run the writer with a longer delay to make the reader timeout -set (TimeoutReader_CMD "run_multi_test -test_protocol one_to_one -verbose -nw 1 -nr 1 -rarg --non_blocking -warg --ms_delay -warg 2000 -warg --engine_params -warg ENGINE_PARAMS") +set (TimeoutReader_CMD "run_test.py --test_protocol one_client -nw 1 -nr 1 --rarg=--non_blocking --warg=--ms_delay --warg=2000 --warg=--engine_params --warg=ENGINE_PARAMS") set (TimeoutReader_TIMEOUT "60") set (TimeoutReader_PROPERTIES "RUN_SERIAL;1") # Readers using LatestAvailable Writer runs faster than reader, so we expect misses -set (LatestReader_CMD "run_multi_test -test_protocol one_to_one -verbose -nw 1 -nr 1 -warg --ms_delay -warg 250 -warg --engine_params -warg ENGINE_PARAMS -rarg --latest -rarg --long_first_delay") +set (LatestReader_CMD "run_test.py --test_protocol one_client -nw 1 -nr 1 --warg=--ms_delay --warg=250 --warg=--engine_params --warg=ENGINE_PARAMS --rarg=--latest --rarg=--long_first_delay") set (LatestReader_PROPERTIES "RUN_SERIAL;1") # A faster writer and a queue policy that will cause timesteps to be discarded -set (DiscardWriter_CMD "run_multi_test -test_protocol one_to_one -verbose -nw 1 -nr 1 -warg --engine_params -warg QueueLimit:1,QueueFullPolicy:discard,ENGINE_PARAMS -warg --ms_delay -warg 250 -rarg --discard") +set (DiscardWriter_CMD "run_test.py --test_protocol one_client -nw 1 -nr 1 --warg=--engine_params --warg=QueueLimit:1,QueueFullPolicy:discard,ENGINE_PARAMS --warg=--ms_delay --warg=250 --rarg=--discard") function(remove_engine_params_placeholder dst_str src_str ) string(REGEX REPLACE "([^ ]*),ENGINE_PARAMS" "\\1" src_str "${src_str}") if ("${src_str}" MATCHES "ENGINE_PARAMS") # empty engine params remains - string(REGEX REPLACE "-warg *--engine_params *-warg *ENGINE_PARAMS" "" src_str "${src_str}") - string(REGEX REPLACE "-warg *--engine_params *-rarg *ENGINE_PARAMS" "" src_str "${src_str}") + string(REGEX REPLACE "--warg=--engine_params --warg=ENGINE_PARAMS" "" src_str "${src_str}") + string(REGEX REPLACE "--rarg=--engine_params --rarg=ENGINE_PARAMS" "" src_str "${src_str}") string(REGEX REPLACE "-arg *ENGINE_PARAMS" "" src_str "${src_str}") endif() set(${dst_str} ${src_str} PARENT_SCOPE) @@ -170,14 +172,13 @@ endfunction() function(add_common_test basename engine) set(testname "Staging.${basename}.${engine}") - set(filename "Staging.${basename}.${engine}") if ("${${basename}_CMD}" STREQUAL "") message(SEND_ERROR "Staging-Common test ${basename} has no defined ${basename}_CMD") endif() string (CONCAT command "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/" ${${basename}_CMD}) remove_engine_params_placeholder(command "${command}") separate_arguments(command) - list(INSERT command 1 "-e" "${engine}" "-f" "${filename}") + list(INSERT command 1 "${engine}" "${testname}") add_test( NAME ${testname} COMMAND ${command}) diff --git a/testing/adios2/engine/staging-common/run_multi_test.in b/testing/adios2/engine/staging-common/run_multi_test.in deleted file mode 100755 index 6a7f9fe12b..0000000000 --- a/testing/adios2/engine/staging-common/run_multi_test.in +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/perl -# This script has been build to run the tests in the bin directory. -use Getopt::Long; -use List::Util qw(shuffle); -use strict; -use warnings; - -##Parse Args -my $verbose = 0; # option variable with default value (false) -my $writer_prog = "TestCommonServer"; -my $reader_prog = "TestCommonClient"; -my @writer_args = (); -my @reader_args = (); -my $num_writers = 3; -my $num_readers = 2; -my $max_readers = 3; -my $test_protocol = 'kill_readers'; -my $duration = 60; -my $interval = 5; -my $exit_value = 0; -my $engine = "SST"; -my $filename = "CommonStaging"; - -use File::Basename; -my $my_dirname = dirname(__FILE__); - -GetOptions ('verbose!' => \$verbose, - 'writer=s' => \$writer_prog, - 'reader=s' => \$reader_prog, - 'e=s' => \$engine, - 'f=s' => \$filename, - 'warg=s@' => \@writer_args, - 'rarg=s@' => \@reader_args, - 'nw=i' => \$num_writers, - 'nr=i' => \$num_readers, - 'duration=i' => \$duration, - 'interval=i' => \$interval, - 'max_readers=i' => \$max_readers, - 'test_protocol=s' => \$test_protocol) - or die("Error in command line arguments\n"); - - -print "Test protocol is $test_protocol\n" if $verbose; - -my $writer_output = ""; -my $reader_output = ""; -my $result = 1; -my $writer_exec_cmd = "@MPIEXEC@ @MPIEXEC_NUMPROC_FLAG@ $num_writers"; -my $reader_exec_cmd = "@MPIEXEC@ @MPIEXEC_NUMPROC_FLAG@ $num_readers"; - -if (("@MPIEXEC@" eq "") or ("@MPIEXEC@" eq "MPIEXEC_EXECUTABLE-NOTFOUND")) { - # NO MPI - $writer_exec_cmd = ""; - $reader_exec_cmd = ""; -} - -defined(my $writer_pid = fork) or die "Cannot fork $!"; -unless($writer_pid) -{ - #Child process is here - my $writer_arg_str = ""; - $writer_arg_str = join(" ", @writer_args) if (@writer_args); - my $command = "$writer_exec_cmd $my_dirname/$writer_prog $engine $filename " . $writer_arg_str; - $command =~ s/^\s+//; - print "TestDriver: EXECwriter $command writer PID $$\n" if $verbose; - my $result = system (split / /,$command); - print "TestDriver: System for writer returns ", $result, " \n"; - exit $result; -} -print "TestDriver: Writer PID: $writer_pid\n" if $verbose; - -my $endtime = time() + $duration; - -if ($test_protocol eq "kill_readers") { - - my @ReaderPIDs; - print "TestDriver: Duration at beginning is $duration\n" if $verbose; - - while (time() < $endtime) { - my $this_start = time(); - my $r = rand(); - print "TestDriver: Start, number of readers is " . scalar(@ReaderPIDs) . ", max readers is $max_readers\n" if $verbose; - if (((scalar(@ReaderPIDs) <= 0) || ($r < 0.5)) && (scalar(@ReaderPIDs) != $max_readers)){ - # fork a reader - defined(my $reader_pid = fork) or die "Cannot fork $!"; - unless($reader_pid) - { - #Child process is here - my $command = "$reader_exec_cmd $my_dirname/$reader_prog $engine $filename " . join(" ", @reader_args); - $command =~ s/^\s+//; - print "TestDriver: System( $command )\n" if $verbose; - my $result = system (split / /,$command); - print "TestDriver: System for multi_readers Reader returns ", $result, " \n"; - exit $result; - } - print "TestDriver: Reader PID: $reader_pid\n" if $verbose; - push @ReaderPIDs, $reader_pid; - } else { - # kill a reader - my $readerToKill; - @ReaderPIDs = shuffle @ReaderPIDs; - $readerToKill = shift @ReaderPIDs; - kill 'KILL', $readerToKill; - print "TestDriver: KILLED Reader PID: $readerToKill\n" if $verbose; - waitpid($readerToKill, 0); - print "TestDriver: Status of killed reader was $?\n" if $verbose; - if (($? != 0) && ($? != 9)) { - $exit_value = 1; #failure - print "TestDriver: Setting failure return because of bad exit status of killed reader\n"; - } - } - my $sleep_time = ($this_start + $interval) - time(); - if ($sleep_time > 0) { - select undef, undef, undef, $sleep_time + 0.0001; - } - my $time_remaining = $endtime - time(); - print "TestDriver: TEST TIME REMAINING is $time_remaining \n" if $verbose; - } - print "TestDriver: Killing the writer\n" if $verbose; - system("touch DieTest"); - foreach my $readerPID (@ReaderPIDs) { - waitpid($readerPID, 0); - print "TestDriver: Status of final reader was $?\n" if $verbose; - if ($? != 0) { - $exit_value = 1; #failure - print "TestDriver: Setting failure return because of bad exit status ($?) on normal reader\n"; - } - } - my $ret = waitpid($writer_pid, 0); - unlink("DieTest"); - print "TestDriver: Status of writer was $? with return value $ret\n" if $verbose; - if ($? != 0) { - $exit_value = 1; #failure - print "TestDriver: Setting failure return because of bad exit status ($?) of writer\n"; - } - exit $exit_value; -} # end kill_readers protocol - -if ($test_protocol eq "one_to_one") { - - defined(my $reader_pid = fork) or die "Cannot fork $!"; - unless($reader_pid) - { - #Child process is here - my $command = "$reader_exec_cmd $my_dirname/$reader_prog $engine $filename " . join(" ", @reader_args); - $command =~ s/^\s+//; - print "TestDriver: EXECreader $command\n" if $verbose; - my $result = system (split / /,$command); - print "TestDriver: System() for one_to_one Reader returned $result\n" if $verbose; - exit $result; - } - print "TestDriver: Reader PID: $reader_pid\n" if $verbose; - waitpid($reader_pid, 0); - my $reader_exit = ${^CHILD_ERROR_NATIVE}; - print "TestDriver: Status of one_to_one reader was $reader_exit\n" if $verbose; - if ($reader_exit != 0) { - $exit_value = 1; - print "TestDriver: Setting failure return because of bad exit status ($?) on normal reader\n"; - } - system("touch DieTest"); - my $ret = waitpid($writer_pid, 0); - unlink("DieTest"); - print "TestDriver: Status of writer was $?\n" if $verbose; - if ($? != 0) { - $exit_value = 1; #failure - print "TestDriver: Setting failure return because of bad exit status ($?) of writer\n"; - } - exit $exit_value; - -} # end one_to_one protocol - diff --git a/testing/adios2/engine/staging-common/run_staging_test.in b/testing/adios2/engine/staging-common/run_staging_test.in deleted file mode 100755 index 36f9c40427..0000000000 --- a/testing/adios2/engine/staging-common/run_staging_test.in +++ /dev/null @@ -1,172 +0,0 @@ -#!/bin/bash - -cur_dir=${PWD##*/} - -qflag=no; -vflag=no; -nr="2" -nw="2" - -usage() -{ - cat << EO - Usage: $PROGNAME [options] - - Run a simple staging test. - - Options: -EO - cat < & prefix of Reader and Writer programs - -r & name of reader-side program - -w & name of writer-side program - -n & number of nodes to run both sides - -nw & number of nodes to run write side - -nr & number of nodes to run read side - -e & staging engine to use with the test - -f & filename to specify for connection info - -rd & number of seconds to delay before staring the reader - -arg & pass on the command line to the executables - -v & run this script verbosely - -q & be quiet (don't print PASSED/FAILED) -EO -} - -PROGNAME=${0##*/} - -reader_prog="UNSET" -writer_prog="UNSET" -engine="sst" -filename="StagingTest" - -reader_delay=0 -args="" - -while [ $# -gt 0 ] -do - case "$1" in - -h|--help) - usage - exit 0 - ;; - (-q) qflag=yes;; - (-v) vflag=yes;; - (-r) reader_prog="$2"; shift;; - (-w) writer_prog="$2"; shift;; - (-e) engine="$2"; shift;; - (-f) filename="$2"; shift;; - (-n) nw="$2"; nr="$2"; shift;; - (-p) prefix="$2"; shift;; - (-nw) nw="$2"; shift;; - (-nr) nr="$2"; shift;; - (-arg) args="$args $2"; shift;; - (-rd) reader_delay="$2"; shift;; - (--) shift; break;; - (-*) echo "$0: error - unrecognized option $1" ; usage; 1>&2; exit 1;; - (*) break;; - esac - shift -done - -cd @CMAKE_RUNTIME_OUTPUT_DIRECTORY@ - -if [ "$reader_prog" == "UNSET" ]; then - reader_prog="$prefix""Read" -fi -if [ "$writer_prog" == "UNSET" ]; then - writer_prog="$prefix""Write" -fi - -# remove any lingering engine contact files (IF YOU ADD AN ENGINE, ADD TO THIS LIST) -rm -f $filename.{sst,other} - -use_mpmd=0; -if [ $reader_delay -ne 0 ] ; then - use_mpmd=0; -fi - -if [ $nr -eq 0 ] ; then - use_mpmd=0; -fi - -if [ -z "@MPIEXEC@" ]; then - write_spawn_cmd="" - read_spawn_cmd="" - use_mpmd=0 -elif [ "@MPIEXEC@" = "MPIEXEC_EXECUTABLE-NOTFOUND" ]; then - write_spawn_cmd="" - read_spawn_cmd="" - use_mpmd=0 -else - write_spawn_cmd="@MPIEXEC@ @MPIEXEC_NUMPROC_FLAG@ $nw" - read_spawn_cmd="@MPIEXEC@ @MPIEXEC_NUMPROC_FLAG@ $nr" -fi - -if [ $use_mpmd -eq 1 ] ; then - mpmd_cmd="@MPIEXEC@ @MPIEXEC_NUMPROC_FLAG@ $nw ./$writer_prog $engine $filename $args : @MPIEXEC_NUMPROC_FLAG@ $nr ./$reader_prog $engine $filename $args" - if [ $vflag == "yes" ]; then - echo "Doing ($mpmd_cmd)" - fi - $mpmd_cmd - exit_value=$? -else - # Spawn the writer - if [ $nr -eq "0" ]; then - read_spawn_cmd="echo" - fi - - if [ $vflag == "yes" ]; then - echo "Doing ($write_spawn_cmd ./$writer_prog $engine $filename $args) & writer_pid=$!" - fi - - ($write_spawn_cmd ./$writer_prog $engine $filename $args ) & writer_pid=$! - - # Spawn the reader - if [ "$reader_delay" -ne 0 ]; then - sleep $reader_delay - fi - if [ $vflag == "yes" ]; then - echo "Doing ($read_spawn_cmd ./$reader_prog $engine $filename $args ) & reader_pid=$!" - fi - ($read_spawn_cmd ./$reader_prog $engine $filename $args) & reader_pid=$! - - - - # wait on our worker process and return the exitcode - if [ $vflag == "yes" ]; then - echo -n "Wait for reader $reader_pid " - date - fi - wait $reader_pid - reader_exitcode=$? - - # wait on our worker process and return the exitcode - if [ $vflag == "yes" ]; then - echo -n "Wait for writer $writer_pid " - date - fi - - wait $writer_pid - writer_exitcode=$? - - exit_value=0 - if [ "$writer_exitcode" -ne "0" ]; then - echo "$writer_prog exited with error code $writer_exitcode" - exit_value=1 - fi - if [ "$reader_exitcode" -ne "0" ]; then - echo "$reader_prog exited with error code $reader_exitcode" - exit_value=1 - fi -fi - -if [ $qflag != "yes" ]; then - if [ $exit_value -eq "0" ]; then - echo "TEST PASSED"; - else - echo "TEST FAILED"; - fi -fi - -exit $exit_value diff --git a/testing/adios2/engine/staging-common/run_test.in b/testing/adios2/engine/staging-common/run_test.in new file mode 100755 index 0000000000..88720d1d6d --- /dev/null +++ b/testing/adios2/engine/staging-common/run_test.in @@ -0,0 +1,216 @@ +#!/usr/bin/python +# This script has been build to run the tests in the bin directory. +import argparse +import subprocess +import os +import sys +import shutil +import time +import random +import atexit + + +def test_setup(testname) : + testdir = testname + "_testdir" + if os.path.exists(testdir): + shutil.rmtree(testdir) + os.mkdir(testdir) + os.chdir(testdir) + +def test_teardown(testname) : + testdir = testname + "_testdir" + os.chdir('..') + shutil.rmtree(testdir) + +def touch(path): + with open(path, 'a'): + os.utime(path, None) + +def clean_server_kill(writer): + touch('DieTest'); + writer.wait() + os.remove('DieTest') + +def do_simple_test(writer_cmd, reader_cmd, reader_delay) : + return_code = 0; + writer = subprocess.Popen(writer_cmd); + + if reader_cmd is not None : + time.sleep(reader_delay) + reader = subprocess.Popen(reader_cmd); + reader.wait(); + print "TestDriver: Reader exit status was " + str(reader.returncode); + if reader.returncode != 0 : + print "TestDriver: Reader failed, causing test failure" + return_code = 1 + + writer.wait(); + print("TestDriver: Writer exit status was " + str(writer.returncode)); + if writer.returncode != 0 : + print "TestDriver: Writer failed, causing test failure" + return_code = 1 + return return_code + +def do_one_client_test(writer_cmd, reader_cmd) : + return_code = 0; + writer = subprocess.Popen(writer_cmd); + reader = subprocess.Popen(reader_cmd); + reader.wait(); + print "TestDriver: Reader exit status was " + str(reader.returncode); + if reader.returncode != 0 : + print "TestDriver: Reader failed, causing test failure" + return_code = 1 + clean_server_kill(writer); + print("TestDriver: Writer exit status was " + str(writer.returncode)); + if writer.returncode != 0 : + print "TestDriver: Writer failed, causing test failure" + return_code = 1 + return return_code + +def do_kill_writer_test(writer_cmd, reader_cmd, interval) : + return_code = 0; + writer = subprocess.Popen(writer_cmd); + reader = subprocess.Popen(reader_cmd); + print "TestDriver: Waiting " + str(interval) + " seconds"; + time.sleep(interval); + print "TestDriver: Killing Writer"; + writer.terminate(); + writer.wait(); + reader.wait(); + print("TestDriver: Reader exit status was " + str(reader.returncode)); + if reader.returncode != 0 : + print("TestDriver: Reader failed, causing test failure") + return_code = 1 + print("TestDriver: Writer exit status was " + str(writer.returncode)) + " (ignored)"; + return return_code + +def do_kill_readers_test(writer_cmd, reader_cmd, duration, interval) : + return_code = 0; + writer = subprocess.Popen(writer_cmd); + start = time.time(); + timeout = time.time() + duration; + readers = []; + while (time.time() < timeout) : + print ("TestDriver: Beginning interval at time " + str(time.time() - start)); + if (((len(readers) == 0) or (random.randint(0,1) == 0)) and (len(readers) < args.max_readers)) : + print "TestDriver: Forking a reader"; + reader = subprocess.Popen(reader_cmd); + readers.append(reader); + print "TestDriver: There are now " + str(len(readers)) + " readers"; + else : + reader_index = random.randrange(0,len(readers)) + print "TestDriver: Killing a reader " + str(reader_index) + " out of " + str(len(readers)); + readers[reader_index].poll(); + if readers[reader_index].returncode is not None : + # if reader has already exited, we want to know if it thinks it succeeded and fail otherwise + if readers[reader_index].returncode != 0 : + print("TestDriver: Unterminated Reader failed, causing test failure (return code) " + str(readers[reader_index].returncode) ) + return_code = 1 + + else : + # if reader hasn't already exited, kill it and ignore the exit status + readers[reader_index].terminate(); + readers[reader_index].wait(); + readers.pop(reader_index); + print("Sleeping for time interval " + str(interval)); + sys.stdout.flush() + time.sleep(interval); + for reader in readers : + reader.wait(); + print("TestDriver: Surviving reader exit status was " + str(reader.returncode)); + if reader.returncode != 0 : + print("TestDriver: Reader failed, causing test failure"); + return_code = 1; + sys.stdout.flush() + clean_server_kill(writer); + print("TestDriver: Writer exit status was " + str(writer.returncode)); + if writer.returncode != 0 : + print("TestDriver: Writer failed, causing test failure") + return_code = 1 + return return_code + + +script_directory = sys.path[0]; #os.path.basename(os.path.dirname(os.path.realpath(__file__))); + +parser = argparse.ArgumentParser(description='Run a staging test.') + +parser.add_argument('--verbose', '-v', action='count') +parser.add_argument('--num_writers', '-nw', type=int, default=1) +parser.add_argument('--num_readers', '-nr', type=int, default=1) +parser.add_argument('--warg', action='append', type=str, nargs="?") +parser.add_argument('--rarg', action='append', type=str, nargs="?") +parser.add_argument('--writer', '-w') +parser.add_argument('--reader', '-r') +parser.add_argument('--max_readers', '-mr', type=int, default=1) +parser.add_argument('--duration', type=int, default=60) +parser.add_argument('--interval', type=int, default=5) +parser.add_argument('--reader_delay', '-rd', type=int, default=0) +parser.add_argument('--test_protocol', '-tp', choices=['simple', 'kill_readers', 'one_client', 'kill_writer'], default='simple') +parser.add_argument('engine', default = 'sst') +parser.add_argument('filename', default = 'tmp') + +args = parser.parse_args() + +if args.test_protocol == 'simple' : + if args.writer is None: + args.writer = 'TestCommonWrite' + if args.reader is None: + args.reader = 'TestCommonRead' +else : + if args.writer is None: + args.writer = 'TestCommonServer' + if args.reader is None: + args.reader = 'TestCommonClient' + +writer_exec_cmd = '@MPIEXEC@ @MPIEXEC_NUMPROC_FLAG@ ' + str(args.num_writers); +reader_exec_cmd = '@MPIEXEC@ @MPIEXEC_NUMPROC_FLAG@ ' + str(args.num_readers); + +if ("@MPIEXEC@" == "") or ("@MPIEXEC@" == "MPIEXEC_EXECUTABLE-NOTFOUND"): + # NO MPI + writer_exec_cmd = ''; + reader_exec_cmd = ''; + +print ("Script directory is " + script_directory); +print ("current working directory is " + os.getcwd()); + +writer_executable = os.path.abspath(os.path.join(script_directory, args.writer)); +writer_command_line = writer_exec_cmd.split() +writer_command_line.extend([writer_executable, args.engine, args.filename]) + +if args.warg is not None: + writer_command_line.extend(args.warg) + +reader_executable = os.path.abspath(os.path.join(script_directory, args.reader)); +reader_command_line = reader_exec_cmd.split() +reader_command_line.extend([reader_executable, args.engine, args.filename]) + +if args.rarg is not None: + reader_command_line.extend(args.rarg) + +if args.num_readers == 0: + reader_command_line = None; + +print("TestDriver: Writer command line : " + " ".join(writer_command_line)); +if reader_command_line is not None: + print("TestDriver: Reader command line : " + " ".join(reader_command_line)); + +test_setup(args.filename) +atexit.register(test_teardown, args.filename) +if args.test_protocol == 'simple': + return_code = do_simple_test(writer_command_line, reader_command_line, args.reader_delay); + +elif args.test_protocol == 'kill_readers': + return_code = do_kill_readers_test(writer_command_line, reader_command_line, args.duration, args.interval); + +elif args.test_protocol == 'one_client': + return_code = do_one_client_test(writer_command_line, reader_command_line); + +elif args.test_protocol == 'kill_writer': + return_code = do_kill_writer_test(writer_command_line, reader_command_line, args.interval); + +if return_code != 0 : + print("TestDriver: Exiting with overall failure code"); +else : + print("TestDriver: exiting with success condition"); + +sys.exit(return_code); From 7f0172850583b11fa8d01c5ec15ca466a4cbb772 Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Sat, 18 May 2019 13:06:15 -0400 Subject: [PATCH 2/5] try stdin stdout specs --- testing/adios2/engine/staging-common/run_test.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/adios2/engine/staging-common/run_test.in b/testing/adios2/engine/staging-common/run_test.in index 88720d1d6d..c341af6bcb 100755 --- a/testing/adios2/engine/staging-common/run_test.in +++ b/testing/adios2/engine/staging-common/run_test.in @@ -69,8 +69,8 @@ def do_one_client_test(writer_cmd, reader_cmd) : def do_kill_writer_test(writer_cmd, reader_cmd, interval) : return_code = 0; - writer = subprocess.Popen(writer_cmd); - reader = subprocess.Popen(reader_cmd); + writer = subprocess.Popen(writer_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); + reader = subprocess.Popen(reader_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); print "TestDriver: Waiting " + str(interval) + " seconds"; time.sleep(interval); print "TestDriver: Killing Writer"; @@ -86,7 +86,7 @@ def do_kill_writer_test(writer_cmd, reader_cmd, interval) : def do_kill_readers_test(writer_cmd, reader_cmd, duration, interval) : return_code = 0; - writer = subprocess.Popen(writer_cmd); + writer = subprocess.Popen(writer_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); start = time.time(); timeout = time.time() + duration; readers = []; @@ -94,7 +94,7 @@ def do_kill_readers_test(writer_cmd, reader_cmd, duration, interval) : print ("TestDriver: Beginning interval at time " + str(time.time() - start)); if (((len(readers) == 0) or (random.randint(0,1) == 0)) and (len(readers) < args.max_readers)) : print "TestDriver: Forking a reader"; - reader = subprocess.Popen(reader_cmd); + reader = subprocess.Popen(reader_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); readers.append(reader); print "TestDriver: There are now " + str(len(readers)) + " readers"; else : From 035d9c86305821eb53cc95fd1211228415201a6f Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Sun, 19 May 2019 11:11:46 -0400 Subject: [PATCH 3/5] Test to see if mpiexec is a binary or a script and only do kill tests if it's a binary --- .../engine/staging-common/CMakeLists.txt | 25 ++++++++++++++++++- .../adios2/engine/staging-common/run_test.in | 8 +++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/testing/adios2/engine/staging-common/CMakeLists.txt b/testing/adios2/engine/staging-common/CMakeLists.txt index ca1e793a96..546a405f2d 100644 --- a/testing/adios2/engine/staging-common/CMakeLists.txt +++ b/testing/adios2/engine/staging-common/CMakeLists.txt @@ -89,6 +89,24 @@ configure_file( @ONLY ) +if (ADIOS2_HAVE_MPI) + # we want to know if mpiexec is a shell script or a binary executable + file(READ ${MPIEXEC} MPIFILEDATA LIMIT 1024 HEX) + string(LENGTH ${MPIFILEDATA} DATALENGTH) + math(EXPR last_hex_index "${DATALENGTH} / 2") + foreach(hex_index RANGE ${last_hex_index}) + string(SUBSTRING "${MPIFILEDATA}" "${hex_index}" "2" char) + message("${char}") + message("0x${char} * 1" ) + math (EXPR dec_char "0x${char} * 1" ) + if ((${dec_char} LESS 9) OR (${dec_char} GREATER 126) OR ((${dec_char} GREATER 13) AND (${dec_char} LESS 32))) + # message ("$character ${char} is outside of the printable/character ascii range") + set (MPIEXEC_IS_BINARY TRUE) + break() + endif() + endforeach() +endif() + include ( TestSupp.cmake ) set (TEST_SET "1x1;NoReaderNoWait;Modes;1x1.Attrs;1x1.Local") @@ -96,7 +114,12 @@ set (FORTRAN_TESTS "") if(ADIOS2_HAVE_Fortran) set (FORTRAN_TESTS "FtoC.1x1;CtoF.1x1;FtoF.1x1") endif() -set (SPECIAL_TESTS "KillReadersSerialized;KillReaders3Max;TimeoutReader;KillWriter_2x2;KillWriterTimeout_2x2;LatestReader;DiscardWriter;PreciousTimestep;PreciousTimestepDiscard") + +set (SPECIAL_TESTS "TimeoutReader;LatestReader;DiscardWriter;PreciousTimestep;PreciousTimestepDiscard") +if (MPIEXEC_IS_BINARY) + # run_test.py can only kill readers/writers if mpiexec is not a shell script + list(APPEND SPECIAL_TESTS "KillReadersSerialized;KillReaders3Max;KillWriter_2x2;KillWriterTimeout_2x2") +endif() set (MPI_TESTS "") set (MPI_FORTRAN_TESTS "") diff --git a/testing/adios2/engine/staging-common/run_test.in b/testing/adios2/engine/staging-common/run_test.in index c341af6bcb..88720d1d6d 100755 --- a/testing/adios2/engine/staging-common/run_test.in +++ b/testing/adios2/engine/staging-common/run_test.in @@ -69,8 +69,8 @@ def do_one_client_test(writer_cmd, reader_cmd) : def do_kill_writer_test(writer_cmd, reader_cmd, interval) : return_code = 0; - writer = subprocess.Popen(writer_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); - reader = subprocess.Popen(reader_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); + writer = subprocess.Popen(writer_cmd); + reader = subprocess.Popen(reader_cmd); print "TestDriver: Waiting " + str(interval) + " seconds"; time.sleep(interval); print "TestDriver: Killing Writer"; @@ -86,7 +86,7 @@ def do_kill_writer_test(writer_cmd, reader_cmd, interval) : def do_kill_readers_test(writer_cmd, reader_cmd, duration, interval) : return_code = 0; - writer = subprocess.Popen(writer_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); + writer = subprocess.Popen(writer_cmd); start = time.time(); timeout = time.time() + duration; readers = []; @@ -94,7 +94,7 @@ def do_kill_readers_test(writer_cmd, reader_cmd, duration, interval) : print ("TestDriver: Beginning interval at time " + str(time.time() - start)); if (((len(readers) == 0) or (random.randint(0,1) == 0)) and (len(readers) < args.max_readers)) : print "TestDriver: Forking a reader"; - reader = subprocess.Popen(reader_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False); + reader = subprocess.Popen(reader_cmd); readers.append(reader); print "TestDriver: There are now " + str(len(readers)) + " readers"; else : From 5220263cc559c8db0174091fe98740d746712c1f Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Sun, 19 May 2019 13:25:01 -0400 Subject: [PATCH 4/5] Ugh. Hexadecimal support in CMake is too new. --- .../engine/staging-common/CMakeLists.txt | 16 +++------- .../engine/staging-common/TestSupp.cmake | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/testing/adios2/engine/staging-common/CMakeLists.txt b/testing/adios2/engine/staging-common/CMakeLists.txt index 546a405f2d..026f489c3b 100644 --- a/testing/adios2/engine/staging-common/CMakeLists.txt +++ b/testing/adios2/engine/staging-common/CMakeLists.txt @@ -89,16 +89,17 @@ configure_file( @ONLY ) +include (TestSupp.cmake ) + if (ADIOS2_HAVE_MPI) # we want to know if mpiexec is a shell script or a binary executable file(READ ${MPIEXEC} MPIFILEDATA LIMIT 1024 HEX) string(LENGTH ${MPIFILEDATA} DATALENGTH) - math(EXPR last_hex_index "${DATALENGTH} / 2") + math(EXPR last_hex_index "(${DATALENGTH} / 2) - 1") foreach(hex_index RANGE ${last_hex_index}) string(SUBSTRING "${MPIFILEDATA}" "${hex_index}" "2" char) - message("${char}") - message("0x${char} * 1" ) - math (EXPR dec_char "0x${char} * 1" ) + #math (EXPR dec_char "0x${char}" ) + from_hex(${char} dec_char) if ((${dec_char} LESS 9) OR (${dec_char} GREATER 126) OR ((${dec_char} GREATER 13) AND (${dec_char} LESS 32))) # message ("$character ${char} is outside of the printable/character ascii range") set (MPIEXEC_IS_BINARY TRUE) @@ -107,8 +108,6 @@ if (ADIOS2_HAVE_MPI) endforeach() endif() -include ( TestSupp.cmake ) - set (TEST_SET "1x1;NoReaderNoWait;Modes;1x1.Attrs;1x1.Local") set (FORTRAN_TESTS "") if(ADIOS2_HAVE_Fortran) @@ -154,16 +153,11 @@ MutateTestSet( BP_SST_TESTS "BP" "MarshalMethod:BP" "${COMM_MIN_SST_TESTS};${COM set (SST_TESTS "") LIST (APPEND SST_TESTS ${FFS_SST_TESTS} ${BP_SST_TESTS}) -list( LENGTH SST_TESTS beforelistlen ) - # remove Fto anything tests that use FFS because we can't spec it list(FILTER SST_TESTS EXCLUDE REGEX "Fto.*FFS.*") # remove Fto anything tests that use CommMin because we can't spec it list(FILTER SST_TESTS EXCLUDE REGEX "Fto.*CommMin.*") -list( LENGTH SST_TESTS afterlistlen ) -message (STATUS "Staging tests list before was ${beforelistlen}, after is ${afterlistlen}") - foreach(test ${SST_TESTS}) add_common_test(${test} SST) endforeach() diff --git a/testing/adios2/engine/staging-common/TestSupp.cmake b/testing/adios2/engine/staging-common/TestSupp.cmake index 3bfa2fde93..f38429a943 100644 --- a/testing/adios2/engine/staging-common/TestSupp.cmake +++ b/testing/adios2/engine/staging-common/TestSupp.cmake @@ -193,3 +193,34 @@ function(add_common_test basename engine) set_tests_properties(${testname} PROPERTIES TIMEOUT ${timeout} ${${basename}_PROPERTIES} ) endfunction() +function(from_hex HEX DEC) + string(TOUPPER "${HEX}" HEX) + set(_res 0) + string(LENGTH "${HEX}" _strlen) + + while(_strlen GREATER 0) + math(EXPR _res "${_res} * 16") + string(SUBSTRING "${HEX}" 0 1 NIBBLE) + string(SUBSTRING "${HEX}" 1 -1 HEX) + if(NIBBLE STREQUAL "A") + math(EXPR _res "${_res} + 10") + elseif(NIBBLE STREQUAL "B") + math(EXPR _res "${_res} + 11") + elseif(NIBBLE STREQUAL "C") + math(EXPR _res "${_res} + 12") + elseif(NIBBLE STREQUAL "D") + math(EXPR _res "${_res} + 13") + elseif(NIBBLE STREQUAL "E") + math(EXPR _res "${_res} + 14") + elseif(NIBBLE STREQUAL "F") + math(EXPR _res "${_res} + 15") + else() + math(EXPR _res "${_res} + ${NIBBLE}") + endif() + + string(LENGTH "${HEX}" _strlen) + endwhile() + + set(${DEC} ${_res} PARENT_SCOPE) +endfunction() + From e18cb65e83458eeadc2aed71933afee0ef145e52 Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Sun, 19 May 2019 15:22:00 -0400 Subject: [PATCH 5/5] extract the right hex string --- testing/adios2/engine/staging-common/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/adios2/engine/staging-common/CMakeLists.txt b/testing/adios2/engine/staging-common/CMakeLists.txt index 026f489c3b..b1e655d93d 100644 --- a/testing/adios2/engine/staging-common/CMakeLists.txt +++ b/testing/adios2/engine/staging-common/CMakeLists.txt @@ -97,7 +97,8 @@ if (ADIOS2_HAVE_MPI) string(LENGTH ${MPIFILEDATA} DATALENGTH) math(EXPR last_hex_index "(${DATALENGTH} / 2) - 1") foreach(hex_index RANGE ${last_hex_index}) - string(SUBSTRING "${MPIFILEDATA}" "${hex_index}" "2" char) + math (EXPR str_loc "2*${hex_index}") + string(SUBSTRING "${MPIFILEDATA}" "${str_loc}" "2" char) #math (EXPR dec_char "0x${char}" ) from_hex(${char} dec_char) if ((${dec_char} LESS 9) OR (${dec_char} GREATER 126) OR ((${dec_char} GREATER 13) AND (${dec_char} LESS 32)))