Skip to content

Commit c66de3f

Browse files
committed
Restrict the concurrency of the unit tests
Sometimes, running a bunch of Docker containers in parallel can overwhelm the test host. This allows us a control knob to avoid the problem.
1 parent b890003 commit c66de3f

File tree

5 files changed

+79
-8
lines changed

5 files changed

+79
-8
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ jobs:
222222
name: frontend
223223
path: tests/server/build/
224224
- name: Run orchestrator unit tests
225+
env:
226+
TESTS_MAX_CONCURRENCY: 3
225227
run: chmod +x ./server/unit_tests_orchestrator && ./server/unit_tests_orchestrator
226228
- name: Run ui unit tests
227229
run: chmod +x ./server/unit_tests_ui && ./server/unit_tests_ui

ci/workflows.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ workflows:
312312
path: tests/server/build/
313313

314314
- name: "Run orchestrator unit tests"
315+
env:
316+
TESTS_MAX_CONCURRENCY: 3
315317
run: |-
316318
chmod +x ./server/unit_tests_orchestrator && ./server/unit_tests_orchestrator
317319

compiler/base/orchestrator/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/base/orchestrator/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ tracing = { version = "0.1.37", default-features = false, features = ["attribute
2222
[dev-dependencies]
2323
assert_matches = "1.5.0"
2424
assertables = "7.0.1"
25+
once_cell = "1.18.0"
2526
tempdir = "0.3.7"
2627
tracing-subscriber = "0.3.17"

compiler/base/orchestrator/src/coordinator.rs

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,8 +1709,10 @@ fn spawn_io_queue(stdin: ChildStdin, stdout: ChildStdout, token: CancellationTok
17091709
mod tests {
17101710
use assertables::*;
17111711
use futures::{future::try_join_all, Future, FutureExt};
1712-
use std::{sync::Once, time::Duration};
1712+
use once_cell::sync::Lazy;
1713+
use std::{env, sync::Once, time::Duration};
17131714
use tempdir::TempDir;
1715+
use tokio::sync::{OwnedSemaphorePermit, Semaphore};
17141716

17151717
use super::*;
17161718

@@ -1774,15 +1776,78 @@ mod tests {
17741776
}
17751777
}
17761778

1777-
async fn new_coordinator() -> Coordinator<impl Backend> {
1779+
const MAX_CONCURRENT_TESTS: Lazy<usize> = Lazy::new(|| {
1780+
env::var("TESTS_MAX_CONCURRENCY")
1781+
.ok()
1782+
.and_then(|v| v.parse().ok())
1783+
.unwrap_or(5)
1784+
});
1785+
1786+
static CONCURRENT_TEST_SEMAPHORE: Lazy<Arc<Semaphore>> =
1787+
Lazy::new(|| Arc::new(Semaphore::new(*MAX_CONCURRENT_TESTS)));
1788+
1789+
struct RestrictedCoordinator<T> {
1790+
_permit: OwnedSemaphorePermit,
1791+
coordinator: Coordinator<T>,
1792+
}
1793+
1794+
impl<T> RestrictedCoordinator<T>
1795+
where
1796+
T: Backend,
1797+
{
1798+
async fn with<F, Fut>(f: F) -> Self
1799+
where
1800+
F: FnOnce() -> Fut,
1801+
Fut: Future<Output = Coordinator<T>>,
1802+
{
1803+
let semaphore = CONCURRENT_TEST_SEMAPHORE.clone();
1804+
let permit = semaphore
1805+
.acquire_owned()
1806+
.await
1807+
.expect("Unable to acquire permit");
1808+
let coordinator = f().await;
1809+
Self {
1810+
_permit: permit,
1811+
coordinator,
1812+
}
1813+
}
1814+
1815+
async fn shutdown(self) -> super::Result<T, super::Error> {
1816+
self.coordinator.shutdown().await
1817+
}
1818+
}
1819+
1820+
impl<T> ops::Deref for RestrictedCoordinator<T> {
1821+
type Target = Coordinator<T>;
1822+
1823+
fn deref(&self) -> &Self::Target {
1824+
&self.coordinator
1825+
}
1826+
}
1827+
1828+
impl<T> ops::DerefMut for RestrictedCoordinator<T> {
1829+
fn deref_mut(&mut self) -> &mut Self::Target {
1830+
&mut self.coordinator
1831+
}
1832+
}
1833+
1834+
async fn new_coordinator_test() -> RestrictedCoordinator<impl Backend> {
1835+
RestrictedCoordinator::with(|| Coordinator::new(TestBackend::new())).await
1836+
}
1837+
1838+
async fn new_coordinator_docker() -> RestrictedCoordinator<impl Backend> {
1839+
RestrictedCoordinator::with(|| Coordinator::new_docker()).await
1840+
}
1841+
1842+
async fn new_coordinator() -> RestrictedCoordinator<impl Backend> {
17781843
#[cfg(not(force_docker))]
17791844
{
1780-
Coordinator::new(TestBackend::new()).await
1845+
new_coordinator_test().await
17811846
}
17821847

17831848
#[cfg(force_docker)]
17841849
{
1785-
Coordinator::new_docker().await
1850+
new_coordinator_docker().await
17861851
}
17871852
}
17881853

@@ -2472,7 +2537,7 @@ mod tests {
24722537
#[snafu::report]
24732538
async fn compile_wasm() -> Result<()> {
24742539
// cargo-wasm only exists inside the container
2475-
let coordinator = Coordinator::new_docker().await;
2540+
let coordinator = new_coordinator_docker().await;
24762541

24772542
let req = CompileRequest {
24782543
target: CompileTarget::Wasm,
@@ -2703,7 +2768,7 @@ mod tests {
27032768
#[snafu::report]
27042769
async fn network_connections_are_disabled() -> Result<()> {
27052770
// The limits are only applied to the container
2706-
let coordinator = Coordinator::new_docker().await;
2771+
let coordinator = new_coordinator_docker().await;
27072772

27082773
let req = ExecuteRequest {
27092774
code: r#"
@@ -2729,7 +2794,7 @@ mod tests {
27292794
#[snafu::report]
27302795
async fn memory_usage_is_limited() -> Result<()> {
27312796
// The limits are only applied to the container
2732-
let coordinator = Coordinator::new_docker().await;
2797+
let coordinator = new_coordinator_docker().await;
27332798

27342799
let req = ExecuteRequest {
27352800
code: r#"
@@ -2756,7 +2821,7 @@ mod tests {
27562821
#[snafu::report]
27572822
async fn number_of_pids_is_limited() -> Result<()> {
27582823
// The limits are only applied to the container
2759-
let coordinator = Coordinator::new_docker().await;
2824+
let coordinator = new_coordinator_docker().await;
27602825

27612826
let req = ExecuteRequest {
27622827
code: r##"

0 commit comments

Comments
 (0)