Skip to content

Commit bfe0f7d

Browse files
committed
added windows integration testing and improved issue templating
1 parent c20a9e3 commit bfe0f7d

8 files changed

Lines changed: 173 additions & 2 deletions

File tree

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ body:
4545
[DEBUG] ...
4646
validations:
4747
required: false
48+
- type: textarea
49+
id: fix
50+
attributes:
51+
label: Proposed Fix
52+
description: If you have a technical suggestion or a snippet, please share it!
53+
placeholder: e.g. We should use zond_common::net::interface to filter the scan targets.
54+
validations:
55+
required: false
4856
- type: dropdown
4957
id: os
5058
attributes:

.github/ISSUE_TEMPLATE/protocol_request.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ body:
3939
placeholder: e.g. https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html
4040
validations:
4141
required: true
42-
- type: checkbox
42+
- type: checkboxes
4343
id: priority
4444
attributes:
4545
label: Desired Depth

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ coverage/
2929
# Packaging
3030
packaging/aur/src/
3131
packaging/aur/pkg/
32+
33+
# Proptests
34+
**/proptest-regressions/
35+

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ members = [
1010
]
1111

1212
[workspace.package]
13-
version = "0.3.5"
13+
version = "0.3.6"
1414
license = "MPL-2.0"
1515
edition = "2024"
1616
repository = "https://github.com/hollowpointer/zond"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<#
2+
.SYNOPSIS
3+
Run Zond Integration Tests on Windows.
4+
5+
.DESCRIPTION
6+
This script automates the execution of the Zond integration test suite on Windows.
7+
It ensures the environment is suitable for testing (Administrator check) and
8+
executes the platform-specific integration tests.
9+
10+
.EXAMPLE
11+
.\run_integration_windows.ps1
12+
#>
13+
14+
# 1. Require Administrator Privileges
15+
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
16+
if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
17+
Write-Error "Zond integration tests require Administrator privileges to perform hardware heuristics and raw socket discovery."
18+
Write-Host "Please restart your PowerShell session as Administrator and try again." -ForegroundColor Red
19+
exit 1
20+
}
21+
22+
Write-Host ">>> Zond Windows Integration Test Suite" -ForegroundColor Cyan
23+
24+
# 2. Workspace Check
25+
if (-not (Test-Path "Cargo.toml")) {
26+
Write-Error "Script must be run from the repository root."
27+
exit 1
28+
}
29+
30+
# 3. Execution
31+
Write-Host ">>> Compiling and running platform tests..." -ForegroundColor Gray
32+
# We target use 'zond-integration-tests' specifically to isolate from Linux-bound tests
33+
cargo test -p zond-integration-tests -- --nocapture
34+
35+
if ($LASTEXITCODE -ne 0) {
36+
Write-Host "`n>>> Integration tests FAILED." -ForegroundColor Red
37+
exit $LASTEXITCODE
38+
} else {
39+
Write-Host "`n>>> Integration tests PASSED." -ForegroundColor Green
40+
exit 0
41+
}

tests/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ pub mod discovery;
3232
pub mod port_scan;
3333
#[cfg(test)]
3434
pub mod utils;
35+
#[cfg(test)]
36+
pub mod platform;

tests/src/platform/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) 2026 OverTheFlow and Contributors
2+
//
3+
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4+
// If a copy of the MPL was not distributed with this file, You can obtain one at
5+
// https://mozilla.org/MPL/2.0/.
6+
7+
//! Platform-specific integration tests.
8+
9+
#[cfg(target_os = "windows")]
10+
pub mod windows;

