From 68eec9d9b13e3706a21926776d63c71323968d99 Mon Sep 17 00:00:00 2001 From: saibulusu Date: Tue, 2 Sep 2025 13:06:56 -0700 Subject: [PATCH 1/7] FIO platform --- src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs | 2 +- .../VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json | 2 +- .../profiles/PERF-IO-FIO-MULTITHROUGHPUT.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs b/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs index f13f6cec07..f3988ec7ee 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs @@ -25,7 +25,7 @@ namespace VirtualClient.Actions /// /// Manages the execution runtime of the FIO workload. /// - [SupportedPlatforms("linux-arm64,linux-x64,win-arm64,win-x64")] + [SupportedPlatforms("linux-arm64,linux-x64,win-x64")] public class FioExecutor : VirtualClientComponent { /// diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json index bd159a855e..d91e1d036d 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json @@ -2,7 +2,7 @@ "Description": "FIO I/O Stress Performance Workload", "Metadata": { "RecommendedMinimumExecutionTime": "02:00:00", - "SupportedPlatforms": "linux-x64,linux-arm64,win-x64", + "SupportedPlatforms": "linux-x64,linux-arm64", "SupportedOperatingSystems": "CBL-Mariner,CentOS,Debian,RedHat,Suse,Ubuntu,Windows" }, "Parameters": { diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json index dc86616a1f..9f38487859 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json @@ -2,8 +2,8 @@ "Description": "FIO Multi Throughput (OLTP-C) Workload", "Metadata": { "DiskSelectionInformation": "Sequential disk count specifies the number of disks being used for Sequential I/O from selected disks. Out of which the smallest disks are selected.", - "RecommendedMinimumExecutionTime": "02:00:00", - "SupportedPlatforms": "linux-x64,linux-arm64,win-x64", + "RecommendedMinimumExecutionTime": "02:00:00", + "SupportedPlatforms": "linux-x64,linux-arm64", "SupportedOperatingSystems": "CBL-Mariner,CentOS,Debian,RedHat,Suse,Ubuntu,Windows" }, "Parameters": { From 3a9d4e5584ce36d2dfb18276f0a65f322506ef1c Mon Sep 17 00:00:00 2001 From: saibulusu Date: Tue, 9 Sep 2025 22:14:50 -0700 Subject: [PATCH 2/7] Removing discovery & multithroughput, removing job file from FioExecutor. --- .../FioDiscoveryProfileTests.cs | 273 ------ .../FioMultiThroughputProfileTests.cs | 109 --- .../FIO/FioDiscoveryExecutorTests.cs | 315 ------- .../FIO/FioExecutorTests.cs | 88 -- .../FIO/FioMultiThroughputExecutorTests.cs | 419 --------- .../FIO/FioDiscoveryExecutor.cs | 328 ------- .../VirtualClient.Actions/FIO/FioExecutor.cs | 74 +- .../FIO/FioMultiThroughputExecutor.cs | 853 ------------------ .../FIO/oltp-c.fio.jobfile | 79 -- ...kfill.fio.jobfile => oltp-c2-diskfill.fio} | 6 +- ....fio.jobfile => oltp-c2-operations-4k.fio} | 42 +- .../VirtualClient.Actions.csproj | 2 +- .../profiles/PERF-IO-FIO-DISCOVERY.json | 632 ------------- .../profiles/PERF-IO-FIO-MULTITHROUGHPUT.json | 112 --- .../profiles/PERF-IO-FIO-OLTP.json | 160 +--- 15 files changed, 36 insertions(+), 3456 deletions(-) delete mode 100644 src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioDiscoveryProfileTests.cs delete mode 100644 src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioMultiThroughputProfileTests.cs delete mode 100644 src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioDiscoveryExecutorTests.cs delete mode 100644 src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioMultiThroughputExecutorTests.cs delete mode 100644 src/VirtualClient/VirtualClient.Actions/FIO/FioDiscoveryExecutor.cs delete mode 100644 src/VirtualClient/VirtualClient.Actions/FIO/FioMultiThroughputExecutor.cs delete mode 100644 src/VirtualClient/VirtualClient.Actions/FIO/oltp-c.fio.jobfile rename src/VirtualClient/VirtualClient.Actions/FIO/{oltp-c2-diskfill.fio.jobfile => oltp-c2-diskfill.fio} (88%) rename src/VirtualClient/VirtualClient.Actions/FIO/{oltp-c2-operations.fio.jobfile => oltp-c2-operations-4k.fio} (57%) delete mode 100644 src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json delete mode 100644 src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json diff --git a/src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioDiscoveryProfileTests.cs b/src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioDiscoveryProfileTests.cs deleted file mode 100644 index a75c4e97dd..0000000000 --- a/src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioDiscoveryProfileTests.cs +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace VirtualClient.Actions -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using NUnit.Framework; - using VirtualClient.Common; - using VirtualClient.Contracts; - - [TestFixture] - [Category("Functional")] - public class FioDiscoveryProfileTests - { - private DependencyFixture mockFixture; - - [OneTimeSetUp] - public void SetupFixture() - { - this.mockFixture = new DependencyFixture(); - ComponentTypeCache.Instance.LoadComponentTypes(TestDependencies.TestDirectory); - } - - [Test] - [TestCase("PERF-IO-FIO-DISCOVERY.json")] - public void FioDiscoveryWorkloadProfileParametersAreInlinedCorrectly(string profile) - { - this.mockFixture.Setup(PlatformID.Win32NT); - using (ProfileExecutor executor = TestDependencies.CreateProfileExecutor(profile, this.mockFixture.Dependencies)) - { - WorkloadAssert.ParameterReferencesInlined(executor.Profile); - } - } - - [Test] - [TestCase("PERF-IO-FIO-DISCOVERY.json")] - public async Task FioDiscoveryWorkloadProfileInstallsTheExpectedDependenciesOnUnixPlatform(string profile) - { - // The disks are setup in a typical Azure VM scenario - // (e.g. 1 OS disk, 1 temp/local disk, multiple remote disks that are unformatted). - this.mockFixture.Setup(PlatformID.Unix); - this.mockFixture.SetupDisks(withUnformatted: true); - - using (ProfileExecutor executor = TestDependencies.CreateProfileExecutor(profile, this.mockFixture.Dependencies, dependenciesOnly: true)) - { - await executor.ExecuteAsync(ProfileTiming.OneIteration(), CancellationToken.None).ConfigureAwait(false); - - // Format disk dependency expectations. - // By the time the dependencies have been installed, all disks should be formatted and ready for - // operations against the file system. - WorkloadAssert.DisksAreInitialized(this.mockFixture); - - // Apt packages expectations - // There are a few Apt packages that must be installed for the FIO workload to run. - WorkloadAssert.AptPackageInstalled(this.mockFixture, "fio"); - } - } - - [Test] - [TestCase("PERF-IO-FIO-DISCOVERY.json")] - public async Task FioDiscoveryWorkloadProfileExecutesTheExpectedWorkloadsOnUnixPlatform(string profile) - { - IEnumerable expectedCommands = FioDiscoveryProfileTests.GetFioProfileExpectedCommands(PlatformID.Unix); - - // Setup the expectations for the workload - // - Disks are formatted and ready - // - Workload package is installed and exists. - // - Workload binaries/executables exist on the file system. - // - The workload generates valid results. - this.mockFixture.Setup(PlatformID.Unix); - this.mockFixture.SetupDisks(withUnformatted: false); - this.mockFixture.SetupPackage("fio", expectedFiles: $@"linux-x64/fio"); - - this.mockFixture.ProcessManager.OnCreateProcess = (command, arguments, workingDir) => - { - IProcessProxy process = this.mockFixture.CreateProcess(command, arguments, workingDir); - if (arguments.Contains("fio", StringComparison.OrdinalIgnoreCase)) - { - process.StandardOutput.Append(TestDependencies.GetResourceFileContents("Results_FIO.json")); - } - - return process; - }; - - using (ProfileExecutor executor = TestDependencies.CreateProfileExecutor(profile, this.mockFixture.Dependencies)) - { - await executor.ExecuteAsync(ProfileTiming.OneIteration(), CancellationToken.None).ConfigureAwait(false); - - WorkloadAssert.CommandsExecuted(this.mockFixture, expectedCommands.ToArray()); - } - } - - private static IEnumerable GetFioProfileExpectedCommands(PlatformID platform) - { - return new List - { - "fio --name=disk_fill --size=134G --rw=write --bs=256K --numjobs=1 --iodepth=64 --ioengine=libaio --fallocate=none --refill_buffers=1 --direct=1 --overwrite=1 --output-format=json", - "fio --name=fio_discovery_randread_134G_1k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randread --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randread --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randread --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randread --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_4k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_4k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_4k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randread --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_4k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randread --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_4k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randread --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_4k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randread --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_8k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_8k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_8k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randread --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_8k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randread --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_8k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randread --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_8k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randread --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_16k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_16k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_16k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randread --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_16k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randread --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_16k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randread --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_16k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randread --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_64k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_64k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_64k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randread --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_64k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randread --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_64k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randread --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_64k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randread --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_256k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_256k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_256k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randread --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_256k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randread --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_256k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randread --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_256k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randread --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1024k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1024k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randread --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1024k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randread --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1024k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randread --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1024k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randread --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randread_134G_1024k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randread --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randwrite --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randwrite --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randwrite --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_4k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_4k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_4k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_4k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randwrite --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_4k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randwrite --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_4k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randwrite --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_8k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_8k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_8k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_8k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randwrite --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_8k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randwrite --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_8k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randwrite --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_16k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_16k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_16k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_16k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randwrite --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_16k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randwrite --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_16k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randwrite --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_64k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_64k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_64k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_64k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randwrite --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_64k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randwrite --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_64k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randwrite --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_256k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_256k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_256k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_256k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randwrite --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_256k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randwrite --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_256k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randwrite --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1024k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1024k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1024k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1024k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=randwrite --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1024k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=randwrite --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_randwrite_134G_1024k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=randwrite --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=read --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=read --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=read --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=read --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_4k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_4k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_4k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=read --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_4k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=read --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_4k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=read --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_4k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=read --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_8k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_8k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_8k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=read --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_8k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=read --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_8k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=read --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_8k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=read --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_16k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_16k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_16k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=read --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_16k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=read --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_16k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=read --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_16k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=read --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_64k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_64k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_64k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=read --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_64k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=read --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_64k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=read --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_64k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=read --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_256k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_256k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_256k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=read --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_256k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=read --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_256k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=read --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_256k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=read --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1024k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1024k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=read --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1024k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=read --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1024k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=read --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1024k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=read --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_read_134G_1024k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=read --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=write --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=write --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=write --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=write --bs=1k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_4k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_4k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_4k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=write --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_4k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=write --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_4k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=write --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_4k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=write --bs=4k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_8k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_8k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_8k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=write --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_8k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=write --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_8k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=write --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_8k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=write --bs=8k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_16k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_16k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_16k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=write --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_16k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=write --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_16k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=write --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_16k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=write --bs=16k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_64k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_64k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_64k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=write --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_64k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=write --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_64k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=write --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_64k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=write --bs=64k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_256k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_256k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_256k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=write --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_256k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=write --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_256k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=write --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_256k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=write --bs=256k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1024k_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1024k_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=write --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1024k_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=write --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1024k_d8_th8 --numjobs=8 --iodepth=8 --ioengine=libaio --size=134G --rw=write --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1024k_d32_th8 --numjobs=8 --iodepth=32 --ioengine=libaio --size=134G --rw=write --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - "fio --name=fio_discovery_write_134G_1024k_d128_th8 --numjobs=8 --iodepth=128 --ioengine=libaio --size=134G --rw=write --bs=1024k --direct=1 --ramp_time=15 --runtime=180 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]" - }; - } - } -} diff --git a/src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioMultiThroughputProfileTests.cs b/src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioMultiThroughputProfileTests.cs deleted file mode 100644 index ab22ded16d..0000000000 --- a/src/VirtualClient/VirtualClient.Actions.FunctionalTests/FioMultiThroughputProfileTests.cs +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace VirtualClient.Actions -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading; - using System.Threading.Tasks; - using NUnit.Framework; - using VirtualClient.Common; - using VirtualClient.Contracts; - - [TestFixture] - [Category("Functional")] - public class FioMultiThroughputProfileTests - { - private DependencyFixture mockFixture; - - [OneTimeSetUp] - public void SetupFixture() - { - this.mockFixture = new DependencyFixture(); - ComponentTypeCache.Instance.LoadComponentTypes(TestDependencies.TestDirectory); - } - - [Test] - [TestCase("PERF-IO-FIO-MULTITHROUGHPUT.json")] - public void FioWorkloadMultiThroughputProfileParametersAreInlinedCorrectly(string profile) - { - this.mockFixture.Setup(PlatformID.Unix); - using (ProfileExecutor executor = TestDependencies.CreateProfileExecutor(profile, this.mockFixture.Dependencies)) - { - WorkloadAssert.ParameterReferencesInlined(executor.Profile); - } - } - - [Test] - [TestCase("PERF-IO-FIO-MULTITHROUGHPUT.json")] - public async Task FioWorkloadMultiThroughputProfileInstallsTheExpectedDependenciesOnUnixPlatform(string profile) - { - // The disks are setup in a typical Azure VM scenario - // (e.g. 1 OS disk, 1 temp/local disk, multiple remote disks that are unformatted). - this.mockFixture.Setup(PlatformID.Unix); - this.mockFixture.SetupDisks(withUnformatted: true); - - using (ProfileExecutor executor = TestDependencies.CreateProfileExecutor(profile, this.mockFixture.Dependencies, dependenciesOnly: true)) - { - await executor.ExecuteAsync(ProfileTiming.OneIteration(), CancellationToken.None).ConfigureAwait(false); - - // Format disk dependency expectations. - // By the time the dependencies have been installed, all disks should be formatted and ready for - // operations against the file system. - WorkloadAssert.DisksAreInitialized(this.mockFixture); - - // Apt packages expectations - // There are a few Apt packages that must be installed for the FIO workload to run. - WorkloadAssert.AptPackageInstalled(this.mockFixture, "fio"); - } - } - - [Test] - [TestCase("PERF-IO-FIO-MULTITHROUGHPUT.json")] - public async Task FioWorkloadMultiThroughputProfileExecutesTheExpectedWorkloadsOnUnixPlatform(string profile) - { - IEnumerable expectedCommands = FioMultiThroughputProfileTests.GetFioStressProfileExpectedCommands(PlatformID.Unix); - - // Setup the expectations for the workload - // - Disks are formatted and ready - // - Workload package is installed and exists. - // - Workload binaries/executables exist on the file system. - // - The workload generates valid results. - this.mockFixture.Setup(PlatformID.Unix); - this.mockFixture.SetupDisks(withUnformatted: false); - this.mockFixture.SetupPackage("fio", expectedFiles: $@"linux-x64/fio"); - string jobFilePath = this.mockFixture.PlatformSpecifics.Combine(this.mockFixture.ScriptsDirectory, "fio/oltp-c.fio.jobfile"); - this.mockFixture.SetupFile(jobFilePath, Encoding.ASCII.GetBytes(TestDependencies.GetResourceFileContents("oltp-c.fio.jobfile"))); - - this.mockFixture.ProcessManager.OnCreateProcess = (command, arguments, workingDir) => - { - IProcessProxy process = this.mockFixture.CreateProcess(command, arguments, workingDir); - if (arguments.Contains("linux-x64/fio", StringComparison.OrdinalIgnoreCase)) - { - process.StandardOutput.Append(TestDependencies.GetResourceFileContents("Results_FIO.json")); - } - - return process; - }; - - using (ProfileExecutor executor = TestDependencies.CreateProfileExecutor(profile, this.mockFixture.Dependencies)) - { - await executor.ExecuteAsync(ProfileTiming.OneIteration(), CancellationToken.None).ConfigureAwait(false); - - WorkloadAssert.CommandsExecuted(this.mockFixture, expectedCommands.ToArray()); - } - } - - private static IEnumerable GetFioStressProfileExpectedCommands(PlatformID platform) - { - return new List - { - "fio /home/user/tools/VirtualClient/scripts/fio/updated/FioMultiThroughputExecutoroltp-c.fio.jobfile --section initrandomio --section initsequentialio", - "fio /home/user/tools/VirtualClient/scripts/fio/updated/FioMultiThroughputExecutoroltp-c.fio.jobfile --section randomreader --section randomwriter --section sequentialwriter" - }; - } - } -} diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioDiscoveryExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioDiscoveryExecutorTests.cs deleted file mode 100644 index 87d59425ed..0000000000 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioDiscoveryExecutorTests.cs +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace VirtualClient.Actions -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.Extensions.DependencyInjection; - using Moq; - using NUnit.Framework; - using VirtualClient.Common; - using VirtualClient.Contracts; - - [TestFixture] - [Category("Unit")] - class FioDiscoveryExecutorTests : MockFixture - { - private DependencyPath mockPackage; - private ConcurrentBuffer defaultOutput = new ConcurrentBuffer(); - private IEnumerable disks; - private IProcessProxy defaultMemoryProcess; - - [SetUp] - public void SetupTest() - { - this.Setup(PlatformID.Unix); - this.mockPackage = new DependencyPath("fio", this.GetPackagePath("fio")); - - this.SetupPackage(this.mockPackage); - this.SetupMocks(); - - // Setup default profile parameter values - this.Parameters = new Dictionary - { - { nameof(FioDiscoveryExecutor.Scenario), "AnyScenario_ReadOrWrite_AnyBlockSize" }, - { nameof(FioDiscoveryExecutor.CommandLine), "--ioengine=libaio --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json" }, - { nameof(FioDiscoveryExecutor.BlockSize), "4K" }, - { nameof(FioDiscoveryExecutor.DiskFillSize), "140G" }, - { nameof(FioDiscoveryExecutor.FileSize), "134G" }, - { nameof(FioDiscoveryExecutor.QueueDepths), "1,4,16" }, - { nameof(FioDiscoveryExecutor.MaxThreads), 8 }, - { nameof(FioDiscoveryExecutor.IOType), "randwrite" }, - { nameof(FioDiscoveryExecutor.DirectIO), true }, - { nameof(FioDiscoveryExecutor.ProcessModel), WorkloadProcessModel.SingleProcess }, - { nameof(FioDiscoveryExecutor.DeleteTestFilesOnFinish), "true" }, - { nameof(FioDiscoveryExecutor.PackageName), "fio" }, - { nameof(FioDiscoveryExecutor.DiskFilter), "BiggestSize" } - }; - - - this.FileSystem.Setup(fe => fe.File.Exists(It.IsAny())).Returns(true); - this.defaultOutput.Clear(); - this.defaultOutput.Append(MockFixture.ReadFile(MockFixture.ExamplesDirectory, "FIO", "Results_FIO.json")); - - this.disks = this.CreateDisks(PlatformID.Unix, true); - this.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())).ReturnsAsync(this.disks); - - this.defaultMemoryProcess = new InMemoryProcess - { - StartInfo = new ProcessStartInfo - { - FileName = "exe", - Arguments = "--rw=randwrite" - }, - ExitCode = 0, - OnStart = () => true, - OnHasExited = () => true, - StandardOutput = this.defaultOutput - }; - - this.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - return new InMemoryProcess - { - StartInfo = new ProcessStartInfo - { - FileName = file, - Arguments = arguments, - WorkingDirectory = workingDirectory - }, - ExitCode = 0, - OnStart = () => true, - OnHasExited = () => true, - StandardOutput = this.defaultOutput - }; - }; - } - - [Test] - public async Task FioDiscoveryExecutorInitializeAsExpected() - { - this.Parameters.Add(nameof(FioDiscoveryExecutor.DiskFill), "True"); - this.Parameters[nameof(FioDiscoveryExecutor.CommandLine)] = $"--runtime=300 --rw=write --ioengine=libaio"; - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - this.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - if (!arguments.Contains("chmod")) - { - Assert.IsTrue(arguments.Contains($"--runtime=300 --rw=write --ioengine=libaio")); - } - return this.defaultMemoryProcess; - }; - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - } - - [Test] - public async Task FioDiscoveryExecutorRunsExpectedExecutions() - { - int executions = 0; - this.Parameters[nameof(FioDiscoveryExecutor.QueueDepths)] = "4,16,64"; // 3 executions - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - this.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - if (!arguments.Contains("chmod")) - { - executions++; - } - return this.defaultMemoryProcess; - }; - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - Assert.IsTrue(executions == 3); - } - - [Test] - public void FioDiscoveryExecutorDoesNotSupportRunningAgainstTheOperatingSystemDisk_1() - { - // Scenario: - // The disks selected includes the OS disk only (i.e. the disk filter specified pointed at the OS disk) - this.Parameters[nameof(FioDiscoveryExecutor.DiskFilter)] = "OSDisk:true"; - this.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())) - .ReturnsAsync(this.disks.Where(d => d.IsOperatingSystem())); - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - WorkloadException error = Assert.ThrowsAsync(() => executor.ExecuteAsync(CancellationToken.None)); - Assert.AreEqual(ErrorReason.NotSupported, error.Reason); - } - } - - [Test] - public void FioDiscoveryExecutorDoesNotSupportRunningAgainstTheOperatingSystemDisk_2() - { - // Scenario: - // The disks selected includes the OS disk with others (i.e. the disk filter specified pointed at the OS disk) - this.Parameters[nameof(FioDiscoveryExecutor.DiskFilter)] = "OSDisk:true"; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - WorkloadException error = Assert.ThrowsAsync(() => executor.ExecuteAsync(CancellationToken.None)); - Assert.AreEqual(ErrorReason.NotSupported, error.Reason); - } - } - - [Test] - public async Task FioDiscoveryExecutorExecutesAsExpectedInSingleProcessModel() - { - this.Parameters[nameof(FioDiscoveryExecutor.ProcessModel)] = WorkloadProcessModel.SingleProcess; - - List expectedCommandLines = new List - { - $"--name=fio_discovery_randwrite_134G_4K_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z] --filename=/dev/sd[a-z] --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z] --filename=/dev/sd[a-z] --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z] --filename=/dev/sd[a-z] --filename=/dev/sd[a-z]" - }; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - - Assert.AreEqual(4, this.ProcessManager.Commands.Count()); - Assert.IsTrue(this.ProcessManager.CommandsExecuted(expectedCommandLines.ToArray())); - } - } - - [Test] - public async Task FioDiscoveryExecutorExecutesAsExpectedInSingleProcessPerDiskModel() - { - this.Parameters[nameof(FioDiscoveryExecutor.ProcessModel)] = WorkloadProcessModel.SingleProcessPerDisk; - - List expectedCommandLines = new List - { - $"--name=fio_discovery_randwrite_134G_4K_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]", - $"--name=fio_discovery_randwrite_134G_4K_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sd[a-z]" - }; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - - Assert.AreEqual(10, this.ProcessManager.Commands.Count()); - Assert.IsTrue(this.ProcessManager.CommandsExecuted(expectedCommandLines.ToArray())); - } - } - - [Test] - public async Task FioDiscoveryExecutorUsesBufferedIOWhenInstructed() - { - this.Parameters[nameof(FioDiscoveryExecutor.DirectIO)] = false; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - - Assert.IsTrue(this.ProcessManager.CommandsExecuted("--direct=0")); - } - } - - [Test] - public async Task FioDiscoveryExecutorUsesDirectIOWhenInstructed() - { - this.Parameters[nameof(FioDiscoveryExecutor.DirectIO)] = true; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - - Assert.IsTrue(this.ProcessManager.CommandsExecuted("--direct=1")); - } - } - - [Test] - public async Task FioDiscoveryExecutorDoesNotUseDirectIOWhenInstructedOtherwise() - { - this.Parameters[nameof(FioDiscoveryExecutor.DirectIO)] = false; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - - Assert.IsTrue(this.ProcessManager.CommandsExecuted("--direct=0")); - } - } - - [Test] - [TestCase(true, 1)] - [TestCase(1, 1)] - [TestCase(false, 0)] - [TestCase(0, 0)] - public async Task FioDiscoveryExecutorHandlesBothBooleanAndIntegerValuesForDirectIOParameters(IConvertible parameterValue, int expectedCommandLineValue) - { - this.Parameters[nameof(FioDiscoveryExecutor.DirectIO)] = parameterValue; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - - Assert.IsTrue(this.ProcessManager.CommandsExecuted($"--direct={expectedCommandLineValue}")); - } - } - - [Test] - public async Task FioDiscoveryExecutorExecutesAsExpectedIfGroupIDIsRemoved() - { - this.Parameters[nameof(FioDiscoveryExecutor.ProcessModel)] = WorkloadProcessModel.SingleProcess; - - List expectedCommandLines = new List - { - $"sudo chmod", - $"--name=fio_discovery_randwrite_134G_4K_d1_th1 --numjobs=1 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sdc --filename=/dev/sdd --filename=/dev/sde", - $"--name=fio_discovery_randwrite_134G_4K_d1_th4 --numjobs=4 --iodepth=1 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sdc --filename=/dev/sdd --filename=/dev/sde", - $"--name=fio_discovery_randwrite_134G_4K_d2_th8 --numjobs=8 --iodepth=2 --ioengine=libaio --size=134G --rw=randwrite --bs=4K --direct=1 --ramp_time=30 --runtime=300 --time_based --overwrite=1 --thread --group_reporting --output-format=json --filename=/dev/sdc --filename=/dev/sdd --filename=/dev/sde" - }; - - using (TestFioDiscoveryExecutor executor = new TestFioDiscoveryExecutor(this.Dependencies, this.Parameters)) - { - executor.Metadata.Remove("GroupId".CamelCased()); - await executor.ExecuteAsync(CancellationToken.None); - - Assert.AreEqual(4, this.ProcessManager.Commands.Count()); - Assert.IsTrue(this.ProcessManager.CommandsExecuted(expectedCommandLines.ToArray())); - } - } - - private class TestFioDiscoveryExecutor : FioDiscoveryExecutor - { - public TestFioDiscoveryExecutor(IServiceCollection dependencies, IDictionary parameters) - : base(dependencies, parameters) - { - - } - /// - /// Retry Wait Time for FIO executors. - /// - protected static new TimeSpan RetryWaitTime { get; } = TimeSpan.FromSeconds(0); - - } - } -} - diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioExecutorTests.cs index 09c64fdea1..75de4bf259 100644 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioExecutorTests.cs +++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioExecutorTests.cs @@ -160,94 +160,6 @@ public void FioExecutorAppliesConfigurationParametersCorrectly() } } - [Test] - public void FioExecutorThrowsOnNullCommandLineAndJobFiles() - { - this.profileParameters[nameof(TestFioExecutor.CommandLine)] = null; - this.profileParameters[nameof(TestFioExecutor.JobFiles)] = null; - - using (TestFioExecutor executor = new TestFioExecutor(this.Dependencies, this.profileParameters)) - { - WorkloadException error = Assert.Throws(executor.Validate); - - Assert.AreEqual(ErrorReason.InvalidProfileDefinition, error.Reason); - } - } - - [Test] - public void FioExecutorThrowsIfCommandLineAndJobFilesIncluded() - { - this.profileParameters[nameof(TestFioExecutor.CommandLine)] = "--name=fio_randwrite_{FileSize}_4k_d{QueueDepth}_th{ThreadCount}_direct --size=496GB --numjobs={ThreadCount} --rw=randwrite --bs=4k --iodepth={QueueDepth}"; - this.profileParameters[nameof(TestFioExecutor.JobFiles)] = "{ScriptPath:fio}/oltp-c.fio.jobfile"; - - using (TestFioExecutor executor = new TestFioExecutor(this.Dependencies, this.profileParameters)) - { - WorkloadException error = Assert.Throws(executor.Validate); - - Assert.AreEqual(ErrorReason.InvalidProfileDefinition, error.Reason); - } - } - - [Test] - public void FioExecutorRunsCommandWithJobFile_SingleProcess() - { - this.profileParameters[nameof(TestFioExecutor.CommandLine)] = null; - this.profileParameters[nameof(TestFioExecutor.JobFiles)] = "jobfile1path"; - - DependencyPath workloadPlatformSpecificPackage = - this.ToPlatformSpecificPath(this.mockPackage, this.Platform, this.CpuArchitecture); - - string updatedJobFilePath = this.PlatformSpecifics.Combine(workloadPlatformSpecificPackage.Path, "jobfile1path"); - - using (TestFioExecutor fioExecutor = new TestFioExecutor(this.Dependencies, this.profileParameters)) - { - string expectedCommand = "/home/any/fio"; - string expectedArguments = $"{updatedJobFilePath} --output-format=json"; - string expectedTestedInstance = "SingleProcess,BiggestSize,4"; - - Disk diskToTest = this.disks.Where(disk => !disk.IsOperatingSystem()).First(); - DiskWorkloadProcess workloadProcess = fioExecutor.CreateWorkloadProcesses(expectedCommand, expectedArguments, this.disks, WorkloadProcessModel.SingleProcess, EventContext.None) - .First(); - - Assert.IsNotNull(workloadProcess); - Assert.IsNotNull(workloadProcess.Process); - Assert.IsTrue($"{workloadProcess.Command} {workloadProcess.CommandArguments}".StartsWith($"sudo {expectedCommand} {expectedArguments}")); - Assert.AreEqual(expectedTestedInstance, workloadProcess.Categorization); - Assert.AreEqual(4, workloadProcess.TestFiles.Count()); - } - } - - [Test] - public void FioExecutorRunsCommandWithMultipleJobFiles() - { - this.profileParameters[nameof(TestFioExecutor.CommandLine)] = null; - this.profileParameters[nameof(TestFioExecutor.JobFiles)] = "path/to/jobfile1,path/jobfile2;path/jobfile3"; - - DependencyPath workloadPlatformSpecificPackage = - this.ToPlatformSpecificPath(this.mockPackage, this.Platform, this.CpuArchitecture); - - string updatedJobFile1Path = this.PlatformSpecifics.Combine(workloadPlatformSpecificPackage.Path, "jobfile1"); - string updatedJobFile2Path = this.PlatformSpecifics.Combine(workloadPlatformSpecificPackage.Path, "jobfile2"); - string updatedJobFile3Path = this.PlatformSpecifics.Combine(workloadPlatformSpecificPackage.Path, "jobfile3"); - - using (TestFioExecutor fioExecutor = new TestFioExecutor(this.Dependencies, this.profileParameters)) - { - string expectedCommand = "/home/any/fio"; - string expectedArguments = $"{updatedJobFile1Path} {updatedJobFile2Path} {updatedJobFile3Path} --output-format=json"; - string expectedTestedInstance = "SingleProcess,BiggestSize,4"; - - Disk diskToTest = this.disks.Where(disk => !disk.IsOperatingSystem()).First(); - DiskWorkloadProcess workloadProcess = fioExecutor.CreateWorkloadProcesses(expectedCommand, expectedArguments, this.disks, WorkloadProcessModel.SingleProcess, EventContext.None) - .First(); - - Assert.IsNotNull(workloadProcess); - Assert.IsNotNull(workloadProcess.Process); - Assert.IsTrue($"{workloadProcess.Command} {workloadProcess.CommandArguments}".StartsWith($"sudo {expectedCommand} {expectedArguments}")); - Assert.AreEqual(expectedTestedInstance, workloadProcess.Categorization); - Assert.AreEqual(4, workloadProcess.TestFiles.Count()); - } - } - [Test] public void FioExecutorAppliesConfigurationParametersCorrectly_DiskFillScenario() { diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioMultiThroughputExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioMultiThroughputExecutorTests.cs deleted file mode 100644 index 4797ae7fa9..0000000000 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/FIO/FioMultiThroughputExecutorTests.cs +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace VirtualClient.Actions -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.IO; - using System.Linq; - using System.Text.RegularExpressions; - using System.Threading; - using System.Threading.Tasks; - using AutoFixture; - using Microsoft.Extensions.DependencyInjection; - using Moq; - using NUnit.Framework; - using VirtualClient.Common; - using VirtualClient.Contracts; - - [TestFixture] - [Category("Unit")] - class FioMultiThroughputExecutorTests - { - private static readonly string ExamplesDirectory = MockFixture.GetDirectory(typeof(NTttcpExecutorTests2), "Examples", "FIO"); - - private MockFixture mockFixture; - private DependencyPath mockPackage; - - private ConcurrentBuffer defaultOutput = new ConcurrentBuffer(); - private IEnumerable disks; - private IProcessProxy defaultMemoryProcess; - - [SetUp] - public void SetupTest() - { - this.mockFixture = new MockFixture(); - this.mockFixture.Setup(PlatformID.Unix); - this.mockPackage = this.mockFixture.Create(); - this.mockFixture.SetupMocks(); - - this.mockFixture.Parameters = new Dictionary - { - { nameof(FioMultiThroughputExecutor.TemplateJobFile), "oltp-c.fio.jobfile" }, - { nameof(FioMultiThroughputExecutor.GroupReporting), 1 }, - { nameof(FioMultiThroughputExecutor.Duration), 1 }, - { nameof(FioMultiThroughputExecutor.DirectIO), 1 }, - { nameof(FioMultiThroughputExecutor.TargetIOPS), "5000" }, - { nameof(FioMultiThroughputExecutor.TargetPercents), 10 }, - { nameof(FioMultiThroughputExecutor.RandomIOFileSize), "124G" }, - { nameof(FioMultiThroughputExecutor.RandomReadBlockSize), "8K" }, - { nameof(FioMultiThroughputExecutor.RandomReadQueueDepth), 512 }, - { nameof(FioMultiThroughputExecutor.RandomReadNumJobs), 1 }, - { nameof(FioMultiThroughputExecutor.RandomReadWeight), 5416 }, - { nameof(FioMultiThroughputExecutor.RandomWriteBlockSize), "8K" }, - { nameof(FioMultiThroughputExecutor.RandomWriteQueueDepth), 512 }, - { nameof(FioMultiThroughputExecutor.RandomWriteNumJobs), 1 }, - { nameof(FioMultiThroughputExecutor.RandomWriteWeight), 4255 }, - { nameof(FioMultiThroughputExecutor.SequentialIOFileSize), "20G" }, - { nameof(FioMultiThroughputExecutor.SequentialReadBlockSize), "56K" }, - { nameof(FioMultiThroughputExecutor.SequentialReadQueueDepth), 64 }, - { nameof(FioMultiThroughputExecutor.SequentialReadNumJobs), 1 }, - { nameof(FioMultiThroughputExecutor.SequentialReadWeight), 0 }, - { nameof(FioMultiThroughputExecutor.SequentialWriteBlockSize), "56K" }, - { nameof(FioMultiThroughputExecutor.SequentialWriteQueueDepth), 64 }, - { nameof(FioMultiThroughputExecutor.SequentialWriteNumJobs), 1 }, - { nameof(FioMultiThroughputExecutor.SequentialWriteWeight), 329 }, - { nameof(FioMultiThroughputExecutor.PackageName), "fio" } - }; - - this.mockFixture.PackageManager.OnGetPackage().ReturnsAsync(this.mockPackage); - this.mockFixture.Directory.Setup(d => d.Exists(It.IsAny())).Returns(true); - this.mockFixture.File.Setup(f => f.Exists(It.IsAny())).Returns(true); - - string rawtext = File.ReadAllText(Path.Combine(FioMultiThroughputExecutorTests.ExamplesDirectory, "Results_FIO.json")); - string templateJobFile = File.ReadAllText(Path.Combine(FioMultiThroughputExecutorTests.ExamplesDirectory, "oltp-c.fio.jobfile")); - this.mockFixture.FileSystem.Setup(rt => rt.File.ReadAllText(It.IsAny())).Returns(templateJobFile); - - this.defaultOutput.Clear(); - this.defaultOutput.Append(rawtext); - - this.disks = this.mockFixture.CreateDisks(PlatformID.Unix, true); - this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())).ReturnsAsync(this.disks); - - this.defaultMemoryProcess = new InMemoryProcess - { - StartInfo = new ProcessStartInfo - { - FileName = "exe", - Arguments = "args" - }, - ExitCode = 0, - OnStart = () => true, - OnHasExited = () => true, - StandardOutput = this.defaultOutput - }; - } - - [Test] - public async Task FioMultiThroughputExecutorInitializeAsExpected() - { - this.mockFixture.Parameters.Add(nameof(FioMultiThroughputExecutor.DiskFill), "True"); - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - if (!arguments.Contains("chmod")) - { - Assert.IsTrue(arguments.Equals($"{this.mockPackage.Path}/linux-x64/fio {this.mockFixture.PlatformSpecifics.GetScriptPath("fio")}/updated/" + - $"{nameof(FioMultiThroughputExecutor)}" + - $"{executor.Parameters[nameof(FioMultiThroughputExecutor.TemplateJobFile)]} " + - $"--section initrandomio --section initsequentialio " + - $"--time_based --output-format=json --thread --fallocate=none")); - } - return this.defaultMemoryProcess; - }; - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - } - - [Test] - public async Task FioMultiThroughputExecutorRunsExpectedExecutions() - { - int executions = 0; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.TargetPercents)] = "10,20,30,50,70,100,110"; - - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - if (!arguments.Contains("chmod")) - { - executions++; - } - return this.defaultMemoryProcess; - }; - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - - Assert.IsTrue(executions == 7); - } - - [Test] - public void FioMultiThroughputExecutorDoesNotSupportRunningAgainstTheOperatingSystemDisk_1() - { - // Scenario: - // The disks selected includes the OS disk only (i.e. the disk filter specified pointed at the OS disk) - this.mockFixture.Parameters[nameof(FioDiscoveryExecutor.DiskFilter)] = "OSDisk:true"; - this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())) - .ReturnsAsync(this.disks.Where(d => d.IsOperatingSystem())); - - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - WorkloadException error = Assert.ThrowsAsync(() => executor.ExecuteAsync(CancellationToken.None)); - Assert.AreEqual(ErrorReason.NotSupported, error.Reason); - } - } - - [Test] - public void FioMultiThroughputExecutorDoesNotSupportRunningAgainstTheOperatingSystemDisk_2() - { - // Scenario: - // The disks selected includes the OS disk with others (i.e. the disk filter specified pointed at the OS disk) - this.mockFixture.Parameters[nameof(FioDiscoveryExecutor.DiskFilter)] = "OSDisk:true"; - - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - WorkloadException error = Assert.ThrowsAsync(() => executor.ExecuteAsync(CancellationToken.None)); - Assert.AreEqual(ErrorReason.NotSupported, error.Reason); - } - } - - [Test] - public async Task FioMultiThroughputExecutorExecutesExpectedCommandLine() - { - int executions = 0; - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - if (!arguments.Contains("chmod")) - { - executions++; - Assert.IsTrue(arguments.Equals($"{this.mockPackage.Path}/linux-x64/fio {this.mockFixture.PlatformSpecifics.GetScriptPath("fio")}/updated/" + - $"{nameof(FioMultiThroughputExecutor)}" + - $"{executor.Parameters[nameof(FioMultiThroughputExecutor.TemplateJobFile)]}" + - $" --section randomreader --section randomwriter --section sequentialwriter --time_based --output-format=json --thread --fallocate=none")); - } - return this.defaultMemoryProcess; - }; - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - Assert.IsTrue(executions == 1); - - } - - [Test] - public async Task FioMultiThroughputExecutorCreatesExpectedJobFileForMultipleDisks() - { - bool createdExpectedJobFile = false; - - this.disks = new List - { - this.mockFixture.CreateDisk(0, PlatformID.Unix, os: true, "/dev/sda", "/dev/sda1"), - this.mockFixture.CreateDisk(1, PlatformID.Unix, os: false, "/dev/sdc", "/dev/sdc1"), - this.mockFixture.CreateDisk(2, PlatformID.Unix, os: false, "/dev/sdd", "/dev/sdd1"), - this.mockFixture.CreateDisk(3, PlatformID.Unix, os: false, "/dev/sde", "/dev/sde1"), - this.mockFixture.CreateDisk(4, PlatformID.Unix, os: false, "/dev/sdf", "/dev/sdf1"), - this.mockFixture.CreateDisk(5, PlatformID.Unix, os: false, "/dev/sdg", "/dev/sdg1"), - this.mockFixture.CreateDisk(6, PlatformID.Unix, os: false, "/dev/sdh", "/dev/sdh1") - }; - - this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())).ReturnsAsync(this.disks); - string expectedJobFile = File.ReadAllText(Path.Combine(FioMultiThroughputExecutorTests.ExamplesDirectory, "expectedoltp-c.fio1.jobfile")); - - using (TestFioMultiThroughputExecutor fioMultiThroughputExecutor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => this.defaultMemoryProcess; - this.mockFixture.FileSystem.Setup(fe => fe.File.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((string path, string contents) => - { - createdExpectedJobFile = true; - }); - - await fioMultiThroughputExecutor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - - Assert.IsTrue(createdExpectedJobFile); - } - - [Test] - public async Task FioMultiThroughputExecutorCreatesExpectedJobFileForMultipleDisksAnd2SequentialDisks() - { - bool createdExpectedJobFile = false; - - this.disks = new List - { - this.mockFixture.CreateDisk(0, PlatformID.Unix, os: true, "/dev/sda", "/dev/sda1"), - this.mockFixture.CreateDisk(1, PlatformID.Unix, os: false, "/dev/sdc", "/dev/sdc1"), - this.mockFixture.CreateDisk(2, PlatformID.Unix, os: false, "/dev/sdd", "/dev/sdd1"), - this.mockFixture.CreateDisk(3, PlatformID.Unix, os: false, "/dev/sde", "/dev/sde1"), - this.mockFixture.CreateDisk(4, PlatformID.Unix, os: false, "/dev/sdf", "/dev/sdf1"), - this.mockFixture.CreateDisk(5, PlatformID.Unix, os: false, "/dev/sdg", "/dev/sdg1"), - this.mockFixture.CreateDisk(6, PlatformID.Unix, os: false, "/dev/sdh", "/dev/sdh1") - }; - - this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())).ReturnsAsync(this.disks); - this.mockFixture.Parameters.Add(nameof(FioMultiThroughputExecutor.SequentialDiskCount), "2"); - string expectedJobFile = File.ReadAllText(Path.Combine(FioMultiThroughputExecutorTests.ExamplesDirectory, "expectedoltp-c.fio2.jobfile")); - - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => this.defaultMemoryProcess; - this.mockFixture.FileSystem.Setup(fe => fe.File.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((string path, string contents) => - { - createdExpectedJobFile = true; - }); - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - - Assert.IsTrue(createdExpectedJobFile); - } - - [Test] - public async Task FioMultiThroughputExecutorCreatesExpectedJobFileForSingleDisk() - { - bool createdExpectedJobFile = false; - - this.disks = new List - { - this.mockFixture.CreateDisk(0, PlatformID.Unix, os: true, "/dev/sda", "/dev/sda1"), - this.mockFixture.CreateDisk(1, PlatformID.Unix, os: false, "/dev/sdc", "/dev/sdc1") - }; - - this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())).ReturnsAsync(this.disks); - string expectedJobFile = File.ReadAllText(Path.Combine(FioMultiThroughputExecutorTests.ExamplesDirectory, "expectedoltp-c.fio3.jobfile")); - - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => this.defaultMemoryProcess; - this.mockFixture.FileSystem.Setup(fe => fe.File.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((string path, string contents) => - { - createdExpectedJobFile = true; - }); - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - - Assert.IsTrue(createdExpectedJobFile); - } - - [Test] - public async Task FioMultiThroughputExecutorCreatesExpectedJobFile_Anomalous_Scenario_1() - { - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.RandomReadNumJobs)] = 8; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.RandomReadQueueDepth)] = 2048; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.RandomWriteNumJobs)] = 8; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.RandomWriteQueueDepth)] = 2048; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.SequentialWriteNumJobs)] = 2; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.SequentialWriteQueueDepth)] = 128; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.TargetIOPS)] = 400000; - this.mockFixture.Parameters[nameof(FioMultiThroughputExecutor.TargetPercents)] = "10,40,80,90,98,100,102,110"; - - this.disks = new List - { - this.mockFixture.CreateDisk(0, PlatformID.Unix, os: true, "/dev/sda", "/dev/sda1"), - this.mockFixture.CreateDisk(1, PlatformID.Unix, os: false, "/dev/sdc", "/dev/sdc1") - }; - - this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny())) - .ReturnsAsync(this.disks); - - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - List iopsValues = new List(); - - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => this.defaultMemoryProcess; - this.mockFixture.FileSystem.Setup(fe => fe.File.WriteAllText(It.IsAny(), It.IsAny())) - .Callback((string path, string contents) => - { - MatchCollection rateIops = Regex.Matches(contents, "rate_iops=(-*[0-9]+)"); - foreach (System.Text.RegularExpressions.Match match in rateIops) - { - // Bug: - // We found a scenario where the use of Int32/int data types cause the mathematical - // calculations for some of the target IOPS to be negative numbers. - iopsValues.Add(int.Parse(match.Groups[1].Value)); - } - }); - - await executor.ExecuteAsync(CancellationToken.None); - - Assert.IsNotEmpty(iopsValues); - Assert.IsTrue(iopsValues.All(rate => rate >= 0)); - } - } - - [Test] - public async Task FioMultiThroughputSucceedsIfGroupIDIsRemoved() - { - int executions = 0; - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - executor.Metadata.Remove("GroupId".CamelCased()); - - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - if (!arguments.Contains("chmod")) - { - executions++; - Assert.IsTrue(arguments.Equals($"{this.mockPackage.Path}/linux-x64/fio {this.mockFixture.PlatformSpecifics.GetScriptPath("fio")}/updated/" + - $"{nameof(FioMultiThroughputExecutor)}" + - $"{executor.Parameters[nameof(FioMultiThroughputExecutor.TemplateJobFile)]}" + - $" --section randomreader --section randomwriter --section sequentialwriter --time_based --output-format=json --thread --fallocate=none")); - } - return this.defaultMemoryProcess; - }; - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - Assert.IsTrue(executions == 1); - } - - [Test] - public async Task FioMultiThroughputSucceedsIfGroupIDHasBadCasing() - { - int executions = 0; - using (TestFioMultiThroughputExecutor executor = new TestFioMultiThroughputExecutor(this.mockFixture.Dependencies, this.mockFixture.Parameters)) - { - executor.Metadata.Remove("GroupId"); - executor.Metadata.Add("grouPId", string.Empty); - - this.mockFixture.ProcessManager.OnCreateProcess = (file, arguments, workingDirectory) => - { - if (!arguments.Contains("chmod")) - { - executions++; - Assert.IsTrue(arguments.Equals($"{this.mockPackage.Path}/linux-x64/fio {this.mockFixture.PlatformSpecifics.GetScriptPath("fio")}/updated/" + - $"{nameof(FioMultiThroughputExecutor)}" + - $"{executor.Parameters[nameof(FioMultiThroughputExecutor.TemplateJobFile)]}" + - $" --section randomreader --section randomwriter --section sequentialwriter --time_based --output-format=json --thread --fallocate=none")); - } - return this.defaultMemoryProcess; - }; - - await executor.ExecuteAsync(CancellationToken.None) - .ConfigureAwait(false); - } - Assert.IsTrue(executions == 1); - } - - private class TestFioMultiThroughputExecutor : FioMultiThroughputExecutor - { - public TestFioMultiThroughputExecutor(IServiceCollection dependencies, IDictionary parameters) - : base(dependencies, parameters) - { - - } - /// - /// Retry Wait Time for FIO executors. - /// - protected static new TimeSpan RetryWaitTime { get; } = TimeSpan.FromSeconds(0); - - } - } -} \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/FioDiscoveryExecutor.cs b/src/VirtualClient/VirtualClient.Actions/FIO/FioDiscoveryExecutor.cs deleted file mode 100644 index 023efb1d07..0000000000 --- a/src/VirtualClient/VirtualClient.Actions/FIO/FioDiscoveryExecutor.cs +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace VirtualClient.Actions -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.Extensions.DependencyInjection; - using Polly; - using VirtualClient.Common; - using VirtualClient.Common.Extensions; - using VirtualClient.Common.Telemetry; - using VirtualClient.Contracts; - - /// - /// Manages the execution runtime of the FIO workload for Perf Engineering Discovery Scenario. - /// - [SupportedPlatforms("linux-arm64,linux-x64")] - public class FioDiscoveryExecutor : FioExecutor - { - private static int variationNumber = 0; - private static IAsyncPolicy fioDiscoveryRetryPolicy = Policy.Handle().WaitAndRetryAsync(3, _ => RetryWaitTime); - - /// - /// Initializes a new instance of the class. - /// - /// Provides required dependencies to the workload. - /// The set of parameters defined for the action in the profile definition. - public FioDiscoveryExecutor(IServiceCollection dependencies, IDictionary parameters) - : base(dependencies, parameters) - { - // Since in this case we are testing on raw disks, we are not cleaning up test files - this.DeleteTestFilesOnFinish = false; - - // Convert to desired data types. - this.DirectIO = parameters.GetValue(nameof(this.DirectIO), true) ? 1 : 0; - } - - /// - /// The Blocksizes list for discovery parameters. - /// - public string BlockSize - { - get - { - return this.Parameters.GetValue(nameof(this.BlockSize)); - } - } - - /// - /// Parameter. True to used direct, non-buffered I/O (default). False to use buffered I/O. - /// - public int DirectIO - { - get - { - return this.Parameters.GetValue(nameof(this.DirectIO), 1); - } - - private set - { - this.Parameters[nameof(this.DirectIO)] = value; - } - } - - /// - /// The IO type whether it is randomRead,randomWrite, read (sequential read), write (sequential write). - /// - public string IOType - { - get - { - return this.Parameters.GetValue(nameof(this.IOType)); - } - } - - /// - /// The maximum number of threads. - /// - public int MaxThreads - { - get - { - return this.Parameters.GetValue(nameof(this.MaxThreads)); - } - } - - /// - /// The Queue depths for discovery parameters. - /// - public List QueueDepths - { - get - { - return this.Parameters.GetValue(nameof(this.QueueDepths)).Split(VirtualClientComponent.CommonDelimiters).Select(int.Parse).ToList(); - } - } - - /// - /// Group Id. - /// - public string GroupId - { - get - { - IConvertible value = string.Empty; - if (this.Metadata != null) - { - (this.Metadata as Dictionary).TryGetValue(nameof(this.GroupId), out value); - } - - return value == null ? string.Empty : value.ToString(); - } - } - - /// - /// Retry Wait Time for FIO executors. - /// - protected static TimeSpan RetryWaitTime { get; } = TimeSpan.FromSeconds(30); - - /// - /// Executes the FIO workload, captures performance results and logs them to telemetry. - /// - /// Provides context information that will be captured with telemetry events. - /// A token that can be used to cancel the operation. - protected override async Task ExecuteAsync(EventContext telemetryContext, CancellationToken cancellationToken) - { - IEnumerable disks = await this.SystemManagement.DiskManager.GetDisksAsync(cancellationToken); - - if (disks?.Any() != true) - { - throw new WorkloadException( - "Unexpected scenario. The disks defined for the system could not be properly enumerated.", - ErrorReason.WorkloadUnexpectedAnomaly); - } - - IEnumerable disksToTest = this.GetDisksToTest(disks); - - if (disksToTest?.Any() != true) - { - throw new WorkloadException( - "Expected disks to test not found. Given the parameters defined for the profile action/step or those passed " + - "in on the command line, the requisite disks do not exist on the system or could not be identified based on the properties " + - "of the existing disks. Verify or specify the disk filter.", - ErrorReason.DependencyNotFound); - } - - if (disksToTest?.Any(disk => disk.IsOperatingSystem()) == true) - { - throw new WorkloadException( - "Expected disks to test contain the disk on which the operation system is installed. This scenario runs I/O operations against the raw disk without any file " + - "system layers and can overwrite important information on the disk such as disk volume partitions. As such I/O operations against the operating system disk " + - "are not supported.", - ErrorReason.NotSupported); - } - - disksToTest.ToList().ForEach(disk => this.Logger.LogTraceMessage($"Disk Target: '{disk}'")); - - telemetryContext.AddContext("executable", this.ExecutablePath); - telemetryContext.AddContext(nameof(disks), disks); - telemetryContext.AddContext(nameof(disksToTest), disksToTest); - - this.WorkloadProcesses.Clear(); - List fioProcessTasks = new List(); - - if (this.DiskFill) - { - Interlocked.Exchange(ref variationNumber, 0); - - if (await this.IsDiskFillCompleteAsync(cancellationToken) == false) - { - string commandLine = this.ApplyParameter(this.CommandLine, nameof(this.Scenario), this.Scenario); - commandLine = this.ApplyParameter(commandLine, nameof(this.DiskFillSize), this.DiskFillSize); - - this.Logger.LogTraceMessage($"{this.Scenario}.ExecutionStarted", telemetryContext); - this.WorkloadProcesses.AddRange(this.CreateWorkloadProcesses(this.ExecutablePath, commandLine, disksToTest, this.ProcessModel, telemetryContext)); - - foreach (DiskWorkloadProcess process in this.WorkloadProcesses) - { - fioProcessTasks.Add(this.ExecuteWorkloadAsync(process, this.Scenario, telemetryContext, cancellationToken)); - } - - if (!cancellationToken.IsCancellationRequested) - { - await Task.WhenAll(fioProcessTasks); - } - - this.Logger.LogTraceMessage($"{this.Scenario}.ExecutionEnded", telemetryContext); - - await this.RegisterDiskFillCompleteAsync(cancellationToken); - } - } - else - { - List exceptions = new List(); - foreach (int queueDepth in this.QueueDepths) - { - int variation = Interlocked.Increment(ref variationNumber); - if (!cancellationToken.IsCancellationRequested) - { - int numJobs = (queueDepth < this.MaxThreads) ? queueDepth : this.MaxThreads; - int queueDepthPerThread = (queueDepth + numJobs - 1) / numJobs; - - // e.g. fio_discovery_randread_134G_4K_d8_th8 - string testName = $"fio_discovery_{this.IOType.ToLowerInvariant()}_{this.FileSize}_{this.BlockSize}_d{queueDepthPerThread}_th{numJobs}"; - - EventContext variationContext = telemetryContext.Clone().AddContext(nameof(testName), testName); - - try - { - await this.Logger.LogMessageAsync($"{this.TypeName}.ExecuteVariation", variationContext, async () => - { - // Converting Byte to Gigabytes - double fileSizeGiB = Convert.ToDouble(TextParsingExtensions.TranslateStorageByUnit(this.FileSize, MetricUnit.Gigabytes)); - - // Converting Bytes to Kilobytes - double blockSizeKiB = Convert.ToDouble(TextParsingExtensions.TranslateStorageByUnit(this.BlockSize, MetricUnit.Kilobytes)); - - string commandLine = this.ApplyParameter(this.CommandLine, nameof(this.FileSize), this.FileSize); - - commandLine = this.ApplyParameter(commandLine, nameof(this.IOType), this.IOType); - commandLine = this.ApplyParameter(commandLine, nameof(this.BlockSize), this.BlockSize); - // commandLine = this.ApplyParameter(commandLine, nameof(this.Duration), this.Duration); - - int direct = this.DirectIO; - commandLine = this.ApplyParameter(commandLine, nameof(this.DirectIO), direct); - commandLine = $"--name={testName} --numjobs={numJobs} --iodepth={queueDepthPerThread} {commandLine}"; - - string filePath = string.Join(',', disksToTest.Select(disk => disk.DevicePath).ToArray()); - - Dictionary metricsMetadata = new Dictionary - { - [nameof(this.GroupId).CamelCased()] = this.GroupId, - // [nameof(this.Duration).CamelCased()] = this.Duration, - [nameof(this.ProfileIteration).CamelCased()] = this.ProfileIteration, - [nameof(this.ProfileIterationStartTime).CamelCased()] = this.ProfileIterationStartTime, - [nameof(this.IOType).CamelCased()] = this.IOType, - [nameof(this.MaxThreads).CamelCased()] = this.MaxThreads, - [nameof(blockSizeKiB).CamelCased()] = blockSizeKiB, - [nameof(queueDepth).CamelCased()] = queueDepth, - [nameof(testName).CamelCased()] = testName, - [nameof(commandLine).CamelCased()] = commandLine, - [nameof(variation).CamelCased()] = variation, - [nameof(numJobs).CamelCased()] = numJobs, - [nameof(fileSizeGiB).CamelCased()] = fileSizeGiB, - [nameof(filePath).CamelCased()] = filePath - }; - - await fioDiscoveryRetryPolicy.ExecuteAsync(async () => - { - using (BackgroundOperations profiling = BackgroundOperations.BeginProfiling(this, cancellationToken)) - { - this.WorkloadProcesses.Clear(); - this.WorkloadProcesses.AddRange(this.CreateWorkloadProcesses(this.ExecutablePath, commandLine, disksToTest, this.ProcessModel, telemetryContext)); - - foreach (DiskWorkloadProcess process in this.WorkloadProcesses) - { - fioProcessTasks.Add(this.ExecuteWorkloadAsync(process, testName, variationContext, cancellationToken, metricsMetadata)); - } - - if (!cancellationToken.IsCancellationRequested) - { - await Task.WhenAll(fioProcessTasks); - } - } - }); - - }); - - await this.CleanUpWorkloadTestFilesAsync(); - } - catch (VirtualClientException exc) - { - exceptions.Add(exc); - } - finally - { - await this.CleanUpWorkloadTestFilesAsync(); - } - } - } - - if (exceptions.Any()) - { - AggregateException aggregateException = new AggregateException(exceptions); - - WorkloadException workloadException = new WorkloadException( - $"{nameof(FioDiscoveryExecutor)} failed with following exceptions", - aggregateException, - exceptions.Max(ex => ex.Reason)); - - throw workloadException; - } - } - } - - /// - /// Returns the target device/file test path. Note that this may be either a file - /// or a direct path to the physical device (e.g. /dev/sda, /mnt_dev_sda1/fio-test.dat). - /// - protected override string GetTestDevicePath(Disk disk) - { - return disk.DevicePath; - } - - /// - protected override void Validate() - { - // Parameters themselves throw on being null. - } - - private async Task CleanUpWorkloadTestFilesAsync() - { - foreach (DiskWorkloadProcess workload in this.WorkloadProcesses) - { - await this.DeleteTestVerificationFilesAsync(workload.TestFiles); - - if (this.DeleteTestFilesOnFinish) - { - await this.DeleteTestFilesAsync(workload.TestFiles); - } - } - } - } -} \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs b/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs index f3988ec7ee..f9e78b23eb 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs @@ -73,18 +73,6 @@ public TimeSpan CoolDownPeriod } } - /// - /// Defines the job files specified in the profile. - /// - public string JobFiles - { - get - { - return this.Parameters.ContainsKey(nameof(this.JobFiles)) ? - this.Parameters.GetValue(nameof(this.JobFiles)) : null; - } - } - /// /// True/false whether the test files that FIO uses in benchmark tests should be deleted at the end /// of each individual round of test execution. @@ -320,11 +308,6 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel return; } - if (!string.IsNullOrEmpty(this.JobFiles)) - { - this.CommandLine = this.GetCommandForJobFilesAsync(cancellationToken); - } - // Apply parameters to the FIO command line options. await this.EvaluateParametersAsync(telemetryContext); @@ -863,18 +846,11 @@ protected Task RegisterDiskFillCompleteAsync(CancellationToken cancellationToken /// protected override void Validate() { - if (string.IsNullOrWhiteSpace(this.CommandLine) && string.IsNullOrWhiteSpace(this.JobFiles)) + if (string.IsNullOrWhiteSpace(this.CommandLine)) { throw new WorkloadException( $"Unexpected profile definition. One or more of the actions in the profile does not contain the " + - $"required '{nameof(FioExecutor.CommandLine)}' or '{nameof(FioExecutor.JobFiles)}' arguments defined.", - ErrorReason.InvalidProfileDefinition); - } - - if (!string.IsNullOrWhiteSpace(this.CommandLine) && !string.IsNullOrWhiteSpace(this.JobFiles)) - { - throw new WorkloadException( - "Unexpected profile definition. Only one of JobFiles or CommandLine can be defined.", + $"required '{nameof(FioExecutor.CommandLine)}' argument defined.", ErrorReason.InvalidProfileDefinition); } @@ -886,7 +862,7 @@ protected override void Validate() ErrorReason.InvalidProfileDefinition); } - if (this.DiskFill && string.IsNullOrWhiteSpace(this.JobFiles) && string.IsNullOrWhiteSpace(this.DiskFillSize)) + if (this.DiskFill && string.IsNullOrWhiteSpace(this.DiskFillSize)) { throw new WorkloadException( $"Unexpected profile definition. One or more of the actions in the profile does not contain the " + @@ -1022,22 +998,6 @@ private IEnumerable CreateSingleProcessPerDiskWorkloadProce return processes; } - private void CreateOrUpdateJobFile(string sourcePath, string destinationPath) - { - string text = this.SystemManagement.FileSystem.File.ReadAllText(sourcePath); - - foreach (string key in this.Parameters.Keys) - { - string value = this.Parameters.GetValue(key); - if (!string.IsNullOrEmpty(value)) - { - text = Regex.Replace(text, @$"\${{{key.ToLower()}}}", value); - } - } - - this.SystemManagement.FileSystem.File.WriteAllText(@destinationPath, text); - } - private string FilterWarnings(string fioOutput) { string modifiedOutput = Regex.Replace(fioOutput, @"^fio:.*$", string.Empty, RegexOptions.Multiline).Trim(); @@ -1045,34 +1005,6 @@ private string FilterWarnings(string fioOutput) return modifiedOutput; } - private string GetCommandForJobFilesAsync(CancellationToken cancellationToken) - { - string jobFileFolder = this.PlatformSpecifics.GetScriptPath("fio"); - string updatedJobFileFolder = Path.Combine(jobFileFolder, "updated"); - - if (!this.SystemManagement.FileSystem.Directory.Exists(updatedJobFileFolder)) - { - this.SystemManagement.FileSystem.Directory.CreateDirectory(updatedJobFileFolder); - } - - string command = string.Empty; - string[] templateJobFilePaths = this.JobFiles.Split(new char[] { ';', ',' }); - - foreach (string templateJobFilePath in templateJobFilePaths) - { - // Create/update new job file at runtime. - string templateJobFileName = Path.GetFileName(templateJobFilePath); - string updatedJobFilePath = this.PlatformSpecifics.Combine(jobFileFolder, "updated", templateJobFileName); - this.CreateOrUpdateJobFile(templateJobFilePath, updatedJobFilePath); - - // Update command to include the new job file. - command += $"{updatedJobFilePath} "; - } - - command = $"{command.Trim()} --output-format=json"; - return command; - } - private string RemoveOption(string commandLine, string option) { return Regex.Replace(commandLine, $@"{option}=[\x21-\x7E]+\s", string.Empty, RegexOptions.IgnoreCase); diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/FioMultiThroughputExecutor.cs b/src/VirtualClient/VirtualClient.Actions/FIO/FioMultiThroughputExecutor.cs deleted file mode 100644 index 31db66eec6..0000000000 --- a/src/VirtualClient/VirtualClient.Actions/FIO/FioMultiThroughputExecutor.cs +++ /dev/null @@ -1,853 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace VirtualClient.Actions -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.Extensions.DependencyInjection; - using Polly; - using VirtualClient.Common; - using VirtualClient.Common.Extensions; - using VirtualClient.Common.Platform; - using VirtualClient.Common.Telemetry; - using VirtualClient.Contracts; - - /// - /// Manages the execution runtime of the FIO Multi Throughput workload. - /// It represents an OLTP-C scenario. - /// Random IO represents Database transactions. - /// Sequential IO represents Logger transactions. - /// - [SupportedPlatforms("linux-arm64,linux-x64")] - public class FioMultiThroughputExecutor : FioExecutor - { - private static readonly object VariationLock = new object(); - private static int variationNumber = 0; - private string randomIOFilePath; - private string sequentialIOFilePath; - private long totalIOPS; - private long randomReadIOPS; - private long randomWriteIOPS; - private long sequentialReadIOPS; - private long sequentialWriteIOPS; - - private static IAsyncPolicy fioMultiThroughputRetryPolicy = Policy.Handle().WaitAndRetryAsync(3, _ => RetryWaitTime); - - /// - /// Initializes a new instance of the class. - /// - /// Provides required dependencies to the workload. - /// The set of parameters defined for the action in the profile definition. - public FioMultiThroughputExecutor(IServiceCollection dependencies, IDictionary parameters) - : base(dependencies, parameters) - { - // Since in this case we are testing on raw disks, we are not cleaning up test files - this.DeleteTestFilesOnFinish = false; - - // Convert to desired data types. - this.DirectIO = parameters.GetValue(nameof(this.DirectIO), true) ? 1 : 0; - } - - /// - /// Parameter. True to used direct, non-buffered I/O (default). False to use buffered I/O. - /// - public int DirectIO - { - get - { - return this.Parameters.GetValue(nameof(this.DirectIO), 1); - } - - private set - { - this.Parameters[nameof(this.DirectIO)] = value; - } - } - - /// - /// Group Id. - /// - public string GroupId - { - get - { - IConvertible value = string.Empty; - if (this.Metadata != null) - { - (this.Metadata as Dictionary).TryGetValue(nameof(this.GroupId), out value); - } - - return value == null ? string.Empty : value.ToString(); - } - } - - /// - /// Group reporting parameter for FIO. - /// - public int GroupReporting - { - get - { - return this.Parameters.GetValue(nameof(this.GroupReporting)); - } - } - - /// - /// Random IO File Size. - /// - public string RandomIOFileSize - { - get - { - return this.Parameters.GetValue(nameof(this.RandomIOFileSize)); - } - } - - /// - /// Block size for Random Read. - /// - public string RandomReadBlockSize - { - get - { - return this.Parameters.GetValue(nameof(this.RandomReadBlockSize)); - } - } - - /// - /// Number Jobs for Random Read. - /// - public int RandomReadNumJobs - { - get - { - return this.Parameters.GetValue(nameof(this.RandomReadNumJobs)); - } - } - - /// - /// Queue Depth for Random Read. - /// - public int RandomReadQueueDepth - { - get - { - return this.Parameters.GetValue(nameof(this.RandomReadQueueDepth)); - } - } - - /// - /// Block size for Random Write. - /// - public string RandomWriteBlockSize - { - get - { - return this.Parameters.GetValue(nameof(this.RandomWriteBlockSize)); - } - } - - /// - /// Number of Jobs for Random Write. - /// - public int RandomWriteNumJobs - { - get - { - return this.Parameters.GetValue(nameof(this.RandomWriteNumJobs)); - } - } - - /// - /// QueueDepth for Random Write. - /// - public int RandomWriteQueueDepth - { - get - { - return this.Parameters.GetValue(nameof(this.RandomWriteQueueDepth)); - } - } - - /// - /// Run Time for running the FIO in Seconds. - /// - public string Duration - { - get - { - return TimeSpan.Parse(this.Parameters.GetValue(nameof(this.Duration))).TotalSeconds.ToString(); - } - } - - /// - /// File size of Sequential IO File. - /// - public string SequentialIOFileSize - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialIOFileSize)); - } - } - - /// - /// Block Size for Sequential Read. - /// - public string SequentialReadBlockSize - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialReadBlockSize)); - } - } - - /// - /// Number of Jobs for Sequential Read. - /// - public int SequentialReadNumJobs - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialReadNumJobs)); - } - } - - /// - /// Queue Depth for Sequential Read. - /// - public int SequentialReadQueueDepth - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialReadQueueDepth)); - } - } - - /// - /// Block Size for Sequential Write. - /// - public string SequentialWriteBlockSize - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialWriteBlockSize)); - } - } - - /// - /// Number of Jobs for Sequential Write. - /// - public int SequentialWriteNumJobs - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialWriteNumJobs)); - } - } - - /// - /// Queue Depth for Sequential Write. - /// - public int SequentialWriteQueueDepth - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialWriteQueueDepth)); - } - } - - /// - /// Target percents list. - /// - public List TargetPercents - { - get - { - return this.Parameters.GetValue(nameof(this.TargetPercents)).Split(VirtualClientComponent.CommonDelimiters).Select(int.Parse).ToList(); - } - } - - /// - /// Weight for Random Read. - /// - public int RandomReadWeight - { - get - { - return this.Parameters.GetValue(nameof(this.RandomReadWeight)); - } - } - - /// - /// Weight for Random Write. - /// - public int RandomWriteWeight - { - get - { - return this.Parameters.GetValue(nameof(this.RandomWriteWeight)); - } - } - - /// - /// Weight for Sequential Read. - /// - public int SequentialReadWeight - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialReadWeight)); - } - } - - /// - /// Weight for Sequential Write. - /// - public int SequentialWriteWeight - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialWriteWeight)); - } - } - - /// - /// Target IOPS. - /// - public int TargetIOPS - { - get - { - return this.Parameters.GetValue(nameof(this.TargetIOPS)); - } - } - - /// - /// Number of sequential disks. - /// - public int SequentialDiskCount - { - get - { - return this.Parameters.GetValue(nameof(this.SequentialDiskCount), 1); - } - } - - /// - /// Template for Job file. - /// - public string TemplateJobFile - { - get - { - return this.Parameters.GetValue(nameof(this.TemplateJobFile)); - } - } - - /// - /// Retry Wait Time for FIO executors. - /// - protected static TimeSpan RetryWaitTime { get; } = TimeSpan.FromSeconds(10); - - /// - /// Executes the FIO workload, captures performance results and logs them to telemetry. - /// - /// Provides context information that will be captured with telemetry events. - /// A token that can be used to cancel the operation. - protected override async Task ExecuteAsync(EventContext telemetryContext, CancellationToken cancellationToken) - { - IEnumerable disks = await this.SystemManagement.DiskManager.GetDisksAsync(cancellationToken) - .ConfigureAwait(false); - - if (disks?.Any() != true) - { - throw new WorkloadException( - "Unexpected scenario. The disks defined for the system could not be properly enumerated.", - ErrorReason.WorkloadUnexpectedAnomaly); - } - - IEnumerable disksToTest = this.GetDisksToTest(disks); - - if (disksToTest?.Any() != true) - { - throw new WorkloadException( - "Expected disks to test not found. Given the parameters defined for the profile action/step or those passed " + - "in on the command line, the requisite disks do not exist on the system or could not be identified based on the properties " + - "of the existing disks. Verify or specify the disk filter.", - ErrorReason.DependencyNotFound); - } - - if (disksToTest?.Any(disk => disk.IsOperatingSystem()) == true) - { - throw new WorkloadException( - "Expected disks to test contain the disk on which the operation system is installed. This scenario runs I/O operations against the raw disk without any file " + - "system layers and can overwrite important information on the disk such as disk volume partitions. As such I/O operations against the operating system disk " + - "are not supported.", - ErrorReason.NotSupported); - } - - disksToTest.ToList().ForEach(disk => this.Logger.LogTraceMessage($"Disk Target: '{disk}'")); - - this.UpdateTestFilePaths(disksToTest); - - telemetryContext.AddContext("executable", this.ExecutablePath); - telemetryContext.AddContext(nameof(disks), disks); - telemetryContext.AddContext(nameof(disksToTest), disksToTest); - telemetryContext.AddContext(nameof(this.sequentialIOFilePath), this.sequentialIOFilePath); - telemetryContext.AddContext(nameof(this.randomIOFilePath), this.randomIOFilePath); - - if (this.DiskFill) - { - Interlocked.Exchange(ref variationNumber, 0); - - if (await this.IsDiskFillCompleteAsync(cancellationToken).ConfigureAwait(false) == false) - { - await this.ExecuteWorkloadAsync(this.Scenario, new Dictionary(), telemetryContext, cancellationToken) - .ConfigureAwait(false); - - await this.RegisterDiskFillCompleteAsync(cancellationToken) - .ConfigureAwait(false); - } - } - else - { - List exceptions = new List(); - - foreach (int targetPercent in this.TargetPercents) - { - if (!cancellationToken.IsCancellationRequested) - { - int variation = Interlocked.Increment(ref variationNumber); - - // e.g. - // fio_multithroughput_read/write/randread/randwrite_20G_128G(56k/56k/8k/8k, d64/64/512/512, th1/1/1/1, w0/329/5416/4255)_10% - string testName = $"fio_multithroughput_read/write/randread/randwrite_{this.SequentialIOFileSize}_{this.RandomIOFileSize}(" + - $"{this.SequentialReadBlockSize.ToLowerInvariant()}/{this.SequentialWriteBlockSize.ToLowerInvariant()}/{this.RandomReadBlockSize.ToLowerInvariant()}/{this.RandomWriteBlockSize.ToLowerInvariant()}, " + - $"d{this.SequentialReadQueueDepth}/{this.SequentialWriteQueueDepth}/{this.RandomReadQueueDepth}/{this.RandomWriteQueueDepth}, " + - $"th{this.SequentialReadNumJobs}/{this.SequentialWriteNumJobs}/{this.RandomReadNumJobs}/{this.RandomWriteNumJobs}, " + - $"w{this.SequentialReadWeight}/{this.SequentialWriteWeight}/{this.RandomReadWeight}/{this.RandomWriteWeight})_{targetPercent}%"; - - EventContext variationContext = telemetryContext.Clone().AddContext(nameof(testName), testName); - - try - { - await this.Logger.LogMessageAsync($"{this.TypeName}.ExecuteVariation", variationContext, async () => - { - this.SetRuntimeParameters(targetPercent); - - Dictionary metricsMetadata = new Dictionary - { - [nameof(targetPercent).CamelCased()] = targetPercent, - [nameof(variation).CamelCased()] = variation, - [nameof(testName).CamelCased()] = testName - }; - - await fioMultiThroughputRetryPolicy.ExecuteAsync(async () => - { - await this.ExecuteWorkloadAsync(testName, metricsMetadata, variationContext, cancellationToken) - .ConfigureAwait(false); - }).ConfigureAwait(false); - - }).ConfigureAwait(false); - } - catch (VirtualClientException exc) - { - exceptions.Add(exc); - } - } - } - - if (exceptions.Any()) - { - AggregateException aggregateException = new AggregateException(exceptions); - - WorkloadException workloadException = new WorkloadException( - $"{nameof(FioMultiThroughputExecutor)} failed with following exceptions", - aggregateException, - exceptions.Max(ex => ex.Reason)); - - throw workloadException; - } - } - } - - /// - protected override void Validate() - { - // Override default validation. - } - - /// - /// Gets the logging setting. Checks workload profile, then command line arguments, then defaults to READ - /// - /// Logging setting that controls which results are reported - protected override void GetMetricsParsingDirectives(out bool parseReadMetrics, out bool parseWriteMetrics, string commandLine) - { - parseReadMetrics = false; - parseWriteMetrics = false; - - if (commandLine.Contains("--section init", StringComparison.OrdinalIgnoreCase) || commandLine.Contains("--section randomwrite", StringComparison.OrdinalIgnoreCase) || commandLine.Contains("--section sequentialwrite", StringComparison.OrdinalIgnoreCase)) - { - parseWriteMetrics = true; - } - - if (commandLine.Contains("--section randomread", StringComparison.OrdinalIgnoreCase) || commandLine.Contains("--section sequentialread", StringComparison.OrdinalIgnoreCase) || parseWriteMetrics == false) - { - parseReadMetrics = true; - } - } - - /// - protected override void CaptureMetrics( - IProcessProxy workloadProcess, string testName, string metricCategorization, string commandArguments, EventContext telemetryContext, Dictionary metricMetadata = null) - { - this.GetMetricsParsingDirectives(out bool parseReadMetrics, out bool parseWriteMetrics, commandArguments); - FioMetricsParser parser = new FioMetricsParser(workloadProcess.StandardOutput.ToString(), parseReadMetrics, parseWriteMetrics); - IList metrics = parser.Parse(); - - if (this.MetricFilters?.Any() == true) - { - metrics = metrics.FilterBy(this.MetricFilters).ToList(); - } - - if (metricMetadata != null) - { - foreach (var metric in metrics) - { - foreach (var metricMetadataValue in metricMetadata) - { - metric.Metadata[metricMetadataValue.Key] = metricMetadataValue.Value; - } - } - } - - this.Logger.LogMetrics( - "FIO", - testName, - workloadProcess.StartTime, - workloadProcess.ExitTime, - this.GetSectionizedMetrics(metrics), - metricCategorization, - commandArguments, - this.Tags, - telemetryContext); - } - - /// - /// Executes the FIO workload, captures performance results and logs them to telemetry. - /// - private async Task ExecuteWorkloadAsync(string testName, Dictionary metricsMetadata, EventContext telemetryContext, CancellationToken cancellationToken) - { - if (!cancellationToken.IsCancellationRequested) - { - telemetryContext.AddContext("executable", this.ExecutablePath); - telemetryContext.AddContext(nameof(this.TemplateJobFile), this.TemplateJobFile); - - string jobFileFolder = this.PlatformSpecifics.GetScriptPath("fio"); - string updatedJobFileFolder = Path.Combine(jobFileFolder, "updated"); - - if (!this.SystemManagement.FileSystem.Directory.Exists(updatedJobFileFolder)) - { - this.SystemManagement.FileSystem.Directory.CreateDirectory(updatedJobFileFolder); - } - - string templateJobFilePath = this.PlatformSpecifics.Combine(jobFileFolder, this.TemplateJobFile); - string jobFilePath = this.PlatformSpecifics.Combine(jobFileFolder, "updated", nameof(FioMultiThroughputExecutor) + this.TemplateJobFile); - - this.CreateOrUpdateJobFile(templateJobFilePath, jobFilePath); - - DiskWorkloadProcess process = this.CreateWorkloadProcess(this.ExecutablePath, jobFilePath); - - metricsMetadata[nameof(this.CommandLine)] = process.CommandArguments; - using (BackgroundOperations profiling = BackgroundOperations.BeginProfiling(this, cancellationToken)) - { - await this.ExecuteWorkloadAsync(process, testName, telemetryContext, cancellationToken, metricsMetadata); - } - } - } - - /// - /// Creates a process to run FIO targeting the file names specified. - /// - private DiskWorkloadProcess CreateWorkloadProcess(string executable, string jobFile) - { - string fioArguments = $"{jobFile.Trim()} {this.GetSections().Trim()} --time_based --output-format=json --thread --fallocate=none".Trim(); - - IProcessProxy process = this.SystemManagement.ProcessManager.CreateElevatedProcess(this.Platform, executable, fioArguments); - - string testedInstances = $"{this.randomIOFilePath},{this.sequentialIOFilePath}"; - List testFiles = new List() { this.randomIOFilePath, this.sequentialIOFilePath }; - - return new DiskWorkloadProcess(process, testedInstances, testFiles.ToArray()); - } - - private void CreateOrUpdateJobFile(string sourcePath, string destinationPath) - { - string text = this.SystemManagement.FileSystem.File.ReadAllText(sourcePath); - int direct = this.DirectIO; - - if (this.DiskFill) - { - text = text.Replace("${ioengine}", this.Engine); - text = text.Replace($"${{{nameof(this.Duration).ToLower()}}}", this.Duration.ToString()); - text = text.Replace($"${{{nameof(this.GroupReporting).ToLower()}}}", this.GroupReporting.ToString()); - text = text.Replace($"${{{nameof(this.DirectIO).ToLower()}}}", direct.ToString()); - text = text.Replace($"${{{nameof(this.RandomIOFileSize).ToLower()}}}", this.RandomIOFileSize.ToString()); - text = text.Replace($"${{{nameof(this.randomIOFilePath).ToLower()}}}", this.randomIOFilePath.ToString()); - text = text.Replace($"${{{nameof(this.SequentialIOFileSize).ToLower()}}}", this.SequentialIOFileSize.ToString()); - text = text.Replace($"${{{nameof(this.sequentialIOFilePath).ToLower()}}}", this.sequentialIOFilePath.ToString()); - } - else - { - int randomReadIOdepth = this.RandomReadQueueDepth / this.RandomReadNumJobs; - int randomWriteIOdepth = this.RandomWriteQueueDepth / this.RandomWriteNumJobs; - int sequentialReadIOdepth = this.SequentialReadQueueDepth / this.SequentialReadNumJobs; - int sequentialWriteIOdepth = this.SequentialWriteQueueDepth / this.SequentialWriteNumJobs; - - text = text.Replace("${ioengine}", this.Engine); - text = text.Replace($"${{{nameof(this.DirectIO).ToLower()}}}", direct.ToString()); - text = text.Replace($"${{{nameof(this.Duration).ToLower()}}}", this.Duration.ToString()); - text = text.Replace($"${{{nameof(this.GroupReporting).ToLower()}}}", this.GroupReporting.ToString()); - - text = text.Replace($"${{{nameof(this.RandomIOFileSize).ToLower()}}}", this.RandomIOFileSize.ToString()); - text = text.Replace($"${{{nameof(this.randomIOFilePath).ToLower()}}}", this.randomIOFilePath.ToString()); - text = text.Replace($"${{{nameof(this.SequentialIOFileSize).ToLower()}}}", this.SequentialIOFileSize.ToString()); - text = text.Replace($"${{{nameof(this.sequentialIOFilePath).ToLower()}}}", this.sequentialIOFilePath.ToString()); - - text = text.Replace($"${{{nameof(this.RandomReadBlockSize).ToLower()}}}", this.RandomReadBlockSize); - text = text.Replace($"${{{nameof(randomReadIOdepth).ToLower()}}}", randomReadIOdepth.ToString()); - text = text.Replace($"${{{nameof(this.randomReadIOPS).ToLower()}}}", this.randomReadIOPS.ToString()); - text = text.Replace($"${{{nameof(this.RandomReadNumJobs).ToLower()}}}", this.RandomReadNumJobs.ToString()); - - text = text.Replace($"${{{nameof(this.RandomWriteBlockSize).ToLower()}}}", this.RandomWriteBlockSize); - text = text.Replace($"${{{nameof(randomWriteIOdepth).ToLower()}}}", randomWriteIOdepth.ToString()); - text = text.Replace($"${{{nameof(this.randomWriteIOPS).ToLower()}}}", this.randomWriteIOPS.ToString()); - text = text.Replace($"${{{nameof(this.RandomWriteNumJobs).ToLower()}}}", this.RandomWriteNumJobs.ToString()); - - text = text.Replace($"${{{nameof(this.SequentialReadBlockSize).ToLower()}}}", this.SequentialReadBlockSize); - text = text.Replace($"${{{nameof(sequentialReadIOdepth).ToLower()}}}", sequentialReadIOdepth.ToString()); - text = text.Replace($"${{{nameof(this.sequentialReadIOPS).ToLower()}}}", this.sequentialReadIOPS.ToString()); - text = text.Replace($"${{{nameof(this.SequentialReadNumJobs).ToLower()}}}", this.SequentialReadNumJobs.ToString()); - - text = text.Replace($"${{{nameof(this.SequentialWriteBlockSize).ToLower()}}}", this.SequentialWriteBlockSize); - text = text.Replace($"${{{nameof(sequentialWriteIOdepth).ToLower()}}}", sequentialWriteIOdepth.ToString()); - text = text.Replace($"${{{nameof(this.sequentialWriteIOPS).ToLower()}}}", this.sequentialWriteIOPS.ToString()); - text = text.Replace($"${{{nameof(this.SequentialWriteNumJobs).ToLower()}}}", this.SequentialWriteNumJobs.ToString()); - } - - this.SystemManagement.FileSystem.File.WriteAllText(@destinationPath, text); - } - - private IList GetSectionizedMetrics(IList metrics) - { - IList sectionizedMetrics = new List(); - - foreach (var metric in metrics) - { - string ioType = metric.Metadata["rw"].ToString(); - bool validMetric = true; - - switch (ioType.ToLower()) - { - case "read": - case "randread": - if (metric.Name.StartsWith("write", StringComparison.OrdinalIgnoreCase)) - { - validMetric = false; - } - - break; - - case "write": - case "randwrite": - if (metric.Name.StartsWith("read", StringComparison.OrdinalIgnoreCase)) - { - validMetric = false; - } - - break; - - default: - validMetric = true; - break; - } - - if (validMetric) - { - IDictionary metadata = this.GetMetricsMetadata(ioType); - - foreach (var metadataValue in metadata) - { - metric.Metadata[metadataValue.Key] = metadataValue.Value; - } - - sectionizedMetrics.Add(metric); - } - } - - return sectionizedMetrics; - } - - private IDictionary GetMetricsMetadata(string ioType) - { - Dictionary metadata = new Dictionary(); - - metadata[nameof(this.ProfileIteration).CamelCased()] = this.ProfileIteration; - metadata[nameof(this.ProfileIterationStartTime).CamelCased()] = this.ProfileIterationStartTime; - metadata[nameof(this.GroupId)] = this.GroupId; - - if (!this.DiskFill) - { - string blockSizeKiB = string.Empty; - string fileSizeGiB = string.Empty; - string queueDepth = string.Empty; - string numJobs = string.Empty; - string filePath = string.Empty; - string weight = string.Empty; - - switch (ioType.ToLower()) - { - case "randread": - blockSizeKiB = TextParsingExtensions.TranslateStorageByUnit(this.RandomReadBlockSize, MetricUnit.Kilobytes); - fileSizeGiB = TextParsingExtensions.TranslateStorageByUnit(this.RandomIOFileSize, MetricUnit.Gigabytes); - queueDepth = this.RandomReadQueueDepth.ToString(); - numJobs = this.RandomReadNumJobs.ToString(); - filePath = this.randomIOFilePath.ToString(); - weight = this.RandomReadWeight.ToString(); - - break; - - case "read": - blockSizeKiB = TextParsingExtensions.TranslateStorageByUnit(this.SequentialReadBlockSize, MetricUnit.Kilobytes); - fileSizeGiB = TextParsingExtensions.TranslateStorageByUnit(this.SequentialIOFileSize, MetricUnit.Gigabytes); - queueDepth = this.SequentialReadQueueDepth.ToString(); - numJobs = this.SequentialReadNumJobs.ToString(); - filePath = this.sequentialIOFilePath.ToString(); - weight = this.SequentialReadWeight.ToString(); - - break; - - case "randwrite": - blockSizeKiB = TextParsingExtensions.TranslateStorageByUnit(this.RandomWriteBlockSize, MetricUnit.Kilobytes); - fileSizeGiB = TextParsingExtensions.TranslateStorageByUnit(this.RandomIOFileSize, MetricUnit.Gigabytes); - queueDepth = this.RandomWriteQueueDepth.ToString(); - numJobs = this.RandomWriteNumJobs.ToString(); - filePath = this.randomIOFilePath.ToString(); - weight = this.RandomWriteWeight.ToString(); - - break; - - case "write": - blockSizeKiB = TextParsingExtensions.TranslateStorageByUnit(this.SequentialWriteBlockSize, MetricUnit.Kilobytes); - fileSizeGiB = TextParsingExtensions.TranslateStorageByUnit(this.SequentialIOFileSize, MetricUnit.Gigabytes); - queueDepth = this.SequentialWriteQueueDepth.ToString(); - numJobs = this.SequentialWriteNumJobs.ToString(); - filePath = this.sequentialIOFilePath.ToString(); - weight = this.SequentialWriteWeight.ToString(); - - break; - } - - metadata[nameof(this.TargetIOPS).CamelCased()] = this.TargetIOPS; - metadata[nameof(this.Duration).CamelCased()] = this.Duration; - metadata[nameof(this.DirectIO).CamelCased()] = this.DirectIO; - metadata[nameof(this.GroupReporting).CamelCased()] = this.GroupReporting; - metadata[nameof(ioType).CamelCased()] = ioType; - metadata[nameof(blockSizeKiB).CamelCased()] = blockSizeKiB; - metadata[nameof(fileSizeGiB).CamelCased()] = fileSizeGiB; - metadata[nameof(queueDepth).CamelCased()] = queueDepth; - metadata[nameof(numJobs).CamelCased()] = numJobs; - metadata[nameof(filePath).CamelCased()] = filePath; - metadata[nameof(weight).CamelCased()] = weight; - } - - return metadata; - } - - private void SetRuntimeParameters(int targetPercent) - { - this.totalIOPS = (this.TargetIOPS * targetPercent) / 100; - long totalWeights = this.RandomReadWeight + this.RandomWriteWeight + this.SequentialReadWeight + this.SequentialWriteWeight; - totalWeights = totalWeights == 0 ? 1 : totalWeights; - - this.randomReadIOPS = ((this.totalIOPS * this.RandomReadWeight) / totalWeights) / this.RandomReadNumJobs; - this.randomWriteIOPS = ((this.totalIOPS * this.RandomWriteWeight) / totalWeights) / this.RandomWriteNumJobs; - this.sequentialReadIOPS = ((this.totalIOPS * this.SequentialReadWeight) / totalWeights) / this.SequentialReadNumJobs; - this.sequentialWriteIOPS = ((this.totalIOPS * this.SequentialWriteWeight) / totalWeights) / this.SequentialWriteNumJobs; - } - - private void UpdateTestFilePaths(IEnumerable disksToTest) - { - disksToTest.ThrowIfNullOrEmpty(nameof(disksToTest)); - disksToTest.OrderByDescending(disk => disk.SizeInBytes(this.Platform)); - - if (disksToTest.Count() == 1) - { - this.randomIOFilePath = disksToTest.FirstOrDefault().DevicePath; - this.sequentialIOFilePath = disksToTest.FirstOrDefault().DevicePath; - } - else - { - int sequentialDiskCount = this.SequentialDiskCount; - - if (sequentialDiskCount >= disksToTest.Count()) - { - sequentialDiskCount = disksToTest.Count() - 1; - this.Logger.LogTraceMessage($"{nameof(sequentialDiskCount)} should be less than total disks to test. Setting it to {sequentialDiskCount}."); - } - - int randomDiskCount = disksToTest.Count() - sequentialDiskCount; - this.Logger.LogTraceMessage($"{nameof(randomDiskCount)} : {randomDiskCount} and {nameof(sequentialDiskCount)}: {sequentialDiskCount}."); - - this.randomIOFilePath = string.Join(':', disksToTest.Take(randomDiskCount).Select(disk => disk.DevicePath).ToArray()); - this.sequentialIOFilePath = string.Join(':', disksToTest.TakeLast(sequentialDiskCount).Select(disk => disk.DevicePath).ToArray()); - } - - // e.g. - // /dev/sdc - // /dev/sdc, /dev/sdd, /dev/sde - this.Logger.LogTraceMessage($"Disk Targets (Random I/O): {this.randomIOFilePath.Replace(":", ", ")}"); - this.Logger.LogTraceMessage($"Disk Targets (Sequential I/O): '{this.sequentialIOFilePath.Replace(":", ", ")}'"); - } - - private string GetSections() - { - string sections = string.Empty; - - if (this.DiskFill) - { - sections = "--section initrandomio --section initsequentialio"; - } - else - { - if (this.randomReadIOPS > 0) - { - sections = sections + " --section randomreader"; - } - - if (this.randomWriteIOPS > 0) - { - sections = sections + " --section randomwriter"; - } - - if (this.sequentialReadIOPS > 0) - { - sections = sections + " --section sequentialreader"; - } - - if (this.sequentialWriteIOPS > 0) - { - sections = sections + " --section sequentialwriter"; - } - } - - return sections; - } - } -} \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c.fio.jobfile b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c.fio.jobfile deleted file mode 100644 index f9a279e650..0000000000 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c.fio.jobfile +++ /dev/null @@ -1,79 +0,0 @@ -# fio template for OLTP-C runs -# defines three components: readers, writes, and loggers - -# --------------- Global section defines defaults across all components -[global] -direct=${directio} -filename=${randomiofilepath} -ioengine=${ioengine} -group_reporting=${groupreporting} -size=${randomiofilesize} -time_based=1 - -# by setting the submit mode to offload, we can guarantee a fixed rate of -# submission regardless of what the device completion rate is. -#io_submit_mode=offload - -# Represents reading of data from sql/OLTP database. -[randomreader] -new_group -bs=${randomreadblocksize} -iodepth=${randomreadiodepth} -numjobs=${randomreadnumjobs} -rate_iops=${randomreadiops} -runtime=${duration} -rw=randread - -# Represents writing of data in sql/OLTP database. -[randomwriter] -new_group -bs=${randomwriteblocksize} -iodepth=${randomwriteiodepth} -numjobs=${randomwritenumjobs} -rate_iops=${randomwriteiops} -runtime=${duration} -rw=randwrite - -# Represents log readers of sql/OLTP database. -[sequentialreader] -new_group -bs=${sequentialreadblocksize} -filename=${sequentialiofilepath} -iodepth=${sequentialreadiodepth} -numjobs=${sequentialreadnumjobs} -rate_iops=${sequentialreadiops} -runtime=${duration} -rw=read -size=${sequentialiofilesize} - -# Represents log writers of sql/OLTP database. -[sequentialwriter] -new_group -bs=${sequentialwriteblocksize} -filename=${sequentialiofilepath} -iodepth=${sequentialwriteiodepth} -numjobs=${sequentialwritenumjobs} -rate_iops=${sequentialwriteiops} -runtime=${duration} -rw=write -size=${sequentialiofilesize} - -# Initialize database data. -[initrandomio] -new_group -bs=256K -filename=${randomiofilepath} -iodepth=64 -numjobs=1 -rw=write -size=${randomiofilesize} - -# Initialize logs database. -[initsequentialio] -new_group -bs=256K -filename=${sequentialiofilepath} -iodepth=64 -numjobs=1 -rw=write -size=${sequentialiofilesize} \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio.jobfile b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio similarity index 88% rename from src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio.jobfile rename to src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio index 39ec037622..ff472f4f15 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio.jobfile +++ b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio @@ -3,7 +3,7 @@ # --------------- Global section defines defaults across all components [global] -direct=${directio} +direct=1 group_reporting=0 time_based=1 @@ -18,7 +18,7 @@ bs=256K iodepth=64 numjobs=1 rw=write -size=${randomiofilesize} +size=124G # Initialize logs database. [initsequentialio] @@ -27,4 +27,4 @@ bs=256K iodepth=64 numjobs=1 rw=write -size=${sequentialiofilesize} \ No newline at end of file +size=20G \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations.fio.jobfile b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio similarity index 57% rename from src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations.fio.jobfile rename to src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio index e85733d7bd..f466058b87 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations.fio.jobfile +++ b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio @@ -3,7 +3,7 @@ # --------------- Global section defines defaults across all components [global] -direct=${directio} +direct=1 group_reporting=0 time_based=1 @@ -14,43 +14,43 @@ time_based=1 # Represents reading of data from sql/OLTP database. [randomreader] new_group -bs=${randomreadblocksize} -iodepth=${randomreadiodepth} -numjobs=${randomreadnumjobs} +bs=4k +iodepth=512 +numjobs=1 rate_iops=2708 -runtime=${duration} +runtime=180 rw=randread -size=${randomiofilesize} +size=124G # Represents writing of data in sql/OLTP database. [randomwriter] new_group -bs=${randomwriteblocksize} -iodepth=${randomwriteiodepth} -numjobs=${randomwritenumjobs} +bs=4k +iodepth=512 +numjobs=1 rate_iops=2128 -runtime=${duration} +runtime=180 rw=randwrite -size=${randomiofilesize} +size=124G # Represents log readers of sql/OLTP database. [sequentialreader] new_group -bs=${sequentialreadblocksize} -iodepth=${sequentialreadiodepth} -numjobs=${sequentialreadnumjobs} +bs=4k +iodepth=64 +numjobs=1 rate_iops=0 -runtime=${duration} +runtime=180 rw=read -size=${sequentialiofilesize} +size=20G # Represents log writers of sql/OLTP database. [sequentialwriter] new_group -bs=${sequentialwriteblocksize} -iodepth=${sequentialwriteiodepth} -numjobs=${sequentialwritenumjobs} +bs=4k +iodepth=64 +numjobs=1 rate_iops=164 -runtime=${duration} +runtime=180 rw=write -size=${sequentialiofilesize} \ No newline at end of file +size=20G \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/VirtualClient.Actions.csproj b/src/VirtualClient/VirtualClient.Actions/VirtualClient.Actions.csproj index 33cb51d7b5..5902041e1a 100644 --- a/src/VirtualClient/VirtualClient.Actions/VirtualClient.Actions.csproj +++ b/src/VirtualClient/VirtualClient.Actions/VirtualClient.Actions.csproj @@ -22,7 +22,7 @@ - + diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json deleted file mode 100644 index d91e1d036d..0000000000 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-DISCOVERY.json +++ /dev/null @@ -1,632 +0,0 @@ -{ - "Description": "FIO I/O Stress Performance Workload", - "Metadata": { - "RecommendedMinimumExecutionTime": "02:00:00", - "SupportedPlatforms": "linux-x64,linux-arm64", - "SupportedOperatingSystems": "CBL-Mariner,CentOS,Debian,RedHat,Suse,Ubuntu,Windows" - }, - "Parameters": { - "DiskFillSize": "134G", - "FileSize": "134G", - "DiskFilter": "BiggestSize", - "Duration": "00:03:00", - "ProcessModel": "SingleProcess", - "MaxThreads": "8", - "QueueDepths": "1,4,16,64,256,1024", - "Engine": "{calculate(\"{Platform}\".StartsWith(\"linux\") ? \"libaio\" : \"windowsaio\")}", - "DirectIO": true - }, - "Actions": [ - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "DiskFill", - "CommandLine": "--name=disk_fill --size={DiskFillSize} --rw=write --bs=256K --numjobs=1 --iodepth=64 --ioengine={Engine} --fallocate=none --refill_buffers=1 --direct=1 --overwrite=1 --output-format=json", - "Engine": "$.Parameters.Engine", - "PackageName": "fio", - "ProcessModel": "SingleProcessPerDisk", - "DiskFillSize": "$.Parameters.DiskFillSize", - "DiskFill": true, - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomRead_1k_BlockSize", - "BlockSize": "1k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randread", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randread" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomRead_4k_BlockSize", - "BlockSize": "4k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randread", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randread" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomRead_8k_BlockSize", - "BlockSize": "8k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randread", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randread" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomRead_16k_BlockSize", - "BlockSize": "16k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randread", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randread" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomRead_64k_BlockSize", - "BlockSize": "64k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randread", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randread" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomRead_256k_BlockSize", - "BlockSize": "256k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randread", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randread" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomRead_1024k_BlockSize", - "BlockSize": "1024k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randread", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randread" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomWrite_1k_BlockSize", - "BlockSize": "1k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randwrite", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randwrite" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomWrite_4k_BlockSize", - "BlockSize": "4k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randwrite", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randwrite" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomWrite_8k_BlockSize", - "BlockSize": "8k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randwrite", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randwrite" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomWrite_16k_BlockSize", - "BlockSize": "16k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randwrite", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randwrite" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomWrite_64k_BlockSize", - "BlockSize": "64k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randwrite", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randwrite" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomWrite_256k_BlockSize", - "BlockSize": "256k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randwrite", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randwrite" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "RandomWrite_1024k_BlockSize", - "BlockSize": "1024k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "randwrite", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,randwrite" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialRead_1k_BlockSize", - "BlockSize": "1k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "read", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,read" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialRead_4k_BlockSize", - "BlockSize": "4k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "read", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,read" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialRead_8k_BlockSize", - "BlockSize": "8k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "read", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,read" - } - }, - - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialRead_16k_BlockSize", - "BlockSize": "16k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "read", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,read" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialRead_64k_BlockSize", - "BlockSize": "64k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "read", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,read" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialRead_256k_BlockSize", - "BlockSize": "256k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "read", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,read" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialRead_1024k_BlockSize", - "BlockSize": "1024k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "read", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,read" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialWrite_1k_BlockSize", - "BlockSize": "1k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "write", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,write" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialWrite_4k_BlockSize", - "BlockSize": "4k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "write", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,write" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialWrite_8k_BlockSize", - "BlockSize": "8k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "write", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,write" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialWrite_16k_BlockSize", - "BlockSize": "16k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "write", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,write" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialWrite_64k_BlockSize", - "BlockSize": "64k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "write", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,write" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialWrite_256k_BlockSize", - "BlockSize": "256k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "write", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,write" - } - }, - { - "Type": "FioDiscoveryExecutor", - "Parameters": { - "Scenario": "SequentialWrite_1024k_BlockSize", - "BlockSize": "1024k", - "CommandLine": "--ioengine={Engine} --size={FileSize} --rw={IOType} --bs={BlockSize} --direct={DirectIO} --ramp_time=15 --runtime={Duration.TotalSeconds} --time_based --overwrite=1 --thread --group_reporting --output-format=json", - "Engine": "$.Parameters.Engine", - "FileSize": "$.Parameters.FileSize", - "Duration": "$.Parameters.Duration", - "IOType": "write", - "MaxThreads": "$.Parameters.MaxThreads", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "QueueDepths": "$.Parameters.QueueDepths", - "DirectIO": "$.Parameters.DirectIO", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "Tags": "IO,FIO,Discovery,write" - } - } - ], - "Dependencies": [ - { - "Type": "LinuxPackageInstallation", - "Parameters": { - "Scenario": "InstallLinuxPackages", - "Packages-Apt": "fio", - "Packages-Dnf": "fio,lshw,parted", - "Packages-Yum": "fio", - "Packages-Zypper": "fio" - } - }, - { - "Type": "FormatDisks", - "Parameters": { - "Scenario": "InitializeDisks" - } - }, - { - "Type": "MountDisks", - "Parameters": { - "Scenario": "CreateMountPoints", - "DiskFilter": "$.Parameters.DiskFilter" - } - }, - { - "Type": "DependencyPackageInstallation", - "Parameters": { - "Scenario": "InstallFIOPackage", - "SupportedPlatforms": "win-x64", - "BlobContainer": "packages", - "BlobName": "fio.3.30.0.zip", - "PackageName": "fio", - "Extract": true - } - } - ] -} \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json deleted file mode 100644 index 9f38487859..0000000000 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-MULTITHROUGHPUT.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "Description": "FIO Multi Throughput (OLTP-C) Workload", - "Metadata": { - "DiskSelectionInformation": "Sequential disk count specifies the number of disks being used for Sequential I/O from selected disks. Out of which the smallest disks are selected.", - "RecommendedMinimumExecutionTime": "02:00:00", - "SupportedPlatforms": "linux-x64,linux-arm64", - "SupportedOperatingSystems": "CBL-Mariner,CentOS,Debian,RedHat,Suse,Ubuntu,Windows" - }, - "Parameters": { - "DirectIO": true, - "DiskFilter": "BiggestSize", - "Duration": "00:03:00", - "RandomIOFileSize": "124G", - "SequentialDiskCount": "1", - "SequentialIOFileSize": "20G", - "TargetIOPS": "5000", - "TargetPercents": "10,40,90,98,100,102,110", - "Engine": "{calculate(\"{Platform}\".StartsWith(\"linux\") ? \"libaio\" : \"windowsaio\")}" - }, - "Actions": [ - { - "Type": "FioMultiThroughputExecutor", - "Parameters": { - "Scenario": "DiskFill", - "DirectIO": true, - "DiskFilter": "$.Parameters.DiskFilter", - "DiskFill": true, - "Engine": "$.Parameters.Engine", - "GroupReporting": "0", - "PackageName": "fio", - "ProcessModel": "SingleProcessPerDisk", - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "Duration": "00:10:00", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize", - "SequentialDiskCount": "$.Parameters.SequentialDiskCount", - "Tags": "IO,FIO,MultiThroughput,OLTP", - "TemplateJobFile": "oltp-c.fio.jobfile" - } - }, - { - "Type": "FioMultiThroughputExecutor", - "Parameters": { - "Scenario": "OLTP", - "PackageName": "fio", - "DirectIO": "$.Parameters.DirectIO", - "DiskFilter": "$.Parameters.DiskFilter", - "Duration": "$.Parameters.Duration", - "Engine": "$.Parameters.Engine", - "GroupReporting": "0", - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "RandomReadBlockSize": "8K", - "RandomReadNumJobs": 1, - "RandomReadQueueDepth": 512, - "RandomReadWeight": 5416, - "RandomWriteBlockSize": "8K", - "RandomWriteNumJobs": 1, - "RandomWriteQueueDepth": 512, - "RandomWriteWeight": 4255, - "SequentialDiskCount": "$.Parameters.SequentialDiskCount", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize", - "SequentialReadBlockSize": "56K", - "SequentialReadNumJobs": 1, - "SequentialReadQueueDepth": 64, - "SequentialReadWeight": 0, - "SequentialWriteBlockSize": "56K", - "SequentialWriteNumJobs": 1, - "SequentialWriteQueueDepth": 64, - "SequentialWriteWeight": 329, - "TargetIOPS": "$.Parameters.TargetIOPS", - "TargetPercents": "$.Parameters.TargetPercents", - "TemplateJobFile": "oltp-c.fio.jobfile", - "Tags": "IO,FIO,Multi-Throughput,OLTP" - } - } - ], - "Dependencies": [ - { - "Type": "LinuxPackageInstallation", - "Parameters": { - "Scenario": "InstallLinuxPackages", - "Packages-Apt": "fio", - "Packages-Dnf": "fio,lshw,parted", - "Packages-Yum": "fio", - "Packages-Zypper": "fio" - } - }, - { - "Type": "FormatDisks", - "Parameters": { - "Scenario": "InitializeDisks" - } - }, - { - "Type": "MountDisks", - "Parameters": { - "Scenario": "CreateMountPoints", - "DiskFilter": "$.Parameters.DiskFilter" - } - }, - { - "Type": "DependencyPackageInstallation", - "Parameters": { - "Scenario": "InstallFIOPackage", - "SupportedPlatforms": "win-x64", - "BlobContainer": "packages", - "BlobName": "fio.3.30.0.zip", - "PackageName": "fio", - "Extract": true - } - } - ] -} \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json index ceb9e6e66a..22efc60785 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json @@ -4,12 +4,11 @@ "RecommendedMinimumExecutionTime": "00:30:00", "SupportedPlatforms": "linux-x64,linux-arm64,win-x64", "SupportedOperatingSystems": "CBL-Mariner,CentOS,Debian,RedHat,Suse,Ubuntu,Windows", - "Notes": "This profile uses FIO job files (e.g. *.jobfile). The job file paths should be comma/semicolon-delimited under 'JobFiles'.", + "Notes": "This profile uses FIO job files (e.g. *.jobfile) via the command line.", "Documentation": "FIO documentation: https://fio.readthedocs.io/en/latest/fio_doc.html FIO Job File documentation: https://fio.readthedocs.io/en/latest/fio_doc.html#job-file-format" }, "Parameters": { - "RandomIOFileSize": "124G", - "SequentialIOFileSize": "20G", + "Engine": "{calculate(\"{Platform}\".StartsWith(\"linux\") ? \"libaio\" : \"windowsaio\")}", "DiskFilter": "BiggestSize", "ProcessModel": "SingleProcess" }, @@ -20,15 +19,12 @@ "Scenario": "DiskFill", "MetricScenario": "disk_fill", "PackageName": "fio", - "ProcessModel": "SingleProcessPerDisk", - "JobFiles": "{ScriptPath:fio}/oltp-c2-diskfill.fio.jobfile", + "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-diskfill.fio", + "Engine": "$.Parameters.Engine", "FileName": "fio-test.dat", - "DeleteTestFilesOnFinish": false, "DiskFilter": "$.Parameters.DiskFilter", - "DirectIO": 1, - "DiskFill": true, - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize" + "ProcessModel": "SingleProcessPerDisk", + "DeleteTestFilesOnFinish": false } }, { @@ -37,152 +33,12 @@ "Scenario": "FioExecutorJobFile_4K_BlockSize", "MetricScenario": "read_write_operations_4k_blocksize", "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "JobFiles": "{ScriptPath:fio}/oltp-c2-operations.fio.jobfile", - "FileName": "fio-test.dat", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "DirectIO": 1, - "DurationSec": "180", - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "RandomReadBlockSize": "4K", - "RandomReadNumJobs": 1, - "RandomWriteBlockSize": "4K", - "RandomWriteNumJobs": 1, - "SequentialDiskCount": "1", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize", - "SequentialReadBlockSize": "4K", - "SequentialReadNumJobs": 1, - "SequentialWriteBlockSize": "4K", - "SequentialWriteNumJobs": 1, - "SequentialWriteIODepth": 64, - "RandomReadIODepth": 512, - "RandomWriteIODepth": 512, - "SequentialReadIODepth": 64, - "Tags": "IO,FIO,OLTP" - } - }, - { - "Type": "FioExecutor", - "Parameters": { - "Scenario": "FioExecutorJobFile_8K_BlockSize", - "MetricScenario": "read_write_operations_8k_blocksize", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "JobFiles": "{ScriptPath:fio}/oltp-c2-operations.fio.jobfile", + "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-operations-4k.fio", + "Engine": "$.Parameters.Engine", "FileName": "fio-test.dat", - "DeleteTestFilesOnFinish": false, "DiskFilter": "$.Parameters.DiskFilter", - "DirectIO": 1, - "DurationSec": "180", - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "RandomReadBlockSize": "8K", - "RandomReadNumJobs": 1, - "RandomReadIODepth": 512, - "RandomWriteBlockSize": "8K", - "RandomWriteNumJobs": 1, - "RandomWriteIODepth": 512, - "SequentialDiskCount": "1", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize", - "SequentialReadBlockSize": "8K", - "SequentialReadNumJobs": 1, - "SequentialReadIODepth": 64, - "SequentialWriteBlockSize": "8K", - "SequentialWriteNumJobs": 1, - "SequentialWriteIODepth": 64, - "Tags": "IO,FIO,OLTP" - } - }, - { - "Type": "FioExecutor", - "Parameters": { - "Scenario": "FioExecutorJobFile_12K_BlockSize", - "MetricScenario": "read_write_operations_12k_blocksize", - "PackageName": "fio", "ProcessModel": "$.Parameters.ProcessModel", - "JobFiles": "{ScriptPath:fio}/oltp-c2-operations.fio.jobfile", - "FileName": "fio-test.dat", "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "DirectIO": 1, - "DurationSec": "180", - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "RandomReadBlockSize": "12K", - "RandomReadNumJobs": 1, - "RandomReadIODepth": 512, - "RandomWriteBlockSize": "12K", - "RandomWriteNumJobs": 1, - "RandomWriteIODepth": 512, - "SequentialDiskCount": "1", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize", - "SequentialReadBlockSize": "12K", - "SequentialReadNumJobs": 1, - "SequentialReadIODepth": 64, - "SequentialWriteBlockSize": "12K", - "SequentialWriteNumJobs": 1, - "SequentialWriteIODepth": 64, - "Tags": "IO,FIO,OLTP" - } - }, - { - "Type": "FioExecutor", - "Parameters": { - "Scenario": "FioExecutorJobFile_16K_BlockSize", - "MetricScenario": "read_write_operations_16k_blocksize", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "JobFiles": "{ScriptPath:fio}/oltp-c2-operations.fio.jobfile", - "FileName": "fio-test.dat", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "DirectIO": 1, - "DurationSec": "180", - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "RandomReadBlockSize": "16K", - "RandomReadNumJobs": 1, - "RandomReadIODepth": 512, - "RandomWriteBlockSize": "16K", - "RandomWriteNumJobs": 1, - "RandomWriteIODepth": 512, - "SequentialDiskCount": "1", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize", - "SequentialReadBlockSize": "16K", - "SequentialReadNumJobs": 1, - "SequentialReadIODepth": 64, - "SequentialWriteBlockSize": "16K", - "SequentialWriteNumJobs": 1, - "SequentialWriteIODepth": 64, - "Tags": "IO,FIO,OLTP" - } - }, - { - "Type": "FioExecutor", - "Parameters": { - "Scenario": "FioExecutorJobFile_1024K_BlockSize", - "MetricScenario": "read_write_operations_1024k_blocksize", - "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "JobFiles": "{ScriptPath:fio}/oltp-c2-operations.fio.jobfile", - "FileName": "fio-test.dat", - "DeleteTestFilesOnFinish": false, - "DiskFilter": "$.Parameters.DiskFilter", - "DirectIO": 1, - "DurationSec": "180", - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "RandomReadBlockSize": "1024K", - "RandomReadNumJobs": 1, - "RandomReadIODepth": 512, - "RandomWriteBlockSize": "1024K", - "RandomWriteNumJobs": 1, - "RandomWriteIODepth": 512, - "SequentialDiskCount": "1", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize", - "SequentialReadBlockSize": "1024K", - "SequentialReadNumJobs": 1, - "SequentialReadIODepth": 64, - "SequentialWriteBlockSize": "1024K", - "SequentialWriteNumJobs": 1, - "SequentialWriteIODepth": 64, "Tags": "IO,FIO,OLTP" } } From 5bfbd2c082f1ad0b724bcf7852eef5d6b5c7e953 Mon Sep 17 00:00:00 2001 From: saibulusu Date: Wed, 10 Sep 2025 14:43:35 -0700 Subject: [PATCH 3/7] PERF IO FIO OLTP changes --- .../FIO/oltp-c2-operations-4k.fio | 15 +++------------ .../profiles/PERF-IO-FIO-OLTP.json | 4 ++-- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio index f466058b87..8ed82d3d68 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio +++ b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio @@ -6,6 +6,9 @@ direct=1 group_reporting=0 time_based=1 +bs=4k +runtime=180 +numjobs=1 # by setting the submit mode to offload, we can guarantee a fixed rate of # submission regardless of what the device completion rate is. @@ -14,43 +17,31 @@ time_based=1 # Represents reading of data from sql/OLTP database. [randomreader] new_group -bs=4k iodepth=512 -numjobs=1 rate_iops=2708 -runtime=180 rw=randread size=124G # Represents writing of data in sql/OLTP database. [randomwriter] new_group -bs=4k iodepth=512 -numjobs=1 rate_iops=2128 -runtime=180 rw=randwrite size=124G # Represents log readers of sql/OLTP database. [sequentialreader] new_group -bs=4k iodepth=64 -numjobs=1 rate_iops=0 -runtime=180 rw=read size=20G # Represents log writers of sql/OLTP database. [sequentialwriter] new_group -bs=4k iodepth=64 -numjobs=1 rate_iops=164 -runtime=180 rw=write size=20G \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json index 22efc60785..774300b25d 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json @@ -19,7 +19,7 @@ "Scenario": "DiskFill", "MetricScenario": "disk_fill", "PackageName": "fio", - "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-diskfill.fio", + "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-diskfill.fio --output-format=json", "Engine": "$.Parameters.Engine", "FileName": "fio-test.dat", "DiskFilter": "$.Parameters.DiskFilter", @@ -33,7 +33,7 @@ "Scenario": "FioExecutorJobFile_4K_BlockSize", "MetricScenario": "read_write_operations_4k_blocksize", "PackageName": "fio", - "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-operations-4k.fio", + "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-operations-4k.fio --output-format=json", "Engine": "$.Parameters.Engine", "FileName": "fio-test.dat", "DiskFilter": "$.Parameters.DiskFilter", From 254f0306ffedb82216eb7634e1f7bb62b093fadf Mon Sep 17 00:00:00 2001 From: saibulusu Date: Thu, 11 Sep 2025 14:08:17 -0700 Subject: [PATCH 4/7] documentation changes, OLTP profile changes. --- ...perations-4k.fio => oltp-c-operations.fio} | 11 +- .../FIO/oltp-c2-diskfill.fio | 30 -- .../profiles/PERF-IO-FIO-OLTP.json | 18 +- website/docs/workloads/fio/fio-profiles.md | 316 ------------------ 4 files changed, 11 insertions(+), 364 deletions(-) rename src/VirtualClient/VirtualClient.Actions/FIO/{oltp-c2-operations-4k.fio => oltp-c-operations.fio} (87%) delete mode 100644 src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio similarity index 87% rename from src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio rename to src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio index 8ed82d3d68..7bac772037 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations-4k.fio +++ b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio @@ -6,7 +6,6 @@ direct=1 group_reporting=0 time_based=1 -bs=4k runtime=180 numjobs=1 @@ -18,30 +17,22 @@ numjobs=1 [randomreader] new_group iodepth=512 -rate_iops=2708 rw=randread -size=124G # Represents writing of data in sql/OLTP database. [randomwriter] new_group iodepth=512 -rate_iops=2128 rw=randwrite -size=124G # Represents log readers of sql/OLTP database. [sequentialreader] new_group iodepth=64 -rate_iops=0 rw=read -size=20G # Represents log writers of sql/OLTP database. [sequentialwriter] new_group iodepth=64 -rate_iops=164 -rw=write -size=20G \ No newline at end of file +rw=write \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio deleted file mode 100644 index ff472f4f15..0000000000 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio +++ /dev/null @@ -1,30 +0,0 @@ -# fio template for OLTP-C runs -# defines three components: readers, writes, and loggers - -# --------------- Global section defines defaults across all components -[global] -direct=1 -group_reporting=0 -time_based=1 - -# by setting the submit mode to offload, we can guarantee a fixed rate of -# submission regardless of what the device completion rate is. -#io_submit_mode=offload - -# Initialize database data. -[initrandomio] -new_group -bs=256K -iodepth=64 -numjobs=1 -rw=write -size=124G - -# Initialize logs database. -[initsequentialio] -new_group -bs=256K -iodepth=64 -numjobs=1 -rw=write -size=20G \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json index 774300b25d..a1afc663e4 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json @@ -9,8 +9,9 @@ }, "Parameters": { "Engine": "{calculate(\"{Platform}\".StartsWith(\"linux\") ? \"libaio\" : \"windowsaio\")}", - "DiskFilter": "BiggestSize", - "ProcessModel": "SingleProcess" + "DiskFillSize": "200G", + "FileSize": "124G", + "DiskFilter": "BiggestSize" }, "Actions": [ { @@ -19,10 +20,11 @@ "Scenario": "DiskFill", "MetricScenario": "disk_fill", "PackageName": "fio", - "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-diskfill.fio --output-format=json", - "Engine": "$.Parameters.Engine", - "FileName": "fio-test.dat", "DiskFilter": "$.Parameters.DiskFilter", + "CommandLine": "--name=disk_fill --size={DiskFillSize} --numjobs=1 --rw=write --bs=256k --iodepth=64 --ioengine={Engine} --direct=1 --overwrite=1 --thread", + "Engine": "$.Parameters.Engine", + "DiskFill": true, + "DiskFillSize": "$.Parameters.DiskFillSize", "ProcessModel": "SingleProcessPerDisk", "DeleteTestFilesOnFinish": false } @@ -33,11 +35,11 @@ "Scenario": "FioExecutorJobFile_4K_BlockSize", "MetricScenario": "read_write_operations_4k_blocksize", "PackageName": "fio", - "CommandLine": "--ioengine={Engine} {ScriptPath:fio}/oltp-c2-operations-4k.fio --output-format=json", + "CommandLine": "--bs=4k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", "Engine": "$.Parameters.Engine", - "FileName": "fio-test.dat", + "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", - "ProcessModel": "$.Parameters.ProcessModel", + "ProcessModel": "SingleProcess", "DeleteTestFilesOnFinish": false, "Tags": "IO,FIO,OLTP" } diff --git a/website/docs/workloads/fio/fio-profiles.md b/website/docs/workloads/fio/fio-profiles.md index 84bcb724dc..2d84a7d8dc 100644 --- a/website/docs/workloads/fio/fio-profiles.md +++ b/website/docs/workloads/fio/fio-profiles.md @@ -159,322 +159,6 @@ aspects of the workload execution. ./VirtualClient --profile=PERF-IO-FIO.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --scenarios=RandomWrite_4k_BlockSize,RandomWrite_8k_BlockSize,RandomRead_8k_BlockSize,RandomRead_4k_BlockSize ``` -## PERF-IO-FIO-DISCOVERY.json -Runs an IO-intensive workload using the Flexible IO Tester (FIO) toolset. FIO Discovery measures throughput as a function of increasing queue depth for multiple operation -types(Random Read,Random Write,Sequential Write & Sequential Read) and block sizes. The workload runs directly against the raw disks without having the file system involved -(e.g. /dev/sda, /dev/sdc). - -This profile uses an algorithm to determine the total number of jobs/threads as well as queue depth for each job/thread. - -* Total number of jobs/threads = Minimum(ScenarioQueueDepth, MaxThreadsThreshold). These 2 parameters are described below. - - ``` script - Examples: - For ScenarioQueueDepth = 1, MaxThreadsThreshold = 4: - Total number of jobs/threads = Minimum(1,4) = 1 - - For ScenarioQueueDepth = 16, MaxThreadsThreshold = 4: - Total number of jobs/threads = Minimum(16,4) = 4 - ``` - -* Queue Depth per Thread = (ScenarioQueueDepth + Threads - 1) / Threads where Threads = Total number of jobs/threads - - ``` script - Examples: - For ScenarioQueueDepth = 16, Threads = 5: - Queue Depth per Thread = (16 + 5 -1)/5 = 4 - - For ScenarioQueueDepth = 16, MaxThreadsThreshold = 6: - Queue Depth per Thread = (16 + 6 -1)/6 ~= 3 [Round down to closest integer] - ``` - -* **Supported Platform/Architectures** - * linux-x64 - * linux-arm64 - * win-x64 - -* **Supported Operating Systems** - * Ubuntu 18 - * Ubuntu 20 - * Ubuntu 22 - * Ubuntu 24 - * Azlinux 3 - -* **Dependencies** - The dependencies defined in the 'Dependencies' section of the profile itself are required in order to run the workload operations effectively. - * Internet connection. - * Disk mount points exist for the disks to be targeted. Virtual Client will generally ensure that mount points exist by default. Details for mount point creation procedures can be found in the 'Testing Disks' documentation above. - * Any 'DiskFilter' parameter value used should match the set of disks desired. See the link for 'Testing Disks' above. - - Additional information on components that exist within the 'Dependencies' section of the profile can be found in the following locations: - * [Installing Dependencies](https://microsoft.github.io/VirtualClient/docs/category/dependencies/) - -* **Scenarios** - The following scenarios are covered by this workload profile. For each one of the scenarios, the profile runs the workload through the range of - queue depths noted (by default) in sequence. - - * Random Write Operations - * 4k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 8k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 16k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 64k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 256k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 1024k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * Random Read Operations - * 4k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 8k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 16k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 64k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 256k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 1024k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * Sequential Write Operations - * 4k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 8k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 16k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 64k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 256k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 1024k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * Sequential Read Operations - * 4k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 8k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 16k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 64k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 256k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - * 1024k block size, queue depths [1,4,16,64,256,1024], multiple jobs/threads per disk - -* **Profile Parameters** - The following parameters can be optionally supplied on the command line to modify the behaviors of the workload. - - | Parameter | Purpose | Default Value | - |---------------------------|---------------------------------------------------------------------------------|---------------| - | DiskFilter | Optional. Filter allowing the user to select the disks on which to test.

