August 5, 2009

Segue/Borland/MicroFocus SilkPerformer - Who Owns It?

SilkPerformer is a popular performance and load testing tool. It has a confusing history and has bounced around between companies quite a bit. Here is where it came from and the current state of who owns it.

The history AFAIK:

  • Segue buys a product from some (scandanavian?) company and names it Segue SilkPerformer.
  • Borland buys Segue and names it Borland SilkPerformer.
  • Micro Focus buys Borland and name it Micro Focus SilkPerformer.

Right now it is a little confusing because Borland still lists it as a product. The acquisition of Borland just went through a few days ago and now Micro Focus has it listed on its site also. I would expect the Borland site to eventually disappear.

To make it even more confusing; Micro Focus also bought Compuware which had its own performance/load testing application. So now Micro Focus is marketing QALoad as well as SilkPerformer, which overlap in most functionality.

It will be interesting to see where this goes and what happens to the product lines.

July 20, 2009

[Software] Tools Don't Make You a Mechanic

FYI: Learning LoadRunner does not mean that one has learned Performance Testing. LoadRunner is only a tool. Learning to use one of these:

...does not mean that one can disassemble and reassemble one of these:

[via JakeBrake]

July 10, 2009

Python - Zip Directories Recursively

This helped me out today with some backup scripts. Posting here so I can remember it. Idea and snippet adapted from: http://mail.python.org/pipermail/python-list/2007-February/596539.html

        
#!/usr/bin/env python

import os
import zipfile


def main():
    zipper('c:/test', 'c:/temp/test.zip')


def zipper(dir, zip_file):
    zip = zipfile.ZipFile(zip_file, 'w', compression=zipfile.ZIP_DEFLATED)
    root_len = len(os.path.abspath(dir))
    for root, dirs, files in os.walk(dir):
        archive_root = os.path.abspath(root)[root_len:]
        for f in files:
            fullpath = os.path.join(root, f)
            archive_name = os.path.join(archive_root, f)
            print f
            zip.write(fullpath, archive_name, zipfile.ZIP_DEFLATED)
    zip.close()
    return zip_file


if __name__ == '__main__':
    main()

* code updated. there was a bug in the original I posted (cmg - 07/13/09)

July 7, 2009

OpenSTA - SCL Code Boilerplate for HTTP Load Tests

(small code dump...)

OpenSTA (Open Systems Testing Architecture) is a popular open source web performance test tool. It uses a scripting language named SCL (Script Control Language), which seems to be heavily influenced by Fortran. It's a little bit dated and clumsy to program with, but suffices for writing scripts modeling complex web transactions.

Here is the basic structure I start with when modeling tests in OpenSTA:

!Browser:IE5


Environment
    Description "TEST SCRIPT"
    Mode HTTP
    WAIT UNIT MILLISECONDS


Definitions
    Include         "RESPONSE_CODES.INC"
    Include         "GLOBAL_VARIABLES.INC"
    CONSTANT        DEFAULT_HEADERS = "Host: www.goldb.org^J" &
                        "User-Agent: OpenSTAzilla/4.0"
    Integer         USE_PAGE_TIMERS
    Timer           T_Response
    CHARACTER*32768 logStuff, Local
    CHARACTER*512   USER_AGENT
    CHARACTER*256   MESSAGE


Code
    Entry[USER_AGENT,USE_PAGE_TIMERS]

    Start Timer T_Response

    PRIMARY GET URI "http://www.goldb.org/index.html HTTP/1.0" ON 1 &
        HEADER DEFAULT_HEADERS &
        ,WITH {"Accept: */*", "Accept-Language: en-us"}

    SYNCHRONIZE REQUESTS
    
    DISCONNECT FROM 1
    
    End Timer T_Response
  
Exit


ERR_LABEL:
    If (MESSAGE <> "") Then
        Report MESSAGE
    Endif

Exit

Nothing much to see here. If you use the OpenSTA recorder and record a simple HTTP GET request, it would generate a similar script for you.

Web Performance Tool Evaluation - lower end proprietary tools

I am in the middle of a Performance and Load tools selection process and wanted to get some feedback here.

I currently work in a shop that uses a mix of proprietary and open source tools for web performance & load testing. The bulk of our workload and analysis is currently done using SilkPerformer. As you all probably know, there is a class of tools that is *very* expensive (including SilkPerformer). Installations and maintenance can run into 7 figures ($$$) with yearly maintenance contracts upwards of 6 figures. Since SilkPerformer is in place and we are happy with it (besides price/maintenance), there is no point in moving to a similarly priced tool. Therefore I have ruled out the class of "high end" tools from my selection:

High-end tools
------------------------
Borland/Segue - SilkPerformer
HP/Mercury - LoadRunner
IBM/Rational - IBM Rational Performance Tester
Microfocus/Compuware - QALoad
Oracle/Empirix - Oracle Load Testing For Web Applications (e-Load)

The tool I select will be used across several web applications.. pretty straight forward HTML/AJAX/JavaScript Web UI. Here is a basic list of requirements:

Requirements
------------------------
Protocols:
- HTTP
- ODBC (SQL)

Features:
- distributed load generation
- reporting/analytics
- data driven testing
- 5000+ VU

I work on a very skilled team that is *very* proficient with programming, tools, and web technologies. Adapting to a new tool or programming language is not much of an issue.

I've searched the Open Source landscape pretty good. There are some fantastic tools (OpenSTA, JMeter, Pylot) to augment our testing, but no open source load generation tool completely meets our criteria.

Open Source tools
------------------------
OpenSTA
JMeter
Pylot

Now finally to the question/point....

I am looking at a class of tools that I will call "low-end performance tools". This includes all proprietary tools that are not listed above as "high-end tools". They tend be cheaper and more limited in functionality than the big guns, but are substantially cheaper and sometimes sufficient for complex web performance testing. This is where my interest lies. I have scoured the web and came up with a list of tools to evaluate.

Low-end tools
------------------------
Microsoft - VSTS
Radview - WebLOAD
SoftLogica - WAPT
Facilita - Forecast
Zoho - QEngine
Neotys - NeoLoad

Does anyone have any feedback or experience reports using any of the "low-end" tools listed above? Are there other tools I am overlooking that I should definitely look into?

any comments/suggestions are appreciated.

June 25, 2009

XML-RPC Clients In Python and Perl

I was just writing some XML-RPC code and wanted to post some simple examples of how to talk to an XML-RPC server with some simple client-side code. Here are examples in both Python and Perl.

The examples below show how to connect to an XML-RPC server and call the service's start() method.


a simple XML-RPC client in Python:

#!/usr/bin/env python

import xmlrpclib

host = 'http://localhost'
port = '8888'

server = xmlrpclib.Server('%s:%s' % (host, port))
response = server.start()
print response

a simple XML-RPC client in Perl (using the Frontier-RPC module):

#!/usr/bin/perl -w

use strict;
use Frontier::Client;

my $host = 'http://localhost';
my $port = '8888';

my $server = Frontier::Client->new('url' => "$host:$port");
my $response = $server->call('start');
print $response;

June 24, 2009

Google Calls for a Joint Effort to Speed Up the Internet

check out:
http://code.google.com/speed/

writeup here:
http://www.infoq.com/news/2009/06/Google-Speed-Up-the-Internet

"Google has launched a web site in an attempt to find ways and push the speed up process of the entire Internet. Google shares research data, web site speed optimization tutorials, recorded presentations on performance, links to lots of performance optimization tools, and a discussion group inviting everyone to share ideas on how to make the web faster."

Pylot is listed in the downloads section!

May 14, 2009

Mini Web Load Tester with Python and Pylot Core

Pylot is a performance tool for benchmarking web services/applications. I am working on exposing some of Pylot's internals so you can use it as a Python Module/API for generating concurrent HTTP load.

Below is a simple function that runs a mini [multi-threaded] load test against a single URL. It will return a dictionary containing runtime statistics. Results and timing information from each request is also logged to a file.

I use something like this to run performance unit tests rapidly (10-30 secs usually). I can bang on the URL for my application and quickly see how it performs and scales.

Here is a small Python script that uses Pylot as a module:

#!/usr/bin/env python

import pylot.core.engine as pylot_engine
import os
import sys
import time
        

pylot_engine.GENERATE_RESULTS = False

url = 'http://www.pylot.org'
num_agents = 5
duration = 10
runtime_stats = {}

original_stdout = sys.stdout
sys.stdout = open(os.devnull, 'w')

req = pylot_engine.Request(url)
lm = pylot_engine.LoadManager(num_agents, 0, 0, False, runtime_stats, [])
lm.add_req(req)

lm.start()
time.sleep(duration)
lm.stop()

sys.stdout = original_stdout

for agent_num, stats in runtime_stats.iteritems():
    print 'agent %i : %i reqs : avg %.3f secs' % \
        (agent_num + 1, stats.count, stats.avg_latency)

Output:

agent 1 : 46 reqs : avg 0.220 secs
agent 2 : 46 reqs : avg 0.218 secs
agent 3 : 46 reqs : avg 0.220 secs
agent 4 : 46 reqs : avg 0.221 secs
agent 5 : 46 reqs : avg 0.221 secs

Here is a slightly larger example with some more structure and features. This creates a small command line interface for running a mini load test.

Code:

#!/usr/bin/env python
# Corey Goldberg 2009

import pylot.core.engine as pylot_engine
import os
import sys
import time



def main():
    """
    Usage: >python pylot_mini_loadtest.py   
    """
    url = sys.argv[1]
    num_agents = int(sys.argv[2])
    duration = int(sys.argv[3])
    pylot_engine.GENERATE_RESULTS = False
    print '\nmini web load test \n---------------------------------'
    agent_stats = run_loadtest(url, num_agents, duration)
    throughput = sum([stat.count for stat in agent_stats.values()]) / float(duration)
    print '%.2f reqs/sec' % throughput
    for agent_num, stats in agent_stats.iteritems():
        print 'agent %i : %i reqs : avg %.3f secs' % \
            (agent_num + 1, stats.count, stats.avg_latency)
        


def run_loadtest(url, num_agents, duration):
    """
    Runs a load test and returns a dictionary of statistics from agents.
    """
    original_stdout = sys.stdout
    sys.stdout = open(os.devnull, 'w')
    
    runtime_stats = {}
    req = pylot_engine.Request(url)
    lm = pylot_engine.LoadManager(num_agents, 0, 0, False, runtime_stats, [])
    lm.add_req(req)
    
    lm.start()
    time.sleep(duration)
    lm.stop()
    
    sys.stdout = original_stdout
    
    return runtime_stats



if __name__ == '__main__':
    main()

Usage/Output:

C:\test>python pylot_mini_loadtest.py http://www.goldb.org 8 10

mini web load test
---------------------------------
19.20 reqs/sec
agent 1 : 24 reqs : avg 0.416 secs
agent 2 : 24 reqs : avg 0.418 secs
agent 3 : 24 reqs : avg 0.417 secs
agent 4 : 24 reqs : avg 0.418 secs
agent 5 : 24 reqs : avg 0.415 secs
agent 6 : 24 reqs : avg 0.419 secs
agent 7 : 24 reqs : avg 0.419 secs
agent 8 : 24 reqs : avg 0.419 secs

Of course, for more complex scenarios, you can use the full blown tool, available at: www.pylot.org/download.html

Questions? Hit me up.