System.InvalidProgramException при выполнении модульных тестов в MSTest после обновления безопасности Microsoft MS13-004
После применения обновления Microsoft Security 8 января 2013 г. http://technet.microsoft.com/en-us/security/bulletin/ms13-004 мы начали испытывать сбои в наших сборках CI на наших серверах сборки и локально, когда запуск тестов на наших блоках разработки.
Мы получаем System.InvalidProgramException: Common Language Runtime обнаружил недопустимую программу.
Это происходит только при запуске тестов с использованием MSTest, которые используют Castle Windsor DynamicProxy, хотя я не уверен, что здесь DynamicProxy виноват.
Пример кода, который генерирует исключение, приведен ниже.
[TestMethod]
public void ShouldBeAbleToGenerateADynamicProxyForAnObject()
{
var container = new WindsorContainer();
container.Register(Component.For<TestInterceptor>());
container.Register(Component.For<ISomething>()
.Instance(new TestDependency("Called from test framework."))
.LifeStyle.Transient);
container.Register(Component.For<IService>()
.ImplementedBy<TestService>()
.Interceptors(InterceptorReference.ForType<TestInterceptor>())
.Anywhere
.LifeStyle.Transient);
var service = container.Resolve<IService>();
Assert.AreEqual("Called from test framework.", service.MethodNumberOne());
}
Это генерирует трассировку стека, которая в итоге выдает исключение при вызове конструктора MixinData в DynamicProxy:
Castle.DynamicProxy.MixinData..ctor (IEnumerable`1 mixinInstances) Castle.DynamicProxy.ProxyGenerationOptions.Initialize() Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(тип proxyTargetType, параметры типа [CastleDefence.DoD.Directory.OccessDefender). Proxy. CreateInterfaceProxyTypeWithTarget(тип interfaceToProxy, тип [] additionalInterfacesToProxy, тип TargetType, варианты ProxyGenerationOptions) Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithTarget(тип interfaceToProxy, тип [] additionalInterfacesToProxy, тип TargetType, опционы ProxyGenerationOptions) Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithTarget(тип interfaceToProxy, тип [] AdditionalInterfacesToProxy, Цель объекта, параметры ProxyGenerationOptions, перехватчики IInterceptor []) Castle.Windsor.Proxy.DefaultProxyFactory.Create(ядро IKernel, цель объекта, модель ComponentModel, контекст CreationContext, объект [] constructorArguments) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(контекст CreationContext, конструктор ConstructorCandidate, аргументы Object []) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator. Контекст CreationContext) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(контекст CreationContext) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(контекст CreationContext.Crext.Chance.LF) MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(контекст CreationContext, IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(контекст CreationContext, логический requireDecommission, логический экземпляр Required, B urden и нагрузка) Castle.MicroKernel.Handlers.DefaultHandler.Resolve(контекст CreationContext, логический instanceRequired) Castle.MicroKernel.Handlers.AbstractHandler.Resolve(контекст CreationContext) Castle.MicroKernel.DefaultKernel.Ris ольверполучатель, агент-получатель-получатель политика) Castle.MicroKernel. TestCastleWindsorDynamicProxy.cs: строка 34
Моей первой мыслью было, что DynamicProxy фактически генерирует недопустимый IL после обновления безопасности при создании Proxy, но, насколько я понимаю, это не так, поскольку он не зашел так далеко. Я декомпилировал Castle и прошел через отладчик, и я вижу, что исключение выдается согласно трассировке стека, когда конструктор MixinData вызывается из класса ProxyGenerationOptions с помощью вызова, как показано ниже (Примечание: в приведенном выше примере кода this.mixins будет null, но это ожидается и правильно обрабатывается в коде вызываемого конструктора):
this.mixinData = new Castle.DynamicProxy.MixinData(this.mixins);
За пределами MSTest Runner все работает должным образом, наши приложения продолжают функционировать, и при запуске модульных тестов в xUnit или даже TestDriven.NET с использованием MSTest они не генерируют исключение. Мы видим это только при выполнении тестов из Visual Studio или использовании TFS и наших сценариев MSBuild для наших автоматических сборок.
Прежде чем поднять заявку в службу поддержки Microsoft, я подумал, что мы спросим, испытывал ли кто-либо что-либо подобное или есть какие-либо идеи о том, что может быть причиной нашей проблемы?
Изменить: После прохождения нескольких новых вещей сегодня утром мы обнаружили, что это на самом деле, похоже, относится к пакету Castle NuGet, который мы используем. Когда мы ссылаемся на Castle с использованием последнего пакета NuGet, мы получаем ссылку на сборку Castle.Core, скомпилированную для .NET Client Profile 4, эта ссылка является причиной исключения, описанного выше (почему? Я пока не совсем уверен). Изменение ссылки на версию, скомпилированную для.NET 3.5, гарантирует, что тесты пройдут, как и ожидалось, во всех сценариях.
Редактировать: После еще нескольких копаний появляется связанная проблема (которая дала нам основания вернуться в Microsoft и посмотреть, что они говорят). Common Language Runtime обнаружил недопустимую ошибку программы в модульном тестировании.
2 ответа
Я только что исправил ту же ошибку на одном из моих коллег компьютеров, удалив исправление безопасности micrsoft kb2742595 для.net. Я предполагаю, что что-то исправлено в настройках безопасности, и бегун MSTest не может обработать новые настройки. У нас нет Castle.Core установлен.
У меня была похожая ошибка при попытке запустить тесты, которые использовали TypeMock. Чтобы решить проблему, я открыл свое решение в Visual Studio и выбрал Test - Edit Test Settings. В диалоговом окне " Настройки теста " я выбрал " Хосты" и переключил его на " Запуск тестов в 64-битном процессе на 64-битной машине".
Позвольте мне знать, если это помогает. Если это не имеет отношения к вашей ошибке, дайте мне знать, и я удалю свой ответ.