# Monday, November 29, 2004

TestDriven.NET 1.0 is released on www.testdriven.net (MbUnit ships with TD.NET). Check out the brand new web site!   

You are a TD.NET user ? Use the link builder and add a cool image like this one on your blog or web site...TestDriven.NET

posted on Monday, November 29, 2004 4:49:00 PM (Pacific Standard Time, UTC-08:00)  #    Comments [14]
# Sunday, November 28, 2004

The next version (greater than 1.0.903d) contains a bunch of decorators that will deny access to file, file dialog, sql client, oracle client, etc... The decorators are located in the MbUnit.Framework.1.1.dll in the MbUnit.Framework.Security namespace.

For example you can deny access to the SqlClient using the following:

using MbUnit.Core.Framework;
using MbUnit.Framework;
using MbUnit.Framework.Security;
[TestFixture]
public class MyFixture
{
    [Test]
    [DenySqlClient]
    public void AccessDatabase()
    {
        // access to SQL client will fail in this method.
    }
}
posted on Sunday, November 28, 2004 4:49:00 PM (Pacific Standard Time, UTC-08:00)  #    Comments [11]

I have added 2 new improvements to MbUnit to avoid having tests blocked by assertions or timeouts:

  • Assertion dialog caused by Debug.Assert are automatically swallowed (by removing the default debug trace)
  • TimeOut (in minutes) can be set at the fixture level:
[TestFixture(TimeOut = 1)]
public class MyFixture{...}

Those changes will be available in release greater than 1.0.903

posted on Sunday, November 28, 2004 4:24:00 PM (Pacific Standard Time, UTC-08:00)  #    Comments [3]
# Friday, November 26, 2004

Question: So you are using files in your application, how do you test easily how it behaves if the file access is denied ?
Answer: Use declarative permissions to deny all access on the files

Ok that's a rough introduction, let me develop the idea. When your application relies on using resources such as files, TcpChannels, registry, etc... you should test how it behaves when the access to those resources is refused. The resource denial can be caused by a lot of external factors (loss of connectivity, etc...), lack of physical resources, .... or by denied security permissions. In other words, security permissions is an easy way to simulate various situations such as file access error, etc... 

Let me illustrate this by implementing a test decorator for MbUnit that makes all file access diened.

Creating DenyFileIOAccess decorator

As all test decorators, we derive a new attribute class from MbUnit.Core.DecoratorPatternAttribute and a new IRunInvoker from DecoratorRunInvoker:

using System;
using System.Security.Permissions;
using System.Collections;
using MbUnit.Core.Invokers;
using MbUnit.Core.Framework;
namespace MbUnit.Framework.Security
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple  = false, Inherited =true)]
    public sealed class DenyFileIOAccessAttribute : DecoratorPatternAttribute
    {
        public override IRunInvoker GetInvoker(IRunInvoker invoker)
        {
            return new DenyFileIOAccessRunInvoker(invoker, this);
        }
        private sealed class DenyFileIOAccessRunInvoker : DecoratorRunInvoker
        {
            private DenyFileIOAccessAttribute attribute;
            public DenyFileIOAccessRunInvoker(
                IRunInvoker invoker,
                DenyFileIOAccessAttribute attribute)
                :base(invoker)
            {
                this.attribute = attribute;
            }
            [FileIOPermission(SecurityAction.Deny, AllFiles = FileIOPermissionAccess.AllAccess)]
            public override object Execute(Object o, IList args)
            {
                return this.Invoker.Execute(o, args);
            }
        }
    }
}

The important thing to notice in the snippet is the FileIOPermission attribute that tags the execute method. All the code executed inside that method will have file IO denied. So since Invoker.Execute calls the test method, we have what we are looking for.

DenyFileIOAccessAttribute in action

Let put the new decorator in action. The following snippet shows a simple test that tries to create a new file. The execution log using TestDriven.NET is outputed below. As one can see, a SecurityException was raised by the framework when trying to open the file.... it's magic.

