From cc458a810b8fd474bd5ea9d42e9f97d35b386ae3 Mon Sep 17 00:00:00 2001 From: Archie Date: Mon, 10 Mar 2025 13:31:35 -0600 Subject: [PATCH 1/2] Fixed Issue 94. Still need to do tests --- NodeSetToAML.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/NodeSetToAML.cs b/NodeSetToAML.cs index 96e1eec..032ba95 100644 --- a/NodeSetToAML.cs +++ b/NodeSetToAML.cs @@ -564,14 +564,15 @@ private void AddBaseNodeClassAttributes( AttributeSequence seq, UANode uanode, U // only set the value if different from the base node string baseuri = ""; if (basenode != null ) - baseuri = m_modelManager.ModelNamespaceIndexes[basenode.DecodedNodeId.NamespaceIndex].NamespaceUri; - string myuri = m_modelManager.ModelNamespaceIndexes[uanode.DecodedNodeId.NamespaceIndex].NamespaceUri; + baseuri = m_modelManager.ModelNamespaceIndexes[basenode.DecodedBrowseName.NamespaceIndex].NamespaceUri; + string myuri = m_modelManager.ModelNamespaceIndexes[uanode.DecodedBrowseName.NamespaceIndex].NamespaceUri; var nodeId = seq["NodeId"]; if (uanode.DecodedNodeId.IsNullNodeId == false) { - ExpandedNodeId expandedNodeId = new ExpandedNodeId(uanode.DecodedNodeId, myuri); + ExpandedNodeId expandedNodeId = new ExpandedNodeId(uanode.DecodedNodeId, + m_modelManager.ModelNamespaceIndexes[uanode.DecodedNodeId.NamespaceIndex].NamespaceUri); Variant variant = new Variant(expandedNodeId); nodeId = AddModifyAttribute(seq, "NodeId", "NodeId", variant); } From 7ea3b025d7d2d67fd4775149aef72bfd8629fbc4 Mon Sep 17 00:00:00 2001 From: Archie Date: Mon, 10 Mar 2025 17:08:32 -0600 Subject: [PATCH 2/2] Tests for 94 - Improper BrowseName --- SystemTest/NodeSetFiles/AmlFxTest.xml | 24 +++++- SystemTest/TestNamespaceUriAttributes.cs | 97 ++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 SystemTest/TestNamespaceUriAttributes.cs diff --git a/SystemTest/NodeSetFiles/AmlFxTest.xml b/SystemTest/NodeSetFiles/AmlFxTest.xml index 4b10783..005760b 100644 --- a/SystemTest/NodeSetFiles/AmlFxTest.xml +++ b/SystemTest/NodeSetFiles/AmlFxTest.xml @@ -4,14 +4,16 @@ http://opcfoundation.org/UA/FX/AML/TESTING/AmlFxTest/ http://opcfoundation.org/UA/FX/AC/ http://opcfoundation.org/UA/FX/Data/ - + http://opcfoundation.org/UA/DI/ + - i=35 + i=21 + i=35 i=40 i=46 i=47 @@ -77,7 +79,23 @@ ns=1;i=5003 - + + + AnAsset + + ns=1;i=5004 + ns=2;i=3 + + + + Manufacturer + + ns=1;i=5008 + i=68 + + + + CloseConnections ns=1;i=5003 diff --git a/SystemTest/TestNamespaceUriAttributes.cs b/SystemTest/TestNamespaceUriAttributes.cs new file mode 100644 index 0000000..7784b43 --- /dev/null +++ b/SystemTest/TestNamespaceUriAttributes.cs @@ -0,0 +1,97 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using Aml.Engine.AmlObjects; +using Aml.Engine.CAEX; +using Aml.Engine.CAEX.Extensions; +using Opc.Ua; + + +namespace SystemTest +{ + [TestClass] + public class TestNamespaceUriAttributes + { + // Test is to address issue 94 - + // The Namespaces of BrowseNames differ between the generated AML file and the original Nodeset file. + // Test Both NodeId NamespaceUris and BrowseNameUris + + private const string FxIdPrefix = "nsu%3Dhttp%3A%2F%2Fopcfoundation.org%2FUA%2FFX%2FAC%2F%3Bi%3D"; + private const string AmlFxTestPrefix = "nsu%3Dhttp%3A%2F%2Fopcfoundation.org%2FUA%2FFX%2FAML%2FTESTING%2FAmlFxTest%2F%3Bi%3D"; + public const string TestAmlUri = "http://opcfoundation.org/UA/FX/AML/TESTING/AmlFxTest/"; + private const string FxAcUri = "http://opcfoundation.org/UA/FX/AC/"; + private const string DiUri = "http://opcfoundation.org/UA/DI/"; + + CAEXDocument m_document = null; + + #region Tests + + [TestMethod, Timeout( TestHelper.UnitTestTimeout )] + [DataRow( false, "3", FxAcUri, DisplayName = "FxAssetType" )] + [DataRow( false, "175", FxAcUri, DisplayName = "Manufacturer" )] + [DataRow( true, "5008", TestAmlUri, DisplayName = "Asset Instance" )] + [DataRow( true, "6008", TestAmlUri, DisplayName = "Manufacturer Instance")] + public void TestNodeIds( bool instance, string nodeIdentifier, string expectedUri) + { + SystemUnitClassType objectToTest = GetTestObject( instance, nodeIdentifier ); + AttributeType nodeId = objectToTest.Attribute[ "NodeId" ]; + Assert.IsNotNull( nodeId ); + AttributeType rootNodeId = nodeId.Attribute[ "RootNodeId" ]; + Assert.IsNotNull( rootNodeId ); + AttributeType namespaceUri = rootNodeId.Attribute[ "NamespaceUri" ]; + Assert.IsNotNull( namespaceUri ); + Assert.AreEqual( expectedUri, namespaceUri.Value ); + + AttributeType identifier = rootNodeId.Attribute[ "NumericId" ]; + Assert.IsNotNull( identifier ); + Assert.AreEqual( nodeIdentifier, identifier.Value ); + } + + [TestMethod, Timeout(TestHelper.UnitTestTimeout)] + [DataRow(false, "3", FxAcUri, DisplayName = "FxAssetType")] + [DataRow(false, "175", DiUri, DisplayName = "Manufacturer")] + [DataRow(true, "5008", TestAmlUri, DisplayName = "Asset Instance")] + [DataRow(true, "6008", DiUri, DisplayName = "Manufacturer Instance")] + public void TestBrowseNames(bool instance, string nodeIdentifier, string expectedUri) + { + SystemUnitClassType objectToTest = GetTestObject(instance, nodeIdentifier); + AttributeType browseName = objectToTest.Attribute["BrowseName"]; + Assert.IsNotNull(browseName); + AttributeType namespaceUri = browseName.Attribute["NamespaceURI"]; + Assert.IsNotNull(namespaceUri); + Assert.AreEqual(expectedUri, namespaceUri.Value); + } + + #endregion + + #region Helpers + + private CAEXDocument GetDocument() + { + if( m_document == null ) + { + m_document = TestHelper.GetReadOnlyDocument( "AmlFxTest.xml.amlx" ); + } + Assert.IsNotNull( m_document, "Unable to retrieve Document" ); + return m_document; + } + + public SystemUnitClassType GetTestObject(bool instance, string nodeId) + { + CAEXDocument document = GetDocument(); + + string rootName = FxIdPrefix; + if ( instance ) + { + rootName = AmlFxTestPrefix; + } + CAEXObject initialObject = document.FindByID(rootName + nodeId); + Assert.IsNotNull(initialObject, "Unable to find Initial Object"); + SystemUnitClassType theObject = initialObject as SystemUnitClassType; + Assert.IsNotNull(theObject, "Unable to Cast Initial Object"); + return theObject; + } + + #endregion + } +}