[netemul] Deny unused results

Bug: 73468
Change-Id: I2fbf759d850db98f5896c1530d4593ec5f43209a
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/514653
Fuchsia-Auto-Submit: Bruno Dal Bo <brunodalbo@google.com>
Reviewed-by: Jay Zhuang <jayzhuang@google.com>
Reviewed-by: Tamir Duberstein <tamird@google.com>
Reviewed-by: Peter Johnston <peterjohnston@google.com>
Commit-Queue: Bruno Dal Bo <brunodalbo@google.com>
diff --git a/build/config/rust/BUILD.gn b/build/config/rust/BUILD.gn
index 5b9e4c4..8992d65 100644
--- a/build/config/rust/BUILD.gn
+++ b/build/config/rust/BUILD.gn
@@ -146,7 +146,6 @@
     "//src/connectivity/network/lib/*",
     "//src/connectivity/network/netstack/*",
     "//src/connectivity/network/netstack3/*",
-    "//src/connectivity/network/testing/netemul/*",
     "//src/connectivity/network/tests/connect/*",
     "//src/connectivity/network/tests/dhcp_interop/*",
     "//src/connectivity/network/tools/*",
diff --git a/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/BUILD.gn b/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/BUILD.gn
index a650ddd..4c8de72 100644
--- a/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/BUILD.gn
@@ -25,4 +25,6 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
diff --git a/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/src/main.rs b/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/src/main.rs
index 941859f..d0509f0 100644
--- a/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/src/main.rs
+++ b/src/connectivity/network/testing/netemul/runner/helpers/mock_device_settings/src/main.rs
@@ -8,10 +8,9 @@
     Status, ValueType,
 };
 use fuchsia_async as fasync;
-use fuchsia_component::server::ServiceFs;
-use futures::{future, StreamExt, TryFutureExt, TryStreamExt};
+use fuchsia_component::server::{ServiceFs, ServiceFsDir};
+use futures::{lock::Mutex, StreamExt, TryStreamExt};
 use std::collections::HashMap;
-use std::sync::{Arc, Mutex};
 use structopt::StructOpt;
 
 #[derive(StructOpt, Debug)]
@@ -28,6 +27,7 @@
     int_key: Vec<String>,
 }
 
+#[derive(Debug)]
 enum Key {
     StringKey(String),
     IntKey(i64),
@@ -65,107 +65,112 @@
     for s_key in opt.string_key {
         let (k, v) = split_once(&s_key)?;
         log::info!("Startup {}={}", k, v);
-        state.keys.insert(String::from(k), Key::StringKey(String::from(v)));
+        if let Some(previous_value) =
+            state.keys.insert(String::from(k), Key::StringKey(String::from(v)))
+        {
+            panic!("duplicate key {}={} in startup, previously set to {:?}", k, v, previous_value);
+        }
     }
 
     for i_key in opt.int_key {
         let (k, v) = split_once(&i_key)?;
         let v = v.parse::<i64>()?;
         log::info!("Startup {}={}", k, v);
-        state.keys.insert(String::from(k), Key::IntKey(v));
+        if let Some(previous_value) = state.keys.insert(String::from(k), Key::IntKey(v)) {
+            panic!("duplicate key {}={} in startup, previously set to {:?}", k, v, previous_value);
+        }
     }
 
     Ok(())
 }
 
