Blog

Testing GWT applications for capacity and performance

14 Oct, 2012
Xebia Background Header Wave

In my current role as application performance specialist I see a lot of different frameworks that are used to develop applications faster, to make a more reactive frontend application or just a framework that is the latest and greatest from a development point of view.
One of these frameworks is Google Web Toolkit. Frameworks like this are a good thing for development… but for performance testing they might be a problem.
For performance testing the best practice is to use a proxy server recording all traffic between a browser and the application. In most cases this is just plain http with html or xml as a protocol. So it is easy to replay the recorded test and parameterize it with different values.
In most cases I use JMeter with a few good plugins like the plugins on Google code.
First you set your browser to a proxy which you define in JMeter. JMeter will record the requests you do.
image
After that you can fire the recorded requests to the application. Of course you first have to add proper test data so each session has different data.
image

While recording my first GWT applications I found out that GWT uses its own proprietary protocol wrapped in a sort of JSON. This gives at least 3 challenges if you use JMeter for record and playback.
In the following 4 paragraphs I will give an overview of GWT and tell you three of the tricks I used to be able to record and playback scripts for GWT applications. In my next blog I will also explain an alternative approach to test frameworks like GWT.

GWT overview

GWT is a framework in which you can code an application that will be precompiled to javascript and a services part (java). The javascript part will be used for a single page view in a browser.
This way you have a high responsive application because you don’t have to reload pages over and over again. GWT also has a lot of controls you can use without taking care about the communication between your control an your service. All the javascript and communication code will be generated by the precompile step.

3 Tricks to use JMeter for load testing GWT

GWT session context

GWT uses a session for each unique user.
Here you see a sample request coming from the GWT generated javascript frontend:

7|0|4|https://myserver:9080/myurl/|ABE2C0B156012B8657E5E26645105F43|
org.class.MyClass|FieldName|1|2|3|4|0|

One of the first things you might see is the sort of hash code (ABE2C0B156012B8657E5E26645105F43) this code can be found in one of the first html pages with the .nocache file extension which is fetched before. This is a sort of session context. You need it for each unique session.

Object id obfuscation/ compression

If you are requesting an object by id via GWT in the frontend, GWT will obfuscate/ compress it. To be able to get predefined records you have to deobfuscate/ decompress it. In the sample below I am requesting a record with id 318 (E$). What you see in the communication is E$.

//OK[7,1,[“java.lang.Integer/3438268394”],0,7,E$]

It took me quite some time to find out how to map the GWT obfuscated/ compressed id’s to the id’s which where used in the application.
Finally I was able to created a function to compress/ encrypt an id like GWT does it.

String chars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$_”;
long id = 318;
String out = “”;
while(id > 0){
    long charpos = id % 64;
id /= 64;
out = chars.charAt((int)charpos) + out;
}
System.out.println(“GWT id: ” + out);
GWT specific JSON

The next problem I found was that if you have a list of objects the field length is not equal for all objects in the list. In the later part of a request you see some id’s. In this list the field length for each object is also set together with a reference of the value used in some of the other records that came before.
Here you see an example JSON response from GWT.

//OK[35,8,34,27,5,’CvA’,
4,26,3,8,33,27,5,’CvB’,
4,0,3,8,7,6,5,’Cvh’,
4,0,3,30,2,2559,1,[“com.search.searchResult/3409195600″,”java.util.ArrayList/4159755760”,
“com.data.client.message.MyMessageSummary/3311733355″,”java.lang.Long/4227064769”,
type.type1“,”My Object type 1.”,”08-10-2012 10:06″,”55863485″,
“04-10-2012 11:27″,
type.type2“,”My Object type 54″,”04-10-2012 11:28″,
“05-10-2012 11:27”,

This response represents a list of 4 records. The first 4 lines give some information about the object id and the amount of data for that record which will differ from the records before.

RecordDateType
34508-10-2012 10:06type.type1
34604-10-2012 11:27type.type2
34704-10-2012 11:28type.type1
34805-10-2012 11:27type.type2

As you can see the type.type1 and type.type2 data will only be seen two times in the JSON data.
This while it is used 4 times. GWT uses some type of pointers between the records to point to data which is used before.

Different way of testing

This was the point I decided we needed a different way to test GWT applications.
In the GWT manuals there is a description to create special hooks in the backend code to test the individual backend services individual. This is something I can not use, different teams make the applications and making extra hooks will mean an application change and different code for production and testing. This is not the best way to test for scalability and performance in my opinion.
Function testers use Selenium a lot for functional testing. After a while I found a method to use Selenium in combination with JMeter to do performance testing. I will write a blog to describe this method later.

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts