Introduction
Some of our client applications get distributed using the Click-Once paradigm. One day we noticed that the time between the initial click on the download link in the browser and the complete initialization of the Click-Once desktop client application took much longer than a user would tolerate. We decided to debug the deployment of the application and fix the problem. We chose the Microsoft Netmon 3.2 and the VRTA (Visual Round Trip Analyzer) for the initial analysis.
Figure 1: VRTA Analysis
Tools
Visual Round Trip Analyzer
VRTA sits on top of NetMon 3.2 which is also released publically for free. VRTA abstracts the use of Netmon so the user does not need to know the details of Netmon but can simply click to start/stop the capture. VRTA has three primary features
- A main chart which displays http traffic in 3 dimensions
- An All Files view that shows critical measurements for each file loading
- An Analysis report that indicates which file transfers are exceptions to best practice rules.
VRTA can be downloaded here: VRTA
There is also a nice document that describes the the VRTA tool in detail: 12 steps to faster web pages with Visual Round Trip Analyzer
Netmon
Network Monitor 3.2 is a protocol analyzer. It allows you to capture network traffic, view and analyze it.
Netmon 3.2 can be downloaded from here: Netmon 3.2
Figure 2: Netmon 3.2 with HTTP Parser
Tests and Measurements
We did two groups of measurements. The first measured the HTTP requests and their outcome during the very first time of the application deployment. The second group did the same analysis for subsequent downloads.
Analysis results
We found a couple of sources for download latency. Many requests resulted in 404 or 402 errors, which should be easy to fix. Other delays were causes by an unexpectedly high number of web service calls.
Before and After comparison with PowerShell
Once we identified the problems and put fixes in place we needed to verify the result. This is the point where PowerShell comes into the picture. The HTTP parsing results from VRTA can be exported as text files. We did an export before the changes and used this text file as baseline, then we ran the same capture with the fixed version of our web application and exported a new capture file. We used a PowerShell script to analyze the two capture export files and to filter out the differences.
Figure 3: ISE comparing two VRTA capture export files
The capture files
VRTA is a great visualization tool for exploratory analysis, but it doesn’t provide some kind of a diff tool. Looking at the capture text files and trying to compare the files manually doesn’t make any sense. Just look at the following two screenshots and you know what I am talking about.
Figure 4: Test 1 before the changes
Figure 5: Test 1 after the changes
The PowerShell script
The following script reads the text files line-by-line as strings, uses the split() function to isolate the url and error code fields and populates one hashtable for each of the capture files. Then it uses the compare-object cmdlet to perform a diff operation. Remember to set the SyncWindow parameter big enough!
1: CLS
2: $LinesAfter = Get-Content -path "C:\PTMShare\TESTRESULTS\TrendDownload\After\Test3.txt"
3: $FileResultsMapAfter = @{}
4: $LinesAfter | ForEach-Object { $a = $_.split(); if( $a[5] -match '^http://.*$') {$FileResultsMapAfter[$a[5].Trim()] = $a[6]}}
5: "Number of requests after the change: " + $LinesAfter.count
6: $LinesBefore = Get-Content -path "C:\PTMShare\TESTRESULTS\TrendDownload\Before\Test3.txt"
7: $FileResultsMapBefore = @{}
8: $LinesBefore | ForEach-Object { $a = $_.split(); if( $a[5] -match '^http://.*$') {$FileResultsMapBefore[$a[5].Trim()] = $a[6]}}
9: "Number of requests before the change: " + $Linesbefore.count
10: $FileResultsAfter = $FileResultsMapAfter.GetEnumerator() | Sort-Object -Property Key
11: $FileResultsBefore = $FileResultsMapBefore.GetEnumerator() | Sort-Object -Property Key
12: $ComparisonResult = Compare-Object -Property Key -ReferenceObject $FileResultsBefore -DifferenceObject $FileResultsAfter -IncludeEqual -SyncWindow $FileResultsBefore.Count
13: Write-Host "Files that are not requested after the change:" -ForegroundColor white -BackgroundColor red
14: $ComparisonResult | ForEach-Object {if ($_.SideIndicator -eq "<=") {$FileResultsMapBefore[$_.Key] + ": " + $_.Key }}
15: Write-Host "File requests that are identical after the change:" -ForegroundColor white -BackgroundColor red
16: $ComparisonResult | ForEach-Object {if ($_.SideIndicator -eq "==") {if ($FileResultsMapBefore[$_.Key] -ne $FileResultsMapAfter[$_.Key]) {Write-Host "!!!" -ForegroundColor white -BackgroundColor red} $FileResultsMapBefore[$_.Key] + ": " + $FileResultsMapAfter[$_.Key] + ": " +$_.Key }}
17: Write-Host "Files only requested after the change:" -ForegroundColor white -BackgroundColor red
18: $ComparisonResult | ForEach-Object {if ($_.SideIndicator -eq "=>") {$FileResultsMapBefore[$_.Key] + ": " + $_.Key }}
The comparison results
Figure 6: Comparison Results of Test 1
Download
And in case somebody wants to play with the script, the source code and a set of capture files can be downloaded here: CompareVRTACaptureFiles.zip
Ausblick
As a next step I would like to automate the VRTA comparison and have it run as an automated regression test. Unfortunately the VRTA doesn’t provide a way to script its UI actions. The good news is that NetMon 3.2 comes with several hooks that could be used for automation. There is the NMAPI.dll and a C# file that has PInvoke declarations for the NetMon 3.2 API. And there is a command line utility for capturing and parsing http traffic.