Start the whole HQ server, including almost all bells and whistles, and then run a future that will perform the actual test on it. After the future finishes, the server will be shut down. If you need to configure the server, add parameters (or some builder) here.
(test_fn: F)
| 34 | /// |
| 35 | /// If you need to configure the server, add parameters (or some builder) here. |
| 36 | pub async fn run_hq_test<F, Fut>(test_fn: F) |
| 37 | where |
| 38 | // We pass the server by value and return it because of problematic lifetimes |
| 39 | // with the closure + future combination. Async closures should fix this. |
| 40 | F: FnOnce(RunningHqServer) -> Fut, |
| 41 | Fut: Future<Output = anyhow::Result<RunningHqServer>>, |
| 42 | { |
| 43 | let tmp_dir = TempDir::with_prefix("hq-test").unwrap(); |
| 44 | |
| 45 | let gsettings = GlobalSettings::new( |
| 46 | tmp_dir.path().to_path_buf(), |
| 47 | Box::new(CliOutput::new(ColorChoice::Never)), |
| 48 | ); |
| 49 | let server_cfg = ServerConfig { |
| 50 | worker_host: "localhost".to_string(), |
| 51 | client_host: "localhost".to_string(), |
| 52 | idle_timeout: None, |
| 53 | client_port: None, |
| 54 | worker_port: None, |
| 55 | journal_path: None, |
| 56 | journal_flush_period: Duration::from_secs(30), |
| 57 | worker_secret_key: None, |
| 58 | client_secret_key: None, |
| 59 | server_uid: None, |
| 60 | }; |
| 61 | let (fut, notify, _state, _senders) = |
| 62 | initialize_server(&gsettings, server_cfg, 1.into(), 1, None) |
| 63 | .await |
| 64 | .unwrap(); |
| 65 | let localset = LocalSet::new(); |
| 66 | |
| 67 | // Run the server in the background, concurrently with the testing future |
| 68 | let server_fut = localset.spawn_local(fut); |
| 69 | |
| 70 | let server = RunningHqServer { |
| 71 | dir: tmp_dir.path().to_path_buf(), |
| 72 | notify_quit: true, |
| 73 | }; |
| 74 | // Run the test itself. If it fails, we still try to finish the server itself, |
| 75 | // for better error propagation. |
| 76 | let test_error = localset.run_until(test_fn(server)).await; |
| 77 | let notify_quit = test_error.as_ref().map(|s| s.notify_quit).unwrap_or(true); |
| 78 | |
| 79 | // Tell the server to quit if the test didn't opt out |
| 80 | if notify_quit { |
| 81 | notify.notify_one(); |
| 82 | } |
| 83 | |
| 84 | // Wait for it to quit. Panics will be propagated from `run_until`. |
| 85 | let server_error = localset |
| 86 | .run_until(async move { |
| 87 | match timeout(Duration::from_secs(5), server_fut).await { |
| 88 | Ok(res) => res.unwrap(), |
| 89 | Err(_) => { |
| 90 | panic!("The server has not finished in 5 seconds. Maybe there is a deadlock?") |
| 91 | } |
| 92 | } |
| 93 | }) |