Frage

Ich mag automatisierte Tests schreiben, die in mittlerer Vertrauenswürdigkeit ausgeführt werden und versagen, wenn sie voll Vertrauen erfordern.

Ich schreibe eine Bibliothek, in der einige Funktionen nur in voller Vertrauen Szenarien zur Verfügung, und ich möchte, um zu überprüfen, dass der Code, den ich in mittlerer Vertrauenswürdigkeit ausführen möchten wird funktionieren. Wenn Sie wollen auch wissen, dass, wenn ich ändern, um eine Klasse, die volles Vertrauen erfordert, dass meine Tests fehlschlagen wird.

Ich habe versucht, einen anderen AppDomain zu schaffen und das Medium Vertrauen Policy Laden, aber ich bekomme immer einen Fehler mit der Montage oder die Abhängigkeit konnte nicht geladen werden beim Versuch, das Kreuz AppDomain Rückruf auszuführen.

Gibt es eine Möglichkeit, diese ziehen aus?

UPDATE : Basierend Antworten, hier ist das, was ich habe. Beachten Sie, dass Ihre Klasse getestet werden müssen MarshalByRefObject verlängern. Dies ist sehr zu beschränken, aber ich habe keinen Weg, um es sehen.

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 );
        }
    }
}
War es hilfreich?

Lösung

Ich habe gerade gebucht einen Artikel mit dem Titel Testen mit xUnit.net . Es wird ausführlich auf das xUnit.net-basiertes Framework, das wir auf dem Entity Framework Team verwenden Code unter teilweiser Vertrauenswürdigkeit zu trainieren.

Hier ist ein Beispiel für seine Verwendung.

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

Andere Tipps

Schamlos von Wie ein Teil Vertrauen Sandbox Host - # 7 , aber neu implementiert (zusammen mit einem einfachen Testfall) in F # nur für Kicks: -)

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

Und eine C # Version:

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

Ich habe in Medium Trust auf Unit-Tests dreiteiligen Blog-Eintrag geschrieben

Ich spinne hier eine alternative AppDomain in ähnlicher Weise auf ein paar Antworten, aber nehmen Sie es weiter durch einen MarshalByRefObject mit dem Testverfahren in der anderen AppDomain, was bedeutet, Ihre Testklassen müssen nicht aufrufen MarshalByRefObject

implementieren

Der dritte Teil (Links zu den anderen Teilen enthalten) ist hier http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with -nunitpart-drei-umbraco-Rahmen-Tests /

Ich habe nie versucht, dies zu tun, aber im Allgemeinen, Montag Ladefehler von benutzerdefinierten AppDomains zu handhaben, können Sie das AppDomain.AssemblyResolve Ereignis verwenden.

Obwohl völlig unabhängig, hier ist ein Beispiel für AppDomain verwenden. AssemblyResolve .

Die Antwort hängt davon ab, was Ihr Code macht, wenn jemand mit Privileg Medium Vertrauen versucht, eine volles Vertrauen Funktion zuzugreifen. Ich gehe davon aus einer Art Ausnahme ausgelöst wird.

In diesem Fall einen Komponententest schreiben, die in Medium Vertrauenskontext ausgeführt wird, versucht, eine volle Vertrauen Funktion zuzugreifen, und erwartet, dass die Ausnahme ausgelöst werden. Wenn Sie noch nie einen Test wie diesen, ein gemeinsamer Weg, es zu tun, dass die meist Test-Frameworks unterstützen wird, ist dies geschrieben haben:

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

Wenn die Ausnahme gefangen wird, es bedeutet, dass Ihre nicht vertrauenswürdigen Benutzer die Funktion Zugang haben (und der Test bestanden wird), aber wenn die Ausnahme nicht abgefangen wird, schlägt der Test fehl (wir eine Ausnahme zu erwarten und es nicht bekommen ).

Dies ist Java-artige Pseudocode, aber dieses Muster sollte in Arbeit welcher Sprache Sie verwenden es Ausnahmebehandlung unterstützen angenommen wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top