<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-5236867476487043111</id><updated>2009-11-26T19:12:53.424-05:00</updated><title type='text'>Corey Goldberg</title><subtitle type='html'>Blog - Technology, Software, Performance</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://coreygoldberg.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default?start-index=26&amp;max-results=25'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>98</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-6093550631238844372</id><published>2009-10-23T13:39:00.004-04:00</published><updated>2009-10-23T13:42:32.327-04:00</updated><title type='text'>Linus on Evolution</title><content type='html'>&lt;p&gt;
Here is a great rant from Linus Torvalds back in 2002 on biological and software evolution.&lt;br /&gt;
... from a thread on &lt;a href="http://www.tux.org/lkml/"&gt;LKML&lt;/a&gt;, summarized here:  &lt;a href="http://kerneltrap.org/node/11"&gt;http://kerneltrap.org/node/11&lt;/a&gt;
&lt;/p&gt;

&lt;hr /&gt;

&lt;blockquote&gt;&lt;em&gt;
&lt;p&gt;
You know what the most complex piece of engineering known to man in the
whole solar system is?
&lt;/p&gt;

&lt;p&gt;
Guess what - it's not Linux, it's not Solaris, and it's not your car.
&lt;/p&gt;

&lt;p&gt;
It's you. And me.
&lt;/p&gt;

&lt;p&gt;
And think about how you and me actually came about - not through any
complex design.
&lt;/p&gt;

&lt;p&gt;
Right. "sheer luck".
&lt;/p&gt;

&lt;p&gt;
Well, sheer luck, AND:
&lt;ul&gt;
&lt;li&gt;free availability and _crosspollination_ through sharing of "source
   code", although biologists call it DNA.&lt;/li&gt;
&lt;li&gt;a rather unforgiving user environment, that happily replaces bad
   versions of us with better working versions and thus culls the herd
   (biologists often call this "survival of the fittest")&lt;/li&gt;
&lt;li&gt;massive undirected parallel development ("trial and error")&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
I'm deadly serious: we humans have _never_ been able to replicate
something more complicated than what we ourselves are, yet natural
selection did it without even thinking.
&lt;/p&gt;

&lt;p&gt;
Don't underestimate the power of survival of the fittest.
&lt;/p&gt;

&lt;p&gt;
And don't EVER make the mistake that you can design something better than
what you get from ruthless massively parallel trial-and-error with a
feedback cycle. That's giving your intelligence _much_ too much credit.
&lt;/p&gt;

&lt;p&gt;
&lt;br /&gt;
&lt;br /&gt;
Linus
&lt;/p&gt;

&lt;/em&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-6093550631238844372?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=6093550631238844372' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/6093550631238844372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/6093550631238844372'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/10/linus-on-evolution.html' title='Linus on Evolution'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-2586325013368745694</id><published>2009-10-19T11:13:00.002-04:00</published><updated>2009-10-19T11:16:47.538-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - URL Timer - Web Monitor Utility</title><content type='html'>&lt;p&gt;
In a &lt;a href="http://coreygoldberg.blogspot.com/2009/09/python-http-request-profiler.html"&gt;previous post&lt;/a&gt;, I showed how to insert timers between steps in an http request to do some basic profiling.  Peter Bengtsson contacted me with some enhancements to the original code.  I took his enhancements and added some more of my own to create a neat little web monitoring utility.
&lt;/p&gt;

&lt;p&gt;
It uses Python's &lt;a href="http://docs.python.org/library/httplib.html"&gt;httplib&lt;/a&gt; to send a GET requests at regular intervals to a URL and adds some timing instrumentation between each step of the request/response.  Results are printed to the console.
&lt;/p&gt;

&lt;p&gt;
get it here:&lt;br&gt;
&lt;a href="http://code.google.com/p/corey-projects/source/browse/trunk/url_timer.py"&gt;http://code.google.com/p/corey-projects/source/browse/trunk/url_timer.py&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
to use, give it a site and interval:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;&gt; python url_timer.py www.goldb.org 5
&lt;/pre&gt;

&lt;p&gt;
... or an https/ssl url and an interval:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;&gt; python url_timer.py https://ssl.sonic.net/ 5
&lt;/pre&gt;

&lt;p&gt;
sample output:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;&gt;python url_timer.py www.goldb.org 5
request sent         response received    content transferred  size
------------         -----------------    -------------------  ----
0.0040 (0.0040)      0.2830 (0.2830)      0.2846 (0.2846)      9810 bytes (0.010 MB total)
0.0009 (0.0024)      0.2790 (0.2810)      0.2803 (0.2825)      9810 bytes (0.020 MB total)
0.0009 (0.0019)      0.2841 (0.2821)      0.2854 (0.2834)      9810 bytes (0.029 MB total)
0.0010 (0.0017)      0.2775 (0.2809)      0.2789 (0.2823)      9810 bytes (0.039 MB total)
0.0008 (0.0015)      0.2794 (0.2806)      0.2820 (0.2822)      9810 bytes (0.049 MB total)
0.0009 (0.0014)      0.2845 (0.2813)      0.2859 (0.2828)      9810 bytes (0.059 MB total)
0.0010 (0.0013)      0.2796 (0.2810)      0.2809 (0.2826)      9810 bytes (0.069 MB total)
0.0009 (0.0013)      0.2798 (0.2809)      0.2808 (0.2823)      9810 bytes (0.078 MB total)
0.0009 (0.0012)      0.2791 (0.2807)      0.2803 (0.2821)      9810 bytes (0.088 MB total)
...
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-2586325013368745694?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=2586325013368745694' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2586325013368745694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2586325013368745694'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/10/python-url-timer-web-monitor-utility.html' title='Python - URL Timer - Web Monitor Utility'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-5694058757971072920</id><published>2009-10-05T10:39:00.002-04:00</published><updated>2009-10-05T10:42:03.068-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Automated Web/HTTP Profiler with Selenium-RC and Python</title><content type='html'>&lt;p&gt;
A small new open source project I am working on:
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Selenium-profiler&lt;/b&gt; is a web/http profiler built with Selenium-RC and Python.  It profiles page load time and network traffic for a web page.  The profiler uses Selenium-RC to automate site navigation (via browser), proxy traffic, and sniff the proxy for network traffic stats as requests pass through during a page load.
&lt;/p&gt;

&lt;p&gt;It is useful to answer questions like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;how many http requests does that page make?&lt;/li&gt;
&lt;li&gt;how fast are the http responses coming back?&lt;/li&gt;
&lt;li&gt;which http status codes are returned?&lt;/li&gt;
&lt;li&gt;how many of each object type are requested?&lt;/li&gt;
&lt;li&gt;what is the total page load time?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Get it here:&lt;br /&gt;
&lt;a href="http://selenium-profiler.googlecode.com/"&gt;http://selenium-profiler.googlecode.com/&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Sample Output:&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
--------------------------------
results for http://www.google.com/

content size: 38.06 kb

http requests: 9
status 200: 6
status 204: 1
status 403: 2

profiler timing:
2.063 secs (page load)
2.047 secs (network: end last request)
0.111 secs (network: end first request)

file extensions: (count, size)
gif: 1, 8.558 kb
ico: 2, 2.488 kb
js: 2, 18.046 kb
png: 1, 5.401 kb
unknown: 3, 3.567 kb

http timing detail:
403, GET, /favicon.ico, 111 ms
200, GET, /newkey, 738 ms
200, GET, /, 332 ms
403, GET, /favicon.ico, 3 ms
200, GET, /logo.gif, 255 ms
200, GET, /d9n_Nh4I09g.js, 411 ms
200, GET, /2cca7b2e99206b9c.js, 65 ms
204, GET, /generate_204, 88 ms
200, GET, /nav_logo7.png, 49 ms
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-5694058757971072920?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=5694058757971072920' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/5694058757971072920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/5694058757971072920'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/10/automated-webhttp-profiler-with.html' title='Automated Web/HTTP Profiler with Selenium-RC and Python'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-6759545051352041945</id><published>2009-09-23T12:43:00.003-04:00</published><updated>2009-09-23T19:43:29.266-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Selenium RC with Python in 30 Seconds</title><content type='html'>&lt;p&gt;
&lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; is a suite of tools to automate web app testing across many platforms.  It has various pieces (Core, RC, IDE, etc), and I struggled trying to figure out how everything fits together and works.  At the end of the day, all I wanted to do was use Selenium from my Python code to drive a browser session.  
&lt;/p&gt;

&lt;p&gt;
Selenium ships with full tests and some good sample code, but the driver examples all contain test frameworks/runners (JUnit, unittest, etc).  All I wanted was a simple way to integrate with Python.  To do this, the piece I need is &lt;b&gt;Selenium RC&lt;/b&gt; (which includes Selenium Core).
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;So here is the beginners' 30-second guide to getting the Python client driver working with Selenium-RC:&lt;/b&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; (and add it to your path)&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://www.java.com/"&gt;Java&lt;/a&gt; (and add it to your path)&lt;/li&gt;
&lt;li&gt;Download &lt;a href="http://seleniumhq.org/download/"&gt;Selenium RC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unzip Selenium RC and search for 'selenium-server.jar' and 'selenium.py'&lt;/li&gt;
&lt;li&gt;Copy them to a directory and run 'java -jar selenium-server.jar' to start the server&lt;/li&gt;
&lt;li&gt;Start writing your Python driver code! (import selenium)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
So what's actually going on when you run a driver script?
&lt;/p&gt;

&lt;p&gt;
Selenium-server is the core program, which also contains an integrated web server.  You send HTTP requests to the server to instruct it how to drive your browser.  The 'selenium.py' module is just a wrapper around 'httplib' that provides a Python API for interacting with the Selenium-server.  You need to import the 'selenium.py' module from your script and then you are ready to go.
&lt;/p&gt;

&lt;p&gt;
now let's test it out and see if it works.  Try the following Python script.  It should open Firefox and navigate to www.google.com.
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;#!/usr/bin/env python

from selenium import selenium

