From 800bb5f413e3d1d9098f17c9de831b863ae0e27d Mon Sep 17 00:00:00 2001 From: sfauvel Date: Tue, 18 Feb 2025 11:53:08 +0100 Subject: [PATCH 1/6] feat: Implement an Unknown variant in the artifact locations --- .../src/commands/cardano_db_v2/show.rs | 100 +++++++++++++----- .../src/entities/cardano_database.rs | 9 ++ .../src/messages/cardano_database.rs | 50 +++++++++ 3 files changed, 132 insertions(+), 27 deletions(-) diff --git a/mithril-client-cli/src/commands/cardano_db_v2/show.rs b/mithril-client-cli/src/commands/cardano_db_v2/show.rs index c2b885792d9..708d0306e2f 100644 --- a/mithril-client-cli/src/commands/cardano_db_v2/show.rs +++ b/mithril-client-cli/src/commands/cardano_db_v2/show.rs @@ -122,20 +122,18 @@ fn digest_location_rows(locations: &[DigestLocation]) -> Vec> { locations .iter() + .filter(|location| *location != &DigestLocation::Unknown) .enumerate() - .map(|(index, location)| match location { - DigestLocation::Aggregator { uri } => { - vec![ - format!("{location_name} ({})", index + 1).cell(), - format!("Aggregator, uri: \"{}\"", uri).cell(), - ] - } - DigestLocation::CloudStorage { uri } => { - vec![ - format!("{location_name} ({})", index + 1).cell(), - format!("CloudStorage, uri: \"{}\"", uri).cell(), - ] - } + .filter_map(|(index, location)| match location { + DigestLocation::Aggregator { uri } => Some(vec![ + format!("{location_name} ({})", index + 1).cell(), + format!("Aggregator, uri: \"{}\"", uri).cell(), + ]), + DigestLocation::CloudStorage { uri } => Some(vec![ + format!("{location_name} ({})", index + 1).cell(), + format!("CloudStorage, uri: \"{}\"", uri).cell(), + ]), + DigestLocation::Unknown => None, }) .collect() } @@ -145,16 +143,16 @@ fn immutables_location_rows(locations: &[ImmutablesLocation]) -> Vec match uri { - MultiFilesUri::Template(template_uri) => { - vec![ - format!("{location_name} ({})", index + 1).cell(), - format!("CloudStorage, template_uri: \"{}\"", template_uri.0).cell(), - ] - } + MultiFilesUri::Template(template_uri) => Some(vec![ + format!("{location_name} ({})", index + 1).cell(), + format!("CloudStorage, template_uri: \"{}\"", template_uri.0).cell(), + ]), }, + ImmutablesLocation::Unknown => None, }) .collect() } @@ -164,14 +162,14 @@ fn ancillary_location_rows(locations: &[AncillaryLocation]) -> Vec { - vec![ - format!("{location_name} ({})", index + 1).cell(), - format!("CloudStorage, uri: \"{}\"", uri).cell(), - ] - } + .filter_map(|(index, location)| match location { + AncillaryLocation::CloudStorage { uri } => Some(vec![ + format!("{location_name} ({})", index + 1).cell(), + format!("CloudStorage, uri: \"{}\"", uri).cell(), + ]), + AncillaryLocation::Unknown => None, }) .collect() } @@ -212,6 +210,22 @@ mod tests { assert!(rows_rendered.contains("Aggregator, uri: \"http://aggregator.net/\"")); } + #[test] + fn digest_location_rows_display_and_count_only_known_location() { + let locations = vec![ + DigestLocation::Unknown, + DigestLocation::CloudStorage { + uri: "http://cloudstorage.com/".to_string(), + }, + ]; + + let rows = digest_location_rows(&locations); + assert_eq!(1, rows.len()); + + let rows_rendered = rows.table().display().unwrap().to_string(); + assert!(rows_rendered.contains("Digest location (1)")); + } + #[test] fn immutables_location_rows_when_no_uri_found() { let rows = immutables_location_rows(&[]); @@ -243,6 +257,22 @@ mod tests { assert!(rows_rendered.contains("CloudStorage, template_uri: \"http://cloudstorage2.com/\"")); } + #[test] + fn immutables_location_row_display_and_count_only_known_location() { + let locations = vec![ + ImmutablesLocation::Unknown {}, + ImmutablesLocation::CloudStorage { + uri: MultiFilesUri::Template(TemplateUri("http://cloudstorage2.com/".to_string())), + }, + ]; + + let rows = immutables_location_rows(&locations); + assert_eq!(1, rows.len()); + + let rows_rendered = rows.table().display().unwrap().to_string(); + assert!(rows_rendered.contains("Immutables location (1)")); + } + #[test] fn ancillary_location_rows_when_no_uri_found() { let rows = ancillary_location_rows(&[]); @@ -273,4 +303,20 @@ mod tests { assert!(rows_rendered.contains("Ancillary location (2)")); assert!(rows_rendered.contains("CloudStorage, uri: \"http://cloudstorage2.com/\"")); } + + #[test] + fn ancillary_location_rows_display_and_count_only_known_location() { + let locations = vec![ + AncillaryLocation::Unknown {}, + AncillaryLocation::CloudStorage { + uri: "http://cloudstorage2.com/".to_string(), + }, + ]; + + let rows = ancillary_location_rows(&locations); + assert_eq!(1, rows.len()); + + let rows_rendered = rows.table().display().unwrap().to_string(); + assert!(rows_rendered.contains("Ancillary location (1)")); + } } diff --git a/mithril-common/src/entities/cardano_database.rs b/mithril-common/src/entities/cardano_database.rs index e02ce4d4a50..2fdc79a48a6 100644 --- a/mithril-common/src/entities/cardano_database.rs +++ b/mithril-common/src/entities/cardano_database.rs @@ -80,6 +80,9 @@ pub enum DigestLocation { /// URI of the aggregator digests route location. uri: String, }, + /// Other location not known. + #[serde(other)] + Unknown, } /// Locations of the immutable files. @@ -91,6 +94,9 @@ pub enum ImmutablesLocation { /// URI of the cloud storage location. uri: MultiFilesUri, }, + /// Other location not known. + #[serde(other)] + Unknown, } /// Locations of the ancillary files. @@ -102,6 +108,9 @@ pub enum AncillaryLocation { /// URI of the cloud storage location. uri: String, }, + /// Other location not known. + #[serde(other)] + Unknown, } /// Locations of the Cardano database related files. diff --git a/mithril-common/src/messages/cardano_database.rs b/mithril-common/src/messages/cardano_database.rs index 2ee6b40f734..d5017e1e202 100644 --- a/mithril-common/src/messages/cardano_database.rs +++ b/mithril-common/src/messages/cardano_database.rs @@ -197,4 +197,54 @@ mod tests { assert_eq!(golden_current_message(), message); } + + #[test] + fn test_a_future_json_deserialized_with_unknown_location_types() { + let json = r#" + { + "hash": "d4071d518a3ace0f6c04a9c0745b9e9560e3e2af1b373bafc4e0398423e9abfb", + "merkle_root": "c8224920b9f5ad7377594eb8a15f34f08eb3103cc5241d57cafc5638403ec7c6", + "beacon": { + "epoch": 123, + "immutable_file_number": 2345 + }, + "certificate_hash": "f6c01b373bafc4e039844071d5da3ace4a9c0745b9e9560e3e2af01823e9abfb", + "total_db_size_uncompressed": 800796318, + "locations": { + "digests": [ + { + "type": "whatever", + "new_field": "digest-1" + } + ], + "immutables": [ + { + "type": "whatever", + "new_field": [123, 125] + } + ], + "ancillary": [ + { + "type": "whatever", + "new_field": "ancillary-3" + } + ] + }, + "compression_algorithm": "gzip", + "cardano_node_version": "0.0.1", + "created_at": "2023-01-19T13:43:05.618857482Z" + }"#; + let message: CardanoDatabaseSnapshotMessage = serde_json::from_str(json).expect( + "This JSON is expected to be successfully parsed into a CardanoDatabaseSnapshotMessage instance.", + ); + + assert_eq!(message.locations.digests.len(), 1); + assert_eq!(DigestLocation::Unknown, message.locations.digests[0]); + + assert_eq!(message.locations.immutables.len(), 1); + assert_eq!(ImmutablesLocation::Unknown, message.locations.immutables[0]); + + assert_eq!(message.locations.ancillary.len(), 1); + assert_eq!(AncillaryLocation::Unknown, message.locations.ancillary[0]); + } } From 119356af2e8c5a70b1d18989f9a32698d700d4e2 Mon Sep 17 00:00:00 2001 From: sfauvel Date: Wed, 19 Feb 2025 09:06:00 +0100 Subject: [PATCH 2/6] refacto: split cell content format and row format --- .../src/commands/cardano_db_v2/show.rs | 107 +++++++++--------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/mithril-client-cli/src/commands/cardano_db_v2/show.rs b/mithril-client-cli/src/commands/cardano_db_v2/show.rs index 708d0306e2f..0cbfe6448ed 100644 --- a/mithril-client-cli/src/commands/cardano_db_v2/show.rs +++ b/mithril-client-cli/src/commands/cardano_db_v2/show.rs @@ -85,21 +85,17 @@ impl CardanoDbShowCommand { ], ]; - for digest_location in digest_location_rows(&cardano_db_message.locations.digests) { - cardano_db_table.push(digest_location); - } - - for immutables_location in - immutables_location_rows(&cardano_db_message.locations.immutables) - { - cardano_db_table.push(immutables_location); - } - - for ancillary_location in - ancillary_location_rows(&cardano_db_message.locations.ancillary) - { - cardano_db_table.push(ancillary_location); - } + cardano_db_table.append(&mut digest_location_rows( + &cardano_db_message.locations.digests, + )); + + cardano_db_table.append(&mut immutables_location_rows( + &cardano_db_message.locations.immutables, + )); + + cardano_db_table.append(&mut ancillary_location_rows( + &cardano_db_message.locations.ancillary, + )); cardano_db_table.push(vec![ "Created".cell(), @@ -117,59 +113,60 @@ impl CardanoDbShowCommand { } } +fn digest_location_iter(locations: &[DigestLocation]) -> impl Iterator + use<'_> { + locations.iter().filter_map(|location| match location { + DigestLocation::Aggregator { uri } => Some(format!("Aggregator, uri: \"{}\"", uri)), + DigestLocation::CloudStorage { uri } => Some(format!("CloudStorage, uri: \"{}\"", uri)), + DigestLocation::Unknown => None, + }) +} + fn digest_location_rows(locations: &[DigestLocation]) -> Vec> { - let location_name = "Digest location"; + format_location_rows("Digest location", digest_location_iter(locations)) +} - locations - .iter() - .filter(|location| *location != &DigestLocation::Unknown) - .enumerate() - .filter_map(|(index, location)| match location { - DigestLocation::Aggregator { uri } => Some(vec![ - format!("{location_name} ({})", index + 1).cell(), - format!("Aggregator, uri: \"{}\"", uri).cell(), - ]), - DigestLocation::CloudStorage { uri } => Some(vec![ - format!("{location_name} ({})", index + 1).cell(), - format!("CloudStorage, uri: \"{}\"", uri).cell(), - ]), - DigestLocation::Unknown => None, - }) - .collect() +fn immutables_location_iter( + locations: &[ImmutablesLocation], +) -> impl Iterator + use<'_> { + locations.iter().filter_map(|location| match location { + ImmutablesLocation::CloudStorage { uri } => match uri { + MultiFilesUri::Template(template_uri) => Some(format!( + "CloudStorage, template_uri: \"{}\"", + template_uri.0 + )), + }, + ImmutablesLocation::Unknown => None, + }) } fn immutables_location_rows(locations: &[ImmutablesLocation]) -> Vec> { - let location_name = "Immutables location"; + format_location_rows("Immutables location", immutables_location_iter(locations)) +} - locations - .iter() - .filter(|location| *location != &ImmutablesLocation::Unknown) - .enumerate() - .filter_map(|(index, location)| match location { - ImmutablesLocation::CloudStorage { uri } => match uri { - MultiFilesUri::Template(template_uri) => Some(vec![ - format!("{location_name} ({})", index + 1).cell(), - format!("CloudStorage, template_uri: \"{}\"", template_uri.0).cell(), - ]), - }, - ImmutablesLocation::Unknown => None, - }) - .collect() +fn ancillary_location_iter( + locations: &[AncillaryLocation], +) -> impl Iterator + use<'_> { + locations.iter().filter_map(|location| match location { + AncillaryLocation::CloudStorage { uri } => Some(format!("CloudStorage, uri: \"{uri}\"")), + AncillaryLocation::Unknown => None, + }) } fn ancillary_location_rows(locations: &[AncillaryLocation]) -> Vec> { - let location_name = "Ancillary location"; + format_location_rows("Ancillary location", ancillary_location_iter(locations)) +} +fn format_location_rows( + location_name: &str, + locations: impl Iterator, +) -> Vec> { locations - .iter() - .filter(|location| *location != &AncillaryLocation::Unknown) .enumerate() - .filter_map(|(index, location)| match location { - AncillaryLocation::CloudStorage { uri } => Some(vec![ + .map(|(index, cell_content)| { + vec![ format!("{location_name} ({})", index + 1).cell(), - format!("CloudStorage, uri: \"{}\"", uri).cell(), - ]), - AncillaryLocation::Unknown => None, + cell_content.cell(), + ] }) .collect() } From 12e4c3ed6a35e2b33eb4b1f04aef3bd75896bf8d Mon Sep 17 00:00:00 2001 From: sfauvel Date: Wed, 19 Feb 2025 15:17:29 +0100 Subject: [PATCH 3/6] chore: Improve comments --- mithril-common/src/entities/cardano_database.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mithril-common/src/entities/cardano_database.rs b/mithril-common/src/entities/cardano_database.rs index 2fdc79a48a6..a47ad3d0466 100644 --- a/mithril-common/src/entities/cardano_database.rs +++ b/mithril-common/src/entities/cardano_database.rs @@ -80,7 +80,7 @@ pub enum DigestLocation { /// URI of the aggregator digests route location. uri: String, }, - /// Other location not known. + /// Catchall for unknown location variants. #[serde(other)] Unknown, } @@ -94,7 +94,7 @@ pub enum ImmutablesLocation { /// URI of the cloud storage location. uri: MultiFilesUri, }, - /// Other location not known. + /// Catchall for unknown location variants. #[serde(other)] Unknown, } @@ -108,7 +108,7 @@ pub enum AncillaryLocation { /// URI of the cloud storage location. uri: String, }, - /// Other location not known. + /// Catchall for unknown location variants. #[serde(other)] Unknown, } From 84d6c87f68fe7ff0738c90f3774ef92cffcfa311 Mon Sep 17 00:00:00 2001 From: sfauvel Date: Wed, 19 Feb 2025 18:40:47 +0100 Subject: [PATCH 4/6] feat: Adapt client downloading when Unknown location --- .../download_unpack.rs | 56 ++++++++++++- .../src/cardano_database_client/proving.rs | 22 ++++- .../src/file_downloader/interface.rs | 82 +++++++++++++++++-- 3 files changed, 148 insertions(+), 12 deletions(-) diff --git a/mithril-client/src/cardano_database_client/download_unpack.rs b/mithril-client/src/cardano_database_client/download_unpack.rs index b53f5966eb7..3ed18ca4d40 100644 --- a/mithril-client/src/cardano_database_client/download_unpack.rs +++ b/mithril-client/src/cardano_database_client/download_unpack.rs @@ -359,6 +359,9 @@ impl InternalArtifactDownloader { let file_size = 0; let file_downloader = match &location { ImmutablesLocation::CloudStorage { .. } => self.http_file_downloader.clone(), + ImmutablesLocation::Unknown => { + return Err(anyhow!("Unknown location type to download immutable")); + } }; let file_downloader_uris = FileDownloaderUri::expand_immutable_files_location_to_file_downloader_uris( @@ -414,8 +417,11 @@ impl InternalArtifactDownloader { .await; let file_downloader = match &location { AncillaryLocation::CloudStorage { .. } => self.http_file_downloader.clone(), + AncillaryLocation::Unknown => { + continue; + } }; - let file_downloader_uri = location.into(); + let file_downloader_uri = location.try_into()?; let downloaded = file_downloader .download_unpack( &file_downloader_uri, @@ -468,7 +474,7 @@ mod tests { use crate::cardano_database_client::CardanoDatabaseClientDependencyInjector; use crate::feedback::StackFeedbackReceiver; - use crate::file_downloader::MockFileDownloaderBuilder; + use crate::file_downloader::{MockFileDownloader, MockFileDownloaderBuilder}; use crate::test_utils; use super::*; @@ -876,6 +882,32 @@ mod tests { .expect_err("download_unpack_immutable_files should fail"); } + #[tokio::test] + async fn download_unpack_immutable_files_fails_if_location_is_unknown() { + let total_immutable_files = 2; + let immutable_file_range = ImmutableFileRange::Range(1, total_immutable_files); + let target_dir = TempDir::new("cardano_database_client", "download_unpack").build(); + let artifact_downloader = InternalArtifactDownloader::new( + Arc::new(MockFileDownloader::new()), + FeedbackSender::new(&[]), + test_utils::test_logger(), + ); + + artifact_downloader + .download_unpack_immutable_files( + &[ImmutablesLocation::Unknown {}], + immutable_file_range + .to_range_inclusive(total_immutable_files) + .unwrap(), + &CompressionAlgorithm::default(), + &target_dir, + 1, + "download_id", + ) + .await + .expect_err("download_unpack_immutable_files should fail"); + } + #[tokio::test] async fn download_unpack_immutable_files_succeeds_if_all_are_retrieved_with_same_location() { @@ -1091,6 +1123,26 @@ mod tests { .expect_err("download_unpack_ancillary_file should fail"); } + #[tokio::test] + async fn download_unpack_ancillary_files_fails_if_location_is_unknown() { + let target_dir = Path::new("."); + let artifact_downloader = InternalArtifactDownloader::new( + Arc::new(MockFileDownloader::new()), + FeedbackSender::new(&[]), + test_utils::test_logger(), + ); + + artifact_downloader + .download_unpack_ancillary_file( + &[AncillaryLocation::Unknown {}], + &CompressionAlgorithm::default(), + target_dir, + "download_id", + ) + .await + .expect_err("download_unpack_ancillary_file should fail"); + } + #[tokio::test] async fn download_unpack_ancillary_file_succeeds_if_at_least_one_location_is_retrieved() { let target_dir = Path::new("."); diff --git a/mithril-client/src/cardano_database_client/proving.rs b/mithril-client/src/cardano_database_client/proving.rs index 9e8c177d547..f61515e7655 100644 --- a/mithril-client/src/cardano_database_client/proving.rs +++ b/mithril-client/src/cardano_database_client/proving.rs @@ -106,8 +106,11 @@ impl InternalArtifactProver { DigestLocation::CloudStorage { .. } | DigestLocation::Aggregator { .. } => { self.http_file_downloader.clone() } + DigestLocation::Unknown => { + continue; + } }; - let file_downloader_uri: FileDownloaderUri = location.into(); + let file_downloader_uri: FileDownloaderUri = location.try_into()?; let downloaded = file_downloader .download_unpack( &file_downloader_uri, @@ -350,6 +353,8 @@ mod tests { mod download_unpack_digest_file { + use crate::file_downloader::MockFileDownloader; + use super::*; #[tokio::test] @@ -383,6 +388,21 @@ mod tests { .expect_err("download_unpack_digest_file should fail"); } + #[tokio::test] + async fn fails_if_location_is_unknown() { + let target_dir = Path::new("."); + let artifact_prover = InternalArtifactProver::new( + Arc::new(MockFileDownloader::new()), + FeedbackSender::new(&[]), + test_utils::test_logger(), + ); + + artifact_prover + .download_unpack_digest_file(&[DigestLocation::Unknown], target_dir) + .await + .expect_err("download_unpack_digest_file should fail"); + } + #[tokio::test] async fn succeeds_if_at_least_one_location_is_retrieved() { let target_dir = Path::new("."); diff --git a/mithril-client/src/file_downloader/interface.rs b/mithril-client/src/file_downloader/interface.rs index 7515563ae24..5c57172e199 100644 --- a/mithril-client/src/file_downloader/interface.rs +++ b/mithril-client/src/file_downloader/interface.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, path::Path}; +use anyhow::anyhow; use async_trait::async_trait; use mithril_common::{ @@ -7,7 +8,7 @@ use mithril_common::{ AncillaryLocation, CompressionAlgorithm, DigestLocation, FileUri, ImmutableFileNumber, ImmutablesLocation, }, - StdResult, + StdError, StdResult, }; use crate::feedback::{MithrilEvent, MithrilEventCardanoDatabase}; @@ -44,6 +45,9 @@ impl FileDownloaderUri { Ok(immutable_files_range.zip(file_downloader_uris).collect()) } + ImmutablesLocation::Unknown => { + Err(anyhow!("Unknown location type to download immutable")) + } } } @@ -67,20 +71,28 @@ impl From for FileDownloaderUri { } } -impl From for FileDownloaderUri { - fn from(digest_location: AncillaryLocation) -> Self { - match digest_location { - AncillaryLocation::CloudStorage { uri } => Self::FileUri(FileUri(uri)), +impl TryFrom for FileDownloaderUri { + type Error = StdError; + + fn try_from(location: AncillaryLocation) -> Result { + match location { + AncillaryLocation::CloudStorage { uri } => Ok(Self::FileUri(FileUri(uri))), + AncillaryLocation::Unknown => { + Err(anyhow!("Unknown location type to download ancillary")) + } } } } -impl From for FileDownloaderUri { - fn from(digest_location: DigestLocation) -> Self { - match digest_location { +impl TryFrom for FileDownloaderUri { + type Error = StdError; + + fn try_from(location: DigestLocation) -> Result { + match location { DigestLocation::CloudStorage { uri } | DigestLocation::Aggregator { uri } => { - Self::FileUri(FileUri(uri)) + Ok(Self::FileUri(FileUri(uri))) } + DigestLocation::Unknown => Err(anyhow!("Unknown location type to download digest")), } } } @@ -226,6 +238,18 @@ mod tests { ); } + #[test] + fn immutable_files_location_to_file_downloader_uris_return_error_when_location_is_unknown() { + let immutable_files_location = ImmutablesLocation::Unknown; + let immutable_files_range: Vec = (1..=1).collect(); + + FileDownloaderUri::expand_immutable_files_location_to_file_downloader_uris( + &immutable_files_location, + &immutable_files_range, + ) + .expect_err("expand_immutable_files_location_to_file_downloader_uris should fail"); + } + #[test] fn download_event_type_builds_correct_event() { let download_event_type = DownloadEvent::Immutable { @@ -282,4 +306,44 @@ mod tests { event, ); } + + #[test] + fn file_downloader_uri_from_ancillary_location() { + let location = AncillaryLocation::CloudStorage { + uri: "http://whatever/ancillary-1".to_string(), + }; + let file_downloader_uri: FileDownloaderUri = location.try_into().unwrap(); + + assert_eq!( + FileDownloaderUri::FileUri(FileUri("http://whatever/ancillary-1".to_string())), + file_downloader_uri + ); + } + #[test] + fn file_downloader_uri_from_unknown_ancillary_location() { + let location = AncillaryLocation::Unknown; + let file_downloader_uri: StdResult = location.try_into(); + + file_downloader_uri.expect_err("try_into should fail on Unknown ancillary location"); + } + + #[test] + fn file_downloader_uri_from_digest_location() { + let location = DigestLocation::CloudStorage { + uri: "http://whatever/digest-1".to_string(), + }; + let file_downloader_uri: FileDownloaderUri = location.try_into().unwrap(); + + assert_eq!( + FileDownloaderUri::FileUri(FileUri("http://whatever/digest-1".to_string())), + file_downloader_uri + ); + } + #[test] + fn file_downloader_uri_from_unknown_digest_location() { + let location = DigestLocation::Unknown; + let file_downloader_uri: StdResult = location.try_into(); + + file_downloader_uri.expect_err("try_into should fail on Unknown digest location"); + } } From ee3e6b16a4210f786489253ca7712d09f644e4c2 Mon Sep 17 00:00:00 2001 From: sfauvel Date: Thu, 20 Feb 2025 12:14:56 +0100 Subject: [PATCH 5/6] fix: add `check-all-features-set` in `mithril-client` and fix code under features --- mithril-client/Makefile | 17 +++++++ .../src/cardano_database_client/api.rs | 47 ++++++++++++++++--- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/mithril-client/Makefile b/mithril-client/Makefile index 5562910930e..5d44d63acf8 100644 --- a/mithril-client/Makefile +++ b/mithril-client/Makefile @@ -6,6 +6,7 @@ args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}` CARGO = cargo +FEATURES := fs unstable all: test build @@ -25,3 +26,19 @@ clean: doc: ${CARGO} doc --no-deps --open --features full + +# Compute the powerset of all the given features and save it to a file +.feature-sets: + powerset() { [ $$# -eq 0 ] && echo || (shift; powerset "$$@") | while read r ; do echo "$$1 $$r"; echo "$$r"; done };\ + powerset $$(echo "$(FEATURES)") > .features-sets + +check-all-features-set: .feature-sets + # Read the file to run cargo clippy on all those features sets + cat .features-sets | while read features_set; do \ + echo "Clippy client with feature '$$features_set''"; \ + ${CARGO} clippy -p mithril-client --features "$$features_set"; \ + done + echo "Clippy client without features"; \ + ${CARGO} clippy -p mithril-client + + rm .features-sets diff --git a/mithril-client/src/cardano_database_client/api.rs b/mithril-client/src/cardano_database_client/api.rs index 9dcef1bb9ab..11673885b34 100644 --- a/mithril-client/src/cardano_database_client/api.rs +++ b/mithril-client/src/cardano_database_client/api.rs @@ -115,17 +115,18 @@ impl CardanoDatabaseClient { pub(crate) mod test_dependency_injector { use super::*; - use crate::{ - aggregator_client::MockAggregatorClient, - feedback::FeedbackReceiver, - file_downloader::{FileDownloader, MockFileDownloaderBuilder}, - test_utils, - }; + use crate::aggregator_client::MockAggregatorClient; + #[cfg(feature = "fs")] + use crate::file_downloader::{FileDownloader, MockFileDownloaderBuilder}; + #[cfg(feature = "fs")] + use crate::{feedback::FeedbackReceiver, test_utils}; /// Dependency injector for `CardanoDatabaseClient` for testing purposes. pub(crate) struct CardanoDatabaseClientDependencyInjector { aggregator_client: MockAggregatorClient, + #[cfg(feature = "fs")] http_file_downloader: Arc, + #[cfg(feature = "fs")] feedback_receivers: Vec>, } @@ -133,6 +134,7 @@ pub(crate) mod test_dependency_injector { pub(crate) fn new() -> Self { Self { aggregator_client: MockAggregatorClient::new(), + #[cfg(feature = "fs")] http_file_downloader: Arc::new( MockFileDownloaderBuilder::default() .with_compression(None) @@ -140,6 +142,7 @@ pub(crate) mod test_dependency_injector { .with_times(0) .build(), ), + #[cfg(feature = "fs")] feedback_receivers: vec![], } } @@ -153,6 +156,7 @@ pub(crate) mod test_dependency_injector { self } + #[cfg(feature = "fs")] pub(crate) fn with_http_file_downloader( self, http_file_downloader: Arc, @@ -163,6 +167,7 @@ pub(crate) mod test_dependency_injector { } } + #[cfg(feature = "fs")] pub(crate) fn with_feedback_receivers( self, feedback_receivers: &[Arc], @@ -173,6 +178,7 @@ pub(crate) mod test_dependency_injector { } } + #[cfg(feature = "fs")] pub(crate) fn build_cardano_database_client(self) -> CardanoDatabaseClient { CardanoDatabaseClient::new( Arc::new(self.aggregator_client), @@ -181,15 +187,23 @@ pub(crate) mod test_dependency_injector { test_utils::test_logger(), ) } + + #[cfg(not(feature = "fs"))] + pub(crate) fn build_cardano_database_client(self) -> CardanoDatabaseClient { + CardanoDatabaseClient::new(Arc::new(self.aggregator_client)) + } } mod tests { use mockall::predicate; - use crate::{aggregator_client::AggregatorRequest, feedback::StackFeedbackReceiver}; + use crate::aggregator_client::AggregatorRequest; + #[cfg(feature = "fs")] + use crate::feedback::StackFeedbackReceiver; use super::*; + #[cfg(feature = "fs")] #[test] fn test_cardano_database_client_dependency_injector_builds() { let _ = CardanoDatabaseClientDependencyInjector::new() @@ -214,5 +228,24 @@ pub(crate) mod test_dependency_injector { .with_feedback_receivers(&[Arc::new(StackFeedbackReceiver::new())]) .build_cardano_database_client(); } + + #[cfg(not(feature = "fs"))] + #[test] + fn test_cardano_database_client_dependency_injector_builds() { + let _ = CardanoDatabaseClientDependencyInjector::new() + .with_aggregator_client_mock_config(|http_client| { + let message = vec![CardanoDatabaseSnapshotListItem { + hash: "hash-123".to_string(), + ..CardanoDatabaseSnapshotListItem::dummy() + }]; + http_client + .expect_get_content() + .with(predicate::eq( + AggregatorRequest::ListCardanoDatabaseSnapshots, + )) + .return_once(move |_| Ok(serde_json::to_string(&message).unwrap())); + }) + .build_cardano_database_client(); + } } } From 8969387c81cbb937ab66e29e6ed396b242a1a1e8 Mon Sep 17 00:00:00 2001 From: sfauvel Date: Fri, 21 Feb 2025 12:10:14 +0100 Subject: [PATCH 6/6] chore: upgrade crate versions * mithril-client-cli from `0.11.1` to `0.11.2` * mithril-client from `0.11.3` to `0.11.4` * mithril-common from `0.5.5` to `0.5.6` --- Cargo.lock | 6 +++--- mithril-client-cli/Cargo.toml | 2 +- mithril-client/Cargo.toml | 2 +- mithril-common/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30c5e1e5ba5..fc8bf8a73e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3701,7 +3701,7 @@ dependencies = [ [[package]] name = "mithril-client" -version = "0.11.3" +version = "0.11.4" dependencies = [ "anyhow", "async-recursion", @@ -3732,7 +3732,7 @@ dependencies = [ [[package]] name = "mithril-client-cli" -version = "0.11.1" +version = "0.11.2" dependencies = [ "anyhow", "async-trait", @@ -3777,7 +3777,7 @@ dependencies = [ [[package]] name = "mithril-common" -version = "0.5.5" +version = "0.5.6" dependencies = [ "anyhow", "async-trait", diff --git a/mithril-client-cli/Cargo.toml b/mithril-client-cli/Cargo.toml index 2a630ed9c81..e5155e1f5a4 100644 --- a/mithril-client-cli/Cargo.toml +++ b/mithril-client-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-client-cli" -version = "0.11.1" +version = "0.11.2" description = "A Mithril Client" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-client/Cargo.toml b/mithril-client/Cargo.toml index e9142b92aca..12737f2f5a9 100644 --- a/mithril-client/Cargo.toml +++ b/mithril-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-client" -version = "0.11.3" +version = "0.11.4" description = "Mithril client library" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-common/Cargo.toml b/mithril-common/Cargo.toml index 752c5cfe0b1..abf397155e2 100644 --- a/mithril-common/Cargo.toml +++ b/mithril-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-common" -version = "0.5.5" +version = "0.5.6" description = "Common types, interfaces, and utilities for Mithril nodes." authors = { workspace = true } edition = { workspace = true }