Extreme Mesh-Up using NUnit, PSExec, PowerShell and NetMon 3.2 to automate http traffic monitoring

by Klaus Graefensteiner 28. April 2009 09:53

Introduction

A few weeks ago I wrote a blog post about the Microsoft Visual Round Trip Analyzer (VRTA) tool and how we used it to tune the performance of our web application: Tuning Click-Once deployment performance with VRTA and PowerShell. In this follow-up article I am now demonstrating how I automated the analysis of the http traffic. The article also demonstrates one of the virtues of PowerShell: Meshing up different tools and technologies to automate a very specific tasks.

Dhaka Traffic 

Figure 1: Dhaka traffic

Problem

I was looking for answers of the following questions:

  • How can you automatically measure the http traffic caused by a remote client that is requesting certain pages from the web server?
  • And what could be the most pragmatic solution for this problem?

I didn’t want to reinvent the wheel and needed to mesh something up quickly. The following set of screenshots demonstrates my solution. I was taking advantage of existing tools and PowerShell’s ability to “glue” it all together.

Toolbox

This mesh-up requires the following tools:

  • NUnit - .NET unit testing framework to kick-off test sequence
  • PSExec – Sysinternal’s remote command execution tool to start PowerShell on remote client computer
  • PowerShell 2.0 CTP3 – Running the Internet Explorer load scenario, starting the Network Monitor capture and analyzing the capture file
  • NetMon 3.2 – Microsoft Network Monitor tool for capturing http traffic frames
  • VRTA – Optional tool to visualize the captured frames

Solution

Overview

The test sequence gets triggered by the execution of a NUnit unit test. I wrote a unit tests in C# that starts PowerShell on a remote machine using PSUnit from Sysinternals. I didn’t have time to figure out how to pass parameters to PowerShell via the PSExec command line, so I decided to launch my work horse PowerShell script as part of the PowerShell profile. This profile script executed during the startup of PowerShell. The PowerShell script starts nmcap.exe, which is the command line tool that the Microsoft Network Monitor 3.2 uses to automate the capture of network, in this case http, frames. Once the capture is started, PowerShell is then starting Internet Explorer and passing in the URL that IE is going to load initially. The network capture is running for about 60 seconds and then stops. Then the PowerShell closes IE and starts with the analysis of the *.cap file. It reads the number of frames that the capture contained. The script compares this number with a baseline value. If the value is not in the expected limits, then the script will delay the completion of the script and wait for 4 minutes. The script returns either right away or after the waiting period. On the other machine the call to launch PSExec returns. The unit test measures how long the roundtrip took. If it took longer than 5 minutes then the test fails, otherwise it passes. The following paragraphs provide some more details.

Nunit test to launch PowerShell on remote computer via PSExec

TestRunner - NUnit Window 

Figure 2: NUnit Test Runner executing unit test

The following source code defines a NUnit test that starts the process PSExec, which then starts PowerShell.exe on a remote computer.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4: using System.Diagnostics;
   5:  
   6: using NUnit.Framework;
   7:  
   8: namespace NetMonUnitTest
   9: {
  10:     [TestFixture]
  11:     public class LauchRemotePSScript
  12:     {
  13:         [Test]
  14:         public void RemoteExecutionCompletesInLessThan5Minutes()
  15:         {
  16:             DateTime Start = DateTime.Now;
  17:  
  18:             Process PSExec = new Process();
  19:             ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\BrowserTest\psexec.exe");
  20:             startInfo.Arguments = @"-i -u Administrator -p Pa$$w0rd \\Yellowtail powershell";
  21:             PSExec.StartInfo = startInfo;
  22:             
  23:             PSExec.Start();
  24:  
  25:             PSExec.WaitForExit(10 * 60 * 1000);
  26:  
  27:             DateTime End = DateTime.Now;
  28:             TimeSpan Duration = End - Start;
  29:             
  30:             Assert.Less(Duration.Minutes, 5, "Browser Performance test failed");
  31:  
  32:         }
  33:     }
  34: }