sel = selenium('localhost', 4444, '*firefox', 'http://www.google.com/')
sel.start()
sel.open('/')
sel.wait_for_page_to_load(10000)
sel.stop()
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-6759545051352041945?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=6759545051352041945' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/6759545051352041945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/6759545051352041945'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/09/selenium-rc-with-python-in-30-seconds.html' title='Selenium RC with Python in 30 Seconds'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-2356653209748476828</id><published>2009-09-11T09:08:00.005-04:00</published><updated>2009-09-23T17:31:58.534-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - HTTP Request Profiler</title><content type='html'>&lt;p&gt;
Here is a script in Python that profiles an HTTP request to a web server.
&lt;/p&gt;

&lt;p&gt;
to use, give it a url:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;

&gt; python http_profiler.py www.goldb.org

&lt;/pre&gt;

&lt;p&gt;
output:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;

0.12454 request sent
0.24967 response received
0.49155 data transferred (9589 bytes)

&lt;/pre&gt;

&lt;p&gt;
It uses Python's httplib to send a GET request to the URL and adds some timing instrumentation between each step of the request/response.
&lt;/p&gt;

&lt;p&gt;
Python Code:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;

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


import httplib
import sys
import time



if len(sys.argv) != 2:
    print 'usage:\nhttp_profiler.py &lt;url&gt;\n(do not include http://)'
    sys.exit(1)

# get host and path names from url
location = sys.argv[1]
if '/' in location:
    parts = location.split('/')
    host = parts[0]
    path = '/' + '/'.join(parts[1:])
else:
    host = location
    path = '/'

# select most accurate timer based on platform
if sys.platform.startswith('win'):
    default_timer = time.clock
else:
    default_timer = time.time

# profiled http request
conn = httplib.HTTPConnection(host)
start = default_timer()  
conn.request('GET', path)
request_time = default_timer()
resp = conn.getresponse()
response_time = default_timer()
size = len(resp.read())
conn.close()     
transfer_time = default_timer()

# output
print '%.5f request sent' % (request_time - start)
print '%.5f response received' % (response_time - start)
print '%.5f content transferred (%i bytes)' % ((transfer_time - start), size)

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-2356653209748476828?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=2356653209748476828' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2356653209748476828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2356653209748476828'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/09/python-http-request-profiler.html' title='Python - HTTP Request Profiler'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-5974117785777852809</id><published>2009-09-10T11:37:00.002-04:00</published><updated>2009-09-10T11:39:42.869-04:00</updated><title type='text'>Web Page Profilers for Windows/Internet Explorer</title><content type='html'>&lt;p&gt;
A "Web Page Profiler" is a tool that is used to measure and analyze web page performance.  It is usually implemented as a browser plugin or add-on, and lets you see performance of web pages/objects as they are transferred/loaded/executed/rendered.
&lt;/p&gt;

&lt;p&gt;
For Firefox, choosing a profiler is a no-brainer.  Firebug is an excellent developer tool that includes profiling capabilities.
&lt;/p&gt;

&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
Unfortunately, Firebug does not work with Microsoft's Internet Explorer.  There is Firebug Lite, which "can" work with IE, but it is limited in functionality and requires you to install some server side code (which is not always feasible).
&lt;/p&gt;

&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://getfirebug.com/lite.html"&gt;Firebug Lite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
There are some web profilers specifically for IE, but none of them live up to the functionality or stability of Firebug.  Some to look at are:
&lt;/p&gt;

&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/apps/mediawiki/pagetest"&gt;AOL Pagetest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msfast.myspace.com/"&gt;MySpace Performance Tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
... also, Internet Explorer 8 has built-in "Developer Tools" (press F12) that include a basic performance profiler for JavaScript execution.
&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;
Does anyone know of any other profilers/performance tools that work with IE?  Thoughts?
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-5974117785777852809?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=5974117785777852809' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/5974117785777852809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/5974117785777852809'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/09/web-page-profilers-for-windowsinternet.html' title='Web Page Profilers for Windows/Internet Explorer'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-1478423287920989605</id><published>2009-08-05T09:35:00.002-04:00</published><updated>2009-08-05T09:37:31.024-04:00</updated><title type='text'>Segue/Borland/MicroFocus SilkPerformer - Who Owns It?</title><content type='html'>&lt;p&gt;
&lt;a href="http://www.microfocus.com/products/SilkPerformer/"&gt;SilkPerformer&lt;/a&gt; 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.
&lt;/p&gt;

&lt;p&gt;
The history AFAIK:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Segue buys a product from some (scandanavian?) company and names it Segue SilkPerformer.&lt;/li&gt;
&lt;li&gt;Borland buys Segue and names it Borland SilkPerformer.&lt;/li&gt;
&lt;li&gt;Micro Focus buys Borland and name it Micro Focus SilkPerformer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
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 &lt;a href="http://www.microfocus.com/products/QALoad/"&gt;QALoad&lt;/a&gt; as well as &lt;a href="http://www.microfocus.com/products/SilkPerformer/"&gt;SilkPerformer&lt;/a&gt;, which overlap in most functionality.
&lt;/p&gt;

