十五年测试老手,长期负责WEB\APP 项目测试,目前主要负责团队管理工作。

PERFORMANCE TESTING A FLEX BLAZEDS APPLICATION

上一篇 / 下一篇  2010-07-04 19:27:43 / 个人分类:JMeter

查看( 783 ) / 评论( 0 )
In the past few years I’ve seen an increasing interest in Flex applications at our customers. I have to say that I’m not surprised about this trend. Not only do Flex applications generally look great, but they also provide a big boost to user experience. As a developer and architect I am also quite pleased with the programming model and extensive widget library. Sure, Adobe can still improve on a lot of things, but so far I have always worked with pleasure on Flex applications.
"QI.d*Kkh051Testing软件测试网d{;y1i5~%p2v-\

-W lw1V3lE0Recently, at one of our customers, I bumped into another interesting side of Flex application development, namely performance testing (e.g. load-testing or stress-testing). Surprisingly enough, it is very hard to find an affordable solution for this. There are commercial tools out there that seem to do it quite well (Neoload) or reasonably well (WebLOAD) but I could not find a single viable open source alternative.51Testing软件测试网,GfN7A8}}]
Of course, it’s not exactly straightforward to write such a tool. The difficulty lies in the ability to generate and send AMF requests to the webserver, plus the interpretation of the AMF response you get back. The standard approach that most performance testing tools use is based on the assumption of HTTP requests and responses. While the AMF protocol technically “hitches a ride” on the HTTP protocol as well, the content is packed into a binary format (AMF) that can’t be interpreted the regular way HTTP requests and responses can. Hence the need for a dedicated tool thatcaninterpret AMF. However, not every customer has tens of thousands of dollars to spend. So, how do you cope with this?
4N.aSX'j"J/k0
Dc:yMI ~eT0AMF request generationAs it turns out, with a little ingenuity and the help of the BlazeDS codebase, you can create a solution that together with the excellentJMeterallows you to execute performance tests just as you are used to doing. Let’s start with the generation of AMF requests.
_"wdmsg0In the blazeds-core.jar there are representations of AMF messages and ways of de-/serializing them. This is actually used by BlazeDS itself to convert between AMF data to a Java Object model and vice versa. Because they kindly open sourced this code, I was able to reuse these classes to generate AMF requests and save those to a file. Here are a couple of code snippets I wrote to do this:51Testing软件测试网+zkC kWM)eN~e
public byte[] generate(AmfRequestParameters params) {    ActionMessage message = new ActionMessage();    message.addBody(createMessageBody(params));    ByteArrayOutputStream ut = new ByteArrayOutputStream();    MessageSerializer serializer = createMessageSerializer(out);    try {        serializer.writeMessage(message);    } catch (IOException e) {        throw new AmfRequestGenerationException(e);    }    return out.toByteArray();}First thing to note is the creation of an ActionMessage. This is actually a representation of an AMF request to which we will add a body in the second line of this method. Because we want to save this AMF request to a file we of course need to serialize it first. We do this by using the MessageSerializer class BlazeDS kindly provides. We let it serialize the message to a ByteArrayOutputStream so that we can potentially use it for other purposes than saving it to a File, but you could just as easily pass in a FileOutputStream. Finally, we return the byte array back to the client that called this method.51Testing软件测试网X8G2R"i)n7e+q2m

