Take the PIA out of load testing AMF services

Testing service APIs is a big pain. More so when you are using a format that isn’t widely supported by testing tools. Load testing AMF services…ugh.

Recently I was tasked with finding a way to load test some AMF services built using PHP. In the past I had used jMeter for load testing. So, that is where I started. jMeter is a good tool, but not for AMF. A few extensions for jMeter have been built for AMF, but they are a PIA to setup.

I found a couple of tools that have made load testing AMF serivices a snap. Both of the tools are from SmartBear, and both are open source and free to use. Bonus!

  1. Tool one: soapUI
  2. Tool two: loadUI

The following are the basic steps to get a simple load test set up:

Setting up the project

  1. Download and install soapUI (you’ll need Java too).
  2. Start up soapUI.
    soapUI Startup
  3. Create a new soapUI project – File -> ‘New soapUI Project’
  4. Name your project and click ‘OK’.
    soapUI New Project
  5. Add a new TestSuite – right-click your new project -> ‘New TestSuite’
  6. Name your TestSuite and click ‘OK’
    soapUI New TestSuite
  7. Create a new TestCase – right-click the new TestSuite -> ‘New TestCase’
  8. Name your TestCase and click ‘OK’
    soapui New TestCase
  9. Expand the Test Case
  10. Right-click ‘Test Steps’, select ‘Add Step’ -> AMF Request.
    soapui New AMF Request
  11. Your project is set up and ready-to-roll. Save it.

Configuring the AMF Request

Now that we have a request set up we need to specify the arguments for the call. The is where I had troubles with jMeter – setting up the data required proxies and additional tools. There was no where to easily create & edit AMF object to pass along in the AMF request.

Enter soapUI. Lets say we have an API method called getMonkeys(). getMonkeys() requires an array of ids that specifies what monkeys we want in the list. The name of this parameter is ‘monkeyIds’.

  1. In soapUI, right-click the AMF Request object and select ‘Open Editor’. You should see a window similar to the following:
    AMF Request Editor
  2. In the text field for ‘Endpoint’ enter your service end point. For example: http://www.thekuroko.com/Monkey/amfphp/gateway.php
  3. Enter the name of your call in the text field for the AMF Call setting: For example Monkey.getMonkeys
  4. Just under the entry for Endpoint add property to the property list for the call by clicking the ‘Add Property’ button.
    New Property Button
  5. Enter ‘monkeyIds’ as the name of the property. If the value for this property were a simple value we could enter it into the value column. We need an array though.
  6. To set the value for the property we’ll use the script window just under the property list.
  7. In the script window, enter the following to create an Array that contains the id values 1,2 & 3 and assigns that Array to the monkeyIds parameter.
    parameters[“monkeyIds”] = [1,2,3];
  8. That is it. The call for getMonkeys() is set up.
  9. To test the call click the little green arrow in the top left of the AMF Request editor.
  10. If your paths and data are set up correctly, you should see an XML formatted response in the window to the right of the Script editor.
    soapUI AMF Request Result

Creating and Running a Load Test

So now we have a test for a service, but we wanted to get some load testing done. If you’re looking for quick and simple load testing, you don’t have to go much further than soapUI itself. To create a load test in soapUI:

  1. Right-click the ‘Load Tests’ node under ‘Test Steps’ -> ‘New Load Test’
  2. Name the new load test and click ‘OK’
  3. 2 steps. That’s it, the load test is set up. You can run the test “as-is”.

Now, this is a very simple load test and there are a ton of things you can add to the test to improve it to build more useful load tests within soapUI.

Running Load Test with loadUI

The other tool I mentioned, loadUI, is built to integrate with soapUI and make load testing “easier and more efficient”.

Once loadUI is installed can you execute the test case that you set up in soapUI in loadUI.

  1. Right-click the test case, then select ‘Run with loadUI’.
  2. You will be prompted to save the project, do so.
  3. Select ‘Fixed Rate for the ‘Default Generator’ selection – this will determine how “clients” are generated for the load test.
  4. Select ‘Statistics’ for the ‘Default Statistics’ selection – this will display a graph for the load test metrics.
    loadUI Test Settings
  5. Click ‘OK’.
  6. loadUI will launch.
    loadUI Sstartup
  7. Click the ‘Play/Stop’ button to start the load test.
    load Play/Stop Button

