15 December 2007

Correcting blank image and link dialogs in Joomla

I was going nuts! When I worked on my friend's Joomla site from home, the Image and Link dialogs appear just fine:


But when I tried it from work or when my friend did it from her house, the dialogs came up blank:


I tried every combination of browser setting and browser (Firefox, Opera, IE). Nothing. What was so magical about my machine at home?

I found the answer on Alex Le's blog. It turns out that my site home (as defined by $mosConfig_live_site) was set to www.site_name.com while I was firing up the administration console with http://site_name.com/administrator (notice the lack of www). Once I launched from http://www.site_name.com/administrator, the edit dialogs are dandy again, just like they are from home. Thanks, Alex!

Getting JRuby gem utility to work

I've been cursing my brains out trying to get the JRuby version of gem to work. After much hunting around, I found that a Java memory size issue was causing the problem. Things have been working fine since I started installing gems with:

jruby -J-Xmx512M -S gem install

My apologies for having lost the original reference to this information. This bug entry might have been where I first found the solution.

JRuby as a system programming language

At work, we are starting to refactor some of our system utilities. The scripts interact with these basic components:
  • Postgres databases
  • FTP servers
  • Files on various servers
  • Java applications
  • Specific system calls
My boss, being from an "older generation" ;-), favors Unix scripting (sed, bash, etc.) . Being a Ruby/JRuby enthusiast myself, I wanted to show my team how easy these tasks are in JRuby. While sed might take fewer characters in some cases, I think JRuby strikes an ideal match between terseness and readability.

Note that the following code will not run on your computer, at least not without setting up a Postgres database and changing the FTP server info, etc. But it will give you a good flavor for system programming in JRuby.


#

# Copyright 2007 Effectiveqa.com. All rights reserved

#



def postgres

# Accessing Postgres from JRuby

# http://ruby.scripting.ca/postgres/rdoc/



$LOAD_PATH << 'C:/jruby-1.0.1/lib/ruby/gems/1.8/gems/postgres-pr-0.4.0/lib'

require 'postgres'

