diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/Network/NetworkingWorkloadExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/Network/NetworkingWorkloadExecutorTests.cs index f0388f4ccb..205f03dad3 100644 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/Network/NetworkingWorkloadExecutorTests.cs +++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/Network/NetworkingWorkloadExecutorTests.cs @@ -90,6 +90,7 @@ public void NetworkingWorkloadStateInstancesAreJsonSerializable(bool? noSyncEnab "Profiling_Scenario_1", "00:00:30", "00:00:05", + 1, noSyncEnabled, Guid.NewGuid()); @@ -126,6 +127,7 @@ public void NetworkingWorkloadStateInstancesAreJsonSerializable_2() "Profiling_Scenario_1", "00:00:30", "00:00:05", + 1, false, Guid.NewGuid(), // @@ -174,6 +176,7 @@ public void NetworkingWorkloadStateInstancesAreJsonSerializable_3() "Profiling_Scenario_1", "00:00:30", "00:00:05", + 1, false, Guid.NewGuid(), // diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSClientExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSClientExecutor.cs index 21b41bc7d7..322b933c4f 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSClientExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSClientExecutor.cs @@ -31,21 +31,158 @@ public CPSClientExecutor(VirtualClientComponent component) public CPSClientExecutor(IServiceCollection dependencies, IDictionary parameters) : base(dependencies, parameters) { + this.InitializeWindowsClientCommandline(); + this.InitializeLinuxClientCommandline(); } - - /// - /// Returns the CPS client-side command line arguments. - /// - protected override string GetCommandLineArguments() + + private void InitializeWindowsClientCommandline() { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + // Ensure base string isn't null. + this.CommandLineWindowsClient ??= string.Empty; + + // Normalize: keep a trailing space so appends don't glue together. + if (this.CommandLineWindowsClient.Length > 0 && !char.IsWhiteSpace(this.CommandLineWindowsClient[^1])) + { + this.CommandLineWindowsClient += " "; + } + + // -c (client mode) + if (!this.CommandLineWindowsClient.Contains("-c", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsClient += " -c"; + } + + // -r {Connections} + // Your reference includes "-c -r {Connections}" + if (!this.CommandLineWindowsClient.Contains("-r", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsClient += $"-r {this.Connections} "; + } + + // Endpoint tuple: + // {clientIPAddress},0,{serverIPAddress},{Port},{ConnectionsPerThread},{MaxPendingRequestsPerThread},{ConnectionDuration},{DataTransferMode} + // Add it only if we don't already see the server IP (good heuristic to avoid duplication). + if (!this.CommandLineWindowsClient.Contains(serverIPAddress, StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsClient += + $"{clientIPAddress},0,{serverIPAddress},{this.Port},{this.ConnectionsPerThread},{this.MaxPendingRequestsPerThread},{this.ConnectionDuration},{this.DataTransferMode} "; + } + + // -i {DisplayInterval} + if (!this.CommandLineWindowsClient.Contains("-i", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsClient += $"-i {this.DisplayInterval} "; + } + + // -wt {WarmupTime.TotalSeconds} + if (!this.CommandLineWindowsClient.Contains("-wt", StringComparison.OrdinalIgnoreCase) && this.WarmupTime != null) + { + this.CommandLineWindowsClient += $"-wt {this.WarmupTime.TotalSeconds} "; + } + + // -t {TestDuration.TotalSeconds} + if (!this.CommandLineWindowsClient.Contains("-t", StringComparison.OrdinalIgnoreCase) && this.TestDuration != null) + { + this.CommandLineWindowsClient += $"-t {this.TestDuration.TotalSeconds} "; + } + + // Optional: -ds {DelayTime.TotalSeconds} only if DelayTime != 0 + if (!this.CommandLineWindowsClient.Contains("-ds", StringComparison.OrdinalIgnoreCase) && + this.DelayTime != TimeSpan.Zero) + { + this.CommandLineWindowsClient += $"-ds {this.DelayTime.TotalSeconds} "; + } + + // Additional params (append once) + if (!string.IsNullOrWhiteSpace(this.AdditionalParams)) + { + // Optional: prevent double-appending if already present. + // You can remove this block if AdditionalParams is expected to be dynamic. + if (!this.CommandLineWindowsClient.Contains(this.AdditionalParams, StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsClient += $"{this.AdditionalParams} "; + } + } + + this.CommandLineWindowsClient = this.CommandLineWindowsClient.Trim(); + } + + private void InitializeLinuxClientCommandline() + { string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + // Ensure base string isn't null. + this.CommandLineLinuxClient ??= string.Empty; + + // Normalize: keep a trailing space so appends don't glue together. + if (this.CommandLineLinuxClient.Length > 0 && !char.IsWhiteSpace(this.CommandLineLinuxClient[^1])) + { + this.CommandLineLinuxClient += " "; + } + + // -c (client mode) + if (!this.CommandLineLinuxClient.Contains("-c", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += " -c"; + } + + // -r {Connections} + // Your reference includes "-c -r {Connections}" + if (!this.CommandLineLinuxClient.Contains("-r", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $"-r {this.Connections} "; + } + + // Endpoint tuple: + // {clientIPAddress},0,{serverIPAddress},{Port},{ConnectionsPerThread},{MaxPendingRequestsPerThread},{ConnectionDuration},{DataTransferMode} + // Add it only if we don't already see the server IP (good heuristic to avoid duplication). + if (!this.CommandLineLinuxClient.Contains(serverIPAddress, StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += + $"{clientIPAddress},0,{serverIPAddress},{this.Port},{this.ConnectionsPerThread},{this.MaxPendingRequestsPerThread},{this.ConnectionDuration},{this.DataTransferMode} "; + } + + // -i {DisplayInterval} + if (!this.CommandLineLinuxClient.Contains("-i", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $"-i {this.DisplayInterval} "; + } + + // -wt {WarmupTime.TotalSeconds} + if (!this.CommandLineLinuxClient.Contains("-wt", StringComparison.OrdinalIgnoreCase) && this.WarmupTime != null) + { + this.CommandLineLinuxClient += $"-wt {this.WarmupTime.TotalSeconds} "; + } + + // -t {TestDuration.TotalSeconds} + if (!this.CommandLineLinuxClient.Contains("-t", StringComparison.OrdinalIgnoreCase) && this.TestDuration != null) + { + this.CommandLineLinuxClient += $"-t {this.TestDuration.TotalSeconds} "; + } + + // Optional: -ds {DelayTime.TotalSeconds} only if DelayTime != 0 + if (!this.CommandLineLinuxClient.Contains("-ds", StringComparison.OrdinalIgnoreCase) && + this.DelayTime != TimeSpan.Zero) + { + this.CommandLineLinuxClient += $"-ds {this.DelayTime.TotalSeconds} "; + } + + // Additional params (append once) + if (!string.IsNullOrWhiteSpace(this.AdditionalParams)) + { + // Optional: prevent double-appending if already present. + // You can remove this block if AdditionalParams is expected to be dynamic. + if (!this.CommandLineLinuxClient.Contains(this.AdditionalParams, StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $"{this.AdditionalParams} "; + } + } - return $"-c -r {this.Connections} " + - $"{clientIPAddress},0,{serverIPAddress},{this.Port},{this.ConnectionsPerThread},{this.MaxPendingRequestsPerThread},{this.ConnectionDuration},{this.DataTransferMode} " + - $"-i {this.DisplayInterval} -wt {this.WarmupTime.TotalSeconds} -t {this.TestDuration.TotalSeconds} " + - $"{((this.DelayTime != TimeSpan.Zero) ? $"-ds {this.DelayTime.TotalSeconds}" : string.Empty)} " + - $"{this.AdditionalParams}".Trim(); + this.CommandLineLinuxClient = this.CommandLineLinuxClient.Trim(); } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSMetricsParser.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSMetricsParser.cs index 1d1489957b..60b2d72c9d 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSMetricsParser.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSMetricsParser.cs @@ -82,18 +82,18 @@ private static void AddStatisticalMetrics(IList metrics, List ti double lowerCI = mean - t; double upperCI = mean + t; - metrics.Add(new Metric("ConnectsPerSec_Min", connectsPerSec.Min())); - metrics.Add(new Metric("ConnectsPerSec_Max", connectsPerSec.Max())); - metrics.Add(new Metric("ConnectsPerSec_Med", connectsPerSec.Median())); + metrics.Add(new Metric("ConnectsPerSec_Min", connectsPerSec.Min(), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_Max", connectsPerSec.Max(), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_Med", connectsPerSec.Median(), relativity: MetricRelativity.HigherIsBetter)); metrics.Add(new Metric("ConnectsPerSec_Avg", connectsPerSec.Average(), MetricUnit.TransactionsPerSec, MetricRelativity.HigherIsBetter, verbosity: 0)); - metrics.Add(new Metric("ConnectsPerSec_P25", connectsPerSec.Percentile(25))); - metrics.Add(new Metric("ConnectsPerSec_P50", connectsPerSec.Percentile(50))); - metrics.Add(new Metric("ConnectsPerSec_P75", connectsPerSec.Percentile(75))); - metrics.Add(new Metric("ConnectsPerSec_P90", connectsPerSec.Percentile(90))); - metrics.Add(new Metric("ConnectsPerSec_P99", connectsPerSec.Percentile(99))); - metrics.Add(new Metric("ConnectsPerSec_P99_9", Statistics.QuantileCustom(connectsPerSec, 1d - 0.001d, QuantileDefinition.R3))); - metrics.Add(new Metric("ConnectsPerSec_P99_99", Statistics.QuantileCustom(connectsPerSec, 1d - 0.0001d, QuantileDefinition.R3))); - metrics.Add(new Metric("ConnectsPerSec_P99_999", Statistics.QuantileCustom(connectsPerSec, 1d - 0.00001d, QuantileDefinition.R3))); + metrics.Add(new Metric("ConnectsPerSec_P25", connectsPerSec.Percentile(25), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_P50", connectsPerSec.Percentile(50), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_P75", connectsPerSec.Percentile(75), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_P90", connectsPerSec.Percentile(90), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_P99", connectsPerSec.Percentile(99), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_P99_9", Statistics.QuantileCustom(connectsPerSec, 1d - 0.001d, QuantileDefinition.R3), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_P99_99", Statistics.QuantileCustom(connectsPerSec, 1d - 0.0001d, QuantileDefinition.R3), relativity: MetricRelativity.HigherIsBetter)); + metrics.Add(new Metric("ConnectsPerSec_P99_999", Statistics.QuantileCustom(connectsPerSec, 1d - 0.00001d, QuantileDefinition.R3), relativity: MetricRelativity.HigherIsBetter)); double median = Statistics.Median(connectsPerSec); double[] absoluteDeviations = connectsPerSec.Select(x => Math.Abs(x - median)).ToArray(); metrics.Add(new Metric("ConnectsPerSec_Mad", Statistics.Median(absoluteDeviations), MetricUnit.TransactionsPerSec, MetricRelativity.LowerIsBetter, verbosity: 2)); diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSServerExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSServerExecutor.cs index 16889bdcae..b06a18b32d 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSServerExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/CPS/CPSServerExecutor.cs @@ -33,14 +33,132 @@ public CPSServerExecutor(IServiceCollection dependencies, IDictionary - /// Returns the CPS client-side command line arguments. - /// - protected override string GetCommandLineArguments() + private void InitializeLinuxServerCommandline() + { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + // Ensure base string isn't null. + this.CommandLineLinuxServer ??= string.Empty; + + // Normalize: keep a trailing space so appends don't glue together. + if (this.CommandLineLinuxServer.Length > 0 && !char.IsWhiteSpace(this.CommandLineLinuxServer[^1])) + { + this.CommandLineLinuxServer += " "; + } + + // -c (client mode) + if (!this.CommandLineLinuxServer.Contains("-s", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += " -s"; + } + + // -r {Connections} + // Your reference includes "-c -r {Connections}" + if (!this.CommandLineLinuxServer.Contains("-r", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += $" -r {this.Connections} "; + } + + // Endpoint tuple: + // {clientIPAddress},0,{serverIPAddress},{Port},{ConnectionsPerThread},{MaxPendingRequestsPerThread},{ConnectionDuration},{DataTransferMode} + // Add it only if we don't already see the server IP (good heuristic to avoid duplication). + if (!this.CommandLineLinuxServer.Contains(serverIPAddress, StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += + $"{serverIPAddress},{this.Port} "; + } + + // -i {DisplayInterval} + if (!this.CommandLineLinuxServer.Contains("-i", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += $" -i {this.DisplayInterval} "; + } + + // -wt {WarmupTime.TotalSeconds} + if (!this.CommandLineLinuxServer.Contains("-wt", StringComparison.OrdinalIgnoreCase) && this.WarmupTime != null) + { + this.CommandLineLinuxServer += $" -wt {this.WarmupTime.TotalSeconds} "; + } + + // -t {TestDuration.TotalSeconds} + if (!this.CommandLineLinuxServer.Contains("-t", StringComparison.OrdinalIgnoreCase) && this.TestDuration != null) + { + this.CommandLineLinuxServer += $" -t {this.TestDuration.TotalSeconds} "; + } + + // Optional: -ds {DelayTime.TotalSeconds} only if DelayTime != 0 + if (!this.CommandLineLinuxServer.Contains("-ds", StringComparison.OrdinalIgnoreCase) && + this.DelayTime != TimeSpan.Zero) + { + this.CommandLineLinuxServer += $" -ds {this.DelayTime.TotalSeconds} "; + } + + this.CommandLineLinuxServer = this.CommandLineLinuxServer.Trim(); + } + + private void InitializeWindowsServerCommandline() { string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; - return $"-s -r {this.Connections} {serverIPAddress},{this.Port} -i {this.DisplayInterval} -wt {this.WarmupTime.TotalSeconds} -t {this.TestDuration.TotalSeconds} " + - $"{((this.DelayTime != TimeSpan.Zero) ? $"-ds {this.DelayTime.TotalSeconds}" : string.Empty)} "; + string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + // Ensure base string isn't null. + this.CommandLineWindowsServer ??= string.Empty; + + // Normalize: keep a trailing space so appends don't glue together. + if (this.CommandLineWindowsServer.Length > 0 && !char.IsWhiteSpace(this.CommandLineWindowsServer[^1])) + { + this.CommandLineWindowsServer += " "; + } + + // -c (client mode) + if (!this.CommandLineWindowsServer.Contains("-s", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsServer += " -s"; + } + + // -r {Connections} + // Your reference includes "-c -r {Connections}" + if (!this.CommandLineWindowsServer.Contains("-r", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsServer += $" -r {this.Connections} "; + } + + // Endpoint tuple: + // {clientIPAddress},0,{serverIPAddress},{Port},{ConnectionsPerThread},{MaxPendingRequestsPerThread},{ConnectionDuration},{DataTransferMode} + // Add it only if we don't already see the server IP (good heuristic to avoid duplication). + if (!this.CommandLineWindowsServer.Contains(serverIPAddress, StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsServer += + $"{serverIPAddress},{this.Port} "; + } + + // -i {DisplayInterval} + if (!this.CommandLineWindowsServer.Contains("-i", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsServer += $" -i {this.DisplayInterval} "; + } + + // -wt {WarmupTime.TotalSeconds} + if (!this.CommandLineWindowsServer.Contains("-wt", StringComparison.OrdinalIgnoreCase) && this.WarmupTime != null) + { + this.CommandLineWindowsServer += $" -wt {this.WarmupTime.TotalSeconds} "; + } + + // -t {TestDuration.TotalSeconds} + if (!this.CommandLineWindowsServer.Contains("-t", StringComparison.OrdinalIgnoreCase) && this.TestDuration != null) + { + this.CommandLineWindowsServer += $" -t {this.TestDuration.TotalSeconds} "; + } + + // Optional: -ds {DelayTime.TotalSeconds} only if DelayTime != 0 + if (!this.CommandLineWindowsServer.Contains("-ds", StringComparison.OrdinalIgnoreCase) && + this.DelayTime != TimeSpan.Zero) + { + this.CommandLineWindowsServer += $" -ds {this.DelayTime.TotalSeconds} "; + } + + this.CommandLineWindowsServer = this.CommandLineWindowsServer.Trim(); } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteClientExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteClientExecutor.cs index 25a3807e36..98bb9de30a 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteClientExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteClientExecutor.cs @@ -38,6 +38,7 @@ public LatteClientExecutor(VirtualClientComponent component) public LatteClientExecutor(IServiceCollection dependencies, IDictionary parameters) : base(dependencies, parameters) { + this.InitializeWindowsClientCommandline(); } /// @@ -96,18 +97,6 @@ await this.ProcessStartRetryPolicy.ExecuteAsync(async () => }); } - /// - /// Returns the Latte client-side command line arguments. - /// - protected override string GetCommandLineArguments() - { - string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; - string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; - - return $"-so -c -a {serverIPAddress}:{this.Port} -rio -i {this.Iterations} -riopoll {this.RioPoll} -{this.Protocol.ToString().ToLowerInvariant()} " + - $"-hist -hl 1 -hc 9998 -bl {clientIPAddress}"; - } - /// /// Logs the workload metrics to the telemetry. /// @@ -138,5 +127,39 @@ protected override void CaptureMetrics(string results, string commandArguments, results); } } + + private void InitializeWindowsClientCommandline() + { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + + this.CommandLineWindowsClient ??= string.Empty; + + if (this.CommandLineWindowsClient.Length > 0 && !char.IsWhiteSpace(this.CommandLineWindowsClient[^1])) + { + this.CommandLineWindowsClient += " "; + } + + if (!this.CommandLineWindowsClient.Contains("--tcp", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineWindowsClient += this.Protocol.ToLowerInvariant() == "tcp" ? " --tcp" : string.Empty; + } + + if (!this.CommandLineWindowsClient.Contains("-i", StringComparison.OrdinalIgnoreCase) && this.Iterations != 0) + { + this.CommandLineWindowsClient += $" -i {this.Iterations} "; + } + + if (!this.CommandLineWindowsClient.Contains("-riopoll", StringComparison.OrdinalIgnoreCase) && this.RioPoll != 0) + { + this.CommandLineWindowsClient += $" -riopoll {this.RioPoll}"; + } + + if (this.Protocol != null && !this.CommandLineWindowsClient.Contains($"-{this.Protocol.ToString().ToLowerInvariant()}")) + { + this.CommandLineWindowsClient += $" -{this.Protocol.ToString().ToLowerInvariant()}"; + } + + this.CommandLineWindowsClient = this.CommandLineWindowsClient.Trim(); + } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteServerExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteServerExecutor.cs index b09594d2d5..2710cd91f3 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteServerExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/Latte/LatteServerExecutor.cs @@ -27,6 +27,7 @@ public class LatteServerExecutor : LatteExecutor public LatteServerExecutor(VirtualClientComponent component) : base(component) { + this.InitializeWindowsServerCommandline(); } /// @@ -99,14 +100,33 @@ await this.ProcessStartRetryPolicy.ExecuteAsync(async () => }); } - /// - /// Produces powershell script parameters using the workload parameters provided. - /// - /// Powershell script parameters as a string. - protected override string GetCommandLineArguments() + private void InitializeWindowsServerCommandline() { string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; - return $"-a {serverIPAddress}:{this.Port} -rio -i {this.Iterations} -riopoll {this.RioPoll} -{this.Protocol.ToLowerInvariant()}"; + + this.CommandLineWindowsServer ??= string.Empty; + + if (this.CommandLineWindowsServer.Length > 0 && !char.IsWhiteSpace(this.CommandLineWindowsServer[^1])) + { + this.CommandLineWindowsServer += " "; + } + + if (!this.CommandLineWindowsServer.Contains("-i", StringComparison.OrdinalIgnoreCase) && this.Iterations != 0) + { + this.CommandLineWindowsServer += $" -i {this.Iterations} "; + } + + if (!this.CommandLineWindowsServer.Contains("-riopoll", StringComparison.OrdinalIgnoreCase) && this.RioPoll != 0) + { + this.CommandLineWindowsServer += $" -riopoll {this.RioPoll}"; + } + + if (this.Protocol != null && !this.CommandLineWindowsServer.Contains($"-{this.Protocol.ToString().ToLowerInvariant()}")) + { + this.CommandLineWindowsServer += $" -{this.Protocol.ToString().ToLowerInvariant()}"; + } + + this.CommandLineWindowsServer = this.CommandLineWindowsServer.Trim(); } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpClientExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpClientExecutor.cs index d02bb42e66..2ac3be7b4a 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpClientExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpClientExecutor.cs @@ -30,6 +30,130 @@ public NTttcpClientExecutor(VirtualClientComponent component) public NTttcpClientExecutor(IServiceCollection dependencies, IDictionary parameters) : base(dependencies, parameters) { + this.IntializeLinuxClientCommandline(); + this.IntializeWindowsClientCommandline(); + } + + private void IntializeWindowsClientCommandline() + { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + if (!this.CommandLineWindowsClient.Contains("-r") && !this.CommandLineWindowsClient.Contains("-s")) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + " -s"; + } + + if (!this.CommandLineWindowsClient.Contains("-t") && this.TestDuration != null) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $" -t {this.TestDuration.TotalSeconds}"; + } + + if (!this.CommandLineWindowsClient.Contains("-l") && this.BufferSizeServer != null) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $" -l {this.BufferSizeClient}"; + } + + if (!this.CommandLineWindowsClient.Contains("-p")) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $" -p {this.Port}"; + } + + if (!this.CommandLineWindowsClient.Contains("-xml") && this.ResultsPath != null) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $" -xml {this.ResultsPath}"; + } + + if (!this.CommandLineWindowsClient.Contains("-u") && this.Protocol != null) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $"{(this.Protocol.ToLowerInvariant() == "udp" ? " -u" : string.Empty)} "; + } + + if (!this.CommandLineWindowsClient.Contains("-ns") && this.NoSyncEnabled != null) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $"{(this.NoSyncEnabled == true ? " -ns" : string.Empty)} "; + } + + if (!this.CommandLineWindowsClient.Contains("-m")) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $" -m {this.ThreadCount},*,{serverIPAddress} "; + } + + if (!this.CommandLineWindowsClient.Contains("-nic")) + { + this.CommandLineWindowsClient = this.CommandLineWindowsClient + $" -nic {clientIPAddress}"; + } + } + + private void IntializeLinuxClientCommandline() + { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + if (!this.CommandLineLinuxClient.Contains("-r") && !this.CommandLineLinuxClient.Contains("-s")) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + " -s"; + } + + if (!this.CommandLineLinuxClient.Contains("-t") && this.TestDuration != null) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $" -t {this.TestDuration.TotalSeconds}"; + } + + if (!this.CommandLineLinuxClient.Contains("-l") && this.BufferSizeClient != null) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $" -l {this.BufferSizeClient}"; + } + + if (!this.CommandLineLinuxClient.Contains("-p")) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $" -p {this.Port}"; + } + + if (!this.CommandLineLinuxClient.Contains("-xml") && this.ResultsPath != null) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $" -xml {this.ResultsPath}"; + } + + if (!this.CommandLineLinuxClient.Contains("-u") && this.Protocol != null) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $"{(this.Protocol.ToLowerInvariant() == "udp" ? " -u" : string.Empty)} "; + } + + if (!this.CommandLineLinuxClient.Contains("-ns") && this.NoSyncEnabled != null) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $"{(this.NoSyncEnabled == true ? " -ns" : string.Empty)} "; + } + + if (!this.CommandLineLinuxClient.Contains("-m")) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $" -m {this.ThreadCount},*,{serverIPAddress} "; + } + + if (!this.CommandLineLinuxClient.Contains("-L")) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $"{(this.SenderLastClient == true ? " -L" : string.Empty)} "; + } + + if (!this.CommandLineLinuxClient.Contains("-n")) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $"{((this.ThreadsPerServerPort != null) ? $" -n {this.ThreadsPerServerPort}" : string.Empty)} "; + } + + if (!this.CommandLineLinuxClient.Contains("-l")) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $"{((this.ConnectionsPerThread != null) ? $" -l {this.ConnectionsPerThread}" : string.Empty)} "; + } + + if (!this.CommandLineLinuxClient.Contains("-N") && this.NoSyncEnabled != null) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $"{(this.NoSyncEnabled == true ? " -N" : string.Empty)} "; + } + + if (!this.CommandLineLinuxClient.Contains("--show-dev-interrupts") && this.DevInterruptsDifferentiator != null) + { + this.CommandLineLinuxClient = this.CommandLineLinuxClient + $"{((this.DevInterruptsDifferentiator != null) ? $" --show-dev-interrupts {this.DevInterruptsDifferentiator}" : string.Empty)}".Trim(); + } } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpExecutor.cs index 242eae9a69..f9e41bfa9c 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpExecutor.cs @@ -250,24 +250,6 @@ protected override Task InitializeAsync(EventContext telemetryContext, Cancellat return this.SystemManagement.MakeFileExecutableAsync(this.ExecutablePath, this.Platform, cancellationToken); } - /// - /// Returns the NTttcp command line arguments. - /// - protected override string GetCommandLineArguments() - { - string command = null; - if (this.Platform == PlatformID.Win32NT) - { - command = this.GetWindowsSpecificCommandLine(); - } - else if (this.Platform == PlatformID.Unix) - { - command = this.GetLinuxSpecificCommandLine(); - } - - return command; - } - /// /// Gets the Sysctl command output. /// @@ -440,43 +422,5 @@ await this.SystemManagement.FileSystem.File.DeleteAsync(this.ResultsPath) .ConfigureAwait(false); } } - - private string GetWindowsSpecificCommandLine() - { - string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; - string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; - return $"{(this.IsInClientRole ? "-s" : "-r")} " + - $"-m {this.ThreadCount},*,{serverIPAddress} " + - $"-wu {NTttcpExecutor.DefaultWarmupTime.TotalSeconds} " + - $"-cd {NTttcpExecutor.DefaultCooldownTime.TotalSeconds} " + - $"-t {this.TestDuration.TotalSeconds} " + - $"-l {(this.IsInClientRole ? $"{this.BufferSizeClient}" : $"{this.BufferSizeServer}")} " + - $"-p {this.Port} " + - $"-xml {this.ResultsPath} " + - $"{(this.Protocol.ToLowerInvariant() == "udp" ? "-u" : string.Empty)} " + - $"{(this.NoSyncEnabled == true ? "-ns" : string.Empty)} " + - $"{(this.IsInClientRole ? $"-nic {clientIPAddress}" : string.Empty)}".Trim(); - } - - private string GetLinuxSpecificCommandLine() - { - string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; - return $"{(this.IsInClientRole ? "-s" : "-r")} " + - $"-V " + - $"-m {this.ThreadCount},*,{serverIPAddress} " + - $"-W {NTttcpExecutor.DefaultWarmupTime.TotalSeconds} " + - $"-C {NTttcpExecutor.DefaultCooldownTime.TotalSeconds} " + - $"-t {this.TestDuration.TotalSeconds} " + - $"-b {(this.IsInClientRole ? $"{this.BufferSizeClient}" : $"{this.BufferSizeServer}")} " + - $"-x {this.ResultsPath} " + - $"-p {this.Port} " + - $"{(this.Protocol.ToLowerInvariant() == "udp" ? "-u" : string.Empty)} " + - $"{((this.IsInClientRole && this.SenderLastClient == true) ? "-L" : string.Empty)} " + - $"{((this.IsInServerRole && this.ReceiverMultiClientMode == true) ? "-M" : string.Empty)} " + - $"{((this.IsInClientRole && this.ThreadsPerServerPort != null) ? $"-n {this.ThreadsPerServerPort}" : string.Empty)} " + - $"{((this.IsInClientRole && this.ConnectionsPerThread != null) ? $"-l {this.ConnectionsPerThread}" : string.Empty)} " + - $"{(this.NoSyncEnabled == true ? "-N" : string.Empty)} " + - $"{((this.DevInterruptsDifferentiator != null) ? $"--show-dev-interrupts {this.DevInterruptsDifferentiator}" : string.Empty)}".Trim(); - } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpServerExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpServerExecutor.cs index 24e9f242c7..8341d08348 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpServerExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NTttcp/NTttcpServerExecutor.cs @@ -5,6 +5,7 @@ namespace VirtualClient.Actions.NetworkPerformance { using System; using System.Collections.Generic; + using System.Linq; using Microsoft.Extensions.DependencyInjection; using VirtualClient.Contracts; @@ -30,6 +31,113 @@ public NTttcpServerExecutor(VirtualClientComponent component) public NTttcpServerExecutor(IServiceCollection dependencies, IDictionary parameters) : base(dependencies, parameters) { + this.IntializeLinuxServerCommandline(); + this.IntializeWindowsServerCommandline(); + } + + private void IntializeWindowsServerCommandline() + { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + if (!this.CommandLineWindowsServer.Contains("-r") && !this.CommandLineWindowsServer.Contains("-s")) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + " -r"; + } + + if (!this.CommandLineWindowsServer.Contains("-t") && this.TestDuration != null) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + $" -t {this.TestDuration.TotalSeconds}"; + } + + if (!this.CommandLineWindowsServer.Contains("-l") && this.BufferSizeServer != null) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + $" -l {this.BufferSizeServer}"; + } + + if (!this.CommandLineWindowsServer.Contains("-p")) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + $" -p {this.Port}"; + } + + if (!this.CommandLineWindowsServer.Contains("-xml") && this.ResultsPath != null) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + $" -xml {this.ResultsPath}"; + } + + if (!this.CommandLineWindowsServer.Contains("-u") && this.Protocol != null) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + $"{(this.Protocol.ToLowerInvariant() == "udp" ? " -u" : string.Empty)} "; + } + + if (!this.CommandLineWindowsServer.Contains("-ns") && this.NoSyncEnabled != null) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + $"{(this.NoSyncEnabled == true ? " -ns" : string.Empty)} "; + } + + if (!this.CommandLineWindowsServer.Contains("-m")) + { + this.CommandLineWindowsServer = this.CommandLineWindowsServer + $" -m {this.ThreadCount},*,{serverIPAddress} "; + } + } + + private void IntializeLinuxServerCommandline() + { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + if (!this.CommandLineLinuxClient.Contains("-r") && !this.CommandLineLinuxServer.Contains("-s")) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + " -r"; + } + + if (!this.CommandLineLinuxServer.Contains("-t") && this.TestDuration != null) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $" -t {this.TestDuration.TotalSeconds}"; + } + + if (!this.CommandLineLinuxServer.Contains("-l") && this.BufferSizeClient != null) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $" -l {this.BufferSizeServer}"; + } + + if (!this.CommandLineWindowsServer.Contains("-p")) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $" -p {this.Port}"; + } + + if (!this.CommandLineLinuxServer.Contains("-xml") && this.ResultsPath != null) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $" -xml {this.ResultsPath}"; + } + + if (!this.CommandLineLinuxServer.Contains("-u") && this.Protocol != null) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $"{(this.Protocol.ToLowerInvariant() == "udp" ? " -u" : string.Empty)} "; + } + + if (!this.CommandLineLinuxServer.Contains("-ns") && this.NoSyncEnabled != null) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $"{(this.NoSyncEnabled == true ? " -ns" : string.Empty)} "; + } + + if (!this.CommandLineLinuxServer.Contains("-m")) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $" -m {this.ThreadCount},*,{serverIPAddress} "; + } + + if (!this.CommandLineLinuxServer.Contains("-M")) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $"{((this.ReceiverMultiClientMode == true) ? " -M" : string.Empty)} "; + } + + if (!this.CommandLineLinuxServer.Contains("-N") && this.NoSyncEnabled != null) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $"{(this.NoSyncEnabled == true ? " -N" : string.Empty)} "; + } + + if (!this.CommandLineLinuxServer.Contains("--show-dev-interrupts") && this.DevInterruptsDifferentiator != null) + { + this.CommandLineLinuxServer = this.CommandLineLinuxServer + $"{((this.DevInterruptsDifferentiator != null) ? $" --show-dev-interrupts {this.DevInterruptsDifferentiator}" : string.Empty)}".Trim(); + } } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadExecutor.cs index e2ad4d3495..23d2e17aa6 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadExecutor.cs @@ -813,6 +813,7 @@ protected void OnInstructionsReceived(object sender, JObject instructions) this.ProfilingScenario = serverInstructions.ProfilingScenario; this.ProfilingPeriod = serverInstructions.ProfilingPeriod; this.ProfilingWarmUpPeriod = serverInstructions.ProfilingWarmUpPeriod; + this.ProfileIteration = serverInstructions.ProfileIteration; this.NoSyncEnabled = serverInstructions.NoSyncEnabled; if (serverInstructions.Metadata?.Any() == true) @@ -982,6 +983,7 @@ await this.ClientExecutionRetryPolicy.ExecuteAsync(async () => this.ProfilingScenario, this.ProfilingPeriod.ToString(), this.ProfilingWarmUpPeriod.ToString(), + this.ProfileIteration, this.NoSyncEnabled, requestId); diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadState.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadState.cs index 955835d76f..7d3aba4f22 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadState.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadState.cs @@ -134,6 +134,7 @@ public NetworkingWorkloadState( string profilingScenario = null, string profilingPeriod = null, string profilingWarmUpPeriod = null, + int? profileIteration = null, bool? noSyncEnabled = null, Guid? clientRequestId = null, IDictionary metadata = null) @@ -169,6 +170,7 @@ public NetworkingWorkloadState( this.Properties[nameof(this.ProfilingScenario)] = profilingScenario; this.Properties[nameof(this.ProfilingPeriod)] = profilingPeriod; this.Properties[nameof(this.ProfilingWarmUpPeriod)] = profilingWarmUpPeriod; + this.Properties[nameof(this.ProfileIteration)] = profileIteration; this.Properties[nameof(this.NoSyncEnabled)] = noSyncEnabled; this.ClientRequestId = clientRequestId; @@ -487,6 +489,17 @@ protected set } } + /// + /// Virtual Client Iteration at which the current profile is executing. + /// + public int ProfileIteration + { + get + { + return this.Properties.GetValue(nameof(this.ProfileIteration), 0); + } + } + /// /// Differentiator for which to convey the number of interrupts (Parameter for Tools: NTttcp) /// diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadToolExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadToolExecutor.cs index 5362cd4d9c..6cb1dd1cf7 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadToolExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/NetworkingWorkloadToolExecutor.cs @@ -42,6 +42,70 @@ protected NetworkingWorkloadToolExecutor(IServiceCollection dependencies, IDicti { } + /// + /// Commandline for linux client side. + /// + public string CommandLineLinuxClient + { + get + { + return this.Parameters.GetValue(nameof(this.CommandLineLinuxClient)); + } + + set + { + this.Parameters[nameof(this.CommandLineLinuxClient)] = value; + } + } + + /// + /// Commandline for linux server side. + /// + public string CommandLineLinuxServer + { + get + { + return this.Parameters.GetValue(nameof(this.CommandLineLinuxServer)); + } + + set + { + this.Parameters[nameof(this.CommandLineLinuxServer)] = value; + } + } + + /// + /// Commandline for windows client side. + /// + public string CommandLineWindowsClient + { + get + { + return this.Parameters.GetValue(nameof(this.CommandLineWindowsClient)); + } + + set + { + this.Parameters[nameof(this.CommandLineWindowsClient)] = value; + } + } + + /// + /// Commandline for windows server side. + /// + public string CommandLineWindowsServer + { + get + { + return this.Parameters.GetValue(nameof(this.CommandLineWindowsServer)); + } + + set + { + this.Parameters[nameof(this.CommandLineWindowsServer)] = value; + } + } + /// /// Name of the scenario. /// @@ -336,7 +400,29 @@ protected virtual bool IsProcessRunning(string processName) /// Produces powershell script parameters using the workload parameters provided. /// /// Powershell script parameters as a string. - protected abstract string GetCommandLineArguments(); + protected virtual string GetCommandLineArguments() + { + string command = string.Empty; + + if (this.Platform == PlatformID.Win32NT && this.IsInClientRole) + { + command = this.CommandLineWindowsClient; + } + else if (this.Platform == PlatformID.Win32NT && !this.IsInClientRole) + { + command = this.CommandLineWindowsServer; + } + else if (this.Platform == PlatformID.Unix && this.IsInClientRole) + { + command = this.CommandLineLinuxClient; + } + else if (this.Platform == PlatformID.Unix && !this.IsInClientRole) + { + command = this.CommandLineLinuxServer; + } + + return command; + } /// /// Returns true if results are found in the results file within the polling/timeout diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfClientExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfClientExecutor.cs index d0a11acf7b..383f7f2775 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfClientExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfClientExecutor.cs @@ -11,7 +11,6 @@ namespace VirtualClient.Actions.NetworkPerformance using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using VirtualClient.Common; - using VirtualClient.Common.Extensions; using VirtualClient.Common.Telemetry; using VirtualClient.Contracts; using VirtualClient.Contracts.Metadata; @@ -29,6 +28,7 @@ public class SockPerfClientExecutor : SockPerfExecutor public SockPerfClientExecutor(VirtualClientComponent component) : base(component) { + this.InitializeLinuxClientCommandline(); } /// @@ -107,26 +107,6 @@ await this.ProcessStartRetryPolicy.ExecuteAsync(async () => }); } - /// - /// Returns the Sockperf client-side command line arguments. - /// - protected override string GetCommandLineArguments() - { - string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; - string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; - string protocolParam = this.Protocol.ToLowerInvariant() == "tcp" ? "--tcp" : string.Empty; - - // sockperf under-load -i 10.0.1.1 -p 8201 -t 60 --mps=max --full-rtt --msg-size 64 --client_ip 10.0.1.0 - return $"{this.TestMode} " + - $"-i {serverIPAddress} " + - $"-p {this.Port} {protocolParam} " + - $"-t {this.TestDuration.TotalSeconds} " + - $"{(this.MessagesPerSecond.ToLowerInvariant() == "max" ? "--mps=max" : $"--mps {this.MessagesPerSecond}")} " + - $"--full-rtt --msg-size {this.MessageSize} " + - $"--client_ip {clientIPAddress} " + - $"--full-log {this.ResultsPath}"; - } - /// /// Logs the workload metrics to the telemetry. /// @@ -165,5 +145,65 @@ await this.SystemManagement.FileSystem.File.DeleteAsync(this.ResultsPath) .ConfigureAwait(false); } } + + private void InitializeLinuxClientCommandline() + { + string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; + string clientIPAddress = this.GetLayoutClientInstances(ClientRole.Client).First().IPAddress; + + this.CommandLineLinuxClient ??= string.Empty; + + if (this.CommandLineLinuxClient.Length > 0 && !char.IsWhiteSpace(this.CommandLineLinuxClient[^1])) + { + this.CommandLineLinuxClient += " "; + } + + if (!this.CommandLineLinuxClient.Contains(this.TestMode, StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $" {this.TestMode}"; + } + + if (!this.CommandLineLinuxClient.Contains("--tcp", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += this.Protocol.ToLowerInvariant() == "tcp" ? "--tcp" : string.Empty; + } + + if (!this.CommandLineLinuxClient.Contains("-i", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $"-i {serverIPAddress} "; + } + + if (!this.CommandLineLinuxClient.Contains("-p", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $" -p {this.Port}"; + } + + if (!this.CommandLineLinuxClient.Contains("-t", StringComparison.OrdinalIgnoreCase) && this.TestDuration != null) + { + this.CommandLineLinuxClient += $"-t {this.TestDuration.TotalSeconds} "; + } + + if (!this.CommandLineLinuxClient.Contains("--mps", StringComparison.OrdinalIgnoreCase) && this.MessagesPerSecond != null) + { + this.CommandLineLinuxClient += $" {(this.MessagesPerSecond.ToLowerInvariant() == "max" ? "--mps=max" : $"--mps {this.MessagesPerSecond}")}"; + } + + if (!this.CommandLineLinuxClient.Contains("--msg-size", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $" --msg-size {this.MessageSize}"; + } + + if (!this.CommandLineLinuxClient.Contains("--client_ip", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $" --client_ip {clientIPAddress}"; + } + + if (!this.CommandLineLinuxClient.Contains("--full-log", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxClient += $" --full-log {this.ResultsPath}"; + } + + this.CommandLineLinuxClient = this.CommandLineLinuxClient.Trim(); + } } } diff --git a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfServerExecutor.cs b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfServerExecutor.cs index 51833271c6..fa21677393 100644 --- a/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfServerExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/Network/NetworkingWorkload/SockPerf/SockPerfServerExecutor.cs @@ -37,6 +37,7 @@ public SockPerfServerExecutor(VirtualClientComponent component) public SockPerfServerExecutor(IServiceCollection dependencies, IDictionary parameters) : base(dependencies, parameters) { + this.InitializeLinuxServerCommandline(); } /// @@ -104,16 +105,43 @@ await this.ProcessStartRetryPolicy.ExecuteAsync(async () => }); } - /// - /// Returns the Sockperf server-side command line arguments. - /// - protected override string GetCommandLineArguments() + private void InitializeLinuxServerCommandline() { - // sockperf server -i 10.0.1.1 -p 8201 --tcp string serverIPAddress = this.GetLayoutClientInstances(ClientRole.Server).First().IPAddress; - string protocolParam = this.Protocol.ToLowerInvariant() == "tcp" ? "--tcp" : string.Empty; + + this.CommandLineLinuxServer ??= string.Empty; + + if (this.CommandLineLinuxServer.Length > 0 && !char.IsWhiteSpace(this.CommandLineLinuxServer[^1])) + { + this.CommandLineLinuxServer += " "; + } + + if (!this.CommandLineLinuxServer.Contains("server", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += "server"; + } + + if (!this.CommandLineLinuxServer.Contains("--tcp", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += this.Protocol.ToLowerInvariant() == "tcp" ? "--tcp" : string.Empty; + } + + if (!this.CommandLineLinuxServer.Contains("-i", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += $"-i {serverIPAddress} "; + } + + if (!this.CommandLineLinuxServer.Contains("-p", StringComparison.OrdinalIgnoreCase)) + { + this.CommandLineLinuxServer += $" -p {this.Port}"; + } + + if (!this.CommandLineLinuxServer.Contains("-t", StringComparison.OrdinalIgnoreCase) && this.TestDuration != null) + { + this.CommandLineLinuxServer += $"-t {this.TestDuration.TotalSeconds} "; + } - return $"server -i {serverIPAddress} -p {this.Port} {protocolParam}".Trim(); + this.CommandLineLinuxServer = this.CommandLineLinuxServer.Trim(); } } } diff --git a/src/VirtualClient/VirtualClient.Contracts/VirtualClientComponent.cs b/src/VirtualClient/VirtualClient.Contracts/VirtualClientComponent.cs index f4028be9f1..3872aca4d5 100644 --- a/src/VirtualClient/VirtualClient.Contracts/VirtualClientComponent.cs +++ b/src/VirtualClient/VirtualClient.Contracts/VirtualClientComponent.cs @@ -417,6 +417,11 @@ public int ProfileIteration this.Parameters.TryGetValue(nameof(this.ProfileIteration), out IConvertible profileIteration); return profileIteration != null ? (int)Convert.ChangeType(profileIteration, typeof(int)) : 0; } + + protected set + { + this.Parameters[nameof(this.ProfileIteration)] = value; + } } ///