Testing Strategy
Relevant source files
The following files were used as context for generating this wiki page:
The testing strategy for the rust-battery project focuses on validating cross-platform battery data extraction and normalization. Since the library interacts with diverse OS-specific interfaces (e.g., Linux sysfs, macOS IOKit, Windows IOCTL), the testing approach relies heavily on mocking hardware data sources to ensure consistent behavior across different environments. This includes regression testing for specific hardware quirks and verifying that raw values (in millivolts, milliamperes, etc.) are correctly converted into SI measurement units.
Mocking and Data Abstraction
To facilitate testing without physical hardware, the project uses abstraction traits and mock data sources. On macOS, this is achieved through the DataSource trait, while on Linux, a specialized macro creates temporary directory structures to simulate the sysfs filesystem.
macOS Testing Architecture
The macOS implementation utilizes a TestDataSource struct that implements the DataSource trait. This allows tests to manually define battery states (voltage, amperage, capacities) as raw u32 or i32 values, mimicking the output of the Apple ioreg tool.
The diagram shows how TestDataSource provides raw values to the device implementation for verification against SI unit expectations.
Sources: src/platform/darwin/tests.rs:17-30, src/platform/darwin/tests.rs:104-118
Linux Sysfs Mocking
For Linux, the project employs a macro sysfs_test_suite! that generates a temporary directory structure containing files representing battery attributes (e.g., capacity, voltage_now). This allows the SysFsDevice to be tested against realistic file-based data without requiring a real Linux system.
The flow represents the simulation of the Linux kernel's power supply class interface using temporary files.
Sources: src/platform/linux/tests/mod.rs:3-21, src/platform/linux/tests/issue_28.rs:16-33
Regression Testing for Hardware Quirks
The project maintains specific test files for issues encountered in production, ensuring that previous bugs do not reappear. These tests often handle "edge cases" where hardware drivers provide incomplete or unconventional data.
Handled Edge Cases
| Case | Description | Source File |
|---|---|---|
| Missing Design Files | Handles scenarios where energy_full_design or charge_full_design files are absent. | src/platform/linux/tests/issue_40.rs |
| Invalid Device Error | Simulates ENODEV or ENOENT errors when accessing certain attributes. | src/platform/linux/tests/issue_28.rs |
| Zero Cycle Counts | Validates that a cycle count of 0 is treated as a missing value to avoid misleading users. | src/platform/linux/sysfs/source.rs:252-263 |
| Precision Buffering | Ensures that nearly full or empty batteries do not report massive or impossible energy rates. | src/platform/linux/sysfs/source.rs:188-210 |
Unit and Integration Assertions
Tests utilize the approx crate to perform floating-point comparisons of SI units. This is critical because the library converts raw integers from the OS into typed values (e.g., WattHour, Kelvin).
Energy Calculation Logic
Tests verify that calculations for energy_rate, energy, and time_to_full follow standardized formulas even when the underlying OS provides different units (e.g., mAh vs mWh).
// Example from macOS test suite
assert_eq!(device.energy_rate().get::<milliwatt>().floor(), 13292.0);
assert_eq!(device.energy().get::<watt_hour>().floor(), 50.0);
Sources: src/platform/darwin/tests.rs:114-117, src/platform/linux/tests/issue_40.rs:43-50
Infallible Logic Verification
Since BatteryDevice methods are designed to be infallible, the tests verify that the DataBuilder (on Linux) or InstantData (on macOS) has preloaded and validated all necessary information before the user accesses it.
Sources: src/platform/traits.rs:36-40, src/platform/linux/sysfs/source.rs:56-68
Conclusion
The testing strategy ensures reliability by abstracting hardware interactions through mocks and temporary files. By focusing on SI unit accuracy and regression testing for known platform-specific issues, the project maintains a consistent API across diverse operating systems. Summary calculations, such as state_of_health and time_to_empty, are validated against default trait implementations to ensure cross-platform consistency.
Sources: src/platform/traits.rs:43-52, src/platform/traits.rs:106-123