The unit test launches PSExec and waits for it to return. If it returns in less than 5 minutes than the Unit test passes, otherwise it fails.

TestRunner - PSExec Window

Figure 3: PSExec started on server machine

PowerShell script snippet to start Netmon capture

The following snippet shows how to launch nmcap.exe to capture http traffic for about 60 seconds at the specified client IP address:

   1: "Starting netmon capture"
   2:  
   3: start-process -FilePath nmcap -ArgumentList "/network * /capture http AND ipv4.address == 192.168.1.71 /File c:\http.cap /stopwhen /timeafter 1min".Split()

IENMCap - PowerShell Script in ISE

Figure 4: PowerShell script in ISE

PowerShell script snippet to launch IE and navigate to a specific URL

The Netmon capture is running now. The script waits 10 seconds and launches Internet Explorer with a pre-defined URL.

IENMCap - PowerShell

Figure 5: Script launches Internet Explorer with pre-defined URL

   1: "Launching IE"
   2: start-process -FilePath "C:\Program Files\Internet Explorer\iexplore.exe" -ArgumentList "http://www.tellingmachine.com"
   3:  
   4: "Waiting for nmcap.exe to complete"
   5: wait-process -Name nmcap -Timeout 120
   6:  
   7: "Stopping IE"
   8: stop-Process -Name IExplore -Force
   9:  
  10: "Loading Capture File"
  11: $Buffer = Import-CaptureFile -Path "c:\http.cap"
  12:  
  13: "Parsing and calculating Frame count"
  14: $n = NumberOfFrames -Buffer $Buffer 
  15:  
  16:  
  17:  
  18:  
  19: $ExptectedFrameCount = 180
  20: $Tolerance = 20
  21: "Number of Frames: $n"
  22: "Expected        : $ExptectedFrameCount"
  23: "Deviation       : $Tolerance"
  24:  
  25:  
  26: if ($n -lt ($ExptectedFrameCount - $Tolerance) -or $n -gt ($ExptectedFrameCount + $Tolerance))
  27: {
  28:     "Test failed - Sleeping for 4 minutes"
  29:     start-sleep -Seconds 240
  30: }
  31: else
  32: {
  33:     "Test passed"
  34:     start-sleep -Seconds 10
  35: }
  36:  
  37: Stop-Process -Name PowerShell 

IENMCap - NMCap

Figure 6: Netmon is capturing frames during the next 60 seconds

IENMCap - Internet Explorer - PowerShell

Figure 7: IE loaded successfully passed-in URL

PowerShell script snippet to analyze the Network Monitor capture file

IENMCap - PowerShell Capture Analysis

Figure 8: Script analyzes capture file to get the number of http frames