-fn spawn_device_settings_server(
-    state: Arc<Mutex<DeviceSettingsManagerServer>>,
+async fn run_request_stream(
+    state: &Mutex<DeviceSettingsManagerServer>,
     stream: DeviceSettingsManagerRequestStream,
 ) {
-    fasync::Task::spawn(
-        stream
-            .try_for_each(move |req| {
-                let mut state = state.lock().unwrap();
-                future::ready(match req {
-                    DeviceSettingsManagerRequest::GetInteger { key, responder } => {
-                        match state.keys.get(&key) {
-                            None => {
-                                log::info!("Key {} doesn't exist", key);
-                                responder.send(0, Status::ErrNotSet)
-                            }
-                            Some(Key::IntKey(val)) => responder.send(*val, Status::Ok),
-                            _ => {
-                                log::info!("Key {} is not an integer", key);
-                                responder.send(0, Status::ErrIncorrectType)
-                            }
+    stream
+        .try_for_each(move |req| async move {
+            let mut state = state.lock().await;
+            match req {
+                DeviceSettingsManagerRequest::GetInteger { key, responder } => {
+                    match state.keys.get(&key) {
+                        None => {
+                            log::info!("Key {} doesn't exist", key);
+                            responder.send(0, Status::ErrNotSet)
+                        }
+                        Some(Key::IntKey(val)) => responder.send(*val, Status::Ok),
+                        _ => {
+                            log::info!("Key {} is not an integer", key);
+                            responder.send(0, Status::ErrIncorrectType)
                         }
                     }
-                    DeviceSettingsManagerRequest::GetString { key, responder } => {
-                        match state.keys.get(&key) {
-                            None => {
-                                log::info!("Key {} doesn't exist", key);
-                                responder.send("", Status::ErrNotSet)
-                            }
-                            Some(Key::StringKey(val)) => responder.send(val, Status::Ok),
-                            _ => {
-                                log::info!("Key {} is not a string", key);
-                                responder.send("", Status::ErrIncorrectType)
-                            }
+                }
+                DeviceSettingsManagerRequest::GetString { key, responder } => {
+                    match state.keys.get(&key) {
+                        None => {
+                            log::info!("Key {} doesn't exist", key);
+                            responder.send("", Status::ErrNotSet)
+                        }
+                        Some(Key::StringKey(val)) => responder.send(val, Status::Ok),
+                        _ => {
+                            log::info!("Key {} is not a string", key);
+                            responder.send("", Status::ErrIncorrectType)
                         }
                     }
-                    DeviceSettingsManagerRequest::SetInteger { key, val, responder } => {
-                        match state.keys.get(&key) {
-                            Some(Key::IntKey(_)) => {
-                                log::info!("Set {}={}", key, val);
-                                state.run_watchers(&key, ValueType::Number);
-                                state.keys.insert(key, Key::IntKey(val));
-                                responder.send(true)
-                            }
-                            _ => {
-                                log::info!("Failed to set integer key {}={}", key, val);
-                                responder.send(false)
-                            }
+                }
+                DeviceSettingsManagerRequest::SetInteger { key, val, responder } => {
+                    match state.keys.get(&key) {
+                        Some(Key::IntKey(_)) => {
+                            log::info!("Set {}={}", key, val);
+                            state.run_watchers(&key, ValueType::Number);
+                            let _: Option<Key> = state.keys.insert(key, Key::IntKey(val));
+                            responder.send(true)
+                        }
+                        _ => {
+                            log::info!("Failed to set integer key {}={}", key, val);
+                            responder.send(false)
                         }
                     }
-                    DeviceSettingsManagerRequest::SetString { key, val, responder } => {
-                        match state.keys.get(&key) {
-                            Some(Key::StringKey(_)) => {
-                                log::info!("Set {}={}", key, val);
-                                state.run_watchers(&key, ValueType::Text);
-                                state.keys.insert(key, Key::StringKey(val));
-                                responder.send(true)
-                            }
-                            _ => {
-                                log::info!("Failed to set string key {}={}", key, val);
-                                responder.send(false)
-                            }
+                }
+                DeviceSettingsManagerRequest::SetString { key, val, responder } => {
+                    match state.keys.get(&key) {
+                        Some(Key::StringKey(_)) => {
+                            log::info!("Set {}={}", key, val);
+                            state.run_watchers(&key, ValueType::Text);
+                            let _: Option<Key> = state.keys.insert(key, Key::StringKey(val));
+                            responder.send(true)
+                        }
+                        _ => {
+                            log::info!("Failed to set string key {}={}", key, val);
+                            responder.send(false)
                         }
                     }
-                    DeviceSettingsManagerRequest::Watch { key, watcher, responder } => {
-                        match state.keys.get(&key) {
-                            None => {
-                                log::info!("Can't watch key {}, it doesn't exist", key);
-                                responder.send(Status::ErrInvalidSetting)
-                            }
-                            _ => match watcher.into_proxy() {
-                                Ok(watcher) => {
-                                    let mv = state.watchers.entry(key).or_insert(Vec::new());
-                                    mv.push(watcher);
-                                    responder.send(Status::Ok)
-                                }
-                                Err(e) => {
-                                    log::info!("Error watching key {}: {}", key, e);
-                                    responder.send(Status::ErrUnknown)
-                                }
-                            },
+                }
+                DeviceSettingsManagerRequest::Watch { key, watcher, responder } => {
+                    match state.keys.get(&key) {
+                        None => {
+                            log::info!("Can't watch key {}, it doesn't exist", key);
+                            responder.send(Status::ErrInvalidSetting)
                         }
+                        _ => match watcher.into_proxy() {
+                            Ok(watcher) => {
+                                let mv = state.watchers.entry(key).or_insert(Vec::new());
+                                mv.push(watcher);
+                                responder.send(Status::Ok)
+                            }
+                            Err(e) => {
+                                log::info!("Error watching key {}: {}", key, e);
+                                responder.send(Status::ErrUnknown)
+                            }
+                        },
                     }
-                })
-            })
-            .map_ok(|_| ())
-            .unwrap_or_else(|e| log::error!("error running mock device settings server: {:?}", e)),
-    )
-    .detach();
+                }
+            }
+        })
+        .await
+        .unwrap_or_else(|e| {
+            log::error!("error running mock device settings server: {:?}", e);
+        })
 }
 
 #[fasync::run_singlethreaded]
@@ -175,12 +180,12 @@
     let opt = Opt::from_args();
     let mut state = DeviceSettingsManagerServer { keys: HashMap::new(), watchers: HashMap::new() };
     let () = config_state(&mut state, opt)?;
-    let state = Arc::new(Mutex::new(state));
+    let state = Mutex::new(state);
     let mut fs = ServiceFs::new();
-    fs.dir("svc")
-        .add_fidl_service(move |stream| spawn_device_settings_server(state.clone(), stream));
-    fs.take_and_serve_directory_handle()?;
-    let () = fs.collect().await;
+    let _: &mut ServiceFsDir<'_, _> =
+        fs.dir("svc").add_fidl_service(|stream: DeviceSettingsManagerRequestStream| stream);
+    let _: &mut ServiceFs<_> = fs.take_and_serve_directory_handle()?;
+    let () = fs.for_each_concurrent(None, |stream| run_request_stream(&state, stream)).await;
     Ok(())
 }
 
@@ -249,6 +254,10 @@
                 }
             });
 
-        wait_watch.try_next().await.unwrap();
+        let () = wait_watch
+            .try_next()
+            .await
+            .expect("failed to watch")
+            .expect("stream ended unexpectedly");
     }
 }
diff --git a/src/connectivity/network/testing/netemul/runner/helpers/netstack_cfg/BUILD.gn b/src/connectivity/network/testing/netemul/runner/helpers/netstack_cfg/BUILD.gn
index 342099f..8690f1d 100644
--- a/src/connectivity/network/testing/netemul/runner/helpers/netstack_cfg/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/helpers/netstack_cfg/BUILD.gn
@@ -30,4 +30,6 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
diff --git a/src/connectivity/network/testing/netemul/runner/test/dummy_proc/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/dummy_proc/BUILD.gn
index b0d5fb3..00a7be0 100644
--- a/src/connectivity/network/testing/netemul/runner/test/dummy_proc/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/dummy_proc/BUILD.gn
@@ -24,6 +24,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("dummy_proc") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/dummy_proc/src/main.rs b/src/connectivity/network/testing/netemul/runner/test/dummy_proc/src/main.rs
index e304351..daf0764 100644
--- a/src/connectivity/network/testing/netemul/runner/test/dummy_proc/src/main.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/dummy_proc/src/main.rs
@@ -73,9 +73,12 @@
                 }
                 None => futures::future::ok(None),
             },
-            _ => futures::future::ok(None),
+            fidl_fuchsia_netemul_sync::BusEvent::OnClientAttached { client: _ }
+            | fidl_fuchsia_netemul_sync::BusEvent::OnClientDetached { client: _ } => {
+                futures::future::ok(None)
+            }
         });
-        stream.try_next().await?;
+        let () = stream.try_next().await?.context("event stream ended unexpectedly")?;
         Ok(())
     }
 