&lt;p&gt;
It will be interesting to see where this goes and what happens to the product lines.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-1478423287920989605?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=1478423287920989605' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/1478423287920989605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/1478423287920989605'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/08/segueborlandmicrofocus-silkperformer.html' title='Segue/Borland/MicroFocus SilkPerformer - Who Owns It?'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-8479711436339120418</id><published>2009-07-20T09:41:00.004-04:00</published><updated>2009-07-20T09:45:42.896-04:00</updated><title type='text'>[Software] Tools Don't Make You a Mechanic</title><content type='html'>&lt;p&gt;
FYI: Learning LoadRunner does not mean that one has learned Performance Testing. LoadRunner is only a tool. Learning to use one of these:
&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k7-jvtv2cLo/SmR0z1gKiSI/AAAAAAAAAYg/MU4_Mp_uj7I/s1600-h/200px-Englaender.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 200px; height: 135px;" src="http://4.bp.blogspot.com/_k7-jvtv2cLo/SmR0z1gKiSI/AAAAAAAAAYg/MU4_Mp_uj7I/s400/200px-Englaender.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5360537890361870626" /&gt;&lt;/a&gt;

&lt;p&gt;
...does not mean that one can disassemble and reassemble one of these:
&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_k7-jvtv2cLo/SmR07Cq_1hI/AAAAAAAAAYo/t7iMek-ohJ8/s1600-h/09-zr1-engine.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 205px;" src="http://2.bp.blogspot.com/_k7-jvtv2cLo/SmR07Cq_1hI/AAAAAAAAAYo/t7iMek-ohJ8/s400/09-zr1-engine.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5360538014156051986" /&gt;&lt;/a&gt;

&lt;p&gt;
&lt;i&gt;[via &lt;a href="http://www.sqablogs.com/JakeBrake/"&gt;JakeBrake&lt;/a&gt;]&lt;/i&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-8479711436339120418?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=8479711436339120418' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/8479711436339120418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/8479711436339120418'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/07/software-tools-dont-make-you-mechanic.html' title='[Software] Tools Don&apos;t Make You a Mechanic'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_k7-jvtv2cLo/SmR0z1gKiSI/AAAAAAAAAYg/MU4_Mp_uj7I/s72-c/200px-Englaender.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-7273261698522684220</id><published>2009-07-10T10:52:00.006-04:00</published><updated>2009-07-13T09:24:24.263-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - Zip Directories Recursively</title><content type='html'>&lt;p&gt;
This helped me out today with some backup scripts.  Posting here so I can remember it.  Idea and snippet adapted from:
&lt;a href="http://mail.python.org/pipermail/python-list/2007-February/596539.html"&gt;http://mail.python.org/pipermail/python-list/2007-February/596539.html&lt;/a&gt;
&lt;/p&gt;        

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
        
#!/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()
&lt;/pre&gt;

&lt;p&gt;&lt;i&gt;* code updated.  there was a bug in the original I posted (cmg - 07/13/09)&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-7273261698522684220?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=7273261698522684220' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7273261698522684220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7273261698522684220'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/07/python-zip-directories-recursively.html' title='Python - Zip Directories Recursively'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-2896910862111264839</id><published>2009-07-07T12:25:00.001-04:00</published><updated>2009-07-07T12:27:48.676-04:00</updated><title type='text'>OpenSTA - SCL Code Boilerplate for HTTP Load Tests</title><content type='html'>&lt;p&gt;
&lt;i&gt;(small code dump...)&lt;/i&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://www.opensta.org/"&gt;OpenSTA&lt;/a&gt; (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.
&lt;/p&gt;

&lt;p&gt;
Here is the basic structure I start with when modeling tests in OpenSTA:
&lt;/p&gt;


&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
!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" &amp;
                        "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 &amp;
        HEADER DEFAULT_HEADERS &amp;
        ,WITH {"Accept: */*", "Accept-Language: en-us"}

    SYNCHRONIZE REQUESTS
    
    DISCONNECT FROM 1
    
    End Timer T_Response
  
Exit


ERR_LABEL:
    If (MESSAGE &lt;&gt; "") Then
        Report MESSAGE
    Endif

Exit
&lt;/pre&gt;

&lt;p&gt;
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.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-2896910862111264839?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=2896910862111264839' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2896910862111264839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2896910862111264839'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/07/opensta-scl-code-boilerplate-for-http.html' title='OpenSTA - SCL Code Boilerplate for HTTP Load Tests'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-3507223106666858974</id><published>2009-07-07T11:10:00.001-04:00</published><updated>2009-07-07T14:42:11.041-04:00</updated><title type='text'>Web Performance Tool Evaluation - lower end proprietary tools</title><content type='html'>&lt;p&gt;
I am in the middle of a Performance and Load tools selection process and wanted to get some feedback here.
&lt;/p&gt;

&lt;p&gt;
I currently work in a shop that uses a mix of proprietary and open source tools for web performance &amp; 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:
&lt;/p&gt;

&lt;pre&gt;
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)
&lt;/pre&gt;

&lt;p&gt;
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:
&lt;/p&gt;

&lt;pre&gt;
Requirements
------------------------
Protocols:
- HTTP
- ODBC (SQL)

Features:
- distributed load generation
- reporting/analytics
- data driven testing
- 5000+ VU
&lt;/pre&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;pre&gt;
Open Source tools
------------------------
OpenSTA
JMeter
Pylot
&lt;/pre&gt;

&lt;p&gt;
Now finally to the question/point....
&lt;/p&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;pre&gt;
Low-end tools
------------------------
Microsoft - VSTS
Radview - WebLOAD
SoftLogica - WAPT
Facilita - Forecast
Zoho - QEngine
Neotys - NeoLoad
&lt;/pre&gt;

