From 75c8fa932c0ec0234396874cfda540219f5546bf Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Mon, 27 Oct 2025 15:11:50 -0400 Subject: [PATCH 1/4] feat: Global settings --- sdk/src/settings/mod.rs | 98 +++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 8253ba8df..12d6ae468 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -19,11 +19,12 @@ pub mod signer; #[cfg(feature = "file_io")] use std::path::Path; use std::{ - cell::RefCell, io::{BufRead, BufReader, Cursor}, + sync::RwLock, }; use config::{Config, FileFormat}; +use lazy_static::lazy_static; use serde_derive::{Deserialize, Serialize}; use signer::SignerSettings; @@ -31,10 +32,10 @@ use crate::{crypto::base64, settings::builder::BuilderSettings, Error, Result, S const VERSION: u32 = 1; -thread_local!( - static SETTINGS: RefCell = - RefCell::new(Config::try_from(&Settings::default()).unwrap_or_default()); -); +lazy_static! { + static ref SETTINGS: RwLock = + RwLock::new(Config::try_from(&Settings::default()).unwrap_or_default()); +} // trait used to validate user input to make sure user supplied configurations are valid pub(crate) trait SettingsValidate { @@ -401,12 +402,15 @@ impl Settings { .build() .map_err(|_e| Error::BadParam("could not parse configuration file".into()))?; - let update_config = SETTINGS.with_borrow(|current_settings| { - Config::builder() - .add_source(current_settings.clone()) - .add_source(new_config) - .build() // merge overrides, allows for partial changes - }); + let update_config = match SETTINGS.read() { + Ok(current_settings) => { + Config::builder() + .add_source(current_settings.clone()) + .add_source(new_config) + .build() // merge overrides, allows for partial changes + } + Err(_) => return Err(Error::OtherError("could not read settings".into())), + }; match update_config { Ok(update_config) => { @@ -418,7 +422,10 @@ impl Settings { settings.validate()?; - SETTINGS.set(update_config.clone()); + match SETTINGS.write() { + Ok(mut settings) => *settings = update_config.clone(), + Err(_) => return Err(Error::OtherError("could not write settings".into())), + } Ok(settings) } @@ -432,6 +439,13 @@ impl Settings { Settings::from_string(toml, "toml").map(|_| ()) } + /// Create [Settings] from a toml string without affecting global state. + pub(crate) fn from_toml_str(toml: &str) -> Result { + #[allow(deprecated)] + Settings::from_string(toml, "toml") + } + + /// Set the [Settings] from a url to a toml file. #[cfg(not(target_arch = "wasm32"))] pub fn from_url(url: &str) -> Result<()> { @@ -451,7 +465,10 @@ impl Settings { /// deep based on the [Settings] definition. #[allow(unused)] pub(crate) fn set_value>(value_path: &str, value: T) -> Result<()> { - let c = SETTINGS.take(); + let c = match SETTINGS.read() { + Ok(config) => config.clone(), + Err(_) => return Err(Error::OtherError("could not read settings".into())), + }; let update_config = Config::builder() .add_source(c.clone()) @@ -468,11 +485,17 @@ impl Settings { .map_err(|e| Error::BadParam(e.to_string()))?; settings.validate()?; - SETTINGS.set(update_config); + match SETTINGS.write() { + Ok(mut settings) => *settings = update_config, + Err(_) => return Err(Error::OtherError("could not write settings".into())), + } Ok(()) } else { - SETTINGS.set(c); + match SETTINGS.write() { + Ok(mut settings) => *settings = c, + Err(_) => return Err(Error::OtherError("could not write settings".into())), + } Err(Error::OtherError("could not save settings".into())) } } @@ -484,29 +507,36 @@ impl Settings { /// deep based on the [Settings] definition. #[allow(unused)] fn get_value<'de, T: serde::de::Deserialize<'de>>(value_path: &str) -> Result { - SETTINGS.with_borrow(|current_settings| { - let update_config = Config::builder() - .add_source(current_settings.clone()) - .build() - .map_err(|_e| Error::OtherError("could not update configuration".into()))?; - - update_config - .get::(value_path) - .map_err(|_| Error::NotFound) - }) + match SETTINGS.read() { + Ok(current_settings) => { + let update_config = Config::builder() + .add_source(current_settings.clone()) + .build() + .map_err(|_e| Error::OtherError("could not update configuration".into()))?; + + update_config + .get::(value_path) + .map_err(|_| Error::NotFound) + } + Err(_) => Err(Error::OtherError("could not read settings".into())), + } } /// Set [Settings] back to the default values. #[allow(unused)] pub(crate) fn reset() -> Result<()> { if let Ok(default_settings) = Config::try_from(&Settings::default()) { - SETTINGS.set(default_settings); + match SETTINGS.write() { + Ok(mut settings) => *settings = default_settings, + Err(_) => return Err(Error::OtherError("could not write settings".into())), + } Ok(()) } else { Err(Error::OtherError("could not save settings".into())) } } + /// Serializes the [Settings] into a toml string. pub fn to_toml() -> Result { let settings = @@ -528,6 +558,10 @@ impl Settings { pub fn signer() -> Result> { SignerSettings::signer() } + + pub(crate) fn signer_from_settings(settings: &Settings) -> Result> { + SignerSettings::signer_from_settings(settings) + } } impl Default for Settings { @@ -568,7 +602,10 @@ impl SettingsValidate for Settings { // Get snapshot of the Settings objects, returns None if there is an error #[allow(unused)] pub(crate) fn get_settings() -> Option { - SETTINGS.with_borrow(|config| config.clone().try_deserialize::().ok()) + match SETTINGS.try_read() { + Ok(config) => config.clone().try_deserialize::().ok(), + Err(_) => None, + } } // Load settings from configuration file @@ -884,10 +921,7 @@ pub mod tests { #[test] fn test_load_settings_from_sample_toml() { - #[cfg(target_os = "wasi")] - Settings::reset().unwrap(); - - let toml = include_bytes!("../../examples/c2pa.toml"); - Settings::from_toml(std::str::from_utf8(toml).unwrap()).unwrap(); + let toml_bytes = include_bytes!("../../examples/c2pa.toml"); + Settings::from_toml(std::str::from_utf8(toml_bytes).unwrap()).unwrap(); } } From bdf5cc78ee78ec187ed662b4d6c3bc09e655b385 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Mon, 27 Oct 2025 15:44:33 -0400 Subject: [PATCH 2/4] fix: Run reader and builder tests single threaded. --- .github/workflows/ci.yml | 14 ++++++++++++-- .github/workflows/release_readiness.yml | 20 ++++++++++++++++---- sdk/src/builder.rs | 7 ------- sdk/src/reader.rs | 3 ++- sdk/src/settings/mod.rs | 12 ------------ 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46bd3d00b..878a764a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,7 +79,12 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl.info + # Run reader and builder tests single-threaded to avoid global state issues + cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl-reader-builder.info -- --test-threads=1 builder::tests reader::tests + # Run all other tests multi-threaded for better performance + cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl-other.info -- --exclude builder::tests --exclude reader::tests + # Combine coverage reports + lcov --add-tracefile lcov-openssl-reader-builder.info --add-tracefile lcov-openssl-other.info --output-file lcov-openssl.info # Tokens aren't available for PRs originating from forks, # so we don't attempt to upload code coverage in that case. @@ -128,7 +133,12 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.rust-native-features}} run: | - cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto.info + # Run reader and builder tests single-threaded to avoid global state issues + cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto-reader-builder.info -- --test-threads=1 builder::tests reader::tests + # Run all other tests multi-threaded for better performance + cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto-other.info -- --exclude builder::tests --exclude reader::tests + # Combine coverage reports + lcov --add-tracefile lcov-rust_native_crypto-reader-builder.info --add-tracefile lcov-rust_native_crypto-other.info --output-file lcov-rust_native_crypto.info # Tokens aren't available for PRs originating from forks, # so we don't attempt to upload code coverage in that case. diff --git a/.github/workflows/release_readiness.yml b/.github/workflows/release_readiness.yml index b7696b277..df36b0454 100644 --- a/.github/workflows/release_readiness.yml +++ b/.github/workflows/release_readiness.yml @@ -69,7 +69,10 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - cargo test --features "$FEATURES" + # Run reader and builder tests single-threaded to avoid global state issues + cargo test --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests + # Run all other tests multi-threaded for better performance + cargo test --features "$FEATURES" -- --exclude builder::tests --exclude reader::tests tests-rust-native-crypto: name: Unit tests (with Rust native crypto installed) @@ -100,7 +103,10 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.rust_native_crypto-features}} run: | - cargo test --features "$FEATURES" + # Run reader and builder tests single-threaded to avoid global state issues + cargo test --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests + # Run all other tests multi-threaded for better performance + cargo test --features "$FEATURES" -- --exclude builder::tests --exclude reader::tests tests-cross: name: Unit tests @@ -134,7 +140,10 @@ jobs: env: FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} + # Run reader and builder tests single-threaded to avoid global state issues + cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --test-threads=1 builder::tests reader::tests + # Run all other tests multi-threaded for better performance + cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --exclude builder::tests --exclude reader::tests test-direct-minimal-versions: name: Unit tests with minimum versions of direct dependencies @@ -163,7 +172,10 @@ jobs: env: FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" + # Run reader and builder tests single-threaded to avoid global state issues + cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests + # Run all other tests multi-threaded for better performance + cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --exclude builder::tests --exclude reader::tests docs_rs: name: Preflight docs.rs build diff --git a/sdk/src/builder.rs b/sdk/src/builder.rs index 98d6176d6..e4523a53f 100644 --- a/sdk/src/builder.rs +++ b/sdk/src/builder.rs @@ -1955,7 +1955,6 @@ mod tests { // Source: https://github.com/contentauth/c2pa-rs/pull/1458 #[test] fn test_builder_one_placed_action_via_ingredient_id_ref() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( @@ -2027,7 +2026,6 @@ mod tests { #[test] fn test_builder_settings_auto_created() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( @@ -2065,7 +2063,6 @@ mod tests { #[test] fn test_builder_settings_auto_opened() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); let mut builder = Builder::new(); @@ -2121,7 +2118,6 @@ mod tests { #[test] fn test_builder_settings_auto_placed() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( @@ -2217,7 +2213,6 @@ mod tests { #[test] fn test_builder_settings_all_actions_included() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( @@ -2257,7 +2252,6 @@ mod tests { #[test] fn test_builder_settings_action_templates() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( @@ -2318,7 +2312,6 @@ mod tests { #[test] fn test_builder_settings_actions() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( diff --git a/sdk/src/reader.rs b/sdk/src/reader.rs index 16c4adf33..d1490a7da 100644 --- a/sdk/src/reader.rs +++ b/sdk/src/reader.rs @@ -1020,8 +1020,9 @@ pub mod tests { } #[test] - #[cfg(not(target_os = "wasi"))] // todo: enable when disable we find out wasi trust issues fn test_reader_trusted() -> Result<()> { + crate::settings::reset_default_settings()?; + let reader = Reader::from_stream("image/jpeg", std::io::Cursor::new(IMAGE_COMPLEX_MANIFEST))?; assert_eq!(reader.validation_state(), ValidationState::Trusted); diff --git a/sdk/src/settings/mod.rs b/sdk/src/settings/mod.rs index 12d6ae468..30fb501ed 100644 --- a/sdk/src/settings/mod.rs +++ b/sdk/src/settings/mod.rs @@ -439,13 +439,6 @@ impl Settings { Settings::from_string(toml, "toml").map(|_| ()) } - /// Create [Settings] from a toml string without affecting global state. - pub(crate) fn from_toml_str(toml: &str) -> Result { - #[allow(deprecated)] - Settings::from_string(toml, "toml") - } - - /// Set the [Settings] from a url to a toml file. #[cfg(not(target_arch = "wasm32"))] pub fn from_url(url: &str) -> Result<()> { @@ -536,7 +529,6 @@ impl Settings { } } - /// Serializes the [Settings] into a toml string. pub fn to_toml() -> Result { let settings = @@ -558,10 +550,6 @@ impl Settings { pub fn signer() -> Result> { SignerSettings::signer() } - - pub(crate) fn signer_from_settings(settings: &Settings) -> Result> { - SignerSettings::signer_from_settings(settings) - } } impl Default for Settings { From b1b8dbba728f3acbd99d4abe93b10e4349c3292f Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Mon, 27 Oct 2025 16:05:25 -0400 Subject: [PATCH 3/4] fix: CI --- .github/workflows/ci.yml | 8 ++++++-- .github/workflows/release_readiness.yml | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 878a764a0..b024d30bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,8 +81,10 @@ jobs: run: | # Run reader and builder tests single-threaded to avoid global state issues cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl-reader-builder.info -- --test-threads=1 builder::tests reader::tests + # Get all other test modules (excluding reader and builder) + OTHER_TESTS=$(cargo test --lib --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') # Run all other tests multi-threaded for better performance - cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl-other.info -- --exclude builder::tests --exclude reader::tests + cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl-other.info -- $OTHER_TESTS # Combine coverage reports lcov --add-tracefile lcov-openssl-reader-builder.info --add-tracefile lcov-openssl-other.info --output-file lcov-openssl.info @@ -135,8 +137,10 @@ jobs: run: | # Run reader and builder tests single-threaded to avoid global state issues cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto-reader-builder.info -- --test-threads=1 builder::tests reader::tests + # Get all other test modules (excluding reader and builder) + OTHER_TESTS=$(cargo test -p c2pa --no-default-features --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') # Run all other tests multi-threaded for better performance - cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto-other.info -- --exclude builder::tests --exclude reader::tests + cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto-other.info -- $OTHER_TESTS # Combine coverage reports lcov --add-tracefile lcov-rust_native_crypto-reader-builder.info --add-tracefile lcov-rust_native_crypto-other.info --output-file lcov-rust_native_crypto.info diff --git a/.github/workflows/release_readiness.yml b/.github/workflows/release_readiness.yml index df36b0454..56e763bcb 100644 --- a/.github/workflows/release_readiness.yml +++ b/.github/workflows/release_readiness.yml @@ -71,8 +71,10 @@ jobs: run: | # Run reader and builder tests single-threaded to avoid global state issues cargo test --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests + # Get all other test modules (excluding reader and builder) + OTHER_TESTS=$(cargo test --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') # Run all other tests multi-threaded for better performance - cargo test --features "$FEATURES" -- --exclude builder::tests --exclude reader::tests + cargo test --features "$FEATURES" -- $OTHER_TESTS tests-rust-native-crypto: name: Unit tests (with Rust native crypto installed) @@ -105,8 +107,10 @@ jobs: run: | # Run reader and builder tests single-threaded to avoid global state issues cargo test --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests + # Get all other test modules (excluding reader and builder) + OTHER_TESTS=$(cargo test --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') # Run all other tests multi-threaded for better performance - cargo test --features "$FEATURES" -- --exclude builder::tests --exclude reader::tests + cargo test --features "$FEATURES" -- $OTHER_TESTS tests-cross: name: Unit tests @@ -142,8 +146,10 @@ jobs: run: | # Run reader and builder tests single-threaded to avoid global state issues cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --test-threads=1 builder::tests reader::tests + # Get all other test modules (excluding reader and builder) + OTHER_TESTS=$(cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') # Run all other tests multi-threaded for better performance - cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --exclude builder::tests --exclude reader::tests + cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- $OTHER_TESTS test-direct-minimal-versions: name: Unit tests with minimum versions of direct dependencies @@ -174,8 +180,10 @@ jobs: run: | # Run reader and builder tests single-threaded to avoid global state issues cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests + # Get all other test modules (excluding reader and builder) + OTHER_TESTS=$(cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') # Run all other tests multi-threaded for better performance - cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --exclude builder::tests --exclude reader::tests + cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- $OTHER_TESTS docs_rs: name: Preflight docs.rs build From 7032ffa37e83633d1b0b2cc6ed30a4e43913967b Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Mon, 27 Oct 2025 17:00:29 -0400 Subject: [PATCH 4/4] fix: --- .github/workflows/ci.yml | 24 ++++++++----------- .github/workflows/release_readiness.yml | 32 ++++++++++--------------- sdk/src/settings/signer.rs | 2 -- sdk/src/utils/thumbnail.rs | 3 --- 4 files changed, 22 insertions(+), 39 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b024d30bd..2de61aa68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,14 +79,12 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - # Run reader and builder tests single-threaded to avoid global state issues - cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl-reader-builder.info -- --test-threads=1 builder::tests reader::tests - # Get all other test modules (excluding reader and builder) - OTHER_TESTS=$(cargo test --lib --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') - # Run all other tests multi-threaded for better performance - cargo llvm-cov --lib --features "$FEATURES" --lcov --output-path lcov-openssl-other.info -- $OTHER_TESTS - # Combine coverage reports - lcov --add-tracefile lcov-openssl-reader-builder.info --add-tracefile lcov-openssl-other.info --output-file lcov-openssl.info + # Run reader, builder, and settings tests single-threaded to avoid global state issues + cargo llvm-cov -p c2pa --features "$FEATURES" --no-default-features --lib --lcov --output-path lcov-openssl-reader-builder-settings.info -- --test-threads=1 reader::tests builder::tests settings:: │ + # Run all other tests multi-threaded for better performance │ + cargo llvm-cov -p c2pa --features "$FEATURES" --no-default-features --lib --lcov --output-path lcov-openssl-other.info -- --skip "reader::tests" --skip "builder::tests" --skip "settings::" │ + # Combine coverage reports │ + lcov --add-tracefile lcov-openssl-reader-builder-settings.info --add-tracefile lcov-openssl-other.info --output-file lcov-openssl.info │ # Tokens aren't available for PRs originating from forks, # so we don't attempt to upload code coverage in that case. @@ -135,14 +133,12 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.rust-native-features}} run: | - # Run reader and builder tests single-threaded to avoid global state issues - cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto-reader-builder.info -- --test-threads=1 builder::tests reader::tests - # Get all other test modules (excluding reader and builder) - OTHER_TESTS=$(cargo test -p c2pa --no-default-features --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') + # Run reader, builder, and settings tests single-threaded to avoid global state issues + cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lib --lcov --output-path lcov-rust_native_crypto-reader-builder-settings.info -- --test-threads=1 reader::tests builder::tests settings:: # Run all other tests multi-threaded for better performance - cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lcov --output-path lcov-rust_native_crypto-other.info -- $OTHER_TESTS + cargo llvm-cov -p c2pa --no-default-features --features "$FEATURES" --lib --lcov --output-path lcov-rust_native_crypto-other.info -- --skip "reader::tests" --skip "builder::tests" --skip "settings::" # Combine coverage reports - lcov --add-tracefile lcov-rust_native_crypto-reader-builder.info --add-tracefile lcov-rust_native_crypto-other.info --output-file lcov-rust_native_crypto.info + lcov --add-tracefile lcov-rust_native_crypto-reader-builder-settings.info --add-tracefile lcov-rust_native_crypto-other.info --output-file lcov-rust_native_crypto.info # Tokens aren't available for PRs originating from forks, # so we don't attempt to upload code coverage in that case. diff --git a/.github/workflows/release_readiness.yml b/.github/workflows/release_readiness.yml index 56e763bcb..83a3b0989 100644 --- a/.github/workflows/release_readiness.yml +++ b/.github/workflows/release_readiness.yml @@ -69,12 +69,10 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - # Run reader and builder tests single-threaded to avoid global state issues - cargo test --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests - # Get all other test modules (excluding reader and builder) - OTHER_TESTS=$(cargo test --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') + # Run reader, builder, and settings tests single-threaded to avoid global state issues + cargo test -p c2pa --features "$FEATURES" --no-default-features --lib -- --test-threads=1 reader::tests builder::tests settings:: # Run all other tests multi-threaded for better performance - cargo test --features "$FEATURES" -- $OTHER_TESTS + cargo test -p c2pa --features "$FEATURES" --no-default-features --lib -- --skip "reader::tests" --skip "builder::tests" --skip "settings::" tests-rust-native-crypto: name: Unit tests (with Rust native crypto installed) @@ -105,12 +103,10 @@ jobs: RUST_BACKTRACE: "1" FEATURES: ${{needs.get-features.outputs.rust_native_crypto-features}} run: | - # Run reader and builder tests single-threaded to avoid global state issues - cargo test --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests - # Get all other test modules (excluding reader and builder) - OTHER_TESTS=$(cargo test --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') + # Run reader, builder, and settings tests single-threaded to avoid global state issues + cargo test -p c2pa --features "$FEATURES" --no-default-features --lib -- --test-threads=1 reader::tests builder::tests settings:: # Run all other tests multi-threaded for better performance - cargo test --features "$FEATURES" -- $OTHER_TESTS + cargo test -p c2pa --features "$FEATURES" --no-default-features --lib -- --skip "reader::tests" --skip "builder::tests" --skip "settings::" tests-cross: name: Unit tests @@ -144,12 +140,10 @@ jobs: env: FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - # Run reader and builder tests single-threaded to avoid global state issues - cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --test-threads=1 builder::tests reader::tests - # Get all other test modules (excluding reader and builder) - OTHER_TESTS=$(cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') + # Run reader, builder, and settings tests single-threaded to avoid global state issues + cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --test-threads=1 reader::tests builder::tests settings:: # Run all other tests multi-threaded for better performance - cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- $OTHER_TESTS + cross test --all-targets --features "$FEATURES" --target ${{ matrix.target }} -- --skip "reader::tests" --skip "builder::tests" --skip "settings::" test-direct-minimal-versions: name: Unit tests with minimum versions of direct dependencies @@ -178,12 +172,10 @@ jobs: env: FEATURES: ${{needs.get-features.outputs.openssl-features}} run: | - # Run reader and builder tests single-threaded to avoid global state issues - cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --test-threads=1 builder::tests reader::tests - # Get all other test modules (excluding reader and builder) - OTHER_TESTS=$(cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --list | grep "::tests::" | grep -v "builder::tests\|reader::tests" | sed 's/::tests::.*//' | sort -u | tr '\n' ' ') + # Run reader, builder, and settings tests single-threaded to avoid global state issues + cargo +nightly-2025-07-28 test -p c2pa -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --test-threads=1 reader::tests builder::tests settings:: # Run all other tests multi-threaded for better performance - cargo +nightly-2025-07-28 test -Z direct-minimal-versions --all-targets --features "$FEATURES" -- $OTHER_TESTS + cargo +nightly-2025-07-28 test -p c2pa -Z direct-minimal-versions --all-targets --features "$FEATURES" -- --skip "reader::tests" --skip "builder::tests" --skip "settings::" docs_rs: name: Preflight docs.rs build diff --git a/sdk/src/settings/signer.rs b/sdk/src/settings/signer.rs index 4a83059bf..195d7b4f7 100644 --- a/sdk/src/settings/signer.rs +++ b/sdk/src/settings/signer.rs @@ -300,7 +300,6 @@ pub mod tests { #[test] fn test_make_local_signer() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); // Testing with a different alg than the default test signer. @@ -330,7 +329,6 @@ pub mod tests { use crate::create_signer; - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); let alg = SigningAlg::Ps384; diff --git a/sdk/src/utils/thumbnail.rs b/sdk/src/utils/thumbnail.rs index 7f19d1df0..c7fa22c33 100644 --- a/sdk/src/utils/thumbnail.rs +++ b/sdk/src/utils/thumbnail.rs @@ -407,7 +407,6 @@ pub mod tests { #[test] fn test_make_thumbnail_bytes_from_stream() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( @@ -437,7 +436,6 @@ pub mod tests { #[test] fn test_make_thumbnail_with_prefer_smallest_format() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml( @@ -504,7 +502,6 @@ pub mod tests { #[test] fn test_make_thumbnail_and_ignore_errors() { - #[cfg(target_os = "wasi")] Settings::reset().unwrap(); Settings::from_toml(