diff --git a/src/connectivity/network/testing/netemul/runner/test/dynamic_devices/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/dynamic_devices/BUILD.gn
index b7c4834..5531d8b 100644
--- a/src/connectivity/network/testing/netemul/runner/test/dynamic_devices/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/dynamic_devices/BUILD.gn
@@ -23,6 +23,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("dynamic_devices") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/BUILD.gn
index 5aadd23..2bb7bb7 100644
--- a/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/BUILD.gn
@@ -27,6 +27,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("easy_netstack_cfg") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/src/main.rs b/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/src/main.rs
index 9ff5d77..edab8c8 100644
--- a/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/src/main.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/easy_netstack_cfg/src/main.rs
@@ -63,7 +63,10 @@
             return Err(format_err!("Got unexpected request from client: {}", req));
         }
         log::info!("Got request {}", req);
-        stream.write(HELLO_MSG_RSP.as_bytes()).context("write failed")?;
+        assert_eq!(
+            stream.write(HELLO_MSG_RSP.as_bytes()).context("write failed")?,
+            HELLO_MSG_RSP.as_bytes().len()
+        );
         stream.flush().context("flush failed")?;
     }
 
@@ -88,7 +91,7 @@
         let addr: SocketAddr = format!("{}:{}", ip, PORT).parse()?;
         let mut stream = TcpStream::connect(&addr).context("Tcp connection failed")?;
         let request = HELLO_MSG_REQ.as_bytes();
-        stream.write(request)?;
+        assert_eq!(stream.write(request)?, request.len());
         stream.flush()?;
 
         let mut buffer = [0; 512];
diff --git a/src/connectivity/network/testing/netemul/runner/test/env_build/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/env_build/BUILD.gn
index eef8864..7fb15bb 100644
--- a/src/connectivity/network/testing/netemul/runner/test/env_build/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/env_build/BUILD.gn
@@ -24,6 +24,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("env_build") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/env_build/src/main.rs b/src/connectivity/network/testing/netemul/runner/test/env_build/src/main.rs
index 326f051..3fec890 100644
--- a/src/connectivity/network/testing/netemul/runner/test/env_build/src/main.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/env_build/src/main.rs
@@ -74,7 +74,7 @@
             },
             _ => futures::future::ok(None),
         });
-        stream.try_next().await?;
+        let () = stream.try_next().await?.context("event stream ended unexpectedly")?;
         Ok(())
     }
 }
diff --git a/src/connectivity/network/testing/netemul/runner/test/guest/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/guest/BUILD.gn
index 93df169..e23b381 100644
--- a/src/connectivity/network/testing/netemul/runner/test/guest/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/guest/BUILD.gn
@@ -27,6 +27,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 rustc_library("lib") {
@@ -44,6 +46,8 @@
   ]
 
   sources = [ "src/lib.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("guest") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/guest/src/lib.rs b/src/connectivity/network/testing/netemul/runner/test/guest/src/lib.rs
index 5617f41..14101f0 100644
--- a/src/connectivity/network/testing/netemul/runner/test/guest/src/lib.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/guest/src/lib.rs
@@ -72,7 +72,7 @@
                 zx::ok(status)?;
 
                 if let Some((stdin_socket, to_write)) = stdin.as_ref() {
-                    stdin_socket.write(to_write.as_bytes())?;
+                    assert_eq!(stdin_socket.write(to_write.as_bytes())?, to_write.as_bytes().len());
                 }
             }
             CommandListenerEvent::OnTerminated { status, return_code } => {
diff --git a/src/connectivity/network/testing/netemul/runner/test/guest/src/main.rs b/src/connectivity/network/testing/netemul/runner/test/guest/src/main.rs
index 1a6c296..26163d6 100644
--- a/src/connectivity/network/testing/netemul/runner/test/guest/src/main.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/guest/src/main.rs
@@ -54,10 +54,10 @@
     let mut copy_contents = String::new();
 
     let mut original_file = File::open(local_test_data)?;
-    original_file.read_to_string(&mut original_contents)?;
+    let _read: usize = original_file.read_to_string(&mut original_contents)?;
 
     let mut verification_file = File::open(verification_copy)?;
-    verification_file.read_to_string(&mut copy_contents)?;
+    let _read: usize = verification_file.read_to_string(&mut copy_contents)?;
 
     assert_eq!(original_contents, copy_contents);
 
@@ -112,12 +112,12 @@
     // Validate the stdout and stderr.
     let mut guest_stdout = Vec::new();
     let mut stdout_socket = fasync::Socket::from_socket(stdout_0)?;
-    stdout_socket.read_to_end(&mut guest_stdout).await?;
+    let _read: usize = stdout_socket.read_to_end(&mut guest_stdout).await?;
     assert_eq!(std::str::from_utf8(&guest_stdout)?.trim(), stdout_expected_string);
 
     let mut guest_stderr = Vec::new();
     let mut stderr_socket = fasync::Socket::from_socket(stderr_0)?;
-    stderr_socket.read_to_end(&mut guest_stderr).await?;
+    let _read: usize = stderr_socket.read_to_end(&mut guest_stderr).await?;
     assert_eq!(std::str::from_utf8(&guest_stderr)?.trim(), stderr_expected_string);
 
     // Pull the file that was created by the script and validate its contents.
@@ -133,7 +133,7 @@
 
     let mut file_contents = String::new();
     let mut stdin_file = File::open(local_copy)?;
-    stdin_file.read_to_string(&mut file_contents)?;
+    let _read: usize = stdin_file.read_to_string(&mut file_contents)?;
 
     assert_eq!(file_contents, stdin_input.to_string());
 
diff --git a/src/connectivity/network/testing/netemul/runner/test/guest_grpc_stress/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/guest_grpc_stress/BUILD.gn
index 5e0907b..f597a2e 100644
--- a/src/connectivity/network/testing/netemul/runner/test/guest_grpc_stress/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/guest_grpc_stress/BUILD.gn
@@ -26,6 +26,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("guest_grpc_stress") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/inheritance/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/inheritance/BUILD.gn
index 2388773..9ac8068 100644
--- a/src/connectivity/network/testing/netemul/runner/test/inheritance/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/inheritance/BUILD.gn
@@ -31,6 +31,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("inheritance") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/inheritance/src/main.rs b/src/connectivity/network/testing/netemul/runner/test/inheritance/src/main.rs
index e78b80f..5efb1fd 100644
--- a/src/connectivity/network/testing/netemul/runner/test/inheritance/src/main.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/inheritance/src/main.rs
@@ -12,7 +12,7 @@
     },
     fuchsia_async as fasync,
     fuchsia_component::client,
