New st-client deployment. Allow to load same stack id (accumulative services), ignori...
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Tue, 13 Oct 2015 00:36:49 +0000 (02:36 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Tue, 13 Oct 2015 00:36:49 +0000 (02:36 +0200)
12 files changed:
example/diameter/launcher/DEPLOY.sh
example/diameter/launcher/DEPLOY_setups.sh
example/diameter/launcher/Launcher.cpp
example/diameter/launcher/deployments/st-client/README [new file with mode: 0644]
example/diameter/launcher/deployments/st-client/configure.sh [new file with mode: 0755]
example/diameter/launcher/deployments/st-client/hex_examples [new symlink]
example/diameter/launcher/deployments/st-client/operation.sh [new symlink]
example/diameter/launcher/deployments/st-client/run.sh [new file with mode: 0755]
example/diameter/launcher/deployments/st-client/run_all.sh [new file with mode: 0755]
example/diameter/launcher/deployments/st-client/xml_examples [new symlink]
example/diameter/launcher/testing/TestManager.cpp
example/diameter/launcher/testing/TestManager.hpp

index 3e3cbd9..e44e928 100755 (executable)
@@ -29,12 +29,13 @@ _exit () {
 }
 
 usage () {
-  echo "Usage: $0 [deployment_type: a|b|f] [deployment_path]"
+  echo "Usage: $0 [deployment_type: a|b|f|s] [deployment_path]"
   echo
   echo "       deployment_type:"
   echo "          a=advanced"
   echo "          b=basic"
   echo "          f=function test client"
+  echo "          s=system test client"
   echo "       deployment_path:"
   echo "          non-existent path directory."
   echo
@@ -42,6 +43,7 @@ usage () {
   echo "          $0 b $HOME/ADML/basicServer"
   echo "          $0 b $HOME/ADML/MMSbalancer"
   echo "          $0 f $HOME/ADML/tester"
+  echo "          $0 s $HOME/ADML/stress-client"
   echo
   exit 0
 }
@@ -54,6 +56,7 @@ createRunScript () {
   local other=
   [ "$1" = "a" ] && { exe=ADML-launcher ; other="--httpServer \`grep -v ^# .httpServer\`"; }
   [ "$1" = "f" ] && { exe=ADML-ftclient ; ln -s ADML-launcher $exe ; }
+  [ "$1" = "s" ] && { exe=ADML-stclient ; other="--disableLogs"; ln -s ADML-launcher $exe ; }
 
   echo "Creating 'run.sh' script ..."
 
@@ -151,6 +154,7 @@ then
   echo " (a)dvanced version:     includes burst management script and templates for different scenarios. Automatic configuration during start."
   echo " (b)asic version:        4 types of launcher (client, server, balancer, dummy), lightly configured and managed through SIGURS2 method."
   echo " (f)unction test client: special client with regexp scheduler script based on splitted traffic logs. Requires a server to perform the tests."
+  echo " (s)ystem test client:   special client for stress testing. Requires a server to perform the tests."
   echo
   echo "Input option [b]:"
   read option
@@ -178,6 +182,12 @@ case $option in
     DPATH_dflt=$HOME/ADML/ft-client
   ;;
 
+  s)
+    echo "ST deployment"
+    DEPLOYMENTS_DIR=deployments/st-client
+    DPATH_dflt=$HOME/ADML/st-client
+  ;;
+
   *)
     _exit "Invalid deployment type '$option' !!"
   ;;
index 3457bbf..b050efd 100755 (executable)
@@ -23,6 +23,7 @@ echo "Which one you want to deploy [1]:"
 echo
 echo "   1. Client and server"
 echo "   2. Ft-client and server"
+echo "   3. St-client and server"
 echo
 read type
 [ "$type" = "" ] && type=1
@@ -36,6 +37,10 @@ case $type in
     DEPLOY_DIR__dflt=$HOME/ADML-ftclientAndServer
   ;;
 
+  3)
+    DEPLOY_DIR__dflt=$HOME/ADML-stclientAndServer
+  ;;
+
   *)
     echo "Unknown option!"
     exit 1