using System;
using System.IO;
using MbUnit.Framework;
using MbUnit.Framework.Security;
namespace MbUnit.Demo
{
    [TestFixture]
    public class SecurityTest
    {
        [Test]
        [DenyFileIOAccess]
        public void SecureMethod()
        {
            using (StreamWriter writer = new StreamWriter("test.txt"))
            {
                writer.Write("we should not be here");
            }
        }
    }
}

-- output

------ Test started: Assembly: MbUnit.Tests.1.1.dll ------
Info: Test Execution
Info: Exploring MbUnit.Tests.1.1, Version=1.0.1791.9801, Culture=neutral, PublicKeyToken=null
Info: MbUnit 2.22.0.0 Addin
Info: Found 1 tests
Info: [failure] SecurityTest.SecureMethod
TestCase 'SecurityTest.SecureMethod' failed: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
 System.Security.SecurityException
 Message: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
 Source: mscorlib
 StackTrace:
 at System.Security.CodeAccessSecurityEngine.Check(PermissionToken permToken, CodeAccessPermission demand, StackCrawlMark& stackMark, Int32 checkFrames, Int32 unrestrictedOverride)
 at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
 at System.Security.CodeAccessPermission.Demand()
 at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
 at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
 at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
 at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
 at System.IO.StreamWriter..ctor(String path)
 \securitytest.cs(22,0): at MbUnit.Demo.SecurityTest.SecureMethod()
0 succeeded, 1 failed, 0 skipped, took 0.00 seconds.

---------------------- Done ----------------------

This methodology applies to the other types of permissions that can be found in the System.Security namespace.

Where can I get those ?

MbUnit will soon contain a few other of those attributes. Since it is a .Net 1.1 feature, they will be enclosed in the MbUnit.Framework.1.1.dll under the MbUnit.Security namespace.

posted on Friday, November 26, 2004 3:07:00 AM (Pacific Standard Time, UTC-08:00)  #    Comments [3]
# Tuesday, November 23, 2004

Reflector.CodeMetrics is a new Addin for Reflector that analyses and computes several code quality metrics on your assemblies. This addin uses the excellent Reflector API to compute classic metrics such as the cyclomatic complexity or more straightforward such as the number of local variables in a method. All results can be dumped to file (using DataSet.Save)

Download Reflector.CodeMetrics (look for Reflector.CodeMetrics.zip) For installation and usage instructions, please read the Readme.txt enclosed in the zip file.

Tip: when you explore the result, you can doubleclick on the border of the row to show the item in the decompiler

 

posted on Tuesday, November 23, 2004 12:21:00 PM (Pacific Standard Time, UTC-08:00)  #    Comments [14]
# Wednesday, November 17, 2004

This is a preview of a new Reflector Addin that computes various CodeMetrics on .Net assemblies. The excellent Reflector API makes it very easy to do this kind of things. Here are the metrics that I plan to implement :

  • Counting metrics: Module/Assembly, Type/Module, Method/Type, etc...
  • IL counting metrics: IL/Method, LocalVariables/Method, ExceptionHandlers/Method, etc...
  • IL flow graph metrics: components, cyclomatic complexity,
  • Method graph: methodrank, callers, callees, components, distance from entry point,
  • Type graph: type rank, inherance level, etc...

I have not done an extensive research on the subject so I might forget a lot of them, suggestions and links welcome.

Note that this uses a plugin architecture so that anyone can write and use his own metric.

Screenshot:

posted on Wednesday, November 17, 2004 6:50:00 PM (Pacific Standard Time, UTC-08:00)  #    Comments [18]
posted on Wednesday, November 17, 2004 2:55:00 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
# Monday, November 15, 2004
posted on Monday, November 15, 2004 2:48:00 PM (Pacific Standard Time, UTC-08:00)  #    Comments [3]