-    fuchsia_component::server::ServiceFs,
+    fuchsia_component::server::{ServiceFs, ServiceFsDir},
     futures::prelude::*,
     std::sync::Arc,
     std::sync::Mutex,
@@ -145,9 +145,14 @@
 }
 
 async fn run_no_inherit() -> Result<(), Error> {
-    simple_increment(1)
+    let err = simple_increment(1)
         .await
-        .expect_err("Shouldn't be able to use service due to inheritance setup");
+        .expect_err("Shouldn't be able to use service due to inheritance setup")
+        .downcast::<fidl::Error>()
+        .expect("unexpected error type");
+    // We can get different types of FIDL closing errors, assert broadly on closed-type errors to
+    // avoid races.
+    assert!(err.is_closed(), "FIDL error should be PEER_CLOSED: {:?}", err);
     Ok(())
 }
 
@@ -176,8 +181,9 @@
 async fn run_server() -> Result<(), Error> {
     let data = Arc::new(Mutex::new(CounterData { value: 0 }));
     let mut fs = ServiceFs::new();
-    fs.dir("svc").add_fidl_service(move |chan| spawn_counter_server(chan, data.clone()));
-    fs.take_and_serve_directory_handle()?;
+    let _: &mut ServiceFsDir<'_, _> =
+        fs.dir("svc").add_fidl_service(move |chan| spawn_counter_server(chan, data.clone()));
+    let _: &mut ServiceFs<_> = fs.take_and_serve_directory_handle()?;
     let () = fs.collect().await;
     Ok(())
 }
