pallet_migrations/
mock_helpers.rs1#![allow(missing_docs)]
21
22use alloc::{vec, vec::Vec};
23use codec::{Decode, Encode};
24use frame_support::{
25 migrations::*,
26 weights::{Weight, WeightMeter},
27};
28use sp_core::ConstU32;
29use sp_runtime::BoundedVec;
30
31pub type MockedIdentifier = BoundedVec<u8, ConstU32<256>>;
33
34#[derive(Debug, Clone, Copy, Encode, Decode)]
36pub enum MockedMigrationKind {
37 SucceedAfter,
39 FailAfter,
41 TimeoutAfter,
43 HighWeightAfter(Weight),
46 #[cfg(feature = "try-runtime")]
48 PreUpgradeFail,
49 #[cfg(feature = "try-runtime")]
51 PostUpgradeFail,
52}
53use MockedMigrationKind::*; pub fn mocked_id(kind: MockedMigrationKind, steps: u32) -> MockedIdentifier {
57 (b"MockedMigration", kind, steps).encode().try_into().unwrap()
58}
59
60frame_support::parameter_types! {
61 storage MIGRATIONS: Vec<(MockedMigrationKind, u32)> = vec![];
63}
64
65pub struct MockedMigrations;
69impl SteppedMigrations for MockedMigrations {
70 fn len() -> u32 {
71 MIGRATIONS::get().len() as u32
72 }
73
74 fn nth_id(n: u32) -> Option<Vec<u8>> {
75 let k = MIGRATIONS::get().get(n as usize).copied();
76 k.map(|(kind, steps)| mocked_id(kind, steps).into_inner())
77 }
78
79 fn nth_step(
80 n: u32,
81 cursor: Option<Vec<u8>>,
82 _meter: &mut WeightMeter,
83 ) -> Option<Result<Option<Vec<u8>>, SteppedMigrationError>> {
84 let (kind, steps) = MIGRATIONS::get()[n as usize];
85
86 let mut count: u32 =
87 cursor.as_ref().and_then(|c| Decode::decode(&mut &c[..]).ok()).unwrap_or(0);
88 log::debug!("MockedMigration: Step {count} vs max {steps}");
89 if count != steps || matches!(kind, TimeoutAfter) {
90 count += 1;
91 return Some(Ok(Some(count.encode())))
92 }
93
94 Some(match kind {
95 SucceedAfter => {
96 log::debug!("MockedMigration: Succeeded after {count} steps");
97 Ok(None)
98 },
99 HighWeightAfter(required) => {
100 log::debug!("MockedMigration: Not enough weight after {count} steps");
101 Err(SteppedMigrationError::InsufficientWeight { required })
102 },
103 FailAfter => {
104 log::debug!("MockedMigration: Failed after {count} steps");
105 Err(SteppedMigrationError::Failed)
106 },
107 TimeoutAfter => unreachable!(),
108 #[cfg(feature = "try-runtime")]
109 PreUpgradeFail | PostUpgradeFail => Ok(None),
110 })
111 }
112
113 fn nth_transactional_step(
114 n: u32,
115 cursor: Option<Vec<u8>>,
116 meter: &mut WeightMeter,
117 ) -> Option<Result<Option<Vec<u8>>, SteppedMigrationError>> {
118 Self::nth_step(n, cursor, meter)
120 }
121
122 fn nth_max_steps(n: u32) -> Option<Option<u32>> {
123 MIGRATIONS::get().get(n as usize).map(|(_, s)| Some(*s))
124 }
125
126 #[cfg(feature = "try-runtime")]
127 fn nth_pre_upgrade(n: u32) -> Option<Result<Vec<u8>, sp_runtime::TryRuntimeError>> {
128 let (kind, _) = MIGRATIONS::get()[n as usize];
129
130 if let PreUpgradeFail = kind {
131 return Some(Err("Some pre-upgrade error".into()))
132 }
133
134 Some(Ok(vec![]))
135 }
136
137 #[cfg(feature = "try-runtime")]
138 fn nth_post_upgrade(
139 n: u32,
140 _state: Vec<u8>,
141 ) -> Option<Result<(), sp_runtime::TryRuntimeError>> {
142 let (kind, _) = MIGRATIONS::get()[n as usize];
143
144 if let PostUpgradeFail = kind {
145 return Some(Err("Some post-upgrade error".into()))
146 }
147
148 Some(Ok(()))
149 }
150
151 fn cursor_max_encoded_len() -> usize {
152 65_536
153 }
154
155 fn identifier_max_encoded_len() -> usize {
156 256
157 }
158}
159
160impl MockedMigrations {
161 pub fn set(migrations: Vec<(MockedMigrationKind, u32)>) {
163 MIGRATIONS::set(&migrations);
164 }
165}
166
167impl crate::MockedMigrations for MockedMigrations {
168 fn set_fail_after(steps: u32) {
169 MIGRATIONS::set(&vec![(FailAfter, steps)]);
170 }
171
172 fn set_success_after(steps: u32) {
173 MIGRATIONS::set(&vec![(SucceedAfter, steps)]);
174 }
175}