Skip to content

Commit

Permalink
Bug fixes in ref server and more tests cases (#1590)
Browse files Browse the repository at this point in the history
- fix the complex types of the test nodeset (requires OPCFoundation/UA-ModelCompiler#96)
- improve some client / server tests
- add tests for complex types datatype definition integrity on ref server, validate bsd and xml dictionaries in the test server (open issue:  https://mantis.opcfoundation.org/view.php?id=7393, xml validation always failing)
- improve server fixture, to allow for custom config changes 
- fix an issue that caused kestrel not start on windows/.NET Core 3.1 and above, when a new certificate was issued, thereby ignoring all https client tests.
  • Loading branch information
mregen committed Nov 11, 2021
1 parent 860c968 commit 3b233c6
Show file tree
Hide file tree
Showing 34 changed files with 1,957 additions and 1,472 deletions.
884 changes: 442 additions & 442 deletions Applications/Quickstarts.Servers/TestData/TestData.NodeSet.xml

Large diffs are not rendered by default.

884 changes: 442 additions & 442 deletions Applications/Quickstarts.Servers/TestData/TestData.NodeSet2.xml

Large diffs are not rendered by default.

Binary file not shown.
884 changes: 442 additions & 442 deletions Applications/Quickstarts.Servers/TestData/TestData.PredefinedNodes.xml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Applications/Quickstarts.Servers/TestData/TestData.Types.bsd
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<opc:Field Name="LocalizedTextValue" TypeName="ua:LocalizedText" />
<opc:Field Name="StatusCodeValue" TypeName="ua:StatusCode" />
<opc:Field Name="VariantValue" TypeName="ua:Variant" />
<opc:Field Name="EnumerationValue" TypeName="ua:Int32" />
<opc:Field Name="EnumerationValue" TypeName="opc:Int32" />
<opc:Field Name="StructureValue" TypeName="ua:ExtensionObject" />
<opc:Field Name="Number" TypeName="ua:Variant" />
<opc:Field Name="Integer" TypeName="ua:Variant" />
Expand Down Expand Up @@ -84,7 +84,7 @@
<opc:Field Name="NoOfVariantValue" TypeName="opc:Int32" />
<opc:Field Name="VariantValue" TypeName="ua:Variant" LengthField="NoOfVariantValue" />
<opc:Field Name="NoOfEnumerationValue" TypeName="opc:Int32" />
<opc:Field Name="EnumerationValue" TypeName="ua:Int32" LengthField="NoOfEnumerationValue" />
<opc:Field Name="EnumerationValue" TypeName="opc:Int32" LengthField="NoOfEnumerationValue" />
<opc:Field Name="NoOfStructureValue" TypeName="opc:Int32" />
<opc:Field Name="StructureValue" TypeName="ua:ExtensionObject" LengthField="NoOfStructureValue" />
<opc:Field Name="NoOfNumber" TypeName="opc:Int32" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<xs:element name="LocalizedTextValue" type="ua:LocalizedText" minOccurs="0" nillable="true" />
<xs:element name="StatusCodeValue" type="ua:StatusCode" minOccurs="0" />
<xs:element name="VariantValue" type="ua:Variant" minOccurs="0" />
<xs:element name="EnumerationValue" type="ua:Int32" minOccurs="0" />
<xs:element name="EnumerationValue" type="xs:int" minOccurs="0" />
<xs:element name="StructureValue" type="ua:ExtensionObject" minOccurs="0" nillable="true" />
<xs:element name="Number" type="ua:Variant" minOccurs="0" />
<xs:element name="Integer" type="ua:Variant" minOccurs="0" />
Expand Down
1 change: 1 addition & 0 deletions Libraries/Opc.Ua.Client.ComplexTypes/ComplexTypeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ public async Task<bool> LoadNamespace(string nameSpace, bool throwOnError = fals
/// - Convert all structured types in the dictionaries to the DataTypeDefinion attribute, if possible.
/// - Create all structured types from the dictionaries using the converted DataTypeDefinion attribute..
/// </remarks>
/// <returns>true if all DataTypes were loaded.</returns>
public async Task<bool> Load(bool onlyEnumTypes = false, bool throwOnError = false)
{
try
Expand Down
15 changes: 12 additions & 3 deletions Libraries/Opc.Ua.Client/DataDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ private void ReadDataTypes(NodeId dictionaryId)
/// <summary>
/// Reads the contents of a data dictionary.
/// </summary>
private byte[] ReadDictionary(NodeId dictionaryId)
internal byte[] ReadDictionary(NodeId dictionaryId)
{
// create item to read.
ReadValueId itemToRead = new ReadValueId();
Expand Down Expand Up @@ -277,8 +277,9 @@ private byte[] ReadDictionary(NodeId dictionaryId)
/// <summary>
/// Validates the type dictionary.
/// </summary>
/// <param name="dictionary"></param>
private async Task Validate(byte[] dictionary)
/// <param name="dictionary">The encoded dictionary to validate.</param>
/// <param name="throwOnError">Throw if an error occurred.</param>
internal async Task Validate(byte[] dictionary, bool throwOnError = false)
{
MemoryStream istrm = new MemoryStream(dictionary);

Expand All @@ -293,6 +294,10 @@ private async Task Validate(byte[] dictionary)
catch (Exception e)
{
Utils.Trace(e, "Could not validate schema.");
if (throwOnError)
{
throw;
}
}

m_validator = validator;
Expand All @@ -309,6 +314,10 @@ private async Task Validate(byte[] dictionary)
catch (Exception e)
{
Utils.Trace(e, $"Could not validate schema. {e.Message}");
if (throwOnError)
{
throw;
}
}

m_validator = validator;
Expand Down
10 changes: 9 additions & 1 deletion Libraries/Opc.Ua.Client/NodeCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public NodeCache(Session session)
m_session = session;
m_typeTree = new TypeTable(m_session.NamespaceUris);
m_nodes = new NodeTable(m_session.NamespaceUris, m_session.ServerUris, m_typeTree);
m_uaTypesLoaded = false;
}
#endregion

Expand Down Expand Up @@ -492,8 +493,12 @@ public NodeId FindDataTypeId(NodeId encodingId)
/// <inheritdoc/>
public void LoadUaDefinedTypes(ISystemContext context)
{
NodeStateCollection predefinedNodes = new NodeStateCollection();
if (m_uaTypesLoaded)
{
return;
}

NodeStateCollection predefinedNodes = new NodeStateCollection();
var assembly = typeof(ArgumentCollection).GetTypeInfo().Assembly;
predefinedNodes.LoadFromBinaryResource(context, "Opc.Ua.Stack.Generated.Opc.Ua.PredefinedNodes.uanodes", assembly, true);

Expand All @@ -508,11 +513,13 @@ public void LoadUaDefinedTypes(ISystemContext context)

type.Export(context, m_nodes);
}
m_uaTypesLoaded = true;
}

/// <inheritdoc/>
public void Clear()
{
m_uaTypesLoaded = false;
m_nodes.Clear();
}

Expand Down Expand Up @@ -730,6 +737,7 @@ public NodeId BuildBrowsePath(ILocalNode node, IList<QualifiedName> browsePath)
private Session m_session;
private TypeTable m_typeTree;
private NodeTable m_nodes;
private bool m_uaTypesLoaded;
#endregion
}
}
2 changes: 1 addition & 1 deletion Libraries/Opc.Ua.Client/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,7 @@ public async Task<DataDictionary> LoadDataDictionary(ReferenceDescription dictio
}
catch (Exception ex)
{
Utils.Trace("Dictionary load error for Dictionary {0} : {1}", r.NodeId, ex.Message);
Utils.Trace(Utils.TraceMasks.Error, "Dictionary load error for Dictionary {0} : {1}", r.NodeId, ex.Message);
}
}
}
Expand Down
11 changes: 8 additions & 3 deletions Libraries/Opc.Ua.Configuration/ApplicationInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ ushort lifeTimeInMonths
Utils.GetAbsoluteDirectoryPath(id.StorePath, true, true, true);
}

