diff --git a/lib/bencher_comment/src/lib.rs b/lib/bencher_comment/src/lib.rs index e7897d268..9a11380f9 100644 --- a/lib/bencher_comment/src/lib.rs +++ b/lib/bencher_comment/src/lib.rs @@ -66,14 +66,30 @@ impl ReportComment { pub fn human(&self) -> String { let mut text = String::new(); + self.human_report_link(&mut text); + self.human_no_benchmarks(&mut text); self.human_results_list(&mut text); self.human_alerts_list(&mut text); self.human_unclaimed(&mut text); text } + fn human_report_link(&self, text: &mut String) { + let url = self.resource_url_human(Resource::Report(self.json_report.uuid)); + text.push_str(&format!("View report: {url}")); + } + + fn human_no_benchmarks(&self, text: &mut String) { + if self.benchmark_count == 0 { + text.push_str("\n\nWARNING: No benchmarks found!"); + } + } + fn human_results_list(&self, text: &mut String) { - text.push_str("View results:"); + if self.benchmark_count == 0 { + return; + } + text.push_str("\n\nView results:"); for (i, iteration) in self.json_report.results.iter().enumerate() { if self.multiple_iterations { if i != 0 { @@ -658,7 +674,15 @@ impl ReportComment { false } + fn resource_url_human(&self, resource: Resource) -> Url { + self.resource_url_inner(resource, false) + } + fn resource_url(&self, resource: Resource) -> Url { + self.resource_url_inner(resource, true) + } + + fn resource_url_inner(&self, resource: Resource, utm: bool) -> Url { let url = self.console_url.clone(); let query_param = resource.query_param(); let path = if self.public_links { @@ -682,7 +706,7 @@ impl ReportComment { url.query_pairs_mut().append_pair(key, &value); } - if self.is_bencher_cloud() { + if utm && self.is_bencher_cloud() { url.query_pairs_mut() .append_pair("utm_medium", "referral") .append_pair("utm_source", &self.source) diff --git a/services/cli/src/bencher/sub/run/mod.rs b/services/cli/src/bencher/sub/run/mod.rs index 47de68b5d..238c6f197 100644 --- a/services/cli/src/bencher/sub/run/mod.rs +++ b/services/cli/src/bencher/sub/run/mod.rs @@ -89,6 +89,7 @@ struct Job { timeout: Option, build_time: bool, poll_interval: bencher_json::PollTimeout, + detach: bool, } impl TryFrom for Run { @@ -128,7 +129,8 @@ impl TryFrom for Run { env: job.env.map(bencher_parser::parse_env), timeout: job.job_timeout, build_time, - poll_interval: job.poll_interval.unwrap_or(*DEFAULT_POLL_INTERVAL), + poll_interval: job.job_poll_interval.unwrap_or(*DEFAULT_POLL_INTERVAL), + detach: job.detach, }) } else { None @@ -227,6 +229,10 @@ impl Run { #[cfg(feature = "plus")] if let Some(job_uuid) = json_report.job { + if self.job.as_ref().is_some_and(|j| j.detach) { + cli_eprintln_quietable!(self.log, "Remote job submitted successfully: {job_uuid}"); + return self.display_and_check_alerts(json_report).await; + } return self.poll_job(json_report, job_uuid).await; } diff --git a/services/cli/src/parser/run.rs b/services/cli/src/parser/run.rs index e8d3a78a8..abbe71b73 100644 --- a/services/cli/src/parser/run.rs +++ b/services/cli/src/parser/run.rs @@ -271,6 +271,11 @@ pub struct CliRunJob { pub job_timeout: Option, /// Poll interval in seconds when waiting for remote job completion (requires: --image) - #[clap(long, requires = "image")] - pub poll_interval: Option, + // TODO remove in due time + #[clap(long, alias = "poll-interval", requires = "image")] + pub job_poll_interval: Option, + + /// Detach after submitting the remote job, without waiting for completion (requires: --image). + #[clap(long, requires = "image", conflicts_with = "job_poll_interval")] + pub detach: bool, } diff --git a/services/console/src/chunks/docs-explanation/bencher-run/de/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/de/detach.mdx new file mode 100644 index 000000000..76e1d93cd --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/de/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus: Nach dem Absenden des Remote-Jobs trennen, ohne auf den Abschluss zu warten. +Erforderlich: `--image` +Konflikte mit: `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/de/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/de/job-poll-interval.mdx new file mode 100644 index 000000000..4aa588f9a --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/de/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus: Setzen Sie das Abfrageintervall in Sekunden beim Warten auf den Abschluss des Remote-Jobs. +Erforderlich: `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/en/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/en/detach.mdx new file mode 100644 index 000000000..6bce915bc --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/en/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus: Detach after submitting the remote job, without waiting for completion. +Requires: `--image` +Conflicts with: `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/en/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/en/job-poll-interval.mdx new file mode 100644 index 000000000..c1d6873d7 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/en/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus: Set the poll interval in seconds when waiting for remote job completion. +Requires: `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/es/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/es/detach.mdx new file mode 100644 index 000000000..73e5eaec0 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/es/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus: Desconectarse después de enviar el job remoto, sin esperar a que finalice. +Requiere: `--image` +Conflictos con: `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/es/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/es/job-poll-interval.mdx new file mode 100644 index 000000000..94d185a1a --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/es/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus: Establezca el intervalo de sondeo en segundos al esperar la finalización del job remoto. +Requiere: `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/fr/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/fr/detach.mdx new file mode 100644 index 000000000..7bf958bfe --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/fr/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus : Se détacher après avoir soumis le job distant, sans attendre l'achèvement. +Requiert : `--image` +Conflits avec : `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/fr/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/fr/job-poll-interval.mdx new file mode 100644 index 000000000..faf3ffbeb --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/fr/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus : Définissez l'intervalle de sondage en secondes lors de l'attente de l'achèvement du job distant. +Requiert : `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/ja/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/ja/detach.mdx new file mode 100644 index 000000000..0f1c29ef8 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/ja/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus: リモートジョブを送信した後、完了を待たずにデタッチします。 +必要条件: `--image` +競合: `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/ja/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/ja/job-poll-interval.mdx new file mode 100644 index 000000000..a30d53854 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/ja/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus: リモートジョブの完了を待つ際のポーリング間隔を秒単位で設定します。 +必要条件: `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/ko/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/ko/detach.mdx new file mode 100644 index 000000000..4f523b4b0 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/ko/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus: 원격 작업을 제출한 후 완료를 기다리지 않고 분리합니다. +필수 조건: `--image` +충돌: `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/ko/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/ko/job-poll-interval.mdx new file mode 100644 index 000000000..408b32abc --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/ko/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus: 원격 작업 완료를 대기할 때 폴링 간격을 초 단위로 설정합니다. +필수 조건: `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/pt/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/pt/detach.mdx new file mode 100644 index 000000000..cb5c608fa --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/pt/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus: Desconectar após enviar o job remoto, sem esperar pela conclusão. +Requer: `--image` +Conflita com: `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/pt/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/pt/job-poll-interval.mdx new file mode 100644 index 000000000..12e44bfe0 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/pt/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus: Defina o intervalo de sondagem em segundos ao aguardar a conclusão do job remoto. +Requer: `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/ru/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/ru/detach.mdx new file mode 100644 index 000000000..a5f61eea2 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/ru/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus: Отключиться после отправки удалённого задания, не дожидаясь завершения. +Требуется: `--image` +Конфликтует с: `--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/ru/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/ru/job-poll-interval.mdx new file mode 100644 index 000000000..561c1d680 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/ru/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus: Установите интервал опроса в секундах при ожидании завершения удалённого задания. +Требуется: `--image` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/zh/detach.mdx b/services/console/src/chunks/docs-explanation/bencher-run/zh/detach.mdx new file mode 100644 index 000000000..8c746cf67 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/zh/detach.mdx @@ -0,0 +1,7 @@ +### `--detach` + +
+ +➕ Bencher Plus:提交远程作业后分离,不等待完成。 +要求:`--image` +冲突:`--job-poll-interval` diff --git a/services/console/src/chunks/docs-explanation/bencher-run/zh/job-poll-interval.mdx b/services/console/src/chunks/docs-explanation/bencher-run/zh/job-poll-interval.mdx new file mode 100644 index 000000000..859680546 --- /dev/null +++ b/services/console/src/chunks/docs-explanation/bencher-run/zh/job-poll-interval.mdx @@ -0,0 +1,6 @@ +### `--job-poll-interval ` + +
+ +➕ Bencher Plus:设置等待远程作业完成时的轮询间隔(秒)。 +要求:`--image` diff --git a/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx b/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx index 073953f8d..1a9210cd0 100644 --- a/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx +++ b/services/console/src/chunks/docs-reference/changelog/en/changelog.mdx @@ -1,6 +1,8 @@ ## Pending `v0.6.1` - Buffer OCI upload network frames into configurable S3 chunks (`registry.data_store.chunk_size`, default 5 MB) to reduce S3 operations during Docker push - Add `idempotency_key` to `bencher run` to deduplicate retried submissions +- Rename `--poll-interval` to `--job-poll-interval` for `bencher run` (`--poll-interval` is still supported as a deprecated alias) +- Add `--detach` flag to `bencher run` to skip waiting for remote job completion ## `v0.6.0` - **BREAKING CHANGE** Update Bencher Metric Format (BMF) to accept UUID, slug, or name for the Benchmark identifier diff --git a/services/console/src/content/docs-explanation/de/bencher-run.mdx b/services/console/src/content/docs-explanation/de/bencher-run.mdx index 691662469..1f0037273 100644 --- a/services/console/src/content/docs-explanation/de/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/de/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/de/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/de/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/de/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/de/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/de/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/de/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/de/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/de/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/de/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/de/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/en/bencher-run.mdx b/services/console/src/content/docs-explanation/en/bencher-run.mdx index bd184e63d..10cfde1c7 100644 --- a/services/console/src/content/docs-explanation/en/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/en/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/en/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/en/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/en/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/en/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/en/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/en/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/en/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/en/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/en/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/en/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/es/bencher-run.mdx b/services/console/src/content/docs-explanation/es/bencher-run.mdx index 2246e98d7..bb1d01daa 100644 --- a/services/console/src/content/docs-explanation/es/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/es/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/es/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/es/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/es/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/es/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/es/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/es/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/es/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/es/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/es/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/es/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/fr/bencher-run.mdx b/services/console/src/content/docs-explanation/fr/bencher-run.mdx index 03e2c4a13..170653c5d 100644 --- a/services/console/src/content/docs-explanation/fr/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/fr/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/fr/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/fr/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/fr/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/fr/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/fr/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/fr/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/fr/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/fr/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/fr/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/fr/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/ja/bencher-run.mdx b/services/console/src/content/docs-explanation/ja/bencher-run.mdx index 855c1381e..afdebccca 100644 --- a/services/console/src/content/docs-explanation/ja/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/ja/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/ja/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/ja/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/ja/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/ja/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/ja/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/ja/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/ja/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/ja/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/ja/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/ja/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/ko/bencher-run.mdx b/services/console/src/content/docs-explanation/ko/bencher-run.mdx index 05195b34f..2cbda73e7 100644 --- a/services/console/src/content/docs-explanation/ko/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/ko/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/ko/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/ko/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/ko/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/ko/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/ko/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/ko/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/ko/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/ko/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/ko/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/ko/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/pt/bencher-run.mdx b/services/console/src/content/docs-explanation/pt/bencher-run.mdx index 802cf6851..f8261c3b0 100644 --- a/services/console/src/content/docs-explanation/pt/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/pt/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/pt/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/pt/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/pt/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/pt/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/pt/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/pt/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/pt/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/pt/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/pt/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/pt/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/ru/bencher-run.mdx b/services/console/src/content/docs-explanation/ru/bencher-run.mdx index f8d8b2cad..f36f94a89 100644 --- a/services/console/src/content/docs-explanation/ru/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/ru/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/ru/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/ru/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/ru/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/ru/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/ru/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/ru/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/ru/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/ru/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/ru/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/ru/help.mdx";
+ + +
+ + + +
+
diff --git a/services/console/src/content/docs-explanation/zh/bencher-run.mdx b/services/console/src/content/docs-explanation/zh/bencher-run.mdx index dadb8c782..0046422dc 100644 --- a/services/console/src/content/docs-explanation/zh/bencher-run.mdx +++ b/services/console/src/content/docs-explanation/zh/bencher-run.mdx @@ -15,6 +15,8 @@ import Image from "../../../chunks/docs-explanation/bencher-run/zh/image.mdx"; import Entrypoint from "../../../chunks/docs-explanation/bencher-run/zh/entrypoint.mdx"; import Env from "../../../chunks/docs-explanation/bencher-run/zh/env.mdx"; import JobTimeout from "../../../chunks/docs-explanation/bencher-run/zh/job-timeout.mdx"; +import JobPollInterval from "../../../chunks/docs-explanation/bencher-run/zh/job-poll-interval.mdx"; +import Detach from "../../../chunks/docs-explanation/bencher-run/zh/detach.mdx"; import CiOnTheFly from "../../../chunks/docs-explanation/bencher-run/zh/ci-on-the-fly.mdx"; import Token from "../../../chunks/docs-explanation/bencher-run/zh/token.mdx"; import BranchSelection from "../../../chunks/docs-explanation/bencher-run/zh/branch-selection.mdx"; @@ -75,6 +77,14 @@ import Help from "../../../chunks/docs-explanation/bencher-run/zh/help.mdx";
+ + +
+ + + +
+
diff --git a/tasks/test_api/src/task/plus/runner.rs b/tasks/test_api/src/task/plus/runner.rs index 07785122e..7bead0ba4 100644 --- a/tasks/test_api/src/task/plus/runner.rs +++ b/tasks/test_api/src/task/plus/runner.rs @@ -231,6 +231,13 @@ impl RunnerTest { Ok(()) }; + // Run the detach runner test + let detach_result = if no_sandbox_result.is_ok() { + run_detach_runner_test(&self.url, &self.token) + } else { + Ok(()) + }; + // Always kill runner daemons, even if the test failed if let Some((mut runner_child, reader_handle)) = runner_child_and_handle { let _kill = runner_child.kill(); @@ -243,6 +250,7 @@ impl RunnerTest { result?; no_sandbox_result?; + detach_result?; println!("=== Runner Daemon Test Passed ==="); Ok(()) } @@ -331,8 +339,8 @@ pub fn run_runner_test(url: &Url, username: &str, token: &Jwt, spec: &str) -> an "--quiet", "--job-timeout", "120", - "--poll-interval", - "2", + "--job-poll-interval", + "1", "--exec", "mock", ]; @@ -389,8 +397,8 @@ fn run_no_sandbox_runner_test(url: &Url, token: &Jwt) -> anyhow::Result<()> { "--quiet", "--job-timeout", "120", - "--poll-interval", - "2", + "--job-poll-interval", + "1", "--exec", "mock", ]; @@ -415,6 +423,112 @@ fn run_no_sandbox_runner_test(url: &Url, token: &Jwt) -> anyhow::Result<()> { Ok(()) } +/// Run a detach runner smoke test: submit a job with `--detach` and verify +/// it returns immediately with a `JsonReport` containing a job UUID, +/// then poll `bencher job view` until the job reaches a terminal state. +fn run_detach_runner_test(url: &Url, token: &Jwt) -> anyhow::Result<()> { + let host = url.as_ref(); + + println!("Running detach runner smoke test against: {host}"); + + // Submit the job with --detach (returns immediately) + let mut cmd = Command::cargo_bin(BENCHER_CMD)?; + let image_ref = format!("{PROJECT_SLUG}:{IMAGE_TAG}"); + let args = [ + "run", + HOST_ARG, + host, + TOKEN_ARG, + token.as_ref(), + "--project", + PROJECT_SLUG, + "--branch", + "master", + "--testbed", + "base", + "--image", + &image_ref, + "--spec", + "no-sandbox-spec", + "--format", + "json", + "--quiet", + "--job-timeout", + "120", + "--detach", + "--exec", + "mock", + ]; + cmd.args(args).current_dir(CLI_DIR); + let output = cmd.output()?; + anyhow::ensure!( + output.status.success(), + "bencher run --detach failed:\nstdout: {}\nstderr: {}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + + let json: bencher_json::JsonReport = serde_json::from_slice(&output.stdout)?; + assert_eq!(json.project.slug.to_string(), PROJECT_SLUG); + let job_uuid = json + .job + .ok_or_else(|| anyhow::anyhow!("Expected job UUID in detach report: {json:?}"))?; + + // Poll `bencher job view` until the job reaches a terminal state + let job_uuid_str = job_uuid.to_string(); + let start = std::time::Instant::now(); + let timeout = std::time::Duration::from_secs(240); + + loop { + std::thread::sleep(std::time::Duration::from_secs(1)); + + if start.elapsed() > timeout { + anyhow::bail!("Timed out waiting for detached job {job_uuid} to complete"); + } + + let mut cmd = Command::cargo_bin(BENCHER_CMD)?; + cmd.args([ + "job", + "view", + HOST_ARG, + host, + TOKEN_ARG, + token.as_ref(), + PROJECT_SLUG, + &job_uuid_str, + ]) + .current_dir(CLI_DIR); + let output = cmd.output()?; + anyhow::ensure!( + output.status.success(), + "bencher job view failed:\nstdout: {}\nstderr: {}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + + let job: bencher_json::JsonJob = serde_json::from_slice(&output.stdout)?; + match job.status { + bencher_json::JobStatus::Processed => { + println!("Detached job {job_uuid} processed successfully"); + break; + }, + bencher_json::JobStatus::Failed => { + anyhow::bail!("Detached job {job_uuid} failed: {job:?}"); + }, + bencher_json::JobStatus::Canceled => { + anyhow::bail!("Detached job {job_uuid} was canceled: {job:?}"); + }, + bencher_json::JobStatus::Pending + | bencher_json::JobStatus::Claimed + | bencher_json::JobStatus::Running + | bencher_json::JobStatus::Completed => {}, + } + } + + println!("Detach runner smoke test passed!"); + Ok(()) +} + /// Ensure that `host.docker.internal` resolves on the host by adding it to /// `/etc/hosts` if not already present. Requires `sudo`. fn ensure_hosts_entry() -> anyhow::Result<()> {