diff --git a/src/connectivity/network/testing/netemul/runner/test/multiple_guests/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/multiple_guests/BUILD.gn
index d68af84..cafbfc3 100644
--- a/src/connectivity/network/testing/netemul/runner/test/multiple_guests/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/multiple_guests/BUILD.gn
@@ -26,6 +26,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("multiple_guests") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/BUILD.gn
index 4144ec8..194963f 100644
--- a/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/BUILD.gn
@@ -28,6 +28,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("netstack_intermediary") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/src/main.rs b/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/src/main.rs
index 60ab0ef..9c4a149 100644
--- a/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/src/main.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/netstack_intermediary/src/main.rs
@@ -79,7 +79,10 @@
     let echo_string = String::from("hello");
 
     let bus = open_bus(&ep_name)?;
-    bus.wait_for_clients(&mut vec![server_name.as_str()].drain(..), 0).await?;
+    let (success, absent) =
+        bus.wait_for_clients(&mut vec![server_name.as_str()].drain(..), 0).await?;
+    assert!(success);
+    assert_eq!(absent, None);
 
     fake_ep.write(echo_string.as_bytes()).await.context("write failed")?;
 
@@ -145,10 +148,11 @@
             ethernet::Event::Receive(rx, _flags) => {
                 if !sent_response {
                     let mut data: [u8; 100] = [0; 100];
-                    rx.read(&mut data);
-                    let user_message = str::from_utf8(&data[0..rx.len() as usize]).unwrap();
+                    let sz = rx.read(&mut data);
+                    let user_message =
+                        str::from_utf8(&data[0..sz]).expect("failed to parse string");
                     println!("From client: {}", user_message);
-                    eth_client.send(&data[0..rx.len() as usize]);
+                    let () = eth_client.send(&data[0..sz]);
                     sent_response = true;
 
                     // Start listening for the server's response to be
diff --git a/src/connectivity/network/testing/netemul/runner/test/netstack_socks/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/netstack_socks/BUILD.gn
index 25c5fe9..4d353f3 100644
--- a/src/connectivity/network/testing/netemul/runner/test/netstack_socks/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/netstack_socks/BUILD.gn
@@ -35,6 +35,8 @@
     "src/common.rs",
     "src/main.rs",
   ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("netstack_socks") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/netstack_socks/src/child.rs b/src/connectivity/network/testing/netemul/runner/test/netstack_socks/src/child.rs
index b49d96af..aa9d5e4 100644
--- a/src/connectivity/network/testing/netemul/runner/test/netstack_socks/src/child.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/netstack_socks/src/child.rs
@@ -46,7 +46,10 @@
     }
     println!("Got request ({} bytes) '{}'", rd, req);
     println!("Sending response '{}'", HELLO_MSG_RSP);
-    stream.write(HELLO_MSG_RSP.as_bytes()).context("write failed")?;
+    assert_eq!(
+        stream.write(HELLO_MSG_RSP.as_bytes()).context("write failed")?,
+        HELLO_MSG_RSP.as_bytes().len()
+    );
     stream.flush().context("flush failed")?;
     println!("Server done");
     Ok(())
@@ -59,7 +62,7 @@
     println!("Connected to server!");
     let request = HELLO_MSG_REQ.as_bytes();
     println!("Sending message '{}'", HELLO_MSG_REQ);
-    stream.write(request).context("write failed")?;
+    assert_eq!(stream.write(request).context("write failed")?, request.len());
     stream.flush().context("flush failed")?;
 
     let mut buffer = [0; 512];
diff --git a/src/connectivity/network/testing/netemul/runner/test/network_device/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/network_device/BUILD.gn
index 9ba8755..8fda2a2 100644
--- a/src/connectivity/network/testing/netemul/runner/test/network_device/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/network_device/BUILD.gn
@@ -19,6 +19,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("network_device") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/sandbox_service/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/sandbox_service/BUILD.gn
index 677ef66..a94b375 100644
--- a/src/connectivity/network/testing/netemul/runner/test/sandbox_service/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/sandbox_service/BUILD.gn
@@ -24,4 +24,6 @@
   ]
 
   sources = [ "src/lib.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
diff --git a/src/connectivity/network/testing/netemul/runner/test/sandbox_service/src/lib.rs b/src/connectivity/network/testing/netemul/runner/test/sandbox_service/src/lib.rs
index 3d56c19..46b70e2 100644
--- a/src/connectivity/network/testing/netemul/runner/test/sandbox_service/src/lib.rs
+++ b/src/connectivity/network/testing/netemul/runner/test/sandbox_service/src/lib.rs
@@ -88,6 +88,10 @@
         get_network_from_context(&netctx, name).await
     }
 