tests/src/platform/windows.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) 2026 OverTheFlow and Contributors
2+
//
3+
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4+
// If a copy of the MPL was not distributed with this file, You can obtain one at
5+
// https://mozilla.org/MPL/2.0/.
6+
7+
use std::net::{IpAddr, TcpListener};
8+
use zond_common::config::ZondConfig;
9+
use zond_common::models::ip::set::IpSet;
10+
use zond_core::scanner;
11+
use pnet::datalink;
12+
13+
/// Verifies that Windows hardware heuristics (physical/wireless detection)
14+
/// execute correctly and find plausible adapters.
15+
#[tokio::test]
16+
async fn windows_hardware_heuristics() {
17+
let interfaces = datalink::interfaces();
18+
assert!(!interfaces.is_empty(), "No network interfaces found on the system");
19+
20+
let mut physically_found = 0;
21+
for iface in interfaces {
22+
// These calls verify that the GetIfTable2 FFI logic works on the real host
23+
let physical = zond_common::net::interface::os::is_physical(&iface);
24+
let wireless = zond_common::net::interface::os::is_wireless(&iface);
25+
26+
if physical {
27+
physically_found += 1;
28+
}
29+
30+
// Integrity check: Wireless adapters are always physical
31+
if wireless {
32+
assert!(physical, "Interface {} identified as wireless but not physical", iface.name);
33+
}
34+
}
35+
36+
// On a real machine, at least one interface (Ethernet or Wi-Fi) should be physical
37+
assert!(physically_found > 0, "No physical adapters detected - verify Administrator privileges");
38+
}
39+
40+
/// Performs a full unprivileged discovery scan against a local mock listener.
41+
/// This verifies the orchestration path: Dispatcher -> Connect -> Result.
42+
#[tokio::test]
43+
async fn windows_local_discovery_integration() {
44+
let cfg = ZondConfig {
45+
no_banner: true,
46+
no_dns: true,
47+
quiet: 0,
48+
..Default::default()
49+
};
50+
51+
// 1. Find a valid local IPv4 interface
52+
let interfaces = datalink::interfaces();
53+
let target_ip = interfaces.iter()
54+
.filter(|i| i.is_up() && !i.is_loopback())
55+
.flat_map(|i| i.ips.iter())
56+
.find(|ip| ip.is_ipv4())
57+
.map(|ip| ip.ip())
58+
.expect("No active local IPv4 interface found for testing");
59+
60+
// 2. Spawn a mock listener on a random port
61+
let listener = TcpListener::bind((target_ip, 0)).expect("Failed to bind mock listener");
62+
let local_addr = listener.local_addr().unwrap();
63+
let port = local_addr.port();
64+
65+
// 3. Run discovery targeting that specific IP
66+
let mut targets = IpSet::new();
67+
targets.insert(target_ip);
68+
69+
let handle = tokio::spawn(async move {
70+
scanner::discover(targets, &cfg).await
71+
});
72+
73+
// We give the scanner a moment. Since it's local, RTT is near zero.
74+
let result = handle.await.unwrap();
75+
assert!(result.is_ok(), "Scanner failed on Windows: {:?}", result.err());
76+
77+
let hosts = result.unwrap();
78+
79+
// 4. Verify the host was found
80+
assert!(!hosts.is_empty(), "Scanner did not find the local host on Windows");
81+
assert_eq!(hosts[0].primary_ip, target_ip);
82+
83+
// Explicitly keep listener alive until here
84+
drop(listener);
85+
}
86+
87+
/// Verifies loopback discovery on Windows.
88+
#[tokio::test]
89+
async fn windows_loopback_fidelity() {
90+
let cfg = ZondConfig {
91+
no_banner: true,
92+
no_dns: true,
93+
..Default::default()
94+
};
95+
96+
let mut targets = IpSet::new();
97+
let localhost = IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1));
98+
targets.insert(localhost);
99+
100+
let result = scanner::discover(targets, &cfg).await;
101+
assert!(result.is_ok());
102+
let hosts = result.unwrap();
103+
104+
assert!(!hosts.is_empty(), "Loopback discovery failed on Windows");
105+
assert_eq!(hosts[0].primary_ip, localhost);
106+
}

0 commit comments

Comments
 (0)