diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/OpenSSL/OpenSslExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/OpenSSL/OpenSslExecutorTests.cs index 7227dd6311..4fa8e44023 100644 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/OpenSSL/OpenSslExecutorTests.cs +++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/OpenSSL/OpenSslExecutorTests.cs @@ -23,6 +23,7 @@ public class OpenSslExecutorTests { private DependencyFixture fixture; private DependencyPath mockPackage; + private string mockOpensslVersion = "OpenSSL 3.5.0 8 Apr 2025 (Library: OpenSSL 3.5.0 8 Apr 2025)\n"; [Test] [TestCase(PlatformID.Unix, Architecture.X64, "linux-x64/bin/openssl")] @@ -287,6 +288,24 @@ await executor.ExecuteAsync(CancellationToken.None) } } + [Test] + public async Task OpenSslExecutorExecutesGetOpensslVersion() + { + this.SetupDefaultBehaviors(); + this.SetupOpensslVersionBehavior(); + + using (TestOpenSslExecutor executor = new TestOpenSslExecutor(this.fixture)) + { + + await executor.ExecuteAsync(CancellationToken.None) + .ConfigureAwait(false); + + var messages = this.fixture.Logger.MessagesLogged($"{nameof(OpenSslExecutor)}.GetOpenSslVersion"); + Assert.IsNotEmpty(messages); + Assert.IsTrue(messages.All(msg => (msg.Item3 as EventContext).Properties["opensslVersion"].ToString() == "OpenSSL 3.5.0 8 Apr 2025 (Library: OpenSSL 3.5.0 8 Apr 2025)")); + } + } + private void SetupDefaultBehaviors(PlatformID platform = PlatformID.Unix, Architecture architecture = Architecture.X64) { // Setup the default behaviors given all expected dependencies are in place such that the @@ -329,8 +348,20 @@ private void SetupDefaultBehaviors(PlatformID platform = PlatformID.Unix, Archit process.StandardOutput.Append(TestResources.Results_OpenSSL_speed); } }; + } + private void SetupOpensslVersionBehavior() + { + this.fixture.ProcessManager.OnProcessCreated = (process) => + { + // mock openssl version command result + if (process.IsMatch("openssl(.exe)* version")) + { + process.StandardOutput.Append(this.mockOpensslVersion); + } + }; + } private class TestOpenSslExecutor : OpenSslExecutor { public TestOpenSslExecutor(DependencyFixture mockFixture) diff --git a/src/VirtualClient/VirtualClient.Actions/OpenSSL/OpenSslExecutor.cs b/src/VirtualClient/VirtualClient.Actions/OpenSSL/OpenSslExecutor.cs index 829beb2db5..c676fc4913 100644 --- a/src/VirtualClient/VirtualClient.Actions/OpenSSL/OpenSslExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/OpenSSL/OpenSslExecutor.cs @@ -18,6 +18,7 @@ namespace VirtualClient.Actions using VirtualClient.Common.Telemetry; using VirtualClient.Contracts; using VirtualClient.Contracts.Metadata; + using YamlDotNet.Serialization; /// /// Executes the OpenSSL workload. @@ -90,17 +91,50 @@ await this.InitializeWorkloadToolsetsAsync(cancellationToken) .ConfigureAwait(false); } - private void CaptureMetrics(IProcessProxy workloadProcess, string commandArguments, EventContext telemetryContext) + /// + /// Gets openssl version by running openssl version command. + /// + private async Task GetOpenSslVersion(CancellationToken cancellationToken, string toolCommand) { - if (workloadProcess.ExitCode == 0) + // The OpenSSL version is not available in the workload output. We need to run a separate command to get the version. + // The command 'openssl version' will return the version of OpenSSL installed on the system. + string opensslVersion = "Unknown"; + if (!cancellationToken.IsCancellationRequested) { - try + this.Logger.LogTraceMessage($"Executing process 'openssl version' at directory '{this.ExecutablePath}'."); + using (IProcessProxy process = this.systemManagement.ProcessManager.CreateProcess(this.ExecutablePath, "version")) { + this.SetEnvironmentVariables(process); + await process.StartAndWaitAsync(cancellationToken).ConfigureAwait(false); + process.ThrowIfWorkloadFailed(); + + opensslVersion = process.StandardOutput?.ToString().Trim() ?? "Unknown"; + if (string.IsNullOrWhiteSpace(opensslVersion)) + { + opensslVersion = "Unknown"; + } + + this.MetadataContract.Add("OpenSSLVersion", opensslVersion, MetadataContractCategory.Dependencies); + this.Logger.LogMessage($"{nameof(OpenSslExecutor)}.GetOpenSslVersion", LogLevel.Information, EventContext.Persisted().AddContext("opensslVersion", opensslVersion)); + this.MetadataContract.AddForScenario( "OpenSSL Speed", - workloadProcess.FullCommand(), - toolVersion: null); + toolCommand, + toolVersion: opensslVersion); + } + } + + } + private void CaptureMetrics(IProcessProxy workloadProcess, string commandArguments, EventContext telemetryContext, CancellationToken cancellationToken) + { + if (workloadProcess.ExitCode == 0) + { + try + { + // Retrieve OpenSSL version + this.GetOpenSslVersion(cancellationToken, workloadProcess.FullCommand()); + this.MetadataContract.Apply(telemetryContext); OpenSslMetricsParser resultsParser = new OpenSslMetricsParser(workloadProcess.StandardOutput.ToString(), commandArguments); @@ -133,7 +167,7 @@ private Task ExecuteWorkloadAsync(EventContext telemetryContext, CancellationTok EventContext relatedContext = telemetryContext.Clone() .AddContext("executable", this.ExecutablePath) - .AddContext("commandArguments", commandArguments); + .AddContext("commandArguments", commandArguments); return this.Logger.LogMessageAsync($"{nameof(OpenSslExecutor)}.ExecuteWorkload", relatedContext, async () => { @@ -153,7 +187,7 @@ private Task ExecuteWorkloadAsync(EventContext telemetryContext, CancellationTok await this.LogProcessDetailsAsync(process, telemetryContext, "OpenSSL", logToFile: true); process.ThrowIfWorkloadFailed(); - this.CaptureMetrics(process, commandArguments, telemetryContext); + this.CaptureMetrics(process, commandArguments, telemetryContext, cancellationToken); } } finally