Question

Je voudrais écrire des tests automatisés qui fonctionnent en fiducie moyen et échouent si elles exigent une confiance totale.

Je suis en train d'écrire une bibliothèque où une fonctionnalité est uniquement disponible dans les scénarios de confiance totale et je veux vérifier que le code que je veux courir en fiducie moyen fonctionnera bien. Si veulent aussi savoir que si je change une classe qui exige la pleine confiance que mes tests échoueront.

Je l'ai essayé de créer une autre AppDomain et le chargement du PolicyLevel moyen de confiance, mais je reçois toujours une erreur de montage ou sa dépendance ne peut être chargé en essayant d'exécuter le rappel croix AppDomain.

Y at-il un moyen de retirer ceci?

Mise à jour : réponses basées, voici ce que j'ai. Notez que votre classe testée doit se prolonger MarshalByRefObject. Ceci est très limite, mais je ne vois pas un moyen de contourner.

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 );
        }
    }
}
Était-ce utile?

La solution

Je viens de publier un article intitulé confiance partielle Test avec xUnit.net . Il détaille le cadre basé xUnit.net-que nous utilisons l'équipe Entity Framework au code exercice en confiance partielle.

Voici un exemple de son utilisation.

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

Autres conseils

Shamelessly volé Comment organiser une confiance partielle Bac à sable - # 7 , mais réimplémentées (avec un cas de test simple) en F # juste pour le plaisir: -)

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

Et une version 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

J'ai posté un billet de blog en trois parties sur les tests unitaires en moyenne confiance

Je me retourne créer un AppDomain alternatif de façon similaire à quelques réponses ici, mais Approfondissement en utilisant un MarshalByRefObject pour appeler la méthode d'essai dans l'autre AppDomain, ce qui signifie vos classes de test ne ont pas besoin de mettre en œuvre MarshalByRefObject

La troisième partie (contenant des liens vers les autres parties) est ici http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with -nunitpart-trois Umbraco-cadre-test /

Je ne l'ai jamais essayé de le faire, mais en général, pour gérer les défaillances de charge d'assemblage de AppDomains personnalisés, vous pouvez utiliser l'événement AppDomain.AssemblyResolve.

Bien que totalement indépendant, est ici un exemple d'utilisation AppDomain. AssemblyResolve .

La réponse dépend de ce que votre code fait quand quelqu'un avec privilège de confiance moyen tente d'accéder à une fonction de confiance totale. Je suppose une sorte d'exception sera levée.

Dans ce cas, écrire un test unitaire qui fonctionne dans un contexte de confiance moyen, tente d'accéder à une fonction de confiance totale, et prévoit l'exception à être jeté. Si vous ne l'avez jamais écrit un test comme celui-ci, d'une manière commune de le faire que la plupart des cadres de test soutiendront est le suivant:

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 l'exception est pris, cela signifie que votre utilisateur non fiable n'a pas eu à accéder à la fonction (et le test passe) mais si l'exception est jamais pris, le test échoue (nous nous attendions à une exception et n'a pas l'obtenir ).

est un code pseudo java-esque, mais ce modèle devrait fonctionner dans la langue que vous utilisez en supposant qu'il supporte la gestion des exceptions.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top