Path Copy Copy

by Administrator 30. Dezember 2011 05:34

... adds a context menu to the explorer that allows to copy the path to a file/folder to the clipboard. Really nice, get it here.

Tags:

Tools

Creating a NUnity activity for TFS 2010 Build

by Administrator 30. Dezember 2011 04:42

TFS build is really nice - I used to work with CruiseControl.NET / NAnt before and having not to work with angle brackets and debug logs all the time makes your job so much easier. If you stick to Microsoft tools, you'll find that lots of activities for your build are already there, if you want something else, it's really easy to implement your own. In our project we decided to go with NUnit instead of MSTest for several reasons. There is no standard activity to run NUnit tests inside a build process, however the Community TFS Build Extensions project offers such a thing.

I found that there are some things I would like to have different when running Unit tests an decided to roll my own activity for that matter. You'll find the source attached to this post. I do not intend to maintain a project here or contribute to the community project, however I hope you'll find some interesting insights on how to create your own activities.

The first thing that I wanted differently was the ability to run multiple unit tests at once. Since unit tests are independent of each other by definition and most build servers will have multiple cores one should see a great performance boost when doing that. TFS Build is built on top of Windows Workflow Foundation. There is a container that you can drop activities into that should run in parallel, however when placing several NUnit activities in it you'll see that they run sequentially nevertheless. The reason for that is, that workflow foundation has a concept of an idle state in activities. When an activity reaches a point in it's execution where it cannot do anything until something happened (e.g. a download finished, an executable completed...), it signals it's idle state to the workflow runtime and other activities in a container marked for parallel execution may get a time slice.

Activities that support idleness inherit from another base class and use the Begin/End idiom used in .NET. Here is an extract of the entry method of the activity:

protected override IAsyncResult BeginExecute( AsyncCodeActivityContext context, AsyncCallback callback, object state )
{
  // ...Initialization code
  Func<ExecutionContext> execution =
    () =>
    {
      ... here goes the code that takes some time...
    };
   
  context.UserState = execution;
  return execution.BeginInvoke( callback, state );
}

The actual thing the we consider being the idle state is when NUnit runs and we wait for it's return. You will see that the code inside the execution function with the NUnit process being launched:

process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();

The Start() method does not wait for the process to return. To wait, you use the WaitForExit() method. Now let's look at the method that ends the asynchronous call:

protected override bool EndExecute( AsyncCodeActivityContext context, IAsyncResult result )
{
   Func<ExecutionContext> execution = ( Func<ExecutionContext> )context.UserState;
   ExecutionContext executionContext = execution.EndInvoke( result );
   executionContext.Process.WaitForExit();
}

As you see the UserState is used to marshal state in between the two methods. The ExecutionContext is a class by me that holds information about the process being launched.

With this construct in place you will be able to run several NUnit activities in a parallel block. The next thing that somehow bogged me was, that when publishing tests results to the build, you will not see to which project tests belong:

Neither the link to get to the test results, nor the results themselves indicated the test solution. This was a little annoying to me. I started off with the XSLT document from the community project (included with the ZIP) to transform the nunit xml output to the mstest xml format. There is a name attribute on the root of the mstest that contains the name. I injected that via XLinq (I'm not really into XSLT and want it to stay that way :P).

XDocument document = XDocument.Load( memoryStream );
document.Root.Attribute( "name" ).Value = Path.GetFileNameWithoutExtension( Project.Get( context ) );

The above code takes the XSL transformed document and injects the value of the node.

At this point I had everything I needed in place, however I found out that sometimes publishing the results of the tests failed. I did not notice the problem with the community activiy, however I came to the conclusion that the same might happen here - though more seldomly. This article pointed me to the right direction. An MSTest file contains a GUID that needs to be unqiue among tests in a build. If it's not and you publish another test with the same GUID, you will get an error that the results have already been published. Peeking into the XSLT i found out that the GUID is generated from a fixed part and a part that depends on the current time (down to the second). This causes problem when you execute multiple tests runs in the same second - highly unlikely when synchronous, highly likely when asynchronous. I injected a new GUID to prevent clashes.

XDocument document = XDocument.Load( memoryStream );
document.Root.Attribute( "id" ).Value = Guid.NewGuid().ToString();

That's all I wanted to show. Thanks again to the guys that did the community project - I would not have done this without them.

NUnitActivity.zip (7,10 kb)

Tags: , , ,

My Stuff | Projects | TFS

Using Appmd.exe to configure IIS

by Administrator 23. Dezember 2011 11:22

Alright, I found this article on how to configure the IIS loadbalancer via commandline. I've gotta say:

Guys - Posting code snippets that do not work? NOT COOL!

appcmd.exe set config –section:webFarms /+[name=serverFarmName] /commit:apphost

I really expect to be able to copy&paste such stuff, especially when dealing with such cryptic commands. Thanks for wasting half an hour of my life Cry

Using normal quoutes/apostrophes the stuff actually works.

Tags:

General

NUnit Tests in TFS Build

by Administrator 14. Dezember 2011 07:13

By default TFS only integrates MSTest unit tests directly, however there is the Community TFS Extensions project that offers a NUnit activity. There's one quite annoying flaw hower. In most builds you probably want to make the build fail when unit tests fail. The activity offers a FailBuildOnError property, that I expected to do the job but I guess this one means that the build should fail if NUnit cannot be invoked properly.

What you can do is count failures and errors in unit tests and then make the build fail if there are any. NUnit distinguishes failed unit tests (assertions not met) from failures (exceptions).

I created three local variables, one that accumulates error and failures and two the take the result for errors and failures for an individual NUnit run:

Right after each unit test I add up the total fail count:

TotalFailedUnitTests + FailedUnitTests + ErrorUnitTests

At the end I put an If block that throws an exception when the count is greater 0.

New Microsoft.TeamFoundation.Build.Workflow.Activities.BuildProcessException("The Build failed with " & TotalFailedUnitTests.ToString() & " broken unit tests.")

Tags:

TFS

Migrating TFS to another Server and Team Foundation Build Notification

by Administrator 14. Dezember 2011 03:12

Either I missed this part when doing the steps to move to another server or it was really not mentioned. Migrating a TFS 2010 intance to another server is quite easy. You basicly make backups of the databases and run some commandline tools to make the new instances your new home. However I noticed that the Build Notification Tool still redirected me to the old server when clicking the window.

I finally found this article that pointed me to the right direction.

Another step in addition to these commandline things Microsoft suggests in it's migration script you have to adjust the url in the TFS administration console:

For some reason this did not work directly but just the next day when I rebooted.

Tags: , ,

TFS

Nancy Json Response Size Limits

by Administrator 12. Dezember 2011 14:43

I noticed that Response.AsJson causes errors with larger responses - first I was quite sure to have spotted a flaw, but this is intentional. There are two limits you can set for JSON objects, the total size and the recursion depth. You can set those via

Nancy.Json.JsonSettings.MaxJsonLength = <length in bytes>;
Nancy.Json.JsonSettings.MaxRecursions = <recursion depth>;

I guess the intention is similar to the limits on messages in WCF. Unfortunately there is no real reference documentation for Nancy at this point so it takes some time to dig such stuff out. I hope this will change in the future since this project is really well made and the team is great on supporting in their forums.

I'll add this to SoapWatch when I find time.

Tags: , ,

C#

SoapWatch

by Administrator 3. Dezember 2011 11:34

I added a small article about a little one day project that I used to fiddle around with Nancy and FiddlerCore.Check it out here.

Tags: , , ,

C# | My Stuff | Wcf

Mocking the UrlHelper in MVC

by Administrator 2. Dezember 2011 03:18

This took me some time to find out but it's actually quite easy. I wanted to test a method that calls IsLocalUrl on the UrlHelper class provided by MVC. The bad news is that there does not seem to be a good way to replace the class as a whole, however there is an easy way to get what you need. The following code is done for RhinoMocks but you should easily be able to use it with other mocking frameworks as well:

UrlHelper m_UrlHelper = new UrlHelper( new RequestContext(){HttpContext = m_Mock.PartialMock<HttpContextBase>()});
using( m_Mock.Record() )
{
  m_UrlHelper.RequestContext.HttpContext
     .Expect( context => context.Request.Url )
     .Repeat.Any()
     .Return( new Uri( "http://PC/DevUIWeb" ) );
}

The key takeaway here is, that the url helper itself does not provide it's methods as virtual (thanks guys) and mocking is not possible out of the box. However you can mimic a real context by mocking the actual HttpContext object inside.

Tags: , ,

ASP.NET MVC | C#

About the author

for comments and suggestions contact:

 

Month List