SpecFlow icon indicating copy to clipboard operation
SpecFlow copied to clipboard

BoDi.ObjectContainerException : Object container disposed

Open jjmanton opened this issue 4 years ago • 5 comments

SpecFlow Version: Seems to affect all versions 3.x

  • [x] 3.7
  • [x] 3.6
  • [x] 3.5
  • [x] 3.4
  • [x] 3.3
  • [x] 3.1
  • [x] 3.0
  • [ ] 2.4
  • [ ] 2.3
  • [ ] 2.2
  • [ ] 2.1
  • [ ] 2.0
  • [ ] 1.9

Used Test Runner

  • [ ] SpecFlow+Runner
  • [ ] MSTest
  • [ ] NUnit
  • [x] Xunit

Version number: We use a forked version of 2.4.1 that has inclusion file support here (xunit/xunit#2018)

Project Format of the SpecFlow project

  • [ ] Classic project format using packages.config
  • [x] Classic project format using <PackageReference> tags
  • [ ] Sdk-style project format

.feature.cs files are generated using

  • [x] SpecFlow.Tools.MsBuild.Generation NuGet package
  • [ ] SpecFlowSingleFileGenerator custom tool

Visual Studio Version

  • [x] VS 2019
  • [ ] VS 2017

Enable SpecFlowSingleFileGenerator Custom Tool option in Visual Studio extension settings

  • [ ] Enabled
  • [x] Disabled

Are the latest Visual Studio updates installed?

  • [x] Yes
  • [ ] No, I use Visual Studio version <Major>.<Minor>.<Patch>

.NET Framework:

  • [x] >= .NET 4.5
  • [ ] before .NET 4.5
  • [ ] .NET Core 2.1
  • [ ] .NET Core 3.1
  • [ ] .NET 5.0

Test Execution Method:

  • [ ] Visual Studio Test Explorer
  • [ ] TFS/VSTS/Azure DevOps – Task – PLEASE SPECIFY THE NAME OF THE TASK
  • [x] Command line – PLEASE SPECIFY THE FULL COMMAND LINE
"xunit.console.exe C:\Installs\IntegrationTests\AW.Integration.UI.Console.Tests.dll C:\Installs\IntegrationTests\AW.Integration.Api.Tests.dll -inclusionfile C:\Installs\IntegrationTests\{bucket_file} -nunit C:\Installs\IntegrationTests\TestResult\{test_output_file} -verbose -diagnostics -parallel all -maxthreads 8 > C:\Installs\IntegrationTests\TestResult\{xunit_log}\"

<SpecFlow> Section in app.config or content of specflow.json

  <specFlow>
    <stepAssemblies>
      <stepAssembly assembly="AW.Integration.UI.Framework" />
      <stepAssembly assembly="AW.Integration.UI.StepDefinitions" />
      <stepAssembly assembly="AW.Integration.Api.StepDefinitions" />
      <stepAssembly assembly="AW.Integration.UI.SSP.StepDefinitions" />
      <stepAssembly assembly="AW.Integration.MockService" />
    </stepAssemblies>
  </specFlow>

AND

  <specFlow>
    <stepAssemblies>
      <stepAssembly assembly="AW.Integration.Api.StepDefinitions" />
      <stepAssembly assembly="AW.Integration.MockService" />
    </stepAssemblies>
  </specFlow>

Issue Description

We will intermittently (about 1 every 10 test runs, and each test run has 7k tests) see the following error message - BoDi.ObjectContainerException : Object container disposed

Here is an example stack trace -

BoDi.ObjectContainerException : Object container disposed
Stack Trace:
   at BoDi.ObjectContainer.AssertNotDisposed()
   at BoDi.ObjectContainer.Resolve(Type typeToResolve, ResolutionList resolutionPath, String name)
   at BoDi.ObjectContainer.Resolve[T](String name)
   at TechTalk.SpecFlow.xUnit.SpecFlowPlugin.XUnitTraceListener.WriteToolOutput(String message)
   at TechTalk.SpecFlow.Tracing.TestTracer.TraceWarning(String text)
   at System.Diagnostics.TraceListener.WriteHeader(String source, TraceEventType eventType, Int32 id)
   at System.Diagnostics.TraceListener.TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, Int32 id, String message)
   at System.Diagnostics.TraceInternal.TraceEvent(TraceEventType eventType, Int32 id, String format, Object[] args)
E:\agt01\COM-CN63887-BAWAP\src\AirWatch API\AW.Api.Client\AW.Api.Client\Http\ApiClient.cs(686,0): at AW.Api.Client.Http.ApiClient.<SendOnceAsync>d__42.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
E:\agt01\COM-CN63887-BAWAP\src\AirWatch API\AW.Api.Client\AW.Api.Client\Http\ApiClient.cs(183,0): at AW.Api.Client.Http.ApiClient.<>c__DisplayClass21_0.<<SendAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Polly.Retry.AsyncRetryEngine.<ImplementationAsync>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Polly.AsyncPolicy.<ExecuteAsync>d__21`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
E:\agt01\COM-CN63887-BAWAP\src\AirWatch API\AW.Api.Client\AW.Api.Client\Http\ApiClient.cs(183,0): at AW.Api.Client.Http.ApiClient.<SendAsync>d__21.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
E:\agt01\COM-CN63887-BAWAP\src\AirWatch API\AW.Api.Client\AW.Api.Client\MAM\Clients\App\AppClient.cs(248,0): at AW.Api.Client.MAM.Clients.App.AppClient.<PutAssignmentForApplicationAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
E:\agt01\COM-CN63887-BAWAP\src\AW Integration Tests\AW.Integration.Api.StepDefinitions\MamApi\Apps\AppSteps.cs(1382,0): at AW.Integration.Api.StepDefinitions.MamApi.Apps.AppSteps.<GivenIhavebelowAssignmentRuleforAppAssignmentModelAsync>d__50.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at TechTalk.SpecFlow.Bindings.SynchronousBindingDelegateInvoker.<>c__DisplayClass2_0.<<InvokeBindingDelegateAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at TechTalk.SpecFlow.Bindings.AsyncHelpers.<>c__DisplayClass1_1`1.<<RunSync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at TechTalk.SpecFlow.Bindings.AsyncHelpers.ExclusiveSynchronizationContext.BeginMessageLoop()
   at TechTalk.SpecFlow.Bindings.AsyncHelpers.RunSync[T](Func`1 task)
   at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(IContextManager contextManager, StepInstance stepInstance)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()

Steps to Reproduce

This is hard to consistently reproduce, but in general you will need many tests calling into async code that has Tracing in some form (see stack trace above).

Repro Project

jjmanton avatar Feb 23 '21 14:02 jjmanton

I see Polly and HttpClient stuff in the stacktrace. Do you have something with it in the AfterScenario hook?

SabotageAndi avatar Feb 23 '21 14:02 SabotageAndi

@SabotageAndi Yes, we do some cleanup API calls in the AfterScenario hook. Our API Client wraps HTTPClient, along with Polly for transient error retry. Is there an issue doing async work in the AfterScenario hook?

jjmanton avatar Feb 23 '21 14:02 jjmanton

There are some issues with async/await in SpecFlow.

Quick search I found these:

  • https://github.com/SpecFlowOSS/SpecFlow/issues/1969
  • https://github.com/SpecFlowOSS/SpecFlow/issues/1623
  • https://github.com/SpecFlowOSS/SpecFlow/issues/2100
  • https://github.com/SpecFlowOSS/SpecFlow/issues/2230
  • https://github.com/SpecFlowOSS/SpecFlow/issues/880

Can you workaround if you wait for execution on your own?

SabotageAndi avatar Feb 23 '21 15:02 SabotageAndi

I'm having a similar situation, but I don't think it is async-related.

I have created several tests that run perfectly on their own, but when I tell the VS Test Runner to run them all at some point there's an error on the cleanup, and the next text to be run throws this error while initializing the Scenario.

here's the stack trace:

 Message: 
    Test method Endpoints.Tests.Specs.Features.ContactEndpointFeature.CreateContactWithInvalidEnrollmentDateValueWillMakeItNull threw exception: 
    BoDi.ObjectContainerException: Object container disposed
  Stack Trace: 
    ObjectContainer.AssertNotDisposed()
    ObjectContainer.Resolve(Type typeToResolve, ResolutionList resolutionPath, String name)
    ObjectContainer.Resolve[T](String name)
    ObjectContainer.Resolve[T]()
    MSTestTestContextProvider.GetTestContext()
    MSTestTraceListener.WriteToolOutput(String message)
    TestTracer.TraceWarning(String text)
    InternalContextManager`1.Init(TContext newInstance, IObjectContainer newObjectContainer)
    ContextManager.InitializeScenarioContext(ScenarioInfo scenarioInfo)
    TestExecutionEngine.OnScenarioInitialize(ScenarioInfo scenarioInfo)
    TestRunner.OnScenarioInitialize(ScenarioInfo scenarioInfo)
    ContactEndpointFeature.ScenarioInitialize(ScenarioInfo scenarioInfo)
    ContactEndpointFeature.CreateContactWithInvalidEnrollmentDateValueWillMakeItNull() line 217

Any ideas what might be happening?

lalberto8085 avatar Aug 18 '21 20:08 lalberto8085

@lalberto8085 as far as I know this happens if you wanto to get something from the container after it was already disposed. We would need a project where this is reproduced to have a clue what is the problem here.

SabotageAndi avatar Aug 23 '21 08:08 SabotageAndi