Improvs.
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Wed, 26 Oct 2016 22:42:21 +0000 (00:42 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Wed, 26 Oct 2016 22:42:21 +0000 (00:42 +0200)
dynamic/launcher/gx/00001/CCR-I.xml [new file with mode: 0644]
dynamic/launcher/gx/00001/CCR-T.xml [new file with mode: 0644]
dynamic/launcher/gx/00001/dynamic.suffix [new file with mode: 0644]
example/diameter/launcher/deployments/st-client/configure.sh
example/diameter/launcher/deployments/st-client/operation_all.sh
example/diameter/launcher/deployments/st-client/program.sh

diff --git a/dynamic/launcher/gx/00001/CCR-I.xml b/dynamic/launcher/gx/00001/CCR-I.xml
new file mode 100644 (file)
index 0000000..a57ef6d
--- /dev/null
@@ -0,0 +1,48 @@
+<message version="1" name="CC-Request" application-id="16777238" hop-by-hop-id="3" end-by-end-id="120858624">
+   <avp name="Session-Id" data="111110000000;BAT004;esmdx0900.gxrel10plusrealm.com;9020000000"/>
+   <avp name="Origin-Host" data="esmdx0900.gxrel10plusrealm.com"/>
+   <avp name="Origin-Realm" data="gxrel10plusrealm.com"/>
+   <avp name="Destination-Realm" data="operatorRealm.com"/>
+   <avp name="Origin-State-Id" data="1"/>
+   <avp name="CC-Request-Number" data="0"/>
+   <avp name="CC-Request-Type" data="1" alias="INITIAL_REQUEST"/>
+   <avp name="Bearer-Usage" data="0" alias="GENERAL"/>
+   <avp name="Framed-IP-Address" hex-data="00000000"/>
+   <avp name="IP-CAN-Type" data="0" alias="3GPP-GPRS"/>
+   <avp name="Subscription-Id">
+      <avp name="Subscription-Id-Type" data="0" alias="END_USER_E164"/>
+      <avp name="Subscription-Id-Data" data="111110000000"/>
+   </avp>
+   <avp name="Subscription-Id">
+      <avp name="Subscription-Id-Type" data="1" alias="END_USER_IMSI"/>
+      <avp name="Subscription-Id-Data" data="0000000"/>
+   </avp>
+   <avp name="Gx-Capability-List" data="25"/>
+   <avp name="Bearer-Identifier" hex-data="3131313131"/>
+   <avp name="Bearer-Operation" data="1" alias="ESTABLISHMENT"/>
+   <avp name="Supported-Features" flags="192">
+      <avp name="Vendor-Id" data="10415"/>
+      <avp name="Feature-List-ID" data="1"/>
+      <avp name="Feature-List" data="11"/>
+   </avp>
+   <avp name="RAI" data="123456010a00"/>
+   <avp name="RAT-Type" data="1000" alias="UTRAN"/>
+   <avp name="Called-Station-Id" data="10.20.110.25"/>
+   <avp name="QoS-Information">
+      <avp name="QoS-Class-Identifier" data="1" alias="QCI_1"/>
+      <avp name="Max-Requested-Bandwidth-UL" data="504000"/>
+      <avp name="Max-Requested-Bandwidth-DL" data="504000"/>
+      <avp name="Guaranteed-Bitrate-UL" data="104000"/>
+      <avp name="Guaranteed-Bitrate-DL" data="104000"/>
+      <avp name="Allocation-Retention-Priority">
+         <avp name="Priority-Level" data="1"/>
+      </avp>
+   </avp>
+   <avp name="QoS-Negotiation" data="1" alias="QoS_NEGOTIATION_SUPPORTED"/>
+   <avp name="QoS-Upgrade" data="1" alias="QoS_UPGRADE_SUPPORTED"/>
+   <avp name="3GPP-Charging-Characteristics" data="0457"/>
+   <avp name="3GPP-User-Location-Info" hex-data="313233343536373839"/>
+   <avp name="3GPP-SGSN-Address" hex-data="0a011450"/>
+   <avp name="Rule-Space-Suggestion" hex-data="43"/>
+   <avp name="Auth-Application-Id" data="16777238"/>
+</message>
diff --git a/dynamic/launcher/gx/00001/CCR-T.xml b/dynamic/launcher/gx/00001/CCR-T.xml
new file mode 100644 (file)
index 0000000..ac44202
--- /dev/null
@@ -0,0 +1,13 @@
+<message version="1" name="CC-Request" application-id="16777238" hop-by-hop-id="4" end-by-end-id="920291330">
+   <avp name="Session-Id" data="111110000000;BAT004;esmdx0900.gxrel10plusrealm.com;9020000000"/>
+   <avp name="Origin-Host" data="esmdx0900.gxrel10plusrealm.com"/>
+   <avp name="Origin-Realm" data="gxrel10plusrealm.com"/>
+   <avp name="Destination-Realm" data="operatorRealm.com"/>
+   <avp name="Origin-State-Id" data="1"/>
+   <avp name="CC-Request-Number" data="1"/>
+   <avp name="CC-Request-Type" data="3" alias="TERMINATION_REQUEST"/>
+   <avp name="Bearer-Usage" data="0" alias="GENERAL"/>
+   <avp name="Termination-Cause" data="1" alias="LOGOUT"/>
+   <avp name="Framed-IP-Address" hex-data="00000000"/>
+   <avp name="Auth-Application-Id" data="16777238"/>
+</message>
diff --git a/dynamic/launcher/gx/00001/dynamic.suffix b/dynamic/launcher/gx/00001/dynamic.suffix
new file mode 100644 (file)
index 0000000..555d12c
--- /dev/null
@@ -0,0 +1,2 @@
+7|CCR-I.xml
+7|CCR-I.xml|CCR-T.xml
index b818a78..25646f3 100755 (executable)
@@ -57,17 +57,18 @@ calculate_deployment_layout() {
   echo "Orientative table"
   echo "-----------------------------------------------------------------------------------------------------------"
   echo -n "Number of instances:  "
+  instances__dflt=$(ceil $max_connections $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE)
   for conn in `seq 1 $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE | tac`
   do
     instances=$(ceil $max_connections $conn)
     echo -n -e "\t$instances"
+    [ $conn -eq 2 ] && instances__dflt=$instances
   done
   echo
   echo -e "Connects per instance:\t10\t9\t8\t7\t6\t5\t4\t3\t2\t1"
   echo "==========================================================================================================="
   echo
   #echo "Input selection (connections per instance 1..$MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE) [1]:"
-  instances__dflt=$(ceil $max_connections $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE)
   echo "Input the desired number of ADML instances [$instances__dflt]:"
   echo " (more than $instances instances, implies 1 single connection/instance)"
   read G_ADML_INSTANCES
@@ -77,7 +78,7 @@ calculate_deployment_layout() {
   if [ $G_ADML_CONNECTIONS -gt $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE ]
   then
     echo "Warning: the number of connections per ADML instance ($G_ADML_CONNECTIONS) is greater"
-    echo "         than the maximum suggested: $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE"
+    echo "         than the maximum recommended: $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE"
     echo
     echo "Press ENTER to continue, CTRL-C to abort ..."
     read dummy
@@ -135,12 +136,15 @@ fi
 
 calculate_deployment_layout
 
+# Format for instance number (for example: 1 -> 001, .., 45 -> 045, 300 -> 300)
+INSTANCE_FORMAT=$(echo $G_ADML_INSTANCES | wc -c)
+INSTANCE_FORMAT=$((INSTANCE_FORMAT-1))
+
 # Dump persintently:
 echo $G_ADML_INSTANCES > $ADML_INSTANCES__ST_CONF_FILE
 echo $G_ADML_CONNECTIONS > $ADML_CONNECTIONS__ST_CONF_FILE
 
 # Rate per instance:
-#rate_per_instance=$(ceil $desired_rate $G_ADML_INSTANCES)
 rate_per_instance=$((desired_rate/$G_ADML_INSTANCES))
 [ $rate_per_instance -lt 1 ] && rate_per_instance=1
 echo $rate_per_instance > $ADML_RATE_PER_INSTANCE__ST_CONF_FILE
@@ -151,7 +155,6 @@ echo "Layout:"
 echo
 echo " - $G_ADML_INSTANCES ADML instances"
 echo " - $G_ADML_CONNECTIONS client connections per ADML instance"
-#maximum_rate_1c=$((G_ADML_INSTANCES*MAXIMUM_ADML_ASYNC_RATE))
 maximum_rate=$((G_ADML_INSTANCES*G_ADML_CONNECTIONS*MAXIMUM_ADML_ASYNC_RATE))
 overcommit_rate_per_instance=$((G_ADML_CONNECTIONS*MAXIMUM_ADML_ASYNC_RATE))
 echo
@@ -171,35 +174,20 @@ echo "Input the number of test cases to program:"
 read N_TESTCASES
 while [ -z "$N_TESTCASES" ]; do read N_TESTCASES; done
 echo $N_TESTCASES > $N_TESTCASES__ST_CONF_FILE
-testcase_per_adml_instance=$N_TESTCASES
 echo "Input the first test id to program [1]:"
 read first_value
 [ "$first_value" = "" ] && first_value=1
 [ $first_value -lt 1 ] && first_value=1
 echo
-time_covered_1=$(ceil $N_TESTCASES $desired_rate)
-time_covered=$(ceil $N_TESTCASES $((desired_rate*G_ADML_INSTANCES)))
-echo "That amount covers $time_covered_1 seconds for one running ADML instance."
-if [ $G_ADML_INSTANCES -gt 1 ]
-then
-  echo "But you will have $G_ADML_INSTANCES instances running in parallel, then the total covered time is: $time_covered seconds"
-  testcase_per_adml_instance=$((N_TESTCASES/G_ADML_INSTANCES))
-  echo "(aproximately, $testcase_per_adml_instance test cases will be programmed on each ADML instance)"
-fi
-
-0>$N_TESTCASES_PROGRAM_LAYOUT__ST_CONF_FILE
-for instance in `seq 1 $G_ADML_INSTANCES`
-do
-  offset=$((testcase_per_adml_instance * (instance-1)))
-  ini=$((offset + first_value))
-  fin=$((offset + first_value + testcase_per_adml_instance - 1))
-  echo "$instance $ini $fin" >> $N_TESTCASES_PROGRAM_LAYOUT__ST_CONF_FILE
-done
+time_covered=$(echo "$N_TESTCASES/$desired_rate" | bc)
+testcase_per_adml_instance=$((N_TESTCASES/G_ADML_INSTANCES))
+echo "Aproximately, $testcase_per_adml_instance test cases will be programmed on each ADML instance (we have $G_ADML_INSTANCES instances)."
+echo "As we shall program $N_TESTCASES test cases, the total time covered for the desired system rate of $desired_rate cps, is $time_covered seconds."
 
 echo
-if [ $time_covered -lt 300 ]
+if [ $time_covered -lt 10 ]
 then
-  echo "$time_covered seconds is under 5 minutes, you should add more test cases to the pool except if you are sure"
+  echo "$time_covered seconds is under 10 seconds, you should add more test cases to the pool except if you are sure"
   echo " they will take less time that cycle completion. You could ensure that with a first timeout step."
   echo "Configuring such timeout slightly under $((1000*time_covered)) milliseconds, you could repeat the cycle safely to"
   echo " obtain a greater total time of testing."
@@ -209,17 +197,20 @@ echo "How many total time you need to cover (in minutes):"
 read minutes
 while [ -z "$minutes" ]; do read minutes; done
 seconds=$((minutes*60))
-repeats=$(ceil $seconds $time_covered)
+repeats=0
+[ $seconds -gt $time_covered ] && { repeats=$(ceil $seconds $time_covered) ; repeats=$((repeats-1)) ; }
 if [ $repeats -gt 0 ]
 then
-  echo "You will need $repeats cycles to cover $minutes minutes."
-  echo "Input the number of cyles [$repeats]: "
-  echo " (providing 0, you will cover $time_covered seconds)"
+  cycles=$((repeats+1))
+  echo "You will need $cycles cycles to cover $minutes minutes."
+  echo "Input the desired number of cyles [$cycles]: "
+  echo " (providing 1, you will cover $time_covered seconds)"
   echo
-  read wanted_repeats
-  [ -z "$wanted_repeats" ] && wanted_repeats=$repeats
-  echo $wanted_repeats > $CYCLE_REPEATS__ST_CONF_FILE
-  [ $wanted_repeats -gt 0 ] && echo "Configured $wanted_repeats cycle repeats ($((wanted_repeats+1)) x $time_covered seconds ~ $(((wanted_repeats+1)*time_covered)) seconds of testing)."
+  read wanted_cycles
+  [ -z "$wanted_cycles" ] && wanted_cycles=$cycles
+  wanted_repeats=$((wanted_cycles-1))
+  echo $wanted_cycles > $CYCLE_REPEATS__ST_CONF_FILE
+  [ $wanted_repeats -gt 0 ] && echo "Configured $wanted_repeats cycle repeats ($wanted_cycles cycles x $time_covered seconds ~ $((wanted_cycles*time_covered)) seconds of testing)."
 fi
 echo
 echo "System test configuration completed."
@@ -233,9 +224,16 @@ cp services.msk services.xml
 sed -i 's/__CLIENT_CONNECTIONS__/'$G_ADML_CONNECTIONS'/g' services.xml
 cd - >/dev/null
 
-
-for instance in `seq 1 $G_ADML_INSTANCES`
+# Create instances and layout:
+0>$N_TESTCASES_PROGRAM_LAYOUT__ST_CONF_FILE
+for i in `seq 1 $G_ADML_INSTANCES`
 do
+  instance=$(printf "%0${INSTANCE_FORMAT}d" $i)
+  offset=$((testcase_per_adml_instance * (i-1)))
+  ini=$((offset + first_value))
+  fin=$((offset + first_value + testcase_per_adml_instance - 1))
+  echo "$instance $ini $fin" >> $N_TESTCASES_PROGRAM_LAYOUT__ST_CONF_FILE
+
   echo "Creating ADML instance $instance ..."
   mkdir -p ADMLS/ADML-$instance
   cd ADMLS/ADML-$instance
index e2efaa4..1304dfd 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
+# touch .operation_background to force background execution of every ADML instances operations "broadcasted"
 cd `dirname $0`
 if [ ! -d "ADMLS" ]
 then
@@ -8,14 +9,23 @@ then
   exit 1
 fi
 
+BGROUND=
+[ -f .operation_background ] && BGROUND=yes
+
 for op in `ls ADMLS/*/operation.sh`
 do
   dn_op=`dirname $op`
   cd $dn_op
   echo -n "Instance `basename $dn_op`: "
   0>launcher.trace
-  ./operation.sh $@
-  [ $? -ne 0 ] && { echo ; exit 1 ; }
+  if [ -n "$BGROUND" ]
+  then
+    ./operation.sh $@ &
+    sleep 0.01
+  else
+    ./operation.sh $@
+     [ $? -ne 0 ] && { echo ; exit 1 ; }
+  fi
   cd - >/dev/null
 done
 
index 07e7616..94dbebf 100755 (executable)
@@ -20,21 +20,64 @@ _exit() {
 }
 
 usage() {
-  echo "Usage: $0 <test stuff directory> [-s]"
-  echo
-  echo "       Performs test case programming from scratch (current test cases will be dropped from ADML involved instances)."
-  echo
-  echo "       test stuff directory: contains msk files, specially a testcase file with xml files referenced inside. Those"
-  echo "                             xml files (without the .msk extension) shall exists in the directory. For example:"
-  echo
-  echo "                                $0 st_examples/DynamicQualification"
-  echo
-  echo "                             Optionally, a file called 'specific' could exists containing testcase-specific information,"
-  echo "                             which normally will be used to specify database sentences. This file will be accumulated"
-  echo "                             as a cloning seed over the file 'specific.all' created on test stuff directory."
-  echo
-  echo
-  echo "       -s: start testing just after programming, using desired rate: $DESIRED_RATE test cases per second."
+  cat << EOF
+Usage: $0 <test stuff directory|dynamic> [-s]
+
+       Performs test case programming from scratch (current test cases will be dropped
+        from ADML involved instances). There are two types of programming depending on
+        the first argument provided:
+
+       test stuff directory:
+
+          The folder provided must contain msk files, specially a testcase file with
+          xml files referenced inside. Those xml files (without the .msk extension)
+          shall exists in the directory. For example:
+
+             $0 st_examples/DynamicQualification
+
+          Optionally, a file 'specific' could exists containing testcase-specific
+          information, which normally will be used to specify database sentences.
+          This file will be accumulated as a cloning seed over the file 'specific.all'
+          created on test stuff directory.
+
+          Template type programming could be used for medium-duration testings, because
+          the scripting used for programming, have lots of groups divisions which even
+          background-executed are much more slower on programming than a c++ builtin
+          procedure: dynamic type is the one for large sets of test cases:
+
+
+       dynamic:
+
+          The current dynamic procedure selected by mean 'dynlibs/select.sh' script,
+          will be programmed using its dirname resources: inside, you may found not
+          only the .so library but the needed xml files for the implemented scenary
+          and a file called 'dynamic.suffix' used to complete the dynamic operation
+          in this way:
+
+             dynamic|<initial sequence>|<final sequence>|<dynamic.suffix content>
+
+          For example, you could have this content for 'dynamic.suffix':
+
+             7|CCR-I.xml|CCR-T.xml
+
+          in order to generate the operation:
+
+             dynamic|<initial sequence>|<final sequence>|7|CCR-I.xml|CCR-T.xml
+
+          which would be parsed for the specific ADML instance programmed:
+
+             dynamic|2000001|2001000|7|CCR-I.xml|CCR-T.xml
+
+          The file 'dynamic.suffix' could have several lines for several scenaries.
+          In this case, this script will prompt for the desired one.
+
+          This script will build every operation for the configured ADML instances
+          to complete all the sequence ranges along the whole test system.
+
+
+
+       -s: start testing just after programming, using desired rate: $DESIRED_RATE test cases per second.
+EOF
   [ $ADML_INSTANCES -gt 1 ] && echo "           In your case, with $ADML_INSTANCES, a rate of $RATE_PER_INSTANCE ttps will be send per instance."
   echo
   _exit
@@ -58,68 +101,129 @@ echo
 
 ./operation.sh --ping >/dev/null
 [ $? -ne 0 ] && _exit "Programming aborted (some ADML client process is not running) !"
-TESTCASE_DIR=$1
+
+# Arguments:
+PROG_TYPE=$1
 AUTOSTART=$2
 
-[ ! -d $TESTCASE_DIR ] && _exit "Cannot found the test directory '$TESTCASE_DIR' !!"
-TESTCASE=( `ls $TESTCASE_DIR/testcase*msk 2>/dev/null` )
-TESTCASE_FILES=${#TESTCASE[@]}
-[ $TESTCASE_FILES -ne 1 ] && _exit "One and only one 'testcase*msk' file must be present !!"
-
-MAX_NUMBER_GROUPS=$(grep ^MAX_NUMBER_GROUPS= clone.sh | cut -d= -f2)
-CLONE_GROUPS=$((MAX_NUMBER_GROUPS/ADML_INSTANCES))
-#CLONE_GROUPS=1
-specific=
-[ -f $TESTCASE_DIR/specific ] && specific=specific
-
-[ -z "$ADML_CONCURRENT_PROVISION_JOBS" ] && ADML_CONCURRENT_PROVISION_JOBS=5
-
-count=0
-while read -r line
-do
-  instance=$(echo $line | awk '{ print $1 }')
-  ini_seq=$(echo $line | awk '{ print $2 }')
-  fin_seq=$(echo $line | awk '{ print $3 }')
-  ADML_DIR=`readlink -f ADMLS/ADML-$instance`
-  echo -e "\rCloning interval [$ini_seq,$fin_seq] for $(basename $ADML_DIR) ..."
-  ./clone.sh $ADML_DIR $TESTCASE $ini_seq $fin_seq $CLONE_GROUPS $specific &
-  sleep 0.1
-  count=$((count+1))
-  if [ $count -eq $ADML_CONCURRENT_PROVISION_JOBS ]
+# test case stuff programming #########################################################
+if [ "$PROG_TYPE" != "dynamic" ]
+then
+  TESTCASE_DIR=$PROG_TYPE
+
+  [ ! -d $TESTCASE_DIR ] && _exit "Cannot found the test directory '$TESTCASE_DIR' !!"
+  TESTCASE=( `ls $TESTCASE_DIR/testcase*msk 2>/dev/null` )
+  TESTCASE_FILES=${#TESTCASE[@]}
+  [ $TESTCASE_FILES -ne 1 ] && _exit "One and only one 'testcase*msk' file must be present !!"
+
+  MAX_NUMBER_GROUPS=$(grep ^MAX_NUMBER_GROUPS= clone.sh | cut -d= -f2)
+  CLONE_GROUPS=$((MAX_NUMBER_GROUPS/ADML_INSTANCES))
+  #CLONE_GROUPS=1
+  specific=
+  [ -f $TESTCASE_DIR/specific ] && specific=specific
+  
+  [ -z "$ADML_CONCURRENT_PROVISION_JOBS" ] && ADML_CONCURRENT_PROVISION_JOBS=5
+  
+  count=0
+  while read -r line
+  do
+    instance=$(echo $line | awk '{ print $1 }')
+    ini_seq=$(echo $line | awk '{ print $2 }')
+    fin_seq=$(echo $line | awk '{ print $3 }')
+    ADML_DIR=`readlink -f ADMLS/ADML-$instance`
+    echo -e "\rCloning interval [$ini_seq,$fin_seq] for $(basename $ADML_DIR) ..."
+    ./clone.sh $ADML_DIR $TESTCASE $ini_seq $fin_seq $CLONE_GROUPS $specific &
+    sleep 0.1
+    count=$((count+1))
+    if [ $count -eq $ADML_CONCURRENT_PROVISION_JOBS ]
+    then
+      idle_cpu=$(top -b -d 0.1 -n 2 | grep 'Cpu(s):'| tail -1 |awk '{print $8}')
+      echo
+      echo "Idle cpu = $idle_cpu%"
+      echo "if cpu is not overcommited, consider increase ADML_CONCURRENT_PROVISION_JOBS environment variable (now $ADML_CONCURRENT_PROVISION_JOBS)"
+      echo
+      wait $(jobs -p)
+      count=0
+    fi
+  
+  done < $PROGRAM_LAYOUT_FILE
+  
+  # Wait background jobs to finish:
+  sleep 5
+  echo "Waiting for clone completion ..."
+  echo "(please be patient, this may take a while)"
+  echo
+  echo "Background Jobs: $(jobs -p | wc -l)"
+  wait $(jobs -p)
+  
+  echo
+  echo "Programming has finished !"
+  echo
+  
+  echo "Configuring repeat cycles ..."
+  ./operation.sh "test|repeats|$REPEATS"
+  
+  if [ -n "$specific" ]
   then
-    idle_cpu=$(top -b -d 0.1 -n 2 | grep 'Cpu(s):'| tail -1 |awk '{print $8}')
-    echo
-    echo "Idle cpu = $idle_cpu%"
-    echo "if cpu is not overcommited, consider increase ADML_CONCURRENT_PROVISION_JOBS environment variable (now $ADML_CONCURRENT_PROVISION_JOBS)"
+    echo "A new file '$TESTCASE_DIR/specific.all' has been created."
+    echo "Probably you need to apply it before starting traffic."
     echo
-    wait $(jobs -p)
-    count=0
+    echo "Press ENTER to continue, CTRL-C to abort ..."
+    read dummy
   fi
 
-done < $PROGRAM_LAYOUT_FILE
+# dynamic programming #################################################################
+else
+  TESTCASE_DIR=$(readlink -f dynlibs/libanna_dynamicLauncherProcedure.so | xargs dirname)
+  DYNAMIC_SUFFIX_FILE=$TESTCASE_DIR/dynamic.suffix
 
-# Wait background jobs to finish:
-sleep 5
-echo "Waiting for clone completion ..."
-echo "(please be patient, this may take a while)"
-echo
-echo "Background Jobs: $(jobs -p | wc -l)"
-wait $(jobs -p)
+  [ ! -f $DYNAMIC_SUFFIX_FILE ] && _exit "Missing '$DYNAMIC_SUFFIX_FILE' file. Use 'dynlibs/select.sh' to change the dynamic procedure and restart the ADML instances."
+  dynamic_suffix=( $(grep -v ^# $DYNAMIC_SUFFIX_FILE) )
 
-echo
-echo "Programming has finished !"
-echo
+  # Multiple scenarios:
+  suffixes=${#dynamic_suffix[@]}
+  if [ $suffixes -gt 1 ]
+  then
+    echo "Detected $suffixes scenarios. Please, select the desired option:"
+    echo
+    tmpfile=$(mktemp)
+    opt=1
+    for line in $(grep -v ^# $DYNAMIC_SUFFIX_FILE)
+    do
+      echo "${opt}) $line"
+      opt=$((opt+1))
+    done > $tmpfile
+    cat $tmpfile
+    echo
+    read option
+    while [ -z "$option" ]; do read option ; done
+    dynamic_suffix=$(grep "^${option}) " $tmpfile | cut -d" " -f2-)
+    [ -z "$dynamic_suffix" ] && _exit "Invalid option !"
+  fi
 
-echo "Configuring repeat cycles ..."
-./operation.sh "test|repeats|$REPEATS"
+  while read -r line
+  do
+    instance=$(echo $line | awk '{ print $1 }')
+    ini_seq=$(echo $line | awk '{ print $2 }')
+    fin_seq=$(echo $line | awk '{ print $3 }')
+    ADML_DIR=`readlink -f ADMLS/ADML-$instance`
+  
+    cd $ADML_DIR
+
+    # Modify xml files path:
+    xmls=( $(echo $dynamic_suffix | sed 's/'\|'/ /g') )
+    dynamic_suffix=$(for xml in ${xmls[@]}
+    do
+      echo $xml | grep -q "\.xml$"
+      [ $? -eq 0 ] && echo -n "$TESTCASE_DIR/"
+      echo -n "${xml}|"
+    done | sed 's/'\|'$//')
+
+    ./operation.sh -t 15 "dynamic|$ini_seq|$fin_seq|$dynamic_suffix"
+    cd - >/dev/null
+  
+  done < $PROGRAM_LAYOUT_FILE
 
-if [ -n "$specific" ]
-then
-  echo "A new file '$TESTCASE_DIR/specific.all' has been created."
-  echo "Probably you need to apply it before starting traffic."
-  echo
-  echo "Press ENTER to continue, CTRL-C to abort ..."
-  read dummy
 fi
 
 echo