See '[disk testing scenarios](https://github.com/microsoft/VirtualClient/blob/main/website/docs/guides/usage-scenarios/test-disks.md)' for more details. | BiggestSize | - | DiskFillSize | Optional. Allows the user to override the default disk fill size used in the FIO profile (e.g. 134GB -> 26GB). This enables the profile to be used in scenarios where the disk size is very small (e.g. local/temp disk -> 32GB in size). | 134GB | - | Engine | Optional. Defines the I/O engine to use for the FIO operations (e.g. posixaio, libaio, windowsaio). | Linux = libaio, Windows = windowsaio | - | FileSize | Optional. Allows the user to override the default file size used in the FIO profile (e.g. 134GB -> 26GB). This enables the profile to be used in scenarios where the disk size is very small (e.g. local/temp disk -> 32GB in size). | 134GB | - | ProcessModel | Optional. Allows the user to override the default value you can selection Single Process for all disk(SingleProcess) or 1 process for each disk under test (SingleProcessPerDisk). | SingleProcess | - | MaxThreads | Optional. Allows the user to override the maximum number of threads used by FIO. | # of logical processors | - | ProcessModel | Optional. Defines how the FIO processes will be executed. The following are valid process models:

SingleProcess
Executes a single FIO process running 1 job targeting I/O operations against each disk. Results are separated per-disk.

SingleProcessPerDisk
Executes a single FIO process for each disk with each process running 1 job targeting I/O operations against that disk (higher stress profile). Results are separated per-disk.

SingleProcessAggregated
Executes a single FIO process running 1 job per disk targeting I/O operations against that disk. Results are provided as an aggregation across all disks (i.e. a rollup). | SingleProcess | - | QueueDepths | Optional. Allows the user to override the a comma seperated list of queuedepths to iterate. A single queueDepth can be named as ScenarioQueueDepth | "1,4,16,64,256,1024" | - | DirectIO | Optional. Set to true to use hardware I/O buffering and false to operate directly against the disk without any hardware buffering/caching (i.e. pure disk). | true | - | InitializeDisksInParallel | Optional. Specifies whether uninitialized/unformatted disks on the system should be initialized + formatted in parallel. | true (initialized in-parallel) | - -* **Profile Component Parameters** - The following section describes the parameters used by the individual components in the profile. - - | Parameter | Purpose | Accepted Values | - |---------------------------|-------------------------------------------------------------------------------|-----------------| - | Scenario | Scenario use to define the given action of profile. This can be used to specify exact actions to run or exclude from the profile. | Any string | - | CommandLine | The command line parameters for FIO tool set. | valid FIO arguments | - | BlockSize | The block size for FIO tool set. | 4k;8k;16k | - | DirectIO | Set to true to use hardware I/O buffering and false to operate directly against the disk without any hardware buffering/caching (i.e. pure disk). | true | - | Duration | Defines the amount of time to run each FIO scenario/action within the profile. | integer or time span | - | Engine | Defines the I/O engine to use for the FIO operations (e.g. posixaio, libaio, windowsaio). | Linux = libaio, Windows = windowsaio | - | IOType | Type of Input Output operation | randread, randwrite, read, write | - | MaxThreads | Allows the user to override the maximum number of threads used by FIO per job. | integer | - | PackageName | The logical name for FIO package downloaded and that contains the toolset. | fio | - | ProcessModel | Defines how the FIO processes will be executed. | SingleProcess
Executes a single FIO process running 1 job targeting I/O operations against each disk. Results are separated per-disk.

SingleProcessPerDisk
Executes a single FIO process for each disk with each process running 1 job targeting I/O operations against that disk (higher stress profile). Results are separated per-disk.

SingleProcessAggregated
Executes a single FIO process running 1 job per disk targeting I/O operations against that disk. Results are provided as an aggregation across all disks (i.e. a rollup). | - | QueueDepths | Allows the user to override the a comma seperated list of queuedepths to iterate. A single queueDepth can be named as ScenarioQueueDepth | "1,4,16,64,256,1024" | - | Tags | Tags useful for telemetry data | Any comma-separated string | - -* **Profile Runtimes** - See the 'Metadata' section of the profile for estimated runtimes. These timings represent the length of time required to run a single round of profile - actions. These timings can be used to determine minimum required runtimes for the Virtual Client in order to get results. These are often estimates based on the - number of system cores. - -* **Usage Examples** - The following section provides a few basic examples of how to use the workload profile. - - ``` bash - # Run the workload on the system (default = largest disks) - ./VirtualClient --profile=PERF-IO-FIO-DISCOVERY.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" - - # The example above runs on the same disks as having DiskFilter=BiggestSize - ./VirtualClient --profile=PERF-IO-FIO-DISCOVERY.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=BiggestSize - - # Run the workload against the operating system disk - ./VirtualClient --profile=PERF-IO-FIO-DISCOVERY.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=OSDisk - - # Run the workload against all of the disks except the operating system disk. - ./VirtualClient --profile=PERF-IO-FIO-DISCOVERY.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=OSDisk:false - - # Run the workload on specific drives/disks - ./VirtualClient --profile=PERF-IO-FIO-DISCOVERY.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=DiskPath:/dev/sdc1,/dev/sdd1 - - # Run against smaller disks on the system - ./VirtualClient --profile=PERF-IO-FIO-DISCOVERY.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=OSDisk:false&smallestSize,,,DiskFillSize=26G,,,FileSize=26G - - # Override the default queue depths - ./VirtualClient --profile=PERF-IO-FIO-DISCOVERY.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters="QueueDepths="4,16,256" - ``` - ------------------------------------------------------------------------ - -## PERF-IO-FIO-MULTITHROUGHPUT.json -Runs an IO-intensive workload using the Flexible IO Tester (FIO) toolset. Multi-throughput OLTP-C workload to emulate a SQL Server OLTP disk -workload by running four workload compononents in-parallel: random reads, random writes, sequential reads and sequential writes each with an overall -weight/percentage defined. -A weight of 0 for and of the workload components will cause that component to be excluded from the overall operations. - -Random IO : It represents the Database of OLTP-C workload. -Sequential IO : It represents the logs of OLTP-C workload. -Therefore, they are performed on different disks - -The workload runs directly against the raw disks without having the file system involved (e.g. /dev/sda, /dev/sdc); - -This profile uses an algorithm to determine the amount of IOPS to run against the disks & Random IO ,Sequential IO Disks: - -* Number of disks used to Perform Sequential I/O = Sequential Disks Count (Smallest Disks) -* Number of disks used to Perform Random I/O = Total Filtered Disks - Sequential Disks Count - - ``` script - Example 1: - Given Disks Matching 'DiskFilter' = [(/dev/sda1 = 1TB), (/dev/sdb1 = 64GB), (/dev/sdc1 = 1TB)] - Sequential Disks Count = 1 - - Disk Used to Perform Random I/O = (/dev/sdc1 = 1TB, /dev/sda1 = 1TB) - - Disk Used to Perform Sequential I/O = (/dev/sdb1 = 64GB) - - Example 2: - Given Disks Matching 'DiskFilter' = [(/dev/sda1 = 1TB), (/dev/sdb1 = 2TB), (/dev/sdc1 = 4TB)] - Sequential Disks Count = 2 - - Disk Used to Perform Random I/O = (/dev/sdc1 = 4TB ) - - Disk Used to Perform Sequential I/O = (/dev/sdb1 = 2TB, /dev/sda1 = 1TB) - ``` - -* Total IOPS = (TargetIOPS * ScenarioTargetPercentage)/100 (parameters described below). - - ``` script - Example 1: - For Target IOPS = 5000, Scenario Target Percentage = 10 - - Total IOPS = (5000 x 10)/100 = 500 - - Example 2: - For Target IOPS = 5555, Scenario Target Percentage = 10 - - Total IOPS = (5555 x 10)/100 = 555 - ``` - -* Component IOPS = ((Total IOPS) * (Component Weight))/(Total Weight) - - ``` script - Examples: - For Total IOPS = 1200, Random Read Weight = 40, Random Write Weight = 40, Sequential Read Weight = 0 , Sequential Write Weight = 40 - - Random Read IOPS = (1200 * 40)/(40+40+0+40) = 400 - - Random Write IOPS = (1200 * 40)/(40+40+0+40) = 400 - - Sequential Read IOPS = (1200 * 0)/(40+40+0+40) = 0 - - Sequential Write IOPS = (1200 * 40)/(40+40+0+40) = 400 - ``` - -* **Supported Platform/Architectures** - * linux-x64 - * linux-arm64 - * win-x64 - -* **Supported Operating Systems** - * Ubuntu 18 - * Ubuntu 20 - * Ubuntu 22 - * Ubuntu 24 - * Azlinux 3 - -* **Dependencies** - The dependencies defined in the 'Dependencies' section of the profile itself are required in order to run the workload operations effectively. - * Internet connection. - * Disk mount points exist for the disks to be targeted. Virtual Client will generally ensure that mount points exist by default. Details for mount point creation procedures can be found in the 'Testing Disks' documentation above. - * Any 'DiskFilter' parameter value used should match the set of disks desired. See the link for 'Testing Disks' above. - - Additional information on components that exist within the 'Dependencies' section of the profile can be found in the following locations: - * [Installing Dependencies](https://microsoft.github.io/VirtualClient/docs/category/dependencies/) - -* **Scenarios** - The following scenarios are covered by this workload profile. - - * 10 target percentage, totalIOPS 500, Random read & write jobs on RandomIODisk & Sequential read & write jobs on SequentialIODisk - * 40 target percentage, totalIOPS 2000, Random read & write jobs on RandomIODisk & Sequential read & write jobs on SequentialIODisk - * 90 target percentage, totalIOPS 4500, Random read & write jobs on RandomIODisk & Sequential read & write jobs on SequentialIODisk - * 98 target percentage, totalIOPS 4900, Random read & write jobs on RandomIODisk & Sequential read & write jobs on SequentialIODisk - * 100 target percentage, totalIOPS 5000, Random read & write jobs on RandomIODisk & Sequential read & write jobs on SequentialIODisk - * 102 target percentage, totalIOPS 5100, Random read & write jobs on RandomIODisk & Sequential read & write jobs on SequentialIODisk - * 110 target percentage, totalIOPS 5100, Random read & write jobs on RandomIODisk & Sequential read & write jobs on SequentialIODisk - -* **Profile Parameters** - The following parameters can be optionally supplied on the command line to modify the behaviors of the workload. - - | Parameter | Purpose | Default Value | - |---------------------------|---------------------------------------------------------------------------------|---------------| - | DefaultNumJobs | Optional. Allows the user to override Number of jobs for each component (Random read component,Random write component,Sequential read component,Sequential write component) | 1 | - | DiskFilter | Disk filter to choose disks. Default is to test on biggest non-OS disks. | BiggestSize | - | RandomIOFileSize | Optional. Allows the user to override the default random io file size used in the profile (e.g. 124GB -> 26GB). This enables the profile to be used in scenarios where the disk size is very small (e.g. local/temp disk -> 32GB in size). | 124GB | - | SequentialIOFileSize | Optional. Allows the user to override the default random io file size used in the profile. | 20GB | - | TargetIOPS | Optional. Allows the user to override the default value for Target IOPS for all the components combined. | 5000 | - | TargetPercents | Optional. Allows the user to override the target percent list which is use to determine Total IOPS. | "10,40,90,98,100,102,110" | - | DirectIO | Optional. Set to true to avoid using I/O buffering and to operate directly against the disk. Set to false to use I/O buffering. | true | - | InitializeDisksInParallel | Optional. Specifies whether uninitialized/unformatted disks on the system should be initialized + formatted in parallel. | true (initialized in-parallel) | - | SequentialDiskCount | Optional. Specifies the number of disk that will have Sequential I/O from Selected Disks. | 1 | - - -* **Profile Component Parameters** - The following section describes the parameters used by the individual components in the profile. - - | Parameter | Purpose | Profile Values | - |---------------------------|---------------------------------------------------------------------------------|-----------------| - | DefaultRandomIOBlockSize | Default Block size value for Random Read and Write. | 8k | - | DefaultRandomIOQueueDepth | Default QueueDepth value for Random Read and Write. | 512 | - | DefaultSequentialIOBlockSize | Default Block size value for Sequential Read and Write. | 56K| - | DefaultSequentialIOQueueDepth | Default Queue Depth value for Sequential Read and Write.| 64| - | DirectIO | Direct IO parameter for FIO toolset |"1"| - | GroupReporting | Group Reporting parameter for FIO toolset| "0" | - | RandomReadBlockSize | Random read component's Block size. If it is provided it overwrites the DefaultRandomIOBlockSize for Random read component. | null | - | RandomReadNumJobs | Random read component's Number of jobs. If it is provided it overwrites the DefaultNumJobs for Random read component. | null | - | RandomReadQueueDepth | Random read component's Queue Depth. If it is provided it overwrites the DefaultRandomIOQueueDepth for Random read component. | null | - | RandomReadWeight | Weight of Random read component being use to calculate the IOPS of random read component. | 5416 | - | RandomWriteBlockSize | Random write component's Block size. If it is provided it overwrites the DefaultRandomIOBlockSize for Random write component. | null | - | RandomWriteNumJobs | Random write component's Number of jobs. If it is provided it overwrites the DefaultNumJobs for Random write component. | null | - | RandomWriteQueueDepth | Random write component's Queue Depth. If it is provided it overwrites the DefaultRandomIOQueueDepth for Random write component. | null | - | RandomWriteWeight | Weight of Random write component being use to calculate the IOPS of random write component. | 4255 | - | SequentialReadBlockSize | Sequential read component's Block size. If it is provided it overwrites the DefaultSequentialIOBlockSize for Sequential read component. | null | - | SequentialReadNumJobs | Sequential read component's Number of jobs. If it is provided it overwrites the DefaultNumJobs for Sequential read component. | null | - | SequentialReadQueueDepth | Sequential read component's Queue Depth. If it is provided it overwrites the DefaultSequentialIOQueueDepth for Sequential read component. | null | - | SequentialReadWeight | Weight of Sequential read component being use to calculate the IOPS of random read component. | 0 | - | SequentialWriteBlockSize | Sequential write component's Block size. If it is provided it overwrites the DefaultSequentialIOBlockSize for Sequential write component. | null | - | SequentialWriteNumJobs | Sequential write component's Number of jobs. If it is provided it overwrites the DefaultNumJobs for Sequential write component. | null | - | SequentialWriteQueueDepth | Sequential write component's Queue Depth. If it is provided it overwrites the DefaultSequentialIOQueueDepth for Sequential write component. | null | - | SequentialWriteWeight | Weight of Sequential write component being use to calculate the IOPS of random write component. | 329 | - | DurationSec | Type of Input Output operation | 300 | - | TemplateJobFile | File name for the template job file.| oltp-c.fio.jobfile | - | Scenario | Scenario use to define the given action of profile | fio_multithroughput | - | Tags | Tags usefull for telemetry data | IO,FIO,MultiThroughput,OLTP | - -* **Profile Runtimes** - See the 'Metadata' section of the profile for estimated runtimes. These timings represent the length of time required to run a single round of profile - actions. These timings can be used to determine minimum required runtimes for the Virtual Client in order to get results. These are often estimates based on the - number of system cores. - -* **Usage Examples** - The following section provides a few basic examples of how to use the workload profile. - - ``` bash - # Run the workload on the system (default = largest disks) - ./VirtualClient --profile=PERF-IO-FIO-MULTITHROUGHPUT.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" - - # The example above runs on the same disks as having DiskFilter=BiggestSize - ./VirtualClient --profile=PERF-IO-FIO-MULTITHROUGHPUT.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=BiggestSize - - # Run the workload against the operating system disk - ./VirtualClient --profile=PERF-IO-FIO-MULTITHROUGHPUT.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=OSDisk - - # Run the workload against all of the disks except the operating system disk. - ./VirtualClient --profile=PERF-IO-FIO-MULTITHROUGHPUT.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=OSDisk:false - - # Run the workload on specific drives/disks - ./VirtualClient --profile=PERF-IO-FIO-MULTITHROUGHPUT.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=DiskPath:/dev/sdc1,/dev/sdd1 - - # Run against smaller disks on the system - ./VirtualClient --profile=PERF-IO-FIO-MULTITHROUGHPUT.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters=DiskFilter=OSDisk:false&smallestSize,,,DiskFillSize=26G,,,FileSize=26G - - # Override the default target percentages - ./VirtualClient --profile=PERF-IO-FIO-MULTITHROUGHPUT.json --system=Demo --timeout=1440 --packageStore="{BlobConnectionString|SAS Uri}" --parameters="TargetPercents="40,80,120" - ``` - - ----------------------------------------------------------------------- ## PERF-IO-FIO-OLTP.json From 94b404056483e4a2b6ed2cf89fc29c4fca7276ee Mon Sep 17 00:00:00 2001 From: saibulusu Date: Thu, 11 Sep 2025 14:11:16 -0700 Subject: [PATCH 5/7] More block sizes for OLTP profile. --- .../profiles/PERF-IO-FIO-OLTP.json | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json index a1afc663e4..5dd4b3d45a 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json @@ -43,6 +43,66 @@ "DeleteTestFilesOnFinish": false, "Tags": "IO,FIO,OLTP" } + }, + { + "Type": "FioExecutor", + "Parameters": { + "Scenario": "FioExecutorJobFile_8K_BlockSize", + "MetricScenario": "read_write_operations_8k_blocksize", + "PackageName": "fio", + "CommandLine": "--bs=8k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Engine": "$.Parameters.Engine", + "FileSize": "$.Parameters.FileSize", + "DiskFilter": "$.Parameters.DiskFilter", + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, + "Tags": "IO,FIO,OLTP" + } + }, + { + "Type": "FioExecutor", + "Parameters": { + "Scenario": "FioExecutorJobFile_12K_BlockSize", + "MetricScenario": "read_write_operations_12k_blocksize", + "PackageName": "fio", + "CommandLine": "--bs=12k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Engine": "$.Parameters.Engine", + "FileSize": "$.Parameters.FileSize", + "DiskFilter": "$.Parameters.DiskFilter", + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, + "Tags": "IO,FIO,OLTP" + } + }, + { + "Type": "FioExecutor", + "Parameters": { + "Scenario": "FioExecutorJobFile_16K_BlockSize", + "MetricScenario": "read_write_operations_16k_blocksize", + "PackageName": "fio", + "CommandLine": "--bs=16k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Engine": "$.Parameters.Engine", + "FileSize": "$.Parameters.FileSize", + "DiskFilter": "$.Parameters.DiskFilter", + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, + "Tags": "IO,FIO,OLTP" + } + }, + { + "Type": "FioExecutor", + "Parameters": { + "Scenario": "FioExecutorJobFile_1024K_BlockSize", + "MetricScenario": "read_write_operations_1024k_blocksize", + "PackageName": "fio", + "CommandLine": "--bs=1024k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Engine": "$.Parameters.Engine", + "FileSize": "$.Parameters.FileSize", + "DiskFilter": "$.Parameters.DiskFilter", + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, + "Tags": "IO,FIO,OLTP" + } } ], "Dependencies": [ From 2e228edfcbecbb577e29f61a9edaa3b3bb295e7e Mon Sep 17 00:00:00 2001 From: saibulusu Date: Thu, 11 Sep 2025 15:38:06 -0700 Subject: [PATCH 6/7] Moving parameters to command line. --- .../VirtualClient.Actions/FIO/oltp-c-operations.fio | 5 ----- .../VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json | 10 +++++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio index 7bac772037..7533f357f1 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio +++ b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio @@ -6,7 +6,6 @@ direct=1 group_reporting=0 time_based=1 -runtime=180 numjobs=1 # by setting the submit mode to offload, we can guarantee a fixed rate of @@ -16,23 +15,19 @@ numjobs=1 # Represents reading of data from sql/OLTP database. [randomreader] new_group -iodepth=512 rw=randread # Represents writing of data in sql/OLTP database. [randomwriter] new_group -iodepth=512 rw=randwrite # Represents log readers of sql/OLTP database. [sequentialreader] new_group -iodepth=64 rw=read # Represents log writers of sql/OLTP database. [sequentialwriter] new_group -iodepth=64 rw=write \ No newline at end of file diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json index 5dd4b3d45a..6d74cf6ed3 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json @@ -35,7 +35,7 @@ "Scenario": "FioExecutorJobFile_4K_BlockSize", "MetricScenario": "read_write_operations_4k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=4k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=4k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -50,7 +50,7 @@ "Scenario": "FioExecutorJobFile_8K_BlockSize", "MetricScenario": "read_write_operations_8k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=8k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=8k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -65,7 +65,7 @@ "Scenario": "FioExecutorJobFile_12K_BlockSize", "MetricScenario": "read_write_operations_12k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=12k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=12k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -80,7 +80,7 @@ "Scenario": "FioExecutorJobFile_16K_BlockSize", "MetricScenario": "read_write_operations_16k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=16k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=16k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -95,7 +95,7 @@ "Scenario": "FioExecutorJobFile_1024K_BlockSize", "MetricScenario": "read_write_operations_1024k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=1024k --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=1024k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", From bf3cb183a97ad2ccdc92c03e7f9f12f88605d397 Mon Sep 17 00:00:00 2001 From: saibulusu Date: Thu, 11 Sep 2025 15:41:34 -0700 Subject: [PATCH 7/7] Using duration.totalseconds. --- .../profiles/PERF-IO-FIO-OLTP.json | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json index 6d74cf6ed3..9cf4c5b2c9 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json @@ -10,6 +10,7 @@ "Parameters": { "Engine": "{calculate(\"{Platform}\".StartsWith(\"linux\") ? \"libaio\" : \"windowsaio\")}", "DiskFillSize": "200G", + "Duration": "00:03:00", "FileSize": "124G", "DiskFilter": "BiggestSize" }, @@ -35,7 +36,8 @@ "Scenario": "FioExecutorJobFile_4K_BlockSize", "MetricScenario": "read_write_operations_4k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=4k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=4k --runtime={Duration.TotalSeconds} --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Duration": "$.Parameters.Duration", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -50,7 +52,8 @@ "Scenario": "FioExecutorJobFile_8K_BlockSize", "MetricScenario": "read_write_operations_8k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=8k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=8k --runtime={Duration.TotalSeconds} --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Duration": "$.Parameters.Duration", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -65,7 +68,8 @@ "Scenario": "FioExecutorJobFile_12K_BlockSize", "MetricScenario": "read_write_operations_12k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=12k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=12k --runtime={Duration.TotalSeconds} --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Duration": "$.Parameters.Duration", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -80,7 +84,8 @@ "Scenario": "FioExecutorJobFile_16K_BlockSize", "MetricScenario": "read_write_operations_16k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=16k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=16k --runtime={Duration.TotalSeconds} --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Duration": "$.Parameters.Duration", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter", @@ -95,7 +100,8 @@ "Scenario": "FioExecutorJobFile_1024K_BlockSize", "MetricScenario": "read_write_operations_1024k_blocksize", "PackageName": "fio", - "CommandLine": "--bs=1024k --runtime=180 --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "CommandLine": "--bs=1024k --runtime={Duration.TotalSeconds} --iodepth=512 --size={FileSize} --ioengine={Engine} {ScriptPath:fio}/oltp-c-operations.fio --output-format=json", + "Duration": "$.Parameters.Duration", "Engine": "$.Parameters.Engine", "FileSize": "$.Parameters.FileSize", "DiskFilter": "$.Parameters.DiskFilter",