&lt;p&gt;
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?
&lt;/p&gt;

&lt;p&gt;
any comments/suggestions are appreciated.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3507223106666858974?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=3507223106666858974' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/3507223106666858974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/3507223106666858974'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/07/web-performance-tool-evaluation-lower.html' title='Web Performance Tool Evaluation - lower end proprietary tools'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-4001458835853898023</id><published>2009-06-25T10:35:00.002-04:00</published><updated>2009-06-25T13:00:28.844-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>XML-RPC Clients In Python and Perl</title><content type='html'>&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
The examples below show how to connect to an XML-RPC server and call the service's start() method.
&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;
a simple XML-RPC client in Python:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;#!/usr/bin/env python

import xmlrpclib

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

server = xmlrpclib.Server('%s:%s' % (host, port))
response = server.start()
print response
&lt;/pre&gt;

&lt;p&gt;
a simple XML-RPC client in Perl (using the Frontier-RPC module):
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;#!/usr/bin/perl -w

use strict;
use Frontier::Client;

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

my $server = Frontier::Client-&gt;new('url' =&gt; "$host:$port");
my $response = $server-&gt;call('start');
print $response;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-4001458835853898023?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=4001458835853898023' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/4001458835853898023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/4001458835853898023'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/06/xml-rpc-clients-in-python-and-perl.html' title='XML-RPC Clients In Python and Perl'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-7471074606151029246</id><published>2009-06-24T09:23:00.002-04:00</published><updated>2009-06-24T09:29:53.314-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Google Calls for a Joint Effort to Speed Up the Internet</title><content type='html'>&lt;p&gt;
check out: &lt;br /&gt;
&lt;a href="http://code.google.com/speed/"&gt;http://code.google.com/speed/&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
writeup here:&lt;br /&gt;
&lt;a href="http://www.infoq.com/news/2009/06/Google-Speed-Up-the-Internet"&gt;http://www.infoq.com/news/2009/06/Google-Speed-Up-the-Internet&lt;/a&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;em&gt;
"Google has &lt;a href="http://code.google.com/speed/"&gt;launched a web site&lt;/a&gt; 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."
&lt;/em&gt;
&lt;/blockquote&gt;

&lt;p&gt;
&lt;a href="http://www.pylot.org"&gt;Pylot&lt;/a&gt; is listed in the &lt;a href="http://code.google.com/speed/downloads.html"&gt;downloads section&lt;/a&gt;!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-7471074606151029246?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=7471074606151029246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7471074606151029246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7471074606151029246'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/06/google-calls-for-joint-effort-to-speed.html' title='Google Calls for a Joint Effort to Speed Up the Internet'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-9110793701346927753</id><published>2009-05-14T12:17:00.002-04:00</published><updated>2009-05-14T12:19:37.202-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Mini Web Load Tester with Python and Pylot Core</title><content type='html'>&lt;p&gt;
&lt;a href="http://www.pylot.org/"&gt;Pylot&lt;/a&gt; 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.  
&lt;/p&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
Here is a small Python script that uses Pylot as a module:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;#!/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)
&lt;/pre&gt;        

&lt;p&gt;
Output:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;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
&lt;/pre&gt;

&lt;p&gt;
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.
&lt;/p&gt;
   
&lt;p&gt;
Code:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;#!/usr/bin/env python
# Corey Goldberg 2009

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



def main():
    """
    Usage: &gt;python pylot_mini_loadtest.py &lt;url&gt; &lt;number of threads/agents&gt; &lt;duration&gt;
    """
    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()
&lt;/pre&gt;    

&lt;p&gt;
Usage/Output:
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;C:\test&gt;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
&lt;/pre&gt;    

&lt;p&gt;
Of course, for more complex scenarios, you can use the full blown tool, available at: &lt;a href="http://www.pylot.org/download.html"&gt;www.pylot.org/download.html&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Questions?  Hit me up.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-9110793701346927753?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=9110793701346927753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/9110793701346927753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/9110793701346927753'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/05/mini-web-load-tester-with-python-and.html' title='Mini Web Load Tester with Python and Pylot Core'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-7438369284070020892</id><published>2009-05-11T14:33:00.004-04:00</published><updated>2009-05-11T14:37:29.242-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Pylot - Total Downloads So Far</title><content type='html'>&lt;p&gt;
Here is a graph showing total downloads of &lt;a href="http://www.pylot.org/"&gt;Pylot&lt;/a&gt; since its first release:
&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k7-jvtv2cLo/Sghvsx7qvFI/AAAAAAAAAYA/hBe232f_yK4/s1600-h/pylot_downloads_05112009.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 295px;" src="http://4.bp.blogspot.com/_k7-jvtv2cLo/Sghvsx7qvFI/AAAAAAAAAYA/hBe232f_yK4/s400/pylot_downloads_05112009.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5334636573728881746" /&gt;&lt;/a&gt;

&lt;p&gt;
Decent uptake so far.  Keep the &lt;a href="http://www.pylot.org/download.html"&gt;downloads&lt;/a&gt; coming!
&lt;/p&gt;

