Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieving Disk Paths via DiskManager #440

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void SetupTest()

this.disks = this.mockFixture.CreateDisks(PlatformID.Unix, true);

this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny<CancellationToken>())).ReturnsAsync(() => this.disks);
this.mockFixture.DiskManager.Setup(mgr => mgr.GetDisksAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(() => this.disks);
this.mockFixture.PackageManager.OnGetPackage().ReturnsAsync(new DependencyPath("fio", this.mockFixture.GetPackagePath("fio")));
this.mockFixture.File.OnFileExists().Returns(true);
this.mockFixture.File.Setup(file => file.ReadAllText(It.IsAny<string>())).Returns(string.Empty);
Expand Down Expand Up @@ -223,39 +223,6 @@ public void FioExecutorAppliesConfigurationParametersCorrectly_DiskFillScenario(
}
}

[Test]
public async Task FioExecutorCreatesExpectedMountPointsForDisksUnderTest_RemoteDiskScenario()
{
// Clear any access points out.
this.disks.ToList().ForEach(disk => disk.Volumes.ToList().ForEach(vol => (vol.AccessPaths as List<string>).Clear()));

List<Tuple<DiskVolume, string>> mountPointsCreated = new List<Tuple<DiskVolume, string>>();

this.mockFixture.DiskManager
.Setup(mgr => mgr.CreateMountPointAsync(It.IsAny<DiskVolume>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
.Callback<DiskVolume, string, CancellationToken>((volume, mountPoint, token) =>
{
(volume.AccessPaths as List<string>).Add(mountPoint);
})
.Returns(Task.CompletedTask);

using (TestFioExecutor workloadExecutor = new TestFioExecutor(this.mockFixture.Dependencies, this.profileParameters))
{
await workloadExecutor.ExecuteAsync(CancellationToken.None);

Assert.IsTrue(this.disks.Skip(1).All(d => d.Volumes.First().AccessPaths?.Any() == true));

string expectedMountPoint1 = Path.Combine(MockFixture.TestAssemblyDirectory, "vcmnt_dev_sdd1");
Assert.AreEqual(expectedMountPoint1, this.disks.ElementAt(1).Volumes.First().AccessPaths.First());

string expectedMountPoint2 = Path.Combine(MockFixture.TestAssemblyDirectory, "vcmnt_dev_sde1");
Assert.AreEqual(expectedMountPoint2, this.disks.ElementAt(2).Volumes.First().AccessPaths.First());

string expectedMountPoint3 = Path.Combine(MockFixture.TestAssemblyDirectory, "vcmnt_dev_sdf1");
Assert.AreEqual(expectedMountPoint3, this.disks.ElementAt(3).Volumes.First().AccessPaths.First());
}
}

[Test]
public void FioExecutorCreatesTheExpectedWorkloadProcess_Scenario1()
{
Expand Down
28 changes: 4 additions & 24 deletions src/VirtualClient/VirtualClient.Actions/FIO/FioExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,9 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel

string ioEngine = FioExecutor.GetIOEngine(Environment.OSVersion.Platform);

IEnumerable<Disk> disks = await this.SystemManagement.DiskManager.GetDisksAsync(cancellationToken)
this.DiskFilter = string.IsNullOrWhiteSpace(this.DiskFilter) ? DiskFilters.DefaultDiskFilter : this.DiskFilter;

IEnumerable<Disk> disks = await this.SystemManagement.DiskManager.GetDisksAsync(this.DiskFilter, cancellationToken)
.ConfigureAwait(false);

if (disks?.Any() != true)
Expand All @@ -313,37 +315,15 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel
ErrorReason.WorkloadUnexpectedAnomaly);
}

IEnumerable<Disk> 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.",
ErrorReason.DependencyNotFound);
}

if (await this.CreateMountPointsAsync(disksToTest, cancellationToken).ConfigureAwait(false))
{
// Refresh the disks to pickup the mount point changes.
await Task.Delay(1000).ConfigureAwait(false);
IEnumerable<Disk> updatedDisks = await this.SystemManagement.DiskManager.GetDisksAsync(cancellationToken)
.ConfigureAwait(false);

disksToTest = this.GetDisksToTest(updatedDisks);
}

telemetryContext.AddContext(nameof(this.DiskFilter), this.DiskFilter);
telemetryContext.AddContext("executable", this.ExecutablePath);
telemetryContext.AddContext(nameof(ioEngine), ioEngine);
telemetryContext.AddContext(nameof(disks), disks);
telemetryContext.AddContext(nameof(disksToTest), disksToTest);

this.WorkloadProcesses.Clear();
List<Task> fioProcessTasks = new List<Task>();

