Merge re/r1.10-rename-tags: RenameTagsAsync via History StartJob
# Conflicts: # docs/plans/hcal-capability-matrix.md # docs/plans/hcal-roadmap.md # src/AVEVA.Historian.Client/Wcf/HistorianWcfTagWriteOrchestrator.cs # tests/AVEVA.Historian.Client.Tests/HistorianClientIntegrationTests.cs # tools/AVEVA.Historian.NativeTraceHarness/Program.cs
This commit is contained in:
@@ -1038,4 +1038,73 @@ public sealed class HistorianClientIntegrationTests
|
||||
// SQL read-back is diagnostic only; never fail the send test on a query issue.
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RenameTagsAsync_AgainstLocalHistorian_RenamesSandboxTag()
|
||||
{
|
||||
// Safety: localhost only, names must start with "RetestSdkWrite". Requires the server's
|
||||
// AllowRenameTags system parameter to be enabled (otherwise StartJob returns false). Gated
|
||||
// on HISTORIAN_RENAME_SANDBOX so it stays skipped unless explicitly enabled.
|
||||
string? host = Environment.GetEnvironmentVariable("HISTORIAN_HOST");
|
||||
string? sandbox = Environment.GetEnvironmentVariable("HISTORIAN_RENAME_SANDBOX");
|
||||
if (string.IsNullOrWhiteSpace(host) || !string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase) || !OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(sandbox) || !sandbox.StartsWith("RetestSdkWrite", StringComparison.Ordinal))
|
||||
{
|
||||
return; // safety gate
|
||||
}
|
||||
|
||||
string src = sandbox + "Src";
|
||||
string dst = sandbox + "Dst";
|
||||
|
||||
HistorianClient client = new(new HistorianClientOptions
|
||||
{
|
||||
Host = host,
|
||||
IntegratedSecurity = true,
|
||||
Transport = HistorianTransport.LocalPipe
|
||||
});
|
||||
|
||||
// Fresh source tag.
|
||||
await client.EnsureTagAsync(new AVEVA.Historian.Client.Models.HistorianTagDefinition
|
||||
{
|
||||
TagName = src,
|
||||
Description = "SDK rename live test",
|
||||
EngineeringUnit = "test",
|
||||
DataType = AVEVA.Historian.Client.Models.HistorianDataType.Float,
|
||||
MinEU = 0.0,
|
||||
MaxEU = 100.0,
|
||||
}, CancellationToken.None);
|
||||
|
||||
try
|
||||
{
|
||||
AVEVA.Historian.Client.Models.HistorianTagRenameResult result =
|
||||
await client.RenameTagAsync(src, dst, CancellationToken.None);
|
||||
|
||||
Assert.True(result.Accepted, "RenameTagsAsync was not accepted by the server (is AllowRenameTags enabled?).");
|
||||
Assert.NotEqual(Guid.Empty, result.JobId);
|
||||
Assert.Equal(1, result.PairCount);
|
||||
|
||||
// Rename completes asynchronously; poll the new name's metadata briefly.
|
||||
bool renamed = false;
|
||||
for (int i = 0; i < 10 && !renamed; i++)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
try
|
||||
{
|
||||
var md = await client.GetTagMetadataAsync(dst, CancellationToken.None);
|
||||
renamed = md is not null && string.Equals(md.Name, dst, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch { /* not yet visible */ }
|
||||
}
|
||||
Assert.True(renamed, $"Renamed tag '{dst}' did not become visible after the job completed.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Clean up whichever name ended up in the DB.
|
||||
try { await client.DeleteTagAsync(dst, CancellationToken.None); } catch { }
|
||||
try { await client.DeleteTagAsync(src, CancellationToken.None); } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user