From 38607791361766fa440e86b1d46a839d9969cbca Mon Sep 17 00:00:00 2001
From: Bart Koelman <104792814+bart-vmware@users.noreply.github.com>
Date: Fri, 18 Sep 2026 10:47:08 +0200
Subject: [PATCH 1/2] Add tests (skipped by default) to verify dumps
compatibility
---
.../Steeltoe.Management.Endpoint.csproj | 1 +
.../Actuators/DumpPackagingTest.cs | 540 ++++++++++++++++++
.../ThreadDump/EventPipeThreadDumperTest.cs | 2 +
.../Steeltoe.Management.Endpoint.Test.csproj | 5 +
...Management.GitProperties.Build.Test.csproj | 2 +-
.../TestAppTargetFramework.cs | 2 +-
6 files changed, 550 insertions(+), 2 deletions(-)
create mode 100644 src/Management/test/Endpoint.Test/Actuators/DumpPackagingTest.cs
diff --git a/src/Management/src/Endpoint/Steeltoe.Management.Endpoint.csproj b/src/Management/src/Endpoint/Steeltoe.Management.Endpoint.csproj
index eba86e4344..8432fa8518 100755
--- a/src/Management/src/Endpoint/Steeltoe.Management.Endpoint.csproj
+++ b/src/Management/src/Endpoint/Steeltoe.Management.Endpoint.csproj
@@ -37,6 +37,7 @@
$(Pkgdotnet-gcdump)\tools\net8.0\any\dotnet-gcdump.dll
diff --git a/src/Management/test/Endpoint.Test/Actuators/DumpPackagingTest.cs b/src/Management/test/Endpoint.Test/Actuators/DumpPackagingTest.cs
new file mode 100644
index 0000000000..45125f0721
--- /dev/null
+++ b/src/Management/test/Endpoint.Test/Actuators/DumpPackagingTest.cs
@@ -0,0 +1,540 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Reflection;
+using System.Text;
+using System.Xml.Linq;
+
+namespace Steeltoe.Management.Endpoint.Test.Actuators;
+
+///
+/// Used to verify whether the version of Microsoft.Diagnostics.FastSerialization embedded in dotnet-gcdump is binary compatible with the version
+/// referenced by Microsoft.Diagnostics.Tracing.TraceEvent. Unskip and run this manually after version bumps (takes several minutes).
+///
+[Collection("TestsForMemoryDumpsMustRunSequentially")]
+[Trait("Category", "MemoryDumps")]
+public sealed class DumpPackagingTest(DumpPackagingTest.PackSteeltoeLibrariesOnceFixture fixture)
+ : IClassFixture
+{
+ private const string EndpointProjectName = "Steeltoe.Management.Endpoint";
+
+ // Tip: Set SkipReason to null to unskip all tests.
+ private const string? SkipReason =
+ "Slow: packs NuGet packages and builds/runs a console app per TFM. Unskip and run locally after changing a dump-related package version.";
+
+ // To reproduce test failures, here's a combination that compiles fine, while crashing at runtime due to binary breaking changes:
+ // - dotnet-gcdump v9.0.621003 (embeds Microsoft.Diagnostics.FastSerialization v3.1.16.0)
+ // - Microsoft.Diagnostics.Tracing.TraceEvent v3.2.6 (embeds Microsoft.Diagnostics.FastSerialization v3.2.6.0)
+
+ [Theory(Skip = SkipReason)]
+ [MemberData(nameof(TestTargetFrameworks))]
+ public async Task Can_take_gcdump_from_packaged_Steeltoe_library(string targetFramework)
+ {
+ Assert.SkipWhen(!IsHighestTestHostFramework(), "Running this test only on the latest .NET SDK is sufficient.");
+
+ var app = await DumpVerificationApp.CreateForGCDumpAsync(fixture, targetFramework);
+
+ // ReSharper disable once AccessToDisposedClosure
+ Func action = app.RunAsync;
+
+ await action.Should().NotThrowAsync();
+ }
+
+ [Theory(Skip = SkipReason)]
+ [MemberData(nameof(TestTargetFrameworks))]
+ public async Task Can_take_minidump_from_packaged_Steeltoe_library(string targetFramework)
+ {
+ Assert.SkipWhen(!IsHighestTestHostFramework(), "Running this test only on the latest .NET SDK is sufficient.");
+
+ var app = await DumpVerificationApp.CreateForMinidumpAsync(fixture, targetFramework);
+
+ // ReSharper disable once AccessToDisposedClosure
+ Func action = app.RunAsync;
+
+ await action.Should().NotThrowAsync();
+ }
+
+ [Theory(Skip = SkipReason)]
+ [MemberData(nameof(TestTargetFrameworks))]
+ public async Task Can_take_thread_dump_from_packaged_Steeltoe_library(string targetFramework)
+ {
+ Assert.SkipWhen(!IsHighestTestHostFramework(), "Running this test only on the latest .NET SDK is sufficient.");
+
+ var app = await DumpVerificationApp.CreateForThreadDumpAsync(fixture, targetFramework);
+
+ // ReSharper disable once AccessToDisposedClosure
+ Func action = app.RunAsync;
+
+ await action.Should().NotThrowAsync();
+ }
+
+ public static TheoryData TestTargetFrameworks()
+ {
+ var theoryData = new TheoryData();
+
+ foreach (string targetFramework in ResolveTestTargetFrameworks())
+ {
+ theoryData.Add(targetFramework);
+ }
+
+ return theoryData;
+ }
+
+ private static string[] ResolveTestTargetFrameworks()
+ {
+ AssemblyMetadataAttribute? attribute = Assembly.GetExecutingAssembly().GetCustomAttributes()
+ .FirstOrDefault(candidate => candidate.Key == "TestTargetFrameworks");
+
+ if (attribute?.Value == null)
+ {
+ throw new InvalidOperationException("Could not resolve TestTargetFrameworks from AssemblyMetadata in test project file.");
+ }
+
+ string[] targetFrameworks = attribute.Value.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+
+ if (targetFrameworks.Length == 0)
+ {
+ throw new InvalidOperationException("TestTargetFrameworks from AssemblyMetadata in test project file is empty.");
+ }
+
+ return targetFrameworks;
+ }
+
+ private static bool IsHighestTestHostFramework()
+ {
+ // The InlineData entries already cover every supported TFM, so running tests on all target frameworks would just repeat identical work.
+
+ Version hostVersion = typeof(object).Assembly.GetName().Version!;
+ int highestMajorVersion = ResolveTestTargetFrameworks().Max(targetFramework => Version.Parse(targetFramework["net".Length..]).Major);
+
+ return hostVersion.Major == highestMajorVersion;
+ }
+
+ ///
+ /// Packs project Steeltoe.Management.Endpoint (along with the Steeltoe projects it references) into an isolated local NuGet feed (once per test run) to
+ /// speed up running tests.
+ ///
+ public sealed class PackSteeltoeLibrariesOnceFixture : IAsyncLifetime
+ {
+ private string? _sessionDirectory;
+
+ internal string SessionDirectory => _sessionDirectory!;
+ internal NuGetSource Source { get; private set; } = null!;
+ internal string PackageVersion { get; } = $"9.9.9-test.{$"{Guid.NewGuid():N}"[..8]}";
+
+ public async ValueTask InitializeAsync()
+ {
+ if (!IsHighestTestHostFramework())
+ {
+ return;
+ }
+
+ string directoryName = $"steeltoe-dumps-test-session-{$"{Guid.NewGuid():N}"[..8]}";
+ string tempPath = Path.GetTempPath();
+ string sessionDirectory = new DirectoryInfo(tempPath).CreateSubdirectory(directoryName).FullName;
+ _sessionDirectory = sessionDirectory;
+
+ var sessionDirectoryInfo = new DirectoryInfo(sessionDirectory);
+ Source = CreateNuGetSource(sessionDirectoryInfo);
+
+ string endpointProjectPath = GetEndpointProjectPath();
+
+ foreach (string projectPath in ResolveSteeltoeProjectFilePaths(endpointProjectPath))
+ {
+ await PackAsync(projectPath, Source.FeedDirectory, PackageVersion);
+ }
+ }
+
+ private static NuGetSource CreateNuGetSource(DirectoryInfo sessionDirectoryInfo)
+ {
+ string feedDirectory = sessionDirectoryInfo.CreateSubdirectory("feed").FullName;
+ string packagesDirectory = sessionDirectoryInfo.CreateSubdirectory("packages").FullName;
+ return new NuGetSource(feedDirectory, packagesDirectory);
+ }
+
+ private static string GetEndpointProjectPath()
+ {
+ string testDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "..", "..", "..");
+ string projectFilePath = Path.Combine(testDirectory, "..", "..", "src", "Endpoint", $"{EndpointProjectName}.csproj");
+ return Path.GetFullPath(projectFilePath);
+ }
+
+ private static HashSet ResolveSteeltoeProjectFilePaths(string startProjectPath)
+ {
+ var discovered = new HashSet(StringComparer.OrdinalIgnoreCase);
+
+ var pending = new Queue();
+ pending.Enqueue(Path.GetFullPath(startProjectPath));
+
+ while (pending.TryDequeue(out string? nextProjectPath))
+ {
+ if (discovered.Add(nextProjectPath))
+ {
+ XDocument document = XDocument.Load(nextProjectPath);
+ string directory = Path.GetDirectoryName(nextProjectPath)!;
+
+ foreach (string relativePath in document.Descendants("ProjectReference").Attributes("Include").Select(attribute => attribute.Value))
+ {
+ string absolutePath = Path.GetFullPath(Path.Combine(directory, NormalizePath(relativePath)));
+ pending.Enqueue(absolutePath);
+ }
+ }
+ }
+
+ return discovered;
+ }
+
+ private static string NormalizePath(string path)
+ {
+ return path.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar);
+ }
+
+ private static async Task PackAsync(string projectPath, string feedDirectory, string packageVersion)
+ {
+ string projectDirectory = Path.GetDirectoryName(projectPath)!;
+
+ await DotNetProcessRunner.RunAsync(projectDirectory, "build", projectPath, "-c", "Release", $"-p:Version={packageVersion}",
+ $"-p:PackageOutputPath={feedDirectory}");
+ }
+
+ public ValueTask DisposeAsync()
+ {
+ if (_sessionDirectory != null)
+ {
+ try
+ {
+ Directory.Delete(_sessionDirectory, true);
+ }
+ catch (Exception exception) when (exception is IOException or UnauthorizedAccessException)
+ {
+ // Best-effort cleanup only: a transiently locked file (e.g. an antivirus scan) must not fail the test run.
+ }
+ }
+
+ return ValueTask.CompletedTask;
+ }
+ }
+
+ internal sealed class DumpVerificationApp
+ {
+ private const string LibrarySource = """
+ using Microsoft.Extensions.DependencyInjection;
+ using Steeltoe.Management.Endpoint.Actuators.HeapDump;
+ using Steeltoe.Management.Endpoint.Actuators.ThreadDump;
+
+ namespace DumpTestLibrary;
+
+ public static class DumpProvider
+ {
+ public static void RegisterHeapDump(IServiceCollection services)
+ {
+ services.AddHeapDumpActuator(false);
+ }
+
+ public static void RegisterThreadDump(IServiceCollection services)
+ {
+ services.AddThreadDumpActuator(false);
+ }
+
+ public static async Task TakeHeapDumpAsync(IServiceProvider services)
+ {
+ var handler = services.GetRequiredService();
+ string path = await handler.InvokeAsync(null, CancellationToken.None);
+ File.Delete(path);
+ }
+
+ public static async Task TakeThreadDumpAsync(IServiceProvider services)
+ {
+ var handler = services.GetRequiredService();
+ await handler.InvokeAsync(null, CancellationToken.None);
+ }
+ }
+ """;
+
+ private const string GCDumpAppSource = """
+ using DumpTestLibrary;
+
+ WebApplicationBuilder builder = WebApplication.CreateBuilder();
+ builder.Configuration["Management:Endpoints:Heapdump:HeapDumpType"] = "GCDump";
+ DumpProvider.RegisterHeapDump(builder.Services);
+
+ await using WebApplication app = builder.Build();
+
+ try
+ {
+ await DumpProvider.TakeHeapDumpAsync(app.Services);
+ return 0;
+ }
+ catch (Exception exception)
+ {
+ Console.WriteLine($"FAILED: {exception}");
+ return 1;
+ }
+ """;
+
+ private const string MinidumpAppSource = """
+ using DumpTestLibrary;
+
+ WebApplicationBuilder builder = WebApplication.CreateBuilder();
+ builder.Configuration["Management:Endpoints:Heapdump:HeapDumpType"] = "Mini";
+ DumpProvider.RegisterHeapDump(builder.Services);
+
+ await using WebApplication app = builder.Build();
+
+ try
+ {
+ await DumpProvider.TakeHeapDumpAsync(app.Services);
+ return 0;
+ }
+ catch (Exception exception)
+ {
+ Console.WriteLine($"FAILED: {exception}");
+ return 1;
+ }
+ """;
+
+ private const string ThreadDumpAppSource = """
+ using DumpTestLibrary;
+
+ WebApplicationBuilder builder = WebApplication.CreateBuilder();
+ DumpProvider.RegisterThreadDump(builder.Services);
+
+ await using WebApplication app = builder.Build();
+
+ try
+ {
+ await DumpProvider.TakeThreadDumpAsync(app.Services);
+ return 0;
+ }
+ catch (Exception exception)
+ {
+ Console.WriteLine($"FAILED: {exception}");
+ return 1;
+ }
+ """;
+
+ private readonly string _appDirectory;
+
+ private DumpVerificationApp(string appDirectory)
+ {
+ _appDirectory = appDirectory;
+ }
+
+ internal static async Task CreateForGCDumpAsync(PackSteeltoeLibrariesOnceFixture fixture, string targetFramework)
+ {
+ return await CreateAsync(fixture, targetFramework, "GCDumpTestApp", GCDumpAppSource);
+ }
+
+ internal static async Task CreateForMinidumpAsync(PackSteeltoeLibrariesOnceFixture fixture, string targetFramework)
+ {
+ return await CreateAsync(fixture, targetFramework, "MinidumpTestApp", MinidumpAppSource);
+ }
+
+ internal static async Task CreateForThreadDumpAsync(PackSteeltoeLibrariesOnceFixture fixture, string targetFramework)
+ {
+ return await CreateAsync(fixture, targetFramework, "ThreadDumpTestApp", ThreadDumpAppSource);
+ }
+
+ private static async Task CreateAsync(PackSteeltoeLibrariesOnceFixture fixture, string targetFramework, string testAppName,
+ string appSource)
+ {
+ const string testLibraryName = "DumpTestLibrary";
+
+ string rootDirectory = Path.Combine(fixture.SessionDirectory, "projects");
+ string libraryDirectory = Directory.CreateDirectory(Path.Combine(rootDirectory, testLibraryName)).FullName;
+ string appDirectory = Directory.CreateDirectory(Path.Combine(rootDirectory, testAppName)).FullName;
+
+ await WriteNuGetConfigFileAsync(rootDirectory, fixture.Source);
+ await WriteLibraryProjectAsync(libraryDirectory, testLibraryName, fixture.PackageVersion, targetFramework);
+ await WriteAppProjectAsync(appDirectory, testAppName, testLibraryName, targetFramework, appSource);
+
+ return new DumpVerificationApp(appDirectory);
+ }
+
+ private static async Task WriteNuGetConfigFileAsync(string directory, NuGetSource source)
+ {
+ string contents = $"""
+
+
+
+
+
+
+
+
+
+ """;
+
+ string nuGetConfigPath = Path.Combine(directory, "nuget.config");
+ await File.WriteAllTextAsync(nuGetConfigPath, contents);
+ }
+
+ private static async Task WriteLibraryProjectAsync(string libraryDirectory, string libraryName, string packageVersion, string targetFramework)
+ {
+ string projectFilePath = Path.Combine(libraryDirectory, $"{libraryName}.csproj");
+ string projectFileContents = GetLibraryProjectFile(packageVersion, targetFramework);
+ await File.WriteAllTextAsync(projectFilePath, projectFileContents);
+
+ string sourcePath = Path.Combine(libraryDirectory, "DumpProvider.cs");
+ await File.WriteAllTextAsync(sourcePath, LibrarySource);
+ }
+
+ private static async Task WriteAppProjectAsync(string appDirectory, string testAppName, string testLibraryName, string targetFramework,
+ string appSource)
+ {
+ string projectFilePath = Path.Combine(appDirectory, $"{testAppName}.csproj");
+ string projectPath = GetAppProjectFile(testLibraryName, targetFramework);
+ await File.WriteAllTextAsync(projectFilePath, projectPath);
+
+ string sourcePath = Path.Combine(appDirectory, "Program.cs");
+ await File.WriteAllTextAsync(sourcePath, appSource);
+ }
+
+ private static string GetLibraryProjectFile(string packageVersion, string targetFramework)
+ {
+ return $"""
+
+
+ {targetFramework}
+ enable
+
+
+
+
+
+ """;
+ }
+
+ private static string GetAppProjectFile(string testLibraryName, string targetFramework)
+ {
+ return $"""
+
+
+ {targetFramework}
+ enable
+
+
+
+
+
+ """;
+ }
+
+ public async Task RunAsync()
+ {
+ await DotNetProcessRunner.RunAsync(_appDirectory, "run");
+ }
+ }
+
+ private static class DotNetProcessRunner
+ {
+ private static readonly TimeSpan ProcessExitTimeout = TimeSpan.FromMinutes(5);
+
+ public static async Task RunAsync(string workingDirectory, params string[] arguments)
+ {
+ CancellationToken cancellationToken = TestContext.Current.CancellationToken;
+
+ string[] dotNetArguments =
+ [
+ .. arguments,
+ "-p:RunAnalyzers=false",
+ "-p:NuGetAudit=false"
+ ];
+
+ var outputBuilder = new StringBuilder();
+ object outputLock = new();
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = "dotnet",
+ WorkingDirectory = workingDirectory,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ StandardOutputEncoding = Encoding.UTF8,
+ StandardErrorEncoding = Encoding.UTF8
+ };
+
+ foreach (string argument in dotNetArguments)
+ {
+ startInfo.ArgumentList.Add(argument);
+ }
+
+ // Without this, a spawned "dotnet build"/"run" leaves a persistent MSBuild worker node running in the background for reuse by a later
+ // build. That node inherits our redirected stdout/stderr pipe handles and keeps them open after the process we launched exits, so the
+ // read end never sees EOF and awaiting exit below would block forever even though the build already completed successfully.
+ startInfo.EnvironmentVariables["MSBUILDDISABLENODEREUSE"] = "1";
+
+ using var process = new Process();
+ process.StartInfo = startInfo;
+ process.OutputDataReceived += (_, eventArgs) => AppendLine(eventArgs.Data);
+ process.ErrorDataReceived += (_, eventArgs) => AppendLine(eventArgs.Data);
+ process.Start();
+ process.BeginOutputReadLine();
+ process.BeginErrorReadLine();
+
+ using var timeoutSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+ timeoutSource.CancelAfter(ProcessExitTimeout);
+
+ try
+ {
+ await process.WaitForExitAsync(timeoutSource.Token);
+ }
+ catch (OperationCanceledException)
+ {
+ KillEntireProcessTreeInBackground(process.Id);
+
+ if (cancellationToken.IsCancellationRequested)
+ {
+ throw;
+ }
+
+ throw new TimeoutException($"'dotnet {string.Join(' ', dotNetArguments)}' in '{workingDirectory}' did not exit within {ProcessExitTimeout}.");
+ }
+
+ string output = outputBuilder.ToString();
+
+ process.ExitCode.Should().Be(0, "'dotnet {0}' in '{1}' was expected to exit successfully. Output:\n{2}", string.Join(' ', dotNetArguments),
+ workingDirectory, output);
+
+ void AppendLine(string? line)
+ {
+ if (line == null)
+ {
+ return;
+ }
+
+#pragma warning disable S6507 // Blocks should not be synchronized on local variables
+ // Justification: Deliberately a call-scoped lock, not a shared static one: a global lock would serialize stdout/stderr callbacks across
+ // every concurrently running process, starving the thread pool under high-volume output (e.g. "dotnet build -v:detailed").
+ lock (outputLock)
+#pragma warning restore S6507 // Blocks should not be synchronized on local variables
+ {
+ outputBuilder.AppendLine(line);
+ }
+ }
+ }
+
+ private static void KillEntireProcessTreeInBackground(int processId)
+ {
+ // Fire-and-forget, so that pressing the Stop button in an IDE responds immediately.
+ _ = Task.Run(() =>
+ {
+ try
+ {
+ using var process = Process.GetProcessById(processId);
+ process.Kill(true);
+ }
+ catch (Exception)
+ {
+ // Best-effort kill of an already-timed-out process.
+ }
+ });
+ }
+ }
+
+ internal sealed record NuGetSource(string FeedDirectory, string PackagesDirectory);
+}
diff --git a/src/Management/test/Endpoint.Test/Actuators/ThreadDump/EventPipeThreadDumperTest.cs b/src/Management/test/Endpoint.Test/Actuators/ThreadDump/EventPipeThreadDumperTest.cs
index 43711fff72..e429641771 100644
--- a/src/Management/test/Endpoint.Test/Actuators/ThreadDump/EventPipeThreadDumperTest.cs
+++ b/src/Management/test/Endpoint.Test/Actuators/ThreadDump/EventPipeThreadDumperTest.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
+using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
using Steeltoe.Common.TestResources;
using Steeltoe.Management.Endpoint.Actuators.ThreadDump;
@@ -96,6 +97,7 @@ await action.Should().ThrowExactlyAsync()
private static class NestedType
{
+ [MethodImpl(MethodImplOptions.NoInlining)]
public static void BackgroundThreadCallback(object? argument)
{
(CancellationToken cancellationToken, ManualResetEventSlim threadStarted) = ((CancellationToken, ManualResetEventSlim))argument!;
diff --git a/src/Management/test/Endpoint.Test/Steeltoe.Management.Endpoint.Test.csproj b/src/Management/test/Endpoint.Test/Steeltoe.Management.Endpoint.Test.csproj
index 97607ba184..85b9af34bb 100644
--- a/src/Management/test/Endpoint.Test/Steeltoe.Management.Endpoint.Test.csproj
+++ b/src/Management/test/Endpoint.Test/Steeltoe.Management.Endpoint.Test.csproj
@@ -5,6 +5,11 @@
+
+
+
+
+
PreserveNewest
diff --git a/src/Management/test/GitProperties.Build.Test/Steeltoe.Management.GitProperties.Build.Test.csproj b/src/Management/test/GitProperties.Build.Test/Steeltoe.Management.GitProperties.Build.Test.csproj
index 983a147341..74b0e57f71 100644
--- a/src/Management/test/GitProperties.Build.Test/Steeltoe.Management.GitProperties.Build.Test.csproj
+++ b/src/Management/test/GitProperties.Build.Test/Steeltoe.Management.GitProperties.Build.Test.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/src/Management/test/GitProperties.Build.Test/TestAppTargetFramework.cs b/src/Management/test/GitProperties.Build.Test/TestAppTargetFramework.cs
index f50113a03c..4f7a506d28 100644
--- a/src/Management/test/GitProperties.Build.Test/TestAppTargetFramework.cs
+++ b/src/Management/test/GitProperties.Build.Test/TestAppTargetFramework.cs
@@ -16,7 +16,7 @@ internal static partial class TestAppTargetFramework
private static string Resolve()
{
AssemblyMetadataAttribute? attribute = Assembly.GetExecutingAssembly().GetCustomAttributes()
- .FirstOrDefault(candidate => candidate.Key == "TargetFramework");
+ .FirstOrDefault(candidate => candidate.Key == "TestTargetFramework");
if (attribute?.Value == null)
{
From 029fd43565238ff8cfa9573a872370dc1e204064 Mon Sep 17 00:00:00 2001
From: Bart Koelman <104792814+bart-vmware@users.noreply.github.com>
Date: Fri, 18 Sep 2026 10:47:25 +0200
Subject: [PATCH 2/2] Bump dump dependencies to latest versions
---
versions.props | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/versions.props b/versions.props
index e94e82c170..35675e60c2 100644
--- a/versions.props
+++ b/versions.props
@@ -55,7 +55,7 @@
2.2.*
1.8.*
- 9.0.652701
+ 10.0.745401
8.0.*
10.0.*
- 0.2.652701
- 3.1.23
+ 0.2.745401
+ 3.2.6
1.15.*-*
1.15.*
10.0.*