Gatling/AppMon 7.0 integration

Gatling is an open-source load testing framework. Using the Automation Library for AppMon 7.0, it is fairly easy to drive integration from any Gatling scenario written in Scala.

AppMon uses the Java automation library in the context of a Gatling/Scala script. According to the Scala Web Site: "Scala runs on the JVM, so Java and Scala stacks can be freely mixed for totally seamless integration."

To do this, add the server-rest-sdk-0.0.2.jar automation library to your project’s classpath. It allows you to use the objects provided by the library.

// AppMon automation library

import com.dynatrace.sdk.server._, exceptions._, sessions._, sessions.models._, testautomation._, testautomation.models._, systemprofiles._, systemprofiles.models._
// --------- Context ------------------

val dt_server_host = "localhost" // Server Hostname
val dt_server_port = 8021        // Server Port
val dt_ssl = true                // use SSL ?
val dt_user = "admin"            // User ID
val dt_pwd = "admin"             // User password
val dt_profile = "easyTravel"    // System Profile

// get a client configuration object
  val dc = new DynatraceClient(new BasicServerConfiguration(dt_user, dt_pwd, dt_ssl, dt_server_host, dt_server_port, false, 0))

WEB API test run

When using Gatling to run Web API tests, this interface creates a new test run with metadata. When this method is called, the response contains a unique ID for your test metadata on the AppMon Server. This ID is often referred to as testRunId. The AppMon Server uses the ID to distinguish test executions. Specify it in the request headers (see below) when executing your tests.

// initialize the context for our Test Run
  val ctrr = new CreateTestRunRequest()
  ctrr.setSystemProfile(dt_profile)      // System Profile.
  ctrr.setCategory(TestCategory.WEB_API) // Category of the test. Valid value is one of UNIT, UI_DRIVEN, PERFORMANCE, WEB_API or EXTERNAL.
  ctrr.setVersionMajor("1")              // Major version.
  ctrr.setVersionMinor("0")              // Minor version.
  ctrr.setVersionRevision("0")           // Revision.
  ctrr.setVersionBuild("1")              // Build number.
  ctrr.setVersionMilestone("1")          // Milestone.
  ctrr.setMarker("1.0.0.1.1")            // Special version marker, used in the heat-field of the Test Results dashlet chart.
  ctrr.setPlatform("Linux")              // The platform the test runs on. If not defined here, the platform is detected by the library.

  // Register the Test run and get the ID
  val dt_testrunid = new TestAutomation(dc).createTestRun(ctrr).getId()

Use header tags to convey context information with your requests

By default, AppMon labels recorded web requests from their URIs. In order to give them meaningful names (such as step names in a test scenario), a specific header tag can be added to the web requests.

This tag can also include a reference to the testrunid to indicate the test run a particular web request is part of.

Assemble the tag

The following helper function builds a AppMon header tag with the expected format, from the provided context data.

See Web API tests for more information.

def dt_web_api_tag(TN:String, TR:String) : Map[String, String] =
  {
       /*  Web API test attributes for request header :

TN	Test Name (TN) should be provided using this field.
		Metrics for requests with the same name are aggregated.
		You can execute as many tests as desired within the same test run,
		but give them different names if they are not testing the same thing.

TR	TestRunId (TR), from a registered test run.
		See REST API POST testruns for more information.
		* */

      var value:String = "TN="+TN+";TR="+TR

      return Map("x-dynaTrace" -> value)
   }

Use the tag

When issuing HTTP requests, add the AppMon tag in the header by calling the aforementioned helper function with a name for the test and the testRunId:

	val chain_1 = exec(http("request")
                    .get("/REST/SomeFunction")
                    .headers(dt_web_api_tag("My Web API test", dt_testrunid))
                    )

Analyze results in AppMon

LOAD test run

When using Gatling to run Load Tests, you can :

Use hooks to start/stop session recording and switch configuration

Before actually starting the test, you can use the before hook to:

When the test is done, use the after hook to:

  • Stop session recording to close the session.
  • Switch back to default configuration to revert DTAM to its defaults settings regarding transaction capturing details.
// --------- Initialization ------------------