@@ -67,6 +72,14 @@ case $type in
     echo s | ./configure.sh
     cd - >/dev/null
   ;;
+
+  3)
+    $DEPLOY_SCR s $DIR/st-client
+    $DEPLOY_SCR b $DIR/server
+    cd $DIR/server
+    echo s | ./configure.sh
+    cd - >/dev/null
+  ;;
 esac
 
 echo
index 4ec6ea0..8ea7511 100644 (file)
@@ -174,6 +174,11 @@ void Launcher::servicesFromXML(const anna::xml::Node* servicesNode, bool eventOp
       dictionary = (*it)->getAttribute("dictionary");
       id_value = id->getIntegerValue();
 
+      if (stackEngine.getDictionary(id_value)) { // Ignore (but don't fail) dictionary load with same stack id already registered
+        LOGWARNING(anna::Logger::warning(anna::functions::asString("Ignore dictionary load for stack id already registered: %llu", id_value), ANNA_FILE_LOCATION));
+        continue;
+      }
+
       try {
         d = stackEngine.createDictionary(id_value, dictionary->getValue());
         LOGDEBUG(anna::Logger::debug(anna::functions::asString("Created dictionary (%p) for stack id %llu", d, id_value), ANNA_FILE_LOCATION));
@@ -1310,13 +1315,18 @@ std::string Launcher::help() const throw() {
   result += "\n";
   result += "\n                                 Provide 0 in order to stop the timer triggering.";
   result += "\n";
-  result += "\n                                 There timer manager resolution currently harcoded allows a maximum  of ";
+  result += "\n                                 The timer manager resolution currently harcoded allows a maximum  of ";
   result += anna::functions::asString(1000/a_admlMinResolution); result += " events";
   result += "\n                                 per second. To reach greater rates ADML will join synchronously the needed number of";
   result += "\n                                 new time-triggered test cases per a single event, writting a warning-level trace to";
   result += "\n                                 advice about the risk of burst sendings and recommend launching multiple instances";
   result += "\n                                 to achieve such load with a lower rate per instance.";
   result += "\n";
+  result += "\n   test|next[|<sync-amount>]     Forces the execution of the next test case(s) without waiting for test manager tick.";
+  result += "\n                                 Provide an integer value for 'sync-amount' to send a burst synchronous amount of the";
+  result += "\n                                 next programmed test cases (1 by default). This event works regardless the timer tick";
+  result += "\n                                 function, but it is normally used with the test manager tick stopped.";
+  result += "\n";
   result += "\n   test|ip-limit[|amount]        In-progress limit of test cases. No new test cases will be launched over this value";
   result += "\n                                 (test Manager tick work will be ignored). Zero-value is equivalent to stop the clock.";
   result += "\n                                 tick, -1 is used to specify 'no limit' which is the default. If missing amount, the";
@@ -1757,6 +1767,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
   } else if((opType == "test")) {
     // test|<id>|<command>[|parameters]   Add a new step to the test case ...
     // test|ttps|<amount>                 Starts/resume the provided number of time ticks per second (ttps). The ADML starts ...
+    // test|next[|<sync-amount>]          Forces the execution of the next test case(s) without waiting for test manager tick ...
     // test|ip-limit[|amount]             In-progress limit of test cases. No new test cases will be launched over this value ...
     // test|repeats|<amount>              Restarts the whole programmed test list when finished the amount number of times ...
     // test|report[|[yes]|no]             Every time a test case is finished a report file in xml format will be created under ...
@@ -1783,6 +1794,22 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
         opt_response_content += "unable to configure the test rate provided";
       }
     }
+    else if (param1 == "next") {
+      if (numParams > 2)
+        throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+
+      int sync_amount = ((param2 != "") ? atoi(param2.c_str()) : 1);
+
+      if (sync_amount < 1)
+        throw anna::RuntimeException("The parameter 'sync-amount' must be a positive integer value", ANNA_FILE_LOCATION);
+
+      bool success = testManager.execTestCases(sync_amount);
+
+      opt_response_content = (success ? "" : "not completely " /* completed cycle and no repeats, rare case */);
+      opt_response_content += "processed ";
+      opt_response_content += anna::functions::asString(sync_amount);
+      opt_response_content += ((sync_amount > 1) ? " test cases synchronously" : " test case");
+    }
     else if(param1 == "ip-limit") {
       if (numParams > 2)
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
diff --git a/example/diameter/launcher/deployments/st-client/README b/example/diameter/launcher/deployments/st-client/README
new file mode 100644 (file)
index 0000000..6c8c711
--- /dev/null
@@ -0,0 +1,20 @@
+ABOUT CONTENT
+-------------
+Template for xml messages (message.dtd), dictionaries (dictionary.dtd) and services (services.dtd)
+are informative, not actually required by process. They are located at './DTDs'. Stacks are available
+at './stacks'. There are also some stuff (hex/xml examples, etc.) which could be useful.
+
+Execute './configure.sh' and follow the intructions to clone the ADML instance into the needed amount
+for system testing.
+
+STARTING THE PROCESS
+--------------------
+After configuring the ADML execution context, a new script has been created: 'run.sh'.
+This script will run all the cloned ADML instances within ADMLS directory.
+
+OPERATION
+---------
+Management interface for lite version is based on SIGUSR2 signal caugh. Use './operation.sh'
+script to send any operation to the processes. Ask for help with that script to see all the
+operations supported.
+
diff --git a/example/diameter/launcher/deployments/st-client/configure.sh b/example/diameter/launcher/deployments/st-client/configure.sh
new file mode 100755 (executable)
index 0000000..383c21a
--- /dev/null
@@ -0,0 +1,157 @@
+#!/bin/bash
+
+#############
+# VARIABLES #
+#############
+MAXIMUM_ADML_ASYNC_RATE=50
+MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE=10
+ADML_INSTANCES__ST_CONF_FILE=.st_conf_adml_instances
+ADML_CONNECTIONS__ST_CONF_FILE=.st_conf_adml_connections
+CYCLE_REPEATS__ST_CONF_FILE=.st_conf_cycle_repeats
+N_TESTCASES__ST_CONF_FILE=.st_conf_n_testcases
+
+#############
+# FUNCTIONS #
+#############
+_exit () {
+  echo
+  echo $1
+  echo
+  exit 1
+}
+
+# ceil of division $1/$2
+ceil() {
+  echo "$1 $2" | awk '{print int( ($1/$2) + 1 )}'
+}
+
+# Calculates the number of ADML instances and their client connections
+calculate_deployment_layout() {
+  echo "Input the maximum client connections accepted by the server to be tested [5000]:"
+  read max_server_accepted_connections
+  [ "$max_server_accepted_connections" = "" ] && max_server_accepted_connections=5000
+
+  echo "Input the maximum test case rate per second:"
+  read desired_rate
+  while [ -z "$desired_rate" ]; do read desired_rate; done
+
+  max_connections=$((desired_rate/MAXIMUM_ADML_ASYNC_RATE))
+  if [ $max_connections -eq 0 ]
+  then
+    G_ADML_CONNECTIONS=1
+    G_ADML_INSTANCES=1
+    return
+  fi
+  max_adml_instances=$((max_server_accepted_connections/MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE))
+  if [ $max_connections -gt $max_server_accepted_connections ]
+  then
+    echo
+    echo "Maximum rate reached for $max_server_accepted_connections server connections:"
+    G_ADML_CONNECTIONS=$MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE
+    G_ADML_INSTANCES=$max_adml_instances
+    return
+  fi
+
+  echo
+  echo "==========================================================================================================="
+  echo "Orientative table"
+  echo "-----------------------------------------------------------------------------------------------------------"
+  echo -e "Connects per instance:\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10"
+  echo -n "Number of instances:  "
+  for conn in `seq 1 $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE`
+  do
+    instances=$(ceil $max_connections $conn)
+    echo -n -e "\t$instances"
+  done
+  echo
+  echo "==========================================================================================================="
+  echo
+  echo "Input selection (connections per instance 1..$MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE) [1]:"
+  read G_ADML_CONNECTIONS
+  [ -z "$G_ADML_CONNECTIONS" ] && G_ADML_CONNECTIONS=1
+  [ $G_ADML_CONNECTIONS -lt 1 ] && G_ADML_CONNECTIONS=1
+  [ $G_ADML_CONNECTIONS -gt $MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE ] && G_ADML_CONNECTIONS=$MAXIMUM_SUGGESTED_CLIENT_CONNECTION_PER_ADML_INSTANCE
+  
+  G_ADML_INSTANCES=$((max_connections/G_ADML_CONNECTIONS))
+}
+
+#############
+# EXECUTION #
+#############
+
+cd `dirname $0`
+
+echo
+echo "====================================="
+echo "ADML SYSTEM TEST CONFIGURATION WIZARD"
+echo "====================================="
+echo
+
+calculate_deployment_layout
+
+# Dump persintently:
+echo $G_ADML_INSTANCES > $ADML_INSTANCES__ST_CONF_FILE
+echo $G_ADML_CONNECTIONS > $ADML_CONNECTIONS__ST_CONF_FILE
+
+echo
+echo "Suggested layout:"
+echo " - $G_ADML_INSTANCES ADML instances"
+echo " - $G_ADML_CONNECTIONS client connections per ADML instance"
+maximum_rate=$((G_ADML_INSTANCES*G_ADML_CONNECTIONS*MAXIMUM_ADML_ASYNC_RATE))
+echo " - Maximum rate: $maximum_rate test cases per second"
+echo
+echo "Usually, you will program a test case per subscriber. 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
+echo
+time_covered_1=$(ceil $N_TESTCASES $maximum_rate)
+time_covered=$(ceil $N_TESTCASES $((maximum_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=$(ceil $N_TESTCASES $G_ADML_INSTANCES)
+  echo "(aproximately, $testcase_per_adml_instance test cases will be programmed on each ADML instance)"
+fi
+
+echo
+if [ $time_covered -lt 300 ]
+then
+  echo "$time_covered seconds is under 5 minutes, 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."
+fi
+echo
+echo "How many total time do you want to cover (in minutes):"
+read minutes
+while [ -z "$minutes" ]; do read minutes; done
+seconds=$((minutes*60))
+repeats=$(ceil $seconds $time_covered)
+echo $repeats > $CYCLE_REPEATS__ST_CONF_FILE
+[ $repeats -gt 0 ] && echo "Configured $repeats cycle repeats ($repeats x $time_covered seconds = $seconds seconds (desired $minutes minutes)"
+echo
+echo "System test configuration completed."
+echo
+echo "Ready to clone/start the ADML instances: press ENTER to continue, CTRL+C to abort ..."
+read dummy
+[ ! -d realms ] && _exit "Missing realms configuration (expecting '$PWD/realms' directory). Try with 'realms.example' and see README inside it !"
+
+# Update services.xml regarding the number of client connections:
+cp realms/services.msk realms/services.xml
+sed -i 's/__CLIENT_CONNECTIONS__/'$G_ADML_CONNECTIONS'/g' realms/services.xml
+
+rm -rf ADMLS
+for instance in `seq 1 $G_ADML_INSTANCES`
+do
+  mkdir -p ADMLS/$instance
+  cd ADMLS/$instance
+  # Create resources:
+  ln -s ../../ADML-launcher
+  ln -s ../../operation.sh
+  ln -s ../../realms/services.xml
+  for cer in `ls ../../realms/cer*xml`; do ln -s $cer; done
+  cd - >/dev/null
+done
+
diff --git a/example/diameter/launcher/deployments/st-client/hex_examples b/example/diameter/launcher/deployments/st-client/hex_examples
new file mode 120000 (symlink)
index 0000000..0a74a2d
--- /dev/null
@@ -0,0 +1 @@
+../../resources/hex_examples/
\ No newline at end of file
diff --git a/example/diameter/launcher/deployments/st-client/operation.sh b/example/diameter/launcher/deployments/st-client/operation.sh
new file mode 120000 (symlink)
index 0000000..c9b45ae
--- /dev/null
@@ -0,0 +1 @@
+../../resources/scripts/operation_signal.sh
\ No newline at end of file
diff --git a/example/diameter/launcher/deployments/st-client/run.sh b/example/diameter/launcher/deployments/st-client/run.sh
new file mode 100755 (executable)
index 0000000..27aa362
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+cd `dirname $0`
+EXE_BN=`basename $PWD`
+STARTED=`pgrep $EXE_BN 2>/dev/null`
+[ $? -eq 0 ] && { echo "Already started!"; echo "$STARTED" ; exit 1 ; }
+0> launcher.trace
+rm -f counters/* test-reports/*
+# Execution line:
+nohup ./ADML-client --cntDir counters --tmDir test-reports --disableLogs --services $SERVICES > stdout &
+echo $! > .pid
+
diff --git a/example/diameter/launcher/deployments/st-client/run_all.sh b/example/diameter/launcher/deployments/st-client/run_all.sh
new file mode 100755 (executable)
index 0000000..8f2cd56
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+cd `dirname $0`
+for run in `ls ADMLS/*/run.sh`
+do
+  $run
+done
diff --git a/example/diameter/launcher/deployments/st-client/xml_examples b/example/diameter/launcher/deployments/st-client/xml_examples
new file mode 120000 (symlink)
index 0000000..c18402a
--- /dev/null
@@ -0,0 +1 @@
+../../resources/xml_examples
\ No newline at end of file
index ee6be63..2c03b4d 100644 (file)
@@ -279,14 +279,18 @@ bool TestManager::resetPool(bool hard) throw() {
 
 bool TestManager::tick() throw() {
   LOGDEBUG(anna::Logger::debug("New test clock tick !", ANNA_FILE_LOCATION));
+  return execTestCases(a_synchronousAmount);
+}
+
+bool TestManager::execTestCases(int sync_amount) throw() {
 
   if (!tests()) {
-    LOGWARNING(anna::Logger::warning("Testing pool is empty. You need programming. Stopping test clock", ANNA_FILE_LOCATION));
+    LOGWARNING(anna::Logger::warning("Testing pool is empty. You need programming", ANNA_FILE_LOCATION));
     return false;
   }
 
   // Synchronous sendings per tick:
-  int count = a_synchronousAmount;
+  int count = sync_amount;
   while (count > 0) {
     if (!nextTestCase()) return false; // stop the clock
     count--;
index 2f61501..76abcbb 100644 (file)
@@ -90,6 +90,7 @@ class TestManager : public anna::timex::TimeEventObserver, public anna::Singleto
   int a_synchronousAmount;
   TestClock *a_clock;
   bool tick() throw();
+  bool execTestCases(int sync_amount) throw();
   bool nextTestCase() throw();
 
   // Test timers
@@ -162,6 +163,7 @@ class TestManager : public anna::timex::TimeEventObserver, public anna::Singleto
   friend class TestStepTimeout; // createTimer
   friend class TestStepDelay; // createTimer
   friend class TestClock; // tick
+  friend class Launcher; // tick
 };
 
 #endif