Skip to content

Commit 6830ed1

Browse files
committed
Added ServerSetup struct
1 parent 65080fb commit 6830ed1

File tree

6 files changed

+256
-322
lines changed

6 files changed

+256
-322
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

primitives/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ futures = "0.3"
6868
async-trait = "0.1"
6969
# Other
7070
once_cell = "^1.8"
71+
wiremock = "0.5.12"
7172

7273
[dev-dependencies]
7374
pretty_assertions = "1"

primitives/src/test_util.rs

Lines changed: 197 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@ use chrono::{TimeZone, Utc};
44
use once_cell::sync::Lazy;
55

66
use crate::{
7+
balances::{Balances, UncheckedState},
78
campaign::{Active, Pricing, Validators},
89
channel::Nonce,
910
config::GANACHE_CONFIG,
10-
sentry::{CLICK, IMPRESSION},
11+
sentry::{
12+
message::Message, LastApproved, LastApprovedResponse, MessageResponse, SuccessResponse,
13+
ValidatorMessage, ValidatorMessagesListResponse, CLICK, IMPRESSION,
14+
},
1115
targeting::Rules,
12-
AdUnit, Address, Campaign, Channel, EventSubmission, UnifiedNum, ValidatorDesc, ValidatorId,
13-
IPFS,
16+
validator::{ApproveState, Heartbeat, MessageTypes, NewState, RejectState},
17+
AdUnit, Address, Campaign, Channel, EventSubmission, ToETHChecksum, UnifiedNum, ValidatorDesc,
18+
ValidatorId, IPFS,
19+
};
20+
21+
use wiremock::{
22+
matchers::{method, path, query_param},
23+
Mock, MockGuard, MockServer, ResponseTemplate,
1424
};
1525

1626
pub use logger::discard_logger;
@@ -296,6 +306,190 @@ pub static DUMMY_IPFS: Lazy<[IPFS; 5]> = Lazy::new(|| {
296306
]
297307
});
298308

