9 JTR Distributed Testing

One of the most notable features JTR 4 introduces is EDiT (Effortless Distributed Testing).


With JTR distributed testing it is possible spawning the execution of a JTR test-suite on a set of JTR passive-nodes. This feature allows you to have a set of machines all running their own JTR passive-node, that you can use to truly stress-test your target systems by simply controlling just one node: the JTR active-node. The most attractive aspect of JTR Distributed Testing is that it does not require any configuration at all: everything is transparently (both from the tester and the tests-developer points of view) handled by the JTR-runtime.


JTR Distributed Testing Architecture

Here we are going to understand the architecture that lies behind JTR distributed testing. Let’s provide some useful definitions:


JTR Active-Node

A JTR active-node is a node in which you have installed both the JTR runtime and all your runners and utility classes. Thus is the node from which you typically run your stress-test JTR-based application. A JTR active-node is can run three distinct JTR-services:

  1. ClassLoaderService: this service listens by default on the 21979 TCP port, and it can be bound to a different port by means of either the jtr.cl.port system property or the classLoaderPort JtrRun Ant task optional attribute

  2. OutcomeCollectorService: this service listens by default on the 21980 TCP port, and it can be bound to a different port by means of either the jtr.oc.port system property or the outcomeCollectorPort JtrRun Ant task optional attribute

  3. RegistryService: this service listens by default on the 1099 TCP port, and it can be bound to a different port by means of either the jtr.remote.test.port system property or the registryPort JtrRun Ant task optional attribute


JTR Passive-Node

A JTR passive-node is a node running the JTR runtime in passive-mode. A JTR system launched in passive mode is a demon process waiting for JTR test-execution request to come from other unknown JTR active-nodes. A JTR passive-node always runs two services:

  1. TestGatewayService: this service listens by default on the 21978 TCP port, and it can be bound to a different port by means of either the jtr.gw.port system property or the testGatewayPort JtrPassive Ant task optional attribute

  2. RegistryService: see former description, please (equivalent to active-node)


JTR Distributed Testing Dynamics

Before describing how to set-up a JTR distributed test session, let’s give a brief representation of what should happen at runtime. The figure below depicts one JTR active-node (the green one), and four JTR passive-nodes (the ones in dark-purple). The black arrows represent the first step that takes place at runtime when launching a JTR distributed-test session: the active node sends to the desired passive-nodes the test configuration representing the test suite that should be run (that’s to say the content of the jtr.xml file). The red circle represents the target-node, that is the target system we want to test.




After this first step has been accomplished, all the nodes start running the same test configuration.


Note: should not all of the configured passive-node be reachable during the first step, the overall test would be stopped. At the end of the session you will be able to see, from the JTRConsole, which of the configured JTR passive-node were not contacted.


Configuring JTR Distributed Testing




The figure above represents the description of the jtr.xml nodes element. This element lets you specify for your JTR test-description the set of JTR passive-nodes you want to involve in the test session. As you can see the nodes element hosts a number of node elements each describing a JTR passive-node. This is accomplished providing the host-name or IP-address of the passive-node, and the port number it is listening to.


Let’s see an example of how this jtr.xml configuration section should look like:


<?xml version = '1.0' encoding = 'UTF-8'?>


<!-- JTRunner is free software; you can redistribute it and/or modify

    it under the terms of the GNU General Public License as published by

    the Free Software Foundation; either version 2, or (at your option)

    any later version.

-->


<test xmlns="http://jtrunner.sourceforge.net"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://jtrunner.sourceforge.net file:./config/jtr.xsd"

    runs="10">


    <!-- JTR components factories -->

    <factories>

        <factory key="IAssignmentPolicyFactory"

                 fqn="jtr.assigner.impl.DefaultAssignmentPolicyFactory" />

        <factory key="IOutcomeFactory" fqn="jtr.test.impl.DefaultOutcomeFactory" />

        <factory key="IWsHelperFactory" fqn="jtr.ws.jaxws.JaxWsHelperFactory" />

        <factory key="ITestCompletionListener"

                 fqn="jtr.test.impl.DefaultTestCompletionListener" />

        <factory key="ITestResultDisplayer"

                 fqn="jtr.test.impl.DefaultTestResultDisplayer" />

        <factory key="ITestResultsExporter"

                 fqn="jtr.test.results.exporters.impl.ExcelExporter" />

        <factory key="ITestScriptingEngine" fqn="jtr.script.impl.BshScriptEngine" />

        <factory key="ITestStatFunctions"

                 fqn="jtr.lang.functions.impl.DefaultStatFunctionsFactory" />

    </factories>


    <nodes>

        <node host="passivenode-1.jtr.org" port="2000"/>

        <node host="passivenode-2.jtr.org" port="2000"/>

    </nodes>

    ...

