-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #884 from andrewdavidmackenzie/hardware_tests
hardware_tests
- Loading branch information
Showing
12 changed files
with
399 additions
and
17 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "hw_test" | ||
version = "0.6.0" | ||
edition = "2021" | ||
rust-version = "1.80" | ||
|
||
[features] | ||
default = ["usb", "tcp", "discovery"] | ||
usb = ["pigdef/usb", "pignet/usb"] | ||
tcp = ["pigdef/tcp", "pignet/tcp"] | ||
discovery = ["pigdef/discovery", "pignet/discovery"] | ||
iroh = ["pigdef/iroh", "pignet/iroh"] | ||
|
||
[dev-dependencies] | ||
pigdef = { path = "../pigdef" } | ||
pignet = { path = "../pignet" } | ||
tokio = { version = "1.43", default-features = false, features = ["time", "rt", "rt-multi-thread", "macros"] } | ||
async-std = "1.13.0" | ||
serial_test = "3.1.1" | ||
anyhow = "1.0.96" | ||
mdns-sd = { version = "0.13.2", default-features = false, features = ["async"] } | ||
iroh = { version = "0.33.0", default-features = false } | ||
|
||
[package.metadata.cargo-all-features] | ||
skip_optional_dependencies = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#![cfg(feature = "discovery")] | ||
|
||
use anyhow::anyhow; | ||
#[cfg(feature = "iroh")] | ||
use iroh::{NodeId, RelayUrl}; | ||
#[cfg(feature = "discovery")] | ||
use mdns_sd::{ServiceDaemon, ServiceEvent}; | ||
#[cfg(feature = "discovery")] | ||
use pigdef::description::TCP_MDNS_SERVICE_TYPE; | ||
#[cfg(feature = "tcp")] | ||
use std::net::IpAddr; | ||
#[cfg(all(feature = "tcp", feature = "iroh"))] | ||
use std::str::FromStr; | ||
|
||
#[cfg(feature = "tcp")] | ||
pub async fn get_ip_and_port_by_mdns() -> anyhow::Result<(IpAddr, u16)> { | ||
let mdns = ServiceDaemon::new().expect("Failed to create daemon"); | ||
if let Ok(receiver) = mdns.browse(TCP_MDNS_SERVICE_TYPE) { | ||
while let Ok(event) = receiver.recv_async().await { | ||
if let ServiceEvent::ServiceResolved(info) = event { | ||
if let Some(ip) = info.get_addresses_v4().drain().next() { | ||
let port = info.get_port(); | ||
return Ok((IpAddr::V4(*ip), port)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
Err(anyhow!("Could not discover device by mDNS")) | ||
} | ||
|
||
#[allow(dead_code)] // Only piglet device will offer Iroh properties | ||
#[cfg(feature = "iroh")] | ||
pub async fn get_iroh_by_mdns() -> anyhow::Result<(NodeId, Option<RelayUrl>)> { | ||
let mdns = ServiceDaemon::new().expect("Failed to create daemon"); | ||
if let Ok(receiver) = mdns.browse(TCP_MDNS_SERVICE_TYPE) { | ||
while let Ok(event) = receiver.recv_async().await { | ||
if let ServiceEvent::ServiceResolved(info) = event { | ||
let device_properties = info.get_properties(); | ||
if let Some(nodeid_str) = device_properties.get_property_val_str("IrohNodeID") { | ||
if let Ok(nodeid) = NodeId::from_str(nodeid_str) { | ||
let relay_url = device_properties | ||
.get_property_val_str("IrohRelayURL") | ||
.map(|s| RelayUrl::from_str(s).unwrap()); | ||
return Ok((nodeid, relay_url)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
Err(anyhow!("Could not discover device by mDNS")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#![cfg(feature = "tcp")] | ||
|
||
use async_std::net::TcpStream; | ||
use pigdef::config::HardwareConfig; | ||
use pigdef::config::HardwareConfigMessage::{Disconnect, GetConfig}; | ||
use pigdef::description::HardwareDescription; | ||
use pignet::tcp_host; | ||
use serial_test::serial; | ||
use std::future::Future; | ||
use std::net::IpAddr; | ||
use std::time::Duration; | ||
|
||
mod usb; | ||
#[cfg(feature = "usb")] | ||
use usb::get_ip_and_port_by_usb; | ||
|
||
mod mdns; | ||
#[cfg(feature = "discovery")] | ||
use mdns::get_ip_and_port_by_mdns; | ||
|
||
async fn connect_tcp<F, Fut>(ip: IpAddr, port: u16, test: F) | ||
where | ||
F: FnOnce(HardwareDescription, HardwareConfig, TcpStream) -> Fut, | ||
Fut: Future<Output = ()>, | ||
{ | ||
match tcp_host::connect(ip, port).await { | ||
Ok((hw_desc, hw_config, tcp_stream)) => { | ||
if !hw_desc.details.model.contains("Fake") { | ||
panic!("Didn't connect to fake hardware piglet") | ||
} else { | ||
test(hw_desc, hw_config, tcp_stream).await; | ||
} | ||
} | ||
_ => panic!("Could not connect to piglet"), | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
#[serial] | ||
async fn can_connect_tcp() { | ||
if let Ok((ip, port)) = get_ip_and_port_by_usb().await { | ||
connect_tcp(ip, port, |_d, _c, _co| async {}).await; | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
#[serial] | ||
async fn disconnect_tcp() { | ||
if let Ok((ip, port)) = get_ip_and_port_by_usb().await { | ||
connect_tcp(ip, port, |_d, _c, tcp_stream| async move { | ||
tcp_host::send_config_message(tcp_stream, &Disconnect) | ||
.await | ||
.expect("Could not send Disconnect"); | ||
}) | ||
.await; | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
#[serial] | ||
async fn get_config_tcp() { | ||
if let Ok((ip, port)) = get_ip_and_port_by_usb().await { | ||
connect_tcp(ip, port, |_d, _c, tcp_stream| async move { | ||
tcp_host::send_config_message(tcp_stream, &GetConfig) | ||
.await | ||
.expect("Could not GetConfig"); | ||
}) | ||
.await; | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
#[serial] | ||
async fn reconnect_tcp() { | ||
if let Ok((ip, port)) = get_ip_and_port_by_usb().await { | ||
connect_tcp(ip, port, |_d, _c, tcp_stream| async move { | ||
tcp_host::send_config_message(tcp_stream, &Disconnect) | ||
.await | ||
.expect("Could not send Disconnect"); | ||
}) | ||
.await; | ||
|
||
tokio::time::sleep(Duration::from_secs(1)).await; | ||
|
||
// Test we can re-connect after sending a disconnect request | ||
connect_tcp(ip, port, |_d, _c, _tcp_stream| async {}).await; | ||
} | ||
} | ||
|
||
#[ignore] | ||
#[cfg(feature = "discovery")] | ||
#[tokio::test] | ||
#[serial] | ||
async fn discover_and_connect_tcp() { | ||
if let Ok((ip, port)) = get_ip_and_port_by_mdns().await { | ||
connect_tcp(ip, port, |_d, _c, _co| async {}).await; | ||
} | ||
} | ||
|
||
// piggui tests | ||
// connect using usb from piggui via CLI option | ||
// connect using tcp from piggui via CLI option | ||
// connect using usb from piggui via CLI option |
Oops, something went wrong.