pallet_message_queue/
mock_helpers.rs1#![allow(missing_docs)]
19
20use crate::*;
25use alloc::vec::Vec;
26use frame_support::traits::Defensive;
27
28pub trait IntoWeight {
30 fn into_weight(self) -> Weight;
31}
32
33impl IntoWeight for u64 {
34 fn into_weight(self) -> Weight {
35 Weight::from_parts(self, self)
36 }
37}
38
39#[derive(
41 Copy,
42 Clone,
43 Eq,
44 PartialEq,
45 Encode,
46 Decode,
47 DecodeWithMemTracking,
48 MaxEncodedLen,
49 TypeInfo,
50 Debug,
51)]
52pub enum MessageOrigin {
53 Here,
54 There,
55 Everywhere(u32),
56}
57
58impl From<u32> for MessageOrigin {
59 fn from(i: u32) -> Self {
60 Self::Everywhere(i)
61 }
62}
63
64pub struct NoopMessageProcessor<Origin, const REQUIRED_WEIGHT: u64 = 1>(PhantomData<Origin>);
68impl<Origin, const REQUIRED_WEIGHT: u64> ProcessMessage
69 for NoopMessageProcessor<Origin, REQUIRED_WEIGHT>
70where
71 Origin: codec::FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug,
72{
73 type Origin = Origin;
74
75 fn process_message(
76 _message: &[u8],
77 _origin: Self::Origin,
78 meter: &mut WeightMeter,
79 _id: &mut [u8; 32],
80 ) -> Result<bool, ProcessMessageError> {
81 let required = Weight::from_parts(REQUIRED_WEIGHT, REQUIRED_WEIGHT);
82
83 if meter.try_consume(required).is_ok() {
84 Ok(true)
85 } else {
86 Err(ProcessMessageError::Overweight(required))
87 }
88 }
89}
90
91pub fn msg<N: Get<u32>>(x: &str) -> BoundedSlice<u8, N> {
93 BoundedSlice::defensive_truncate_from(x.as_bytes())
94}
95
96pub fn vmsg(x: &str) -> Vec<u8> {
97 x.as_bytes().to_vec()
98}
99
100pub fn page<T: Config>(msg: &[u8]) -> PageOf<T> {
102 PageOf::<T>::from_message::<T>(msg.try_into().unwrap())
103}
104
105pub fn single_page_book<T: Config>() -> BookStateOf<T> {
107 BookState { begin: 0, end: 1, count: 1, message_count: 1, size: 1, ..Default::default() }
108}
109
110pub fn empty_book<T: Config>() -> BookStateOf<T> {
112 BookState { begin: 0, end: 1, count: 1, ..Default::default() }
113}
114
115pub fn full_page<T: Config>() -> (PageOf<T>, usize) {
117 let mut msgs = 0;
118 let mut page = PageOf::<T>::default();
119 for i in 0..u32::MAX {
120 let r = i.using_encoded(|d| page.try_append_message::<T>(d.try_into().unwrap()));
121 if r.is_err() {
122 break
123 } else {
124 msgs += 1;
125 }
126 }
127 assert!(msgs > 0, "page must hold at least one message");
128 (page, msgs)
129}
130
131pub fn book_for<T: Config>(page: &PageOf<T>) -> BookStateOf<T> {
133 BookState {
134 count: 1,
135 begin: 0,
136 end: 1,
137 message_count: page.remaining.into() as u64,
138 size: page.remaining_size.into() as u64,
139 ..Default::default()
140 }
141}
142
143#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
145pub fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
146 assert!(
147 !frame_system::Pallet::<T>::block_number().is_zero(),
148 "The genesis block has n o events"
149 );
150 frame_system::Pallet::<T>::assert_last_event(generic_event.into());
151}
152
153pub fn setup_bump_service_head<T: Config>(
155 current: <<T as Config>::MessageProcessor as ProcessMessage>::Origin,
156 next: <<T as Config>::MessageProcessor as ProcessMessage>::Origin,
157) {
158 crate::Pallet::<T>::enqueue_message(msg("1"), current);
159 crate::Pallet::<T>::enqueue_message(msg("1"), next);
160}
161
162pub fn knit<T: Config>(o: &<<T as Config>::MessageProcessor as ProcessMessage>::Origin) {
164 let mut b = BookStateFor::<T>::get(o);
165 b.ready_neighbours = crate::Pallet::<T>::ready_ring_knit(o).ok().defensive();
166 BookStateFor::<T>::insert(o, b);
167}
168
169pub fn unknit<T: Config>(o: &<<T as Config>::MessageProcessor as ProcessMessage>::Origin) {
171 let mut b = BookStateFor::<T>::get(o);
172 crate::Pallet::<T>::ready_ring_unknit(o, b.ready_neighbours.unwrap());
173 b.ready_neighbours = None;
174 BookStateFor::<T>::insert(o, b);
175}
176
177pub fn build_ring<T: Config>(
179 queues: &[<<T as Config>::MessageProcessor as ProcessMessage>::Origin],
180) {
181 for queue in queues.iter() {
182 crate::Pallet::<T>::enqueue_message(msg("1"), queue.clone());
183 }
184 assert_ring::<T>(queues);
185}
186
187pub fn assert_ring<T: Config>(
191 queues: &[<<T as Config>::MessageProcessor as ProcessMessage>::Origin],
192) {
193 for (i, origin) in queues.iter().enumerate() {
194 let book = BookStateFor::<T>::get(origin);
195 assert_eq!(
196 book.ready_neighbours,
197 Some(Neighbours {
198 prev: queues[(i + queues.len() - 1) % queues.len()].clone(),
199 next: queues[(i + 1) % queues.len()].clone(),
200 })
201 );
202 }
203 assert_eq!(ServiceHead::<T>::get(), queues.first().cloned());
204}