You can play around with the Generator settings to change the rate at which clients are created to see changes in the load test results while the load test is running.
loadUI Generator

loadUI Stats

To view a report of the results you can click the ‘Summary Report’ button in the top right of the loadUI interface.
loadUI Summary Report Button

This is just a simple load test and there are plenty of additional settings, assertions and analysis tools that can be added, adjusted and tweaked to improve the validity of the load tests.

Next Steps

Our next step is to integrate the tests into our Continuous Integration (CI) system. We use Jenkins and I saw this post about Automating loadUI and Jenkins (formerly Hudson). So, in theory it can be done. I’ll let you know what we get worked out on that end when we get there.

So far, I’m pretty excited about the two tools. They are very useful, and free to boot. Hey SmartBear – you really are smart, thank you – you rule.

Resources:

Mobile Flex: View Data

From the previous post you should know how to navigate from 1 view to the next using the ViewNavigator.  Now, you want some data in that view right? No problem, this is where the View object’s ‘data‘ property comes into play. Setting the data property is accomplished by passing the data object, in addition to the View’s class name, into the pushView() method on the navigator object.

Example:

[as3]navigator.pushView(MyNewView, dataObject);[/as3]

This effectively calls the setting for the data property of the new View (MyNewView) object that is created.

Managing View Data

You could work with the data property on the View object directly. For instance, if the data object passed into the View via the pushView() method was a simple user object that contained a name property, you could bind the name property to a label control.

Example:

[xml]<s:Label id="name_lbl" text="{data.name}" />[/xml]

Overriding the Data Property Setter

Usually though, you’d want to override the setter for the data property. Then you can type your object and work with it in a better manner.

Example:

[as3]protected var user:User;
override public function set data(value:Object):void
{
super.data = value;
user = value as User;
}[/as3]

[xml]<s:Label text="{user.name}" />[/xml]

So now we’ve got the data in the view. The next step is to manage the state of each view. With mobile apps you can’t count on the view staying around, so we’ll need to keep a tight control on the state of each view. That way we can bring the user right back where they expect to be when they come back to the app after a call for example. In the next post we’ll look into how to do this. Stay tuned.

This article has also been posted on the Realeyes website.

Mobile Flex: ViewNavigator Basics

Flex 4.5 provides some pretty slick updates and enhancements, the least of which is the of Mobile components and the ability to slam out some pretty nice mobile apps easily. The first thing I’d like to talk about is a new concept, the ViewNavigator. The ViewNavigator provides some pretty intense functionality such as view management.

What is the ViewNavigator?

The ViewNavigator keeps track of your views. It does this by keeping your views in a list.  To add a new view you ‘push’ the view into the list, to remove a view you can ‘pop’ a view out of the list. You can think of it as a stack – first in, last out – and the last view in is the visible view.

Pushing a View into ViewNavigator's 'stack'
Popping a view out of the ViewNavigator's 'stack'

Using the ViewNavigator

Using the view navigator is a pretty straight forward process of capturing a user interaction, such as a button click, then pushing the new View into the ViewNavigator’s stack.

For example, let’s pretend that you have a new Flex mobile project. The default view of that project contains a button, that when clicked should display another view named MyNewView.  MyNewView also contains a button, that when clicked returns you to the the home view.

Home View Component

In the Home View component all you really need to worry about the the click handler on the button:

[xml]<s:Button id="next_btn"
label="NEXT"
width="100%"
click="navigtor.pushView(MyNewView)" />[/xml]

The click handler calls the pushView() method on ‘navigator‘, a property available from the View class, passing it the class name of the View that you want to display. We’ll cover getting data into that view and transitions in other posts.  The creation of the new View & default transition are all handled by the  framework.

MyNewView Component

The MyNewView View component is basically the same thing:

[xml]<s:Button id="back_btn"
label="BACK"
width="100%"
click="navigtor.popView()" />[/xml]

You call popView() on the ‘navigator‘ property which removes the view from the stack displaying the Home view again.