</test>


JTR Distributed Testing JVM System Properties

In order to have a JTR node take part (either as active or passive), it must be launched at least with the two following properties set (or their equivalent Ant task attributes, see here):

  1. jtr.remote.test.host: this is the name or IP address of the host running the JTR node. This property applies to both active and passive nodes (Ant task host attribute)

  2. java.security.policy: the path to the java.policy file (you can use the one provided with the JTR distribution if you want). This property applies to both active and passive nodes (Ant task policy attribute)


If you need to change one of the default TCP ports JTR uses by default, please use the following optional properties (or their equivalent Ant task attributes as seen before and as detailed here):


  1. jtr.remote.test.port: this is the port that the JTR node will use to export its registry. This property applies to both active and passive nodes

  2. jtr.gw.port: please, see before

  3. jtr.cl.port: please, see before

  4. jtr.oc.port: please, see before


Launching a JTR passive-node

JTR is not just an API and a runtime you can use for developing and running your own tests, but it can also be directly launched in passive mode by means of the passiveNode Ant target available in the build.xml file located right under the jtr top-most directory of the downloaded archive.


Launching a JTR active-node

In order to launch a JTR active-node you simply have to follow the simple steps suggested in this section, remembering you still need to set the JTR distributed testing runtime-properties just seen before.


Important Tips

In order to see a JTR distributed testing session work fine, remember to follow theses steps:

  1. if you can, turn off every firewall running on the involved JTR nodes (both passive and active), or pay attention to the TCP ports your nodes are going to use and instruct your firewall to let packets flow through these ports

  2. remember to launch each JTR node (both active and passive) with the properties introduced before properly set


Example

Let’s suppose I’ve developed my new JTR-based test-suite on my laptop called laptop.jtr.org and I want to run the same distributed test session from another machine called workstation.jtr.org.


First of all I edit the jtr.xml file I have locally (on my laptop) adding the lines:


   <nodes>

        <node host="workstation.jtr.org" port="2000"/>

   </nodes>


The above snippet means that the same JTR test-description will be sent to the node workstation.jtr.org having the registry listening on port 2000 (we have changed the default value which is 1099).


Now I launch the JTR passive node with the following properties set:

  1. -Djtr.remote.test.host=workstation.jtr.org (or its IP address)

  2. -Djtr.remote.test.port=2000

simply typing from the command line


%> ant passiveNode


A JTR passive-node should have been properly launched if I can see the following message on the standard output:


Registry entry #0: JTR-TestGatewayService


Now I can launch the test on my JTR active-node, ensuring that the following properties have been set:

  1. -Djtr.remote.test.host=laptop.jtr.org (or its IP address)

  2. -Djtr.remote.test.port=2000

  3. -Djava.security.policy=./java.policy


for example typing something like (supposing we are using an Ant target like the one exposed in the next section):


%> ant test


This example completes our discussion about the distributed testing facilities offered by the JTR framework.


JTR EDiT FAQs

  1. 1.Does a JTR passive-node require a jtr.xml file?

No, the jtr.xml file is required only by the JTR active-node: JTR passive-nodes are dynamically instructed by JTR active-nodes on the test-suites that must be executed.


  1. 2.Do I need to manually install all the jars required by my JTR active-node into my JTR passive-nodes’ classpath?

No, you don’t need to manually deploy neither any third-party library you need to use during your tests nor your own JTR runners into JTR passive-nodes’ classpaths.

JTR-passive nodes are dynamically configured by JTR active-nodes for proper test execution.




Next step: launching a JTR test