Search code examples
c#automated-testsfunctional-testingmedium-trustfull-trust

How to Automate Testing of Medium Trust Code


I would like to write automated tests that run in medium trust and fail if they require full trust.

I am writing a library where some functionality is only available in full trust scenarios and I want to verify that the code I wish to run in medium trust will work fine. If also want to know that if I change a class that requires full trust, that my tests will fail.

I have tried creating another AppDomain and loading the medium trust PolicyLevel, but I always get an error with assembly or its dependency could not be loaded while trying to run the cross AppDomain callback.

Is there a way to pull this off?

UPDATE: Based replies, here is what I have. Note that your class being tested must extend MarshalByRefObject. This is very limiting, but I don't see a way around it.

using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using Xunit;

namespace PartialTrustTest
{
    [Serializable]
    public class ClassUnderTest : MarshalByRefObject
    {
        public void PartialTrustSuccess()
        {
            Console.WriteLine( "partial trust success #1" );
        }

        public void PartialTrustFailure()
        {
            FieldInfo fi = typeof (Int32).GetField( "m_value", BindingFlags.Instance | BindingFlags.NonPublic );
            object value = fi.GetValue( 1 );
            Console.WriteLine( "value: {0}", value );
        }
    }

    public class Test
    {
        [Fact]
        public void MediumTrustWithExternalClass()
        {
            // ClassUnderTest must extend MarshalByRefObject
            var classUnderTest = MediumTrustContext.Create<ClassUnderTest>();

            classUnderTest.PartialTrustSuccess();
            Assert.Throws<FieldAccessException>( classUnderTest.PartialTrustFailure );
        }
    }

    internal static class MediumTrustContext
    {
        public static T Create<T>()
        {
            AppDomain appDomain = CreatePartialTrustDomain();
            var t = (T) appDomain.CreateInstanceAndUnwrap( typeof (T).Assembly.FullName, typeof (T).FullName );
            return t;
        }

        public static AppDomain CreatePartialTrustDomain()
        {
            var setup = new AppDomainSetup {ApplicationBase = AppDomain.CurrentDomain.BaseDirectory};
            var permissions = new PermissionSet( null );
            permissions.AddPermission( new SecurityPermission( SecurityPermissionFlag.Execution ) );
            permissions.AddPermission( new ReflectionPermission( ReflectionPermissionFlag.RestrictedMemberAccess ) );
            return AppDomain.CreateDomain( "Partial Trust AppDomain: " + DateTime.Now.Ticks, null, setup, permissions );
        }
    }
}

Solution

  • I just posted an article titled Partial Trust Testing with xUnit.net. It details the xUnit.net-based framework that we use on the Entity Framework team to exercise code under partial trust.

    Here is an example of its usage.

    public class SomeTests : MarshalByRefObject
    {
        [PartialTrustFact]
        public void Partial_trust_test1()
        {
            // Runs in medium trust
        }
    }
    
    // Or...
    
    [PartialTrustFixture]
    public class MoreTests : MarshalByRefObject
    {
        [Fact]
        public void Another_partial_trust_test()
        {
            // Runs in medium trust
        }
    }