Platform Development Studio - Developer’s Guide

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Using the Platform Test Environment

Testing is a key part of the development cycle. Network Gatekeeper provides an entire suite of testing tools to help you develop your extensions quickly and efficiently. This chapter introduces the Platform Test Environment (PTE). It consists of:

 


Overview

The Platform Test Environment is a key part of the Platform Development Studio.

Figure 10-1 The Platform Test Environment in Context

The Platform Test Environment in Context

The Platform Test Environment is a flexible, powerful tool, consisting of:

 


Installing and Running the Platform Test Environment

The Platform Test Environment is automatically installed when you install Network Gatekeeper. In standard installations, it is found in the <bea_home>/wlng_pds400/pte directory. Before you use the PTE, you must have:

To start the PTE in GUI mode, either type ‘ant run’ in a command window, or, if you are using Windows, double-click the run.cmd file in the PTE directory.

To start the PTE in console mode, type ‘ant console’ in a command window, or, if you are using Windows, double-click the console.cmd file in the PTE directory.

WARNING: Compatibility between the settings of this version of the PTE and any future versions is not guaranteed.

 


Navigating the Platform Test Environment GUI

The Java Swing-based GUI provides an easy to use access point to the many parts of the Platform Test Environment. Any changes made to the GUI are saved on exit. The GUI consists, broadly, of:

The Tools Panel

The Tools Panel is divided into two main sections:

The Tool Selector Panel

Use this panel to select the tool you wish to use:

Figure 10-3 The Tool Selector

The Tool Selector

Notice the Plus and Minus icons in the lower left. You can use these to create multiple versions of the tools. For example, you could create a server tool to correspond to each server instance you are running.

The Tool Action Panel

The Tool Action Panel displays the actions you can do in that particular tool.

The Server Tool
Figure 10-4 The Server Tool Action Panel with the Management Tab selected

The Server Tool Action Panel with the Management Tab selected

At the top of the panel, you specify the server with which you wish to interact and your administrative username and password.

Below that are the three main tabs:

The Database Tool
Figure 10-7 The Database Tool Action Panel with the Database Tab selected

The Database Tool Action Panel with the Database Tab selected

The Database tool lets you scan your database tables and manipulate them directly.

At the top of the panel you enter your database information, including your database username and password. Click the Connect button to connect to the database.

Below that are the two main tabs:

The Clients Tool
Figure 10-9 The Clients Tool Action Panel with the Short Messaging Client Tab selected

The Clients Tool Action Panel with the Short Messaging Client Tab selected

The Clients Tool Action Panel is the most complex of the UIs for the Platform Test Environment. The display is divided into three hierarchical groups:

Note: In some module configuration windows, you will see URLs written out with variable values.
Figure 10-10 Variables in URLs

Variables in URLs

Note: To set those variables, or to add others that are of use to you as you create and run tests, use the Manage Variables window. Click Tools -> Manage Variables. The default variables are shown outlined in red. To add a variable, click the plus button, outlined in blue. When you are finished editing, click the OK button.
Figure 10-11 The Manage Variables Window

The Manage Variables Window

Most client modules are stateless. When you click Send, the operation is executed and it completes. But some modules have state. They are started, and they run until they are stopped. The Short Messaging Notification Manager is such a module. As shown in Figure 10-12, it has a Start button, rather than a Send button.

Figure 10-12 A Stateful Module

A Stateful Module

When you set up notifications, that is, when you tell Network Gatekeeper that your client is interested in receiving asynchronous messages from the network, the client must provide a web service to which the notifications can be delivered. These client-based web services also show up in the PTE GUI as client modules. In Figure 10-13 below, the Notifications tab is selected. This module runs the web service to which both kinds of Short Messaging notifications can be returned: Delivery Receipts for Application-initiated messages and actual SMSes sent from the network to the client application. Notice the dependency on the Axis web server. It must be running for the web service to function.

Figure 10-13 The Client Notification Web Service

The Client Notification Web Service

Finally there is the question of session management. The default setting in Network Gatekeeper is to require applications to start a session and get a Session ID before they send traffic through the system. But this requirement is configurable in Network Gatekeeper, and so the PTE makes it possible to turn the session requirement on and off. By selecting the Other client group and the Session client, the Session Manager module, you can simply check the Sessionless option, shown below in Figure 10-14, and your clients will not be required to acquire or use a Session ID in order to run traffic.

Figure 10-14 Turning Sessions Off

Turning Sessions Off

The Tests Tool
Figure 10-15 Creating an Automated Test Sequence

Creating an Automated Test Sequence

Once you have created your test, click the plus icon at the top of the right column to add operations. The Select an Operation window opens, as in Figure 10-16 below.

Figure 10-16 The Select an Operation Window

The Select an Operation Window

This window shows all operations available in every module in the PTE: clients, simulators, and even duration tests. Select your first operation, and then continue adding until you have completed the desired test sequence.

Note: If you have multiple clients that might be able to perform a particular operation, a popup window will appear and allow you to choose the one you wish to use.

Each test sequence that you create is automatically persisted when the PTE is shut down, so that you only need to create a test once. To run a single test from the GUI, click the Run button on the top of the right column. To run the entire test sequence from the GUI, click the Run button on the top of the left column. The status of the tests is indicated by the color of the box next to the individual test item names: see Figure 10-17 below.

Figure 10-17 A Running Test

A Running Test

Green boxes indicate success; red boxes indicate failure; white boxes indicate an in-progress test; and black boxes indicate tests that have not yet run.

Create a new test by clicking the plus icon in the lower left corner. You are prompted for a name for the test. Configure the test in the upper portion of the right column. Select the type of traffic you wish to run, based on the client type, from the dropdown Traffic menu. Select what you wish to see graphed (Transactions Per Second, Exceptions, or Latency) in the Display dropdown menu outlined in red in the graphic above. Current statistics appear in the boxes at the bottom of the graph, outlined in green.

Make sure the appropriate simulator is running and start the test by clicking the Start button. The test runs in the background, so it is possible to run multiple tests in parallel.

Because duration test results are not saved across PTE sessions, you can choose to export results to be saved in a file and then import them back into the tool later, using the icons outlined in purple above.

The Simulator Panel

Figure 10-19 The Simulator Panel with MM7 Selected

The Simulator Panel with MM7 Selected

Like the Clients Tool, the Simulator panel is set up as a hierarchy. On the extreme left there are two buttons: Map and Simulator. Under the Simulator button is a set of tabs and sub-tabs. The tabs list the available simulator modules, including a simulator for the example communication service (Netex), and a separate tab and module for the Axis Server, which is required to run traffic over HTTP based protocols like MM7. See Figure 10-19 above. Under the row of tabs is the row of sub-tabs. The number of sub-tabs depends on the module selected. In all cases, there is a Control tab in which you can set up any necessary configurations. This area is also where the Start button is for each of the modules. The other tabs may allow you to see the actual content of a message or show you the statistics associated with traffic.

Figure 10-20 The Maps Panel

The Maps Panel

The Maps panel is a variant of a tool which was originally developed as part of the Application Developers SDK. It provides a map on which you can place phone terminals. This offers visual support for testing Parlay X 2.1 SMS, MMS, and Terminal Location traffic.

The SLA Editor

Managing large XML files can be difficult, particularly in a test environment where you may wish to change small details multiple times for various iterations of testing. To help you manage your SLAs, the PTE ships with an SLA editor, which manages the tags and validation so that you can focus on setting appropriate values. To access the SLA editor, first make sure you have selected the Server Tool and are connected to the server. Then click Tools -> Manage SLAs in the Menu Bar. The SLAs are fetched from the file system and the SLA Browser window opens. See Figure 10-21.

Figure 10-21 The SLA Browser

The SLA Browser

The SLA files that were fetched from the file system are listed in the main window. If you want to search for other files that may be on your system, click the Change... button and a file browser appears. To create an entirely new SLA, click the Plus button in the upper left corner, outlined in purple. You can also delete or rename SLAs using buttons in the same area.

