From daeeaacceeccefcac46838f460b19409cc5c4cb4 Mon Sep 17 00:00:00 2001 From: Eduardo Ramos Testillano Date: Tue, 13 Oct 2015 02:36:49 +0200 Subject: [PATCH] New st-client deployment. Allow to load same stack id (accumulative services), ignoring all except first loaded. --- example/diameter/launcher/DEPLOY.sh | 12 +- example/diameter/launcher/DEPLOY_setups.sh | 13 ++ example/diameter/launcher/Launcher.cpp | 29 +++- .../launcher/deployments/st-client/README | 20 +++ .../deployments/st-client/configure.sh | 157 ++++++++++++++++++ .../deployments/st-client/hex_examples | 1 + .../deployments/st-client/operation.sh | 1 + .../launcher/deployments/st-client/run.sh | 11 ++ .../launcher/deployments/st-client/run_all.sh | 6 + .../deployments/st-client/xml_examples | 1 + .../diameter/launcher/testing/TestManager.cpp | 8 +- .../diameter/launcher/testing/TestManager.hpp | 2 + 12 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 example/diameter/launcher/deployments/st-client/README create mode 100755 example/diameter/launcher/deployments/st-client/configure.sh create mode 120000 example/diameter/launcher/deployments/st-client/hex_examples create mode 120000 example/diameter/launcher/deployments/st-client/operation.sh create mode 100755 example/diameter/launcher/deployments/st-client/run.sh create mode 100755 example/diameter/launcher/deployments/st-client/run_all.sh create mode 120000 example/diameter/launcher/deployments/st-client/xml_examples diff --git a/example/diameter/launcher/DEPLOY.sh b/example/diameter/launcher/DEPLOY.sh index 3e3cbd9..e44e928 100755 --- a/example/diameter/launcher/DEPLOY.sh +++ b/example/diameter/launcher/DEPLOY.sh @@ -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' !!" ;; diff --git a/example/diameter/launcher/DEPLOY_setups.sh b/example/diameter/launcher/DEPLOY_setups.sh index 3457bbf..b050efd 100755 --- a/example/diameter/launcher/DEPLOY_setups.sh +++ b/example/diameter/launcher/DEPLOY_setups.sh @@ -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 diff --git a/example/diameter/launcher/Launcher.cpp b/example/diameter/launcher/Launcher.cpp index 4ec6ea0..8ea7511 100644 --- a/example/diameter/launcher/Launcher.cpp +++ b/example/diameter/launcher/Launcher.cpp @@ -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[|] 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||[|parameters] Add a new step to the test case ... // test|ttps| Starts/resume the provided number of time ticks per second (ttps). The ADML starts ... + // test|next[|] 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| 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 index 0000000..6c8c711 --- /dev/null +++ b/example/diameter/launcher/deployments/st-client/README @@ -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 index 0000000..383c21a --- /dev/null +++ b/example/diameter/launcher/deployments/st-client/configure.sh @@ -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 index 0000000..0a74a2d --- /dev/null +++ b/example/diameter/launcher/deployments/st-client/hex_examples @@ -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 index 0000000..c9b45ae --- /dev/null +++ b/example/diameter/launcher/deployments/st-client/operation.sh @@ -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 index 0000000..27aa362 --- /dev/null +++ b/example/diameter/launcher/deployments/st-client/run.sh @@ -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 index 0000000..8f2cd56 --- /dev/null +++ b/example/diameter/launcher/deployments/st-client/run_all.sh @@ -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 index 0000000..c18402a --- /dev/null +++ b/example/diameter/launcher/deployments/st-client/xml_examples @@ -0,0 +1 @@ +../../resources/xml_examples \ No newline at end of file diff --git a/example/diameter/launcher/testing/TestManager.cpp b/example/diameter/launcher/testing/TestManager.cpp index ee6be63..2c03b4d 100644 --- a/example/diameter/launcher/testing/TestManager.cpp +++ b/example/diameter/launcher/testing/TestManager.cpp @@ -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--; diff --git a/example/diameter/launcher/testing/TestManager.hpp b/example/diameter/launcher/testing/TestManager.hpp index 2f61501..76abcbb 100644 --- a/example/diameter/launcher/testing/TestManager.hpp +++ b/example/diameter/launcher/testing/TestManager.hpp @@ -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 -- 2.20.1