&lt;p&gt;
Pylot is a web performance testing tool.  It is Free Open Source Software.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-7438369284070020892?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=7438369284070020892' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7438369284070020892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7438369284070020892'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/05/pylot-total-downloads-so-far.html' title='Pylot - Total Downloads So Far'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_k7-jvtv2cLo/Sghvsx7qvFI/AAAAAAAAAYA/hBe232f_yK4/s72-c/pylot_downloads_05112009.JPG' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-3434479000407736934</id><published>2009-05-11T11:14:00.003-04:00</published><updated>2009-05-11T11:18:32.098-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - Redirect or Turn Off STDOUT and STDERR</title><content type='html'>&lt;p&gt;
Here is an easy way to temporarily turn off STDOUT or STDERR in your Python program.
&lt;/p&gt;

&lt;p&gt;
First you create a class to replace STDOUT.  This is just minimal class with a 'write()' method. 
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;class NullDevice():
    def write(self, s):
        pass
&lt;/pre&gt;        

&lt;p&gt;
Notice its 'write()' method does nothing.  Therefore, when you write to the NullDevice, output goes nowhere and is dropped.  All you need to do is assign sys.stdout to this class.
&lt;/p&gt;

&lt;p&gt;Here is an example of turning STDOUT off and back on:&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;#!/usr/bin/env python

import sys


class NullDevice():
    def write(self, s):
        pass


print "1 - this will print to STDOUT"

original_stdout = sys.stdout  # keep a reference to STDOUT

sys.stdout = NullDevice()  # redirect the real STDOUT

print "2 - this won't print"

sys.stdout = original_stdout  # turn STDOUT back on

print "3 - this will print to SDTDOUT"
&lt;/pre&gt;

&lt;p&gt;
You can also do the same thing with sys.stderr to turn off STDERR.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3434479000407736934?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=3434479000407736934' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/3434479000407736934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/3434479000407736934'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/05/python-redirect-or-turn-off-stdout-and.html' title='Python - Redirect or Turn Off STDOUT and STDERR'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-2721799987442937098</id><published>2009-05-08T10:41:00.001-04:00</published><updated>2009-05-08T11:19:47.097-04:00</updated><title type='text'>C# - Export Windows Event Logs</title><content type='html'>&lt;p&gt;
Here is a little C# program to export Windows Event Logs.  It reads an Event Log and prints entries to STDOUT so you can pipe the output to a file or other application.
&lt;/p&gt;

&lt;pre style="font-size:11px;border:1px #999999 dashed;font-family:monospace;color:#990000;background-color:#EEEEEE;padding-left:10px;"&gt;
using System;
using System.Diagnostics;