this.WorkloadProcesses.AddRange(this.CreateWorkloadProcesses(this.ExecutablePath, this.CommandLine, disksToTest, this.ProcessModel));
this.WorkloadProcesses.AddRange(this.CreateWorkloadProcesses(this.ExecutablePath, this.CommandLine, disks, this.ProcessModel));

using (BackgroundOperations profiling = BackgroundOperations.BeginProfiling(this, cancellationToken))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,20 @@ public void UnixDiskManagerAppliesRetriesOnFailedAttemptsToCreateMountPoints()
Assert.IsTrue(attempts == 4);
}

[Test]
public async Task UnixDiskManagerReturnsListofFilteredDisks()
{
this.testProcess.OnHasExited = () => true;
this.testProcess.OnStart = () => true;
this.testProcess.StandardOutput.Append(Resources.lshw_disk_storage_results);


IEnumerable<Disk> disks = await this.diskManager.GetDisksAsync("osdisk:false", CancellationToken.None)
.ConfigureAwait(false);

Assert.AreEqual(disks.Count(), 3);
}

private class TestUnixDiskManager : UnixDiskManager
{
public TestUnixDiskManager(ProcessManager processManager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,89 @@ public async Task WindowsDiskManagerGetsTheExpectedDisks_Scenario1()
actualDisks.ToList().ForEach(disk => Assert.IsTrue(disk.Volumes.Count() == 2));
}

[Test]
public async Task WindowsDiskManagerReturnsListofFilteredDisks()
{
this.testProcess.OnHasExited = () => true;
this.testProcess.OnStart = () => true;

this.standardInput.BytesWritten += (sender, data) =>
{
string input = data.ToString().Trim();
if (input.Contains($"select disk"))
{
int diskIndex = int.Parse(Regex.Match(input, "[0-9]+").Value);
this.testProcess.StandardOutput.Append($"Disk {diskIndex} is now the selected disk.");
}
else if (input.Contains($"select partition"))
{
int partitionIndex = int.Parse(Regex.Match(input, "[0-9]+").Value);
this.testProcess.StandardOutput.Append($"Partition {partitionIndex} is now the selected partition.");
}
else if (input.Contains("list disk"))
{
StringBuilder listDiskResults = new StringBuilder()
.AppendLine(" ")
.AppendLine(" Disk ### Status Size Free Dyn Gpt")
.AppendLine(" -------- ------------- ------- ------- --- ---")
.AppendLine(" Disk 0 Online 127 GB 1024 KB ");

this.testProcess.StandardOutput.Append(listDiskResults.ToString());
}
else if (input.Contains("list partition"))
{
StringBuilder listPartitionResults = new StringBuilder()
.AppendLine(" ")
.AppendLine(" Partition ### Type Size Offset")
.AppendLine(" ------------- ---------------- ------- -------")
.AppendLine(" Partition 1 Primary 500 MB 1024 KB")
.AppendLine(" Partition 2 Primary 126 GB 501 MB");

this.testProcess.StandardOutput.Append(listPartitionResults.ToString());
}
else if (input.Contains($"detail disk"))
{
StringBuilder detailDiskResults = new StringBuilder()
.AppendLine(" ")
.AppendLine("Virtual HD ATA Device")
.AppendLine("Disk ID: EF349D83")
.AppendLine("Type : ATA")
.AppendLine("Status : Online")
.AppendLine("Path : 0")
.AppendLine("Target : 0")
.AppendLine("LUN ID : 0")
.AppendLine(" ")
.AppendLine(" Volume ### Ltr Label Fs Type Size Status Info ")
.AppendLine(" ---------- --- ----------- ----- ---------- ------- --------- --------")
.AppendLine(" Volume 0 System Rese NTFS Partition 500 MB Healthy System ")
.AppendLine(" Volume 1 C Windows NTFS Partition 126 GB Healthy Boot ");

this.testProcess.StandardOutput.Append(detailDiskResults.ToString());
}
else if (input.Contains($"detail partition"))
{
StringBuilder detailPartitionResults = new StringBuilder()
.AppendLine(" ")
.AppendLine("Partition 1")
.AppendLine("Type : 07")
.AppendLine("Hidden: No")
.AppendLine("Active: Yes")
.AppendLine("Offset in Bytes: 525336576")
.AppendLine(" ")
.AppendLine(" Volume ### Ltr Label Fs Type Size Status Info ")
.AppendLine(" ---------- --- ----------- ----- ---------- ------- --------- --------")
.AppendLine(" Volume 1 C Windows NTFS Partition 126 GB Healthy Boot ");

this.testProcess.StandardOutput.Append(detailPartitionResults.ToString());
}
};

IEnumerable<Disk> disks = await this.diskManager.GetDisksAsync(DiskFilters.DefaultDiskFilter, CancellationToken.None)
.ConfigureAwait(false);

Assert.AreEqual(disks.Count(), 1);
}

private class TestWindowsDiskManager : WindowsDiskManager
{
public TestWindowsDiskManager(ProcessManager processManager)
Expand Down
3 changes: 3 additions & 0 deletions src/VirtualClient/VirtualClient.Core/DiskManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,8 @@ protected DiskManager(ILogger logger)

/// <inheritdoc/>
public abstract Task<IEnumerable<Disk>> GetDisksAsync(CancellationToken cancellationToken);

/// <inheritdoc/>
public abstract Task<IEnumerable<Disk>> GetDisksAsync(string diskFilter, CancellationToken cancellationToken);
}
}
7 changes: 7 additions & 0 deletions src/VirtualClient/VirtualClient.Core/IDiskManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,12 @@ public interface IDiskManager
/// </summary>
/// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
Task<IEnumerable<Disk>> GetDisksAsync(CancellationToken cancellationToken);