Here is a quick screen cast of an application using similar code:
[kml_flashembed publishmethod=”static” fversion=”9.0.0″ movie=”http://thekuroko.com/wp-content/uploads/2011/03/ViewNavigatorSample.swf” width=”485″ height=”785″ targetclass=”flashmovie”]Get Adobe Flash player

[/kml_flashembed]

This article has also been posted on the Realeyes website.

Adobe Camp: 1 Day, 3 Camps: 5280 Reasons to Use the Flash Platform

Rocky Mountain Adobe CampIf you haven’t heard already, the first Rocky Mountain Adobe Camp is open for registration.

The first ever, one of a kind, Rocky Mountain Adobe Camp is right here in Denver on June 22, 2009. Digital professionals at all experience levels are invited to this one-day event to participate in in-depth sessions, and unique hands-on activities taught by some of the most influential speakers in the “Flash-o-sphere”.

Want more information?
Check out http://camp.rmaug.com for event date and location as well as speaker and session info.

Use twitter?
Follow @adobecamp’s updates for more information and news.

There are some interesting sessions that will be divided between 3 different “tracks”:

  • Flash Camp: Get ready to learn best practices, discover hidden features, and extend your abilities
  • Dynamic Media Camp: Developers and content owners alike will expand their current knowledge of the Flash Media Server family
  • eLearning Camp: Trainers, staff development managers, and Human Resource professionals will all gain valuable insight for eLearning development using tools such as Adobe Connect, Adobe Captivate, and Adobe Acrobat

So pick one and register for the First Rocky Mountian Adobe Camp!

Adobe AIR – Issues with Command Line Arguments

After working on a little automation tool for video encoding process we ran into an interesting issue with AIR applications and command line arguments. Here is the scenario:

  1. Encoding process ends.
  2. The encoding process passes a file path to the waiting AIR application via command line.
  3. If the AIR app is not running, it starts up.
  4. The AIR application then checks some data in a database updates some tracking info and possibly grabs the duration out of the file.
  5. The AIR app waits for some more input.

Here is the issue – when the application starts up via the command line call, subsequent calls fail to the AIR application. Our solution, the AIR app has to be running when the OS starts up – that way the initial command line call to start the application doesn’t hold the process.

The command line looks something like in Windows:
[vb]
C:/Program Files/ServerApplication/ServerApplication.exe “D:/my/storagedir/vidfile.f4v”
[/vb]

The command line looks something like on a Mac:
[vb]
/Applications/ServerApplication.app/Contents/MacOS/ServerApplication “D:/my/storagedir/vidfile.f4v”
[/vb]

There has to be some way to start the application via the command line without holding everything up right? What am I missing?

Here is what I’m missing:
The new command line looks something like in Windows (added the /b option):
[vb]
C:/Program Files/ServerApplication/ServerApplication.exe /b “D:/my/storagedir/vidfile.f4v”
[/vb]

The new command line looks something like on a Mac (added the ‘&’ at the end):
[vb]
/Applications/ServerApplication.app/Contents/MacOS/ServerApplication “D:/my/storagedir/vidfile.f4v” &
[/vb]

Now our little automation AIR tool doesn’t need to be running when the first call happens – it will actually start up – and it can stay open and successfully receive new command line arguments.

RMAUG Mini-Max Pixel Bender Presentation Files

Last night I gave an extremely fast run down on Pixel Bender to the Rocky Mountain Adobe User’s Group Mini-Max meeting last night. The presentation was the bare minimum you need to get started playing with Pixel.

I’ve got to give props to Lee Brimelow and his other site gotoandlearn.com for information used in the presentaion as well as the start file for the PixelBender class file in the Flex project.

Resource Links from the preso:

Downloads:
[dm]5[/dm]
[dm]6[/dm]

ANT + Growl notifications = Happy Coder

We have a bunch of projects around here that we build with ANT. One of the biggest gripes with ANT builds and Flex is the amount of time it can take – Flex compiles can be slow. So whilst I’m building a project, I usually end up getting distracted for 10 or 15 minutes by something else, and my newly compiled Flex project sits there waiting for me to return. When I do return I have inevitably forgotten what I was doing.

Enter Growl and ant-growlnotify (thanks Jamie) with the ANT -listener argument. Using it is pretty simple:

  1. Download the ant-growllistener-0.4.jar from google code
  2. Drop the jar into your ant’s lib directory
  3. Run your ANT script with the -library arguement set to com.google.code.ant.growlnotify.GrowlListener
    or add -listener
    com.google.code.ant.growlnotify to ANT_ARGS
  4. Now when you run your ANT script you should get nice Growl notifications.

You’ll need to make sure that you’ve installed growlnotify. growlnotify is in the Extras folder when you install Growl.

In the same notification vein, I also tracked down ImTask last night and got build norifications going with an XMPP server. The project seems a little dated (released in 2003), but still works with OpenFire and Jabber.org.

Identifying Multiple Screens with Adobe AIR

While working on a presentation about Native Windows & Adobe AIR I ran into the Screen class. The screen object provides information about the display screens available to an application allowing you to position applications/windows on different screens. I say screens and not monitors because of a little caveat that the livedocs have in them:

Note that there is not necessarily a one-to-one correspondance between screens and the physical monitors attached to a computer. For example, two monitors may display the same screen.

I thought I’d have a little fun to get my code fingers back after a week in Cabo San Lucas, and create a little AIR app that identifies each screen. The basics are:

  1. Identify the Screens – I knew I had 2 screens, so that was easy. The screens property is an array of Screen objects, so you can work with as many as the user has.
  2. Create something to identify the windows – I used transparent windows with a label to make things simple.
  3. Then position the new windows on the screens.

[as]

private var _screenOne:Screen;
private var _screenTwo:Screen;

private function _identScreens( p_event:MouseEvent ):void
{
// I know I have 2 screens so I’ll just grab those
_screenOne = Screen.screens[0];
_screenTwo = Screen.screens[1];

// Now lets identify the screens
var identOne:IdentWindow = new IdentWindow();
identOne.title = “Screen One”;
identOne.screenLabel = “1”;

// open the irst window and set its position on the first screen
identOne.open( true );
identOne.nativeWindow.x = ( _screenOne.bounds.width / 2 ) – ( identOne.width / 2 );
identOne.nativeWindow.y = ( _screenOne.bounds.height / 2 ) – ( identOne.height / 2 );

var identTwo:IdentWindow = new IdentWindow();
identTwo.title = “Screen Two”
identTwo.screenLabel = “2”;

// open the second window and set its position on the second screen
identTwo.open( true );
identTwo.nativeWindow.x = ( _screenTwo.bounds.right – ( _screenTwo.bounds.width / 2 ) ) – ( identTwo.width / 2 );
identTwo.nativeWindow.y = ( _screenTwo.bounds.bottom / 2 ) – ( identTwo.height / 2 );
}
[/as]

Very straight forward and simple, but a fun little exercise.

You can download and install the app (with source) using the badge below:

[airbadge] Identify Screen Sample, http://www.thekuroko.com/wp-content/plugins/downloads-manager/upload/IdentifyScreens.air, 1.0, badge image.jpg[/airbadge]

Or, download the zip’ed flex archive:
[dm]2[/dm]

Adobe Announces the Open Screen Project

Adobe has just announced the Open Screen Project.

The Skinny:

  • Restrictions on use of the SWF and FLV/F4V specifications will be removed
  • The device porting layer APIs for Adobe Flash Player will be published
  • The Adobe Flash® Cast™ protocol and the AMF protocol for robust data services will be published
  • Licensing fees will be removed – making next major releases of Adobe Flash Player and Adobe AIR for devices free

What does it really mean? Well it could be the promise of a universal application platform and the ability to write an application and deploy it everywhere. But, we know, with the likes of Apple and Google, who haven’t really taken to the flash platform, that probably isn’t the case. To me it means that Adobe is allowing the community as a whole to participate in the direction that the flash platform takes. To develop what what the community wants and thinks needs to be developed. This is a good thing – yay Adobe and yay Flash!

A few more links to read:

Ryan Stewart

Techcrunch

Wired

Developers: http://www.adobe.com/openscreenproject/developers/

Businesses: http://www.adobe.com/openscreenproject/businesses/