Use powershell to integrate fitnesse suite testing on Azure VM

I need to trigger Fitnesse test suite and get result in Teamcity build. But the Fitnesse server is different with Teamcity server and I don’t want to install Teamcity Agent on Fitnesse server. And both servers are on Azure VM.

My plan is using Powershell to trigger Fitnesse test suite and retrieve result through HTTP request. The HTTP Uri I used is like: http://%FitnesseServer%/%TestSuite%?suite&format=xml

At the beginning, I use Invoke-WebRequest to send http request. That works well in the suite which execute less than 5 minutes. But once the suite going longer, WebException: “The operation has timed out” is thrown and my Powershell scripting failed to complete.

After further investigation, I found the problem is that Fitnesse will not response anything before the whole suite test is complete. That will hit a lot of timeout mechanism in System.Net.

Then I rewrite my script by using System.Net objects directly, and set all the Timeout properties of HttpWebRequest and related ServicePoint to a proper time. But the ‘timed out’ issue still occur. That move my eye on server side rather than client side.

At last I find that Azure Load Balance has an ‘idle timeout’ setting of 4 minutes. That means if your connection is idle for 4 minutes, Azure may not maintain the connection between service and your application. So the solution is using $request.ServicePoint.SetTcpKeepAlive() to send keep-alive packet during idle time.

Please find the PowerShell script as below, hope that help you to handle similar scenario.


Param(
[parameter(Mandatory=$true)]
[string]
$Uri
)

[System.Net.ServicePointManager]::MaxServicePointIdleTime = 30*60*1000
$request = [System.Net.HttpWebRequest][System.Net.WebRequest]::Create($Uri)
$request.Method = “Get”
$request.KeepAlive = $true
$request.Timeout = 30*60*1000
$request.ReadWriteTimeout = 30*60*1000
$request.ProtocolVersion = [System.Net.HttpVersion]::Version11
$request.ServicePoint.ConnectionLeaseTimeout = 30*60*1000
$request.ServicePoint.MaxIdleTime = 30*60*1000
$request.ServicePoint.SetTcpKeepAlive($true,60*1000,30*1000)
try
{
$rp = [System.Net.HttpWebResponse]$request.GetResponse()
$stream = $rp.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$ret = $reader.ReadToEnd()
$stream.Close()
$reader.Close()
$rp.Close()
}
finally
{
if ($null -ne $stream)
{
$stream.Close()
}
if ($null -ne $reader)
{
$stream.Close()
}
if ($null -ne $rp)
{
$stream.Close()
}
}
$ret

The link which help me:

http://azure.microsoft.com/blog/2014/08/14/new-configurable-idle-timeout-for-azure-load-balancer/

http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s