Skip to content

Allow overriding OneWire sysfs paths for testing#2478

Open
florianraffl wants to merge 1 commit intodotnet:mainfrom
florianraffl:overriding_onewire_path
Open

Allow overriding OneWire sysfs paths for testing#2478
florianraffl wants to merge 1 commit intodotnet:mainfrom
florianraffl:overriding_onewire_path

Conversation

@florianraffl
Copy link

@florianraffl florianraffl commented Feb 24, 2026

Fixes #2477

Changed SysfsBusDevicesPath and SysfsDevicesPath from const to static string fields to enable runtime modification. Added OverwriteSysfsBusDevicesPath and OverwriteSysfsDevicesPath methods to allow setting custom sysfs directories, with validation. This facilitates testing and use in non-standard environments.

Microsoft Reviewers: Open in CodeFlow

Changed SysfsBusDevicesPath and SysfsDevicesPath from const to static string fields to enable runtime modification. Added OverwriteSysfsBusDevicesPath and OverwriteSysfsDevicesPath methods to allow setting custom sysfs directories, with validation. This facilitates testing and use in non-standard environments.
@dotnet-policy-service dotnet-policy-service bot added the area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio label Feb 24, 2026
@florianraffl
Copy link
Author

@dotnet-policy-service agree

@raffaeler
Copy link
Contributor

@copilot review the pull-request according to the repo policies

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request enables testing of OneWire device bindings by making sysfs paths configurable at runtime. The changes address issue #2477, which requested the ability to override hardcoded sysfs paths for integration testing scenarios.

Changes:

  • Converted SysfsBusDevicesPath and SysfsDevicesPath from const to static string fields to allow runtime modification
  • Added two public static methods (OverwriteSysfsBusDevicesPath and OverwriteSysfsDevicesPath) with directory validation to set custom paths for testing

{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The parameter name in the exception message should use nameof(path) instead of a string literal for consistency with the repository's error handling patterns. This ensures that parameter names stay synchronized if they are ever renamed during refactoring.

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +88
public static void OverwriteSysfsBusDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsBusDevicesPath = path;
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

Missing null validation for the path parameter. The repository consistently uses ArgumentNullException for null parameters (see examples in Ads1115, Adxl345, etc.). Add a null check before the Directory.Exists check.

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +103
public static void OverwriteSysfsDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsDevicesPath = path;
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

Missing null validation for the path parameter. The repository consistently uses ArgumentNullException for null parameters (see examples in Ads1115, Adxl345, etc.). Add a null check before the Directory.Exists check.

Copilot uses AI. Check for mistakes.
Comment on lines 15 to +103
@@ -71,5 +71,35 @@ internal static void ScanForDeviceChangesInternal(OneWireBus bus, int numDevices

File.WriteAllText(Path.Combine(SysfsDevicesPath, bus.BusId, "w1_master_search"), numScans.ToString());
}

/// <summary>
/// Sets the bus path to the specified directory for testing purpose.
/// </summary>
/// <param name="path">The path to the directory that will be set as the bus path. This path must exist and be a valid directory.</param>
/// <exception cref="ArgumentException">Thrown if the specified path does not exist or is not a directory.</exception>
public static void OverwriteSysfsBusDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsBusDevicesPath = path;
}

/// <summary>
/// Sets the devices path to the specified directory for testing purpose.
/// </summary>
/// <param name="path">The path to the directory that will be set as the devices path. This path must exist and be a valid directory.</param>
/// <exception cref="ArgumentException">Thrown if the provided path does not exist or is not a directory.</exception>
public static void OverwriteSysfsDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsDevicesPath = path;
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The static mutable fields SysfsBusDevicesPath and SysfsDevicesPath present thread safety concerns. Multiple threads could read these paths while they are being modified, leading to race conditions. Additionally, there is no mechanism to restore the paths to their original values after testing. Consider: (1) using volatile or Interlocked operations for thread-safe updates, (2) providing Reset methods to restore defaults, or (3) documenting that these methods should only be called before any OneWire operations in a single-threaded test setup context.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree to Copilot here. I suggest you make the strings non-static so that a change only affects the current instance.

