Skip to content

Commit facb127

Browse files
authored
feat(bin): add --shutdown-timeout to set a timeout for shutting down the database connections after a test file is finished (#265)
1 parent 3a3ddc0 commit facb127

File tree

5 files changed

+68
-33
lines changed

5 files changed

+68
-33
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
uses: actions-rs/cargo@v1
6969
with:
7070
command: install
71-
args: cargo-semver-checks --version ^0.39 --locked
71+
args: cargo-semver-checks --version ^0.41 --locked
7272
- name: Check semver
7373
run: |
7474
cargo semver-checks check-release -p sqllogictest

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
## [0.28.3] - 2025-05-16
11+
12+
* bin: Add `--shutdown-timeout` to set a timeout for shutting down the database connections after a test file is finished. By default, this is unspecified, meaning to wait forever.
13+
1014
## [0.28.2] - 2025-05-07
1115

1216
* engines: Enhance graceful shutdown by canceling ongoing queries when shutting down postgres connections. This improves the behavior when receiving a `Ctrl-C` signal by ensuring that any long-running queries are properly canceled before the connection is closed.

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resolver = "2"
33
members = ["sqllogictest", "sqllogictest-bin", "sqllogictest-engines", "tests"]
44

55
[workspace.package]
6-
version = "0.28.2"
6+
version = "0.28.3"
77
edition = "2021"
88
homepage = "https://github.com/risinglightdb/sqllogictest-rs"
99
keywords = ["sql", "database", "parser", "cli"]

sqllogictest-bin/src/main.rs

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ struct Opt {
132132
/// Total number of partitions for test sharding. More details in `partition_id`.
133133
#[clap(long, env = PARTITION_COUNT_ENV_KEY)]
134134
partition_count: Option<u64>,
135+
136+
/// Timeout in seconds for shutting down the connections to the database after a
137+
/// test file is finished. By default, this is unspecified, meaning to wait forever.
138+
#[clap(long = "shutdown-timeout", env = "SLT_SHUTDOWN_TIMEOUT")]
139+
shutdown_timeout_secs: Option<u64>,
135140
}
136141

137142
/// Connection configuration.
@@ -241,6 +246,7 @@ pub async fn main() -> Result<()> {
241246
labels,
242247
partition_count,
243248
partition_id,
249+
shutdown_timeout_secs,
244250
} = Opt::from_arg_matches(&matches)
245251
.map_err(|err| err.exit())
246252
.unwrap();
@@ -341,6 +347,14 @@ pub async fn main() -> Result<()> {
341347
}
342348
});
343349

350+
let run_config = RunConfig {
351+
labels,
352+
junit: junit.clone(),
353+
fail_fast,
354+
cancel,
355+
shutdown_timeout: shutdown_timeout_secs.map(Duration::from_secs),
356+
};
357+
344358
let result = if let Some(jobs) = jobs {
345359
run_parallel(
346360
jobs,
@@ -349,24 +363,11 @@ pub async fn main() -> Result<()> {
349363
all_files,
350364
&engine,
351365
config,
352-
&labels,
353-
junit.clone(),
354-
fail_fast,
355-
cancel,
366+
run_config,
356367
)
357368
.await
358369
} else {
359-
run_serial(
360-
&mut test_suite,
361-
all_files,
362-
&engine,
363-
config,
364-
&labels,
365-
junit.clone(),
366-
fail_fast,
367-
cancel,
368-
)
369-
.await
370+
run_serial(&mut test_suite, all_files, &engine, config, run_config).await
370371
};
371372

372373
report.add_test_suite(test_suite);
@@ -378,18 +379,28 @@ pub async fn main() -> Result<()> {
378379
result
379380
}
380381

381-
#[allow(clippy::too_many_arguments)]
382+
struct RunConfig {
383+
labels: Vec<String>,
384+
junit: Option<String>,
385+
fail_fast: bool,
386+
cancel: CancellationToken,
387+
shutdown_timeout: Option<Duration>,
388+
}
389+
382390
async fn run_parallel(
383391
jobs: usize,
384392
keep_db_on_failure: bool,
385393
test_suite: &mut TestSuite,
386394
files: Vec<PathBuf>,
387395
engine: &EngineConfig,
388396
config: DBConfig,
389-
labels: &[String],
390-
junit: Option<String>,
391-
fail_fast: bool,
392-
cancel: CancellationToken,
397+
RunConfig {
398+
labels,
399+
junit,
400+
fail_fast,
401+
cancel,
402+
shutdown_timeout,
403+
}: RunConfig,
393404
) -> Result<()> {
394405
let mut create_databases = BTreeMap::new();
395406
let mut test_cases = BTreeSet::new();
@@ -427,7 +438,7 @@ async fn run_parallel(
427438
config.db.clone_from(&db_name);
428439
let file = filename.to_string_lossy().to_string();
429440
let engine = engine.clone();
430-
let labels = labels.to_vec();
441+
let labels = labels.clone();
431442
let cancel = cancel.clone();
432443
async move {
433444
let res = AbortOnDropHandle::new(tokio::spawn(async move {
@@ -438,6 +449,7 @@ async fn run_parallel(
438449
config,
439450
&labels,
440451
cancel,
452+
shutdown_timeout,
441453
)
442454
.await
443455
}))
@@ -529,10 +541,13 @@ async fn run_serial(
529541
files: Vec<PathBuf>,
530542
engine: &EngineConfig,
531543
config: DBConfig,
532-
labels: &[String],
533-
junit: Option<String>,
534-
fail_fast: bool,
535-
cancel: CancellationToken,
544+
RunConfig {
545+
labels,
546+
junit,
547+
fail_fast,
548+
cancel,
549+
shutdown_timeout,
550+
}: RunConfig,
536551
) -> Result<()> {
537552
let mut failed_cases = vec![];
538553
let mut connection_refused = false;
@@ -545,8 +560,9 @@ async fn run_serial(
545560
file,
546561
engine,
547562
config.clone(),
548-
labels,
563+
&labels,
549564
cancel.clone(),
565+
shutdown_timeout,
550566
)
551567
.await;
552568
stdout().flush()?;
@@ -694,6 +710,7 @@ async fn connect_and_run_test_file(
694710
config: DBConfig,
695711
labels: &[String],
696712
cancel: CancellationToken,
713+
shutdown_timeout: Option<Duration>,
697714
) -> RunResult {
698715
struct OutputGuard<O: Output>(O);
699716
impl<O: Output> Drop for OutputGuard<O> {
@@ -745,7 +762,7 @@ async fn connect_and_run_test_file(
745762
.unwrap();
746763
RunResult::Cancelled
747764
}
748-
result = run_test_file(&mut out.0, &mut runner, filename) => {
765+
result = run_test_file(&mut out.0, &mut runner, filename.clone()) => {
749766
if let Err(err) = &result {
750767
writeln!(
751768
out.0,
@@ -760,7 +777,21 @@ async fn connect_and_run_test_file(
760777
};
761778

762779
drop(out); // flush the output before shutting down the runner
763-
runner.shutdown_async().await;
780+
781+
match shutdown_timeout {
782+
None => runner.shutdown_async().await,
783+
Some(timeout) => {
784+
if tokio::time::timeout(timeout, runner.shutdown_async())
785+
.await
786+
.is_err()
787+
{
788+
eprintln!(
789+
"shutting down connection to database for test {} timed out",
790+
filename.display()
791+
)
792+
}
793+
}
794+
}
764795

765796
result
766797
}

0 commit comments

Comments
 (0)