}
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
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
}
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 ..."
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
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' !!"
;;
echo
echo " 1. Client and server"
echo " 2. Ft-client and server"
+echo " 3. St-client and server"
echo
read type
[ "$type" = "" ] && type=1
DEPLOY_DIR__dflt=$HOME/ADML-ftclientAndServer
;;
+ 3)
+ DEPLOY_DIR__dflt=$HOME/ADML-stclientAndServer
+ ;;
+
*)
echo "Unknown option!"
exit 1
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
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));
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";
} 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 ...
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);
--- /dev/null
+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.
+
--- /dev/null
+#!/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
+
--- /dev/null
+../../resources/hex_examples/
\ No newline at end of file
--- /dev/null
+../../resources/scripts/operation_signal.sh
\ No newline at end of file
--- /dev/null
+#!/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
+
--- /dev/null
+#!/bin/bash
+cd `dirname $0`
+for run in `ls ADMLS/*/run.sh`
+do
+ $run
+done
--- /dev/null
+../../resources/xml_examples
\ No newline at end of file
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--;
int a_synchronousAmount;
TestClock *a_clock;
bool tick() throw();
+ bool execTestCases(int sync_amount) throw();
bool nextTestCase() throw();
// Test timers
friend class TestStepTimeout; // createTimer
friend class TestStepDelay; // createTimer
friend class TestClock; // tick
+ friend class Launcher; // tick
};
#endif