The main PowerShell script calls a functions in a secondary script file called Import-NMCapture.ps1. One of the functions reads the binary data of the Netmon capture file and retrieves the number of frames.

   1:  
   2:  
   3:  
   4: Function Import-CaptureFile([string] $Path)
   5: {
   6:     $EOF = ""
   7:     $Bytes = Get-Content -Encoding Byte -Path $Path
   8:     return $Bytes
   9: }
  10:  
  11: Function ToInt( [Byte[]] $Buffer)
  12: {
  13:     [int] $Result = 0;
  14:     $Result += $Buffer[0]
  15:     $Result += $Buffer[1] * (0xFF + 1)
  16:     $Result += $Buffer[2] * (0xFFFF + 1)
  17:     $Result += $Buffer[3] * (0xFFFFFF + 1)
  18:     
  19:     return $Result
  20: }
  21:  
  22: Function ToString( [Byte[]] $Buffer)
  23: {
  24:     $Result = [String]::Empty;
  25:     $SB = New-Object -TypeName "System.Text.StringBuilder"
  26:     
  27:     foreach ($c in $Buffer)
  28:     {
  29:         $SB.Append([char][int]$c) | Out-Null
  30:     }
  31:     $Result = $SB.ToString()
  32:     return $Result
  33: }
  34:  
  35: Function NetMonCapFileMagicNumber([Byte[]] $Buffer)
  36: {
  37:     ToString $Buffer[0..3] 
  38: }
  39:  
  40: Function FrameTableOffset([Byte[]] $Buffer)
  41: {
  42:     ToInt $Buffer[24..27]
  43: }
  44:  
  45: Function FrameTableLength([Byte[]] $Buffer)
  46: {
  47:     ToInt $Buffer[28..31]
  48: }
  49:  
  50: Function NumberOfFrames([Byte[]] $Buffer)
  51: {
  52:     [int] $size = FrameTableLength -Buffer $Buffer
  53:     return $size / 4 
  54: }
  55:  
  56: Function FrameTable([Byte[]] $Buffer, [int] $Offset, [int] $Length)
  57: {
  58:     
  59:     $Result = $Buffer[ $Offset .. ($Offset + $Length)]
  60:     $Result 
  61: }
  62:  
  63: Function FrameOffsets([Byte[]] $Buffer, [int] $Offset, [int] $Length)
  64: {
  65:     $FrameTable = FrameTable -Buffer $Buffer -Offset $Offset -Length $Length
  66:     $Result = New-Object -TypeName "System.Collections.ArrayList"
  67:     [int] $FrameOffset = 0
  68:     
  69:     for( $i=0; $i -lt $FrameTable.Length - 4; $i += 4)
  70:     { 
  71:         $FrameOffset = ToInt $FrameTable[$i..($i + 4)]
  72:         $Result.Add($FrameOffset) | Out-Null
  73:     }
  74:     return $Result.ToArray()
  75: }

8 - TestRunner - NUnit Failed Window

Figure 9: NUnit test failed. The actual number of frames didn’t meet the requirement

TestRunner - NUnit Success Window

Figure 10: NUnit test passed. The number of frames met the requirements

IENMCap - Netmon Displaying Capture

Figure 11: Capture file in NetMon. Analyzing frames.

IENMCap - VRTA Displaying Capture

Figure 12: Capture file in VRTA. Graphical analysis of frame content.

Download

The source files of the scripts and NUnit test project can be downloaded here: AutomateNetMon.zip

Ausblick

I was quite surprised how relatively easy it was to put this together. It has quite some potential not just for capturing http frames, but also for load testing web servers. Here is a collection of ideas that can be added to round up my prototype:

  • Use PowerShell 2.0 remoting instead of PSExec
  • Parameterize the URLs and the wait periods between the navigations
  • Take advantage of a web testing framework like WebAii to access AJAX requests
  • Use WebAii to take screen shots of the rendered pages in the web browser
  • Support IE, Firefox and Safari
  • Figure out how to determine from outside the browser when a page is completely loaded and start measure the page load times in the browser
  • Capture the files that a page request returns as actual files
  • Resetting the browser cache from PowerShell

I strongly believe that PowerShell is a series thread to web server load testing frameworks and I would like to spend some more time working on these ideas. Stay tuned!

Tags: , , , ,

PowerShell | Test Automation | Debugging

About Klaus Graefensteiner

I like the programming of machines.

Add to Google Reader or Homepage

LinkedIn FacebookTwitter View Klaus Graefensteiner's profile on Technorati
Klaus Graefensteiner

Klaus Graefensteiner
works as Developer In Test and is founder of the PowerShell Unit Testing Framework PSUnit. More...

Open Source Projects

PSUnit is a Unit Testing framwork for PowerShell. It is designed for simplicity and hosted by Codeplex.
BlogShell is The tool for lazy developers who like to automate the composition of blog content during the writing of a blog post. It is hosted by CodePlex.

Administration

About

Powered by:
BlogEngine.Net
Version: 1.6.1.0

License:
Creative Commons License

Copyright:
© Copyright 2013, Klaus Graefensteiner.

Disclaimer:
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Theme design:
This blog theme was designed and is copyrighted 2013 by Klaus Graefensteiner

Rendertime:
Page rendered at 5/24/2013 11:08:52 AM (PST Pacific Standard Time UTC DST -7)