Skip to content

Commit 140e41e

Browse files
committed
feature(protocol-config): put back aggregator_features route call
1 parent 34308a1 commit 140e41e

File tree

1 file changed

+133
-76
lines changed

1 file changed

+133
-76
lines changed

internal/mithril-protocol-config/src/http_client/aggregator_client.rs

Lines changed: 133 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use mithril_common::{
1212
api_version::APIVersionProvider,
1313
entities::{ClientError, ServerError},
1414
logging::LoggerExtensions,
15-
messages::EpochSettingsMessage,
15+
messages::{AggregatorFeaturesMessage, EpochSettingsMessage},
1616
};
1717

1818
const JSON_CONTENT_TYPE: HeaderValue = HeaderValue::from_static("application/json");
@@ -124,6 +124,11 @@ pub trait AggregatorClient: Sync + Send {
124124
async fn retrieve_epoch_settings(
125125
&self,
126126
) -> Result<Option<EpochSettingsMessage>, AggregatorClientError>;
127+
128+
/// Retrieves aggregator features message from the aggregator
129+
async fn retrieve_aggregator_features(
130+
&self,
131+
) -> Result<AggregatorFeaturesMessage, AggregatorClientError>;
127132
}
128133

129134
/// AggregatorHTTPClient is a http client for an aggregator
@@ -244,45 +249,30 @@ impl AggregatorClient for AggregatorHTTPClient {
244249
Err(err) => Err(AggregatorClientError::RemoteServerUnreachable(anyhow!(err))),
245250
}
246251
}
247-
}
248-
249-
#[cfg(test)]
250-
pub(crate) mod dumb {
251-
use mithril_common::test::double::Dummy;
252-
use tokio::sync::RwLock;
253-
254-
use super::*;
255-
256-
/// This aggregator client is intended to be used by test services.
257-
/// It actually does not communicate with an aggregator host but mimics this behavior.
258-
/// It is driven by a Tester that controls the data it can return, and it can return its internal state for testing.
259-
pub struct DumbAggregatorClient {
260-
epoch_settings: RwLock<Option<EpochSettingsMessage>>,
261-
}
262252

263-
// impl DumbAggregatorClient {
264-
// /// Return the last signer that called with the `register` method.
265-
// pub async fn get_last_registered_signer(&self) -> Option<Signer> {
266-
// self.last_registered_signer.read().await.clone()
267-
// }
268-
// }
269-
270-
impl Default for DumbAggregatorClient {
271-
fn default() -> Self {
272-
Self {
273-
epoch_settings: RwLock::new(Some(EpochSettingsMessage::dummy())),
274-
}
275-
}
276-
}
253+
async fn retrieve_aggregator_features(
254+
&self,
255+
) -> Result<AggregatorFeaturesMessage, AggregatorClientError> {
256+
debug!(self.logger, "Retrieve aggregator features message");
257+
let url = format!("{}/", self.aggregator_endpoint);
258+
let response = self
259+
.prepare_request_builder(self.prepare_http_client()?.get(url.clone()))
260+
.send()
261+
.await;
277262

278-
#[async_trait]
279-
impl AggregatorClient for DumbAggregatorClient {
280-
async fn retrieve_epoch_settings(
281-
&self,
282-
) -> Result<Option<EpochSettingsMessage>, AggregatorClientError> {
283-
let epoch_settings = self.epoch_settings.read().await.clone();
263+
match response {
264+
Ok(response) => match response.status() {
265+
StatusCode::OK => {
266+
self.warn_if_api_version_mismatch(&response);
284267

285-
Ok(epoch_settings)
268+
Ok(response
269+
.json::<AggregatorFeaturesMessage>()
270+
.await
271+
.map_err(|e| AggregatorClientError::JsonParseFailed(anyhow!(e)))?)
272+
}
273+
_ => Err(AggregatorClientError::from_response(response).await),
274+
},
275+
Err(err) => Err(AggregatorClientError::RemoteServerUnreachable(anyhow!(err))),
286276
}
287277
}
288278
}
@@ -305,6 +295,17 @@ mod tests {
305295

306296
use super::*;
307297

298+
macro_rules! assert_is_error {
299+
($error:expr, $error_type:pat) => {
300+
assert!(
301+
matches!($error, $error_type),
302+
"Expected {} error, got '{:?}'.",
303+
stringify!($error_type),
304+
$error
305+
);
306+
};
307+
}
308+
308309
fn setup_client<U: Into<String>>(server_url: U) -> AggregatorHTTPClient {
309310
let discriminant_source = DummyApiVersionDiscriminantSource::new("dummy");
310311
let api_version_provider = APIVersionProvider::new(Arc::new(discriminant_source));
@@ -366,52 +367,108 @@ mod tests {
366367
};
367368
}
368369

369-
#[tokio::test]
370-
async fn test_epoch_settings_ok_200() {
371-
let (server, client) = setup_server_and_client();
372-
let epoch_settings_expected = EpochSettingsMessage::dummy();
373-
let _server_mock = server.mock(|when, then| {
374-
when.path("/epoch-settings");
375-
then.status(200).body(json!(epoch_settings_expected).to_string());
376-
});
370+
mod epoch_settings {
371+
use super::*;
377372

378-
let epoch_settings = client.retrieve_epoch_settings().await;
379-
epoch_settings.as_ref().expect("unexpected error");
380-
assert_eq!(epoch_settings_expected, epoch_settings.unwrap().unwrap());
381-
}
373+
#[tokio::test]
374+
async fn test_epoch_settings_ok_200() {
375+
let (server, client) = setup_server_and_client();
376+
let epoch_settings_expected = EpochSettingsMessage::dummy();
377+
let _server_mock = server.mock(|when, then| {
378+
when.path("/epoch-settings");
379+
then.status(200).body(json!(epoch_settings_expected).to_string());
380+
});
382381

383-
#[tokio::test]
384-
async fn test_epoch_settings_ko_500() {
385-
let (server, client) = setup_server_and_client();
386-
let _server_mock = server.mock(|when, then| {
387-
when.path("/epoch-settings");
388-
then.status(500).body("an error occurred");
389-
});
382+
let epoch_settings = client.retrieve_epoch_settings().await;
383+
epoch_settings.as_ref().expect("unexpected error");
384+
assert_eq!(epoch_settings_expected, epoch_settings.unwrap().unwrap());
385+
}
390386

391-
match client.retrieve_epoch_settings().await.unwrap_err() {
392-
AggregatorClientError::RemoteServerTechnical(_) => (),
393-
e => panic!("Expected Aggregator::RemoteServerTechnical error, got '{e:?}'."),
394-
};
387+
#[tokio::test]
388+
async fn test_epoch_settings_ko_500() {
389+
let (server, client) = setup_server_and_client();
390+
let _server_mock = server.mock(|when, then| {
391+
when.path("/epoch-settings");
392+
then.status(500).body("an error occurred");
393+
});
394+
395+
match client.retrieve_epoch_settings().await.unwrap_err() {
396+
AggregatorClientError::RemoteServerTechnical(_) => (),
397+
e => panic!("Expected Aggregator::RemoteServerTechnical error, got '{e:?}'."),
398+
};
399+
}
400+
401+
#[tokio::test]
402+
async fn test_epoch_settings_timeout() {
403+
let (server, mut client) = setup_server_and_client();
404+
client.timeout_duration = Some(Duration::from_millis(10));
405+
let _server_mock = server.mock(|when, then| {
406+
when.path("/epoch-settings");
407+
then.delay(Duration::from_millis(100));
408+
});
409+
410+
let error = client
411+
.retrieve_epoch_settings()
412+
.await
413+
.expect_err("retrieve_epoch_settings should fail");
414+
415+
assert!(
416+
matches!(error, AggregatorClientError::RemoteServerUnreachable(_)),
417+
"unexpected error type: {error:?}"
418+
);
419+
}
395420
}
396421

397-
#[tokio::test]
398-
async fn test_epoch_settings_timeout() {
399-
let (server, mut client) = setup_server_and_client();
400-
client.timeout_duration = Some(Duration::from_millis(10));
401-
let _server_mock = server.mock(|when, then| {
402-
when.path("/epoch-settings");
403-
then.delay(Duration::from_millis(100));
404-
});
422+
mod aggregator_features {
423+
use super::*;
424+
425+
#[tokio::test]
426+
async fn test_aggregator_features_ok_200() {
427+
let (server, client) = setup_server_and_client();
428+
let message_expected = AggregatorFeaturesMessage::dummy();
429+
let _server_mock = server.mock(|when, then| {
430+
when.path("/");
431+
then.status(200).body(json!(message_expected).to_string());
432+
});
405433

406-
let error = client
407-
.retrieve_epoch_settings()
408-
.await
409-
.expect_err("retrieve_epoch_settings should fail");
434+
let message = client.retrieve_aggregator_features().await.unwrap();
410435

411-
assert!(
412-
matches!(error, AggregatorClientError::RemoteServerUnreachable(_)),
413-
"unexpected error type: {error:?}"
414-
);
436+
assert_eq!(message_expected, message);
437+
}
438+
439+
#[tokio::test]
440+
async fn test_aggregator_features_ko_500() {
441+
let (server, client) = setup_server_and_client();
442+
set_returning_500(&server);
443+
444+
let error = client.retrieve_aggregator_features().await.unwrap_err();
445+
446+
assert_is_error!(error, AggregatorClientError::RemoteServerTechnical(_));
447+
}
448+
449+
#[tokio::test]
450+
async fn test_aggregator_features_ko_json_serialization() {
451+
let (server, client) = setup_server_and_client();
452+
set_unparsable_json(&server);
453+
454+
let error = client.retrieve_aggregator_features().await.unwrap_err();
455+
456+
assert_is_error!(error, AggregatorClientError::JsonParseFailed(_));
457+
}
458+
459+
#[tokio::test]
460+
async fn test_aggregator_features_timeout() {
461+
let (server, mut client) = setup_server_and_client();
462+
client.timeout_duration = Some(Duration::from_millis(10));
463+
let _server_mock = server.mock(|when, then| {
464+
when.path("/");
465+
then.delay(Duration::from_millis(100));
466+
});
467+
468+
let error = client.retrieve_aggregator_features().await.unwrap_err();
469+
470+
assert_is_error!(error, AggregatorClientError::RemoteServerUnreachable(_));
471+
}
415472
}
416473

417474
#[tokio::test]

0 commit comments

Comments
 (0)