public void GraphStructureValidator_NoCircularLinkIfDecision() { Experiment experiment = ExperimentManager.New(); experiment.ExperimentInfo.FilePath = "C:\\somefakelocation\\mockExperiment.teml"; ExperimentNode node1 = experiment.AddComponentFromDefinition(m_emptyComponentMetaDefinition, 5, 5); ExperimentNode node2 = experiment.AddComponentFromDefinition(m_emptyComponentMetaDefinition, 15, 15); var decisionNode = AddDecisionToExperiment(experiment, 10, 10); decisionNode.Data.Metadata = CompileMockDecision(""); experiment.AddConnection(experiment.StartNode, node1); experiment.AddConnection(node1, node2); experiment.AddConnection(node2, decisionNode); experiment.AddConnection(decisionNode, node1); experiment.AddConnection(decisionNode, experiment.EndNode); Assert.IsFalse(node1.HasError); Assert.IsFalse(node2.HasError); Assert.IsFalse(decisionNode.HasError); RunnableNodeFactory templateGraphNodesFactory = new RunnableNodeFactory(AppContext.WorkspaceInstance); RunnableExperimentBase template = GraphAdapter.Adapt(experiment, templateGraphNodesFactory, AppContext.Components, AppContext.WorkspaceInstance.TypeDirectories); Assert.IsFalse(node1.HasError); Assert.IsFalse(node2.HasError); Assert.IsFalse(decisionNode.HasError); Assert.IsFalse(template.IsEmpty); Assert.AreEqual(5, template.Nodes.Count); //check all edges foreach (RunnableNode node in template.Nodes) { if (node is RunnableDecisionNode) { //in this graph decision node has only two outcoming edges Assert.AreEqual(2, node.NextNodes.Count); } else if (node is RunnableEndNode) { //end node has none outcoming edges Assert.AreEqual(0, node.NextNodes.Count); } else { //all other nodes in this graph has only one outcoming edge Assert.AreEqual(1, node.NextNodes.Count); } } }
public void ValidateInputMapping_Decision_CorrectMapping() { Experiment experiment = ExperimentManager.New(); experiment.ExperimentInfo.FilePath = "C:\\somefakelocation\\mockExperiment.teml"; ExperimentNode writerNode = experiment.AddComponentFromDefinition(m_componentWriterMetaDefinition, 15, 15); (writerNode.Data.Metadata as ComponentMetadata).IOSpec.Output["testoutput"].MappedTo = "test"; ExperimentNode readerNode = experiment.AddComponentFromDefinition(m_componentReaderMetaDefinition, 25, 25); (readerNode.Data.Metadata as ComponentMetadata).IOSpec.Input["testinput"].MappedTo = "test"; ExperimentNode incrementerNode = experiment.AddComponentFromDefinition(m_incrementerComponentMetaDefinition, 35, 35); (incrementerNode.Data.Metadata as ComponentMetadata).IOSpec.Input["testinput"].MappedTo = "test"; (incrementerNode.Data.Metadata as ComponentMetadata).IOSpec.Output["testoutput"].MappedTo = "test"; var decisionNode = AddDecisionToExperiment(experiment, 10, 10); //code doesn't really matter in this case, because we don't execute dispatcher string decisionCode = ""; decisionNode.Data.Metadata = CompileMockDecision(decisionCode); experiment.AddConnection(experiment.StartNode, writerNode); experiment.AddConnection(writerNode, readerNode); experiment.AddConnection(readerNode, decisionNode); experiment.AddConnection(decisionNode, incrementerNode); experiment.AddConnection(incrementerNode, readerNode); experiment.AddConnection(decisionNode, experiment.EndNode); Assert.IsFalse(writerNode.HasError); Assert.IsFalse(readerNode.HasError); Assert.IsFalse(incrementerNode.HasError); Assert.IsFalse(decisionNode.HasError); RunnableNodeFactory templateGraphNodesFactory = new RunnableNodeFactory(AppContext.WorkspaceInstance); RunnableExperimentBase template = GraphAdapter.Adapt(experiment, templateGraphNodesFactory, AppContext.Components, AppContext.WorkspaceInstance.TypeDirectories); Assert.IsFalse(writerNode.HasError); Assert.IsFalse(readerNode.HasError); Assert.IsFalse(incrementerNode.HasError); Assert.IsFalse(decisionNode.HasError); Assert.IsFalse(template.IsEmpty); Assert.AreEqual(6, template.Nodes.Count); //check all edges foreach (RunnableNode node in template.Nodes) { if (node is RunnableDecisionNode) { //in this graph decision node has only two outcoming edges Assert.AreEqual(2, node.NextNodes.Count); } else if (node is RunnableEndNode) { //end node has none outcoming edges Assert.AreEqual(0, node.NextNodes.Count); } else { //all other nodes in this graph has only one outcoming edge Assert.AreEqual(1, node.NextNodes.Count); } } }
/// <summary> /// Prepares the benchmark experiment. /// </summary> /// <param name="experimentToBeBenchmarked">The experiment to be benchmarked.</param> /// <exception cref="TraceLab.Core.Exceptions.ExperimentLoadException">throws if experiment load fails</exception> /// <param name="library">The library.</param> public void PrepareBenchmarkExperiment(Experiment experimentToBeBenchmarked, ComponentsLibrary library) { //load benchmark experiment Experiment benchmarkExperiment = ExperimentManager.Load(BenchmarkInfo.FilePath, library); //update benchmark experiment info, so that it refers to the same benchmark info (LoadExperiment would not read BenchmarkInfo, as it only reads ExperimentInfo) benchmarkExperiment.ExperimentInfo = BenchmarkInfo; //2. find template node to be replaced ExperimentNode templateNode = null; foreach (ExperimentNode node in benchmarkExperiment.Vertices) { if (node.Data.Metadata is ComponentTemplateMetadata) { templateNode = node; break; } } if (templateNode == null) { throw new TraceLab.Core.Exceptions.BenchmarkException("Template node has not been found in the benchmark experiment. The benchmark experiment is corrupted."); } //3. export current experiment into composite component foreach (BenchmarkItemSetting <IOItem> item in BenchmarkInputSetting) { item.SelectedSetting.Include = true; } foreach (BenchmarkItemSetting <IOItem> item in BenchmarkOutputsSetting) { item.SelectedSetting.Include = true; } //create temporary component source - note it is just a assembly source name file to satisfy Metadata Assembly requirement //the file is not going to be created (this is UGLY - do refactoring) string tempSource = System.IO.Path.Combine(BenchmarkInfo.FilePath, "temporary"); m_setup.CompositeComponentLocationFilePath = tempSource; CompositeComponentMetadataDefinition definition = m_setup.GenerateCompositeComponentDefinition(); //4. Replace template node by removing it from graph, adding the new node, and reconnecting new not //Add composite component node ExperimentNode replacementNode = benchmarkExperiment.AddComponentFromDefinition(definition, templateNode.Data.X, templateNode.Data.Y); //connect replacement node to the same outgoing nodes as template node foreach (ExperimentNodeConnection nodeConnection in benchmarkExperiment.OutEdges(templateNode)) { benchmarkExperiment.AddConnection(replacementNode, nodeConnection.Target); } //connect replacement node to the same incoming nodes as template node foreach (ExperimentNodeConnection nodeConnection in benchmarkExperiment.InEdges(templateNode)) { benchmarkExperiment.AddConnection(nodeConnection.Source, replacementNode); //if the predecessor is a decision node update its decision code so that it matches new label FixDecisionCode(templateNode.Data.Metadata.Label, replacementNode.Data.Metadata.Label, nodeConnection.Source as ExperimentDecisionNode); } //finally remove the template node benchmarkExperiment.RemoveVertex(templateNode); //now remap io according to settings CompositeComponentMetadata compositeComponentDefinition = (CompositeComponentMetadata)replacementNode.Data.Metadata; foreach (BenchmarkItemSetting <IOItem> item in BenchmarkInputSetting) { item.SelectedSetting.Include = true; compositeComponentDefinition.IOSpec.Input[item.SelectedSetting.ItemSettingName].MappedTo = item.Item.MappedTo; } foreach (BenchmarkItemSetting <IOItem> item in BenchmarkOutputsSetting) { item.SelectedSetting.Include = true; compositeComponentDefinition.IOSpec.Output[item.SelectedSetting.ItemSettingName].MappedTo = item.Item.MappedTo; } BenchmarkExperiment = benchmarkExperiment; }