# 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]
Tracked by:
"poker online" (poker online) [Trackback]
"virginpussy" (online) [Trackback]
Monday, June 06, 2005 2:53:03 AM (Pacific Daylight Time, UTC-07:00)
Can we do this with SQL to test lost database connectivity?
dru
Monday, June 06, 2005 2:53:03 AM (Pacific Daylight Time, UTC-07:00)
Yes you can using SqlClientPermission
Jonathan de Halleux
Monday, June 06, 2005 2:53:03 AM (Pacific Daylight Time, UTC-07:00)
See <a target="_new" href="http://blog.dotnetwiki.org/archive/2004/11/28/1305.aspx">http://blog.dotnetwiki.org/archive/2004/11/28/1305.aspx</a>
Jonathan de Halleux
Comments are closed.