To edit an SLA, select the one you are interested in and then click the pencil icon in the upper right corner, outlined in green. The SLA Editor window opens. See Figure 10-22.

Figure 10-22 The SLA Editor

The SLA Editor

Select the SLA type using the dropdown menu and specify the group identifier. If you wish to import a different SLA from the file system, or to save changes out, use the import and export icons on the bottom left. To upload the SLAs to, or download them from, the repository in the running instance of WLNG, use the icons outlined in blue on the bottom left.

There are two basic kinds of editing you can do - the main Service Contracts and any Overrides you have specified. Each has its own window. To edit a Service Contract, select the item you are interested in and click the pencil icon in the upper right corner. This opens the Contract Editor. See Figure 10-23.

Figure 10-23 The Contract Editor

The Contract Editor

The tags that can be edited appear as tabs at the top of the window. For more information on these tags, see the “Defining Service Provider Group and Application Group SLAs” chapter in Managing Accounts and SLAs a separate document in this set.

In the figure, a rate limit method restriction is being added to the sendData operation of the sample communication service. When you have made your edits, click the OK button and the window closes. Click OK once again (on Figure 10-22) the window closes. To preview the edits you have made in XML format, click the Eye icon at the top left of the SLA Browser (Figure 10-21). The Preview SLA window opens. See Figure 10-24.

Figure 10-24 The Preview SLA window

The Preview SLA window

The Method Restriction rate limit that was added in Figure 10-23 is shown outlined in red.

When you have completed your edits, simply click the Close button on the SLA Browser window.

 


Extending the Platform Test Environment

One of the most common uses for the Platform Testing Environment is to test extension communication services. Depending on how those extensions are implemented, you may need to create one or more new modules so that the PTE can interact successfully with your new communication service. You can implement new client modules, and even new clients containing multiple modules, if support for the application-facing interface that you want your communication service to use is not already available in the PTE. You can also implement new simulators, if the network node type that you want your communication service to interact with is not available. From the point of view of the PTE, a module is a module.

The only relevant distinction in the PTE is between modules for operations that simply execute and return and those for operations that start a process which runs until it is turned off. These are called, respectively, stateless and stateful modules. See Figure 10-12 for more information. Stateless modules must implement the CustomStatelessModule SPI and stateful modules must implement the CustomStatefulModule SPI. There are two additional, optional interfaces that can be implemented if you would like your module to display results (for example, a notification, a message from the network delivered to a client Web Service) or provide statistics in the GUI. The custom module SPI hierarchy is as follows:

Figure 10-25 The Custom SPI Hierarchy

The Custom SPI Hierarchy

Any module that is created must be packaged as a .jar file which must be located in the $PTE_HOME$/lib/modules/ directory. The root of the .jar file must include a descriptor file called module.xml. All custom modules automatically load when the PTE starts up.

Note: The modules created for use with the example communication service are located in <bea_home>/wlng_pds400/example/pte_module.

The Stateful SPI

Figure 10-26 shows the execution sequence for a stateful module:

Figure 10-26 The Execution Sequence for a Stateful Module

The Execution Sequence for a Stateful Module

The following listing is the SPI that must be implemented by stateful PTE modules.

Listing 10-1 CustomStatefulModule SPI
package com.bea.wlcp.wlng.et.spi;
/**
 * This interface must be implemented by a custom stateful module.
 * A stateful module has a start() and a stop() method and will be
 * represented in the UI by the Start/Stop button.
 * Note: a stateful module is not used in duration tests.
 * 
 * @author Copyright (c) 2008 by BEA Systems, Inc. All Rights Reserved.
 */
public interface CustomStatefullModule extends CustomModule {
/**
   * Starts the module.
   * @param context The custom module context
   * @return true if the module successfully started
   * @throws Exception Any exception preventing the module to start
   */
  public boolean start(CustomModuleContext context) throws Exception;
/**
   * Stops the module.
   * @param context The custom module context
   * @return true if the module successfully stopped
   * @throws Exception Any exception preventing the module to stop
   */
  public boolean stop(CustomModuleContext context) throws Exception;
}

