Pregunta

Me gustaría escribir pruebas automáticas que se ejecutan en la confianza mediano y fallan si requieren plena confianza.

Estoy escribiendo una biblioteca en la que algunas funciones sólo está disponible en los escenarios de plena confianza y quiero verificar que el código que desea ejecutar en fideicomiso medio no tendrán ningún problema. Si también quieren saber que si cambio de una clase que requiere plena confianza, que mis pruebas fallarán.

He intentado crear otro dominio de aplicación y cargar el PolicyLevel de confianza medio, pero siempre me sale un error de montaje o su dependencia no se pudo cargar al intentar ejecutar la devolución de llamada dominio de aplicación transversal.

¿Hay una manera de sacar esto adelante?

Actualizar : Basado respuestas, aquí es lo que tengo. Tenga en cuenta que su clase está probando debe extenderse MarshalByRefObject. Esto es muy limitante, pero no veo una manera de evitarlo.

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 );
        }
    }
}
¿Fue útil?

Solución

Me acaba de publicar un artículo titulado confianza parcial Las pruebas con xUnit.net . Se detalla la estructura basada en xUnit.net que utilizamos en el equipo de Entity Framework para ejercer código bajo de confianza parcial.

Aquí es un ejemplo de su uso.

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
    }
}

Otros consejos

robado Desvergonzadamente de Cómo recibir un parcial Confianza Sandbox - # 7 , pero reimplementado (junto con un caso simple prueba) en Fa #, sólo por diversión: -)

open System
open System.Reflection
open System.Security
open System.Security.Permissions
open System.Security.Policy

type Program() =
    inherit System.MarshalByRefObject()
    member x.PartialTrustSuccess() =
        Console.WriteLine("foo")
    member x.PartialTrustFailure() =
        let field = typeof<Int32>.GetField("m_value", BindingFlags.Instance ||| BindingFlags.NonPublic)
        let value = field.GetValue(1)
        Console.WriteLine("value: {0}", value)

[<EntryPoint>]
let main _ =
    let appDomain =
        let setup = AppDomainSetup(ApplicationBase = AppDomain.CurrentDomain.BaseDirectory)
        let permissions = PermissionSet(null)
        permissions.AddPermission(SecurityPermission(SecurityPermissionFlag.Execution)) |> ignore
        permissions.AddPermission(ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)) |> ignore
        AppDomain.CreateDomain("Partial Trust AppDomain", null, setup, permissions)

    let program = appDomain.CreateInstanceAndUnwrap(
                      typeof<Program>.Assembly.FullName,
                      typeof<Program>.FullName) :?> Program

    program.PartialTrustSuccess()

    try
        program.PartialTrustFailure()
        Console.Error.WriteLine("partial trust test failed")
    with
        | :? FieldAccessException -> ()

    0

Y una versión de C #:

using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;

namespace PartialTrustTest
{
    internal class Program : 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);
        }

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

        static void Main(string[] args)
        {
            AppDomain appDomain = CreatePartialTrustDomain();

            Program program = (Program)appDomain.CreateInstanceAndUnwrap(
                typeof(Program).Assembly.FullName,
                typeof(Program).FullName);

            program.PartialTrustSuccess();

            try
            {
                program.PartialTrustFailure();
                Console.Error.WriteLine("!!! partial trust test failed");
            }
            catch (FieldAccessException)
            {
                Console.WriteLine("partial trust success #2");
            }
        }
    }
}
 C:\temp\PartialTrustTest\bin\Debug>PartialTrustTest.exe
 partial trust success #1
 partial trust success #2

He publicado una entrada de blog de tres partes sobre la unidad de pruebas de confianza medio

Me giro a un dominio de aplicación alternativa de una manera similar a algunas respuestas aquí, pero ir más lejos mediante el uso de un MarshalByRefObject para invocar el método de ensayo en el otro dominio de aplicación, es decir, sus clases de prueba no es necesario para poner en práctica MarshalByRefObject

Parte tres (que contiene enlaces a las otras partes) es aquí http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with -nunitpart de tres-umbraco-marco-prueba /

Nunca he intentado hacerlo, pero, en general, para manejar errores de carga de ensamblaje de dominios de aplicación personalizada, puede utilizar el evento AppDomain.AssemblyResolve.

Aunque sin relación alguna, esto es un ejemplo del uso de dominio de aplicación. AssemblyResolve .

La respuesta depende de lo que hace su código cuando alguien con privilegio de confianza medio intenta acceder a una función plena confianza. Asumo que será lanzado algún tipo de excepción.

En ese caso, escribir una prueba de unidad que funciona en el contexto de confianza medio, los intentos de acceder a una función plena confianza, y espera que la excepción sea lanzada. Si usted nunca ha escrito una prueba como esta, una forma común de hacerlo que la mayoría de los marcos de prueba apoyarán es la siguiente:

testMediumTrustUserWontAccessFeatureX()
{
    // set up the context of your test ...

    try
    {
        accessFullTrustFeature();
        fail("Test failed - Medium trust user can access full trust feature");
    }
    catch( SomeKindOfException e )
    {
        // Success - feature was denied to the untrusted user 
    }
}

Si se detecta la excepción, significa que su usuario no es de confianza no llegó a acceder a la función (y se pasa la prueba), pero si la excepción no se detecta, la prueba falla (que esperábamos una excepción y no la conseguí ).

Este es el pseudo código java-esque pero este patrón se debe trabajar en cualquier idioma que está utilizando suponiendo que apoyan el manejo de excepciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top