// get a SystemProfiles object from the client configuration to be able to interact with System Profiles to switch configurations
  val sp = new SystemProfiles(dc)

  // initialize the context for recording a session with our test run
  val srr = new StartRecordingRequest(dt_profile)
  srr.setPresentableName("presentableName")   // User-readable presentable name for the session to be stored.
  srr.setDescription("description")           // Description for the session to be stored
  srr.setRecordingOption(RecordingOption.ALL) //   ALL : All PurePaths including time series,
                                              //   VIOLATIONS : Only PurePaths marked as violated, including time series.
                                              //   TIME_SERIES : Time series only.
  srr.setSessionLocked(false)                 // true to lock the session that is recorded, otherwise false
  srr.setTimestampAllowed(true)               // true to append timestamp information to the recorded session name, otherwise false

// get a Sessions object from the client configuration for the given parameters
  val s = new Sessions(dc)
before {   
  // Optional: switch to a specific configuration  
  // to allow for specific details level in captured data  
  // Note: make sure you created such configuration in AppMon before using it.  
  sp.activateProfileConfiguration(dt_profile, "myCustomConfigurationName")

  // start session recording for this test with given parameters
  s.startRecording(srr)}
after {
    // stop AppMon session recording for this test  
      s.stopRecording(dt_profile)

   
    // switch back to default AppMon configuration  
    sp.activateProfileConfiguration(dt_profile, "Default")  
  }

Use header tags to convey context information with your requests

By default, AppMon labels recorded web requests from their URIs. In order to give them meaningful names (such as step names in a test scenario), a specific header tag can be added to the web requests.

This tag can also include context information about the load test, such as script name, platform, and virtual user.

Assemble the tag

The following helper function builds a AppMon header tag with the expected format, from the provided context data.

See Integration with Web Load Testing and Monitoring Tools for more information.

def dt_load_tag(
              NA:String
            , PC:String=""
            , VU:String=""
            , ID:String=""
            , GR:String=""
            , AN:String=""
            , SN:String=""
            , TE:String=""
            )
  : Map[String, String] =
  {

       /*  Load test attributes for request header :

NA     The timer NAme of the request.
               This can be the timer or transaction name used in the load test script to identify the response time measure,
               or the document/page title, or any other human-readable URL encoded identifier for that document.
             NA=<timername>     
             Required
PC     The Page Context contains information about what document in the currently processed page is loaded.
              The following syntax is recommended, though not required:
              - If it is a named frame, then the value starts with the frame name.
              - The document number, unique for the page, is appended after a period.
              If embedded documents are cached, this number need not be progressive.
               PC=<FrameName>.<DocId>          
             optional
VU     The unique number of the Virtual User that sends the request.
             VU=<Id>     
             optional
ID     The unique request ID (serial number).
               This string should be unique for one web request or a set of web requests that together make up a step/transaction execution.
             ID=<Id>     
             optional
SI     The Source ID can be used to identify the product that triggered the request:
               For example WLT (Web Load Testing), SYM  (dynaTrace Synthetic Monitoring), BB (Backbone), or LM (Last Mile).   
           optional
GR     Geographic Region, useful only for the Synthetic Monitoring solution.
             This contains arbitrary text.    
             optional
AN     Agent Name: the logical name of the Agent from which the request originated.
             This information is used by Synthetic Monitoring.    
             optional
SN     Script Name.
               This groups a set of requests that make up a multi-step transaction, for example making an online purchase.
             optional
TE     TEst Name is the name of the entire load test.
             It uniquely identifies a test run.     
             optional
*/

      var value:String = "NA="+NA+";VU="+VU+";PC="+PC+";ID="+PC+";SI=Gatling;GR="+GR+";AN="+AN+";SN="+SN+";TE="+TE

      return Map("x-dynaTrace" -> value)
   }

Use the tag

When issuing HTTP requests, add the AppMon tag in the header by calling the aforementioned helper function. Then provide the name, testRunId and other optional contextual data:

   val chain_0 = exec(http("request")
                    .get("/")
                    .headers(dt_load_tag("step name"))
                    )

Analyze results in AppMon

Sample DSL scripts

The attached .zip file, includes two sample simulations, one for a Web API test context, the other for a Load test context.