var passwordProvider = configuration.SecurityConfiguration.CertificatePasswordProvider;
X509Certificate2 certificate = CertificateFactory.CreateCertificate(
configuration.ApplicationUri,
configuration.ApplicationName,
Expand All @@ -759,8 +760,8 @@ ushort lifeTimeInMonths
.SetRSAKeySize(keySize)
.CreateForRSA();

// need id for password provider
id.Certificate = certificate;
var passwordProvider = configuration.SecurityConfiguration.CertificatePasswordProvider;
certificate.AddToStore(
id.StoreType,
id.StorePath,
Expand All @@ -773,12 +774,16 @@ ushort lifeTimeInMonths
await AddToTrustedStore(configuration, certificate).ConfigureAwait(false);
}

// reload the certificate from disk.
id.Certificate = await configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKeyEx(passwordProvider).ConfigureAwait(false);

await configuration.CertificateValidator.Update(configuration.SecurityConfiguration).ConfigureAwait(false);

Utils.Trace(Utils.TraceMasks.Information, "Certificate created. Thumbprint={0}", certificate.Thumbprint);

// reload the certificate from disk.
return await configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKeyEx(passwordProvider).ConfigureAwait(false);
// do not dispose temp cert, or X509Store certs become unusable

return id.Certificate;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ public override ICertificateBuilderCreateForRSAAny SetRSAPublicKey(byte[] public
{
if (publicKey == null) throw new ArgumentNullException(nameof(publicKey));
#if NET472_OR_GREATER
throw new NotSupportedException("Import a ECDsaPublicKey is not supported on this platform.");
throw new NotSupportedException("Import a RSAPublicKey is not supported on this platform.");
#else
int bytes = 0;
try
Expand Down
2 changes: 2 additions & 0 deletions Stack/Opc.Ua.Core/Opc.Ua.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
<ItemGroup>
<None Remove="Schema\Opc.Ua.NodeSet2.xml" />
<None Remove="Schema\Opc.Ua.Types.bsd" />
<None Remove="Schema\Opc.Ua.Types.xsd" />
<None Remove="Types\Schemas\BuiltInTypes.bsd" />
<None Remove="Types\Schemas\StandardTypes.bsd" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Schema\Opc.Ua.NodeSet2.xml" />
<EmbeddedResource Include="Schema\Opc.Ua.Types.bsd" />
<EmbeddedResource Include="Schema\Opc.Ua.Types.xsd" />
<EmbeddedResource Include="Stack\Generated\Opc.Ua.PredefinedNodes.uanodes" />
<EmbeddedResource Include="Types\Utils\LocalizedData.txt" />
<EmbeddedResource Include="Schema\ServerCapabilities.csv" />
Expand Down
107 changes: 60 additions & 47 deletions Stack/Opc.Ua.Core/Types/Schemas/XmlSchemaValidator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 1996-2020 The OPC Foundation. All rights reserved.
/* Copyright (c) 1996-2021 The OPC Foundation. All rights reserved.
The source code in this file is covered under a dual-license scenario:
- RCL: for OPC Foundation members in good-standing
- GPL V2: everybody else
Expand All @@ -12,10 +12,10 @@

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Schema;

namespace Opc.Ua.Schema.Xml
Expand Down Expand Up @@ -45,12 +45,13 @@ public XmlSchemaValidator(Dictionary<string, string> fileTable) : base(fileTable

#region Public Members
/// <summary>
/// The schema set that was validated.
/// </summary>
public XmlSchemaSet SchemaSet => m_schemaSet;
/// <summary>
/// The schema that was validated.
/// </summary>
public XmlDocument TargetSchema
{
get { return m_schema; }
}
public XmlSchema TargetSchema => m_schema;

/// <summary>
/// Generates the code from the contents of the address space.
Expand All @@ -70,45 +71,41 @@ public void Validate(Stream stream)
{
using (var xmlReader = XmlReader.Create(stream, Utils.DefaultXmlReaderSettings()))
{
m_schema.Load(xmlReader);
}
m_schema = XmlSchema.Read(xmlReader, new ValidationEventHandler(OnValidate));

foreach (XmlNode import in m_schema.ChildNodes)
{
if (import.NamespaceURI == Namespaces.OpcUa)
var assembly = typeof(XmlSchemaValidator).GetTypeInfo().Assembly;
foreach (XmlSchemaImport import in m_schema.Includes)
{
using (StreamReader strm = new StreamReader(Assembly.Load(new AssemblyName("Opc.Ua.Core")).GetManifestResourceStream("Opc.Ua.Model.Opc.Ua.Types.xsd")))
using (var xmlReader = XmlReader.Create(strm, Utils.DefaultXmlReaderSettings()))
string location = null;

if (!KnownFiles.TryGetValue(import.Namespace, out location))
{
m_schema.Load(xmlReader);
location = import.SchemaLocation;
}
continue;
}

string location = null;

if (!KnownFiles.TryGetValue(import.NamespaceURI, out location))
{
location = import.NamespaceURI;
}

FileInfo fileInfo = new FileInfo(location);
if (!fileInfo.Exists)
{
using (StreamReader strm = new StreamReader(Assembly.Load(new AssemblyName("Opc.Ua.Core")).GetManifestResourceStream(location)))
using (var xmlReader = XmlReader.Create(strm, Utils.DefaultXmlReaderSettings()))
FileInfo fileInfo = new FileInfo(location);
var settings = Utils.DefaultXmlReaderSettings();
if (!fileInfo.Exists)
{
m_schema.Load(xmlReader);
using (StreamReader strm = new StreamReader(assembly.GetManifestResourceStream(location)))
using (var schemaReader = XmlReader.Create(strm, settings))
{
import.Schema = XmlSchema.Read(schemaReader, new ValidationEventHandler(OnValidate));
}
}
}
else
{
using (Stream strm = File.OpenRead(location))
using (var xmlReader = XmlReader.Create(strm, Utils.DefaultXmlReaderSettings()))
else
{
m_schema.Load(xmlReader);
using (Stream strm = File.OpenRead(location))
using (var schemaReader = XmlReader.Create(strm, settings))
{
import.Schema = XmlSchema.Read(schemaReader, new ValidationEventHandler(OnValidate));
}
}
}

m_schemaSet = new XmlSchemaSet();
m_schemaSet.Add(m_schema);
m_schemaSet.Compile();
}
}

Expand All @@ -128,22 +125,24 @@ public override string GetSchema(string typeName)

try
{
if (typeName == null || m_schema.ChildNodes.Count == 0)
if (typeName == null || m_schema.Elements.Values.Count == 0)
{
m_schema.WriteTo(writer);
m_schema.Write(writer);
}
else
{
foreach (XmlNode current in m_schema.ChildNodes)
foreach (XmlSchemaObject current in m_schema.Elements.Values)
{
XmlElement element = current as XmlElement;
XmlSchemaElement element = current as XmlSchemaElement;

if (element != null)
{
if (element.Name == typeName)
{
XmlDocument schema = new XmlDocument();
schema.AppendChild(element);
schema.WriteTo(writer);
XmlSchema schema = new XmlSchema();
schema.Items.Add(element.ElementSchemaType);
schema.Items.Add(element);
schema.Write(writer);
break;
}
}
Expand All @@ -160,13 +159,27 @@ public override string GetSchema(string typeName)
}
#endregion

#region Private Methods
/// <summary>
/// Handles a validation error.
/// </summary>
static void OnValidate(object sender, ValidationEventArgs args)
{
Utils.Trace(Utils.TraceMasks.Error, "Error in XML schema validation: {0}", args.Message);
throw new InvalidOperationException(args.Message, args.Exception);
}
#endregion

#region Private Fields
private readonly string[][] WellKnownDictionaries = new string[][]
/// <summary>
/// The well known schemas embedded in the assembly.
/// </summary>
protected static readonly string[][] WellKnownDictionaries = new string[][]
{
new string[] { Namespaces.OpcUaBuiltInTypes, "Opc.Ua.Types.Schemas.BuiltInTypes.xsd" }
new string[] { Namespaces.OpcUaXsd, "Opc.Ua.Schema.Opc.Ua.Types.xsd" }
};

private XmlDocument m_schema = new XmlDocument();
private XmlSchema m_schema;
private XmlSchemaSet m_schemaSet;
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit.Console" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0">
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Expand All @@ -21,12 +21,15 @@
</ItemGroup>

<ItemGroup>
<Compile Include="..\Common\Main.cs"/>
<Compile Include="..\Common\Main.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Applications\Quickstarts.Servers\Quickstarts.Servers.csproj" />
<ProjectReference Include="..\Opc.Ua.Client.Tests\Opc.Ua.Client.Tests.csproj" />
<ProjectReference Include="..\Opc.Ua.Core.Tests\Opc.Ua.Core.Tests.csproj" />
<ProjectReference Include="..\..\Libraries\Opc.Ua.Client.ComplexTypes\Opc.Ua.Client.ComplexTypes.csproj" />
<ProjectReference Include="..\Opc.Ua.Server.Tests\Opc.Ua.Server.Tests.csproj" />
</ItemGroup>

</Project>

0 comments on commit 3b233c6

Please sign in to comment.