Skip to content

Commit d5da2d4

Browse files
author
lif
committed
use tokio::time::advance
1 parent aa9da2c commit d5da2d4

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

sled-agent/src/instance.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,7 +1560,7 @@ mod tests {
15601560
use tokio::time::timeout;
15611561

15621562
const TIMEOUT_DURATION: tokio::time::Duration =
1563-
tokio::time::Duration::from_secs(3);
1563+
tokio::time::Duration::from_secs(30);
15641564

15651565
#[derive(Default, Clone)]
15661566
enum ReceivedInstanceState {
@@ -1748,7 +1748,7 @@ mod tests {
17481748
tokio::spawn(storage_manager.run());
17491749
let external_zpool_name = ZpoolName::new_external(Uuid::new_v4());
17501750
let external_disk: RawDisk =
1751-
SyntheticDisk::new(external_zpool_name).into();
1751+
SyntheticDisk::new(external_zpool_name, 0).into();
17521752
storage_handle.upsert_disk(external_disk).await;
17531753
storage_handle
17541754
}
@@ -1913,10 +1913,15 @@ mod tests {
19131913

19141914
let (put_tx, put_rx) = oneshot::channel();
19151915

1916+
// pretending we're InstanceManager::ensure_state, start our "instance"
1917+
// (backed by fakes and propolis_mock_server)
19161918
inst.put_state(put_tx, InstanceStateRequested::Running)
19171919
.await
19181920
.expect("failed to send Instance::put_state");
19191921

1922+
// even though we ignore this result at instance creation time in
1923+
// practice (to avoid request timeouts), in this test let's make sure
1924+
// it actually completes.
19201925
timeout(TIMEOUT_DURATION, put_rx)
19211926
.await
19221927
.expect("timed out waiting for Instance::put_state result")
@@ -1982,11 +1987,21 @@ mod tests {
19821987

19831988
let (put_tx, put_rx) = oneshot::channel();
19841989

1990+
tokio::time::pause();
1991+
1992+
// pretending we're InstanceManager::ensure_state, try in vain to start
1993+
// our "instance", but no propolis server is running
19851994
inst.put_state(put_tx, InstanceStateRequested::Running)
19861995
.await
19871996
.expect("failed to send Instance::put_state");
19881997

1989-
timeout(TIMEOUT_DURATION, put_rx)
1998+
let timeout_fut = timeout(TIMEOUT_DURATION, put_rx);
1999+
2000+
tokio::time::advance(TIMEOUT_DURATION).await;
2001+
2002+
tokio::time::resume();
2003+
2004+
timeout_fut
19902005
.await
19912006
.expect_err("*should've* timed out waiting for Instance::put_state, but didn't?");
19922007

@@ -2010,16 +2025,18 @@ mod tests {
20102025
// automock'd things used during this test
20112026
let _mock_vnic_contexts = mock_vnic_contexts();
20122027

2028+
let rt_handle = tokio::runtime::Handle::current();
2029+
20132030
// time out while booting zone, on purpose!
20142031
let boot_ctx = MockZones::boot_context();
2015-
boot_ctx.expect().return_once(|_| {
2016-
std::thread::sleep(TIMEOUT_DURATION * 2);
2032+
boot_ctx.expect().return_once(move |_| {
2033+
rt_handle.block_on(tokio::time::sleep(TIMEOUT_DURATION * 2));
20172034
Ok(())
20182035
});
20192036
let wait_ctx = illumos_utils::svc::wait_for_service_context();
2020-
wait_ctx.expect().times(1..).returning(|_, _, _| Ok(()));
2037+
wait_ctx.expect().times(..).returning(|_, _, _| Ok(()));
20212038
let zone_id_ctx = MockZones::id_context();
2022-
zone_id_ctx.expect().times(1..).returning(|_| Ok(Some(1)));
2039+
zone_id_ctx.expect().times(..).returning(|_| Ok(Some(1)));
20232040

20242041
let FakeNexusParts { nexus_client, nexus_server, state_rx } =
20252042
FakeNexusParts::new(&logctx);
@@ -2051,13 +2068,23 @@ mod tests {
20512068
.await
20522069
.expect("timed out creating Instance struct");
20532070

2071+
tokio::time::pause();
2072+
20542073
let (put_tx, put_rx) = oneshot::channel();
20552074

2075+
// pretending we're InstanceManager::ensure_state, try in vain to start
2076+
// our "instance", but the zone never finishes installing
20562077
inst.put_state(put_tx, InstanceStateRequested::Running)
20572078
.await
20582079
.expect("failed to send Instance::put_state");
20592080

2060-
timeout(TIMEOUT_DURATION, put_rx)
2081+
let timeout_fut = timeout(TIMEOUT_DURATION, put_rx);
2082+
2083+
tokio::time::advance(TIMEOUT_DURATION * 2).await;
2084+
2085+
tokio::time::resume();
2086+
2087+
timeout_fut
20612088
.await
20622089
.expect_err("*should've* timed out waiting for Instance::put_state, but didn't?");
20632090

sled-agent/src/instance_manager.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ impl InstanceManager {
185185
target: InstanceStateRequested,
186186
) -> Result<InstancePutStateResponse, Error> {
187187
let (tx, rx) = oneshot::channel();
188-
189188
self.inner
190189
.tx
191190
.send(InstanceManagerRequest::EnsureState {
@@ -202,7 +201,10 @@ impl InstanceManager {
202201
// (see InstanceRunner::put_state)
203202
InstanceStateRequested::MigrationTarget(_)
204203
| InstanceStateRequested::Running => {
205-
// don't error on channel being closed
204+
// We don't want the sending side of the channel to see an
205+
// error if we drop rx without awaiting it.
206+
// Since we don't care about the response here, we spawn rx
207+
// into a task which will await it for us in the background.
206208
tokio::spawn(rx);
207209
Ok(InstancePutStateResponse { updated_runtime: None })
208210
}

0 commit comments

Comments
 (0)