Diff’ing Made Easier

27 June, 2008 – 12:59 pm

If diff -u or wdiff isn’t cutting it for your correlating requirements when scripting load harnesses, you might want to try daisydiff as an alternative …

* Works with badly formed HTML that can be found “in the wild”.
* The diffing is more specialized in HTML than XML tree differs. Changing part of a text node will not cause the entire node to be changed.
* In addition to the default visual diff, HTML source can be diffed coherently.
* Provides easy to understand descriptions of the changes.
* Allow easy browsing of the modifications through keyboard shortcuts.

Of late have been working with pesky AJAX controls inside a web-app, and one of my gripes with more traditional tools such as wdiff or diff, is that they don’t tell you *where* in the line the change has occurred. Read on for some hacky ways I’ve implemented daisydiff with LoadRunner and other open source tools in general …

First thing I wanted to achieve, was to be able to diff entire documents with other script versions within LoadRunner. If you’ve taken a class or worked in performance testing for a while you’ll know it’s good practice to record twice, to compare what changes in a session between vusers, and sometimes also helps to record an iteration twice, to see what’s changing between iterations for single user. Anyway, you’ll probably end up with various copies of the script, which you will then want to diff for changes in things like session IDs, date time groups, request numbers and so on.

In LoadRunner VuGen you can change your preferred comparison tool in Tools->General Options->Environment Tab
General Options Tab

In my case I’ve wrapped the call to the daisydiff.jar in a simple batch file:

1
2
3
4
5
6
7
@echo off
SET DIFFA=%1
SET DIFFB=%2
:sleep 100
xcopy C:\WINDOWS\system32\daisydiff C:\temp /E /Q /Y
java -jar C:\WINDOWS\system32\daisydiff\daisydiff.jar file:///%DIFFA:\=/% file:///%DIFFB:\=/% %3 --type=tag --file=C:\temp\daisydiff.html
C:\temp\daisydiff.html

Basically I’m grabbing the parameter arguments passed to it from LoadRunner, swapping back slashes for forward slashes (so my daisydiff can parse the file locations), copying the necessary supporting image, css and javascript directories to my C:\TEMP, and then calling the daisydiff jar itself with all the bits and pieces it needs. Finally, it opens up a browser with the html output of the program. An example looking like this:
daisydiff output 2

So that’s pretty handy for comparing whole scripts. Some of the advantages is that it will show you exactly where in the line (with some nice colours) the change has occurred. Also if there is more than one change per line, then you will be able to see those easily as well in a single line.

Useful for analyzing the whole script, but what about just a selection? To do this, I’ve written a simple Perl helper, that uses Tk dialogues to prompt you to copy selection A and selection B into memory (via the clip board). Then it just creates two temporary files and does the same analysis as before. This is useful when you just want to compare two different AJAX calls (and their corresponding XML data). The diff’ing algorithm is not the best (fastest) for large complex XML documents, for that I’d recommend something purpose built, but inside LoadRunner or JMeter scripts, the performance seems fine.

The Perl helper looks like this:
Perl Helper Tk Dialogue

And the supporting code looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use Tk;
use Win32::Clipboard;
 
my $ver    = "0.1";
my $clip   = Win32::Clipboard();
 
my $main;
 
$main = MainWindow->new();
 
$main->Button( -text   => "Clipboard A",
               -command => \&clipA) ->pack(-side => "left");
$main->Button( -text   => "Clipboard B",
               -command => \&clipB) ->pack(-side => "left");               
$main->Button( -text   => "Daisy Diff",
               -command => \&daisydiff) ->pack(-side => "left");               
$main->Button( -text   => "Cancel",
               -command => sub { exit } )  ->pack(-side => "left");
 
MainLoop;
 
sub clipA {
    $clipA = $clip->Get(); 
    $clip->Empty;    
}
 
sub clipB {
    $clipB = $clip->Get();    
    $clip->Empty;
}
 
sub daisydiff {
    $fileA = 'C:/TEMP/fileA.txt';
    open(FILEA, "> $fileA")
        or die "Couldn't open temp file for writing: $!\n";
    print FILEA $clipA;
    close FILEA;
 
    $fileB = 'C:/TEMP/fileB.txt';
    open(FILEB, "> $fileB")
        or die "Couldn't open temp file for writing: $!\n";
    print FILEB $clipB;
    close FILEB;
 
    $cmd ="java -jar C:\\WINDOWS\\system32\\daisydiff\\daisydiff.jar file:///$fileA file:///$fileB --type=tag --file=C:\\TEMP\\daisydiff.html";
    system($cmd);
    system("C:\\TEMP\\daisydiff.html");
}

I’ve also wrapped a simple shell script on my macbookpro when working with JMeter etc, which looks like this:

1
2
java -jar /opt/local/bin/daisydiff.jar file://$1 file://$2 --file=/tmp/daisydiff.html $3
open /tmp/daisydiff.html

Hope that makes your diff’ing a little more pleasant =)

Share it: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Netscape
  • Reddit
  • Slashdot
  • Technorati
  • YahooMyWeb
  1. One Response to “Diff’ing Made Easier”

  2. PS. change the heap size for those bigger files!
    java -Xms32m -Xmx512m

    By tim on Jul 28, 2008

Post a Comment

*
To prove that you're not a bot, enter this code
Anti-Spam Image