System.InvalidProgramException при выполнении модульных тестов в MSTest после обновления Microsoft Security MS13-004

После применения обновления безопасности Microsoft 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());

        container.Register(Component.For()
                               .Instance(new TestDependency("Called from test framework."))
                               .LifeStyle.Transient);

        container.Register(Component.For()
                               .ImplementedBy()
                               .Interceptors(InterceptorReference.ForType())
                               .Anywhere
                               .LifeStyle.Transient);

        var service = container.Resolve();
        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(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options) Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Type targetType, ProxyGenerationOptions options) Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Type targetType, ProxyGenerationOptions options) Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Object target, ProxyGenerationOptions options, IInterceptor[] interceptors) Castle.Windsor.Proxy.DefaultProxyFactory.Create(IKernel kernel, Object target, ComponentModel model, CreationContext context, Object[] constructorArguments) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, ConstructorCandidate constructor, Object[] arguments) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, ConstructorCandidate constructor, Object[] arguments) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden) Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context) Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments) Castle.Windsor.WindsorContainer.ResolveT ShouldBeAbleToGenerateADynamicProxyForAnObject() in TestCastleWindsorDynamicProxy.cs: line 34

Моя первая мысль заключалась в том, что DynamicProxy фактически генерировал недействительный IL после обновления безопасности при создании прокси, но, насколько я вижу, это не так, потому что он не так далеко. Я декомпилировал Castle и перешел через отладчик, и я вижу, что исключение выбрано в соответствии с трассировкой стека, когда конструктор MixinData вызывается из класса ProxyGenerationOptions посредством вызова, как показано ниже ( Примечание: в примере кода выше этого. mixins будет нулевым, но это ожидается и корректно обрабатывается в коде конструктора, который называется ):

this.mixinData = new Castle.DynamicProxy.MixinData(this.mixins);

Вне бегуна MSTest все работает так, как ожидалось, наши приложения продолжают функционировать, и при запуске модульных тестов в xUnit или даже TestDriven.NET с использованием MSTest они не генерируют исключение. Мы видим, что это поведение запускает тесты из Visual Studio или с использованием TFS и наших сценариев MSBuild для наших автоматизированных сборок.

Прежде чем мы подберем билет поддержки с Microsoft, я подумал, что мы спросим, ​​есть ли у кого-либо еще что-либо подобное или какие-либо идеи о том, что может вызвать нашу проблему?

Edit: After going through a few new things this morning we have discovered that this actually seems to relate to the Castle NuGet package we are using. When we reference Castle using the latest NuGet package we end up having a reference to the Castle.Core assembly compiled for the .NET Client Profile 4 this reference is the cause of the exception above (Why? I am not entirely sure yet). Changing the reference to the version compiled for .NET 3.5 ensures the tests pass as expected in all scenarios.

Edit: After some more digging there does appear to be a linked issue (which has given us grounds to go back to Microsoft and see what they have to say) Common Language Runtime detected an invalid program error in unit testing

6
nl ja de
Разве это не проблема с начальным выпуском .NET 4? Возможно, они сломали его снова ...
добавлено автор leppie, источник
Из статьи о технике можно предположить, что MSTest не работает под полным доверием.
добавлено автор leppie, источник
Это хороший звонок, спасибо за информацию. Я посмотрю на Google вокруг выпуска .NET 4 и посмотрю, смогу ли я увидеть что-то подобное. Это странно.
добавлено автор Alex, источник
Насколько я могу судить, мы с полным доверием управляем MSTest. MStest работает нормально, если вы попросите его запустить тест в командной строке. I.e "mstest/testcontainer: ". Кажется, только в наших автоматизированных сборках и при вызове теста из Visual Studio.
добавлено автор Alex, источник

2 ответы

У меня была аналогичная ошибка при попытке запуска тестов, которые использовали TypeMock. Чтобы решить проблему, я открыл свое решение в Visual Studio и выбрал Test - Изменить параметры тестирования . В диалоговом окне Test Settings я выбрал Hosts и переключил его на Запуск тестов в 64-битном процессе на 64-битной машине .

Позвольте мне знать, если это помогает. Если это не имеет никакого отношения к вашей ошибке, сообщите мне, и я удалю свой ответ.

2
добавлено
У меня также была эта проблема, и я обнаружил, что это связано с тем, что TypeMock не играет хорошо в VS2013. Данное исправление не сработало для меня, но это привело меня к исправлению, которое произошло - удаление TypeMock (если вы больше не используете его) или обновить его до последней версии - я использовал последнюю ссылку на этой странице форума forums.typemock .com/viewtopic.php? f = 4 & t = 22477 (опубликовано Wed Mar 26, 2014 10:02 am)
добавлено автор Kai, источник
В VS 2012 этот параметр - Test -> Test Settings -> Default Processor Architecture -> X64
добавлено автор Taedrin, источник
Это то, что мы нашли. По некоторым причинам это помогло в некоторых наших тестовых проектах, но не по всем причинам. Я не мог понять, почему это внезапно изменило бы взгляды на ноты для патча, который был применен.
добавлено автор Alex, источник

Я только что исправил ту же ошибку на одном из моих компьютеров коллег, деинсталлируя исправление безопасности microrsoft kb2742595 для .net. Я думаю, что что-то исправлено в настройках безопасности, а бегун MSTest не может обрабатывать новые настройки. У нас нет Castle.Core.

2
добавлено
В нашем случае есть проверка безопасности в одной из наших собственных библиотек, из-за которой тестовый бегун терпит неудачу. Castle.Core может делать что-то simulair как наш lib. Однако кажется, что тестовый бегун не работает с правильными настройками безопасности.
добавлено автор Peter, источник
Вы делали ошибку в microsoft?
добавлено автор Peter, источник
Спасибо, хорошо знать, что мы не единственные, кто испытывает эту проблему, и что Castle.Core не единственная затронутая ассамблея (в нашем случае это .NET-профиль клиента 4, скомпилированный Castle.Core, который MSTest с проблемами). К сожалению, удаление патча не является реальным вариантом для нас (в настоящее время). У нас есть работа, но было бы хорошо знать, в чем причина, потому что я нервничаю, когда могу что-то сделать, не понимая, что происходит.
добавлено автор Alex, источник
Мы находимся в процессе его поднятия.
добавлено автор Alex, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot