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 f13f6cec07..f9e78b23eb 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 { /// @@ -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-c2-diskfill.fio.jobfile b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio similarity index 53% rename from src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio.jobfile rename to src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio index 39ec037622..7533f357f1 100644 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-diskfill.fio.jobfile +++ b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c-operations.fio @@ -3,28 +3,31 @@ # --------------- Global section defines defaults across all components [global] -direct=${directio} +direct=1 group_reporting=0 time_based=1 +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. #io_submit_mode=offload -# Initialize database data. -[initrandomio] +# Represents reading of data from sql/OLTP database. +[randomreader] new_group -bs=256K -iodepth=64 -numjobs=1 -rw=write -size=${randomiofilesize} +rw=randread -# Initialize logs database. -[initsequentialio] +# Represents writing of data in sql/OLTP database. +[randomwriter] new_group -bs=256K -iodepth=64 -numjobs=1 -rw=write -size=${sequentialiofilesize} \ No newline at end of file +rw=randwrite + +# Represents log readers of sql/OLTP database. +[sequentialreader] +new_group +rw=read + +# Represents log writers of sql/OLTP database. +[sequentialwriter] +new_group +rw=write \ 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-operations.fio.jobfile b/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations.fio.jobfile deleted file mode 100644 index e85733d7bd..0000000000 --- a/src/VirtualClient/VirtualClient.Actions/FIO/oltp-c2-operations.fio.jobfile +++ /dev/null @@ -1,56 +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} -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 - -# Represents reading of data from sql/OLTP database. -[randomreader] -new_group -bs=${randomreadblocksize} -iodepth=${randomreadiodepth} -numjobs=${randomreadnumjobs} -rate_iops=2708 -runtime=${duration} -rw=randread -size=${randomiofilesize} - -# Represents writing of data in sql/OLTP database. -[randomwriter] -new_group -bs=${randomwriteblocksize} -iodepth=${randomwriteiodepth} -numjobs=${randomwritenumjobs} -rate_iops=2128 -runtime=${duration} -rw=randwrite -size=${randomiofilesize} - -# Represents log readers of sql/OLTP database. -[sequentialreader] -new_group -bs=${sequentialreadblocksize} -iodepth=${sequentialreadiodepth} -numjobs=${sequentialreadnumjobs} -rate_iops=0 -runtime=${duration} -rw=read -size=${sequentialiofilesize} - -# Represents log writers of sql/OLTP database. -[sequentialwriter] -new_group -bs=${sequentialwriteblocksize} -iodepth=${sequentialwriteiodepth} -numjobs=${sequentialwritenumjobs} -rate_iops=164 -runtime=${duration} -rw=write -size=${sequentialiofilesize} \ 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 bd159a855e..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,win-x64", - "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 dc86616a1f..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,win-x64", - "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..9cf4c5b2c9 100644 --- a/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json +++ b/src/VirtualClient/VirtualClient.Main/profiles/PERF-IO-FIO-OLTP.json @@ -4,14 +4,15 @@ "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", - "DiskFilter": "BiggestSize", - "ProcessModel": "SingleProcess" + "Engine": "{calculate(\"{Platform}\".StartsWith(\"linux\") ? \"libaio\" : \"windowsaio\")}", + "DiskFillSize": "200G", + "Duration": "00:03:00", + "FileSize": "124G", + "DiskFilter": "BiggestSize" }, "Actions": [ { @@ -20,15 +21,13 @@ "Scenario": "DiskFill", "MetricScenario": "disk_fill", "PackageName": "fio", - "ProcessModel": "SingleProcessPerDisk", - "JobFiles": "{ScriptPath:fio}/oltp-c2-diskfill.fio.jobfile", - "FileName": "fio-test.dat", - "DeleteTestFilesOnFinish": false, "DiskFilter": "$.Parameters.DiskFilter", - "DirectIO": 1, + "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, - "RandomIOFileSize": "$.Parameters.RandomIOFileSize", - "SequentialIOFileSize": "$.Parameters.SequentialIOFileSize" + "DiskFillSize": "$.Parameters.DiskFillSize", + "ProcessModel": "SingleProcessPerDisk", + "DeleteTestFilesOnFinish": false } }, { @@ -37,28 +36,13 @@ "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, + "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", - "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, + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, "Tags": "IO,FIO,OLTP" } }, @@ -68,28 +52,13 @@ "Scenario": "FioExecutorJobFile_8K_BlockSize", "MetricScenario": "read_write_operations_8k_blocksize", "PackageName": "fio", - "ProcessModel": "$.Parameters.ProcessModel", - "JobFiles": "{ScriptPath:fio}/oltp-c2-operations.fio.jobfile", - "FileName": "fio-test.dat", - "DeleteTestFilesOnFinish": false, + "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", - "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, + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, "Tags": "IO,FIO,OLTP" } }, @@ -99,28 +68,13 @@ "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, + "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", - "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, + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, "Tags": "IO,FIO,OLTP" } }, @@ -130,28 +84,13 @@ "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, + "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", - "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, + "ProcessModel": "SingleProcess", + "DeleteTestFilesOnFinish": false, "Tags": "IO,FIO,OLTP" } }, @@ -161,28 +100,13 @@ "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, + "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", - "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, + "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