/// <summary>
/// Gets the set of physical disks that exist on the system.
/// </summary>
/// <param name="diskFilter">Optional filter for disks.</param>
/// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
Task<IEnumerable<Disk>> GetDisksAsync(string diskFilter, CancellationToken cancellationToken);
}
}
15 changes: 15 additions & 0 deletions src/VirtualClient/VirtualClient.Core/UnixDiskManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,21 @@ public override Task<IEnumerable<Disk>> GetDisksAsync(CancellationToken cancella
});
}

/// <summary>
/// Gets the set of physical disks that exist on the system.
/// </summary>
/// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
/// <param name="diskFilter">The filter to apply to the disks.</param>
public override async Task<IEnumerable<Disk>> GetDisksAsync(string diskFilter, CancellationToken cancellationToken)
{
IEnumerable<Disk> disks = await this.GetDisksAsync(cancellationToken)
.ConfigureAwait(false);

IEnumerable<Disk> filteredDisks = DiskFilters.FilterDisks(disks, diskFilter, PlatformID.Unix).ToList();

return filteredDisks;
}

private Task AssignMountPointAsync(DiskVolume volume, string mountPoint, EventContext telemetryContext, CancellationToken cancellationToken)
{
int retries = -1;
Expand Down
15 changes: 15 additions & 0 deletions src/VirtualClient/VirtualClient.Core/WindowsDiskManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,21 @@ await process.WriteInput(command)
return disks;
}

/// <summary>
/// Gets the set of physical disks that exist on the system.
/// </summary>
/// <param name="diskFilter">Optional filter for disks.</param>
/// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
public override async Task<IEnumerable<Disk>> GetDisksAsync(string diskFilter, CancellationToken cancellationToken)
{
IEnumerable<Disk> disks = await this.GetDisksAsync(cancellationToken)
.ConfigureAwait(false);

IEnumerable<Disk> filteredDisks = DiskFilters.FilterDisks(disks, diskFilter, PlatformID.Win32NT).ToList();

return filteredDisks;
}

/// <summary>
/// Returns as set of lines that are all the exact same width.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,12 @@
"Scenario": "InitializeDisks"
}
},
{
"Type": "MountDisks",
"Parameters": {
"Scenario": "CreateMountPoints"
}
},
{
"Type": "LinuxPackageInstallation",
"Parameters": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public InMemoryDiskManager()
/// </summary>
public Action OnGetDisks { get; set; }

/// <summary>
/// Mimics the behavior of getting disks with filter.
/// </summary>
public Action<string> OnGetFilterDisks { get; set; }

/// <summary>
/// Creates a mount point for the volume provided.
/// </summary>
Expand Down Expand Up @@ -123,6 +128,17 @@ public Task<IEnumerable<Disk>> GetDisksAsync(CancellationToken cancellationToken
return Task.FromResult((IEnumerable<Disk>)this);
}

/// <summary>
/// Gets the set of physical disks that exist on the system.
/// </summary>
/// <param name="diskFilter">Optional filter for disks.</param>"
/// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
public Task<IEnumerable<Disk>> GetDisksAsync(string diskFilter, CancellationToken cancellationToken)
{
this.OnGetFilterDisks?.Invoke(diskFilter);
return Task.FromResult((IEnumerable<Disk>)this);
}

private void AddVolumeToDisk(Disk disk, FileSystemType fileSystemType)
{
DiskVolume newVolume = null;
Expand Down
Loading