/// <summary> /// TODO: description what we check... /// <para><remarks>Execute within transaction.</remarks></para> /// </summary> /// <returns>Checker results.</returns> protected IEnumerable <ContextCheckerResult> ValidateTestInjectionPoint(GME.MGA.IMgaReference tip) { List <ContextCheckerResult> results = new List <ContextCheckerResult>(); CyPhy.TopLevelSystemUnderTest tlsut = null; if (this.testBench.Children.TopLevelSystemUnderTestCollection.Count() == 1) { // if there is only one tlsut we can check safely the Test injection point references, otherwise do not. tlsut = this.testBench.Children.TopLevelSystemUnderTestCollection.FirstOrDefault(); } else { return(results); } var tipRefersTo = tip.Referred; if (tipRefersTo == null) { var feedback = new ContextCheckerResult() { Success = false, Subject = tip, Message = string.Format("{0} [{1}] object is null reference.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else { var feedback = new ContextCheckerResult() { Success = true, Subject = tip, Message = string.Format("{0} [{1}] object is not null reference.", tip.Name, tip.Meta.Name) }; results.Add(feedback); // descendant of top level system under test var referred = (tlsut.Impl as GME.MGA.IMgaReference).Referred; if (referred != null && referred is GME.MGA.MgaModel) { var visitedCAs = new HashSet <string>() { referred.ID }; var referenceFilter = referred.Project.CreateFilter(); referenceFilter.Kind = typeof(CyPhy.ComponentRef).Name; var matchingTarget = this.LookForObjectIDInReferencedCAsRecursively( referenceFilter, referred.Project.CreateFilter(), visitedCAs, referred as GME.MGA.IMgaModel, tip.Referred.ID); if (matchingTarget == false) { // tip does not point to a descendant of the tlsut feedback = new ContextCheckerResult() { Success = false, Subject = tip, Message = string.Format("{0} [{1}] does not point to a descendant of the TopLevelSystemUnderTest model.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else { feedback = new ContextCheckerResult() { Success = true, Subject = tip, Message = string.Format("{0} [{1}] points to a descendant of the TopLevelSystemUnderTest model.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } } if (tipRefersTo.Meta.Name == typeof(CyPhy.DesignContainer).Name) { // can point to design container var designContainer = CyPhyClasses.DesignContainer.Cast(tipRefersTo); feedback = new ContextCheckerResult() { Success = true, Subject = tip, Message = string.Format("{0} [{1}] can point to {2}.", tip.Name, tip.Meta.Name, designContainer.Attributes.ContainerType) }; results.Add(feedback); } else if (tipRefersTo.Meta.Name == typeof(CyPhy.ComponentAssembly).Name) { // can point to component assembly feedback = new ContextCheckerResult() { Success = true, Subject = tip, Message = string.Format("{0} [{1}] point can point to Component Assembly.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else if (tipRefersTo.Meta.Name == typeof(CyPhy.Component).Name) { // cannot point to component feedback = new ContextCheckerResult() { Success = false, Subject = tip, Message = string.Format("{0} [{1}] point cannot point to Component.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else if (tipRefersTo.Meta.Name == typeof(CyPhy.ComponentRef).Name) { var componentRef = CyPhyClasses.ComponentRef.Cast(tipRefersTo); // can point to component ref feedback = new ContextCheckerResult() { Success = true, Subject = tip, Message = string.Format("{0} [{1}] can point to Component reference.", tip.Name, tip.Meta.Name) }; results.Add(feedback); if ((componentRef.Impl as GME.MGA.IMgaReference).Referred == null) { // component ref cannot be null feedback = new ContextCheckerResult() { Success = false, Subject = tip, Message = string.Format("{0} [{1}] can point to Component reference, but the Component reference cannot be null.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else { if (componentRef.AllReferred is CyPhy.TestComponent) { // component ref cannot be test component feedback = new ContextCheckerResult() { Success = false, Subject = tip, Message = string.Format("{0} [{1}] can point to Component reference, but the Component reference cannot be a Test Component.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else if (componentRef.AllReferred is CyPhy.Component) { // component ref can be component feedback = new ContextCheckerResult() { Success = true, Subject = tip, Message = string.Format("{0} [{1}] can point to Component reference, which points to a Component.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else if (componentRef.AllReferred is CyPhy.ComponentAssembly) { // component ref can be component assembly feedback = new ContextCheckerResult() { Success = true, Subject = tip, Message = string.Format("{0} [{1}] can point to Component reference, which points to a Component Assembly.", tip.Name, tip.Meta.Name) }; results.Add(feedback); } else { // this cannot happen, but if CyPhyML changes it may happen. throw new NotImplementedException(); } } } } return(results); }
public static IMgaFCO FindTestInjectionTarget( CyPhy.TopLevelSystemUnderTest originalSut, IMgaReference originalTip, CyPhy.TopLevelSystemUnderTest targetSut) { if (originalSut == null) { throw new ArgumentNullException("originalSut"); } if (originalTip == null) { throw new ArgumentNullException("originalTip"); } if (targetSut == null) { throw new ArgumentNullException("targetSut"); } // target that the reference has to be redirected IMgaFCO targetTipByBuilt = null; IMgaFCO targetTipByAbsPath = null; // get tip reference // relative path var relativePath = string.Empty; // ASSUME original SUT is a design container if (originalSut.Referred.DesignContainer == null && targetSut.Referred.ComponentAssembly == null) { throw new NotImplementedException(); } var sutDesignContainer = originalSut.Referred.DesignContainer; var sutComponentAssemblyTarget = targetSut.Referred.ComponentAssembly; // TOOD: Double check this cast CyPhy.DesignEntity originalDesignEntity = null; if (originalTip.Referred.Meta.Name == typeof(CyPhy.DesignContainer).Name) { originalDesignEntity = CyPhyClasses.DesignContainer.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.Component).Name) { originalDesignEntity = CyPhyClasses.Component.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.ComponentRef).Name) { originalDesignEntity = CyPhyClasses.ComponentRef.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.ComponentAssembly).Name) { originalDesignEntity = CyPhyClasses.ComponentAssembly.Cast(originalTip.Referred); } List <CyPhy.DesignEntity> possibleDesignEntities = new List <CyPhy.DesignEntity>(); possibleDesignEntities.Add(originalDesignEntity); // TODO: abspath for component assemblies / Component assembly refs too. Call function recursively if (originalTip.Referred.Meta.Name == typeof(CyPhy.DesignContainer).Name) { var designContainer = CyPhyClasses.DesignContainer.Cast(originalTip.Referred); if (designContainer.Attributes.ContainerType == CyPhyClasses.DesignContainer.AttributesClass.ContainerType_enum.Compound) { // there could be a referece to the compound container // BUG: no tracking of compound containers attempt to get it by AbsPath // this implementation will work as long as // names are unqiue to Compound containes // structure as follows // // == PASS == // | Compound // +-- Compound // | // +-- Compound // // == FAIL 1 == Have no idea how to get the path correctly // | Compound // +-- Alternative // | // +-- Compound // // == FAIL 2 == Have no idea how to get the path correctly // | Compound // +-- Optional // | // +-- Compound // TODO: would be nice to use a regexp or something like that Func <string, string> shortenAbsPath = new Func <string, string>((absPath) => { // Example: // input: /@NewTesting|kind=Testing|relpos=0/@FEA_CompoundTIP_DS|kind=CADTestBench|relpos=0/@DesignContainer|kind=TopLevelSystemUnderTest|relpos=0 // output: /@NewTesting/@FEA_CompoundTIP_DS/@DesignContainer return(string.Join("/", absPath.Split('/').Select(x => string.Join("", x.TakeWhile(y => y != '|'))))); }); var sutPath = shortenAbsPath(originalSut.AllReferred.Impl.AbsPath); var originalTipPath = shortenAbsPath(originalTip.Referred.AbsPath); relativePath = originalTipPath.Substring(sutPath.Length); // TODO: meta base name [kind] can be different if there are no unique path to the object. targetTipByAbsPath = (targetSut.AllReferred.Impl as MgaModel).get_ObjectByPath(relativePath) as MgaFCO; } else { // while optional and alternative containers are not tracked, get all ComponentAssembly, Component, ComponentRef recursively. possibleDesignEntities.AddRange(ExpandInnerOptionalAndAlternativesRecursively(designContainer)); } } Exception ex = null; foreach (var designEntity in possibleDesignEntities) { // Look for a DesignEntityRef, within a CWC, that points to this element in the Design Space. foreach (CyPhy.DesignEntityRef designEntityRef in designEntity.ReferencedBy.DesignEntityRef) { var cwc = CyPhyClasses.CWC.Cast(designEntityRef.ParentContainer.Impl); bool hasMatchingCARoot = false; var caRefs = cwc.DstConnections.Config2CACollection.Select(x => x.DstEnds.ComponentAssemblyRef); foreach (var caRef in caRefs) { if (caRef.AllReferred != null) { if ((caRef.AllReferred.Impl as MgaFCO).RootFCO.ID == (sutComponentAssemblyTarget.Impl as MgaFCO).RootFCO.ID) { hasMatchingCARoot = true; break; } } } if (hasMatchingCARoot == false) { // do not log any messages since they irrelevant. continue; } // TODO: log if design is dirty. // get design entity ref where the refered object is the test injection point reference // // Multiple configuration (1, 2, 3, ...) can have the same design entity refs // // design entity ref ----> DesignSpace element // ^ // | // original test injection --------- // verify root fco do match if ((designEntityRef.Impl as MgaFCO).RootFCO != (sutDesignContainer.Impl as MgaFCO).RootFCO) { // in case user accidentally moves these object in the tree string message = string.Format("Model does not contain traceablity information between the generated configurations and the design space. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } // user may have leftovers from running CAExporter then deleting the CA var builts = designEntityRef.DstConnections.BuiltCollection.Where(x => x.DstEnds.BuiltDesignEntityRef.AllReferred != null); var builtConnections = builts.Count(); if (builtConnections == 0) { // no built connection -> not good string message = string.Format("No 'built' connection. Model does not contain traceablity information between the generated configurations and the design space. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } if (builtConnections > 1) { // more than one built connection -> not good string message = string.Format("There are more than one 'built' connections traceability is ambiguous. Model has to be fixed first. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } // Get the Built connection and then the BuildDesignEntityRef. // The BuildDesignEntityRef will point to our source object within a Component Assembly / configuration. foreach (CyPhy.Built built in builts) { var builtDesignEntityRef = built.DstEnds.BuiltDesignEntityRef; if ((builtDesignEntityRef.AllReferred.Impl as MgaFCO).RootFCO.ID == (sutComponentAssemblyTarget.Impl as MgaFCO).RootFCO.ID) { // verify that the component is inside the target design // TODO: how this would work if it points to a component in a CA which is referred in the design??? targetTipByBuilt = builtDesignEntityRef.AllReferred.Impl as MgaFCO; } } } } if (targetTipByBuilt != null) { // prefer by built return(targetTipByBuilt); } else if (targetTipByAbsPath != null) { // fallback to by abs path return(targetTipByAbsPath); } else if (ex != null) { // not found throw ex; } else { return(null); } }
public static CyPhy.TestBenchType Convert(avm.TestBench avmTestBench, IMgaProject project) { if (avmTestBench == null) { throw new ArgumentNullException("avmTestBench"); } var rootFolder = CyPhyClasses.RootFolder.GetRootFolder((MgaProject)project); var testBenchFolder = rootFolder.Children.TestingCollection.Where(d => d.Name == "TestBenches").FirstOrDefault(); #region Create TestBenchesFolder if (testBenchFolder == null) { testBenchFolder = CyPhyClasses.Testing.Create(rootFolder); testBenchFolder.Name = "TestBenches"; } #endregion #region Create TestBench var cyphyTestBench = CyPhyClasses.TestBench.Create(testBenchFolder); cyphyTestBench.Name = avmTestBench.Name; #endregion #region Create TopLevelSystemUnderTest var avmSystemUnderTest = avmTestBench.TopLevelSystemUnderTest; CyPhy.TopLevelSystemUnderTest cyphySystemUnderTest = null; TestBenchPrimitiveWrapper cyphySystemUnderTestReferred = null; if (avmSystemUnderTest != null) { cyphySystemUnderTest = CyPhyClasses.TopLevelSystemUnderTest.Create(cyphyTestBench); SetLayoutData(avmSystemUnderTest, cyphySystemUnderTest.Impl); if (!string.IsNullOrEmpty(avmSystemUnderTest.DesignID)) { // Looking for the referred component assembly var allComponentAssembly = GetAllComponentAssemblies(rootFolder.Children.ComponentAssembliesCollection); var componentAssembly = allComponentAssembly.FirstOrDefault(x => x.Attributes.ConfigurationUniqueID == avmSystemUnderTest.DesignID); if (componentAssembly != null) { cyphySystemUnderTest.GenericReferred = componentAssembly; cyphySystemUnderTest.Name = componentAssembly.Name; cyphySystemUnderTestReferred = new TestBenchPrimitiveWrapper(componentAssembly); } } } #endregion #region Create Parameters var parameterCache = new List <Tuple <avm.Parameter, CyPhy.Parameter> >(); foreach (var avmParameter in avmTestBench.Parameter) { var cyphyTestBenchParameter = CyPhyClasses.Parameter.Create(cyphyTestBench); cyphyTestBenchParameter.Name = avmParameter.Name; cyphyTestBenchParameter.Attributes.Description = avmParameter.Notes; cyphyTestBenchParameter.Attributes.ID = avmParameter.ID; SetLayoutData(avmParameter, cyphyTestBenchParameter.Impl); parameterCache.Add(new Tuple <avm.Parameter, CyPhy.Parameter>(avmParameter, cyphyTestBenchParameter)); #region Set attribute values var avmValue = avmParameter.Value; if (avmValue != null) { CyPhyClasses.Parameter.AttributesClass.DataType_enum cyphyDataType; // TODO: else give a warning if (ConvertCyPhyDataTypeEnum(avmValue.DataType, out cyphyDataType)) { cyphyTestBenchParameter.Attributes.DataType = cyphyDataType; } cyphyTestBenchParameter.Attributes.Dimension = avmValue.Dimensions; var avmValueExpression = avmValue.ValueExpression; if (avmValueExpression != null && avmValueExpression is avm.ParametricValue) { var avmParametricValue = (avm.ParametricValue)avmValueExpression; var avmAssignedValue = avmParametricValue.AssignedValue as FixedValue; var avmDefault = avmParametricValue.Default as FixedValue; var avmMaximum = avmParametricValue.Maximum as FixedValue; var avmMinimum = avmParametricValue.Minimum as FixedValue; if (avmAssignedValue != null && avmAssignedValue.Value != null) { cyphyTestBenchParameter.Attributes.Value = avmAssignedValue.Value; } if (avmDefault != null && avmDefault.Value != null) { cyphyTestBenchParameter.Attributes.DefaultValue = avmDefault.Value; } if (avmMinimum != null && !string.IsNullOrEmpty(avmMinimum.Value) && avmMaximum != null && !string.IsNullOrEmpty(avmMaximum.Value)) { cyphyTestBenchParameter.Attributes.Range = String.Format("{0}..{1}", avmMinimum.Value, avmMaximum.Value); } } } #endregion } #endregion #region Create Metrics var metricCache = new List <Tuple <avm.Metric, CyPhy.Metric> >(); foreach (var avmMetric in avmTestBench.Metric) { var cyphyTestBenchMetric = CyPhyClasses.Metric.Create(cyphyTestBench); cyphyTestBenchMetric.Name = avmMetric.Name; cyphyTestBenchMetric.Attributes.Description = avmMetric.Notes; SetLayoutData(avmMetric, cyphyTestBenchMetric.Impl); metricCache.Add(new Tuple <avm.Metric, CyPhy.Metric>(avmMetric, cyphyTestBenchMetric)); } #endregion #region Create valueflows // Start with TopLevelSystemUnderTest if (avmSystemUnderTest != null && cyphySystemUnderTest != null) { /* * // Parameters and properties * foreach (var avmParameter in avmSystemUnderTest.PropertyInstance.Where(x=>x.Value!=null)) * { * // Target of valueflow * if (avmParameter.Value.ValueExpression is DerivedValue) * { * var derivedValue = (DerivedValue)avmParameter.Value.ValueExpression; * // Look for the parameter instance * dynamic cyphyValueflowSrc = cyphySystemUnderTestReferred.ParameterCollection.FirstOrDefault(x => x.Attributes.ID == avmParameter.IDinSourceModel); * * // Maybe it is a property * if (cyphyValueflowSrc == null) * { * cyphyValueflowSrc = cyphySystemUnderTestReferred.PropertyCollection.FirstOrDefault(x => x.Attributes.ID == avmParameter.IDinSourceModel); * } * * // TODO: Else warning * if (cyphyValueflowSrc != null) * { * var cachePair = parameterCache.FirstOrDefault(x=>x.Item1.Value.ID == derivedValue.ValueSource); * if (cachePair != null) * { * var cyphyValueflowDst = cachePair.Item2; * var srcRef = ((CyPhy.ValueFlowTarget)cyphyValueflowSrc).ParentContainer is CyPhyClasses.TestBench ? null : cyphySystemUnderTest; * var dstRef = ((CyPhy.ValueFlowTarget)cyphyValueflowDst).ParentContainer is CyPhyClasses.TestBench ? null : cyphySystemUnderTest; * // Doesnt work * CyPhyClasses.ValueFlow.Connect((CyPhy.ValueFlowTarget)cyphyValueflowSrc, (CyPhy.ValueFlowTarget)cyphyValueflowDst, srcRef, dstRef, cyphyTestBench); * //CyPhyClasses.ValueFlow.ConnectGeneric((CyPhy.ValueFlowTarget)cyphyValueflowDst, (CyPhy.ValueFlowTarget)cyphyValueflowSrc, null, null, cyphyTestBench); * } * } * } * } */ } #endregion return(cyphyTestBench); }