Deadlock when Childstep has Input property

Hi,

I am running into deadlock when I have a Parent with an Output Attribute and a child that is specified as an input. When executing the plan, it results in a deadlock. Why?

2022-04-19 14:34:26.544916 ; TestPlan ; Error ; Error running “???”: Deadlock detected.
2022-04-19 14:34:26.546832 ; TestPlan ; Debug ; Exception: Deadlock detected
2022-04-19 14:34:26.563787 ; TestPlan ; Debug ; at OpenTap.TestStepRun.WaitForOutput(OutputAvailability mode)
2022-04-19 14:34:26.563787 ; TestPlan ; Debug ; at OpenTap.InputOutputRelation.GetOutput(IMemberData outputMember, Object outputObject)
2022-04-19 14:34:26.563787 ; TestPlan ; Debug ; at OpenTap.InputOutputRelation.UpdateInputs(ITestStepParent target)
2022-04-19 14:34:26.563787 ; TestPlan ; Debug ; at OpenTap.TestStepExtensions.DoRun(ITestStep Step, TestPlanRun planRun, TestRun parentRun, IEnumerable1 attachedParameters) 2022-04-19 14:34:26.563787 ; TestPlan ; Debug ; at OpenTap.TestStepExtensions.RunChildSteps(ITestStep Step, TestPlanRun currentPlanRun, TestStepRun currentStepRun, IEnumerable1 attachedParameters, CancellationToken cancellationToken)
2022-04-19 14:34:26.563787 ; TestPlan ; Debug ; at OpenTap.TestStep.RunChildSteps(IEnumerable1 attachedParameters, CancellationToken cancellationToken) 2022-04-19 14:34:26.563787 ; TestPlan ; Debug ; at OpenTap.TestStep.RunChildSteps(IEnumerable1 attachedParameters)

Hi @priram,

How did you configure this test step? I think the GUI should not allow you to get into this situation.

What happens is that your child step is waiting for the parent to finish in order for the output to be ready. So this is guaranteed to be a dead-lock situation. That is because we assume that the output is being set during parent.Run() and the only safe conclusion is that it is set after Run() completes. To fix this, you can use OutputAttribute to more specifically define when the output value becomes available.

This is done using the OutputAvailability attribute, which is defined like this:

  public enum OutputAvailability
    {
        /// <summary> The output value is available before the step has run. This can also be interpreted as always available. </summary>
        BeforeRun,
        /// <summary> After this step is completed. This may occur before or after AfterChildDefer. </summary>
        AfterRun,
        /// <summary> After defer of this step. This is the default for Outputs. This occurs after 'AfterChildDefer' and 'AfterRun'. </summary>
        AfterDefer 
    }

So use [Output(OutputAvailability.BeforeRun)] to make the output available to child steps at any time.

5 Likes

Hi @rolf_madsen ,

Thank you. After I specified the output attribute to be BeforeRun, it worked fine.

I was accessing the output attribute in the child step Run to read the value and hence the issue because of the default attribute.

1 Like