Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions src/c#/DrivelutionTest/GeneralDrivelutionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,185 @@ public void GetPlatformInfo_ReportsCorrectSupportStatus()
Assert.False(platformInfo.IsSupported); // MacOS not yet implemented
}
}

/// <summary>
/// Tests that GetDriversFromDirectoryAsync returns empty list for non-existent directory.
/// </summary>
[Fact]
public async Task GetDriversFromDirectoryAsync_WithNonExistentDirectory_ReturnsEmptyList()
{
// Arrange
var nonExistentPath = Path.Combine(Path.GetTempPath(), $"nonexistent_{Guid.NewGuid()}");

// Act
var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(nonExistentPath);

// Assert
Assert.NotNull(result);
Assert.Empty(result);
}

/// <summary>
/// Tests that GetDriversFromDirectoryAsync returns empty list for empty directory.
/// </summary>
[Fact]
public async Task GetDriversFromDirectoryAsync_WithEmptyDirectory_ReturnsEmptyList()
{
// Arrange
var emptyDir = Path.Combine(Path.GetTempPath(), $"empty_{Guid.NewGuid()}");
Directory.CreateDirectory(emptyDir);

try
{
// Act
var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(emptyDir);

// Assert
Assert.NotNull(result);
Assert.Empty(result);
}
finally
{
if (Directory.Exists(emptyDir))
{
Directory.Delete(emptyDir, true);
}
}
}