class EventLogExporter
{
    static void Main(string[] args)
    {
        EventLog evtLog = new EventLog("Application");  // Event Log type
        evtLog.MachineName = ".";  // dot is local machine
        
        foreach (EventLogEntry evtEntry in evtLog.Entries)
        {
            Console.WriteLine(evtEntry.Message);
        }
        
        evtLog.Close();
    }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-2721799987442937098?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=2721799987442937098' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2721799987442937098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/2721799987442937098'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/05/c-export-windows-event-logs.html' title='C# - Export Windows Event Logs'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-6215031317099541785</id><published>2009-05-06T12:39:00.003-04:00</published><updated>2009-05-06T12:48:23.847-04:00</updated><title type='text'>Dell Mini 10 Netbook with Linux == Graphics FAIL</title><content type='html'>&lt;p&gt;
If you are planning on buying a Dell Mini 10 (or Mini 12) to run Linux, read this... 
&lt;/p&gt;

&lt;p&gt;
I used to have the Dell Mini 9 that came with Linux (Ubuntu 8.04).  As soon as I got it, I paved it and installed Ubuntu Intrepid instead.  It worked like a charm.  Then I decided to sell my Mini 9 and upgrade to the Mini 10.  The Mini 10 is a better machine in terms of hardware, and is MUCH better in terms of screen resolution and keyboard size (best keyboard on any netbook).
&lt;/p&gt;

&lt;p&gt;
So, the Mini 10 ships with Windows installed.  Since I had such good luck with the Mini 9, I figured a Linux install would be a breeze.  So with my shiny new Mini 10 netbook, I tried an install Ubuntu Intrepid.  It worked great but no compatible graphics driver.  OK, so I waited for the Ubuntu Jaunty release and then promptly installed that.  Same prob.
&lt;/p&gt;

&lt;p&gt;
Here is the deal:
&lt;b&gt;There is no Linux driver for the graphics card it uses (Intel GMA 500).&lt;/b&gt;  So.. if you want to run Linux on it, your only choice is to run in a non-native resolution using the default driver.  This totally sucks.
&lt;/p&gt;

&lt;p&gt;
There appears to be a native Linux driver somewhere (Poulsbo), &lt;a href="http://www.happyassassin.net/2009/01/30/intel-gma-500-poulsbo-graphics-on-linux-a-precise-and-comprehensive-summary-as-to-why-youre-screwed/"&gt;but it doesn't work right now&lt;/a&gt; and is not packaged.
&lt;/p&gt;

&lt;p&gt;
I am just running Windows for now and waiting for a real native driver to be released.  Shame on Intel for not providing one.
&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k7-jvtv2cLo/SgG_P3dppcI/AAAAAAAAAX4/Cxyjvaxs3LE/s1600-h/dell-mini-10-notebook.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 309px;" src="http://4.bp.blogspot.com/_k7-jvtv2cLo/SgG_P3dppcI/AAAAAAAAAX4/Cxyjvaxs3LE/s400/dell-mini-10-notebook.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5332753713090635202" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-6215031317099541785?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=6215031317099541785' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/6215031317099541785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/6215031317099541785'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/05/dell-mini-10-netbook-with-linux.html' title='Dell Mini 10 Netbook with Linux == Graphics FAIL'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_k7-jvtv2cLo/SgG_P3dppcI/AAAAAAAAAX4/Cxyjvaxs3LE/s72-c/dell-mini-10-notebook.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-3399857439272632274</id><published>2009-05-06T10:24:00.002-04:00</published><updated>2009-05-06T10:28:10.829-04:00</updated><title type='text'>Scripted Testing Isn't  Just Following Scripts</title><content type='html'>&lt;p&gt;
There is an ongoing (or dead horse, depending on your perspective) about "scripted" vs. "exploratory" testing.
&lt;/p&gt;
&lt;p&gt;
I happen to refer to "scripted testing" as programmatic testing. You use programs, scripts, and tools to augment/enable your testing.  You can explore a system with your toolset if you want.  That is an example of doing exploratory testing with scripts/programs/tools.
&lt;/p&gt;
&lt;p&gt;
The debate seems to overlook that definition and defines "scripted" as just following a number of predefined steps.  I think this is the wrong definition and the wrong argument.. or maybe I just don't get it... or maybe I'm confused by the ambiguous definitions of scripting.
&lt;/p&gt;
&lt;p&gt;
I don't see it as a boolean. I think of it terms of a spectrum and somewhere along that programmatic/manual continuum is where you work.  Exploratory testing can fall in many areas of the spectrum and you can do it manually or programmatically.
&lt;/p&gt;
&lt;p&gt;
That is where the argument breaks down (IMHO).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-3399857439272632274?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=3399857439272632274' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/3399857439272632274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/3399857439272632274'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/05/scripted-testing-isnt-just-following.html' title='Scripted Testing Isn&apos;t  Just Following Scripts'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-752723696981499436</id><published>2009-03-30T11:16:00.002-04:00</published><updated>2009-03-30T14:03:51.819-04:00</updated><title type='text'>Ordered a New Laptop - Dell Studio 17 - Running Ubuntu</title><content type='html'>&lt;p&gt;
I just ordered a new laptop for home.  This will be used as my workstation/desktop replacement.
&lt;/p&gt;

&lt;p&gt;
Ubuntu Jaunty Jackalope comes out April 23, and this machine will get a fresh copy.  I'm hoping all my hardware works good with it.
&lt;/p&gt;

&lt;p&gt;Specs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dell Studio 17&lt;/li&gt;
&lt;li&gt;64 bit&lt;/li&gt;
&lt;li&gt;Intel Core 2 Duo T6400 (2.00GHz/800Mhz FSB/2MB cache)&lt;/li&gt;
&lt;li&gt;4GB Shared Dual Channel DDR2 at 800MHz&lt;/li&gt;
&lt;li&gt;256MB ATI Mobility Radeon HD 3650&lt;/li&gt;
&lt;li&gt;250GB SATA Hard Drive (7200RPM)&lt;/li&gt;
&lt;li&gt;Glossy widescreen 17.0 inch display (1920x1200)&lt;/li&gt;
&lt;li&gt;8X CD/DVD Burner&lt;/li&gt;
&lt;li&gt;Intel WiFi Link 5100 802.11agn Half Mini-Card&lt;/li&gt;
&lt;li&gt;Back-lit Keyboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
I will post again to tell how the hardware compatibility with Ubuntu and Linux is.
&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_k7-jvtv2cLo/SdDihal1P3I/AAAAAAAAAXQ/kKTWB9ZfyZA/s1600-h/studio_17_orange_314.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 314px; height: 314px;" src="http://1.bp.blogspot.com/_k7-jvtv2cLo/SdDihal1P3I/AAAAAAAAAXQ/kKTWB9ZfyZA/s400/studio_17_orange_314.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5319000223626116978" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-752723696981499436?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=752723696981499436' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/752723696981499436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/752723696981499436'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/03/ordered-new-laptop-dell-studio-17.html' title='Ordered a New Laptop - Dell Studio 17 - Running Ubuntu'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_k7-jvtv2cLo/SdDihal1P3I/AAAAAAAAAXQ/kKTWB9ZfyZA/s72-c/studio_17_orange_314.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-7252379959926485463</id><published>2009-03-25T11:06:00.001-04:00</published><updated>2009-03-25T11:09:21.115-04:00</updated><title type='text'>Did You Know?</title><content type='html'>&lt;blockquote&gt;
&lt;em&gt;
"We are currently preparing students for jobs that don’t yet exist, using technologies that haven’t yet been invented, in order to solve problems we don’t even know are problems yet."
&lt;/em&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://infosthetics.com/archives/2009/03/did_you_know_30_video.html#extended"&gt;Did You Know 3.0 (video)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;... just something to ponder.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-7252379959926485463?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=7252379959926485463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7252379959926485463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7252379959926485463'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/03/did-you-know.html' title='Did You Know?'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-42741271973953958</id><published>2009-03-23T11:11:00.002-04:00</published><updated>2009-03-23T11:16:16.550-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Pylot Version 1.22 Released - Open Source Web Performance Tool</title><content type='html'>&lt;p&gt;
I just did a release of Pylot, the open source web/http performance tool. You can download it here:&lt;br /&gt;
&lt;a href="http://www.pylot.org/download.html"&gt;http://www.pylot.org/download.html&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
New features in Pylot 1.22:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;restructured code base&lt;/li&gt;
&lt;li&gt;custom timer groups&lt;/li&gt;
&lt;li&gt;socket timeout setting&lt;/li&gt;
&lt;li&gt;misc bug fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Thanks to everyone who contributed to this release!
&lt;/p&gt;

&lt;p&gt;
If you have any problems to report, please post to the discussion forum at:
&lt;a href="http://clearspace.openqa.org/community/pylot "&gt;http://clearspace.openqa.org/community/pylot &lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-42741271973953958?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=42741271973953958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/42741271973953958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/42741271973953958'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/03/pylot-version-122-released-open-source.html' title='Pylot Version 1.22 Released - Open Source Web Performance Tool'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-8639868735991673445</id><published>2009-03-21T17:09:00.006-04:00</published><updated>2009-03-21T17:21:05.716-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Finally Got Me A Hackergotchi</title><content type='html'>&lt;p&gt;My Designer friend whipped up my hackergotchi in about 10 mins.  Always wanted one of these things:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k7-jvtv2cLo/ScVaMSh3OfI/AAAAAAAAAXI/_ryWPb1AKVs/s1600-h/foo.jg.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 131px; height: 131px;" src="http://4.bp.blogspot.com/_k7-jvtv2cLo/ScVaMSh3OfI/AAAAAAAAAXI/_ryWPb1AKVs/s400/foo.jg.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5315754102359538162" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-8639868735991673445?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=8639868735991673445' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/8639868735991673445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/8639868735991673445'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/03/finally-got-me-hackergotchi.html' title='Finally Got Me A Hackergotchi'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_k7-jvtv2cLo/ScVaMSh3OfI/AAAAAAAAAXI/_ryWPb1AKVs/s72-c/foo.jg.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-7896183208143911669</id><published>2009-03-21T17:00:00.005-04:00</published><updated>2009-03-21T17:06:01.307-04:00</updated><title type='text'>Zazzle - Business Cards Are Fun To Design</title><content type='html'>I was bored and played with &lt;a href="http://www.zazzle.com"&gt;Zazzle&lt;/a&gt; for a little while today.  Here is the business card design I came up with:


&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k7-jvtv2cLo/ScVV4aE7pbI/AAAAAAAAAWY/cS7D37W6Lxg/s1600-h/bizcard.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 396px; height: 240px;" src="http://4.bp.blogspot.com/_k7-jvtv2cLo/ScVV4aE7pbI/AAAAAAAAAWY/cS7D37W6Lxg/s400/bizcard.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5315749362741781938" /&gt;&lt;/a&gt;

&lt;br /&gt;
... not gonna order any, but it was fun to design.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-7896183208143911669?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=7896183208143911669' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7896183208143911669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7896183208143911669'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/03/zazzle-business-cards-are-fun-to-design.html' title='Zazzle - Business Cards Are Fun To Design'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_k7-jvtv2cLo/ScVV4aE7pbI/AAAAAAAAAWY/cS7D37W6Lxg/s72-c/bizcard.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236867476487043111.post-7542438393033388678</id><published>2009-03-18T16:41:00.004-04:00</published><updated>2009-03-18T16:46:29.456-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Pylot - It Had To Start Somewhere</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_k7-jvtv2cLo/ScFcwIFaKRI/AAAAAAAAAUw/y0jIXZyyqIE/s1600-h/pylot_00_code.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_k7-jvtv2cLo/ScFcwIFaKRI/AAAAAAAAAUw/y0jIXZyyqIE/s400/pylot_00_code.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5314631017147541778" /&gt;&lt;/a&gt;

&lt;p&gt;
I just found a scrap of paper on my desk.  It is the original version 0.0 of Pylot from May 2007 (notice it all fits on 1 printed page).  I'm just posting this to look back on someday.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="www.pylot.org"&gt;www.pylot.org&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236867476487043111-7542438393033388678?l=coreygoldberg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=5236867476487043111&amp;postID=7542438393033388678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7542438393033388678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236867476487043111/posts/default/7542438393033388678'/><link rel='alternate' type='text/html' href='http://coreygoldberg.blogspot.com/2009/03/pylot-it-had-to-start-somewhere.html' title='Pylot - It Had To Start Somewhere'/><author><name>Corey Goldberg</name><uri>http://www.blogger.com/profile/06219872951977664560</uri><email>corey@goldb.org</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05877227130560928335'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_k7-jvtv2cLo/ScFcwIFaKRI/AAAAAAAAAUw/y0jIXZyyqIE/s72-c/pylot_00_code.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>