9J'J%~!Ov9v0Building the messageSo, let’s have a look at the createMessageBody(params) method:
.N,d%} f,dD @8Ed0protected MessageBody createMessageBody(AmfRequestParameters params) {    RemotingMessage message = new RemotingMessage();    message.setHeader(HEADER_DS_ENDPOINT, channel);    message.setHeader(HEADER_DS_ID, "1");    message.setMessageId("1");    message.setDestination(params.getDestination());    message.setOperation(params.getOperation());    message.setBody(params.getParameters());    return new MessageBody(null, null, new RemotingMessage[] {message});}What we do in this method is create an instance of a RemoteMessage. If you have ever inspected the contents of an AMF request, some of the properties might be familiar to you. Two headers are set: “DSEndpoint” and “DSId”. The endpoint is actually the channel in your services-config.xml file that you use to send all communication through (by default called something like ‘channel-amf’). I am not quite sure what the id header is supposed to do, but BlazeDS seems to require it. However the value does not seem to matter, hence the “1″. Neither does the message id for that matter.
Lq? XG!NE0The interesting parts are the destination, operation and parameters. These properties relate to the backend service you want to call, the method on that service and any arguments for that method. Finally, we return a MessageBody with this RemotingMessage that will be added to the ActionMessage in the generate() method which we saw earlier.
he[3_M0I introduced a small data holder class to hold the dynamic values of the message, called AmfRequestParameters:51Testing软件测试网 b7VI[;Z5S3X/O,y
public class AmfRequestParameters {    private String destination;    private String operation;    private Object[] parameters;    /**     * Creates a new {@code AmfRequestParameters} with the given fields.     *     * @param destination destination of the amf request     * @param operation operation to call on the destination     * @param parameters parameters of the operation     */    public AmfRequestParameters(String destination, String operation, Object[] parameters) {        this.destination = destination;        this.operation = operation;        this.parameters = parameters;    }    // getters and setters omitted}
1? `u [ q&A0Creating a message serializerThe last thing that needs to be done is serializing the message. This can be done with a MessageSerializer:
3wQh4O)U!@9~w t0protected MessageSerializer createMessageSerializer(OutputStream out) {    SerializationContext context = new SerializationContext();    context.setSerializerClass(AmfMessageSerializer.class);    SerializationContext.setSerializationContext(context);    MessageSerializer serializer = context.newMessageSerializer();    serializer.initialize(context, out, null);    return serializer;}In order to create a MessageSerializer, BlazeDS needs to know what type of serializer it needs to create. This is done via a SerializationContext on which you specify the AmfMessageSerializer class as the one it should instantiate. We then initialize the serializer with the context and the chosen outputstream, which is a ByteArrayOutputStream in our case. Optionally, you can add an AmfTrace to the initialization procedure, but I didn’t find that to be of any value to me.
p$f Ik {n l051Testing软件测试网Y(e,zlHe
Adding the AMF request to JMeterIn the end, we now have a byte array that contains a serialized AMF message. This can easily be stored to a file, after which it can be loaded into JMeter:
6RyK.n2^@'y]5Ty+C051Testing软件测试网,uB^*Sc
A couple of things are important to know when sending AMF requests with JMeter. First of all you need to make sure that you point JMeter to the URL that exposes your backend services to your Flex application. This is actually the endpoint URI under the channel element in your services-config.xml file. Second of all, make sure that you specify the HTTP request method as POST. Makes sense if we’re sending a file along with the request. Finally, point JMeter to the AMF request file to include in the request and specify its MIME type as “application/x-amf”.
3z:ls"X0Sk0And that’s it, you are all set for performance testing your Flex BlazeDS application!
dq!I:QSv3h0
}&nY$@ c&D0LimitationsThere are a couple of limitations to this approach:51Testing软件测试网-z f(QiZG4Z
  • You can’t inspect the response of a request in detail. As the response is also in AMF, JMeter can’t inspect it and make assertions on it
  • HTTP response codes are less meaningful. As basically every response from the server is a HTTP 200 response code, we can’t detect well if an error was thrown. For example, if we get a BadCredentialsException during login, we could have added an assertion to JMeter to check if the user actually got to the next screen, instead of being redirected to the login screen. Unfortunately, this does not work for Flex applications as the client application itself has to make a decision on what do with this type of error (instead of the server doing this for us)
  • This approach is limited to BlazeDS only. Due to the code we’re using from the BlazeDS codebase, we can’t for example use WebORB instead of BlazeDS. This is mostly due to the fact that there are subtle differences in the way certain data types are serialized and deserialized
  • Maybe the biggest drawback is that you have to create an AMF request file for each variation on a request. For example, if we want to login with 100 different users, we also need to create 100 login request files. Normally, you would be able to script. this in JMeter by adding variables to the request parameters.
    Currently I am looking into solving some of these limitations by making use of JMeter’s PreProcessors and PostProcessors. You can add custom Java code to JMeter that will execute on each request. You may therefore be able to generate the AMF request file on the fly.51Testing软件测试网VS)z k*@S
    51Testing软件测试网\cB&Fy?\
    ConclusionBy making use of the BlazeDS codebase and JMeter we are able to performance test a Flex BlazeDS application in a very cost-effective manner. JMeter has proven itself over the years to be an excellent tool for performance testing and it is a relief that, with a little ingenuity, we can use it for Flex applications too.51Testing软件测试网!q+pL~zi
    I think I’ve only scratched the surface on what can be accomplished with this combination. There is definetely a lot of potential to be explored here and I encourage everyone that has read this blog entry to go out there and try it yourself!51Testing软件测试网X&t)p YNN
    51Testing软件测试网)?;M9H^%WP!M7Y
    原文地址:http://blog.jteam.nl/2009/07/14/performance-testing-a-flex-blazeds-application/

    TAG:

    我来说两句

    (可选)

    Open Toolbar