From 5da7c6a4888b83fc71496faea608811802b03357 Mon Sep 17 00:00:00 2001 From: Mariusz Date: Fri, 30 Apr 2021 21:42:12 +0200 Subject: [PATCH 1/2] Import all dependencies for the model #575 - added check if the required model exist. - fixed ADI test --- .../BuildingErrorsHandling/BuildErrors.cs | 8 +++ .../XML/BuildErrorsCollection.xml | 6 +++ .../NamespaceTableUnitTest.cs | 52 +++++++++++++++---- .../XML/UAModelContextUnitTest.cs | 18 +++++++ .../XMLModelsProblemsToReportUnitTest.cs | 6 +-- .../AddressSpaceContext.cs | 6 ++- .../DataSerialization/ExpandedNodeId.cs | 2 +- .../UANodeSetValidation/INamespaceTable.cs | 10 ++-- .../UANodeSetValidation/NamespaceTable.cs | 39 +++++++++++--- .../XML/ModelTableEntry.cs | 17 ------ .../UANodeSetValidation/XML/UAModelContext.cs | 4 +- 11 files changed, 124 insertions(+), 44 deletions(-) diff --git a/SemanticData/BuildingErrorsHandling/BuildErrors.cs b/SemanticData/BuildingErrorsHandling/BuildErrors.cs index c1e0f4f3..46fa27c7 100644 --- a/SemanticData/BuildingErrorsHandling/BuildErrors.cs +++ b/SemanticData/BuildingErrorsHandling/BuildErrors.cs @@ -279,6 +279,14 @@ public partial class BuildError Identifier = "P6-0F03000000", Descriptor = "SymbolicName contains characters that are not allowed. Only letters, digits or the underscore (‘_’) are permitted." }; } } /// + /// Error: P6-0F02000000; Focus: XML; The required model is missing. + /// + /// An instance of describing the error P6-0F02000000. + public static BuildError LackOfRequiredModel { get { return new BuildError() + { Focus = Focus.XML, + Identifier = "P6-0F02000000", + Descriptor = "The required model is missing." }; } } + /// /// Error: P3-XXXXX00000; Focus: DataType; Abstract DataType of the field of a concrete structure is not permitted. /// /// An instance of describing the error P3-XXXXX00000. diff --git a/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml b/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml index e6887d3e..bf968024 100644 --- a/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml +++ b/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml @@ -205,6 +205,12 @@ SymbolicName contains characters that are not allowed. Only letters, digits or the underscore (‘_’) are permitted. WrongSymbolicName + + XML + P6-0F02000000 + The required model is missing. + LackOfRequiredModel + DataType P3-XXXXX00000 diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs index 5099e93d..2eaabce8 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs @@ -26,7 +26,11 @@ public void ConstructorTest() List listOfExportedNamespaceTable = models.ToList(); Assert.AreEqual(1, listOfExportedNamespaceTable.Count); Assert.AreEqual(new Uri("http://opcfoundation.org/UA/"), listOfExportedNamespaceTable[0].ModelUri); - Assert.IsNull(listOfExportedNamespaceTable[0].RequiredModel); + Assert.ThrowsException(() => listOfExportedNamespaceTable[0].AccessRestrictions); + Assert.ThrowsException(() => listOfExportedNamespaceTable[0].PublicationDate); + Assert.ThrowsException(() => listOfExportedNamespaceTable[0].RequiredModel); + Assert.ThrowsException(() => listOfExportedNamespaceTable[0].RolePermissions); + Assert.ThrowsException(() => listOfExportedNamespaceTable[0].Version); } [TestMethod] @@ -60,9 +64,9 @@ public void GetURIIndexIndexTest() public void UpadateModelOrAppendTest() { NamespaceTable instance = new NamespaceTable(); - IModelTableEntry model1 = ModelTableEntry.GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1"); + IModelTableEntry model1 = GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1"); ((INamespaceTable)instance).RegisterModel(model1); - IModelTableEntry model2 = ModelTableEntry.GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1"); + IModelTableEntry model2 = GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1"); ((INamespaceTable)instance).RegisterModel(model2); IModelTableEntry model3 = instance.GetModelTableEntry(1); Assert.IsNotNull(model3); @@ -74,15 +78,45 @@ public void UpadateModelOrAppendTest() public void ModelsTest() { NamespaceTable instance = new NamespaceTable(); - ((INamespaceTable)instance).RegisterModel(ModelTableEntry.GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1")); - ((INamespaceTable)instance).RegisterModel(ModelTableEntry.GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest3")); - ((INamespaceTable)instance).RegisterModel(ModelTableEntry.GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest2")); - ((INamespaceTable)instance).RegisterModel(ModelTableEntry.GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1")); + ((INamespaceTable)instance).RegisterModel(GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1")); + ((INamespaceTable)instance).RegisterModel(GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest3")); + ((INamespaceTable)instance).RegisterModel(GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest2")); + ((INamespaceTable)instance).RegisterModel(GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1")); Assert.AreEqual(4, instance.Models.Count()); } - #region instrumentation + [TestMethod] + public void ValidateNamesapceTableTestMethod() + { + NamespaceTable instance = new NamespaceTable(); + List undefinedModels = new List(); + Assert.IsFalse(instance.ValidateNamesapceTable(y => undefinedModels.Add(y))); + Assert.AreEqual(1, undefinedModels.Count); + Assert.AreEqual(new Uri("http://opcfoundation.org/UA/"), undefinedModels[0]); + ((INamespaceTable)instance).RegisterModel(GetDefaultModelTableEntry("http://opcfoundation.org/UA/")); + Assert.IsTrue(instance.ValidateNamesapceTable(y => Assert.Fail())); + } + + #region fixtures + + /// + /// Gets the default model table entry. + /// + /// The model URI. + /// IModelTableEntry. + private static IModelTableEntry GetDefaultModelTableEntry(string modelUri) + { + return new ModelTableEntry + { + AccessRestrictions = 0xC, + ModelUri = modelUri, + PublicationDate = DateTime.UtcNow.Date, + RequiredModel = null, + RolePermissions = new XML.RolePermission[] { new XML.RolePermission() }, + Version = new Version(1, 0).ToString() + }; + } - #endregion instrumentation + #endregion fixtures } } \ No newline at end of file diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs index 0ea1d33c..76fea186 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs @@ -278,5 +278,23 @@ public void ParseUANodeSetModelHeaderCallBack() asMock.Verify(x => x.RegisterModel(It.IsAny()), Times.Once); Assert.AreEqual(0, trace.Count); } + + /// + /// Gets the default model table entry. + /// + /// The model URI. + /// IModelTableEntry. + private static IModelTableEntry GetDefaultModelTableEntry(string modelUri) + { + return new ModelTableEntry + { + AccessRestrictions = 0xC, + ModelUri = modelUri, + PublicationDate = DateTime.UtcNow.Date, + RequiredModel = null, + RolePermissions = new XML.RolePermission[] { new XML.RolePermission() }, + Version = new Version(1, 0).ToString() + }; + } } } \ No newline at end of file diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs index f2257d5a..f9e4c9d3 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs @@ -41,14 +41,14 @@ public void ADITest() Assert.AreEqual(24, traceContext.TraceList.Where(x => x.BuildError.Focus == Focus.NodeClass).Count()); Assert.AreEqual(0, traceContext.TraceList.Where(x => x.BuildError.Focus == Focus.NonCategorized).Count()); Assert.AreEqual(23, traceContext.TraceList.Where(x => x.BuildError.Focus == Focus.Reference).Count()); - Assert.AreEqual(1, traceContext.TraceList.Where(x => x.BuildError.Focus == Focus.XML).Count()); + Assert.AreEqual(2, traceContext.TraceList.Where(x => x.BuildError.Focus == Focus.XML).Count()); //errors - Assert.AreEqual(48, traceContext.TraceList.Count); + Assert.AreEqual(49, traceContext.TraceList.Count); Assert.AreEqual(3, traceContext.TraceList.Where(x => x.BuildError.Identifier == BuildError.NodeIdNotDefined.Identifier).Count()); Assert.AreEqual(5, traceContext.TraceList.Where(x => x.BuildError.Identifier == BuildError.UndefinedHasSubtypeTarget.Identifier).Count()); Assert.AreEqual(18, traceContext.TraceList.Where(x => x.BuildError.Identifier == BuildError.UndefinedHasTypeDefinition.Identifier).Count()); Assert.AreEqual(1, traceContext.TraceList.Where(x => x.BuildError.Identifier == BuildError.ModelContainsErrors.Identifier).Count()); - Assert.AreEqual(BuildError.ModelContainsErrors.Identifier, traceContext.TraceList[47].BuildError.Identifier); + Assert.AreEqual(BuildError.ModelContainsErrors.Identifier, traceContext.TraceList[48].BuildError.Identifier); } } diff --git a/SemanticData/UANodeSetValidation/AddressSpaceContext.cs b/SemanticData/UANodeSetValidation/AddressSpaceContext.cs index ce9ae462..a32fcf9c 100644 --- a/SemanticData/UANodeSetValidation/AddressSpaceContext.cs +++ b/SemanticData/UANodeSetValidation/AddressSpaceContext.cs @@ -117,8 +117,12 @@ void IAddressSpaceContext.ValidateAndExportModel() void IAddressSpaceContext.ValidateAndExportModel(Uri targetNamespace) { m_TraceEvent.TraceEvent(TraceMessage.DiagnosticTraceMessage(string.Format("Entering IAddressSpaceContext.ValidateAndExportModel - starting for the {0} namespace.", targetNamespace))); + List undefinedUriLists = new List(); + if (!m_NamespaceTable.ValidateNamesapceTable(x => undefinedUriLists.Add(x))) + foreach (Uri item in undefinedUriLists) + m_TraceEvent.TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.LackOfRequiredModel, $"I cannot find definition of the required model {item}")); int _nsIndex = m_NamespaceTable.GetURIIndex(targetNamespace); - //TODO This example doesn't work #583 + //TODO This example doesn't work #583 - handle this exception if (_nsIndex == -1) throw new ArgumentOutOfRangeException("targetNamespace", $"Cannot find this {targetNamespace} namespace"); ValidateAndExportModel(_nsIndex); diff --git a/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs b/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs index 3182c14a..b2054163 100644 --- a/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs +++ b/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs @@ -500,7 +500,7 @@ internal static ExpandedNodeId Parse(string text, INamespaceTable currentNamespa string uri = nodeId.m_namespaceUri; if (nodeId.m_nodeId.NamespaceIndex != 0) uri = currentNamespaces.GetModelTableEntry(nodeId.m_nodeId.NamespaceIndex).ModelUri.ToString(); - // translate the namespace uri. + // translate the namespace Uri. ushort namespaceIndex = 0; if (!String.IsNullOrEmpty(uri)) { diff --git a/SemanticData/UANodeSetValidation/INamespaceTable.cs b/SemanticData/UANodeSetValidation/INamespaceTable.cs index 1ddfcfa0..d21d9c9b 100644 --- a/SemanticData/UANodeSetValidation/INamespaceTable.cs +++ b/SemanticData/UANodeSetValidation/INamespaceTable.cs @@ -24,12 +24,16 @@ public interface INamespaceTable ushort GetURIIndexOrAppend(Uri URI); /// - /// Updates the model or append it the existing collection. + /// Updates the model or append it to the existing collection /// - /// The model. + /// The model in concern. void RegisterModel(IModelTableEntry model); - void RegisterDepenency(IModelTableEntry model); + /// + /// Registers the dependency. + /// + /// The model that is required. + void RegisterDependency(IModelTableEntry model); /// /// Gets the model table entry. diff --git a/SemanticData/UANodeSetValidation/NamespaceTable.cs b/SemanticData/UANodeSetValidation/NamespaceTable.cs index ffb7d18d..36126310 100644 --- a/SemanticData/UANodeSetValidation/NamespaceTable.cs +++ b/SemanticData/UANodeSetValidation/NamespaceTable.cs @@ -53,17 +53,17 @@ void INamespaceTable.RegisterModel(IModelTableEntry model) modelsList.Add(model); } - void INamespaceTable.RegisterDepenency(IModelTableEntry model) + void INamespaceTable.RegisterDependency(IModelTableEntry model) { int index = GetURIIndex((model ?? throw new ArgumentNullException("", "Model table entry must not be null")).ModelUri); - if (index == -1 ) + if (index == -1) modelsList.Add(model); } /// /// Gets the model table entry. /// - /// The nsi. + /// The namespace index. /// IModelTableEntry. /// namespace index - Namespace index has not been registered public IModelTableEntry GetModelTableEntry(ushort nsi) @@ -92,16 +92,41 @@ public int GetURIIndex(Uri URI) //internal Uri DefaultModelURI => modelsList[defaultModelIndex].ModelUri; //int INamespaceTable.DefaultModelIndex => defaultModelIndex; - internal void ValidateNamesapceTable() + internal bool ValidateNamesapceTable(Action add2UndefinedModelUriList) { - //TODO Import all dependencies for the model #575 - throw new NotImplementedException("Import all dependencies for the model #575"); + if (modelsList.Count == 0) + return false; + bool returnValue = true; + foreach (IModelTableEntry item in modelsList) + { + if (item is ModelTableEntryFixture) + { + add2UndefinedModelUriList(item.ModelUri); + returnValue = false; + } + }; + return returnValue; } #endregion Public Members #region private + private class ModelTableEntryFixture : IModelTableEntry + { + public ModelTableEntryFixture(Uri URI) + { + ModelUri = URI; + } + + public byte AccessRestrictions { get; private set; } = 0xC; + public Uri ModelUri { get; private set; } + public DateTime? PublicationDate { get; private set; } = DateTime.UtcNow.Date; + public IModelTableEntry[] RequiredModel { get; private set; } + public IRolePermission[] RolePermissions { get; } = new XML.RolePermission[] { new XML.RolePermission() }; + public string Version { get; } = new Version().ToString(); + } + private List modelsList = new List(); private int Append(Uri URI) @@ -109,7 +134,7 @@ private int Append(Uri URI) int index = GetURIIndex(URI); if (index == -1) { - modelsList.Add(XML.ModelTableEntry.GetDefaultModelTableEntry(URI.ToString())); + modelsList.Add(new ModelTableEntryFixture(URI)); index = modelsList.Count - 1; } return index; diff --git a/SemanticData/UANodeSetValidation/XML/ModelTableEntry.cs b/SemanticData/UANodeSetValidation/XML/ModelTableEntry.cs index 75384460..2a4b3423 100644 --- a/SemanticData/UANodeSetValidation/XML/ModelTableEntry.cs +++ b/SemanticData/UANodeSetValidation/XML/ModelTableEntry.cs @@ -53,22 +53,5 @@ public partial class ModelTableEntry : IModelTableEntry /// The version. string IModelTableEntry.Version => Version; - /// - /// Gets the default model table entry. - /// - /// The model URI. - /// IModelTableEntry. - internal static IModelTableEntry GetDefaultModelTableEntry(string modelUri) - { - return new ModelTableEntry - { - AccessRestrictions = 0xC, - ModelUri = modelUri, - PublicationDate = DateTime.UtcNow.Date, - RequiredModel = null, - RolePermissions = new XML.RolePermission[] { new XML.RolePermission() }, - Version = new Version(1, 0).ToString() - }; - } } } \ No newline at end of file diff --git a/SemanticData/UANodeSetValidation/XML/UAModelContext.cs b/SemanticData/UANodeSetValidation/XML/UAModelContext.cs index f46b6819..91a183fa 100644 --- a/SemanticData/UANodeSetValidation/XML/UAModelContext.cs +++ b/SemanticData/UANodeSetValidation/XML/UAModelContext.cs @@ -162,15 +162,13 @@ private void Parse(ModelTableEntry[] models, INamespaceTable namespaceTable) }; _logTraceMessage(TraceMessage.BuildErrorTraceMessage(BuildError.ModelsCannotBeNull, $"Added default model {models[0].ModelUri}")); } - bool defaultModel = true; foreach (ModelTableEntry item in models) { namespaceTable.RegisterModel(item); //TODO Import all dependencies for the model #575 if (item.RequiredModel != null) foreach (ModelTableEntry requiredModel in item.RequiredModel) - namespaceTable.RegisterDepenency(requiredModel); - defaultModel = false; + namespaceTable.RegisterDependency(requiredModel); } } From e7bc8e17ee5f47cc04a61f8768f838dd7d04bb20 Mon Sep 17 00:00:00 2001 From: Mariusz Date: Sat, 1 May 2021 12:53:13 +0200 Subject: [PATCH 2/2] Import all dependencies for the model #575 - fixes #575 - UT :+1: --- .../NamespaceTableUnitTest.cs | 31 ++++------ .../XML/UAModelContextUnitTest.cs | 19 ++----- .../XMLModelsProblemsToReportUnitTest.cs | 1 - .../AddressSpaceContext.cs | 2 +- .../DataSerialization/ExpandedNodeId.cs | 10 ++-- .../IAddressSpaceContext.cs | 1 + .../UANodeSetValidation/INamespaceTable.cs | 41 ++++++-------- .../UANodeSetValidation/NamespaceTable.cs | 56 ++++++++++++------- .../UANodeSetValidation/XML/UAModelContext.cs | 1 - 9 files changed, 77 insertions(+), 85 deletions(-) diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs index 2eaabce8..13d1f7ff 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/NamespaceTableUnitTest.cs @@ -26,23 +26,18 @@ public void ConstructorTest() List listOfExportedNamespaceTable = models.ToList(); Assert.AreEqual(1, listOfExportedNamespaceTable.Count); Assert.AreEqual(new Uri("http://opcfoundation.org/UA/"), listOfExportedNamespaceTable[0].ModelUri); - Assert.ThrowsException(() => listOfExportedNamespaceTable[0].AccessRestrictions); - Assert.ThrowsException(() => listOfExportedNamespaceTable[0].PublicationDate); - Assert.ThrowsException(() => listOfExportedNamespaceTable[0].RequiredModel); - Assert.ThrowsException(() => listOfExportedNamespaceTable[0].RolePermissions); - Assert.ThrowsException(() => listOfExportedNamespaceTable[0].Version); } [TestMethod] public void GetURIatIndexTest() { NamespaceTable instance = new NamespaceTable(); - Assert.AreEqual(new Uri(Namespaces.OpcUa), instance.GetModelTableEntry(0).ModelUri); - Assert.ThrowsException(() => instance.GetModelTableEntry(1)); + Assert.AreEqual(new Uri(Namespaces.OpcUa), instance.GetModelTableEntry(0)); + Assert.IsNull(instance.GetModelTableEntry(1)); Assert.AreEqual(1, ((INamespaceTable)instance).GetURIIndexOrAppend(new Uri("http://opcfoundation.org/UA/GetURIatIndexTest1"))); Assert.AreEqual(2, ((INamespaceTable)instance).GetURIIndexOrAppend(new Uri("http://opcfoundation.org/UA/GetURIatIndexTest2"))); - Assert.AreEqual(new Uri("http://opcfoundation.org/UA/GetURIatIndexTest2"), instance.GetModelTableEntry(2).ModelUri); - Assert.AreEqual(new Uri("http://opcfoundation.org/UA/GetURIatIndexTest1"), instance.GetModelTableEntry(1).ModelUri); + Assert.AreEqual(new Uri("http://opcfoundation.org/UA/GetURIatIndexTest2"), instance.GetModelTableEntry(2)); + Assert.AreEqual(new Uri("http://opcfoundation.org/UA/GetURIatIndexTest1"), instance.GetModelTableEntry(1)); } [TestMethod] @@ -68,10 +63,9 @@ public void UpadateModelOrAppendTest() ((INamespaceTable)instance).RegisterModel(model1); IModelTableEntry model2 = GetDefaultModelTableEntry("http://opcfoundation.org/UA/GetURIatIndexTest1"); ((INamespaceTable)instance).RegisterModel(model2); - IModelTableEntry model3 = instance.GetModelTableEntry(1); - Assert.IsNotNull(model3); - Assert.AreSame(model2, model3); - Assert.AreNotSame(model1, model3); + Assert.IsNotNull(instance.GetModelTableEntry(1)); + Assert.IsNull(instance.GetModelTableEntry(2)); + Assert.IsNull(instance.GetModelTableEntry(3)); } [TestMethod] @@ -89,18 +83,17 @@ public void ModelsTest() public void ValidateNamesapceTableTestMethod() { NamespaceTable instance = new NamespaceTable(); - List undefinedModels = new List(); - Assert.IsFalse(instance.ValidateNamesapceTable(y => undefinedModels.Add(y))); - Assert.AreEqual(1, undefinedModels.Count); - Assert.AreEqual(new Uri("http://opcfoundation.org/UA/"), undefinedModels[0]); - ((INamespaceTable)instance).RegisterModel(GetDefaultModelTableEntry("http://opcfoundation.org/UA/")); + Assert.IsFalse(instance.ValidateNamesapceTable(y => Assert.AreEqual(new Uri("http://opcfoundation.org/UA/"), y))); + instance.RegisterModel(GetDefaultModelTableEntry("http://opcfoundation.org/UA/")); Assert.IsTrue(instance.ValidateNamesapceTable(y => Assert.Fail())); + instance.RegisterDependency(GetDefaultModelTableEntry("http://opcfoundation.org/UA/RandomName")); + Assert.IsFalse(instance.ValidateNamesapceTable(y => Assert.AreEqual(new Uri("http://opcfoundation.org/UA/RandomName"), y))); } #region fixtures /// - /// Gets the default model table entry. + /// Gets a default model table entry. /// /// The model URI. /// IModelTableEntry. diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs index 76fea186..dcefbd07 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XML/UAModelContextUnitTest.cs @@ -25,21 +25,19 @@ public void ParseUANodeSetModelHeaderTest() { UANodeSet nodeSet = TestData.CreateNodeSetModel(); Assert.IsNotNull(nodeSet); - Mock asMock = new Mock(); + Mock nsMock = new Mock(); List trace = new List(); Action logMock = z => trace.Add(z); - Assert.ThrowsException(() => UAModelContext.ParseUANodeSetModelHeader(null, asMock.Object, logMock)); + Assert.ThrowsException(() => UAModelContext.ParseUANodeSetModelHeader(null, nsMock.Object, logMock)); Assert.AreEqual(0, trace.Count); Assert.ThrowsException(() => UAModelContext.ParseUANodeSetModelHeader(nodeSet, null, logMock)); Assert.AreEqual(0, trace.Count); - Assert.ThrowsException(() => UAModelContext.ParseUANodeSetModelHeader(nodeSet, asMock.Object, null)); + Assert.ThrowsException(() => UAModelContext.ParseUANodeSetModelHeader(nodeSet, nsMock.Object, null)); Assert.AreEqual(0, trace.Count); - UAModelContext modelContext = UAModelContext.ParseUANodeSetModelHeader(nodeSet, asMock.Object, logMock); + UAModelContext modelContext = UAModelContext.ParseUANodeSetModelHeader(nodeSet, nsMock.Object, logMock); Assert.IsNotNull(modelContext); Assert.AreEqual(1, trace.Count); Assert.AreEqual("P0-0001030000", trace[0].BuildError.Identifier); - //TODO Import all dependencies for the model #575 - //Assert.IsTrue(modelContext.ModelUri.ToString().StartsWith(@"http://cas.eu/UA/Demo/")); } [TestMethod] @@ -129,6 +127,7 @@ public void ImportQualifiedNameWrongNamespaceIndexTest() Assert.AreEqual(TraceEventType.Information, trace[0].TraceLevel); } + //TODO AddressSpacePrototyping - IMNamespace must be required in case of export #584 - this UT look useless [TestMethod] public void ModelUriTest() { @@ -141,7 +140,6 @@ public void ModelUriTest() Mock asMock = new Mock(); asMock.Setup(x => x.GetURIIndexOrAppend(It.IsAny())).Returns(10); Action logMock = z => Assert.Fail(); - //TODO Import all dependencies for the model #575 UAModelContext _modelContext = UAModelContext.ParseUANodeSetModelHeader(nodeSet, asMock.Object, logMock); //Assert.AreEqual(nodeSet.Models[0].ModelUri, _modelContext.ModelUri.ToString()); } @@ -248,13 +246,6 @@ public void RecalculateNodeIdsTest() Assert.AreEqual("The BrowseName of a ReferenceType shall be unique.", trace[0].BuildError.Descriptor); Assert.AreEqual("The UAReferenceType duplicated BrowseName=10:QualifiedName. It is not allowed that two different ReferenceTypes have the same BrowseName", trace[0].Message); Debug.WriteLine(trace[0].ToString()); - //TODO Import all dependencies for the model #575 - trace.Clear(); - _modelContext.RegisterUAReferenceType(new QualifiedName("QualifiedName", 11)); - //Assert.AreEqual(1, trace.Count); - //Assert.AreEqual(BuildError.BrowseNameReferenceTypeScope.Identifier, trace[0].BuildError.Identifier); - //Assert.AreEqual("The BrowseName of a ReferenceType is defined outside of the model.", trace[0].BuildError.Descriptor); - //Assert.AreEqual("Wrong NamespaceIndex of the 11:QualifiedName. The UAReferenceType should be defined by the default model 10", trace[0].Message); } [TestMethod] diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs index f9e4c9d3..99353716 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/XMLModelsProblemsToReportUnitTest.cs @@ -29,7 +29,6 @@ public void ADITest() using (TracedAddressSpaceContext traceContext = new TracedAddressSpaceContext()) { IAddressSpaceContext addressSpace = traceContext.CreateAddressSpaceContext(); - //TODO Import all dependencies for the model #575 - DI model must be imported as well addressSpace.ImportUANodeSet(_testDataFileInfo); Assert.AreEqual(1, traceContext.TraceList.Count); Assert.AreEqual(BuildError.ModelsCannotBeNull.Identifier, traceContext.TraceList[0].BuildError.Identifier); diff --git a/SemanticData/UANodeSetValidation/AddressSpaceContext.cs b/SemanticData/UANodeSetValidation/AddressSpaceContext.cs index a32fcf9c..ec9cf540 100644 --- a/SemanticData/UANodeSetValidation/AddressSpaceContext.cs +++ b/SemanticData/UANodeSetValidation/AddressSpaceContext.cs @@ -193,7 +193,7 @@ public IUANodeContext GetOrCreateNodeContext(NodeId nodeId, FuncIndex of the namespace. public string GetNamespace(ushort namespaceIndex) { - return m_NamespaceTable.GetModelTableEntry(namespaceIndex).ModelUri.ToString(); + return m_NamespaceTable.GetModelTableEntry(namespaceIndex).ToString(); } /// diff --git a/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs b/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs index b2054163..6d4f7328 100644 --- a/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs +++ b/SemanticData/UANodeSetValidation/DataSerialization/ExpandedNodeId.cs @@ -1,9 +1,9 @@ -//___________________________________________________________________________________ +//__________________________________________________________________________________________________ // // Copyright (C) 2021, Mariusz Postol LODZ POLAND. // -// To be in touch join the community at GITTER: https://gitter.im/mpostol/OPC-UA-OOI -//___________________________________________________________________________________ +// To be in touch join the community at GitHub: https://github.com/mpostol/OPC-UA-OOI/discussions +//__________________________________________________________________________________________________ using System; using System.Collections.Generic; @@ -499,7 +499,7 @@ internal static ExpandedNodeId Parse(string text, INamespaceTable currentNamespa // lookup the namespace uri. string uri = nodeId.m_namespaceUri; if (nodeId.m_nodeId.NamespaceIndex != 0) - uri = currentNamespaces.GetModelTableEntry(nodeId.m_nodeId.NamespaceIndex).ModelUri.ToString(); + uri = currentNamespaces.GetModelTableEntry(nodeId.m_nodeId.NamespaceIndex).ToString(); // translate the namespace Uri. ushort namespaceIndex = 0; if (!String.IsNullOrEmpty(uri)) @@ -608,7 +608,7 @@ internal static void UnescapeUri(string text, int start, int index, StringBuilde } } - #endregion statioc Parse + #endregion static Parse #region IComparable Members diff --git a/SemanticData/UANodeSetValidation/IAddressSpaceContext.cs b/SemanticData/UANodeSetValidation/IAddressSpaceContext.cs index 79dd5220..72ba5add 100644 --- a/SemanticData/UANodeSetValidation/IAddressSpaceContext.cs +++ b/SemanticData/UANodeSetValidation/IAddressSpaceContext.cs @@ -36,6 +36,7 @@ public interface IAddressSpaceContext /// The information model factory. IModelFactory InformationModelFactory { set; } + //TODO AddressSpacePrototyping - IMNamespace must be required in case of export #584 /// /// Validates and exports the selected model for the default namespace at index 1 if defined or standard OPC UA. /// diff --git a/SemanticData/UANodeSetValidation/INamespaceTable.cs b/SemanticData/UANodeSetValidation/INamespaceTable.cs index d21d9c9b..16f39e99 100644 --- a/SemanticData/UANodeSetValidation/INamespaceTable.cs +++ b/SemanticData/UANodeSetValidation/INamespaceTable.cs @@ -1,9 +1,9 @@ -//___________________________________________________________________________________ +//__________________________________________________________________________________________________ // // Copyright (C) 2021, Mariusz Postol LODZ POLAND. // -// To be in touch join the community at GITTER: https://gitter.im/mpostol/OPC-UA-OOI -//___________________________________________________________________________________ +// To be in touch join the community at GitHub: https://github.com/mpostol/OPC-UA-OOI/discussions +//__________________________________________________________________________________________________ using System; @@ -14,15 +14,6 @@ namespace UAOOI.SemanticData.UANodeSetValidation /// public interface INamespaceTable { - /// - /// Searches for an index that matches the , and returns the zero-based index of the first occurrence within the namespace table. - /// - /// The URI to search for in the namespace table. - /// - /// The zero-based index of the first occurrence of that matches the conditions defined by , if found; otherwise, –1. - /// - ushort GetURIIndexOrAppend(Uri URI); - /// /// Updates the model or append it to the existing collection /// @@ -36,24 +27,26 @@ public interface INamespaceTable void RegisterDependency(IModelTableEntry model); /// - /// Gets the model table entry. + /// Searches for an index that matches the , and returns the zero-based index of the first occurrence within the namespace table. /// - /// Index of the namespace. - /// IModelTableEntry. - IModelTableEntry GetModelTableEntry(ushort namespaceIndex); + /// The URI to search for in the namespace table. + /// + /// The zero-based index of the first occurrence of , if found; otherwise, it is appended. + /// + ushort GetURIIndexOrAppend(Uri URI); /// - /// Gets the index of the URI. + /// Searches for an , and returns the zero-based index of the first occurrence within the . /// /// The URI. - /// System.Int32. + /// The zero-based index of the first occurrence of an , if found; otherwise, –1. int GetURIIndex(Uri URI); - //TOD AddressSpacePrototyping - IMNamespace must be required in case of export #584 - ///// - ///// Gets the index of the default model. - ///// - ///// The index of the default model. - //int DefaultModelIndex { get; } + /// + /// Gets the model . + /// + /// Index of the namespace. + /// An instance that captures of the requested model if already registered, otherwise, null. + Uri GetModelTableEntry(ushort namespaceIndex); } } \ No newline at end of file diff --git a/SemanticData/UANodeSetValidation/NamespaceTable.cs b/SemanticData/UANodeSetValidation/NamespaceTable.cs index 36126310..114ce7b9 100644 --- a/SemanticData/UANodeSetValidation/NamespaceTable.cs +++ b/SemanticData/UANodeSetValidation/NamespaceTable.cs @@ -34,7 +34,7 @@ internal NamespaceTable() /// Searches for an index that matches the , and returns the zero-based index of the first occurrence within the namespace table. /// /// The URI to search for in the namespace table. - /// The zero-based index of the first occurrence of that matches the conditions defined by , if found; otherwise, –1. + /// The zero-based index of the first occurrence of , if found; otherwise, it is appended. ushort INamespaceTable.GetURIIndexOrAppend(Uri URI) { int _index = GetURIIndex(URI); @@ -43,41 +43,49 @@ ushort INamespaceTable.GetURIIndexOrAppend(Uri URI) return (ushort)_index; } - //TODO AddressSpacePrototyping - IMNamespace must be required in case of export #584 - void INamespaceTable.RegisterModel(IModelTableEntry model) + /// + /// Updates the model or append it to the existing collection + /// + /// The model in concern. + /// model - Model table entry must not be null + public void RegisterModel(IModelTableEntry model) { - int index = GetURIIndex((model ?? throw new ArgumentNullException("", "Model table entry must not be null")).ModelUri); + int index = GetURIIndex((model ?? throw new ArgumentNullException("model", "Model table entry must not be null")).ModelUri); if (index >= 0) modelsList[index] = model; else modelsList.Add(model); } - void INamespaceTable.RegisterDependency(IModelTableEntry model) + /// + /// Registers the dependency. + /// + /// The model that is required. + /// Model table entry must not be null + public void RegisterDependency(IModelTableEntry model) { - int index = GetURIIndex((model ?? throw new ArgumentNullException("", "Model table entry must not be null")).ModelUri); + int index = GetURIIndex((model ?? throw new ArgumentNullException("model", "Model table entry must not be null")).ModelUri); if (index == -1) - modelsList.Add(model); + modelsList.Add(new ModelTableEntryFixture(model)); } /// - /// Gets the model table entry. + /// Gets the model . /// - /// The namespace index. - /// IModelTableEntry. - /// namespace index - Namespace index has not been registered - public IModelTableEntry GetModelTableEntry(ushort nsi) + /// Index of the namespace. + /// An instance that captures of the requested model if already registered, otherwise, null. + public Uri GetModelTableEntry(ushort namespaceIndex) { - if (nsi >= modelsList.Count) - throw new ArgumentOutOfRangeException("namespace index", "Namespace index has not been registered"); - return modelsList[nsi]; + if (namespaceIndex >= modelsList.Count) + return null; + return modelsList[namespaceIndex].ModelUri; } /// - /// Gets the index of the URI. + /// Searches for an , and returns the zero-based index of the first occurrence within the . /// /// The URI. - /// System.Int32. + /// The zero-based index of the first occurrence of an , if found; otherwise, –1. public int GetURIIndex(Uri URI) { return modelsList.FindIndex(x => x.ModelUri == URI); @@ -87,10 +95,8 @@ public int GetURIIndex(Uri URI) #region Public Members - internal IEnumerable Models => modelsList; //TODO AddressSpacePrototyping - IMNamespace must be required in case of export #584 - //internal Uri DefaultModelURI => modelsList[defaultModelIndex].ModelUri; - //int INamespaceTable.DefaultModelIndex => defaultModelIndex; + internal IEnumerable Models => modelsList; internal bool ValidateNamesapceTable(Action add2UndefinedModelUriList) { @@ -119,6 +125,16 @@ public ModelTableEntryFixture(Uri URI) ModelUri = URI; } + public ModelTableEntryFixture(IModelTableEntry modelTableEntry) + { + AccessRestrictions = modelTableEntry.AccessRestrictions; + ModelUri = modelTableEntry.ModelUri; + PublicationDate = modelTableEntry.PublicationDate; + RequiredModel = modelTableEntry.RequiredModel; + RolePermissions = modelTableEntry.RolePermissions; + Version = modelTableEntry.Version; + } + public byte AccessRestrictions { get; private set; } = 0xC; public Uri ModelUri { get; private set; } public DateTime? PublicationDate { get; private set; } = DateTime.UtcNow.Date; diff --git a/SemanticData/UANodeSetValidation/XML/UAModelContext.cs b/SemanticData/UANodeSetValidation/XML/UAModelContext.cs index 91a183fa..f10b33d5 100644 --- a/SemanticData/UANodeSetValidation/XML/UAModelContext.cs +++ b/SemanticData/UANodeSetValidation/XML/UAModelContext.cs @@ -165,7 +165,6 @@ private void Parse(ModelTableEntry[] models, INamespaceTable namespaceTable) foreach (ModelTableEntry item in models) { namespaceTable.RegisterModel(item); - //TODO Import all dependencies for the model #575 if (item.RequiredModel != null) foreach (ModelTableEntry requiredModel in item.RequiredModel) namespaceTable.RegisterDependency(requiredModel);