@@ -94,15 +94,29 @@ impl AggregatorDiscoverer for CapableAggregatorDiscoverer {
9494mod tests {
9595 use std:: collections:: BTreeSet ;
9696
97+ use httpmock:: MockServer ;
98+ use serde_json:: json;
99+
97100 use mithril_common:: {
98101 AggregateSignatureType ,
99102 entities:: SignedEntityTypeDiscriminants :: {
100103 CardanoDatabase , CardanoStakeDistribution , CardanoTransactions ,
101104 } ,
105+ messages:: AggregatorFeaturesMessage ,
102106 } ;
103107
104108 use super :: * ;
105109
110+ fn create_aggregator_features_message (
111+ capabilities : AggregatorCapabilities ,
112+ ) -> AggregatorFeaturesMessage {
113+ AggregatorFeaturesMessage {
114+ open_api_version : "1.0.0" . to_string ( ) ,
115+ documentation_url : "https://docs" . to_string ( ) ,
116+ capabilities,
117+ }
118+ }
119+
106120 #[ test]
107121 fn capabilities_match_success ( ) {
108122 let required = AggregatorCapabilities {
@@ -145,18 +159,192 @@ mod tests {
145159 ) ) ;
146160 }
147161
148- #[ tokio:: test]
162+ #[ tokio:: test( flavor = "multi_thread" ) ]
149163 async fn get_available_aggregators_success ( ) {
150- todo ! ( )
164+ let capabilities = AggregatorCapabilities {
165+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
166+ signed_entity_types : BTreeSet :: from ( [ CardanoStakeDistribution , CardanoTransactions ] ) ,
167+ cardano_transactions_prover : None ,
168+ } ;
169+ let aggregator_server = MockServer :: start ( ) ;
170+ let aggregator_server_mock = aggregator_server. mock ( |when, then| {
171+ when. path ( "/" ) ;
172+ then. status ( 200 )
173+ . body ( json ! ( create_aggregator_features_message( capabilities) ) . to_string ( ) ) ;
174+ } ) ;
175+ let discoverer = CapableAggregatorDiscoverer :: new (
176+ AggregatorCapabilities {
177+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
178+ signed_entity_types : BTreeSet :: from ( [ CardanoTransactions ] ) ,
179+ cardano_transactions_prover : None ,
180+ } ,
181+ Arc :: new ( crate :: test:: double:: AggregatorDiscovererFake :: new ( vec ! [
182+ Ok ( vec![ AggregatorEndpoint :: new( aggregator_server. url( "/" ) ) ] ) ,
183+ ] ) ) ,
184+ ) ;
185+
186+ let mut aggregators = discoverer
187+ . get_available_aggregators ( MithrilNetwork :: new ( "release-devnet" . into ( ) ) )
188+ . await
189+ . unwrap ( ) ;
190+
191+ let next_aggregator = aggregators. next ( ) ;
192+ aggregator_server_mock. assert ( ) ;
193+ assert_eq ! (
194+ Some ( AggregatorEndpoint :: new( aggregator_server. url( "/" ) ) ) ,
195+ next_aggregator
196+ ) ;
151197 }
152198
153- #[ tokio:: test]
154- async fn get_available_aggregators_success_when_one_aggregator_capabilities_does_not_match ( ) {
155- todo ! ( )
199+ #[ tokio:: test( flavor = "multi_thread" ) ]
200+ async fn get_available_aggregators_succeeds_when_aggregator_capabilities_do_not_match ( ) {
201+ let capabilities = AggregatorCapabilities {
202+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
203+ signed_entity_types : BTreeSet :: from ( [ CardanoTransactions ] ) ,
204+ cardano_transactions_prover : None ,
205+ } ;
206+ let aggregator_server = MockServer :: start ( ) ;
207+ let aggregator_server_mock = aggregator_server. mock ( |when, then| {
208+ when. path ( "/" ) ;
209+ then. status ( 200 )
210+ . body ( json ! ( create_aggregator_features_message( capabilities) ) . to_string ( ) ) ;
211+ } ) ;
212+ let discoverer = CapableAggregatorDiscoverer :: new (
213+ AggregatorCapabilities {
214+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
215+ signed_entity_types : BTreeSet :: from ( [ CardanoDatabase ] ) ,
216+ cardano_transactions_prover : None ,
217+ } ,
218+ Arc :: new ( crate :: test:: double:: AggregatorDiscovererFake :: new ( vec ! [
219+ Ok ( vec![ AggregatorEndpoint :: new( aggregator_server. url( "/" ) ) ] ) ,
220+ ] ) ) ,
221+ ) ;
222+
223+ let mut aggregators = discoverer
224+ . get_available_aggregators ( MithrilNetwork :: new ( "release-devnet" . into ( ) ) )
225+ . await
226+ . unwrap ( ) ;
227+
228+ let next_aggregator = aggregators. next ( ) ;
229+ aggregator_server_mock. assert ( ) ;
230+ assert ! ( next_aggregator. is_none( ) ) ;
156231 }
157232
158- #[ tokio:: test]
159- async fn get_available_aggregators_success_when_one_aggregator_retruns_an_error ( ) {
160- todo ! ( )
233+ #[ tokio:: test( flavor = "multi_thread" ) ]
234+ async fn get_available_aggregators_succeeds_when_one_aggregator_returns_an_error ( ) {
235+ let aggregator_server_1 = MockServer :: start ( ) ;
236+ let aggregator_server_mock_1 = aggregator_server_1. mock ( |when, then| {
237+ when. path ( "/" ) ;
238+ then. status ( 500 ) ;
239+ } ) ;
240+ let capabilities_2 = AggregatorCapabilities {
241+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
242+ signed_entity_types : BTreeSet :: from ( [ CardanoStakeDistribution , CardanoDatabase ] ) ,
243+ cardano_transactions_prover : None ,
244+ } ;
245+ let aggregator_server_2 = MockServer :: start ( ) ;
246+ let aggregator_server_mock_2 = aggregator_server_2. mock ( |when, then| {
247+ when. path ( "/" ) ;
248+ then. status ( 200 )
249+ . body ( json ! ( create_aggregator_features_message( capabilities_2) ) . to_string ( ) ) ;
250+ } ) ;
251+ let discoverer = CapableAggregatorDiscoverer :: new (
252+ AggregatorCapabilities {
253+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
254+ signed_entity_types : BTreeSet :: from ( [ CardanoDatabase ] ) ,
255+ cardano_transactions_prover : None ,
256+ } ,
257+ Arc :: new ( crate :: test:: double:: AggregatorDiscovererFake :: new ( vec ! [
258+ Ok ( vec![
259+ AggregatorEndpoint :: new( aggregator_server_1. url( "/" ) ) ,
260+ AggregatorEndpoint :: new( aggregator_server_2. url( "/" ) ) ,
261+ ] ) ,
262+ ] ) ) ,
263+ ) ;
264+
265+ let mut aggregators = discoverer
266+ . get_available_aggregators ( MithrilNetwork :: new ( "release-devnet" . into ( ) ) )
267+ . await
268+ . unwrap ( ) ;
269+
270+ let next_aggregator = aggregators. next ( ) ;
271+ aggregator_server_mock_1. assert ( ) ;
272+ aggregator_server_mock_2. assert ( ) ;
273+ assert_eq ! (
274+ Some ( AggregatorEndpoint :: new( aggregator_server_2. url( "/" ) ) ) ,
275+ next_aggregator
276+ ) ;
277+ }
278+
279+ #[ tokio:: test( flavor = "multi_thread" ) ]
280+ async fn get_available_aggregators_succeeds_and_makes_minimum_calls_to_aggregators ( ) {
281+ let aggregator_server_1 = MockServer :: start ( ) ;
282+ let aggregator_server_mock_1 = aggregator_server_1. mock ( |when, then| {
283+ when. path ( "/" ) ;
284+ then. status ( 500 ) ;
285+ } ) ;
286+ let capabilities_2 = AggregatorCapabilities {
287+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
288+ signed_entity_types : BTreeSet :: from ( [ CardanoStakeDistribution ] ) ,
289+ cardano_transactions_prover : None ,
290+ } ;
291+ let aggregator_server_2 = MockServer :: start ( ) ;
292+ let aggregator_server_mock_2 = aggregator_server_2. mock ( |when, then| {
293+ when. path ( "/" ) ;
294+ then. status ( 200 )
295+ . body ( json ! ( create_aggregator_features_message( capabilities_2) ) . to_string ( ) ) ;
296+ } ) ;
297+ let capabilities_3 = AggregatorCapabilities {
298+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
299+ signed_entity_types : BTreeSet :: from ( [ CardanoDatabase ] ) ,
300+ cardano_transactions_prover : None ,
301+ } ;
302+ let aggregator_server_3 = MockServer :: start ( ) ;
303+ let aggregator_server_mock_3 = aggregator_server_3. mock ( |when, then| {
304+ when. path ( "/" ) ;
305+ then. status ( 200 )
306+ . body ( json ! ( create_aggregator_features_message( capabilities_3) ) . to_string ( ) ) ;
307+ } ) ;
308+ let capabilities_4 = AggregatorCapabilities {
309+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
310+ signed_entity_types : BTreeSet :: from ( [ CardanoDatabase ] ) ,
311+ cardano_transactions_prover : None ,
312+ } ;
313+ let aggregator_server_4 = MockServer :: start ( ) ;
314+ let aggregator_server_mock_4 = aggregator_server_4. mock ( |when, then| {
315+ when. path ( "/" ) ;
316+ then. status ( 200 )
317+ . body ( json ! ( create_aggregator_features_message( capabilities_4) ) . to_string ( ) ) ;
318+ } ) ;
319+ let discoverer = CapableAggregatorDiscoverer :: new (
320+ AggregatorCapabilities {
321+ aggregate_signature_type : AggregateSignatureType :: Concatenation ,
322+ signed_entity_types : BTreeSet :: from ( [ CardanoDatabase ] ) ,
323+ cardano_transactions_prover : None ,
324+ } ,
325+ Arc :: new ( crate :: test:: double:: AggregatorDiscovererFake :: new ( vec ! [
326+ Ok ( vec![
327+ AggregatorEndpoint :: new( aggregator_server_1. url( "/" ) ) ,
328+ AggregatorEndpoint :: new( aggregator_server_2. url( "/" ) ) ,
329+ AggregatorEndpoint :: new( aggregator_server_3. url( "/" ) ) ,
330+ AggregatorEndpoint :: new( aggregator_server_4. url( "/" ) ) ,
331+ ] ) ,
332+ ] ) ) ,
333+ ) ;
334+
335+ let mut aggregators = discoverer
336+ . get_available_aggregators ( MithrilNetwork :: new ( "release-devnet" . into ( ) ) )
337+ . await
338+ . unwrap ( ) ;
339+
340+ let next_aggregator = aggregators. next ( ) ;
341+ aggregator_server_mock_1. assert ( ) ;
342+ aggregator_server_mock_2. assert ( ) ;
343+ aggregator_server_mock_3. assert ( ) ;
344+ assert_eq ! ( 0 , aggregator_server_mock_4. calls( ) ) ;
345+ assert_eq ! (
346+ Some ( AggregatorEndpoint :: new( aggregator_server_3. url( "/" ) ) ) ,
347+ next_aggregator
348+ ) ;
161349 }
162350}
0 commit comments