Load test your web applications part 1.5 – Apache ab

Let the world know ...Tweet about this on TwitterShare on Google+Share on FacebookEmail this to someoneShare on LinkedIn

Note: 1st published on SCN on 11.6.2012

With ab, for Web Dynpro applications

In my blog about performance load testing with ab SAP Mentor Anton Wenzelhuemer raised a question if and how you can use ab to test a specific action/event in WD applications. That’s a good question as these events besides input validation normally trigger a connection to the backend and change the context node and attributes. And that is the part where you can improve the performance of the application.

Now, is it possible to test a user action with ab? To remind you, ab is used to test a single resource. The intent is to see how fast your web server can serve a HTML page and test how different configuration parameters affect the performance. You cannot test the flow of an action (load page, press button, get result). To find out if ab can be used to test a WD application, you have to find out what happens when you trigger the event.

Sample WDJ application

I build an example WDJ application using the steps outlined here: it’s and Web Dynpro Java application containing a table that shows the data of the get flight BAPI. For testing forms that require an input you cannot use ab (meaning: setting the input and call the form action), but you can use ab to simulate actually what happens after the input is set and the send button is clicked: the POST action of the browser.

[For testing the form from command line: to insert the airline Id and press the button, use curl, as curl allows interacting with forms. But curl is not a load testing tool (you may look at curl-loader).]

To make things easy for me I implemented a button (named: Generic) that sets the input of the airline to LH, triggers an event that causes the controller to call the BAPI and return the table content. Clicking this button I can record the POST action with Firebug:

http://nwce1:50000/webdynpro/resources/tobias.com/test~wdj~arfc/FlightListApp?SAPEVENTQUEUE=Button_Press%EE%80%82Id%EE%80%84MHDJ.New1CompView.Button1%EE%80%83%EE%80%82ClientAction%EE%80%84submit%EE%80%83%EE%80%82urEventName%EE%80%84BUTTONCLICK%EE%80%83%EE%80%81Form_Request%EE%80%82Id%EE%80%84…form%EE%80%85Async%EE%80%84false%EE%80%85FocusInfo%EE%80%84%40%7B%22sFocussedId%22%3A%20%22MHDJ.New1CompView.Button1%22%7D%EE%80%85Hash%EE%80%84%EE%80%85DomChanged%EE%80%84false%EE%80%85IsDirty%EE%80%84false%EE%80%83%EE%80%82EnqueueCardinality%EE%80%84single%EE%80%83%EE%80%82%EE%80%83&sap-wd-appwndid=ab98f4f2ae8f11e18027000c292b255f&sap-wd-cltwndid=ab98f4f1ae8f11e194f4000c292b255f&sap-wd-norefresh=X&sap-wd-secure-id=ab98f4f3ae8f11e18e55000c292b255f7276476579

Replaying the POST in the browser gives me the content WDJ returns to the browser:

Response in the browser

Response in firebug

The returned content is an XML file containing the data for the table. As you can see, WDJ return the table content as HTML. [Note: Whoever at SAP was or is or will be responsible for this: why? And please stop doing this. This should be done via AJAX and JSON / XML, and definitely you should not transfer HTML. That makes me wonder if the HTML transferred back changes between browsers.]

Conclusion: That POST triggers the server side event and returns the right content. This POST is what ab should send to the server.

How to get ab to send the exact same POST? For this ab offers 2 parameters that have to be used together: -p and –T. The parameter –p defines a file that contains the data to post and –T the content type. Saving the POST data in a file named postwdj.txt and set –T to application/x-www-form-urlencoded; charset=UTF-8.

Using only these two parameters won’t work with WD applications as WD checks the header for the user agent. The browser has to send a user agent that is supported by WD. To set the user agent for ab to IE (I use IE to be on the safe side as support for other browsers heavily depends on your SPS):

-H “User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)”.

The next step is to authenticate the session if the application needs an authenticated user. How exactly you do authentication depends on your server configuration, you can enable basic authentication with ab or send the JSESSION (or MYSAPSSO2) cookie to the WD app: -C JSESSION=<value>

Setting the parameters:

ab -v 4 -n 1 -p postwdj.txt -T “application/x-www-form-urlencoded; charset=UTF-8”

-H “User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)”

-C JSESSIONID=abc123

http://nwce1:50000/webdynpro/resources/tobias.com/test~wdj~arfc/FlightListApp

[Reminder: all these parameters I retrieved from what firebug recorded.]

Returns:

Did it worked? No. Why? “Request referes to an unkown session”. Unkown session? Yes, even with JSESSIONID as the AS Java session identifier, WD is more complex. Take a look at the complete POST data:

sap-wd-appwndid=09c61082af0811e1a8d7000c292b255f&sap-wd-cltwndid=09c61081af0811e1adf6000c292b255f&sap-wd-norefresh=X&sap-wd-secure-id=09c61083af0811e19571000c292b255f6987261425&SAPEVENTQUEUE=Button_Press…

There are several WD specific sessions involved. And these expire too. Make sure that the POST data you get from firebug is valid when you execute ab. With updated POST data:

Now, is that the result expected? Sometimes ab outputs the first lines of the response, sometimes not. To really know what the server returned I use Wireshark. Wireshark allows you to trace the TCP packages and to view the transmitted HTML. The image below shows the result of a not working POST, as the web page of the WD app is returned:

HTTP 200, but the POST was not triggered correctly, so the WD application returns the default view:

A Wireshark trace of a successful ab POST:

And the result at the command line when ab prints the returned message:

Running the test with 1 thread 100 times:

  • Worked fine

10 threads:

  • Worked

Running the test with 30 thread 100 times:

  • Worked

The problem is that too many connections to the application were made, and the session was never terminated, thus causing more and more memory consumption until my server crashed. There is a SAP note explaining this behavior and that in the end of the test run you should terminate the session. With ab this won’t work.

While ab allows you to test web and portal applications quite easily, it is not flexible enough for testing WD applications. Instead of being able to just run the test, you have to get the POST data and run the test shortly after. What ab is missing is to submit forms dynamically (like curl) or to build the POST data based on what the server expects. But for that you need to consider the flow of the application, something ab is not aware of. For testing complex web applications there is a handy tool also available from Apache: jMeter.

Let the world know ...Tweet about this on TwitterShare on Google+Share on FacebookEmail this to someoneShare on LinkedIn

Load test your web applications part 1 – Apache ab

Let the world know ...Tweet about this on TwitterShare on Google+Share on FacebookEmail this to someoneShare on LinkedIn

Note: 1st published on SCN on 4.6.2012

With ab

Load testing an application is more than a task to prepare for the go-live: it has to cover all phases of the lifecycle. It allows tracing the behavior of the application over time, allowing identifying when performance degeneration happened. It’s part of a toolset to avoid “yesterday it worked fine …”.

From the many load testing tools the ones for testing the end user perspective are the ones most useful. For applications that have a web interface this means to test the load from the browser perspective. This way, not only a specific part of the application like the DB is tested: all components involved to generate the HTML output are tested: the web server, application server, network connection, backend applications, DB, and so on. There are several load testing tools available, some are endorsed by SAP and are made available by SAP partners. They have one thing in common (beside the price): they are not easy to use. Because of this they normally get added at the quality test phase, and that is already too late. I will focus here on tools that can be freely downloaded, installed, are simply to set up and use and have a community so finding solutions on the internet is not a big deal.

The Apache web server comes with a simple tool: ab (http://httpd.apache.org/docs/2.0/programs/ab.html). Basically, that tool does everything you need to test the performance of a web page. You can use ab to upload a file, set cookies to find out HTTP server limitations (like 413), emulate authentication, and so on. The intended use case of ab is to test the Apache web server and the impact of configuration parameters on its performance, but as it simulates quite well the load of several browsers and a flexible number of requests, it can be used to test every web page. You can try out parameter changes and see how they impact the performance, how your code handles several requests, find out the impact of the network, and many more.

To run a test that includes 1000 requests, distributed over 10 threads to a URL, the syntax is:

Output:

Ab gives already some important information like requests/sec, number of failed requests and transfer rate. It’s an easy to use tool but pretty low level. Running ab against a local installation of SAP Portal:

This example makes also clear that one important aspect of load testing is the network connection. Instead of making the requests over Wifi to the URL of the 1st example somewhere in the internet and thus slowing down the number of requests, here the requests are done locally and I get an impressive 575 requests per seconds. The key takeaway here is: do your load testing not only at one location, do it at several locations inside your network to rule out or find network related bottlenecks: start near your server for optimizing the performance of your application and then move slowly away. Of course, you should define for each of the locations a threshold.

To test your single application, you need

  1. A direct link
  2. User authentication (if implemented)

The direct link is easy to get. The user authentication with ab is tricky, but the –C parameter does the trick. This will not give real world results as ab will do the tests as the same user, but it gives an overview of the response time of the application. The application is reading some data from the request object and some KM properties.

I ran the test several time and what you cannot see here is that the number of request went up from 49 to 92 and then stayed there. That’s an easy application that only reads some request parameters. Where serving a simple html page came back with 575 hits/sec, the application running inside the portal is not – as expected – as fast.

Now I can add and remove some code to find out if the application runs faster or slower and this way find out where the performance bottleneck is.

Let the world know ...Tweet about this on TwitterShare on Google+Share on FacebookEmail this to someoneShare on LinkedIn