309+
pub struct ServerSetup {
310+
pub server: MockServer,
311+
}
312+
313+
impl ServerSetup {
314+
pub async fn init(channel: &Channel) -> Self {
315+
let server = MockServer::start().await;
316+
let ok_response = SuccessResponse { success: true };
317+
318+
// Making sure all propagations to leader/follower succeed
319+
Mock::given(method("POST"))
320+
.and(path(format!(
321+
"leader/v5/channel/{}/validator-messages",
322+
channel.id()
323+
)))
324+
.respond_with(ResponseTemplate::new(200).set_body_json(&ok_response))
325+
.mount(&server)
326+
.await;
327+
328+
Mock::given(method("POST"))
329+
.and(path(format!(
330+
"follower/v5/channel/{}/validator-messages",
331+
channel.id()
332+
)))
333+
.respond_with(ResponseTemplate::new(200).set_body_json(&ok_response))
334+
.mount(&server)
335+
.await;
336+
337+
let heartbeat = Heartbeat {
338+
signature: String::new(),
339+
state_root: String::new(),
340+
timestamp: Utc::now(),
341+
};
342+
let heartbeat_res = ValidatorMessagesListResponse {
343+
messages: vec![ValidatorMessage {
344+
from: DUMMY_CAMPAIGN.channel.leader,
345+
received: Utc::now(),
346+
msg: MessageTypes::Heartbeat(heartbeat),
347+
}],
348+
};
349+
Mock::given(method("GET"))
350+
.and(path(format!(
351+
"/v5/channel/{}/validator-messages/{}/{}",
352+
DUMMY_CAMPAIGN.channel.id(),
353+
DUMMY_CAMPAIGN.channel.leader,
354+
"Heartbeat",
355+
)))
356+
.and(query_param("limit", "1"))
357+
.respond_with(ResponseTemplate::new(200).set_body_json(&heartbeat_res))
358+
.mount(&server)
359+
.await;
360+
361+
Self { server }
362+
}
363+
364+
pub async fn setup_new_state_response(
365+
&self,
366+
new_state_msg: Option<NewState<UncheckedState>>,
367+
) -> MockGuard {
368+
let new_state_res = match new_state_msg {
369+
Some(msg) => ValidatorMessagesListResponse {
370+
messages: vec![ValidatorMessage {
371+
from: DUMMY_CAMPAIGN.channel.leader,
372+
received: Utc::now(),
373+
msg: MessageTypes::NewState(msg),
374+
}],
375+
},
376+
None => ValidatorMessagesListResponse { messages: vec![] },
377+
};
378+
379+
Mock::given(method("GET"))
380+
.and(path(format!(
381+
"/v5/channel/{}/validator-messages/{}/{}",
382+
DUMMY_CAMPAIGN.channel.id(),
383+
DUMMY_CAMPAIGN.channel.leader,
384+
"NewState",
385+
)))
386+
.and(query_param("limit", "1"))
387+
.respond_with(ResponseTemplate::new(200).set_body_json(&new_state_res))
388+
.expect(1)
389+
.named("GET NewState helper")
390+
.mount_as_scoped(&self.server)
391+
.await
392+
}
393+
394+
// Gets wiremock to return a specific ApproveState message or None when called
395+
pub async fn setup_approve_state_response(
396+
&self,
397+
approve_state: Option<ApproveState>,
398+
) -> MockGuard {
399+
let approve_state_res = match approve_state {
400+
Some(msg) => ValidatorMessagesListResponse {
401+
messages: vec![ValidatorMessage {
402+
from: DUMMY_CAMPAIGN.channel.follower,
403+
received: Utc::now(),
404+
msg: MessageTypes::ApproveState(msg),
405+
}],
406+
},
407+
None => ValidatorMessagesListResponse { messages: vec![] },
408+
};
409+
410+
Mock::given(method("GET"))
411+
.and(path(format!(
412+
"/v5/channel/{}/validator-messages/{}/{}",
413+
DUMMY_CAMPAIGN.channel.id(),
414+
DUMMY_CAMPAIGN.channel.leader,
415+
"ApproveState+RejectState",
416+
)))
417+
.and(query_param("limit", "1"))
418+
.respond_with(ResponseTemplate::new(200).set_body_json(&approve_state_res))
419+
.expect(1)
420+
.named("GET ApproveState helper")
421+
.mount_as_scoped(&self.server)
422+
.await
423+
}
424+
425+
// Gets wiremock to return a specific RejectState message or None when called
426+
pub async fn setup_reject_state_response(
427+
&self,
428+
reject_state: Option<RejectState<UncheckedState>>,
429+
) -> MockGuard {
430+
let reject_state_res = match reject_state {
431+
Some(msg) => ValidatorMessagesListResponse {
432+
messages: vec![ValidatorMessage {
433+
from: DUMMY_CAMPAIGN.channel.follower,
434+
received: Utc::now(),
435+
msg: MessageTypes::RejectState(msg),
436+
}],
437+
},
438+
None => ValidatorMessagesListResponse { messages: vec![] },
439+
};
440+
441+
Mock::given(method("GET"))
442+
.and(path(format!(
443+
"/v5/channel/{}/validator-messages/{}/{}",
444+
DUMMY_CAMPAIGN.channel.id(),
445+
DUMMY_CAMPAIGN.channel.leader,
446+
"ApproveState+RejectState",
447+
)))
448+
.and(query_param("limit", "1"))
449+
.respond_with(ResponseTemplate::new(200).set_body_json(&reject_state_res))
450+
.expect(1)
451+
.named("GET RejectState helper")
452+
.mount_as_scoped(&self.server)
453+
.await
454+
}
455+
456+
pub async fn setup_last_approved_response(
457+
&self,
458+
balances: Balances<UncheckedState>,
459+
state_root: String,
460+
) -> MockGuard {
461+
let last_approved_new_state: NewState<UncheckedState> = NewState {
462+
state_root,
463+
signature: IDS[&*LEADER].to_checksum(),
464+
balances: balances.into_unchecked(),
465+
};
466+
let new_state_res = MessageResponse {
467+
from: IDS[&*LEADER],
468+
received: Utc::now(),
469+
msg: Message::new(last_approved_new_state),
470+
};
471+
let last_approved_response = LastApprovedResponse {
472+
last_approved: Some(LastApproved {
473+
new_state: Some(new_state_res),
474+
approve_state: None,
475+
}),
476+
heartbeats: None,
477+
};
478+
479+
Mock::given(method("GET"))
480+
.and(path(format!(
481+
"/v5/channel/{}/last-approved",
482+
DUMMY_CAMPAIGN.channel.id(),
483+
)))
484+
.and(query_param("withHeartbeat", "true"))
485+
.respond_with(ResponseTemplate::new(200).set_body_json(&last_approved_response))
486+
.expect(1)
487+
.named("GET LastApproved helper")
488+
.mount_as_scoped(&self.server)
489+
.await
490+
}
491+
}
492+
299493
#[cfg(test)]
300494
mod test {
301495
use super::*;

0 commit comments

Comments
 (0)