+    #[derive(thiserror::Error, Debug)]
+    #[error("network not found")]
+    struct NetworkNotFoundError {}
+
     async fn get_network_from_context<'a>(
         netctx: &'a NetworkContextProxy,
         name: &'a str,
@@ -96,7 +100,7 @@
         netctx.get_network_manager(netmgr_server_end)?;
         let network = netmgr.get_network(name).await?;
 
-        Ok(network.ok_or_else(|| format_err!("can't create network"))?.into_proxy()?)
+        Ok(network.ok_or(NetworkNotFoundError {})?.into_proxy()?)
     }
 
     async fn get_on_bus_from_env<'a>(
@@ -172,12 +176,14 @@
         let net3_retrieve = get_network(&env3, "network").await;
         assert!(net3_retrieve.is_err(), "net should not exist in env3");
 
-        get_network_from_context(&netctx1, "network")
+        let _: NetworkProxy = get_network_from_context(&netctx1, "network")
             .await
-            .expect("Should be able to retrieve net from sandbox 1");
-        get_network_from_context(&netctx2, "network")
+            .expect("should be able to retrieve net from sandbox 1");
+        let NetworkNotFoundError {} = get_network_from_context(&netctx2, "network")
             .await
-            .expect_err("Shouldn't be able retrieve net from sandbox 2");
+            .expect_err("shouldn't be able retrieve net from sandbox 2")
+            .downcast::<NetworkNotFoundError>()
+            .expect("unexpected error from context");
     }
 
     #[fasync::run_singlethreaded]
diff --git a/src/connectivity/network/testing/netemul/runner/test/svc_list/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/svc_list/BUILD.gn
index ad45495..e4b1554 100644
--- a/src/connectivity/network/testing/netemul/runner/test/svc_list/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/svc_list/BUILD.gn
@@ -26,6 +26,8 @@
   ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("svc_list") {
diff --git a/src/connectivity/network/testing/netemul/runner/test/virtual_device_directory/BUILD.gn b/src/connectivity/network/testing/netemul/runner/test/virtual_device_directory/BUILD.gn
index e661806..6edd494 100644
--- a/src/connectivity/network/testing/netemul/runner/test/virtual_device_directory/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/runner/test/virtual_device_directory/BUILD.gn
@@ -11,6 +11,8 @@
   deps = [ "//third_party/rust_crates:anyhow" ]
 
   sources = [ "src/main.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }
 
 fuchsia_component("virtual_device_directory") {
diff --git a/src/connectivity/network/testing/netemul/rust/BUILD.gn b/src/connectivity/network/testing/netemul/rust/BUILD.gn
index 89a6c72..3c86aa7 100644
--- a/src/connectivity/network/testing/netemul/rust/BUILD.gn
+++ b/src/connectivity/network/testing/netemul/rust/BUILD.gn
@@ -35,4 +35,6 @@
   ]
 
   sources = [ "src/lib.rs" ]
+
+  configs -= [ "//build/config/rust:allow_unused_results" ]
 }