Comment on lines +75 to +103
/// <summary>
/// Sets the bus path to the specified directory for testing purpose.
/// </summary>
/// <param name="path">The path to the directory that will be set as the bus path. This path must exist and be a valid directory.</param>
/// <exception cref="ArgumentException">Thrown if the specified path does not exist or is not a directory.</exception>
public static void OverwriteSysfsBusDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsBusDevicesPath = path;
}

/// <summary>
/// Sets the devices path to the specified directory for testing purpose.
/// </summary>
/// <param name="path">The path to the directory that will be set as the devices path. This path must exist and be a valid directory.</param>
/// <exception cref="ArgumentException">Thrown if the provided path does not exist or is not a directory.</exception>
public static void OverwriteSysfsDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsDevicesPath = path;
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

Consider adding methods to reset paths to their default values for proper test isolation. Tests that modify these static paths should be able to restore the original state to avoid test interdependencies. For example, add ResetSysfsBusDevicesPath() and ResetSysfsDevicesPath() methods that restore the default "/sys/bus/w1/devices" and "/sys/devices" values respectively.

Copilot uses AI. Check for mistakes.
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The parameter name in the exception message should use nameof(path) instead of a string literal for consistency with the repository's error handling patterns. This ensures that parameter names stay synchronized if they are ever renamed during refactoring.

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +16
internal static string SysfsBusDevicesPath = "/sys/bus/w1/devices";
internal static string SysfsDevicesPath = "/sys/devices";
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest to make these (and the corresponding methods) non-static, to avoid concurrency issues. It also looks like they could be private.

/// </summary>
/// <param name="path">The path to the directory that will be set as the bus path. This path must exist and be a valid directory.</param>
/// <exception cref="ArgumentException">Thrown if the specified path does not exist or is not a directory.</exception>
public static void OverwriteSysfsBusDevicesPath(string path)
Copy link
Contributor

Choose a reason for hiding this comment

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

To simplify the API, I think a single method to set both paths would be sufficient.

Comment on lines 15 to +103
@@ -71,5 +71,35 @@ internal static void ScanForDeviceChangesInternal(OneWireBus bus, int numDevices

File.WriteAllText(Path.Combine(SysfsDevicesPath, bus.BusId, "w1_master_search"), numScans.ToString());
}

/// <summary>
/// Sets the bus path to the specified directory for testing purpose.
/// </summary>
/// <param name="path">The path to the directory that will be set as the bus path. This path must exist and be a valid directory.</param>
/// <exception cref="ArgumentException">Thrown if the specified path does not exist or is not a directory.</exception>
public static void OverwriteSysfsBusDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsBusDevicesPath = path;
}

/// <summary>
/// Sets the devices path to the specified directory for testing purpose.
/// </summary>
/// <param name="path">The path to the directory that will be set as the devices path. This path must exist and be a valid directory.</param>
/// <exception cref="ArgumentException">Thrown if the provided path does not exist or is not a directory.</exception>
public static void OverwriteSysfsDevicesPath(string path)
{
if (!Directory.Exists(path))
{
throw new ArgumentException($"Provided path {path} does not exist or is not a directory.");
}

SysfsDevicesPath = path;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree to Copilot here. I suggest you make the strings non-static so that a change only affects the current instance.

@dotnet-policy-service dotnet-policy-service bot added the Needs: Author Feedback We are waiting for author to react to feedback (action required) label Feb 28, 2026
@dotnet-policy-service
Copy link
Contributor

This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 7 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio Needs: Author Feedback We are waiting for author to react to feedback (action required) Status: No Recent Activity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OneWire sensor - override SysfsBusDevicesPath

4 participants