con = PGconn.connect('localhost', 5432, nil, nil, 'foo', 'postgres', 'password'

res = con.query("select * from bar")

puts res[0][0]

end



def ftp

# FTP Access

# http://ruby-doc.org/stdlib/libdoc/net/ftp/rdoc/index.html

require 'net/ftp'

Net::FTP.open('effectiveqa.com') do |ftp|

ftp.login('username', 'password')

ftp.chdir('public_html')

ftp.list('*.css').each {|file| puts file}

ftp.gettextfile('main.css', 'local_main.css')

end

end



def ftp_password

# Show how easily JRuby can handle password problem

require 'net/ftp'

begin

ftp = Net::FTP.open('effectiveqa.com')

ftp.login('effectiv', 'BADPASSWORD')

rescue

puts "Here is where I fix the password"

ftp.login('username', 'password')

ftp.chdir('public_html')

ftp.list('*.css').each {|file| puts file}
end

end



def file_tricks

# Different file/directory manipulations

# http://www.ruby-doc.org/stdlib/libdoc/fileutils/rdoc/index.html

require 'fileutils'

include FileUtils



begin cd('dfsdf') rescue puts 'Oops, had a problem...' end

chmod(0777, 'local_main.css')

puts "Don't match!" if ! cmp('local_main.css', 'local_main_1.css')

cp('local_main.css', 'local_main_copy.css')

puts "Do match!" if cmp('local_main.css', 'local_main_copy.css')

puts pwd

rm('local_main_copy.css')

begin rm('DOESNT_EXIST') rescue puts 'Caught one' end

end



def file_tests

# Very nice tests

# http://ruby-doc.org/docs/ProgrammingRuby/html/ref_m_filetest.html



puts FileTest.directory?('example.zip') # false

puts FileTest.size('example.zip') # 1723

puts FileTest.file?('.') # false

puts FileTest.file?('example.zip') # true

puts FileTest.readable?('example.zip') # true

puts FileTest.writable?('example.zip') # true



include FileTest

puts directory?('.') # true; needs include

puts file?('.') # false

end

def use_java

# Show off how easy it is to use Java from JRuby

include Java



zf = java.util.zip.ZipFile.new('example.zip')

puts "There are #{zf.size} files in the zip."

zf.entries.each {|entry| puts " file: #{entry}"}

end



def split_files

# Easy processing of DB dump files



lines = IO.readlines('pipeFile.txt')

lines.each {|line| puts line.split('|')[1]}

end



def system_calls

# JRuby has full access to OS calls

lines = `df`.split("\n")

lines.shift # Read off header line

lines.each do |line|

fields = line.split

next unless fields[0] =~ /C:$/ # Only care about the C: drive

percent = fields[4].to_i

puts "Holy cow, disk almost full" if percent > 95

puts "Disk > 50% full" if percent > 50

end

end



# Some interesting Ruby libraries

# http://beaver.net/slides/ruby/10-easy-pieces.html

# Library doc: http://www.ruby-doc.org/stdlib/

# Pathnames: http://www.ruby-doc.org/stdlib/libdoc/pathname/rdoc/index.html

# MD5, sha1: http://www.ruby-doc.org/stdlib/libdoc/digest/rdoc/index.html

# Waking trees: http://ruby-doc.org/stdlib/libdoc/find/rdoc/index.html



puts "\n**** I can access postgres\n"

postgres

puts "\n**** I can access FTP\n"

ftp

puts "\n**** I can tell if an FTP password failed\n"

ftp_password

puts "\n**** I have all kinds of *nix file commands\n"

file_tricks

puts "\n**** I also have all kinds of cool file tests\n"

file_tests

puts "\n**** I can easily use Java code\n"

use_java

puts "\n**** I can split up Dave's db dump files\n"

split_files

puts "\n**** I can make OS calls with ease\n"

system_calls



The only shortcoming I could find with JRuby is that it doesn't support all the command line options that Ruby does. So you can see that JRuby falls behind in the terseness of its one-liner to rip a particular field out of a pipe-delimited dump file, though I would argue it is more readable.

#> ruby -n -a -F"\|" -e "puts $F[1]" pipeFile.txt

#> perl -n -a -F"\|" -e 'print "$F[1]\n"' pipeFile.txt

#> jruby -e "IO.readlines('pipeFile.txt').each {|ln| puts ln.split('|')[1]}"


05 December 2007

Using Subversion svn+ssh protocol without typing passwords

I have been having more and more problems using the svn: protocol for Subversion. So I've moved to using the svn+ssh: protocol. The only frustration was having to constantly enter my password (sometimes many times) for each svn command. It turns out that svn+ssh: is using standard SSH protocols, so SSH key authentication solves the problem.

I found a nice write-up on Aaron Toponce's blog on how to set it up.

It is a little more complicated for Windows. I will address that in a future installment.

28 November 2007

New Mexico Information Technology Infrastructure & Architecture group forming

Today, I attended the first meeting of "New Mexico Information Technology Infrastructure & Architecture," the brainchild of Thierry Thelliez, oft contributor and board member of the AgileNM group that I run. Thierry envisions the group positioned somewhere between the AgileNM/SPIN groups and the technology-focused groups (like the New Mexico Ruby and Java users groups) in terms of where it fits on the technology vs. business continuum. Some of the topics discussed that caught my eye:
  • Server virtualization
  • Web frameworks
  • Open source
  • Scripting languages (e.g. Ruby, Python)
  • Wikis
  • Distributed architectures
The next meeting is scheduled for January, 2008. Visit the NMITIA site for more details and to add your input for topics you'd like to see. Like the AgileNM group, Thierry's vision is that group members will largely drive the agenda. So help drive the group in a direction that will meet your professional needs.

24 November 2007

Flex Functional Testing with Ruby

I have been playing with Flex the last few days, creating an application to screen scrape audio equipment sales sites on a periodic basis and send me email when a component I am looking for is posted. Currently, I am a little hung up trying to use WebORB interface between Flex 3 Beta 2 and Ruby on Rails. The examples appear to all be written for Flex 2. So far, I have found some references that make it sound doable, but I am not quite there yet.

In the meantime, I ran across FunFX, a Ruby library for functional testing of Flex applications. This is very exciting to me since, until now, I was only aware of Mercury (oops, HP) QuickTest Pro as a testing option for Flex. To be able to test Flex apps with code very similar to the Watir tests I write now is very exciting. I have not fired it up yet, but as soon as I have some experience with it, I'll report back.

20 November 2007

Firefox 3 Beta Available!

I just read in the New York Times technology section that the Beta for Firefox 3 (Minefield) is now available. Being too curious, I had to give it a try.

It doesn't work with most of my plugins yet (although I did manage to load Adblock Plus!). The first big problem I found was editing this post. The Javascript editor for Blogger did not respond particularly well, so I am finishing this up with Firefox 2. And, so far, I have not noticed any killer features I can't live without.

Even so, I still plan to use Firefox 3 for most of my casual browsing. The reason I plan to stay with it is speed. Except for Opera, this is the fastest browser I have seen. Mozilla also claims that it has fixed 300 memory leaks.

10 November 2007

Killer CMS - Joomla

I hadn't had much need for a Content Management System (CMS) until, recently, I offered to help a friend get her site up and running. She has written professionally for the Web for years, but the actual web design is handled by the organizations she works for. I was going to whip something up for her myself but with zillions of CMS systems available, I didn't see any reason to start from scratch.

She doesn't have a hosting service yet, so I started looking around at some of them. Many hosting services include CMS support. It seemed like it would be easier to start with one that was pre-installed, so I first looked for services with pre-installed CMS. Several providers supported Joomla!, so I decided to give that a try.

Joomla!'s demo site was down, so I went ahead and installed it on my local machine. It was literally installed in five minutes. My home box is a Windows machine and I already had the Apache/MySql/PHP stack installed using XAMPP. If you haven't tried XAMPP, it is just about the easiest way to get the stack up and running on Windows. All I did was drop the .zip files contents into my xampp\htdocs directory, point my browser at http://localhost/joomla/install, answer a few questions and I was done. So many things like this I get frustrated just getting things set up that I give up before I ever start. Not so with Joomla!.

After the install process completes, you have to remove the install folder in order to continue. This is a security feature. Once it is removed, pointing my browser to http://localhost/joomla produced a page that looked like:



So far, I have found Joomla! to be intuitive and easy to learn. But what really makes it exciting to me is the depth of the community behind it. For example, Googling on "Joomla templates" returns 7.9 MILLION hits. The first template site I went to has 1,500 free templates available! Hundreds of plugins are also available. I guess I am the only one in the world who didn't know about Joomla! until now.

My comments are based on the 1.5 RC3 (codename Takriban) release. The current production version is 1.0.13, which I have not tried.

One thing that frosts me is that it is written in PHP. I consider this a hack language, not worthy of real software efforts. Yet people are getting cool things done with it. Too bad it isn't written in Rails or Django. ;-)

30 October 2007

Using Watir and Hudson to Monitor Performance

Currently, I have a full suite of Watir regression tests that I use routinely during the development of our web app. For those who may not be familiar with it, Watir is a Ruby library which allows programmatic control of Internet Explorer to navigate through an application under test (AUT) and determine if the application is performing properly. I'll have more to say about Watir another time.

One of the challenges with our application is performance. I wanted to have a way of determining which changes to the app, network, hardware, etc. were having a positive or negative impact on performance. By wrapping some timing functions around the most timing-sensitive issues in the regression library, I created a performance benchmark.

The Timing Wrapper

The simplest timing wrapper could be as simple as this:

start = Time.now
# Do your operations here
elapsed = Time.now - start

I started this way then decided I wanted a little more capability, so I came up with a hierarchical timer, to easily time activities within larger activities. A likeness of the library I use is available here.

Watir

Watir is a very nice, open-source Ruby library that allows driving an IE session from a Ruby program and then scraping the pages to determine if a proper result was generated. I started with Selenium, but ran into problems with https and a few other things that Watir was able to handle. The one area where Selenium really beat Watir was in the quality of the recorder. But pretty quickly you learn to write the scripts by hand, with a little help from the IE Developer Toolbar. Watir does have a recorder, but I did not find it very useful.

A simple test might look something like this:

def list_page_to_page
# Try some list features
[['User 1', 'List 1', 'Company 1 page 1 -> page 2'],
['User 2', 'List 2', 'Company 2 page 1 -> page 2'],
['User 3', 'List 3', 'Company 3 page 1 -> page 2'],
].each do |user_name, list, label|
login(user_name, $password, @test_site)
@ie.link(:text, list).click

# Now try paging...
time(label) { @ie.link(:url, /page=2/).click }
logout
end
end


This example logs in as three different users, clicks on a link with particular text in it and then times how long it takes for the page to return when clicking a link that goes to page two of a multi-page list.

Hudson

For a test like this to be valuable, it needs to be run on a regular basis. While cron or Scheduled Tasks can do this, I much prefer Hudson, the continuous integration engine we use for verifying our commits do not break our JUnit tests. Hudson normally fires on actions like Subversion commits, but it can also schedule builds on a regular basis. So I set the performance task to run every hour and it just cranks away, sending me an email if there are any problems. While there are a lot of continuous integration engines available, both open-source and commercial, I am extremely pleased with both the quality of Hudson and the rate of development. I'll be writing a lot more about Hudson as soon as I get a chance. Check it out!



Give Me My Screen Back!

Since Watir actually fires up an instance of IE to do its work, it can be very disconcerting when a test fires off on your desktop machine while you are working on something else. I did have Watir minimize IE as soon as it started, but it would still be stealing focus from me and sometimes things I was trying to type in an editor would end up in some form field in IE and break the test.

I tried using another box, but it turns out it was slow enough that the tests didn't run very well. What finally worked out was using a virtual machine via VMware. Their VMWare Server is free, though you do have to sign up to get activation codes. So far, the amount of spam has been quite reasonable. I have a fairly beefy machine at work (Intel dual core, 2GB RAM), but I don't notice any degradation in performance.

Graphing the Results

While I could export the results to Excel (or better yet, IBM Lotus Symphony), I ended up using the powerful JFreeChart package. It offers an amazing amount of control in creating just the graph you want. I looked for a Ruby graphing package, but everything I found was pathetic compared to JFreeChart. Since I am not much of a Java fan, I wrote the code in JRuby. This also allowed me to pull in information from other sources, including our Apache logs and Zabbix. Here is a sample chart:



This particular graph shows that on a weekend with almost no traffic to the site (pink line), there were still performance hits on both staging (blue line) and production (red line) around 4 AM and 4 PM. These periods also corresponded to increased CPU load on the server (black line).

Summary

By using several open-source tools and a few snippets of code, I am able to record and graph the performance of our system over time and understand the impact changes to our system and operating environment have on our user experience. I recommend adding performance testing to your standard regression test suite. The immediate feedback is very helpful in heading off design decisions with negative performance implications.

19 October 2007

Open Source Load Testing with WebLOAD

Introduction

For some time now I've been playing with Grinder as a load-testing tool. There was much to like about Grinder - it seemed like one of the more advanced open-source load/capacity testers. The scripting language is Jython, which I love as a result of long being a fan of Python. Still, it is clearly underpowered compared to commercial tools. Then, one day when I was visiting Open Source Testing, I ran across WebLOAD and I knew that I was on to something special.

WebLOAD claims to contain over 250 man-years of development. It was converted to open source in April 2007. It was created by Ilan Kinreich, a co-founder of Mercury Interactive. In my opinion, this is a commercial quality application. One area that really shows is the documentation. After trying to piece together how some open-source tools work by reading forum entries, having real documentation is a godsend.

Getting Started

WebLOAD has an excellent Quick Start guide. I highly recommend starting there. The basic steps for running a load test are:
  1. Create an Agenda
  2. Configure a load template
  3. Configure session options
  4. Run the test
  5. Analyze the results
Create an Agenda

Creating agendas are easy. WebLOAD comes with a proxy recorder. You simply start the recorder and execute a user scenario in your browser. The proxy is set up automatically - no manual steps in your browser options. The commands are stored as Javascript. I really appreciate not having to learn yet another proprietary language.



The recorder also has playback and debug capabilities. It is really nice to get your agenda working cleanly before running 1,000 concurrent versions of it!

Configure a Load Template

A load template is when you actually configure the test to be run. What agenda(s) will be used? What statistics will be collected? How many simultaneous users will you simulate? Will they hit the site all at once or ramp up linearly? What host or hosts will provide the virtual clients?

All of this is done from the main WebLOAD console, not the IDE that you used to record the Agenda.

I highly recommend using the wizard that runs through the configuration options to set up the template.

Setting Session Options

Under Tools > Current Session Options, there are a large number of controls you can set, like the maximum time it can take for a page to return before it is considered a failure. In the Quick Start guide, they set a 20-second maximum time and verify 5% of the sessions.

Run the Test

From the Console, you just click the the Start Session icon and you are under way.



I love watching the various stats displaying in real time. Very cool! When running a stress test, monitoring the log view gives a good indication of when things start to break down.

Analyze the Results

WebLOAD has the ability to graph any number of parameters and statistics, including things like CPU and disk utilization on the server(s). It also supports export of data to popular formats such as Excel.

Hurdles

I did have to overcome several problems before WebLOAD would work with the main application I test. The first is that my application uses URL rewriting to track user sessions. So any URL recorded with the IDE will be incorrect at testing time, since each session is assigned a new sessionid which is part of the URL. This is where WebLOAD's professional documentation comes in again. On their forum, a white paper called "Session Management in Performance Testing [How-to]" describes handling URL re-writing along with cookies and hidden-form fields. You've got to love professional documentation!

The second issue I haven't figured out yet is why I was not able to record from our test site. I had to build sessions from our production site, then went in and modified the URLs to reference our test server. I'll let you know what I figure out with this one.

Gotchas

I learned a lesson the hard way. Do not run a stress test on your production system during business hours! (Notice issue number two in "Hurdles.") I managed to run an Agenda that hadn't been converted to the testing server's URLs. Ouch. It brought down the server at one point. Not a good thing to be doing at 10 AM! There is one good thing that came from this - it convinced me that WebLOAD was actually doing something. It's not just a program that draws pretty graphs. ;-)

Summary

Indeed, I am impressed with WebLOAD. It comes closest to an "ideal" load-testing solution than anything I've seen in the open source world. I especially like the professional quality documentation. With most open-source load testers, I give up in frustration before I ever get anything working. With WebLOAD, I had things working in a morning.

Perhaps others who have experience with commercial tools such as HP's LoadRunner will chime in on how it compares to the "big boys".