The Stateless SPI

Figure 10-27 shows the execution sequence for a stateless module:

Figure 10-27 The Execution Sequence for a Stateless Module

The Execution Sequence for a Stateless Module

The following listing is the SPI that must be implemented by stateless PTE modules.

Listing 10-2 CustomStatelessModule SPI
package com.bea.wlcp.wlng.et.spi;
/**
 * This interface must be implemented by custom stateless module.
 * A stateless module has only an execute() method and will be
 * represented in the UI by the Send button.
 *
 * @author Copyright (c) 2008 by BEA Systems, Inc. All Rights Reserved.
 */
public interface CustomStatelessModule extends CustomModule {
/**
   * Asks the module to execute its job and return the result.
   *
   * @param context The custom module context
   * @return The result of the execution
   * @throws Exception Any exception that occurred during the execution
   */
  public Object execute(CustomModuleContext context) throws Exception;
}

The Custom Base SPI

This following is the base SPI for custom PTE modules. It should not be implemented directly. See the first comment.

Listing 10-3 The Custom Base SPI
package com.bea.wlcp.wlng.et.spi;
import com.bea.wlcp.wlng.et.api.CustomModuleContext;
/**
 * This interface defines the general API a custom module must implement.
 * Note: a custom module should NOT implement this interface directly but
 * one of the subinterface like CustomStatefulModule or CustomStatelessModule.
 *
 * @author Copyright (c) 2008 by BEA Systems, Inc. All Rights Reserved.
 */
