Skip to content

Commit a036a85

Browse files
committed
fix: android CI
1 parent 992e997 commit a036a85

3 files changed

Lines changed: 47 additions & 17 deletions

File tree

.github/workflows/ci.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,18 +201,32 @@ jobs:
201201
uses: reactivecircus/android-emulator-runner@v2
202202
env:
203203
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
204+
RUST_LOG: trace
204205
with:
205206
api-level: ${{ matrix.api-level }}
206207
arch: x86_64
207208
target: google_apis
208209
force-avd-creation: false
209-
emulator-options: -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect
210+
# `-dns-server` + `-netfast` + `-no-metrics` are the combination
211+
# reported to give working public-internet connectivity on the
212+
# GH-hosted runner; without them `wlan0` stays NO-CARRIER and
213+
# every connect() to a public IP fails with ENETUNREACH. See
214+
# https://github.com/ReactiveCircus/android-emulator-runner/issues/348#issuecomment-2578082030
215+
emulator-options: -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect -dns-server 8.8.8.8 -netfast -no-metrics
210216
disable-animations: true
211217
# cargo-ndk pushes each test binary to /data/local/tmp on the
212218
# emulator and runs it via adb.
213219
script: |
214220
adb wait-for-device
215221
adb shell 'i=0; while [ -z "$(getprop sys.boot_completed | tr -d "\r")" ]; do i=$((i+1)); if [ $i -gt 300 ]; then echo "boot did not complete within 600s"; exit 1; fi; sleep 2; done'
222+
# `sys.boot_completed=1` only signals that Android finished
223+
# booting, not that the radio/Wi-Fi stack is up. Poll until
224+
# the kernel actually has a route to a public IP, otherwise
225+
# any test that hits the network fails with ENETUNREACH.
226+
adb shell 'i=0; while ! ip route get 8.8.8.8 >/dev/null 2>&1; do i=$((i+1)); if [ $i -gt 60 ]; then echo "no route to 8.8.8.8 after 60s"; ip addr; ip route; exit 1; fi; sleep 1; done'
227+
echo "=== ip addr ===" && adb shell ip addr
228+
echo "=== ip route ===" && adb shell ip route
229+
echo "=== net.dns1 ===" && adb shell getprop net.dns1
216230
cargo ndk test -p iroh-base --all-features
217231
cargo ndk test -p iroh-dns --features tls-ring
218232
cargo ndk test -p iroh-relay --features tls-ring,metrics

iroh-dns/tests/integration.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,13 @@
66
77
use std::time::Duration;
88

9+
#[cfg(target_os = "android")]
10+
use iroh_dns::dns::DnsProtocol;
911
use iroh_dns::dns::DnsResolver;
1012

1113
const TIMEOUT: Duration = Duration::from_secs(8);
1214
const HOST: &str = "dns.iroh.link";
1315

14-
#[tokio::test]
15-
async fn resolver_constructs_without_panic() {
16-
let _resolver = DnsResolver::new();
17-
}
18-
19-
// Ignored on Android: in the GitHub-hosted emulator the public DNS
20-
// fallback's hickory connection pool repeatedly returns
21-
// "no connections available" within ~30 ms, well before the 8s
22-
// per-lookup timeout, so a resolution that works locally fails in
23-
// CI. Tracking the actual fix separately; see Frando/android-dns-fix.
24-
#[cfg_attr(
25-
target_os = "android",
26-
ignore = "flaky on emulator (no connections available)"
27-
)]
2816
#[tokio::test]
2917
async fn resolver_resolves_dns_iroh_link() {
3018
let resolver = DnsResolver::new();
@@ -54,3 +42,33 @@ async fn resolver_resolves_dns_iroh_link() {
5442
);
5543
eprintln!("{HOST} resolved to: {hits:?}");
5644
}
45+
46+
/// Resolves through the Android emulator's QEMU NAT DNS proxy.
47+
///
48+
/// 10.0.2.3 is the well-known emulator DNS gateway, documented at
49+
/// <https://developer.android.com/studio/run/emulator-networking>.
50+
/// Pointing the resolver at it explicitly sidesteps the missing
51+
/// system-DNS reader (no JNI context here) so this test exercises
52+
/// hickory's pool, sockets, and our `DnsResolver` plumbing against a
53+
/// nameserver that is always reachable inside the emulator,
54+
/// independent of whether public DNS is reachable on the runner.
55+
#[cfg(target_os = "android")]
56+
#[tokio::test]
57+
async fn resolves_via_emulator_dns_proxy() {
58+
let nameserver = "10.0.2.3:53".parse().unwrap();
59+
let resolver = DnsResolver::builder()
60+
.with_nameserver(nameserver, DnsProtocol::Udp)
61+
.build();
62+
63+
let addrs: Vec<_> = resolver
64+
.lookup_ipv4(HOST, TIMEOUT)
65+
.await
66+
.expect("IPv4 lookup via 10.0.2.3 should succeed in the emulator")
67+
.collect();
68+
69+
assert!(
70+
!addrs.is_empty(),
71+
"expected at least one A record for {HOST} via 10.0.2.3",
72+
);
73+
eprintln!("{HOST} resolved via 10.0.2.3 to: {addrs:?}");
74+
}

iroh/tests/integration.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ use wasm_bindgen_test::wasm_bindgen_test as test;
3232

3333
const ECHO_ALPN: &[u8] = b"echo";
3434

35-
// Skipped on Android: Test is flaky in the emulator.
36-
#[cfg_attr(target_os = "android", ignore = "flaky against staging from emulator")]
3735
#[test]
3836
async fn simple_endpoint_id_based_connection_transfer() -> Result {
3937
std::panic::set_hook(Box::new(console_error_panic_hook::hook));

0 commit comments

Comments
 (0)