/// <summary> /// saves workspace comparison object and remaps ids for saved data to the new ids /// </summary> /// <param name="wcd1"></param> /// <param name="filePathBase"></param> /// <param name="executionDuration"></param> /// <param name="modelsGuidToIdMap"></param> public static void SaveWorkspaceComparisonDataWithNonGuidIds(serializationTestUtils.WorkspaceComparisonData wcd1, string filePathBase, TimeSpan executionDuration, Dictionary <Guid, string> modelsGuidToIdMap) { var nodeData = new Dictionary <string, Dictionary <string, object> >(); foreach (var d in wcd1.NodeDataMap) { var t = wcd1.NodeTypeMap[d.Key]; var nodeDataDict = new Dictionary <string, object>(); nodeDataDict.Add("nodeType", t.ToString()); nodeDataDict.Add("portValues", d.Value); nodeData.Add(d.Key.ToString(), nodeDataDict); } var workspaceDataDict = new Dictionary <string, object>(); workspaceDataDict.Add("nodeData", nodeData); workspaceDataDict.Add("executionDuration", executionDuration.TotalSeconds); var dataMapStr = JsonConvert.SerializeObject(workspaceDataDict, new JsonSerializerSettings() { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); //replace all the guids in the data file with all of our remapped ids. foreach (var guidKey in modelsGuidToIdMap.Keys) { dataMapStr = dataMapStr.Replace(guidKey.ToString(), modelsGuidToIdMap[guidKey]); } var dataPath = filePathBase + ".data"; if (File.Exists(dataPath)) { File.Delete(dataPath); } File.WriteAllText(dataPath, dataMapStr); }
/// <summary> /// saves the workspace comparison object to disk in a .data file /// </summary> /// <param name="wcd1"></param> /// <param name="filePathBase"></param> /// <param name="executionDuration"></param> /// <param name="modelGuidToIDMap"></param> public static void SaveWorkspaceComparisonData(serializationTestUtils.WorkspaceComparisonData wcd1, string filePathBase, TimeSpan executionDuration, Dictionary <Guid, string> modelGuidToIDMap = null) { var nodeData = new Dictionary <string, Dictionary <string, object> >(); foreach (var d in wcd1.NodeDataMap) { var t = wcd1.NodeTypeMap[d.Key]; var nodeDataDict = new Dictionary <string, object>(); nodeDataDict.Add("nodeType", t.ToString()); nodeDataDict.Add("portValues", d.Value); nodeData.Add(d.Key.ToString(), nodeDataDict); } var workspaceDataDict = new Dictionary <string, object>(); workspaceDataDict.Add("nodeData", nodeData); workspaceDataDict.Add("executionDuration", executionDuration.TotalSeconds); var dataMapStr = JsonConvert.SerializeObject(workspaceDataDict, new JsonSerializerSettings() { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Culture = CultureInfo.InvariantCulture }); var dataPath = filePathBase + ".data"; if (File.Exists(dataPath)) { File.Delete(dataPath); } File.WriteAllText(dataPath, dataMapStr); }
private void DoWorkspaceOpenAndCompare(string filePath, string dirName, Func <DynamoModel, string, string> saveFunction, Action <serializationTestUtils.WorkspaceComparisonData, serializationTestUtils.WorkspaceComparisonData, Dictionary <Guid, String> > workspaceCompareFunction, Action <serializationTestUtils.WorkspaceComparisonData, string, TimeSpan, Dictionary <Guid, string> > workspaceDataSaveFunction) { var openPath = filePath; if (bannedTests.Any(t => filePath.Contains(t))) { Assert.Inconclusive("Skipping test known to kill the test framework..."); } OpenModel(openPath); var model = CurrentDynamoModel; var ws1 = model.CurrentWorkspace; ws1.Description = "TestDescription"; var dummyNodes = ws1.Nodes.Where(n => n is DummyNode); if (dummyNodes.Any()) { Assert.Inconclusive("The Workspace contains dummy nodes for: " + string.Join(",", dummyNodes.Select(n => n.Name).ToArray())); } var cbnErrorNodes = ws1.Nodes.Where(n => n is CodeBlockNodeModel && n.State == ElementState.Error); if (cbnErrorNodes.Any()) { Assert.Inconclusive("The Workspace contains code block nodes in error state due to which rest " + "of the graph will not execute; skipping test ..."); } if (((HomeWorkspaceModel)ws1).RunSettings.RunType == Models.RunType.Manual) { RunCurrentModel(); } var wcd1 = new serializationTestUtils.WorkspaceComparisonData(ws1, CurrentDynamoModel.EngineController); var dirPath = Path.Combine(Path.GetTempPath(), dirName); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } var fi = new FileInfo(filePath); var filePathBase = dirPath + @"\" + Path.GetFileNameWithoutExtension(fi.Name); serializationTestUtils.ConvertCurrentWorkspaceToDesignScriptAndSave(filePathBase, CurrentDynamoModel); string json = saveFunction(model, filePathBase); workspaceDataSaveFunction(wcd1, filePathBase, lastExecutionDuration, modelsGuidToIdMap); lastExecutionDuration = new TimeSpan(); var ws2 = WorkspaceModel.FromJson(json, model.LibraryServices, model.EngineController, model.Scheduler, model.NodeFactory, DynamoModel.IsTestMode, false, model.CustomNodeManager); if (ws2 is CustomNodeWorkspaceModel) { model.AddCustomNodeWorkspace((CustomNodeWorkspaceModel)ws2); } foreach (var c in ws2.Connectors) { Assert.NotNull(c.Start.Owner, "The node is not set for the start of connector " + c.GUID + ". The end node is " + c.End.Owner + "."); Assert.NotNull(c.End.Owner, "The node is not set for the end of connector " + c.GUID + ". The start node is " + c.Start.Owner + "."); } // The following logic is taken from the DynamoModel.Open method. // It assumes a single home workspace model. So, we remove all // others, before adding a new one. if (ws2 is HomeWorkspaceModel) { var currentHomeSpaces = model.Workspaces.OfType <HomeWorkspaceModel>().ToList(); if (currentHomeSpaces.Any()) { var end = ws2 is HomeWorkspaceModel ? 0 : 1; for (var i = currentHomeSpaces.Count - 1; i >= end; i--) { model.RemoveWorkspace(currentHomeSpaces[i]); } } model.AddWorkspace(ws2); var hws = ws2 as HomeWorkspaceModel; if (hws != null) { model.ResetEngine(); if (hws.RunSettings.RunType == RunType.Periodic) { hws.StartPeriodicEvaluation(); } } model.CurrentWorkspace = ws2; } Assert.NotNull(ws2); dummyNodes = ws2.Nodes.Where(n => n is DummyNode); if (dummyNodes.Any()) { Assert.Inconclusive("The Workspace contains dummy nodes for: " + string.Join(",", dummyNodes.Select(n => n.Name).ToArray())); } var wcd2 = new serializationTestUtils.WorkspaceComparisonData(ws2, CurrentDynamoModel.EngineController); workspaceCompareFunction(wcd1, wcd2, modelsGuidToIdMap); var functionNodes = ws2.Nodes.Where(n => n is Function).Cast <Function>(); if (functionNodes.Any()) { Assert.True(functionNodes.All(n => CurrentDynamoModel.CustomNodeManager.LoadedDefinitions.Contains(n.Definition))); } foreach (var c in ws2.Connectors) { Assert.NotNull(c.Start.Owner); Assert.NotNull(c.End.Owner); Assert.True(ws2.Nodes.Contains(c.Start.Owner)); Assert.True(ws2.Nodes.Contains(c.End.Owner)); } //assert that the inputs in the saved json file are the same as those we can gather from the //graph at runtime - because we don't deserialize these directly we check the json itself. //Use load vs parse to preserve date time strings. var jsonReader = new JsonTextReader(new StringReader(json)); jsonReader.DateParseHandling = DateParseHandling.None; var jObject = JObject.Load(jsonReader); var jToken = jObject["Inputs"]; var inputs = jToken.ToArray().Select(x => x.ToObject <NodeInputData>()).ToList(); var inputs2 = ws1.Nodes.Where(x => x.IsSetAsInput == true && x.InputData != null).Select(input => input.InputData).ToList(); //inputs2 might come from a WS with non guids, so we need to replace the ids with guids if they exist in the map foreach (var input in inputs2) { if (modelsGuidToIdMap.ContainsKey(input.Id)) { input.Id = GuidUtility.Create(GuidUtility.UrlNamespace, modelsGuidToIdMap[input.Id]); } } Assert.IsTrue(inputs.SequenceEqual(inputs2)); //assert that the outputs in the saved json file are the same as those we can gather from the //graph at runtime - because we don't deserialize these directly we check the json itself. var jTokenOutput = jObject["Outputs"]; var outputs = jTokenOutput.ToArray().Select(x => x.ToObject <NodeOutputData>()).ToList(); var outputs2 = ws1.Nodes.Where(x => x.IsSetAsOutput == true && x.OutputData != null).Select(output => output.OutputData).ToList(); //Outputs2 might come from a WS with non guids, so we need to replace the ids with guids if they exist in the map foreach (var output in outputs2) { if (modelsGuidToIdMap.ContainsKey(output.Id)) { output.Id = GuidUtility.Create(GuidUtility.UrlNamespace, modelsGuidToIdMap[output.Id]); } } Assert.IsTrue(outputs.SequenceEqual(outputs2)); }
/// <summary> /// saves workspace comparison object and remaps ids for saved data to the new ids /// </summary> /// <param name="wcd1"></param> /// <param name="filePathBase"></param> /// <param name="executionDuration"></param> /// <param name="modelsGuidToIdMap"></param> public static void SaveWorkspaceComparisonDataWithNonGuidIds(serializationTestUtils.WorkspaceComparisonData wcd1, string filePathBase, TimeSpan executionDuration, Dictionary <Guid, string> modelsGuidToIdMap) { var nodeData = new Dictionary <string, Dictionary <string, object> >(); foreach (var d in wcd1.NodeDataMap) { var t = wcd1.NodeTypeMap[d.Key]; var nodeDataDict = new Dictionary <string, object>(); nodeDataDict.Add("nodeType", t.ToString()); nodeDataDict.Add("portValues", d.Value); nodeData.Add(d.Key.ToString(), nodeDataDict); } var workspaceDataDict = new Dictionary <string, object>(); workspaceDataDict.Add("nodeData", nodeData); workspaceDataDict.Add("executionDuration", executionDuration.TotalSeconds); var dataMapStr = JsonConvert.SerializeObject(workspaceDataDict, new JsonSerializerSettings() { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Culture = CultureInfo.InvariantCulture }); //replace all the guids in the data file with all of our remapped ids. foreach (var guidKey in modelsGuidToIdMap.Keys) { dataMapStr = dataMapStr.Replace(guidKey.ToString(), modelsGuidToIdMap[guidKey]); } // If "DynamoCoreWPFTests" test copy .data file to additional structured folder location if (filePathBase.Contains("DynamoCoreWPFTests")) { string structuredTestPath; string fileName = Path.GetFileNameWithoutExtension(filePathBase); string flattenedTestPath = Path.GetTempPath() + "jsonWithView_nonGuidIds\\" + fileName; string extension = Path.GetExtension(filePathBase); string pathWithoutExt = filePathBase.Substring(0, filePathBase.Length - extension.Length); // Determine if .dyn or .dyf // If .dyn and .dyf share common file name .ds and .data files is collide // To avoid this append _dyf to .data and .ds files for all .dyf files if (extension == ".dyf") { structuredTestPath = pathWithoutExt + "_dyf.data"; } else { structuredTestPath = pathWithoutExt + ".data"; } // Write to structured path if (File.Exists(structuredTestPath)) { File.Delete(structuredTestPath); } File.WriteAllText(structuredTestPath, dataMapStr); // Write to flattened path if (File.Exists(flattenedTestPath + ".data")) { File.Delete(flattenedTestPath + ".data"); } File.WriteAllText(flattenedTestPath + ".data", dataMapStr); } else { var dataPath = filePathBase + ".data"; if (File.Exists(dataPath)) { File.Delete(dataPath); } File.WriteAllText(dataPath, dataMapStr); } }
public static void CompareWorkspacesDifferentGuids(serializationTestUtils.WorkspaceComparisonData a, serializationTestUtils.WorkspaceComparisonData b, Dictionary <Guid, string> modelGuidsToIDmap) { var nodeDiff = a.NodeTypeMap.Select(x => x.Value).Except(b.NodeTypeMap.Select(x => x.Value)); if (nodeDiff.Any()) { Assert.Fail("The workspaces don't have the same number of nodes. The json workspace is missing: " + string.Join(",", nodeDiff.Select(i => i.ToString()))); } Assert.AreEqual(a.NodeCount, b.NodeCount, "The workspaces don't have the same number of nodes."); Assert.AreEqual(a.ConnectorCount, b.ConnectorCount, "The workspaces don't have the same number of connectors."); foreach (var kvp in a.InportCountMap) { var countA = kvp.Value; //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var countB = b.InportCountMap[newGuid]; Assert.AreEqual(countA, countB, string.Format("One {0} node has {1} inports, while the other has {2}", a.NodeTypeMap[kvp.Key], countA, countB)); } foreach (var kvp in a.OutportCountMap) { var countA = kvp.Value; //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var countB = b.OutportCountMap[newGuid]; Assert.AreEqual(countA, countB, string.Format("One {0} node has {1} outports, while the other has {2}", a.NodeTypeMap[kvp.Key], countA, countB)); } foreach (var portkvp in a.PortDataMap) { //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[portkvp.Key]); Assert.IsTrue(b.PortDataMap.ContainsKey(newGuid)); var aPort = a.PortDataMap[portkvp.Key]; var bPort = b.PortDataMap[newGuid]; Assert.AreEqual(aPort.UseLevels, bPort.UseLevels); Assert.AreEqual(aPort.KeepListStructure, bPort.KeepListStructure); Assert.AreEqual(aPort.Level, bPort.Level); Assert.AreEqual(aPort.Description, bPort.Description); } foreach (var kvp in a.NodeReplicationMap) { var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var valueA = kvp.Value; var valueB = b.NodeReplicationMap[newGuid]; Assert.AreEqual(valueA, valueB); } foreach (var kvp in a.NodeDataMap) { var valueA = kvp.Value; //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var valueB = b.NodeDataMap[newGuid]; Assert.AreEqual(a.NodeTypeMap[kvp.Key], b.NodeTypeMap[newGuid]); try { // When values are geometry, sometimes the creation // of the string representation for forming this message // fails. Assert.AreEqual(valueA, valueB, string.Format("Node Type:{0} value, {1} is not equal to {2}", a.NodeTypeMap[kvp.Key], valueA, valueB)); } catch { continue; } } }
/// <summary> /// compare two workspace comparison objects that represent workspace models /// </summary> /// <param name="a"> first workspace data to compare</param> /// <param name="b">second workspace data to compare</param> public static void CompareWorkspaceModels(serializationTestUtils.WorkspaceComparisonData a, serializationTestUtils.WorkspaceComparisonData b, Dictionary <Guid, string> c = null) { var nodeDiff = a.NodeTypeMap.Except(b.NodeTypeMap); if (nodeDiff.Any()) { Assert.Fail("The workspaces don't have the same number of nodes. The json workspace is missing: " + string.Join(",", nodeDiff.Select(i => i.Value.ToString()))); } Assert.AreEqual(a.Description, b.Description, "The workspaces don't have the same description."); Assert.AreEqual(a.NodeCount, b.NodeCount, "The workspaces don't have the same number of nodes."); Assert.AreEqual(a.ConnectorCount, b.ConnectorCount, "The workspaces don't have the same number of connectors."); foreach (var kvp in a.InportCountMap) { var countA = kvp.Value; var countB = b.InportCountMap[kvp.Key]; Assert.AreEqual(countA, countB, string.Format("One {0} node has {1} inports, while the other has {2}", a.NodeTypeMap[kvp.Key], countA, countB)); } foreach (var kvp in a.OutportCountMap) { var countA = kvp.Value; var countB = b.OutportCountMap[kvp.Key]; Assert.AreEqual(countA, countB, string.Format("One {0} node has {1} outports, while the other has {2}", a.NodeTypeMap[kvp.Key], countA, countB)); } foreach (var portkvp in a.PortDataMap) { Assert.IsTrue(b.PortDataMap.ContainsKey(portkvp.Key)); Assert.AreEqual(a.PortDataMap[portkvp.Key], b.PortDataMap[portkvp.Key]); } foreach (var kvp in a.NodeReplicationMap) { var valueA = kvp.Value; var valueB = b.NodeReplicationMap[kvp.Key]; Assert.AreEqual(valueA, valueB); } foreach (var kvp in a.NodeDataMap) { var valueA = kvp.Value; var valueB = b.NodeDataMap[kvp.Key]; Assert.AreEqual(a.NodeTypeMap[kvp.Key], b.NodeTypeMap[kvp.Key]); try { // When values are geometry, sometimes the creation // of the string representation for forming this message // fails. Assert.AreEqual(valueA, valueB, string.Format("Node Type:{0} value, {1} is not equal to {2}", a.NodeTypeMap[kvp.Key], valueA, valueB)); } catch { continue; } } foreach (var kvp in a.InputsMap) { var vala = kvp.Value; var valb = b.InputsMap[kvp.Key]; Assert.AreEqual(vala, valb, "input datas are not the same."); } }
public static void CompareWorkspacesDifferentGuids(serializationTestUtils.WorkspaceComparisonData a, serializationTestUtils.WorkspaceComparisonData b, Dictionary <Guid, string> modelGuidsToIDmap) { var nodeDiff = a.NodeTypeMap.Select(x => x.Value).Except(b.NodeTypeMap.Select(x => x.Value)); // Ignore IntegerSlider nodes as they are being read as IntegerSlider64Bit JSON nodes. // TODO: Remove this filter once we deprecate IntegerSlider nodes in a future Dynamo version. nodeDiff = nodeDiff.Where(nd => nd.FullName != "CoreNodeModels.Input.IntegerSlider"); if (nodeDiff.Any()) { Assert.Fail("The workspaces don't have the same number of nodes. The json workspace is missing: " + string.Join(",", nodeDiff.Select(i => i.ToString()))); } Assert.AreEqual(a.NodeCount, b.NodeCount, "The workspaces don't have the same number of nodes."); Assert.AreEqual(a.ConnectorCount, b.ConnectorCount, "The workspaces don't have the same number of connectors."); foreach (var kvp in a.InportCountMap) { var countA = kvp.Value; //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var countB = b.InportCountMap[newGuid]; Assert.AreEqual(countA, countB, string.Format("One {0} node has {1} inports, while the other has {2}", a.NodeTypeMap[kvp.Key], countA, countB)); } foreach (var kvp in a.OutportCountMap) { var countA = kvp.Value; //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var countB = b.OutportCountMap[newGuid]; Assert.AreEqual(countA, countB, string.Format("One {0} node has {1} outports, while the other has {2}", a.NodeTypeMap[kvp.Key], countA, countB)); } foreach (var portkvp in a.PortDataMap) { //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[portkvp.Key]); Assert.IsTrue(b.PortDataMap.ContainsKey(newGuid)); var aPort = a.PortDataMap[portkvp.Key]; var bPort = b.PortDataMap[newGuid]; Assert.AreEqual(aPort.UseLevels, bPort.UseLevels); Assert.AreEqual(aPort.KeepListStructure, bPort.KeepListStructure); Assert.AreEqual(aPort.Level, bPort.Level); // With the change to JSON based IntegerSlider nodes returning 64 bit integers, // the description between the old XML and the new JSON based workspaces will be // "Int32" and "Int64" respectively. if (aPort.Description == "Int32") { Assert.IsTrue(bPort.Description == "Int32" || bPort.Description == "Int64"); } else { Assert.AreEqual(aPort.Description, bPort.Description); } } foreach (var kvp in a.NodeReplicationMap) { var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var valueA = kvp.Value; var valueB = b.NodeReplicationMap[newGuid]; Assert.AreEqual(valueA, valueB); } foreach (var kvp in a.NodeDataMap) { var valueA = kvp.Value; //convert the old guid to the new guid var newGuid = GuidUtility.Create(GuidUtility.UrlNamespace, modelGuidsToIDmap[kvp.Key]); var valueB = b.NodeDataMap[newGuid]; // Ignore IntegerSlider nodes as they are being read as IntegerSlider64Bit JSON nodes. // TODO: Remove this filter once we deprecate IntegerSlider nodes in a future Dynamo version. if (a.NodeTypeMap[kvp.Key].FullName == "CoreNodeModels.Input.IntegerSlider") { Assert.AreEqual("CoreNodeModels.Input.IntegerSlider64Bit", b.NodeTypeMap[newGuid].FullName); continue; } Assert.AreEqual(a.NodeTypeMap[kvp.Key], b.NodeTypeMap[newGuid]); try { // When values are geometry, sometimes the creation // of the string representation for forming this message // fails. Assert.AreEqual(valueA, valueB, string.Format("Node Type:{0} value, {1} is not equal to {2}", a.NodeTypeMap[kvp.Key], valueA, valueB)); } catch { continue; } } }