public interface CustomModule {
  /**
   * Prepares the module with the given context. This method is invoked before
   * the module is executed: it can be used by the module to prepare
   * any internal states needed.
   * Note: when a duration test is performed on the Platform Test Environment,
   * prepare() is invoked only once at the beginning of the duration test.
   *
   * @param context The context of the custom module
   * @throws Exception Any exception that occurred during the module preparation
   */
  public void prepare(CustomModuleContext context) throws Exception;

The Custom Results Provider SPI

The following listing is the SPI that must be implemented by modules that wish to display some sort of results in the GUI.

Listing 10-4 The CustomResultsProvider SPI
package com.bea.wlcp.wlng.et.spi;
/**
 * A custom module can implement this interface if it wants to provide
 * a list of results in the UI. The PTE will automatically display a list
 * and handle the user interaction with it.
 *
 * @author Copyright (c) 2008 by BEA Systems, Inc. All Rights Reserved.
 */
public interface CustomResultsProvider {
/**
   * Clears the results.
   */
  public void clearResults();
/**
   * Returns an array of string that will be used to create
   * the name of each column of the results table.
   * @return An array of string to create the column headers
   */
  public String[] getResultsHeaders();
/**
   * Returns the results. Each result is composed of a map whose keys are
   * the same as the strings returned by getResultsHeaders().
   *
   * Note: It is up to the custom module to accumulate the results until
   * this method is invoked by the PTE.
   *
   * @return A list of results
   */
  public List<Map<String,String>> getResults();
}

The Custom Statistics Provider SPI

The following listing is the SPI that must be implemented by modules that wish to display statistics in the GUI.

Listing 10-5 The CustomStatisticsProvider SPI
package com.bea.wlcp.wlng.et.spi;
/**
 * A custom module can implement this interface if it wants to provide
 * some statistics in the UI. The PTE will automatically display a list
 * and handle the user interaction with it.
 * @author Copyright (c) 2008 by BEA Systems, Inc. All Rights Reserved.
 */
public interface CustomStatisticsProvider {
/**
   * Clears the statistics.
   */
  public void clearStatistics();
/**
   * Returns a map of statistics. Each key represent a particular statistic
   * and the value the value of the statistic.
   * @return The map of statistics
   */
  public Map<String,String> getStatistics();
}

The Context API

The following listing is the API that allows modules to acquire context.

Listing 10-6 The Context API
package com.bea.wlcp.wlng.et.api;
/**
 * This interface defines the context available to a custom module.
 *
 * @author Copyright (c) 2008 by BEA Systems, Inc. All Rights Reserved.
 */
public interface CustomModuleContext {
  /**
   * Returns the custom module data object as described in the module.xml
   * @return The custom module data object
   */
  public Object getData();
  /**
   * Returns the module of the specified type that this module depends on.
   * If there are many modules of the same type, the one chosen by the user
   * in the UI will be chosen.
   *
   * @param type The type of module
   * @return The module instance of the specified type
   */
  public CustomModule getDependency(String type);
  /**
   * Prepares the stub that the module will use to send a request. The PTE
   * will perform various changes to the stub depending on the UI settings,
   * like TCP Monitor or Override Endpoint.
   *
   * @param stub The stub to prepare
   * @param path The path to the parameter declared in module.xml that corresponds
   * to the stub url. Use null if it doesn't have any corresponding parameter.
   */
  public void prepareStub(Stub stub, String path);
  /**
   * Deploy (or undeploy) a service using a specific WSDD file.
   *
   * @param wsddFile The WSDD file that the axis server will execute
   * @throws Exception Any exception when executing the command
   */
  public void axisDeploy(String wsddFile) throws Exception;

The Module.xml Descriptor File

Every module is packaged in a .jar file with a descriptor file, module.xml, in its root. What is in the file depends on the nature of the module.

The following is the listing for a client module and the simulator module supplied with the example communication service:

Listing 10-7 The example module.xml
<module-factory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:noNamespaceSchemaLocation="http://www.bea.com/ns/wlng/40/et">
  <module name="example_application_initiated"
          type="client"
          class="com.bea.wlcp.wlng.et.example.SendDataModule"
          version="1.0"
          depends="session"
          uiPanel="client"
          uiTabs="Other,Example,Application-Initiated"
          >
    <data>
      <parameter name="Parameters"
                 class="com.bea.wlcp.wlng.et.example.SendDataData"
                 occurs="1">
        <parameter name="url"
                   class="java.lang.String"
                   occurs="1"
                   default="http://${at.host}:${at.port}/example/SendData"
                   monitor="true"/>
        <parameter name="data"
                   class="com.acompany.schema.example.data.send.local.SendData"
                   occurs="1">
          <parameter name="address"
                     class="java.net.URI"
                     occurs="1"
                     default="tel:1234"/>
          <parameter name="data"
                     class="java.lang.String"
                     occurs="1"
                     default="Hello, world"/>
        </parameter>
      </parameter>
    </data>
  </module>
  ...
  <module name="example_simulator"
          type="netex"
          class="com.bea.wlcp.wlng.et.example.SimulatorModule"
          version="1.0"
          uiPanel="simulator"
          uiTabs="Netex"
          >
    <data>
      <parameter name="Parameters"
                 class="com.bea.wlcp.wlng.et.example.SimulatorData"
                 occurs="1">
        <parameter name="port"
                   class="int"
                   occurs="1"
                   default="5001"/>
      </parameter>
    </data>
  </module>
</module-factory>

Below is the entire .xsd file for module.xml:

Listing 10-8 The module.xsd File
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
  <!-- Main element that describes one or more modules -->
  <xs:element name="module-factory">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="module" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!-- Defines a single module -->
  <xs:element name="module">
    <xs:complexType>
      <xs:sequence>
        <!-- Optional data of the module -->
        <xs:element ref="data" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <!-- Name of the module. It will be used also for the display -->
      <xs:attribute name="name" type="xs:string" use="required"/>
      <!-- Type of the module -->
      <xs:attribute name="type" type="xs:string" use="required"/>
      <!-- Class of the module (fully qualified) -->
      <xs:attribute name="class" type="xs:string" use="required"/>
      <!-- Version of the module -->
      <xs:attribute name="version" type="xs:string" use="required"/>
      <!-- Name of the module this module depends on.
       Predefined types are:
       - session : session module
       - axis : axis server module
       The PTE will make sure that before this module is started, the
       dependent module is running. -->
      <xs:attribute name="depends" type="xs:string" use="optional"/>
      <!-- UI panel where the module will be located (see ui-panels) -->
      <xs:attribute name="uiPanel" type="ui-panels" use="required"/>
      <!-- Location of the module in the panel tabs.
       The location is a list of UI tab names separated by comma. For example:
       "Other,Example,SendData"
       means that the module will be in a tab named "SendData"
       located in the tab "Example" located in tab "Other".
       The name of each tab is available in the UI.
       If a tab doesn't exist for a particular name, it will be created.-->
      <xs:attribute name="uiTabs" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <!-- Available UI panels -->
  <xs:simpleType name="ui-panels">
    <xs:restriction base="xs:string">
      <!-- Client panel -->
      <xs:enumeration value="client"/>
      <!-- Simulator panel -->
      <xs:enumeration value="simulator"/>
    </xs:restriction>
  </xs:simpleType>
  <!-- Data of the module -->
  <xs:element name="data">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!-- A single parameter -->
  <xs:element name="parameter">
    <xs:complexType>
      <xs:sequence>
        <!-- Can contain other parameters too -->
        <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
        <!-- Values restriction of the parameter (see restricted) -->
        <xs:element ref="restricted" minOccurs="0" maxOccurs="1"/>
        <!-- Internal use only -->
        <xs:element ref="instance" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <!-- Name of the parameter. It will be used to access the member
       of the parameter (MBean-style) -->
      <xs:attribute name="name" type="xs:string" use="required"/>
      <!-- Fully qualified name of the parameter -->
      <xs:attribute name="class" type="xs:string" use="required"/>
      <!-- Occurrences of the parameter (see parameter-occurs) -->
      <xs:attribute name="occurs" type="parameter-occurs" use="required"/>
      <!-- Default value of the parameter -->
      <xs:attribute name="default" type="xs:string" use="optional"/>
      <!-- Set to true if this parameter represent an URL to a stub. If true,
      it can be monitored by TCP monitor and have other properties -->
      <xs:attribute name="stub" type="xs:boolean" use="optional"/>
      <!-- Set to true if this parameter must be instanciated at creation time.
       This is only useful if the parameter is optional. -->
      <xs:attribute name="instanciate" type="xs:boolean" use="optional"/>
      <!-- Internal use only -->
      <xs:attribute name="preview" type="xs:boolean" use="optional"/>
      <!-- Internal use only -->
      <xs:attribute name="help" type="xs:boolean" use="optional"/>
      <!-- Internal use only -->
      <xs:attribute name="multiline" type="xs:integer" use="optional"/>
      <!-- Internal use only -->
      <xs:attribute name="timebase" type="parameter-timebase" use="optional"/>
      <!-- Optional display string to use instead of the name in the UI -->
      <xs:attribute name="display" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>
  <!-- The value the parameter is restricted to -->
  <xs:element name="restricted">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="value" minOccurs="1" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!-- A value has a content only -->
  <xs:element name="value">
    <xs:complexType>
      <xs:attribute name="content" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <!-- The occurrences of a parameter -->
  <xs:simpleType name="parameter-occurs">
    <xs:restriction base="xs:string">
      <!-- required (one and only one) -->
      <xs:enumeration value="1"/>
      <!-- optional -->
      <xs:enumeration value="?"/>
      <!-- one or more -->
      <xs:enumeration value="+"/>
      <!-- zero or more -->
      <xs:enumeration value="*"/>
      <!-- tree of parameter-->
      <xs:enumeration value="t"/>
    </xs:restriction>
  </xs:simpleType>
  <!-- Internal use only -->
  <xs:element name="instance">
    <xs:complexType>
      <xs:attribute name="v1" type="xs:string" use="required"/>
      <xs:attribute name="v2" type="xs:string" use="optional"/>
      <xs:attribute name="v3" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>
  <!-- Internal use only -->
  <xs:simpleType name="parameter-timebase">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ms"/>
      <xs:enumeration value="s"/>
      <xs:enumeration value="min"/>
      <xs:enumeration value="h"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

 


Using the Unit Test Framework (UTFW) with the Platform Test Environment

Unit tests are a core part of any testing cycle. Data are input into the system and the results are retrieved from the system and compared to expected values, all programmatically.

The Unit Test Framework allows you to create unit tests for the PTE easily. You implement your test class based on the abstract class WlngBaseTestCase and it manages the mechanics of using JMX and JMS to connect to the PTE for you. A test.properties file located in the same directory can be used to define commonly changed properties of the test.

Note: The WlngBaseTestCase class is located in <bea_home>/wlng_pds400/lib/wlng/pte_api.jar.

There are five basic steps to creating a unit test for the PTE:

  1. Create any necessary client or simulator modules for the PTE using the required SPI and XML configuration files
  2. Implement a test class based on the abstract class WlngBaseTestCase
  3. Provision Network Gatekeeper
  4. Start the Platform Test Environment and make sure the modules are correctly loaded
  5. Run the test class
  6. Note: The PTE should be running in Console (non-GUI) mode when you run your test. See Installing and Running the Platform Test Environment for more information on starting in Console mode.
    Figure 10-28 An SMS Unit Test Sequence


    An SMS Unit Test Sequence

The test sequence flow is as follows:

  1. The test client calls execute on the PTE’s Module Management MBean. The mechanics of the JMX call are taken care of by the base class.
  2. The MBean calls execute on the specified Module, in this case sendSMS. This request includes a request for delivery receipts.
  3. The sendSMS Module sends the request to Network Gatekeeper.
  4. Network Gatekeeper processes it and submits it to the network simulator module, in this case the SMPP module
  5. The simulator module returns a Delivery Receipt to Network Gatekeeper
  6. Network Gatekeeper sends the receipt on to the Notification module (which represents the client Web Service implementation)
  7. The test client retrieves the result of Network Gatekeeper’s submit from the SMPP simulator
  8. The test client retrieves the Delivery Receipt from the Notification module

To help you understand more clearly how all this works, there is an example unit test, which tests the example communication service, using the example clients and simulator. In standard installations, it is located in <bea_home>/wlng_pds400/example/unit_test/src/com/bea/wlcp/wlng/pds/example. See Listing 10-9 below.

Listing 10-9 A Unit Test for the Example Communication Service
package com.bea.wlcp.wlng.et.example;
import com.bea.wlcp.wlng.et.api.WlngBaseTestCase;
import java.util.List;
import java.util.Map;
/**
 * This class illustrates how to use the Unit Test Framework to
 * test the Communication Service Example. A few things are assumed before
 * running this class:
 * - the WLNG should be running and configured properly
 * - the CS example should be deployed and ready
 *
 * Note: this example uses also the wlngJmx to be able to access the WLNG
 * MBeans to ask the CS example plugin to connect to the Netex simulator.
 *
 */
public class TestSendData extends WlngBaseTestCase {
  private static final String SEND_DATA_MBEAN = "com.bea.wlcp.wlng.pte:group=traffic,name=SendData";
  private static final String NETWORK_TRIGGERED_MBEAN = "com.bea.wlcp.wlng.pte:group=traffic,name=NetworkTriggered";
  private static final String NOTIF_MANAGER_MBEAN = "com.bea.wlcp.wlng.pte:group=client,name=NotificationManager";
  private static final String NOTIF_MBEAN = "com.bea.wlcp.wlng.pte:group=client,name=Notification";
  private static final String NETEX_SIMULATOR_MBEAN = "com.bea.wlcp.wlng.pte:group=netex,name=Simulator";
  private static final String EXAMPLE_PLUGIN_MBEAN =
          "com.bea.wlcp.wlng:AppName=es_example_nt#4.0," +
                  "InstanceName=example_netex_plugin," +
                  "Type=com.acompany.plugin.example.netex.management.ExampleMBean";
  public TestSendData() throws Exception {
  }
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    wlngJmx.open("localhost", 8001, "weblogic", "weblogic");
    start(NETEX_SIMULATOR_MBEAN);
  }
  @Override
  protected void tearDown() throws Exception {
    wlngJmx.close();
    stop(NETEX_SIMULATOR_MBEAN);
    super.tearDown();
  }
  public void testSendData() throws Exception {
    assertTrue(isRunning(NETEX_SIMULATOR_MBEAN));
    resetStatistics(NETEX_SIMULATOR_MBEAN);
    wlngJmx.invokeOperation(EXAMPLE_PLUGIN_MBEAN, "connect");
    String data = "Hello at " + System.currentTimeMillis();
    String to = "tel:1234";
    putParameter(SEND_DATA_MBEAN, "url", "http://localhost:8001/example/SendData");
    putParameter(SEND_DATA_MBEAN, "data.data", data);
    putParameter(SEND_DATA_MBEAN, "data.address", to);
    start(SESSION_MBEAN);
    assertTrue(isRunning(SESSION_MBEAN));
    execute(SEND_DATA_MBEAN);
    Thread.sleep(2000);
    stop(SESSION_MBEAN);
    Map<String,String> stats = listAllStatistics(NETEX_SIMULATOR_MBEAN);
    System.out.println("Simulator statistics: "+stats);
    assertEquals("MessageReceived", "1", stats.get("MessageReceived"));
    assertEquals("MessageSent", "0", stats.get("MessageSent"));
  }
  public void testSendNetworkTriggeredData() throws Exception {
    String data = "Hello at " + System.currentTimeMillis();
    String from = "tel:1234";
    String to = "tel:7878";
    String correlator = "1234567890";
    assertTrue(isRunning(NETEX_SIMULATOR_MBEAN));
    resetStatistics(NETEX_SIMULATOR_MBEAN);
    wlngJmx.invokeOperation(EXAMPLE_PLUGIN_MBEAN, "connect");
    start(SESSION_MBEAN);
    assertTrue(isRunning(SESSION_MBEAN));
    putParameter(NOTIF_MANAGER_MBEAN, "url", "http://localhost:8001/example/NotificationManager");
    putParameter(NOTIF_MANAGER_MBEAN, "start.address", "tel:7878");
    putParameter(NOTIF_MANAGER_MBEAN, "start.correlator", correlator);
    putParameter(NOTIF_MANAGER_MBEAN, "start.endpoint", "http://localhost:13444/axis/services/Notification");
    putParameter(NOTIF_MANAGER_MBEAN, "stop.correlator", correlator);
    start(NOTIF_MANAGER_MBEAN);
    start(NOTIF_MBEAN);
    putParameter(NETWORK_TRIGGERED_MBEAN, "data", data);
    putParameter(NETWORK_TRIGGERED_MBEAN, "fromAddress", from);
    putParameter(NETWORK_TRIGGERED_MBEAN, "toAddress", to);
    clearResults(NOTIF_MBEAN);
    execute(NETWORK_TRIGGERED_MBEAN);
    Thread.sleep(2000);
    stop(NOTIF_MBEAN);
    stop(NOTIF_MANAGER_MBEAN);
    stop(SESSION_MBEAN);
    Map<String,String> stats = listAllStatistics(NETEX_SIMULATOR_MBEAN);
    System.out.println("Simulator statistics: "+stats);
    assertEquals("MessageReceived", "0", stats.get("MessageReceived"));
    assertEquals("MessageSent", "1", stats.get("MessageSent"));
    List<Map<String,String>> results = listAllResults(NOTIF_MBEAN);
    System.out.println("Notification results: "+results);
    assertEquals("Correlator", correlator, results.get(0).get("Correlator"));
    assertEquals("From Address", from, results.get(0).get("From Address"));
    assertEquals("Data", data, results.get(0).get("Data"));
  }
}

  Back to Top       Previous  Next