static InputOutputRelation[] getOutputRelations(ITestStepParent step) => (InputOutputRelation[])Inputs.GetValue(step) ?? Array.Empty <InputOutputRelation>();
/// <summary> Gets the break condition for a given test step. </summary> /// <param name="step"></param> /// <returns></returns> public static BreakCondition GetBreakCondition(ITestStepParent step) { return((BreakCondition)DynamicMemberTypeDataProvider.TestStepTypeData.BreakConditions.GetValue(step)); }
/// <summary> Unassign an input/output relation . </summary> public static void Unassign(ITestStepParent target, IMemberData targetMember, ITestStepParent source, IMemberData sourceMember) { var from = getInputRelations(source); var con = from.FirstOrDefault(i => i.InputObject == target && i.InputMember == targetMember && i.OutputMember == sourceMember); if (con != null) { Unassign(con); } }
public override bool Deserialize(XElement node, ITypeData t, Action <object> setter) { if (t.DescendsTo(typeof(ITestStepParent)) == false) { return(false); } if (node.Element(stepInputsName) is XElement subelems && activeElements.Contains(node) == false) { var tps = Serializer.GetSerializer <TestPlanSerializer>(); ITestStepParent step = null; var prevsetter = setter; setter = x => prevsetter(step = x as ITestStepParent); var plan = tps.Plan; InputOutputMember[] items = null; if (tps != null && Serializer.Deserialize(subelems, x => items = (InputOutputMember[])x, TypeData.FromType(typeof(InputOutputMember[])))) { bool ok = false; activeElements.Add(node); try { ok = Serializer.Deserialize(node, setter, t); } catch { activeElements.Remove(node); } void connectInputs() { if (step == null) { return; } foreach (var elem in items) { ITestStepParent source; if (elem.Id == Guid.Empty) { source = plan; } else { source = plan.ChildTestSteps.GetStep(elem.Id); } var sourceType = TypeData.GetTypeData(source); var targetType = TypeData.GetTypeData(step); var sourceMember = sourceType.GetMember(elem.Member); var targetMember = targetType.GetMember(elem.TargetMember); if (sourceMember != null && targetMember != null) { InputOutputRelation.Assign(step, targetMember, source, sourceMember); } } } if (ok) { Serializer.DeferLoad(connectInputs); } return(ok); } } return(false); }
/// <summary> Sets the break condition for a test step. </summary> /// <param name="step"> Which step to set it on.</param> /// <param name="condition"></param> public static void SetBreakCondition(ITestStepParent step, BreakCondition condition) { DynamicMemberTypeDataProvider.TestStepTypeData.BreakConditions.SetValue(step, condition); }
private static (BreakCondition Condition, string InheritKind, bool MultiselectDifference) getInheritedVerdict(ITestStepParent _step) { ITestStepParent src = _step; src = src.Parent; while (src != null) { var cond = BreakConditionProperty.GetBreakCondition(src); if (cond.HasFlag(BreakCondition.Inherit) == false) { if (src is TestPlan) { return(cond, $"test plan", false); } return(cond, $"parent step '{((ITestStep)src).GetFormattedName()}'", false); } src = src.Parent; } return(convertAbortCondition(EngineSettings.Current.AbortTestPlan), "engine settings", false); }
/// <summary> Expands the text. Macros are harvested from the optional TestPlanRun or the test step.</summary> /// <param name="run">A place to find additional metadata for macro expansion.</param> /// <param name="date">If no date was found in the metadata, this date will be used. If date is not supplied, DateTime.Now will be used.</param> /// <param name="testPlanDir">If no TestPlanDir was found in the metata, this TestPlanDir will be used.</param> /// <param name="replacements">Overrides other macro parameters.</param> /// <returns>The expanded string.</returns> public string Expand(TestPlanRun run, DateTime?date, string testPlanDir, Dictionary <string, object> replacements) { ITestStepParent context = Context; IEnumerable <(string, object)> getMacro() { // note: macros are case-insensitive. if (testPlanDir != null) { yield return("TestPlanDir", testPlanDir); } if (date != null) { yield return("date", date); } if (replacements != null) { foreach (var elem in replacements) { yield return(elem.Key, elem.Value); } } if (run != null) { var runparams = run.Parameters.Concat(ResultParameters.GetMetadataFromObject(run)).Where(y => y.IsMetaData); foreach (var v in runparams) { var path = v.Value; yield return(v.Name, path); yield return(v.MacroName, path); } } ITestStepParent ctx = context; while (ctx != null) { var p = ResultParameters.GetMetadataFromObject(ctx); foreach (var v in p) { if (v.IsMetaData == false) { continue; } var path = v.Value; yield return(v.Name, path); yield return(v.MacroName, path); } ctx = ctx.Parent; } yield return("date", DateTime.Now); yield return("Verdict", Verdict.NotSet); var met = ResultParameters.GetComponentSettingsMetadataLazy(false); foreach (var ps in met) { foreach (var v in ps) { if (v.IsMetaData == false) { continue; } var path = v.Value; yield return(v.Name, path); yield return(v.MacroName, path); } } } return(ReplaceMacros(Text, getMacro().Select(x => (x.Item1, StringConvertProvider.GetString(x.Item2))))); }
/// <summary> Creates a new instance of MacroString with a context. </summary> /// <param name="context"></param> public MacroString(ITestStepParent context) { Context = context; }
/// <summary> Removed a number of steps from the test plan. Also includes child steps of selected steps. </summary> /// <param name="steps">The steps to remove.</param> public void RemoveItems(IEnumerable <ITestStep> steps) { ITestStepParent parent = Parent; while (parent.Parent != null) { parent = parent.Parent; } HashSet <ITestStep> allRemovedSteps = Utils.FlattenHeirarchy(steps, s => s.ChildTestSteps).Distinct().ToHashSet(); List <ITestStep> filteredsteps = steps.Where(s => allRemovedSteps.Contains(s.Parent as ITestStep) == false).ToList(); if (filteredsteps.Any(step => step.Parent.ChildTestSteps.IsReadOnly)) { throw new InvalidOperationException("Cannot remove a step from a read-only list."); } foreach (var step in filteredsteps) { step.Parent.ChildTestSteps.Remove(step); } { // For all remaining steps, check if they have any TestStep properties // If so, check that that property still exists in the plan. Otherwise set it to null. var AllSteps = Utils.FlattenHeirarchy(parent.ChildTestSteps, x => x.ChildTestSteps).ToHashSet(); Dictionary <Type, System.Reflection.PropertyInfo[]> propLookup = new Dictionary <Type, System.Reflection.PropertyInfo[]>(); foreach (var step in AllSteps) { var t = step.GetType(); if (propLookup.ContainsKey(t)) { continue; } var props = t.GetPropertiesTap().Where(p => p.PropertyType.DescendsTo(typeof(ITestStep)) && p.GetSetMethod() != null).ToArray(); propLookup[t] = props; } foreach (var step in AllSteps) { var t = step.GetType(); if (propLookup.ContainsKey(t) == false) { continue; } foreach (var prop in propLookup[t]) { ITestStep value = (ITestStep)prop.GetValue(step); if (AllSteps.Contains(value) == false) { try { prop.SetValue(step, null); } catch { // catch all usercode errors here. } } } } } }
/// <summary> /// Signals that an action is beginning. /// </summary> /// <param name="planRun">The planrun for the currently executing testplan.</param> /// <param name="item">The item affected by the current action. This can be either a testplan or a teststep.</param> /// <param name="stage">The stage that is beginning.</param> /// <param name="cancellationToken">Used to cancel the step early.</param> public void BeginStep(TestPlanRun planRun, ITestStepParent item, TestPlanExecutionStage stage, CancellationToken cancellationToken) { switch (stage) { case TestPlanExecutionStage.Open: case TestPlanExecutionStage.Execute: { var resources = ResourceManagerUtils.GetResourceNodes(StaticResources); if (item is TestPlan plan && stage == TestPlanExecutionStage.Execute) { // Prompt for metadata for all resources, not only static ones. var testPlanResources = ResourceManagerUtils.GetResourceNodes(EnabledSteps); plan.StartResourcePromptAsync(planRun, resources.Concat(testPlanResources).Select(res => res.Resource)); } if (resources.All(r => r.Resource?.IsConnected ?? false)) { return; } // Call ILockManagers before checking for null try { lockManager.BeforeOpen(resources, cancellationToken); } finally { lock (resourceWithBeforeOpenCalled) { resourceWithBeforeOpenCalled.AddRange(resources); } } try { // Check null resources if (resources.Any(res => res.Resource == null)) { // Now check resources since we know one of them should have a null resource resources.ForEach(res => { if (res.StrongDependencies.Contains(null) || res.WeakDependencies.Contains(null)) { throw new Exception(String.Format("Resource property not set on resource {0}. Please configure resource.", res.Resource)); } }); } } finally { OpenResources(resources, cancellationToken); } break; } case TestPlanExecutionStage.Run: if (item is ITestStep step) { var resources = ResourceManagerUtils.GetResourceNodes(new List <object> { step }); if (resources.Any()) { // Call ILockManagers before checking for null try { lockManager.BeforeOpen(resources, cancellationToken); } finally { lock (resourceWithBeforeOpenCalled) { resourceWithBeforeOpenCalled.AddRange(resources); } } try { // Check null resources if (resources.Any(res => res.Resource == null)) { step.CheckResources(); // Now check resources since we know one of them should have a null resource resources.ForEach(res => { if (res.StrongDependencies.Contains(null) || res.WeakDependencies.Contains(null)) { throw new Exception(String.Format("Resource property not set on resource {0}. Please configure resource.", res.Resource)); } }); } } finally { lock (resourceLock) { resourceDependencies[step] = resources.Select(x => x.Resource).ToList(); foreach (ResourceNode n in resources) { if (n.Resource is IResource resource) { if (!resourceReferenceCount.ContainsKey(resource)) { resourceReferenceCount[resource] = 0; } resourceReferenceCount[resource] += 1; } } } OpenResources(resources, cancellationToken); } WaitHandle.WaitAny(new[] { planRun.PromptWaitHandle, planRun.MainThread.AbortToken.WaitHandle }); } } break; } }