Exemple #1
0
        /// <summary>
        /// Gets a new instance of an elaborator based on a given context.
        /// </summary>
        /// <param name="subject">Given context</param>
        /// <param name="logger">Logger which can be used to log messages.</param>
        /// <returns>A new instance of a context aware elaborator.</returns>
        /// <exception cref="ArgumentNullException">If subject or logger null.</exception>
        /// <exception cref="NotSupportedException">If subject does not have an associated elaborator class.</exception>
        public static Elaborator GetElaborator(MgaModel subject, CyPhyGUIs.GMELogger logger, bool UnrollConnectors)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            var        factory    = new CyPhyTypeFactory(subject.Project.RootMeta);
            Elaborator elaborator = null;

            if (subject.MetaBase.MetaRef == factory.TestBenchMeta ||
                subject.MetaBase.MetaRef == factory.CADTestBenchMeta ||
                subject.MetaBase.MetaRef == factory.BlastTestBenchMeta ||
                subject.MetaBase.MetaRef == factory.BallisticTestBenchMeta ||
                subject.MetaBase.MetaRef == factory.CFDTestBenchMeta ||
                subject.MetaBase.MetaRef == factory.KinematicTestBenchMeta ||
                subject.MetaBase.MetaRef == factory.CarTestBenchMeta)
            {
                elaborator = new TestBenchTypeElaborator(subject, UnrollConnectors);
            }
            else if (subject.MetaBase.MetaRef == factory.ComponentAssemblyMeta)
            {
                elaborator = new ComponentAssemblyElaborator(subject, UnrollConnectors);
            }
            else if (subject.MetaBase.MetaRef == factory.DesignContainerMeta)
            {
                elaborator = new DesignContainerElaborator(subject, UnrollConnectors);
            }
            else
            {
                throw new NotSupportedException(string.Format("Not supported context: {0} [{1}]", subject.Name, subject.MetaBase.Name));
            }

            if (subject.IsLibObject)
            {
                throw new NotSupportedException(string.Format("{0} cannot be a library object.", subject.MetaBase.Name));
            }

            elaborator.Logger  = logger;
            elaborator.Factory = factory;
            // TODO: how can we determine this?
            elaborator.IsElaborated = false;

            return(elaborator);
        }
        /// <summary>
        /// Elaborates the give test bench.
        /// </summary>
        public override void Elaborate()
        {
            // gets all objects within the test bench in any depth.
            MgaFilter filter     = this.Subject.Project.CreateFilter();
            var       allObjects = this.Subject.GetDescendantFCOs(filter);

            // list of test injection points in the test bench
            List <MgaReference> tips = new List <MgaReference>();

            foreach (MgaFCO obj in allObjects)
            {
                // add object to traceability
                this.Traceability.Add(obj.ID, obj.ID);

                if (this.Factory.TestInjectionPointsMeta.Contains(obj.MetaBase.MetaRef))
                {
                    // if object is a kind of test injection point
                    if (obj is MgaReference)
                    {
                        // if it is a reference
                        if ((obj as MgaReference).Referred == null)
                        {
                            this.Logger.WriteWarning(string.Format("{0} [{1}] was ignored and skipped, because it points to a null reference.", obj.Name, obj.MetaBase.Name));
                        }
                        else
                        {
                            // has a valid reference which is not null
                            tips.Add(obj as MgaReference);
                        }
                    }
                    else
                    {
                        this.Logger.WriteError(string.Format("{0} [{1}] is not a reference, therefore it was ignored and skipped.", obj.Name, obj.MetaBase.Name));
                    }
                }
            }

            // get the top level system under test object for this test bench
            var tlsut = allObjects.OfType <MgaReference>().FirstOrDefault(x => x.MetaBase.Name == "TopLevelSystemUnderTest");

            // ASSUME we have exactly one

            // make sure it is not null
            if (tlsut == null)
            {
                this.Logger.WriteWarning(string.Format("No top level system under test object in {0} [{1}]", this.Subject.Name, this.Subject.MetaBase.Name));
                this.Logger.WriteWarning("Assumes [{0}] has been elaborated...", this.Subject.MetaBase.Name);
                this.IsElaborated = true;
                return;
            }

            // it has a null reference
            if (tlsut.Referred == null)
            {
                throw new ElaboratorException(string.Format("Top level system under test object in {0} [{1}] is a null reference.", this.Subject.Name, this.Subject.MetaBase.Name));
            }

            // switch the top level system under test to a Component Assembly
            // FIXME: what if it is not a component assembly ???
            string tlsu_referred_id = tlsut.Referred.ID;
            var    ca_tlsut         = this.SwitchReferenceToModel(this.Subject, tlsut, false);

            // delete the reference object.
            tlsut.DestroyObject();

            // component assembly elaborator used to elaborate the Top Level System Under Test object.
            ComponentAssemblyElaborator componentAssemblyElaborator = null;

            // get a Componenet assembly elaborator for the top level system under test object.
            componentAssemblyElaborator = Elaborator.GetElaborator <ComponentAssemblyElaborator>(ca_tlsut, this.Logger, UnrollConnectors);

            // pass our current traceability information
            componentAssemblyElaborator.Traceability   = this.Traceability;
            componentAssemblyElaborator.ComponentGUIDs = this.ComponentGUIDs;

            // elaborate the top level system under test object
            componentAssemblyElaborator.Elaborate();

            // TODO: Elaborate test components

            // get a look up map for all test injection point references
            var map = componentAssemblyElaborator.GetReverseLookupMap(tips.Select(x => x.Referred.ID));

            map[tlsu_referred_id] = new MgaFCO[] { (MgaFCO)ca_tlsut }.ToList();

            // gather all information about test injection points, pretend everything is ok.
            bool success = true;

            foreach (MgaReference tip in tips)
            {
                // get the new targets for this test injection point
                var tipTargets = map[tip.Referred.ID];

                // looking for exactly one target
                if (tipTargets.Count == 0)
                {
                    // no target mark it as failure
                    success = false;
                    this.Logger.WriteFailed("{0} [{1}] --> {2} [{3}] was not found in traceability.", tip.Name, tip.MetaBase.Name, tip.Referred.Name, tip.Referred.MetaBase.Name);
                }
                else if (tipTargets.Count == 1)
                {
                    // exactly one target
                    try
                    {
                        // redirect test injection point to the new target
                        var switcher = new ReferenceSwitcher.ReferenceSwitcherInterpreter();
                        switcher.SwitchReference(tipTargets[0] as IMgaFCO, tip as IMgaReference);
                    }
                    catch (Exception ex)
                    {
                        success = false;

                        // handle failures for this (use case we can lose ports/connections/
                        // what if something is an instance/subtype/readonly etc...
                        this.Logger.WriteFailed("{0} [{1}] --> {2} [{3}] redirecting to --> {4} [{5}]", tip.Name, tip.MetaBase.Name, tip.Referred.Name, tip.Referred.MetaBase.Name, tipTargets[0].Name, tipTargets[0].MetaBase.Name);
                        this.Logger.WriteDebug(ex.ToString());
                    }
                }
                else
                {
                    // tipTarget.Count > 1
                    // more than one possible targets, this case is ambiguous, therefore mark it as failure.
                    success = false;
                    this.Logger.WriteFailed("{0} [{1}] --> {2} [{3}] was found more than once in the system - the choice is ambiguous.", tip.Name, tip.MetaBase.Name, tip.Referred.Name, tip.Referred.MetaBase.Name);
                }
            }

            if (tips.Any())
            {
                if (success)
                {
                    // check if no problems
                    this.Logger.WriteInfo("All test injection points were redirected successfully.");
                }
                else
                {
                    // some problems occured, must raise an exception
                    throw new ElaboratorException("At least one test injection point was not redirected successfully. See log messages above.");
                }
            }

            // if this point is reached, mark it successful.
            this.IsElaborated = true;
        }