Skip to content

Commit 374867d

Browse files
committed
bindings/csharp: Add readme for C# tests
Adds README.md that documents the complete C# bindings test suite design, purpose, and usage. Signed-off-by: Dan Nechita <dan.nechita@analog.com>
1 parent 70ece1e commit 374867d

1 file changed

Lines changed: 214 additions & 0 deletions

File tree

bindings/csharp/tests/README.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# C# Bindings Integration Tests
2+
3+
This directory contains integration tests for the libiio C# bindings (`libiio-sharp.dll`). These tests validate that the C# bindings correctly interact with the native libiio library and catch common deployment issues before they reach end users.
4+
5+
## Files in This Directory
6+
7+
| File | Purpose |
8+
|------|---------|
9+
| **CMakeLists.txt** | CMake build configuration that compiles the C# test executable using the C# compiler (csc.exe on Windows, mcs on Unix). Automatically builds `LibiioIntegrationTests.exe` when C# bindings are enabled. Also copies XML test resources from `tests/resources/xmls/` to the test bin directory. |
10+
| **TestFramework.cs** | Lightweight test framework providing assertion methods, test execution, and result reporting. Contains `AssertTrue()`, `AssertNotNull()`, `AssertEqual()`, `AssertException()`, and summary reporting. No external dependencies required. |
11+
| **SmokeTests.cs** | Smoke tests that validate basic functionality without requiring hardware. Contains the `Main()` entry point. Tests DLL existence, assembly loading, P/Invoke resolution, backend checks, exception handling, and scan functionality. |
12+
| **IntegrationTests.cs** | Integration tests designed for use with the emulation backend. Mimics `iio_info` tool behavior: create context, enumerate devices/channels, read/write attributes. Uses XML files from `../../tests/resources/xmls/` to define emulated devices. |
13+
| **DllCollector.ps1** | PowerShell script that collects all required DLL dependencies from the build and deps directories into the test bin directory. Handles VS version differences and provides clear error messages for missing dependencies. |
14+
15+
## Test Resources
16+
17+
XML test files for the emulation backend are located in `tests/resources/xmls/` (repository root). These files define IIO device configurations used by integration tests. During build, CMake automatically copies these XML files to the test bin directory so they can be referenced by filename in the test code.
18+
19+
To add new test devices, place XML files in `tests/resources/xmls/` and reference them by filename in `IntegrationTests.cs`.
20+
21+
## Test types
22+
23+
### Smoke Tests
24+
25+
**Purpose**: Validate that the C# bindings can be deployed and used without hardware.
26+
27+
**What it tests**:
28+
1. **DLL Existence**: Verifies all 6 required DLLs are present and non-empty
29+
- `libiio1.dll` (native library)
30+
- `libiio-sharp.dll` (C# assembly)
31+
- `libusb-1.0.dll` (USB backend)
32+
- `libzstd.dll` (compression)
33+
- `libxml2.dll` (XML support)
34+
- `libserialport.dll` (serial backend)
35+
36+
2. **Assembly Loading**: Confirms `libiio-sharp.dll` can be loaded via reflection
37+
38+
3. **Type Existence**: Validates all expected C# types are present in the assembly
39+
- Context, Device, Channel, Attr, IOBuffer, Block, Stream, Trigger, Scan, IioLib, IIOException
40+
41+
4. **P/Invoke Resolution**: Tests that native function calls work
42+
- `IioLib.get_builtin_backends_count()` - Basic P/Invoke
43+
- `IioLib.get_builtin_backend()` - String marshaling
44+
- `IioLib.has_backend()` - Boolean return values
45+
46+
5. **Backend Availability**: Checks backend availability without crashing
47+
- Tests `has_backend()` with known and invalid backend names
48+
- Verifies boolean return values work correctly
49+
50+
6. **Exception Handling**: Verifies error handling works correctly
51+
- Invalid context creation throws `IIOException` (not crash)
52+
53+
7. **Scan Functionality**: Tests context discovery without crashing
54+
- Creates `Scan` object
55+
- Reads `nb_results` property (may be 0 without hardware)
56+
- Disposes properly
57+
58+
8. **Version Compatibility**: Validates native library and C# assembly version compatibility
59+
- Reads native library version from `libiio1.dll` via `IioLib.library_version`
60+
- Reads C# assembly version from `libiio-sharp.dll` using reflection
61+
- **FAILS if major versions differ** (incompatible, breaking API changes)
62+
- **WARNS if minor versions differ** (may have limited compatibility)
63+
- **PASSES when versions match** (fully compatible)
64+
- Critical for users deploying different versions of `libiio.dll` with the C# bindings
65+
66+
**Exit Code**:
67+
- `0` = All tests passed
68+
- `1` = One or more tests failed
69+
70+
### Integration Tests
71+
72+
**Purpose**: Exercise the complete C# API surface using emulated hardware.
73+
74+
**What it tests**:
75+
1. **Context Creation**: Create context with emulation backend using XML device definitions
76+
2. **Device Enumeration**: Iterate all emulated devices
77+
3. **Channel Enumeration**: Iterate channels for each device
78+
4. **Device Attribute Access**: Read device attributes
79+
5. **Channel Attribute Access**: Read channel attributes
80+
81+
These tests mimic the behavior of the `iio_info` utility tool but in C#, ensuring the bindings support complete workflows. The tests use XML files from `tests/resources/xmls/` (e.g., `pluto.xml`) to define the emulated IIO devices. The emulation backend allows testing the API without physical hardware.
82+
83+
## What These Tests Are For
84+
85+
### Problem Statement
86+
87+
Users frequently integrate `libiio-sharp.dll` into their C# applications and encounter deployment issues:
88+
89+
- **Missing DLLs**: Native dependencies not included in deployment packages
90+
- **Architecture Mismatches**: Mixing x86/x64 DLLs
91+
- **API Breaking Changes**: C API changes that the C# bindings don't match
92+
- **P/Invoke Failures**: DllNotFoundException or EntryPointNotFoundException at runtime
93+
- **Version Incompatibilities**: Mismatched libiio.dll and libiio-sharp.dll versions
94+
95+
These issues are often discovered by end users in production rather than during development.
96+
97+
### Solution
98+
99+
These integration tests catch deployment and compatibility issues early:
100+
101+
1. **CI/CD Integration**: Tests run automatically on every Windows build in Azure Pipelines
102+
2. **Fail Fast**: Build fails if C# bindings cannot be used, preventing broken releases
103+
3. **Clear Diagnostics**: Detailed error messages identify exactly which DLL is missing or which API call failed
104+
4. **No Hardware Required**: Smoke tests validate deployment without needing physical IIO devices
105+
5. **Version Validation**: Ensures C# bindings match the native library version they were built against
106+
107+
### Use Cases
108+
109+
**For Developers**:
110+
- Verify C# bindings work after modifying the C API
111+
- Catch breaking changes before they reach users
112+
- Test deployment packaging locally before release
113+
114+
**For CI/CD**:
115+
- Automated validation on every build
116+
- Prevents publishing broken C# bindings
117+
- Validates all required dependencies are built and available
118+
119+
**For End Users**:
120+
- Confidence that released C# bindings are functional
121+
- Example code showing correct usage patterns
122+
- Reference for required DLL dependencies
123+
124+
## Running the Tests
125+
126+
### Local Execution
127+
128+
From the repository root:
129+
130+
```powershell
131+
# Default (uses build/ directory, RelWithDebInfo configuration)
132+
.\CI\run_csharp_tests.ps1
133+
134+
# Specify custom build directory or configuration
135+
.\CI\run_csharp_tests.ps1 -BuildDir "C:\path\to\build" -Configuration "Debug"
136+
```
137+
138+
### Azure Pipelines
139+
140+
Tests run automatically on the `WindowsBuilds` job (VS 2022 x64 configuration only) after the build completes. The pipeline will fail if tests fail.
141+
142+
### Manual Execution
143+
144+
If you want to run the tests manually:
145+
146+
```powershell
147+
# 1. Build the test executable
148+
cmake --build . --config RelWithDebInfo --target libiio-csharp-tests
149+
150+
# 2. Collect DLL dependencies
151+
.\bindings\csharp\tests\DllCollector.ps1 -BuildDir ".\build" -Configuration "RelWithDebInfo" -TestBinDir ".\build\bindings\csharp\tests\csharp-test-bin"
152+
153+
# 3. Run the tests
154+
cd build\bindings\csharp\tests\csharp-test-bin
155+
.\LibiioIntegrationTests.exe
156+
```
157+
158+
## Expected Output
159+
160+
```
161+
========================================
162+
libiio C# Bindings - Smoke Tests
163+
========================================
164+
165+
[TEST] DLL Existence Check
166+
[PASS] libiio1.dll exists
167+
[PASS] libiio1.dll has non-zero size (192512 bytes)
168+
[PASS] libiio-sharp.dll exists
169+
...
170+
171+
[TEST] Backend Info API
172+
[PASS] get_builtin_backends_count returned valid count: 4
173+
[PASS] get_builtin_backend(0) returned backend: local
174+
...
175+
176+
========================================
177+
TEST SUMMARY
178+
========================================
179+
Total: 22
180+
Passed: 22
181+
Failed: 0
182+
Success Rate: 100.0%
183+
184+
========================================
185+
All smoke tests PASSED
186+
========================================
187+
```
188+
189+
## Extending the Tests
190+
191+
### Adding New Smoke Tests
192+
193+
1. Open `SmokeTests.cs`
194+
2. Add a new test method following the existing pattern
195+
3. Call `TestFramework.RunTest("Test Name", TestMethod)` in `Main()`
196+
197+
Example:
198+
```csharp
199+
static void TestNewFeature()
200+
{
201+
try
202+
{
203+
// Your test code here
204+
TestFramework.AssertTrue(condition, "Description of what passed");
205+
}
206+
catch (Exception ex)
207+
{
208+
TestFramework.AssertTrue(false, "Test failed: " + ex.Message);
209+
}
210+
}
211+
212+
// In Main():
213+
TestFramework.RunTest("New Feature Test", TestNewFeature);
214+
```

0 commit comments

Comments
 (0)