// Test for parametrisation on the number of roles use rand::{thread_rng, Rng}; use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send, session::Session}; use mpstthree::role::end::RoleEnd; use mpstthree::role::Role; use mpstthree::{ close_mpst, create_broadcast_role, create_choose_mpst_session_multi_both, create_choose_type_multi, create_meshedchannels, create_multiple_normal_name, create_multiple_normal_role, create_offer_mpst_session_multi, create_offer_type_multi, create_recv_mpst_session, create_send_mpst_session, fork_mpst_multi, }; use std::error::Error; // Create new MeshedChannels for three participants create_meshedchannels!(MeshedChannels, 3); // Create new roles // normal create_multiple_normal_role!( RoleA, RoleADual | RoleB, RoleBDual | RoleD, RoleDDual | ); // broadcast create_broadcast_role!(RoleAlltoD, RoleDtoAll); // Create new names create_multiple_normal_name!(NameA, NameB, NameD); // Create new send functions create_send_mpst_session!(send_mpst_d_to_a, RoleA, NameD, MeshedChannels, 3, 1); create_send_mpst_session!(send_mpst_a_to_d, RoleD, NameA, MeshedChannels, 3, 2); create_send_mpst_session!(send_mpst_d_to_b, RoleB, NameD, MeshedChannels, 3, 2); create_send_mpst_session!(send_mpst_b_to_a, RoleA, NameB, MeshedChannels, 3, 1); create_send_mpst_session!(send_mpst_a_to_b, RoleB, NameA, MeshedChannels, 3, 1); // Create new recv functions and related types // normal create_recv_mpst_session!(recv_mpst_d_from_a, RoleA, NameD, MeshedChannels, 3, 1); create_recv_mpst_session!(recv_mpst_a_from_d, RoleD, NameA, MeshedChannels, 3, 2); create_recv_mpst_session!(recv_mpst_b_from_d, RoleD, NameB, MeshedChannels, 3, 2); create_recv_mpst_session!(recv_mpst_b_from_a, RoleA, NameB, MeshedChannels, 3, 1); create_recv_mpst_session!(recv_mpst_a_from_b, RoleB, NameA, MeshedChannels, 3, 1); close_mpst!(close_mpst_multi, MeshedChannels, 3); create_offer_type_multi!(OfferMpstMultiThree, MeshedChannels, 3); create_choose_type_multi!(ChooseMpstThree, MeshedChannels, 3); create_offer_mpst_session_multi!( offer_mpst_session_a_to_d, OfferMpstMultiThree, RoleAlltoD, NameA, MeshedChannels, 3, 2 ); create_offer_mpst_session_multi!( offer_mpst_session_b_to_d, OfferMpstMultiThree, RoleAlltoD, NameB, MeshedChannels, 3, 2 ); create_choose_mpst_session_multi_both!( choose_left_mpst_session_d_to_all, choose_right_mpst_session_d_to_all, ChooseMpstThree, RoleDtoAll, NameD, MeshedChannels, 3 ); fork_mpst_multi!(fork_mpst, MeshedChannels, 3); // Types type AtoCClose = End; type AtoBClose = End; type AtoCVideo = Recv>; type AtoBVideo = Send>; type BtoAClose = ::Dual; type BtoCClose = End; type BtoAVideo = as Session>::Dual; type CtoBClose = ::Dual; type CtoAClose = ::Dual; type CtoAVideo = as Session>::Dual; // Stacks type StackAEnd = RoleEnd; type StackAEndDual = ::Dual; type StackAVideo = RoleD>>>; type StackAVideoDual = ::Dual; type StackAFull = RoleD>>; type StackBEnd = RoleEnd; type StackBEndDual = ::Dual; type StackBVideo = RoleA>; type StackBVideoDual = ::Dual; type StackBFull = RoleAlltoD; type StackCEnd = RoleEnd; type StackCVideo = RoleA>; type StackCChoice = RoleDtoAll; type StackCFull = RoleA>; // Creating the MP sessions // For C type ChooseCtoA = ChooseMpstThree< BtoAVideo, CtoAVideo, BtoAClose, CtoAClose, StackAVideoDual, StackAEnd, NameA, >; type ChooseCtoB = ChooseMpstThree< AtoBVideo, CtoBClose, AtoBClose, CtoBClose, StackBVideoDual, StackBEnd, NameB, >; type InitC = Send>>; type EndpointCFull = MeshedChannels, ChooseCtoB, StackCFull, NameD>; // For A type EndpointAVideo = MeshedChannels, AtoCVideo, StackAVideo, NameA>; type OfferA = OfferMpstMultiThree< AtoBVideo, AtoCVideo, AtoBClose, AtoCClose, StackAVideo, StackAEnd, NameA, >; type InitA = Recv>>; type EndpointAFull = MeshedChannels, StackAFull, NameA>; // For B type EndpointBVideo = MeshedChannels, BtoCClose, StackBVideo, NameB>; type OfferB = OfferMpstMultiThree< BtoAVideo, BtoCClose, BtoAClose, BtoCClose, StackBVideo, StackBEnd, NameB, >; type EndpointBFull = MeshedChannels, StackBFull, NameB>; // Functions related to endpoints fn server(s: EndpointBFull) -> Result<(), Box> { offer_mpst_session_b_to_d( s, |s: EndpointBVideo| { let (request, s) = recv_mpst_b_from_a(s)?; let s = send_mpst_b_to_a(request + 1, s); close_mpst_multi(s) }, close_mpst_multi, ) } fn authenticator(s: EndpointAFull) -> Result<(), Box> { let (id, s) = recv_mpst_a_from_d(s)?; let s = send_mpst_a_to_d(id + 1, s); offer_mpst_session_a_to_d( s, |s: EndpointAVideo| { let (request, s) = recv_mpst_a_from_d(s)?; let s = send_mpst_a_to_b(request + 1, s); let (video, s) = recv_mpst_a_from_b(s)?; let s = send_mpst_a_to_d(video + 1, s); assert_eq!(request, id + 1); assert_eq!(video, id + 3); close_mpst_multi(s) }, close_mpst_multi, ) } fn client_video(s: EndpointCFull) -> Result<(), Box> { let mut rng = thread_rng(); let id: i32 = rng.gen(); let s = send_mpst_d_to_a(id, s); let (accept, s) = recv_mpst_d_from_a(s)?; assert_eq!(accept, id + 1); let s = choose_left_mpst_session_d_to_all::< AtoBVideo, AtoCVideo, BtoAClose, CtoAClose, BtoCClose, AtoCClose, StackAVideoDual, StackAEndDual, NameA, StackBVideoDual, StackBEndDual, NameB, StackCVideo, StackCEnd, >(s); let s = send_mpst_d_to_a(accept, s); let (result, s) = recv_mpst_d_from_a(s)?; assert_eq!(result, accept + 3); close_mpst_multi(s) } fn client_close(s: EndpointCFull) -> Result<(), Box> { let mut rng = thread_rng(); let id: i32 = rng.gen(); let s = send_mpst_d_to_a(id, s); let (accept, s) = recv_mpst_d_from_a(s)?; assert_eq!(accept, id + 1); let s = choose_right_mpst_session_d_to_all::< AtoBVideo, AtoCVideo, BtoAClose, CtoAClose, BtoCClose, AtoCClose, StackAVideoDual, StackAEndDual, NameA, StackBVideoDual, StackBEndDual, NameB, StackCVideo, StackCEnd, >(s); close_mpst_multi(s) } //////////////////////////////////////// pub fn test_new_choice_full() { // Test video branch. let (thread_a, thread_pawn, thread_d) = fork_mpst(authenticator, server, client_video); assert!(thread_a.join().is_ok()); assert!(thread_pawn.join().is_ok()); assert!(thread_d.join().is_ok()); } pub fn test_new_choice_close() { // Test end branch. let (thread_a, thread_pawn, thread_d) = fork_mpst(authenticator, server, client_close); assert!(thread_a.join().is_ok()); assert!(thread_pawn.join().is_ok()); assert!(thread_d.join().is_ok()); }