in src/Azure.IIoT.OpcUa.Publisher.Testing/src/Plc/PluginNodes/SlowFastCommon.cs [145:295]
private void UpdateNodes(BaseDataVariableState[] nodes, NodeType type, StatusCode status, bool addBadValue)
{
if (nodes == null || nodes.Length == 0)
{
_logger.LogWarning("Invalid argument {Argument} provided.", nodes);
return;
}
for (var nodeIndex = 0; nodeIndex < nodes.Length; nodeIndex++)
{
var extendedNode = (BaseDataVariableStateExtended)nodes[nodeIndex];
object value = null;
if (StatusCode.IsNotBad(status) || addBadValue)
{
switch (type)
{
case NodeType.DoubleScalar:
var minDoubleValue = (double)extendedNode.MinValue;
var maxDoubleValue = (double)extendedNode.MaxValue;
var extendedDoubleNodeValue = (double)(extendedNode.Value ?? minDoubleValue);
if (extendedNode.Randomize)
{
if (minDoubleValue != maxDoubleValue)
{
// Hybrid range case (e.g. -5.0 to 5.0).
if (minDoubleValue < 0 && maxDoubleValue > 0)
{
// If new random value is same as previous one, generate a new one until it is not.
while (value == null || extendedDoubleNodeValue == (double)value)
{
// Split the range from 0 on both sides.
#pragma warning disable CA5394 // Do not use insecure randomness
var value1 = _random.NextDouble() * maxDoubleValue;
#pragma warning restore CA5394 // Do not use insecure randomness
#pragma warning disable CA5394 // Do not use insecure randomness
var value2 = _random.NextDouble() * minDoubleValue;
#pragma warning restore CA5394 // Do not use insecure randomness
// Return random value from postive or negative range, randomly.
#pragma warning disable CA5394 // Do not use insecure randomness
value = _random.Next(10) % 2 == 0 ? value1 : value2;
#pragma warning restore CA5394 // Do not use insecure randomness
}
}
else // Negative and positive only range cases (e.g. -5.0 to -8.0 or 0 to 9.5).
{
// If new random value is same as previous one, generate a new one until it is not.
while (value == null || extendedDoubleNodeValue == (double)value)
{
#pragma warning disable CA5394 // Do not use insecure randomness
value = minDoubleValue + (_random.NextDouble() * (maxDoubleValue - minDoubleValue));
#pragma warning restore CA5394 // Do not use insecure randomness
}
}
}
else
{
throw new ArgumentException($"Range {minDoubleValue} to {maxDoubleValue}does not have provision for randomness.");
}
}
else
{
// Positive only range cases (e.g. 0 to 9.5).
if (minDoubleValue >= 0 && maxDoubleValue > 0)
{
value = (extendedDoubleNodeValue % maxDoubleValue) < minDoubleValue
? minDoubleValue
: ((extendedDoubleNodeValue % maxDoubleValue) + (double)extendedNode.StepSize) > maxDoubleValue
? minDoubleValue
: ((extendedDoubleNodeValue % maxDoubleValue) + (double)extendedNode.StepSize);
}
else if (maxDoubleValue <= 0 && minDoubleValue < 0) // Negative only range cases (e.g. 0 to -9.5).
{
value = (extendedDoubleNodeValue % minDoubleValue) > maxDoubleValue
? maxDoubleValue
: ((extendedDoubleNodeValue % minDoubleValue) - (double)extendedNode.StepSize) < minDoubleValue
? maxDoubleValue
: (extendedDoubleNodeValue % minDoubleValue) - (double)extendedNode.StepSize;
}
else
{
// This is to prevent infinte loop while attempting to create a different random number than previous one if no range is provided.
throw new ArgumentException($"Negative to positive range {minDoubleValue} to {maxDoubleValue} for sequential node values is not supported currently.");
}
}
break;
case NodeType.BoolScalar:
value = extendedNode.Value == null || !(bool)extendedNode.Value;
break;
case NodeType.UIntArray:
var arrayValue = (uint[])extendedNode.Value;
if (arrayValue != null)
{
for (var arrayIndex = 0; arrayIndex < arrayValue.Length; arrayIndex++)
{
arrayValue[arrayIndex]++;
}
}
else
{
arrayValue = new uint[32];
}
value = arrayValue;
break;
case NodeType.UIntScalar:
var minUIntValue = (uint)extendedNode.MinValue;
var maxUIntValue = (uint)extendedNode.MaxValue;
var extendedUIntNodeValue = (uint)(extendedNode.Value ?? minUIntValue);
if (extendedNode.Randomize)
{
if (minUIntValue != maxUIntValue)
{
// If new random value is same as previous one, generate a new one until it is not.
while (value == null || extendedUIntNodeValue == (uint)value)
{
// uint.MaxValue + 1 cycles back to 0 which causes infinte loop here hence a check maxUIntValue == uint.MaxValue to prevent it.
#pragma warning disable CA5394 // Do not use insecure randomness
value = (uint)(minUIntValue + (_random.NextDouble() * ((maxUIntValue == uint.MaxValue ? maxUIntValue : maxUIntValue + 1) - minUIntValue)));
#pragma warning restore CA5394 // Do not use insecure randomness
}
}
else
{
// This is to prevent infinte loop while attempting to create a different random number than previous one if no range is provided.
throw new ArgumentException($"Range {minUIntValue} to {maxUIntValue} does not have provision for randomness.");
}
}
else
{
value = (extendedUIntNodeValue % maxUIntValue) < minUIntValue
? minUIntValue
: ((extendedUIntNodeValue % maxUIntValue) + (uint)extendedNode.StepSize) > maxUIntValue
? minUIntValue
: ((extendedUIntNodeValue % maxUIntValue) + (uint)extendedNode.StepSize);
}
break;
default:
throw new NotSupportedException("Node type unknown");
}
}
extendedNode.StatusCode = status;
SetValue(extendedNode, value);
}
}