Skip to content

Commit

Permalink
Merge pull request #2320 from input-output-hk/sfa/2293/support_evolvi…
Browse files Browse the repository at this point in the history
…ng_cloud_artifact_locations_type

feat: Implement an Unknown variant in the artifact locations
  • Loading branch information
sfauvel authored Feb 21, 2025
2 parents be28830 + 8969387 commit 01f83cd
Show file tree
Hide file tree
Showing 12 changed files with 371 additions and 83 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mithril-client-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 }
Expand Down
159 changes: 101 additions & 58 deletions mithril-client-cli/src/commands/cardano_db_v2/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -117,61 +113,60 @@ impl CardanoDbShowCommand {
}
}

fn digest_location_iter(locations: &[DigestLocation]) -> impl Iterator<Item = String> + 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<Vec<CellStruct>> {
let location_name = "Digest location";
format_location_rows("Digest location", digest_location_iter(locations))
}

locations
.iter()
.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(),
]
}
})
.collect()
fn immutables_location_iter(
locations: &[ImmutablesLocation],
) -> impl Iterator<Item = String> + 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<Vec<CellStruct>> {
let location_name = "Immutables location";
format_location_rows("Immutables location", immutables_location_iter(locations))
}

locations
.iter()
.enumerate()
.map(|(index, location)| match location {
ImmutablesLocation::CloudStorage { uri } => match uri {
MultiFilesUri::Template(template_uri) => {
vec![
format!("{location_name} ({})", index + 1).cell(),
format!("CloudStorage, template_uri: \"{}\"", template_uri.0).cell(),
]
}
},
})
.collect()
fn ancillary_location_iter(
locations: &[AncillaryLocation],
) -> impl Iterator<Item = String> + 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<Vec<CellStruct>> {
let location_name = "Ancillary location";
format_location_rows("Ancillary location", ancillary_location_iter(locations))
}

fn format_location_rows(
location_name: &str,
locations: impl Iterator<Item = String>,
) -> Vec<Vec<CellStruct>> {
locations
.iter()
.enumerate()
.map(|(index, location)| match location {
AncillaryLocation::CloudStorage { uri } => {
vec![
format!("{location_name} ({})", index + 1).cell(),
format!("CloudStorage, uri: \"{}\"", uri).cell(),
]
}
.map(|(index, cell_content)| {
vec![
format!("{location_name} ({})", index + 1).cell(),
cell_content.cell(),
]
})
.collect()
}
Expand Down Expand Up @@ -212,6 +207,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(&[]);
Expand Down Expand Up @@ -243,6 +254,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(&[]);
Expand Down Expand Up @@ -273,4 +300,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)"));
}
}
2 changes: 1 addition & 1 deletion mithril-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 }
Expand Down
17 changes: 17 additions & 0 deletions mithril-client/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`

CARGO = cargo
FEATURES := fs unstable

all: test build

Expand All @@ -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
47 changes: 40 additions & 7 deletions mithril-client/src/cardano_database_client/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,31 +115,34 @@ 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<dyn FileDownloader>,
#[cfg(feature = "fs")]
feedback_receivers: Vec<Arc<dyn FeedbackReceiver>>,
}

impl CardanoDatabaseClientDependencyInjector {
pub(crate) fn new() -> Self {
Self {
aggregator_client: MockAggregatorClient::new(),
#[cfg(feature = "fs")]
http_file_downloader: Arc::new(
MockFileDownloaderBuilder::default()
.with_compression(None)
.with_success()
.with_times(0)
.build(),
),
#[cfg(feature = "fs")]
feedback_receivers: vec![],
}
}
Expand All @@ -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<dyn FileDownloader>,
Expand All @@ -163,6 +167,7 @@ pub(crate) mod test_dependency_injector {
}
}

#[cfg(feature = "fs")]
pub(crate) fn with_feedback_receivers(
self,
feedback_receivers: &[Arc<dyn FeedbackReceiver>],
Expand All @@ -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),
Expand All @@ -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()
Expand All @@ -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();
}
}
}
Loading

0 comments on commit 01f83cd

Please sign in to comment.