13

中程度の信頼で実行され、完全な信頼が必要な場合に失敗する自動テストを作成したいと考えています。

一部の機能が完全な信頼のシナリオでのみ使用できるライブラリを作成しており、中程度の信頼で実行したいコードが正常に動作することを確認したいと考えています。完全な信頼を必要とするクラスを変更すると、テストが失敗することも知りたい場合。

別の AppDomain を作成し、信頼度が中程度の PolicyLevel を読み込もうとしましたが、クロス AppDomain コールバックを実行しようとすると、常にアセンブリでエラーが発生するか、その依存関係を読み込めませんでした。

これを取り除く方法はありますか?

更新:返信に基づいて、これが私が持っているものです。テストするクラスは MarshalByRefObject を拡張する必要があることに注意してください。これは非常に制限的ですが、それを回避する方法がわかりません。

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 );
        }
    }
}
4

5 に答える 5

7

How to Host a Partial Trust Sandbox – #7から恥知らずに盗用されましたが、キックのために F# で (単純なテスト ケースと共に) 再実装されました :-)

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

そして 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
 部分信頼の成功 #1
 部分信頼の成功 #2
于 2009-11-19T07:24:06.723 に答える
2

xUnit.net を使用した Partial Trust Testingというタイトルの記事を投稿しました。Entity Framework チームが部分信頼下でコードを実行するために使用する xUnit.net ベースのフレームワークについて詳しく説明します。

以下はその使用例です。

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
    }
}
于 2012-08-30T02:23:51.013 に答える
1

Medium Trust での単体テストに関する 3 部構成のブログ記事を投稿しました。

ここでのいくつかの回答と同様の方法で代替 AppDomain をスピンアップしますが、MarshalByRefObject を使用して他の AppDomain でテスト メソッドを呼び出すことにより、さらに進めます。つまり、テスト クラスは MarshalByRefObject を実装する必要はありません。

パート 3 (他のパートへのリンクを含む) はこちらhttp://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-フレームワークテスト/

于 2011-10-21T16:29:23.780 に答える
0

答えは、中程度の信頼権限を持つ誰かが完全な信頼機能にアクセスしようとしたときにコードが何をするかによって異なります。なんらかの例外がスローされると思います。

その場合は、中程度の信頼のコンテキストで実行され、完全な信頼機能へのアクセスを試み、例外がスローされることを期待する単体テストを記述します。このようなテストを書いたことがない場合、ほとんどのテスト フレームワークがサポートする一般的な方法は次のとおりです。

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

例外がキャッチされた場合は、信頼されていないユーザーが機能にアクセスできなかったことを意味します (そしてテストはパスします) が、例外がキャッチされない場合は、テストは失敗します (例外が予期され、取得されませんでした)。

これは Java 風の疑似コードですが、このパターンは、例外処理をサポートしていれば、どの言語を使用していても機能するはずです。

于 2009-10-21T22:12:04.610 に答える