/// <summary>
/// Tests that GetDriversFromDirectoryAsync discovers driver files in directory.
/// </summary>
[Fact]
public async Task GetDriversFromDirectoryAsync_WithDriverFiles_ReturnsDriverInfoList()
{
// Arrange
var testDir = Path.Combine(Path.GetTempPath(), $"drivers_{Guid.NewGuid()}");
Directory.CreateDirectory(testDir);

try
{
// Create test driver files based on platform
var platformInfo = GeneralDrivelution.GetPlatformInfo();
var testFiles = new List<string>();

if (platformInfo.Platform == "Windows")
{
// Create mock .inf file
var infFile = Path.Combine(testDir, "test_driver.inf");
File.WriteAllText(infFile, @"
[Version]
Signature=""$Windows NT$""
DriverVer=01/15/2024,1.0.0.0

[DriverInfo]
DriverDesc=""Test Driver""
");
testFiles.Add(infFile);
}
else if (platformInfo.Platform == "Linux")
{
// Create mock .ko file
var koFile = Path.Combine(testDir, "test_driver.ko");
File.WriteAllText(koFile, "Mock kernel module content");
testFiles.Add(koFile);
}

// Act
var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(testDir);

// Assert
Assert.NotNull(result);

// Should find at least one driver if platform is supported
if (platformInfo.IsSupported && testFiles.Any())
{
Assert.NotEmpty(result);

// Check that driver info has expected properties
var driver = result.First();
Assert.NotNull(driver.Name);
Assert.NotEmpty(driver.Name);
Assert.NotNull(driver.FilePath);
Assert.NotEmpty(driver.FilePath);
Assert.NotNull(driver.Version);
Assert.NotEmpty(driver.Version);
Assert.NotNull(driver.Hash);
Assert.NotEmpty(driver.Hash);
}
}
finally
{
if (Directory.Exists(testDir))
{
Directory.Delete(testDir, true);
}
}
}

/// <summary>
/// Tests that GetDriversFromDirectoryAsync with search pattern filters correctly.
/// </summary>
[Fact]
public async Task GetDriversFromDirectoryAsync_WithSearchPattern_FiltersCorrectly()
{
// Arrange
var testDir = Path.Combine(Path.GetTempPath(), $"drivers_{Guid.NewGuid()}");
Directory.CreateDirectory(testDir);

try
{
// Create different types of files
var infFile = Path.Combine(testDir, "driver1.inf");
var txtFile = Path.Combine(testDir, "readme.txt");
File.WriteAllText(infFile, "INF content");
File.WriteAllText(txtFile, "Text content");

// Act
var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(testDir, "*.inf");

// Assert
Assert.NotNull(result);

// Should only find .inf files
// The count depends on whether the platform supports parsing .inf files
}
Comment on lines +446 to +472
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test doesn't assert the filtering behavior it describes: it only checks result is non-null and then exits. As written it will pass even if GetDriversFromDirectoryAsync ignores searchPattern or always returns an empty list. Add assertions that every returned DriverInfo.FilePath matches *.inf and (when running on Windows or when parsing is expected) that exactly one driver is returned for the single .inf file created.

Copilot uses AI. Check for mistakes.
finally
{
if (Directory.Exists(testDir))
{
Directory.Delete(testDir, true);
}
}
}

/// <summary>
/// Tests that GetDriversFromDirectoryAsync handles cancellation.
/// </summary>
[Fact]
public async Task GetDriversFromDirectoryAsync_WithCancellation_HandlesCancellation()
{
// Arrange
var testDir = Path.Combine(Path.GetTempPath(), $"drivers_{Guid.NewGuid()}");
Directory.CreateDirectory(testDir);

try
{
var cts = new CancellationTokenSource();
cts.Cancel();

// Act
var result = await GeneralDrivelution.GetDriversFromDirectoryAsync(testDir, null, cts.Token);

// Assert - Should complete without throwing or return empty list
Assert.NotNull(result);
}
Comment on lines +482 to +502
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cancellation test only asserts the result is non-null, so it doesn't verify that cancellation is actually honored (e.g., returning an empty/partial list promptly and without doing work). Strengthen it by creating enough files to force iteration and asserting either that the returned list is empty when already-canceled, or that execution stops early (e.g., by checking it returns quickly / fewer results than total).

Copilot uses AI. Check for mistakes.
finally
{
if (Directory.Exists(testDir))
{
Directory.Delete(testDir, true);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@
namespace GeneralUpdate.Drivelution.Abstractions;

/// <summary>
/// 驱动更新器核心接口
/// Core interface for driver updater
/// </summary>
public interface IGeneralDrivelution
{
/// <summary>
/// 异步更新驱动
/// Updates driver asynchronously
/// </summary>
/// <param name="driverInfo">驱动信息 / Driver information</param>
/// <param name="strategy">更新策略 / Update strategy</param>
/// <param name="cancellationToken">取消令牌 / Cancellation token</param>
/// <returns>更新结果 / Update result</returns>
/// <param name="driverInfo">Driver information</param>
/// <param name="strategy">Update strategy</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Update result</returns>
/// <remarks>
/// Note: Update process may include signature validation that requires reflection on some platforms.
/// </remarks>
Expand All @@ -25,12 +23,11 @@ public interface IGeneralDrivelution
Task<UpdateResult> UpdateAsync(DriverInfo driverInfo, UpdateStrategy strategy, CancellationToken cancellationToken = default);

/// <summary>
/// 异步验证驱动
/// Validates driver asynchronously
/// </summary>
/// <param name="driverInfo">驱动信息 / Driver information</param>
/// <param name="cancellationToken">取消令牌 / Cancellation token</param>
/// <returns>验证是否通过 / Validation result</returns>
/// <param name="driverInfo">Driver information</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Validation result</returns>
/// <remarks>
/// Note: Includes signature validation that may require reflection on some platforms.
/// </remarks>
Expand All @@ -39,21 +36,28 @@ public interface IGeneralDrivelution
Task<bool> ValidateAsync(DriverInfo driverInfo, CancellationToken cancellationToken = default);

/// <summary>
/// 异步备份驱动
/// Backs up driver asynchronously
/// </summary>
/// <param name="driverInfo">驱动信息 / Driver information</param>
/// <param name="backupPath">备份路径 / Backup path</param>
/// <param name="cancellationToken">取消令牌 / Cancellation token</param>
/// <returns>备份结果 / Backup result</returns>
/// <param name="driverInfo">Driver information</param>
/// <param name="backupPath">Backup path</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Backup result</returns>
Task<bool> BackupAsync(DriverInfo driverInfo, string backupPath, CancellationToken cancellationToken = default);

/// <summary>
/// 异步回滚驱动
/// Rolls back driver asynchronously
/// </summary>
/// <param name="backupPath">备份路径 / Backup path</param>
/// <param name="cancellationToken">取消令牌 / Cancellation token</param>
/// <returns>回滚结果 / Rollback result</returns>
/// <param name="backupPath">Backup path</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Rollback result</returns>
Task<bool> RollbackAsync(string backupPath, CancellationToken cancellationToken = default);

/// <summary>
/// Reads driver information from local directory
/// </summary>
/// <param name="directoryPath">Directory path</param>
/// <param name="searchPattern">Search pattern (optional, e.g., "*.inf", "*.ko")</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>List of driver information</returns>
Task<List<DriverInfo>> GetDriversFromDirectoryAsync(string directoryPath, string? searchPattern = null, CancellationToken cancellationToken = default);
}
Loading
Loading