Apr 30 2009

Getting InnerXML using XPath

Category: .NetRory Primrose @ 08:33

I previously posted about XML comments and the include element for documenting code in Visual Studio. I commented against that post that xpath queries should end in /*. This tells the query to select all child elements of the xml node identified. Unfortunately this does not cover all scenarios where external xml can be included in xml documentation.

Take the following xml for example.

<?xml version="1.0" encoding="utf-8"?>
<CommonDocumentation>
  <Remarks>
    <Remark name="FirstRemark">
      <para>
        This is a remark in a paragraph.
      </para>
    </Remark>
    <Remark name="SecondRemark">
        This is a remark with just text.
    </Remark>
    <Remark name="ThirdRemark">
      This is a remark with text and <b>xml elements</b>.
    </Remark>
  </Remarks>
</CommonDocumentation>

This xml is referenced by the include statements in the code below.

using System.Diagnostics;
 
namespace ClassLibrary1
{
    public class Class1
    {
        /// <summary>
        /// Does something random.
        /// </summary>
        /// <remarks>
        /// <include file="CommonDocumentation.xml" path="CommonDocumentation/Remarks/Remark[@name='FirstRemark']/*" />
        /// <include file="CommonDocumentation.xml" path="CommonDocumentation/Remarks/Remark[@name='SecondRemark']/text()" />
        /// <include file="CommonDocumentation.xml" path="CommonDocumentation/Remarks/Remark[@name='ThirdRemark']/node()" />
        /// </remarks>
        public void SomeRandomMethod()
        {
            Debug.WriteLine("Do something.");    
        }
    }
}

The code indicates the way in which the xpath queries will be able to correctly get the inner xml of the common documentation. Using a /* query against the SecondRemark or ThirdRemark nodes will produce incorrect results as the text will be ignored because /* only select element nodes. Using /text() against the FirstRemark and ThirdRemark nodes will also produce incorrect values as it will only select text nodes and ignore the element nodes.

The best solution is to use xpath queries that end in /node(). This will successfully select the inner xml of the target node regardless of the makeup of that xml. The xml can contain text, element nodes or a mixture.

Tags:

Apr 25 2009

Mocking a factory created instance to test its consumer

Category: .NetRory Primrose @ 19:26

I have faced a bit of a curly one tonight with a class that I want to unit test. Part of its implementation is to use an instance that is created from a factory class. To adequately test the class, I need to get the factory to return a mock. The factory class is a closed design so this is difficult to achieve. The factory does however use a configuration value to help it determine the concrete type to create.

The difficulty with this scenario is that Type.GetType (using the configuration value) isn’t able to load the mock type directly. The solution to this problem is to use a wrapper around the mock. In doing this, the type loaded by Type.GetType is a statically defined type that happens to hold a reference to the mocked object to which it simply forwards on the required calls.

Here is a slimmed down example.

using System;
using System.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
 
namespace TestProject1
{
    public class ClassToTest
    {
        public void SomethingToTest()
        {
            IDependency dependency = DependencyFactory.Create();
 
            if (string.IsNullOrEmpty(dependency.GetValue()))
            {
                throw new InvalidOperationException();
            }
        }
    }
 
    public interface IDependency
    {
        String GetValue();
    }
 
    public static class DependencyFactory
    {
        public const string DependencyTypeConfigurationKey = "DependencyType";
 
        public static IDependency Create()
        {
            Type dependencyType = Type.GetType(ConfigurationManager.AppSettings[DependencyTypeConfigurationKey]);
            return (IDependency)Activator.CreateInstance(dependencyType);
        }
    }
 
    [TestClass]
    public class UnitTest1
    {
        /// <summary>
        /// Runs test for something to test throws exception when dependency returns an empty value.
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void SomethingToTestThrowsExceptionWhenDependencyReturnsAnEmptyValueTest()
        {
            ConfigurationManager.AppSettings[DependencyFactory.DependencyTypeConfigurationKey] =
                typeof(DependencyMockWrapper).AssemblyQualifiedName;
            MockRepository mock = new MockRepository();
            IDependency dependency = mock.CreateMock<IDependency>();
 
            using (mock.Record())
            {
                dependency.GetValue();
                LastCall.Return(String.Empty);
            }
 
            ClassToTest target = new ClassToTest();
 
            using (mock.Playback())
            {
                DependencyMockWrapper.MockInstance = dependency;
                target.SomethingToTest();
            }
        }
    }
 
    public class DependencyMockWrapper : IDependency
    {
        public string GetValue()
        {
            return MockInstance.GetValue();
        }
 
        public static IDependency MockInstance
        {
            get;
            set;
        }
    }
}

The ClassToTest is, as the name suggests, the class being tested. It makes a call to DependencyFactory to create an instance of something for it to use. Ideally we want this to be the mock, however we need to settle for a static wrapper around a mock. The DependencyFactory consults configuration to determine the type to create and it instantiates the type and returns it.

The unit test uses the DependencyMockWrapper class so that it can be loaded at runtime via Type.GetType, but also allows the unit test to inject the mock into the wrapper before it is used. The unit test sets up configuration to point to the wrapper, creates the mock with its expectations, and injects the mock into the wrapper. The key here is that the MockInstance property on the wrapper must be a static as the factory returns a new instance which the unit test can’t control and it still needs a reference to the mock.

As the class under test invokes the dependency created from the factory, the dependency (being the wrapper) simply forwards the call on to the mock. This satisfies the expectations set up when recording the mock.

Tags:

Apr 23 2009

Saying goodbye to friends (for now)

Category: IT RelatedRory Primrose @ 10:44

I’m saying goodbye to some friends for a couple of weeks as I head back into the land of documentation.

Tags:

Apr 16 2009

Creating SCOM event collection records from database records

Category: .NetRory Primrose @ 11:52

SCOM supports collecting event records that can be reported on. It has inbuilt support for reading the Windows Event Log or a CSV file, but becomes limited beyond that. I played with the idea of getting SCOM to read records out from a database in order to populate these SCOM events. Unfortunately there is not much information on the net about how to get it to work.

The attached SCOM management pack shows an example of how to get this to work. It uses a Microsoft.Windows.TimedScript.EventProvider to read database records into a PropertyBag and to define how the database fields map to SCOM fields. A rule data source then points to the EventProvider and provides the configuration options for hitting the database.

A word of caution though, you need to be careful not to dump too much information into the SCOM data warehouse as it is not designed for collecting large amounts of event records in this manner.

Neovolve.ScomEvents.xml (17.32 kb)

Tags:

Apr 15 2009

Psexec hangs in TeamBuild script when invoking msiexec on remote machine

Category: .NetRory Primrose @ 04:15

I've come across this one a few times and I can never remember what the answer is off the top of my head.

We are getting the msbuild script to execute psexec to invoke msiexec on a host machine to install an msi compiled by the build script. This is done so that the build script can then execute integration and load tests on the deployed application.

In modifying the build script, it seems like I have accidentally changed the psexec arguments which has caused psexec to hang on the build agent. In this case, it is happening when -accepteula is not passed to psexec.

The build script should look like this for executing psexec -> msiexec.

<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
           BuildUri="$(BuildUri)"
           Id="$(DeployMsiBuildStepId)"
           Message="Uninstalling previous version from $(DeploymentServer)" />
 
<!-- Uninstall the existing MSI -->
<Exec Command="PsExec.exe -accepteula -s -i \\$(DeploymentServer) $(DeploymentServerCredentials) msiexec /x &quot;$(ProductCode)&quot; /quiet /lv+ &quot;$(DeploymentServerFolderLocal)\Uninstall$(DeploymentFileLog)&quot;"
      IgnoreExitCode="true"
      ContinueOnError="true"
      Timeout="300000" />
 
<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
           BuildUri="$(BuildUri)"
           Id="$(DeployMsiBuildStepId)"
           Message="Installing new version $(DeploymentServer)" />
 
<!-- Install the MSI -->
<Exec Command="PsExec.exe -accepteula -s -i \\$(DeploymentServer) $(DeploymentServerCredentials) msiexec /i &quot;$(DeploymentServerFolderLocal)\$(DeploymentFile)&quot; TRANSFORMS=&quot;$(DeploymentServerFolderLocal)\$(DeploymentTransformFile)&quot; /quiet /lv+ &quot;$(DeploymentServerFolderLocal)\Install$(DeploymentFileLog)&quot;"
      IgnoreExitCode="false"
      ContinueOnError="false"
      Timeout="300000" />
 
<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
           BuildUri="$(BuildUri)"
           Id="$(DeployMsiBuildStepId)"
           Status="Succeeded" />

Tags: ,

Apr 11 2009

AOP with PostSharp.Laos

Category: .NetRory Primrose @ 10:17

PostSharp.Laos is a Lightweight Aspect-Orientated System for PostSharp that makes it really easy to include AOP in your code. In this demo, PostSharp will be used to aspect the RunTest() method in the following application. The aspect will output console messages before and after the aspected method is executed.

using System;
 
namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            RunTest();
 
            Console.ReadKey();
        }
 
        private static void RunTest()
        {
            Console.WriteLine("Running the test method");
        }
    }
}

Project references required

The project requires PostSharp.Public.dll and PostSharp.Laos.dll references in order to create an aspect attribute.

image

As you can see, I also added in a strong name key to see if it caused any issues with PostSharp. It didn’t.

Code required

I know that PostSharp.Laos is easy to use in comparison to PostSharp.Core, but I was honestly shocked at just how easy it really is. To put this demo together, it look somewhere in the order of two minutes.

In order to aspect the RunTest method in the code defined above, an OnMethodInvocationAspect derived attribute was created for the aspect and declared against the RunTest method.

using System;
using PostSharp.Laos;
 
namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            RunTest();
 
            Console.ReadKey();
        }
 
        [MethodTraceAspect]
        private static void RunTest()
        {
            Console.WriteLine("Running the test method");
        }
    }
 
    [Serializable]
    internal class MethodTraceAspectAttribute : OnMethodInvocationAspect
    {
        public override void OnInvocation(MethodInvocationEventArgs context)
        {
            try
            {
                Console.WriteLine("Calling {0}", context.Delegate.Method);
 
                context.Proceed();
            }
            finally
            {
                Console.WriteLine("Called {0}", context.Delegate.Method);
            }
        }
    }
}

PostSharp will find the MethodTraceAspect attribute on the RunTest method and change the IL so that the OnInvocation method of the attribute is invoked instead of the RunTest method. The context.Proceed() method in the attribute then invokes the RunTest method.

IL result

PostSharp kicks in after the original code has been compiled and changes the IL to include the aspect. Reflector shows the following outcome as the combination of the compiler and PostSharp doing their work.

using System.Reflection;
using System.Runtime.CompilerServices;
using PostSharp.Laos;
 
namespace ConsoleApplication1
{
    internal class Program
    {
        [CompilerGenerated]
        static Program()
        {
            if (!~PostSharp~Laos~Implementation.initialized)
            {
                LaosNotInitializedException.Throw();
            }
            ~PostSharp~Laos~Implementation.~targetMethod~1 = methodof(Program.RunTest);
            ~PostSharp~Laos~Implementation.MethodTraceAspectAttribute~1.RuntimeInitialize(~PostSharp~Laos~Implementation.~targetMethod~1);
        }
 
        private static void ~RunTest()
        {
            Console.WriteLine("Running the test method");
        }
 
        private static void Main(string[] args)
        {
            RunTest();
            Console.ReadKey();
        }
 
        [DebuggerNonUserCode, CompilerGenerated]
        private static void RunTest()
        {
            Delegate delegateInstance = new ~PostSharp~Laos~Implementation.~delegate~0(Program.~RunTest);
            MethodInvocationEventArgs eventArgs = new MethodInvocationEventArgs(delegateInstance, null);
            ~PostSharp~Laos~Implementation.MethodTraceAspectAttribute~1.OnInvocation(eventArgs);
        }
    }
 
    [Serializable]
    internal class MethodTraceAspectAttribute : OnMethodInvocationAspect
    {
        public override void OnInvocation(MethodInvocationEventArgs context)
        {
            try
            {
                Console.WriteLine("Calling {0}", context.Delegate.Method);
                context.Proceed();
            }
            finally
            {
                Console.WriteLine("Called {0}", context.Delegate.Method);
            }
        }
    }
}
 
[CompilerGenerated]
internal sealed class ~PostSharp~Laos~Implementation
{
    internal static MethodBase ~targetMethod~1;
    internal static bool initialized;
    internal static readonly MethodTraceAspectAttribute MethodTraceAspectAttribute~1;
 
    static ~PostSharp~Laos~Implementation()
    {
        try
        {
            object[] objArray = (object[]) Internals.DeserializeFromResource(typeof(~PostSharp~Laos~Implementation).Assembly, "~PostSharp~Laos~CustomAttributes~");
            MethodTraceAspectAttribute~1 = (MethodTraceAspectAttribute) objArray[0];
            initialized = true;
        }
        catch (Exception exception)
        {
            Debugger.Log(30, "PostSharp", exception.Message);
            throw;
        }
    }
 
    [Serializable]
    public delegate void ~delegate~0();
}
 

The important part to note is that the contents of RunTest() have been moved into ~RunTest() and have been replaced with a call to MethodTraceAspectAttribute.OnInvocation. A delegate to ~RunTest() is passed in the arguments to OnInvocation so that the aspect can then invoke the original method.

Compiled assembly references

After PostSharp has finished weaving the aspect into the IL, the assembly still has a reference to PostSharp.Laos.dll and PostSharp.Public.dll.

Debugging support

Debugging the assembly after it has been aspected is seamless. When the Main method invokes RunTest(), the debugger steps into the MethodTraceAspectAttribute.OnInvocation method. Stepping into context.Proceed() takes you into the RunTest() method in the source code (which is actually ~RunTest in the compiled assembly). Stepping out of RunTest takes you back into the MethodTraceAspectAttribute.OnInvocation method.

Runtime result

Result

License implications

My understanding of the PostSharp license (read here and here) is that this implementation does not require a commercial license as PostSharp.Core.dll does not need to be bundled with the application for distribution.

Advantages

PostSharp.Laos is very easy to use. So easy in fact that I am surprised this product isn’t much more famous than it already is. Something this powerful that is so easy to use is a major advantage especially because it can be implemented for free.

Disadvantages

There are several disadvantages using PostSharp.Laos. The importance of each of these disadvantages will depend on your unique scenario.

  • The final assembly requires references to PostSharp.Laos.dll and PostSharp.Public.dll.
    • The requirement for the two PostSharp assemblies to be shipped may be an issue because of increased packaging and dependencies. I prefer projects to be as clean and lean as possible so the less references the better.
  • The reference to the aspected method identifies it as ~RunTest rather than RunTest
    • The changed name of the aspected method is only going to be an issue when the aspect implementation does something with that name. Tracing the method name (as in the case of this demo) may create confusion. The aspect could strip the leading ~, however no assumption about such a behaviour from PostSharp should be made.
  • The IL isn’t very clean with all the code used to redirect the RunTest method invocation through the aspect.
    • If you spend a lot of time in Reflector, the IL generated for the RunTest implementation will be a little confusing especially if compared against the original source code.

Conclusion

Wow, this is an unbelievable product. If you want to get some easy advantages out of AOP and don’t mind the few disadvantages stated above, then PostSharp.Laos is your new best friend.

Tags: , , , , ,

Apr 11 2009

AOP with PostSharp

Category: .NetRory Primrose @ 09:18

PostSharp is a very power AOP framework. It changes the IL emitted from the compiler according to the aspects that it finds. The way PostSharp can be implemented ranges from very easy to very complex.

The demos in this series will look at a very simple scenario. PostSharp will be used to aspect the RunTest() method in the following code. The aspect used will output console messages surrounding the RunTest method.

using System; 

namespace ConsoleApplication1 
{ 
    internal class Program 
    { 
        private static void Main(string[] args) 
        { 
            RunTest(); 
            Console.ReadKey(); 
        } 
        private static void RunTest() 
        { 
            Console.WriteLine("Running the test method"); 
        } 
    } 
} 

Two different implementations of the demo will be run. One with PostSharp.Laos (the easy part) and the other with PostSharp.Core (the hard part). The outcome of each demo will look at the:

  • references required by the project
  • difficulty of code required
  • impact on the IL of the final assembly
  • references required on the final assembly
  • debugging experience

Tags: , , ,

Apr 8 2009

Styles of AOP

Category: .NetRory Primrose @ 18:55

There are many AOP frameworks around and they all use one of just a few techniques to inject code into join points. Oren has previously posted a list of these types of AOP techniques with their advantages and disadvantages. This list is copied below for reference:

# Approach Advantages Disadvantages
1 Remoting Proxies Easy to implement, because of the .Net framework support Somewhat heavy weight
Can only be used on interfaces or MarshalByRefObjects
2 Deriving from ContextBoundObject Easiest to implement
Native support for call interception
Very costly in terms of performance
3 Compile-time subclassing
( Rhino Proxy )
Easiest to understand
Interfaces or virtual methods only
4 Runtime subclassing
( Castle Dynamic Proxy )
Easiest to understand
Very flexible
Complex implementation (but already exists)
Interfaces or virtual methods only
5 Compile time IL-weaving
( Post Sharp / Cecil )
Very powerful
Good performance
Very hard to implement
6 Runtime IL-weaving
( Post Sharp / Cecil )
Very powerful
Good performance
Very hard to implement
7 Hooking into the profiler API
( Type Mock )
Extremely powerful Performance?
Complex implementation (COM API, require separate runner, etc)

What I want in an AOP framework is for it to not be limited to interfaces and virtual methods (1, 3, 4) and preferably to not require decorating types in order to support an AOP framework (1, 2). It also needs to perform well and preferably be free.

My requirements seem to sit in between the easy to implement but not very powerful at one end (1, 2, 3, 4) and incredible powerful but hard to implement or with performance implications on the other (7). PostSharp sits nicely with my requirements. Compile time IL weaving with PostSharp is hard to implement whereas runtime weaving (PostSharp.Laos - redirecting runtime method calls by compile time weaving) is a lot easier.

I will publish a post for each of the two PostSharp methods and indicate their coding differences, IL impact and license considerations.

On a side note, TypeMock recently released an open AOP API for open source projects.

Tags: , ,

Apr 8 2009

TeamBuild: Custom build steps

Category: .NetRory Primrose @ 11:30

I've been working with team build a fair bit over the last month. Yesterday I was bouncing through the MSDN documentation during my MSBuild travels and I came across a very handy build task. The BuildStep task allows you to create custom entries in the build report.

Take the following build target for example:

<Target Name="RunIntegrationTests">
 
  <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
             BuildUri="$(BuildUri)"
             Name="Running integration tests"
             Message="Updating integration test configuration">
    <Output TaskParameter="Id"
            PropertyName="IntegrationTestsBuildStepId" />
  </BuildStep>
 
  <CallTarget Targets="UpdateIntegrationTestConfiguration" />
 
  <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
             BuildUri="$(BuildUri)"
             Id="$(IntegrationTestsBuildStepId)"
             Message="Executing integration tests" />
 
  <CallTarget Targets="ExecuteIntegrationTests" />
 
  <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
             BuildUri="$(BuildUri)"
             Id="$(IntegrationTestsBuildStepId)"
             Status="Succeeded" />
 
</Target>

The BuildStep tasks have allowed the build report to include custom steps that are being executed. In this case, it is reporting on the progress of running integration tests.

image

You can also see that this report contains a custom build step for working with Sandcastle documentation.

This is a very easy to use task that adds rich information to your build reports. It is especially useful for when custom targets fail. Take the case of automated deployment that occurs before running integration tests. If the target is invoked by the inbuilt test targets (probably by overriding AfterTest), then it will be unclear which part of the build broken if the deployment target fails without trawling through the build log. With custom build steps, the report can identify that deployment broke rather than because of running tests.

Tags: , , ,

Apr 6 2009

TFS pet hate - changes should be for changes

Category: .NetRory Primrose @ 05:11

I love TFS, but there is one thing that grates me. Check ins with no changes are very frustrating. I'm reviewing a branch for a service and half the edit and merge changes don't have changes. It's not a big deal, but it would be good if the "noise" in the change sets wasn't there.

Tags: