From fd141762f0c7391d857f8a97ec3ebc7068df9e6c Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 7 Oct 2023 00:35:21 -0400 Subject: [PATCH 01/26] Start a rust-based foreign document test. Instead of using a simple bash script, this will use async rust to run multiple tests in parallel. --- Cargo.toml | 7 ++++ src/bin_foreign_document_test.rs | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/bin_foreign_document_test.rs diff --git a/Cargo.toml b/Cargo.toml index d7fed05..e35076d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,12 @@ path = "src/lib.rs" path = "src/bin_compare.rs" required-features = ["compare"] +[[bin]] + # This bin exists for development purposes only. The real target of this crate is the library. + name = "foreign_document_test" + path = "src/bin_foreign_document_test.rs" + required-features = ["foreign_document_test"] + [dependencies] nom = "7.1.1" opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] } @@ -47,6 +53,7 @@ walkdir = "2.3.3" [features] default = [] compare = [] +foreign_document_test = ["compare", "dep:tokio"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] # Optimized build for any sort of release. diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs new file mode 100644 index 0000000..414c448 --- /dev/null +++ b/src/bin_foreign_document_test.rs @@ -0,0 +1,57 @@ +#![feature(round_char_boundary)] +#![feature(exact_size_is_empty)] +use std::io::Read; + +use organic::compare::run_anonymous_compare; +use organic::compare::run_compare_on_file; + +#[cfg(feature = "tracing")] +use crate::init_tracing::init_telemetry; +#[cfg(feature = "tracing")] +use crate::init_tracing::shutdown_telemetry; +#[cfg(feature = "tracing")] +mod init_tracing; + +#[cfg(not(feature = "tracing"))] +fn main() -> Result<(), Box> { + let rt = tokio::runtime::Runtime::new()?; + let result = rt.block_on(async { + let main_body_result = main_body(); + main_body_result + }); + result +} + +#[cfg(feature = "tracing")] +fn main() -> Result<(), Box> { + let rt = tokio::runtime::Runtime::new()?; + let result = rt.block_on(async { + init_telemetry()?; + let main_body_result = main_body(); + shutdown_telemetry()?; + main_body_result + }); + result +} + +#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] +fn main_body() -> Result<(), Box> { + let args = std::env::args().skip(1); + if args.is_empty() { + let org_contents = read_stdin_to_string()?; + run_anonymous_compare(org_contents) + } else { + for arg in args { + run_compare_on_file(arg)? + } + Ok(()) + } +} + +fn read_stdin_to_string() -> Result> { + let mut stdin_contents = String::new(); + std::io::stdin() + .lock() + .read_to_string(&mut stdin_contents)?; + Ok(stdin_contents) +} From 591b5ed3820203c24e6eb4f1746574147fdac347 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 7 Oct 2023 01:13:26 -0400 Subject: [PATCH 02/26] Starting to define a TestConfig enum. --- src/bin_foreign_document_test.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 414c448..0fb77ef 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -16,7 +16,7 @@ mod init_tracing; fn main() -> Result<(), Box> { let rt = tokio::runtime::Runtime::new()?; let result = rt.block_on(async { - let main_body_result = main_body(); + let main_body_result = main_body().await; main_body_result }); result @@ -27,7 +27,7 @@ fn main() -> Result<(), Box> { let rt = tokio::runtime::Runtime::new()?; let result = rt.block_on(async { init_telemetry()?; - let main_body_result = main_body(); + let main_body_result = main_body().await; shutdown_telemetry()?; main_body_result }); @@ -35,7 +35,7 @@ fn main() -> Result<(), Box> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn main_body() -> Result<(), Box> { +async fn main_body() -> Result<(), Box> { let args = std::env::args().skip(1); if args.is_empty() { let org_contents = read_stdin_to_string()?; @@ -55,3 +55,25 @@ fn read_stdin_to_string() -> Result> { .read_to_string(&mut stdin_contents)?; Ok(stdin_contents) } + +#[derive(Debug)] +enum TestConfig<'s> { + TestLayer(TestLayer<'s>), + SingleFile(SingleFile<'s>), + AnonymousFile(AnonymousFile), +} + +#[derive(Debug)] +struct TestLayer<'s> { + name: &'s str, +} + +#[derive(Debug)] +struct SingleFile<'s> { + name: &'s str, +} + +#[derive(Debug)] +struct AnonymousFile<'s> { + name: String, +} From d7e870cba1b5c5ccb877f41003baeb87cf2cbae9 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 8 Oct 2023 07:54:21 -0400 Subject: [PATCH 03/26] Starting to make result structs. --- Cargo.toml | 2 +- src/bin_foreign_document_test.rs | 35 +++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e35076d..7d83e92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-fil walkdir = "2.3.3" [features] -default = [] +default = ["compare", "foreign_document_test"] compare = [] foreign_document_test = ["compare", "dep:tokio"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 0fb77ef..ef20611 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -1,6 +1,7 @@ #![feature(round_char_boundary)] #![feature(exact_size_is_empty)] use std::io::Read; +use std::path::Path; use organic::compare::run_anonymous_compare; use organic::compare::run_compare_on_file; @@ -66,14 +67,46 @@ enum TestConfig<'s> { #[derive(Debug)] struct TestLayer<'s> { name: &'s str, + children: Vec>, } #[derive(Debug)] struct SingleFile<'s> { + file_path: &'s str, +} + +#[derive(Debug)] +struct AnonymousFile { + name: String, +} + +#[derive(Debug)] +enum TestResult<'s> { + ResultLayer(ResultLayer<'s>), + SingleFileResult(SingleFileResult<'s>), + AnonymousFileResult(AnonymousFileResult), +} + +#[derive(Debug)] +struct ResultLayer<'s> { + name: &'s str, + children: Vec>, +} + +#[derive(Debug)] +struct SingleFileResult<'s> { name: &'s str, } #[derive(Debug)] -struct AnonymousFile<'s> { +struct AnonymousFileResult { name: String, } + +impl<'s> SingleFile<'s> { + fn run_test(&self) -> SingleFileResult<'s> { + let result = run_compare_on_file(self.file_path); + // foo + todo!() + } +} From a1f8cbe079398d2f50a72243841258acdd0d5ade Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 8 Oct 2023 17:17:32 -0400 Subject: [PATCH 04/26] Working on invoking the tests. --- src/bin_foreign_document_test.rs | 67 +++++++++++++++++--------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index ef20611..fda831e 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -37,31 +37,19 @@ fn main() -> Result<(), Box> { #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] async fn main_body() -> Result<(), Box> { - let args = std::env::args().skip(1); - if args.is_empty() { - let org_contents = read_stdin_to_string()?; - run_anonymous_compare(org_contents) - } else { - for arg in args { - run_compare_on_file(arg)? - } - Ok(()) - } -} - -fn read_stdin_to_string() -> Result> { - let mut stdin_contents = String::new(); - std::io::stdin() - .lock() - .read_to_string(&mut stdin_contents)?; - Ok(stdin_contents) + let test_config = TestConfig::TestLayer(TestLayer { + name: "foo", + children: vec![TestConfig::SingleFile(SingleFile { + file_path: Path::new("/tmp/test.org"), + })], + }); + Ok(()) } #[derive(Debug)] enum TestConfig<'s> { TestLayer(TestLayer<'s>), SingleFile(SingleFile<'s>), - AnonymousFile(AnonymousFile), } #[derive(Debug)] @@ -72,19 +60,13 @@ struct TestLayer<'s> { #[derive(Debug)] struct SingleFile<'s> { - file_path: &'s str, -} - -#[derive(Debug)] -struct AnonymousFile { - name: String, + file_path: &'s Path, } #[derive(Debug)] enum TestResult<'s> { ResultLayer(ResultLayer<'s>), SingleFileResult(SingleFileResult<'s>), - AnonymousFileResult(AnonymousFileResult), } #[derive(Debug)] @@ -95,18 +77,41 @@ struct ResultLayer<'s> { #[derive(Debug)] struct SingleFileResult<'s> { - name: &'s str, + file_path: &'s Path, + status: TestStatus, } #[derive(Debug)] -struct AnonymousFileResult { - name: String, +pub(crate) enum TestStatus { + Good, + Bad, +} + +impl<'s> TestConfig<'s> { + async fn run_test(&self) -> TestResult<'s> { + match self { + TestConfig::TestLayer(test) => TestResult::ResultLayer(test.run_test().await), + TestConfig::SingleFile(test) => TestResult::SingleFileResult(test.run_test().await), + } + } } impl<'s> SingleFile<'s> { - fn run_test(&self) -> SingleFileResult<'s> { + async fn run_test(&self) -> SingleFileResult<'s> { let result = run_compare_on_file(self.file_path); - // foo + SingleFileResult { + file_path: self.file_path, + status: if result.is_ok() { + TestStatus::Good + } else { + TestStatus::Bad + }, + } + } +} + +impl<'s> TestLayer<'s> { + async fn run_test(&self) -> ResultLayer<'s> { todo!() } } From 5f93cabff55858e741c579b0a4ed2fbc1d54ff00 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 11 Oct 2023 19:41:32 -0400 Subject: [PATCH 05/26] Hit recursive async. --- src/bin_foreign_document_test.rs | 73 +++++++++++++++++++------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index fda831e..44e76ba 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -2,6 +2,7 @@ #![feature(exact_size_is_empty)] use std::io::Read; use std::path::Path; +use std::path::PathBuf; use organic::compare::run_anonymous_compare; use organic::compare::run_compare_on_file; @@ -37,47 +38,53 @@ fn main() -> Result<(), Box> { #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] async fn main_body() -> Result<(), Box> { - let test_config = TestConfig::TestLayer(TestLayer { - name: "foo", - children: vec![TestConfig::SingleFile(SingleFile { - file_path: Path::new("/tmp/test.org"), - })], + let single_file = TestConfig::SingleFile(SingleFile { + file_path: PathBuf::from("/tmp/test.org"), }); + // let result = single_file.run_test().await; + let result = tokio::spawn(single_file.run_test()); + println!("{:?}", result); + // let test_config = TestConfig::TestLayer(TestLayer { + // name: "foo", + // children: vec![TestConfig::SingleFile(SingleFile { + // file_path: Path::new("/tmp/test.org"), + // })], + // }); Ok(()) } #[derive(Debug)] -enum TestConfig<'s> { - TestLayer(TestLayer<'s>), - SingleFile(SingleFile<'s>), +enum TestConfig { + TestLayer(TestLayer), + SingleFile(SingleFile), } #[derive(Debug)] -struct TestLayer<'s> { - name: &'s str, - children: Vec>, +struct TestLayer { + name: String, + children: Vec, } #[derive(Debug)] -struct SingleFile<'s> { - file_path: &'s Path, +struct SingleFile { + file_path: PathBuf, } #[derive(Debug)] -enum TestResult<'s> { - ResultLayer(ResultLayer<'s>), - SingleFileResult(SingleFileResult<'s>), +enum TestResult { + ResultLayer(ResultLayer), + SingleFileResult(SingleFileResult), } #[derive(Debug)] -struct ResultLayer<'s> { - name: &'s str, - children: Vec>, +struct ResultLayer { + name: String, + children: Vec, } #[derive(Debug)] -struct SingleFileResult<'s> { - file_path: &'s Path, +struct SingleFileResult { + file_path: PathBuf, status: TestStatus, } @@ -87,8 +94,8 @@ pub(crate) enum TestStatus { Bad, } -impl<'s> TestConfig<'s> { - async fn run_test(&self) -> TestResult<'s> { +impl TestConfig { + async fn run_test(self) -> TestResult { match self { TestConfig::TestLayer(test) => TestResult::ResultLayer(test.run_test().await), TestConfig::SingleFile(test) => TestResult::SingleFileResult(test.run_test().await), @@ -96,9 +103,9 @@ impl<'s> TestConfig<'s> { } } -impl<'s> SingleFile<'s> { - async fn run_test(&self) -> SingleFileResult<'s> { - let result = run_compare_on_file(self.file_path); +impl SingleFile { + async fn run_test(self) -> SingleFileResult { + let result = run_compare_on_file(&self.file_path); SingleFileResult { file_path: self.file_path, status: if result.is_ok() { @@ -110,8 +117,16 @@ impl<'s> SingleFile<'s> { } } -impl<'s> TestLayer<'s> { - async fn run_test(&self) -> ResultLayer<'s> { - todo!() +impl TestLayer { + async fn run_test(self) -> ResultLayer { + let mut children = Vec::with_capacity(self.children.len()); + for config in self.children { + let result = config.run_test().await; + children.push(result); + } + ResultLayer { + name: self.name, + children, + } } } From 182c2737cd6b8e9cf6761218dd19de54251ecc47 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 11 Oct 2023 19:47:30 -0400 Subject: [PATCH 06/26] Add futures. --- Cargo.toml | 3 ++- src/bin_foreign_document_test.rs | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7d83e92..1cfd314 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ path = "src/lib.rs" required-features = ["foreign_document_test"] [dependencies] +futures = { version = "0.3.28", optional = true } nom = "7.1.1" opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] } opentelemetry-otlp = { version = "0.13.0", optional = true } @@ -53,7 +54,7 @@ walkdir = "2.3.3" [features] default = ["compare", "foreign_document_test"] compare = [] -foreign_document_test = ["compare", "dep:tokio"] +foreign_document_test = ["compare", "dep:tokio", "dep:futures"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] # Optimized build for any sort of release. diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 44e76ba..ae5d276 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -4,6 +4,9 @@ use std::io::Read; use std::path::Path; use std::path::PathBuf; +use futures::future::BoxFuture; +use futures::future::FutureExt; +use futures::stream::FuturesUnordered; use organic::compare::run_anonymous_compare; use organic::compare::run_compare_on_file; @@ -41,8 +44,9 @@ async fn main_body() -> Result<(), Box> { let single_file = TestConfig::SingleFile(SingleFile { file_path: PathBuf::from("/tmp/test.org"), }); + let mut futs = FuturesUnordered::new(); // let result = single_file.run_test().await; - let result = tokio::spawn(single_file.run_test()); + let result = tokio::spawn(single_file.run_test()).await; println!("{:?}", result); // let test_config = TestConfig::TestLayer(TestLayer { // name: "foo", @@ -95,11 +99,14 @@ pub(crate) enum TestStatus { } impl TestConfig { - async fn run_test(self) -> TestResult { - match self { - TestConfig::TestLayer(test) => TestResult::ResultLayer(test.run_test().await), - TestConfig::SingleFile(test) => TestResult::SingleFileResult(test.run_test().await), + fn run_test(self) -> BoxFuture<'static, TestResult> { + async move { + match self { + TestConfig::TestLayer(test) => TestResult::ResultLayer(test.run_test().await), + TestConfig::SingleFile(test) => TestResult::SingleFileResult(test.run_test().await), + } } + .boxed() } } From b0b795d13be47b15dfa44dbbd9d97ef2ed615926 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 13 Oct 2023 11:41:49 -0400 Subject: [PATCH 07/26] Limit concurrency of running tests. --- Cargo.toml | 2 +- src/bin_foreign_document_test.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1cfd314..366c3a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ walkdir = "2.3.3" [features] default = ["compare", "foreign_document_test"] compare = [] -foreign_document_test = ["compare", "dep:tokio", "dep:futures"] +foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] # Optimized build for any sort of release. diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index ae5d276..4bb471a 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -6,9 +6,9 @@ use std::path::PathBuf; use futures::future::BoxFuture; use futures::future::FutureExt; -use futures::stream::FuturesUnordered; use organic::compare::run_anonymous_compare; use organic::compare::run_compare_on_file; +use tokio::sync::Semaphore; #[cfg(feature = "tracing")] use crate::init_tracing::init_telemetry; @@ -44,7 +44,6 @@ async fn main_body() -> Result<(), Box> { let single_file = TestConfig::SingleFile(SingleFile { file_path: PathBuf::from("/tmp/test.org"), }); - let mut futs = FuturesUnordered::new(); // let result = single_file.run_test().await; let result = tokio::spawn(single_file.run_test()).await; println!("{:?}", result); @@ -57,6 +56,8 @@ async fn main_body() -> Result<(), Box> { Ok(()) } +static TEST_PERMITS: Semaphore = Semaphore::const_new(8); + #[derive(Debug)] enum TestConfig { TestLayer(TestLayer), @@ -112,6 +113,7 @@ impl TestConfig { impl SingleFile { async fn run_test(self) -> SingleFileResult { + let _permit = TEST_PERMITS.acquire().await.unwrap(); let result = run_compare_on_file(&self.file_path); SingleFileResult { file_path: self.file_path, From 5ecd7b8bef512c9532accb8ea5f7b9a541313fbb Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 13 Oct 2023 12:07:52 -0400 Subject: [PATCH 08/26] Launch tests in parallel. --- src/bin_foreign_document_test.rs | 33 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 4bb471a..21cb2d0 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -9,6 +9,7 @@ use futures::future::FutureExt; use organic::compare::run_anonymous_compare; use organic::compare::run_compare_on_file; use tokio::sync::Semaphore; +use tokio::task::JoinError; #[cfg(feature = "tracing")] use crate::init_tracing::init_telemetry; @@ -100,11 +101,13 @@ pub(crate) enum TestStatus { } impl TestConfig { - fn run_test(self) -> BoxFuture<'static, TestResult> { + fn run_test(self) -> BoxFuture<'static, Result> { async move { match self { - TestConfig::TestLayer(test) => TestResult::ResultLayer(test.run_test().await), - TestConfig::SingleFile(test) => TestResult::SingleFileResult(test.run_test().await), + TestConfig::TestLayer(test) => Ok(TestResult::ResultLayer(test.run_test().await?)), + TestConfig::SingleFile(test) => { + Ok(TestResult::SingleFileResult(test.run_test().await?)) + } } } .boxed() @@ -112,30 +115,34 @@ impl TestConfig { } impl SingleFile { - async fn run_test(self) -> SingleFileResult { + async fn run_test(self) -> Result { let _permit = TEST_PERMITS.acquire().await.unwrap(); let result = run_compare_on_file(&self.file_path); - SingleFileResult { + Ok(SingleFileResult { file_path: self.file_path, status: if result.is_ok() { TestStatus::Good } else { TestStatus::Bad }, - } + }) } } impl TestLayer { - async fn run_test(self) -> ResultLayer { - let mut children = Vec::with_capacity(self.children.len()); - for config in self.children { - let result = config.run_test().await; - children.push(result); + async fn run_test(self) -> Result { + let running_children: Vec<_> = self + .children + .into_iter() + .map(|c| tokio::spawn(c.run_test())) + .collect(); + let mut children = Vec::with_capacity(running_children.len()); + for c in running_children { + children.push(c.await??); } - ResultLayer { + Ok(ResultLayer { name: self.name, children, - } + }) } } From 3927889e663f53383129b86cd8b4f3316b4d25fa Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 13 Oct 2023 12:14:46 -0400 Subject: [PATCH 09/26] Change test status to pass/fail. --- src/bin_foreign_document_test.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 21cb2d0..52ca788 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -96,8 +96,8 @@ struct SingleFileResult { #[derive(Debug)] pub(crate) enum TestStatus { - Good, - Bad, + Pass, + Fail, } impl TestConfig { @@ -121,9 +121,9 @@ impl SingleFile { Ok(SingleFileResult { file_path: self.file_path, status: if result.is_ok() { - TestStatus::Good + TestStatus::Pass } else { - TestStatus::Bad + TestStatus::Fail }, }) } From 8a26965e14f3b5c5c783228147b652c4c7fb3049 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 13 Oct 2023 13:02:17 -0400 Subject: [PATCH 10/26] Write a function to compare all org-mode files in a directory. --- Cargo.toml | 3 ++- src/bin_foreign_document_test.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 366c3a9..b150802 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ tokio = { version = "1.30.0", optional = true, default-features = false, feature tracing = { version = "0.1.37", optional = true } tracing-opentelemetry = { version = "0.20.0", optional = true } tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-filter"] } +walkdir = { version = "2.3.3", optional = true } [build-dependencies] walkdir = "2.3.3" @@ -54,7 +55,7 @@ walkdir = "2.3.3" [features] default = ["compare", "foreign_document_test"] compare = [] -foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync"] +foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync", "dep:walkdir"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] # Optimized build for any sort of release. diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 52ca788..2045834 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -10,6 +10,7 @@ use organic::compare::run_anonymous_compare; use organic::compare::run_compare_on_file; use tokio::sync::Semaphore; use tokio::task::JoinError; +use walkdir::WalkDir; #[cfg(feature = "tracing")] use crate::init_tracing::init_telemetry; @@ -43,6 +44,7 @@ fn main() -> Result<(), Box> { #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] async fn main_body() -> Result<(), Box> { let single_file = TestConfig::SingleFile(SingleFile { + name: "foo".to_owned(), file_path: PathBuf::from("/tmp/test.org"), }); // let result = single_file.run_test().await; @@ -57,6 +59,32 @@ async fn main_body() -> Result<(), Box> { Ok(()) } +fn compare_all_org_document>(root_dir: P) -> impl Iterator { + let root_dir = root_dir.as_ref(); + let test_files = WalkDir::new(root_dir) + .into_iter() + .filter(|e| match e { + Ok(dir_entry) => { + dir_entry.file_type().is_file() + && Path::new(dir_entry.file_name()) + .extension() + .map(|ext| ext.to_ascii_lowercase() == "org") + .unwrap_or(false) + } + Err(_) => true, + }) + .collect::, _>>() + .unwrap(); + let test_configs = test_files.into_iter().map(|test_file| { + let name = test_file.path().as_os_str().to_string_lossy().into_owned(); + TestConfig::SingleFile(SingleFile { + name, + file_path: test_file.into_path(), + }) + }); + test_configs +} + static TEST_PERMITS: Semaphore = Semaphore::const_new(8); #[derive(Debug)] @@ -73,6 +101,7 @@ struct TestLayer { #[derive(Debug)] struct SingleFile { + name: String, file_path: PathBuf, } @@ -90,6 +119,7 @@ struct ResultLayer { #[derive(Debug)] struct SingleFileResult { + name: String, file_path: PathBuf, status: TestStatus, } @@ -119,6 +149,7 @@ impl SingleFile { let _permit = TEST_PERMITS.acquire().await.unwrap(); let result = run_compare_on_file(&self.file_path); Ok(SingleFileResult { + name: self.name, file_path: self.file_path, status: if result.is_ok() { TestStatus::Pass From 8271f6b44a98afcecb8c4123c4f8221742728bd0 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 13 Oct 2023 13:20:21 -0400 Subject: [PATCH 11/26] Start invoking the tests. --- src/bin_foreign_document_test.rs | 34 +++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 2045834..c4d809b 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -43,22 +43,32 @@ fn main() -> Result<(), Box> { #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] async fn main_body() -> Result<(), Box> { - let single_file = TestConfig::SingleFile(SingleFile { - name: "foo".to_owned(), - file_path: PathBuf::from("/tmp/test.org"), + let layer = compare_group("org-mode", || { + compare_all_org_document("/foreign_documents/org-mode") }); - // let result = single_file.run_test().await; - let result = tokio::spawn(single_file.run_test()).await; - println!("{:?}", result); - // let test_config = TestConfig::TestLayer(TestLayer { - // name: "foo", - // children: vec![TestConfig::SingleFile(SingleFile { - // file_path: Path::new("/tmp/test.org"), - // })], - // }); + let layer = layer.chain(compare_group("emacs", || { + compare_all_org_document("/foreign_documents/emacs") + })); + + let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect(); + for test in running_tests.into_iter() { + let test_result = test.await??; + println!("{:?}", test_result); + } + Ok(()) } +fn compare_group, F: Fn() -> I, I: Iterator>( + name: N, + inner: F, +) -> impl Iterator { + std::iter::once(TestConfig::TestLayer(TestLayer { + name: name.into(), + children: inner().collect(), + })) +} + fn compare_all_org_document>(root_dir: P) -> impl Iterator { let root_dir = root_dir.as_ref(); let test_files = WalkDir::new(root_dir) From 3d68e1fd0085719af1c217f99a5c77b2b55358ea Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 13 Oct 2023 13:28:24 -0400 Subject: [PATCH 12/26] Switch the docker container over to invoking the rust-based foreign document test. --- docker/organic_test/Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docker/organic_test/Dockerfile b/docker/organic_test/Dockerfile index 562d302..397b579 100644 --- a/docker/organic_test/Dockerfile +++ b/docker/organic_test/Dockerfile @@ -102,6 +102,4 @@ COPY --from=foreign-document-gather /foreign_documents/doomemacs /foreign_docume COPY --from=foreign-document-gather /foreign_documents/worg /foreign_documents/worg COPY --from=build-org-mode /root/org-mode /foreign_documents/org-mode COPY --from=build-emacs /root/emacs /foreign_documents/emacs -COPY foreign_document_test_entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] +ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test"] From dde4bc79203cfb375d46ac5ebadd64aa4edc6b8d Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 14:30:24 -0400 Subject: [PATCH 13/26] Add code for structured printing of test results. --- src/bin_foreign_document_test.rs | 148 ++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index c4d809b..f6018b9 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -6,7 +6,6 @@ use std::path::PathBuf; use futures::future::BoxFuture; use futures::future::FutureExt; -use organic::compare::run_anonymous_compare; use organic::compare::run_compare_on_file; use tokio::sync::Semaphore; use tokio::task::JoinError; @@ -53,7 +52,7 @@ async fn main_body() -> Result<(), Box> { let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect(); for test in running_tests.into_iter() { let test_result = test.await??; - println!("{:?}", test_result); + test_result.print(); } Ok(()) @@ -187,3 +186,148 @@ impl TestLayer { }) } } + +impl TestResult { + pub fn print(&self) { + self.print_indented(0); + } + + fn print_indented(&self, indentation: usize) { + match self { + TestResult::ResultLayer(result) => result.print_indented(indentation), + TestResult::SingleFileResult(result) => result.print_indented(indentation), + } + } + + fn has_bad_children(&self) -> bool { + match self { + TestResult::ResultLayer(result) => result.has_bad_children(), + TestResult::SingleFileResult(result) => result.has_bad_children(), + } + } + + fn is_immediately_bad(&self) -> bool { + match self { + TestResult::ResultLayer(result) => result.is_immediately_bad(), + TestResult::SingleFileResult(result) => result.is_immediately_bad(), + } + } + + pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> String { + if TestResult::should_use_color() { + format!( + "\x1b[38;2;{red};{green};{blue}m", + red = red, + green = green, + blue = blue + ) + } else { + String::new() + } + } + + #[allow(dead_code)] + pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> String { + if TestResult::should_use_color() { + format!( + "\x1b[48;2;{red};{green};{blue}m", + red = red, + green = green, + blue = blue + ) + } else { + String::new() + } + } + + pub(crate) fn reset_color() -> &'static str { + if TestResult::should_use_color() { + "\x1b[0m" + } else { + "" + } + } + + fn should_use_color() -> bool { + !std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty()) + } +} + +impl SingleFileResult { + fn print_indented(&self, indentation: usize) { + match self.status { + TestStatus::Pass => { + println!( + "{indentation}{color}PASS{reset} {name}", + indentation = " ".repeat(indentation), + color = TestResult::foreground_color(0, 255, 0), + reset = TestResult::reset_color(), + name = self.name + ); + } + TestStatus::Fail => { + println!( + "{indentation}{color}FAIL{reset} {name}", + indentation = " ".repeat(indentation), + color = TestResult::foreground_color(255, 0, 0), + reset = TestResult::reset_color(), + name = self.name + ); + } + } + } + + fn has_bad_children(&self) -> bool { + false + } + + fn is_immediately_bad(&self) -> bool { + match self.status { + TestStatus::Pass => false, + TestStatus::Fail => true, + } + } +} + +impl ResultLayer { + fn print_indented(&self, indentation: usize) { + if self.is_immediately_bad() { + println!( + "{indentation}{color}FAIL{reset} {name}", + indentation = " ".repeat(indentation), + color = TestResult::foreground_color(255, 0, 0), + reset = TestResult::reset_color(), + name = self.name + ); + } else if self.has_bad_children() { + println!( + "{indentation}{color}BADCHILD{reset} {name}", + indentation = " ".repeat(indentation), + color = TestResult::foreground_color(255, 255, 0), + reset = TestResult::reset_color(), + name = self.name + ); + } else { + println!( + "{indentation}{color}PASS{reset} {name}", + indentation = " ".repeat(indentation), + color = TestResult::foreground_color(0, 255, 0), + reset = TestResult::reset_color(), + name = self.name + ); + } + self.children + .iter() + .for_each(|result| result.print_indented(indentation + 1)); + } + + fn has_bad_children(&self) -> bool { + self.children + .iter() + .any(|result| result.is_immediately_bad() || result.has_bad_children()) + } + + fn is_immediately_bad(&self) -> bool { + false + } +} From f43920fc7c30128b6b683a438f043fc1e381d05a Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 14:47:57 -0400 Subject: [PATCH 14/26] Add a silent mode for running the diff. --- src/bin_compare.rs | 11 ++++- src/bin_foreign_document_test.rs | 5 ++- src/compare/compare.rs | 72 ++++++++++++++++++++++---------- src/compare/mod.rs | 2 + 4 files changed, 64 insertions(+), 26 deletions(-) diff --git a/src/bin_compare.rs b/src/bin_compare.rs index b2012a6..655aa7d 100644 --- a/src/bin_compare.rs +++ b/src/bin_compare.rs @@ -34,10 +34,17 @@ fn main_body() -> Result<(), Box> { let args = std::env::args().skip(1); if args.is_empty() { let org_contents = read_stdin_to_string()?; - run_anonymous_compare(org_contents) + if let Ok(true) = run_anonymous_compare(org_contents) { + } else { + Err("Diff results do not match.")?; + } + Ok(()) } else { for arg in args { - run_compare_on_file(arg)? + if run_compare_on_file(arg)? { + } else { + Err("Diff results do not match.")?; + } } Ok(()) } diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index f6018b9..8b2975b 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -7,6 +7,7 @@ use std::path::PathBuf; use futures::future::BoxFuture; use futures::future::FutureExt; use organic::compare::run_compare_on_file; +use organic::compare::silent_compare_on_file; use tokio::sync::Semaphore; use tokio::task::JoinError; use walkdir::WalkDir; @@ -156,11 +157,11 @@ impl TestConfig { impl SingleFile { async fn run_test(self) -> Result { let _permit = TEST_PERMITS.acquire().await.unwrap(); - let result = run_compare_on_file(&self.file_path); + let result = silent_compare_on_file(&self.file_path); Ok(SingleFileResult { name: self.name, file_path: self.file_path, - status: if result.is_ok() { + status: if let Ok(true) = result { TestStatus::Pass } else { TestStatus::Fail diff --git a/src/compare/compare.rs b/src/compare/compare.rs index b8b9c0f..d58d5de 100644 --- a/src/compare/compare.rs +++ b/src/compare/compare.rs @@ -14,37 +14,58 @@ use crate::parser::parse_with_settings; pub fn run_anonymous_compare>( org_contents: P, -) -> Result<(), Box> { - run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default()) +) -> Result> { + run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), false) } -pub fn run_compare_on_file>(org_path: P) -> Result<(), Box> { - run_compare_on_file_with_settings(org_path, &GlobalSettings::default()) +pub fn run_compare_on_file>( + org_path: P, +) -> Result> { + run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), false) +} + +pub fn silent_anonymous_compare>( + org_contents: P, +) -> Result> { + run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), true) +} + +pub fn silent_compare_on_file>( + org_path: P, +) -> Result> { + run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), true) } pub fn run_anonymous_compare_with_settings>( org_contents: P, global_settings: &GlobalSettings, -) -> Result<(), Box> { + silent: bool, +) -> Result> { // TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings. let org_contents = org_contents.as_ref().replace("\r\n", "\n"); let org_contents = org_contents.as_str(); - print_versions()?; + if !silent { + print_versions()?; + } let rust_parsed = parse_with_settings(org_contents, global_settings)?; let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings)?; let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?; - println!("{}\n\n\n", org_contents); - println!("{}", org_sexp); - println!("{:#?}", rust_parsed); + if !silent { + println!("{}\n\n\n", org_contents); + println!("{}", org_sexp); + println!("{:#?}", rust_parsed); + } // We do the diffing after printing out both parsed forms in case the diffing panics let diff_result = compare_document(&parsed_sexp, &rust_parsed)?; - diff_result.print(org_contents)?; + if !silent { + diff_result.print(org_contents)?; + } if diff_result.is_bad() { - Err("Diff results do not match.")?; - } else { + return Ok(false); + } else if !silent { println!( "{color}Entire document passes.{reset}", color = DiffResult::foreground_color(0, 255, 0), @@ -52,15 +73,18 @@ pub fn run_anonymous_compare_with_settings>( ); } - Ok(()) + Ok(true) } pub fn run_compare_on_file_with_settings>( org_path: P, global_settings: &GlobalSettings, -) -> Result<(), Box> { + silent: bool, +) -> Result> { let org_path = org_path.as_ref(); - print_versions()?; + if !silent { + print_versions()?; + } let parent_directory = org_path .parent() .ok_or("Should be contained inside a directory.")?; @@ -80,17 +104,21 @@ pub fn run_compare_on_file_with_settings>( let org_sexp = emacs_parse_file_org_document(org_path, &global_settings)?; let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?; - println!("{}\n\n\n", org_contents); - println!("{}", org_sexp); - println!("{:#?}", rust_parsed); + if !silent { + println!("{}\n\n\n", org_contents); + println!("{}", org_sexp); + println!("{:#?}", rust_parsed); + } // We do the diffing after printing out both parsed forms in case the diffing panics let diff_result = compare_document(&parsed_sexp, &rust_parsed)?; - diff_result.print(org_contents)?; + if !silent { + diff_result.print(org_contents)?; + } if diff_result.is_bad() { - Err("Diff results do not match.")?; - } else { + return Ok(false); + } else if !silent { println!( "{color}Entire document passes.{reset}", color = DiffResult::foreground_color(0, 255, 0), @@ -98,7 +126,7 @@ pub fn run_compare_on_file_with_settings>( ); } - Ok(()) + Ok(true) } fn print_versions() -> Result<(), Box> { diff --git a/src/compare/mod.rs b/src/compare/mod.rs index 278146b..8b65826 100644 --- a/src/compare/mod.rs +++ b/src/compare/mod.rs @@ -10,3 +10,5 @@ pub use compare::run_anonymous_compare; pub use compare::run_anonymous_compare_with_settings; pub use compare::run_compare_on_file; pub use compare::run_compare_on_file_with_settings; +pub use compare::silent_anonymous_compare; +pub use compare::silent_compare_on_file; From 92afdc0ea6281e66f3c234240b892460250048b0 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 15:07:17 -0400 Subject: [PATCH 15/26] Strip prefix from file path. --- src/bin_foreign_document_test.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 8b2975b..60802ea 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -1,12 +1,10 @@ #![feature(round_char_boundary)] #![feature(exact_size_is_empty)] -use std::io::Read; use std::path::Path; use std::path::PathBuf; use futures::future::BoxFuture; use futures::future::FutureExt; -use organic::compare::run_compare_on_file; use organic::compare::silent_compare_on_file; use tokio::sync::Semaphore; use tokio::task::JoinError; @@ -85,14 +83,23 @@ fn compare_all_org_document>(root_dir: P) -> impl Iterator, _>>() .unwrap(); - let test_configs = test_files.into_iter().map(|test_file| { - let name = test_file.path().as_os_str().to_string_lossy().into_owned(); - TestConfig::SingleFile(SingleFile { - name, - file_path: test_file.into_path(), + let test_configs: Vec<_> = test_files + .into_iter() + .map(|test_file| { + let name = test_file + .path() + .strip_prefix(root_dir) + .expect("Result is from walkdir so it must be below the root directory.") + .as_os_str() + .to_string_lossy() + .into_owned(); + TestConfig::SingleFile(SingleFile { + name, + file_path: test_file.into_path(), + }) }) - }); - test_configs + .collect(); + test_configs.into_iter() } static TEST_PERMITS: Semaphore = Semaphore::const_new(8); From aa35d1dc03a01fecb76bbfe85cd2c0b4d873cb58 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 15:18:16 -0400 Subject: [PATCH 16/26] Copy over the rest of the foreign document test config. --- src/bin_foreign_document_test.rs | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 60802ea..75261e6 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -47,6 +47,13 @@ async fn main_body() -> Result<(), Box> { let layer = layer.chain(compare_group("emacs", || { compare_all_org_document("/foreign_documents/emacs") })); + let layer = layer.chain(compare_group("worg", || { + compare_all_org_document("/foreign_documents/worg") + })); + let layer = layer.chain(compare_group("howard_abrams", compare_howard_abrams)); + let layer = layer.chain(compare_group("doomemacs", || { + compare_all_org_document("/foreign_documents/doomemacs") + })); let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect(); for test in running_tests.into_iter() { @@ -57,6 +64,37 @@ async fn main_body() -> Result<(), Box> { Ok(()) } +fn compare_howard_abrams() -> impl Iterator { + let layer = compare_group("dot-files", || { + compare_all_org_document("/foreign_documents/howardabrams/dot-files") + }); + let layer = layer.chain(compare_group("hamacs", || { + compare_all_org_document("/foreign_documents/howardabrams/hamacs") + })); + let layer = layer.chain(compare_group("demo-it", || { + compare_all_org_document("/foreign_documents/howardabrams/demo-it") + })); + let layer = layer.chain(compare_group("magit-demo", || { + compare_all_org_document("/foreign_documents/howardabrams/magit-demo") + })); + let layer = layer.chain(compare_group("pdx-emacs-hackers", || { + compare_all_org_document("/foreign_documents/howardabrams/pdx-emacs-hackers") + })); + let layer = layer.chain(compare_group("flora-simulator", || { + compare_all_org_document("/foreign_documents/howardabrams/flora-simulator") + })); + let layer = layer.chain(compare_group("literate-devops-demo", || { + compare_all_org_document("/foreign_documents/howardabrams/literate-devops-demo") + })); + let layer = layer.chain(compare_group("clojure-yesql-xp", || { + compare_all_org_document("/foreign_documents/howardabrams/clojure-yesql-xp") + })); + let layer = layer.chain(compare_group("veep", || { + compare_all_org_document("/foreign_documents/howardabrams/veep") + })); + layer +} + fn compare_group, F: Fn() -> I, I: Iterator>( name: N, inner: F, From 3e7e54a1bdd8cced45d753c1b2eb723bc3a853b4 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 15:26:04 -0400 Subject: [PATCH 17/26] Add the foreign_document_test to the build tests. --- .lighthouse/pipeline-rust-build.yaml | 22 +++++++++++++++++++++- Cargo.toml | 2 +- Makefile | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.lighthouse/pipeline-rust-build.yaml b/.lighthouse/pipeline-rust-build.yaml index 036a1b7..624e21a 100644 --- a/.lighthouse/pipeline-rust-build.yaml +++ b/.lighthouse/pipeline-rust-build.yaml @@ -137,7 +137,7 @@ spec: value: [] - name: docker-image value: "$(params.image-name):$(tasks.fetch-repository.results.commit)" - - name: run-image-all + - name: run-image-tracing-compare taskRef: name: run-docker-image workspaces: @@ -152,6 +152,26 @@ spec: value: ["--no-default-features", "--features", "tracing,compare"] - name: docker-image value: "$(params.image-name):$(tasks.fetch-repository.results.commit)" + - name: run-image-all + taskRef: + name: run-docker-image + workspaces: + - name: source + workspace: git-source + - name: cargo-cache + workspace: cargo-cache + runAfter: + - run-image-default + params: + - name: args + value: + [ + "--no-default-features", + "--features", + "tracing,compare,foreign_document_test", + ] + - name: docker-image + value: "$(params.image-name):$(tasks.fetch-repository.results.commit)" finally: - name: report-success when: diff --git a/Cargo.toml b/Cargo.toml index b150802..3829de9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ walkdir = { version = "2.3.3", optional = true } walkdir = "2.3.3" [features] -default = ["compare", "foreign_document_test"] +default = [] compare = [] foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync", "dep:walkdir"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] diff --git a/Makefile b/Makefile index a7412bc..fdab0f9 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,7 @@ buildtest: > cargo build --no-default-features --features compare > cargo build --no-default-features --features tracing > cargo build --no-default-features --features compare,tracing +> cargo build --no-default-features --features compare,tracing,foreign_document_test .PHONY: foreign_document_test foreign_document_test: From 00611e05c2076da95a2372162d7bde489ba4b925 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 15:32:36 -0400 Subject: [PATCH 18/26] Remove old bash script. --- .../foreign_document_test_entrypoint.sh | 149 ------------------ 1 file changed, 149 deletions(-) delete mode 100644 docker/organic_test/foreign_document_test_entrypoint.sh diff --git a/docker/organic_test/foreign_document_test_entrypoint.sh b/docker/organic_test/foreign_document_test_entrypoint.sh deleted file mode 100644 index 3a51ce9..0000000 --- a/docker/organic_test/foreign_document_test_entrypoint.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env bash -# -# Run the Organic compare script against a series of documents sourced from exterior places. -set -euo pipefail -IFS=$'\n\t' -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -REALPATH=$(command -v uu-realpath || command -v realpath) - -function log { - (>&2 echo "${@}") -} - -function die { - local status_code="$1" - shift - (>&2 echo "${@}") - exit "$status_code" -} - -function main { - cargo build --no-default-features --features compare --profile release-lto - if [ "${CARGO_TARGET_DIR:-}" = "" ]; then - CARGO_TARGET_DIR=$(realpath target/) - fi - PARSE="${CARGO_TARGET_DIR}/release-lto/compare" - - local all_status=0 - set +e - - (run_compare_function "org-mode" compare_all_org_document "/foreign_documents/org-mode") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "emacs" compare_all_org_document "/foreign_documents/emacs") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "worg" compare_all_org_document "/foreign_documents/worg") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "howard_abrams" compare_howard_abrams) - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "doomemacs" compare_all_org_document "/foreign_documents/doomemacs") - if [ "$?" -ne 0 ]; then all_status=1; fi - - set -e - if [ "$all_status" -ne 0 ]; then - red_text "Some tests failed." - else - green_text "All tests passed." - fi - return "$all_status" -} - -function green_text { - (IFS=' '; printf '\x1b[38;2;0;255;0m%s\x1b[0m' "${*}") -} - -function red_text { - (IFS=' '; printf '\x1b[38;2;255;0;0m%s\x1b[0m' "${*}") -} - -function yellow_text { - (IFS=' '; printf '\x1b[38;2;255;255;0m%s\x1b[0m' "${*}") -} - -function indent { - local depth="$1" - local scaled_depth=$((depth * 2)) - shift 1 - local prefix - prefix=$(printf -- "%${scaled_depth}s") - while read -r l; do - (IFS=' '; printf -- '%s%s\n' "$prefix" "$l") - done -} - -function run_compare_function { - local name="$1" - local stdoutput - shift 1 - set +e - stdoutput=$("${@}") - local status=$? - set -e - if [ "$status" -eq 0 ]; then - echo "$(green_text "GOOD") $name" - indent 1 <<<"$stdoutput" - else - echo "$(red_text "FAIL") $name" - indent 1 <<<"$stdoutput" - return 1 - fi -} - -function compare_all_org_document { - local root_dir="$1" - local target_document - local all_status=0 - while read target_document; do - local relative_path - relative_path=$($REALPATH --relative-to "$root_dir" "$target_document") - set +e - (run_compare "$relative_path" "$target_document") - if [ "$?" -ne 0 ]; then all_status=1; fi - set -e - done<<<"$(find "$root_dir" -type f -iname '*.org' | sort)" - return "$all_status" -} - -function run_compare { - local name="$1" - local target_document="$2" - set +e - ($PARSE "$target_document" &> /dev/null) - local status=$? - set -e - if [ "$status" -eq 0 ]; then - echo "$(green_text "GOOD") $name" - else - echo "$(red_text "FAIL") $name" - return 1 - fi -} - -function compare_howard_abrams { - local all_status=0 - set +e - - (run_compare_function "dot-files" compare_all_org_document "/foreign_documents/howardabrams/dot-files") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "hamacs" compare_all_org_document "/foreign_documents/howardabrams/hamacs") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "demo-it" compare_all_org_document "/foreign_documents/howardabrams/demo-it") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "magit-demo" compare_all_org_document "/foreign_documents/howardabrams/magit-demo") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "pdx-emacs-hackers" compare_all_org_document "/foreign_documents/howardabrams/pdx-emacs-hackers") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "flora-simulator" compare_all_org_document "/foreign_documents/howardabrams/flora-simulator") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "literate-devops-demo" compare_all_org_document "/foreign_documents/howardabrams/literate-devops-demo") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "clojure-yesql-xp" compare_all_org_document "/foreign_documents/howardabrams/clojure-yesql-xp") - if [ "$?" -ne 0 ]; then all_status=1; fi - (run_compare_function "veep" compare_all_org_document "/foreign_documents/howardabrams/veep") - if [ "$?" -ne 0 ]; then all_status=1; fi - - set -e - return "$all_status" -} - -main "${@}" From ff04c4a131efb6f1d7625afebb59981b480f9c54 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 17:26:59 -0400 Subject: [PATCH 19/26] Sort files in a compare_all_org_document. --- src/bin_foreign_document_test.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index 75261e6..c9477ef 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -107,7 +107,7 @@ fn compare_group, F: Fn() -> I, I: Iterator>( fn compare_all_org_document>(root_dir: P) -> impl Iterator { let root_dir = root_dir.as_ref(); - let test_files = WalkDir::new(root_dir) + let mut test_files = WalkDir::new(root_dir) .into_iter() .filter(|e| match e { Ok(dir_entry) => { @@ -121,6 +121,7 @@ fn compare_all_org_document>(root_dir: P) -> impl Iterator, _>>() .unwrap(); + test_files.sort_by_cached_key(|test_file| PathBuf::from(test_file.path())); let test_configs: Vec<_> = test_files .into_iter() .map(|test_file| { From 74a3512038a1ddb00b9033f330059c983a8a4e73 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 17:38:53 -0400 Subject: [PATCH 20/26] Report whether all the tests passed. --- src/bin_foreign_document_test.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index c9477ef..ad9665c 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -2,6 +2,7 @@ #![feature(exact_size_is_empty)] use std::path::Path; use std::path::PathBuf; +use std::process::ExitCode; use futures::future::BoxFuture; use futures::future::FutureExt; @@ -18,7 +19,7 @@ use crate::init_tracing::shutdown_telemetry; mod init_tracing; #[cfg(not(feature = "tracing"))] -fn main() -> Result<(), Box> { +fn main() -> Result> { let rt = tokio::runtime::Runtime::new()?; let result = rt.block_on(async { let main_body_result = main_body().await; @@ -28,7 +29,7 @@ fn main() -> Result<(), Box> { } #[cfg(feature = "tracing")] -fn main() -> Result<(), Box> { +fn main() -> Result> { let rt = tokio::runtime::Runtime::new()?; let result = rt.block_on(async { init_telemetry()?; @@ -40,7 +41,7 @@ fn main() -> Result<(), Box> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -async fn main_body() -> Result<(), Box> { +async fn main_body() -> Result> { let layer = compare_group("org-mode", || { compare_all_org_document("/foreign_documents/org-mode") }); @@ -56,12 +57,30 @@ async fn main_body() -> Result<(), Box> { })); let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect(); + let mut any_failed = false; for test in running_tests.into_iter() { let test_result = test.await??; + if test_result.is_immediately_bad() || test_result.has_bad_children() { + any_failed = true; + } test_result.print(); } - Ok(()) + if any_failed { + println!( + "{color}Some tests failed.{reset}", + color = TestResult::foreground_color(255, 0, 0), + reset = TestResult::reset_color(), + ); + Ok(ExitCode::FAILURE) + } else { + println!( + "{color}All tests passed.{reset}", + color = TestResult::foreground_color(0, 255, 0), + reset = TestResult::reset_color(), + ); + Ok(ExitCode::SUCCESS) + } } fn compare_howard_abrams() -> impl Iterator { From c20e7b5f2f33d9552d1d3c60293d7a4cdf526102 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 17:43:49 -0400 Subject: [PATCH 21/26] Make compare an always-async program. This program is used as a development tool, so it is more valuable that we make it simple by only supporting one mode of operation (async) than making it widely compatible by supporting both. --- Cargo.toml | 4 ++-- src/bin_compare.rs | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3829de9..9b9b0cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,8 +53,8 @@ walkdir = { version = "2.3.3", optional = true } walkdir = "2.3.3" [features] -default = [] -compare = [] +default = ["compare", "foreign_document_test"] +compare = ["dep:tokio"] foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync", "dep:walkdir"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] diff --git a/src/bin_compare.rs b/src/bin_compare.rs index 655aa7d..40f0991 100644 --- a/src/bin_compare.rs +++ b/src/bin_compare.rs @@ -14,7 +14,12 @@ mod init_tracing; #[cfg(not(feature = "tracing"))] fn main() -> Result<(), Box> { - main_body() + let rt = tokio::runtime::Runtime::new()?; + let result = rt.block_on(async { + let main_body_result = main_body().await; + main_body_result + }); + result } #[cfg(feature = "tracing")] @@ -30,7 +35,7 @@ fn main() -> Result<(), Box> { } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn main_body() -> Result<(), Box> { +async fn main_body() -> Result<(), Box> { let args = std::env::args().skip(1); if args.is_empty() { let org_contents = read_stdin_to_string()?; From 123da9cca3666369bfd14f5e2ff397a760e40e7b Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 17:48:38 -0400 Subject: [PATCH 22/26] Make the compare functions async. --- src/bin_compare.rs | 4 ++-- src/bin_foreign_document_test.rs | 2 +- src/compare/compare.rs | 24 ++++++++++++------------ src/context/file_access_interface.rs | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/bin_compare.rs b/src/bin_compare.rs index 40f0991..4c1216b 100644 --- a/src/bin_compare.rs +++ b/src/bin_compare.rs @@ -39,14 +39,14 @@ async fn main_body() -> Result<(), Box> { let args = std::env::args().skip(1); if args.is_empty() { let org_contents = read_stdin_to_string()?; - if let Ok(true) = run_anonymous_compare(org_contents) { + if run_anonymous_compare(org_contents).await? { } else { Err("Diff results do not match.")?; } Ok(()) } else { for arg in args { - if run_compare_on_file(arg)? { + if run_compare_on_file(arg).await? { } else { Err("Diff results do not match.")?; } diff --git a/src/bin_foreign_document_test.rs b/src/bin_foreign_document_test.rs index ad9665c..ccd7e6c 100644 --- a/src/bin_foreign_document_test.rs +++ b/src/bin_foreign_document_test.rs @@ -222,7 +222,7 @@ impl TestConfig { impl SingleFile { async fn run_test(self) -> Result { let _permit = TEST_PERMITS.acquire().await.unwrap(); - let result = silent_compare_on_file(&self.file_path); + let result = silent_compare_on_file(&self.file_path).await; Ok(SingleFileResult { name: self.name, file_path: self.file_path, diff --git a/src/compare/compare.rs b/src/compare/compare.rs index d58d5de..c9aff87 100644 --- a/src/compare/compare.rs +++ b/src/compare/compare.rs @@ -12,33 +12,33 @@ use crate::context::LocalFileAccessInterface; use crate::parser::parse_file_with_settings; use crate::parser::parse_with_settings; -pub fn run_anonymous_compare>( +pub async fn run_anonymous_compare>( org_contents: P, ) -> Result> { - run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), false) + run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), false).await } -pub fn run_compare_on_file>( +pub async fn run_compare_on_file>( org_path: P, ) -> Result> { - run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), false) + run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), false).await } -pub fn silent_anonymous_compare>( +pub async fn silent_anonymous_compare>( org_contents: P, ) -> Result> { - run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), true) + run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), true).await } -pub fn silent_compare_on_file>( +pub async fn silent_compare_on_file>( org_path: P, ) -> Result> { - run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), true) + run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), true).await } -pub fn run_anonymous_compare_with_settings>( +pub async fn run_anonymous_compare_with_settings<'g, 's, P: AsRef>( org_contents: P, - global_settings: &GlobalSettings, + global_settings: &GlobalSettings<'g, 's>, silent: bool, ) -> Result> { // TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings. @@ -76,9 +76,9 @@ pub fn run_anonymous_compare_with_settings>( Ok(true) } -pub fn run_compare_on_file_with_settings>( +pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef>( org_path: P, - global_settings: &GlobalSettings, + global_settings: &GlobalSettings<'g, 's>, silent: bool, ) -> Result> { let org_path = org_path.as_ref(); diff --git a/src/context/file_access_interface.rs b/src/context/file_access_interface.rs index d54c7cf..2d93e63 100644 --- a/src/context/file_access_interface.rs +++ b/src/context/file_access_interface.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use std::path::PathBuf; -pub trait FileAccessInterface: Debug { +pub trait FileAccessInterface: Sync + Debug { fn read_file(&self, path: &str) -> Result; } From e1fde88a60cb155141785d6c301c5e591a01ad25 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 17:55:53 -0400 Subject: [PATCH 23/26] Switch to using tokio too invoke emacs async. --- Cargo.toml | 4 ++-- src/compare/compare.rs | 17 ++++++++++------- src/compare/parse.rs | 23 ++++++++++++----------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9b9b0cf..ba6a561 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,8 +54,8 @@ walkdir = "2.3.3" [features] default = ["compare", "foreign_document_test"] -compare = ["dep:tokio"] -foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync", "dep:walkdir"] +compare = ["tokio/process"] +foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] # Optimized build for any sort of release. diff --git a/src/compare/compare.rs b/src/compare/compare.rs index c9aff87..756dcb7 100644 --- a/src/compare/compare.rs +++ b/src/compare/compare.rs @@ -45,10 +45,10 @@ pub async fn run_anonymous_compare_with_settings<'g, 's, P: AsRef>( let org_contents = org_contents.as_ref().replace("\r\n", "\n"); let org_contents = org_contents.as_str(); if !silent { - print_versions()?; + print_versions().await?; } let rust_parsed = parse_with_settings(org_contents, global_settings)?; - let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings)?; + let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings).await?; let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?; if !silent { @@ -83,7 +83,7 @@ pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef>( ) -> Result> { let org_path = org_path.as_ref(); if !silent { - print_versions()?; + print_versions().await?; } let parent_directory = org_path .parent() @@ -101,7 +101,7 @@ pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef>( global_settings }; let rust_parsed = parse_file_with_settings(org_contents, &global_settings, Some(org_path))?; - let org_sexp = emacs_parse_file_org_document(org_path, &global_settings)?; + let org_sexp = emacs_parse_file_org_document(org_path, &global_settings).await?; let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?; if !silent { @@ -129,8 +129,11 @@ pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef>( Ok(true) } -fn print_versions() -> Result<(), Box> { - eprintln!("Using emacs version: {}", get_emacs_version()?.trim()); - eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim()); +async fn print_versions() -> Result<(), Box> { + eprintln!("Using emacs version: {}", get_emacs_version().await?.trim()); + eprintln!( + "Using org-mode version: {}", + get_org_mode_version().await?.trim() + ); Ok(()) } diff --git a/src/compare/parse.rs b/src/compare/parse.rs index 10cb01d..8b28fc3 100644 --- a/src/compare/parse.rs +++ b/src/compare/parse.rs @@ -1,5 +1,6 @@ use std::path::Path; -use std::process::Command; + +use tokio::process::Command; use crate::context::HeadlineLevelFilter; use crate::settings::GlobalSettings; @@ -25,9 +26,9 @@ fn global_settings_elisp(global_settings: &GlobalSettings) -> String { ret } -pub(crate) fn emacs_parse_anonymous_org_document( +pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>( file_contents: C, - global_settings: &GlobalSettings, + global_settings: &GlobalSettings<'g, 's>, ) -> Result> where C: AsRef, @@ -54,7 +55,7 @@ where .arg("--batch") .arg("--eval") .arg(elisp_script); - let out = cmd.output()?; + let out = cmd.output().await?; let status = out.status.exit_ok(); if status.is_err() { eprintln!( @@ -69,9 +70,9 @@ where Ok(String::from_utf8(org_sexp)?) } -pub(crate) fn emacs_parse_file_org_document

( +pub(crate) async fn emacs_parse_file_org_document<'g, 's, P>( file_path: P, - global_settings: &GlobalSettings, + global_settings: &GlobalSettings<'g, 's>, ) -> Result> where P: AsRef, @@ -106,7 +107,7 @@ where .arg("--batch") .arg("--eval") .arg(elisp_script); - let out = cmd.output()?; + let out = cmd.output().await?; let status = out.status.exit_ok(); if status.is_err() { eprintln!( @@ -143,7 +144,7 @@ where output } -pub fn get_emacs_version() -> Result> { +pub async fn get_emacs_version() -> Result> { let elisp_script = r#"(progn (message "%s" (version)) )"#; @@ -156,12 +157,12 @@ pub fn get_emacs_version() -> Result> { .arg("--eval") .arg(elisp_script); - let out = cmd.output()?; + let out = cmd.output().await?; out.status.exit_ok()?; Ok(String::from_utf8(out.stderr)?) } -pub fn get_org_mode_version() -> Result> { +pub async fn get_org_mode_version() -> Result> { let elisp_script = r#"(progn (org-mode) (message "%s" (org-version nil t nil)) @@ -175,7 +176,7 @@ pub fn get_org_mode_version() -> Result> { .arg("--eval") .arg(elisp_script); - let out = cmd.output()?; + let out = cmd.output().await?; out.status.exit_ok()?; Ok(String::from_utf8(out.stderr)?) } From 2de33b8150bc22268ec181349f2ab8b9288d8028 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 18:00:20 -0400 Subject: [PATCH 24/26] Enable release-lto profile on foreign document test. --- Cargo.toml | 4 ++-- docker/organic_test/Dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ba6a561..0088e92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,9 +53,9 @@ walkdir = { version = "2.3.3", optional = true } walkdir = "2.3.3" [features] -default = ["compare", "foreign_document_test"] +default = [] compare = ["tokio/process"] -foreign_document_test = ["compare", "dep:tokio", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"] +foreign_document_test = ["compare", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] # Optimized build for any sort of release. diff --git a/docker/organic_test/Dockerfile b/docker/organic_test/Dockerfile index 397b579..0ae74eb 100644 --- a/docker/organic_test/Dockerfile +++ b/docker/organic_test/Dockerfile @@ -102,4 +102,4 @@ COPY --from=foreign-document-gather /foreign_documents/doomemacs /foreign_docume COPY --from=foreign-document-gather /foreign_documents/worg /foreign_documents/worg COPY --from=build-org-mode /root/org-mode /foreign_documents/org-mode COPY --from=build-emacs /root/emacs /foreign_documents/emacs -ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test"] +ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test", "--profile", "release-lto"] From ad5efc4b0f2947f92d1d7826b8cd3d1496fa4d2d Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 18:09:50 -0400 Subject: [PATCH 25/26] Only require sync on FileAccessInterface when compiling for compare utilities. Otherwise async compatibility would impact sync users of the plain library. --- src/context/file_access_interface.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/context/file_access_interface.rs b/src/context/file_access_interface.rs index 2d93e63..d269edf 100644 --- a/src/context/file_access_interface.rs +++ b/src/context/file_access_interface.rs @@ -1,10 +1,16 @@ use std::fmt::Debug; use std::path::PathBuf; +#[cfg(any(feature = "compare", feature = "foreign_document_test"))] pub trait FileAccessInterface: Sync + Debug { fn read_file(&self, path: &str) -> Result; } +#[cfg(not(any(feature = "compare", feature = "foreign_document_test")))] +pub trait FileAccessInterface: Debug { + fn read_file(&self, path: &str) -> Result; +} + #[derive(Debug, Clone)] pub struct LocalFileAccessInterface { pub working_directory: Option, From ddb3144e66a47f550e444f7c0cb8ea9376789162 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Oct 2023 18:25:26 -0400 Subject: [PATCH 26/26] Fix the tests. --- Cargo.toml | 2 +- tests/test_template | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0088e92..fa76adf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ walkdir = "2.3.3" [features] default = [] -compare = ["tokio/process"] +compare = ["tokio/process", "tokio/macros"] foreign_document_test = ["compare", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] diff --git a/tests/test_template b/tests/test_template index 108ac0c..1f82406 100644 --- a/tests/test_template +++ b/tests/test_template @@ -1,17 +1,17 @@ // TODO: Investigate writing a proc macro to make specifying these combinations easier. For example, currently I am only setting 1 setting per test to keep the repetition reasonable when I should be mixing all the different combinations. {expect_fail} -#[test] -fn autogen_default_{name}() -> Result<(), Box> {{ +#[tokio::test] +async fn autogen_default_{name}() -> Result<(), Box> {{ let org_path = "{path}"; let org_contents = std::fs::read_to_string(org_path).expect("Read org file."); - organic::compare::run_anonymous_compare(org_contents.as_str())?; + organic::compare::run_anonymous_compare(org_contents.as_str()).await?; Ok(()) }} {expect_fail} -#[test] -fn autogen_la_{name}() -> Result<(), Box> {{ +#[tokio::test] +async fn autogen_la_{name}() -> Result<(), Box> {{ let org_path = "{path}"; let org_contents = std::fs::read_to_string(org_path).expect("Read org file."); let global_settings = {{ @@ -19,13 +19,13 @@ fn autogen_la_{name}() -> Result<(), Box> {{ global_settings.list_allow_alphabetical = true; global_settings }}; - organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings)?; + organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings, false).await?; Ok(()) }} {expect_fail} -#[test] -fn autogen_t1_{name}() -> Result<(), Box> {{ +#[tokio::test] +async fn autogen_t1_{name}() -> Result<(), Box> {{ let org_path = "{path}"; let org_contents = std::fs::read_to_string(org_path).expect("Read org file."); let global_settings = {{ @@ -33,13 +33,13 @@ fn autogen_t1_{name}() -> Result<(), Box> {{ global_settings.tab_width = 1; global_settings }}; - organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings)?; + organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings, false).await?; Ok(()) }} {expect_fail} -#[test] -fn autogen_t16_{name}() -> Result<(), Box> {{ +#[tokio::test] +async fn autogen_t16_{name}() -> Result<(), Box> {{ let org_path = "{path}"; let org_contents = std::fs::read_to_string(org_path).expect("Read org file."); let global_settings = {{ @@ -47,13 +47,13 @@ fn autogen_t16_{name}() -> Result<(), Box> {{ global_settings.tab_width = 16; global_settings }}; - organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings)?; + organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings, false).await?; Ok(()) }} {expect_fail} -#[test] -fn autogen_odd_{name}() -> Result<(), Box> {{ +#[tokio::test] +async fn autogen_odd_{name}() -> Result<(), Box> {{ let org_path = "{path}"; let org_contents = std::fs::read_to_string(org_path).expect("Read org file."); let global_settings = {{ @@ -61,6 +61,6 @@ fn autogen_odd_{name}() -> Result<(), Box> {{ global_settings.odd_levels_only = organic::settings::HeadlineLevelFilter::Odd; global_settings }}; - organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings)?; + organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings, false).await?; Ok(()) }}