如何自动测试中等信任代码
我想编写在中等信任度下运行的自动化测试,如果需要完全信任则失败。
我正在编写一个库,其中某些功能仅在完全信任的情况下可用,并且我想验证我希望在中等信任下运行的代码是否可以正常工作。 如果还想知道如果我更改需要完全信任的类,我的测试将会失败。
我尝试创建另一个 AppDomain 并加载中等信任策略级别,但在尝试运行跨 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 );
}
}
}
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 );
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
无耻地从 窃取如何托管部分信任沙箱 – #7,但在 F# 中重新实现(以及一个简单的测试用例)只是为了好玩:-)
以及 C# 版本:
Shamelessly stolen from How to Host a Partial Trust Sandbox – #7, but reimplemented (along with a simple test case) in F# just for kicks :-)
And a C# version:
我刚刚发布了一篇文章,标题为 使用 xUnit 进行部分信任测试.net。 它详细介绍了我们在实体框架团队中使用的基于 xUnit.net 的框架,以在部分信任的情况下执行代码。
这是其用法的示例。
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.
我在 Medium Trust 中发布了一篇关于单元测试的三部分博客文章,
我以与此处的一些答案类似的方式启动了一个替代 AppDomain,但通过使用 MarshalByRefObject 来调用其他 AppDomain 中的测试方法来进一步实现,这意味着您的测试类不需要实现 MarshalByRefObject
第三部分(包含其他部分的链接)在这里 http://boxbinary.com/2011/10/how-to-run-a-unit-test-in -medium-trust-with-nunitpart-三-umbraco-framework-testing/
I've posted a three-part blog post on unit testing in Medium Trust
I spin up an alternative AppDomain in a similar fashion to some answers here, but take it further by using a MarshalByRefObject to invoke the test method in the other AppDomain, meaning your test classes do not need to implement MarshalByRefObject
Part three (containing links to the other parts) is here http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/
我从未尝试这样做,但一般来说,要处理自定义 AppDomain 的程序集加载失败,您可以使用 AppDomain.AssemblyResolve 事件。
虽然完全不相关,但这里有使用 AppDomain.AssemblyResolve 的示例。
I have never attempted to do this, but in general, to handle assembly load failures from custom AppDomains, you can use the AppDomain.AssemblyResolve event.
Although totally unrelated, here's an example of using AppDomain.AssemblyResolve.
答案取决于当具有中等信任权限的人尝试访问完全信任功能时您的代码会执行什么操作。 我假设会抛出某种异常。
在这种情况下,编写一个在中等信任上下文中运行的单元测试,尝试访问完全信任功能,并期望抛出异常。 如果您从未编写过这样的测试,大多数测试框架都支持的一种常见方法是:
如果捕获到异常,则意味着您不受信任的用户无法访问该功能(并且测试通过)但如果从未捕获异常,则测试失败(我们预期会出现异常,但没有得到它)。
这是 java 式的伪代码,但这种模式应该适用于您使用的任何语言,假设它支持异常处理。
The answer depends on what your code does when someone with medium trust privilege attempts to access a full trust feature. I assume some kind of exception will be thrown.
In that case, write a unit test that runs in medium trust context, attempts to access a full trust feature, and expects the exception to be thrown. If you've never written a test like this, one common way to do it that most testing frameworks will support is this:
If the exception is caught, it means your untrusted user didn't get to access the feature (and the test passes) but if the exception is never caught, the test fails (we expected an exception and didn't get it).
This is java-esque pseudo code but this pattern should work in whatever language you are using assuming it support exception handling.