pop_chains/try_runtime/
mod.rs1use crate::{Error, errors::handle_command_error};
2use duct::cmd;
3pub use frame_try_runtime::{TryStateSelect, UpgradeCheckSelect};
4use std::{fmt::Display, path::PathBuf, str::from_utf8};
5
6pub mod binary;
8pub mod parse;
10pub mod shared_parameters;
12pub mod state;
14
15pub enum TryRuntimeCliCommand {
17 OnRuntimeUpgrade,
19 ExecuteBlock,
21 CreateSnapshot,
23 FastForward,
25}
26
27impl Display for TryRuntimeCliCommand {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 let s = match self {
30 TryRuntimeCliCommand::OnRuntimeUpgrade => "on-runtime-upgrade",
31 TryRuntimeCliCommand::ExecuteBlock => "execute-block",
32 TryRuntimeCliCommand::CreateSnapshot => "create-snapshot",
33 TryRuntimeCliCommand::FastForward => "fast-forward",
34 };
35 write!(f, "{}", s)
36 }
37}
38
39pub fn upgrade_checks_details(upgrade_check_select: &UpgradeCheckSelect) -> (String, String) {
44 match upgrade_check_select {
45 UpgradeCheckSelect::None => ("none".to_string(), "Run no checks".to_string()),
46 UpgradeCheckSelect::All => (
47 "all".to_string(),
48 "Run the `try_state`, `pre_upgrade` and `post_upgrade` checks".to_string(),
49 ),
50 UpgradeCheckSelect::TryState =>
51 ("try-state".to_string(), "Run the `try_state` checks".to_string()),
52 UpgradeCheckSelect::PreAndPost => (
53 "pre-and-post".to_string(),
54 "Run the `pre_upgrade` and `post_upgrade` checks".to_string(),
55 ),
56 }
57}
58
59pub fn try_state_label(try_state_select: &TryStateSelect) -> String {
64 match try_state_select {
65 TryStateSelect::None => "None".to_string(),
66 TryStateSelect::All => "All".to_string(),
67 TryStateSelect::RoundRobin(..) => "Round Robin".to_string(),
68 TryStateSelect::Only(..) => "Only Pallets".to_string(),
69 }
70}
71
72pub fn try_state_details(try_state_select: &TryStateSelect) -> (String, String) {
77 (
78 try_state_label(try_state_select),
79 match try_state_select {
80 TryStateSelect::None => "Run no tests".to_string(),
81 TryStateSelect::All => "Run all the state tests".to_string(),
82 TryStateSelect::RoundRobin(..) =>
83 "Run a fixed number of state tests in a round robin manner.".to_string(),
84 TryStateSelect::Only(..) =>
85 "Run only pallets who's name matches the given list.".to_string(),
86 },
87 )
88}
89
90pub fn parse_try_state_string(try_state: &TryStateSelect) -> Result<String, Error> {
95 Ok(match try_state {
96 TryStateSelect::All => "all".to_string(),
97 TryStateSelect::None => "none".to_string(),
98 TryStateSelect::RoundRobin(rounds) => format!("rr-{}", rounds),
99 TryStateSelect::Only(pallets) => {
100 let mut result = vec![];
101 for pallet in pallets.iter() {
102 result.push(from_utf8(pallet).map_err(|_| {
103 Error::ParamParsingError("Invalid pallet string in `try_state`".to_string())
104 })?);
105 }
106 result.join(",")
107 },
108 })
109}
110
111pub fn run_try_runtime(
120 binary_path: &PathBuf,
121 command: TryRuntimeCliCommand,
122 shared_params: Vec<String>,
123 args: Vec<String>,
124 excluded_args: &[&str],
125) -> Result<(), Error> {
126 let mut cmd_args = shared_params
127 .into_iter()
128 .filter(|arg| !excluded_args.iter().any(|a| arg.starts_with(a)))
129 .collect::<Vec<String>>();
130 cmd_args.extend(vec![command.to_string()]);
131 cmd_args.extend(
132 args.into_iter()
133 .filter(|arg| !excluded_args.iter().any(|a| arg.starts_with(a)))
134 .collect::<Vec<String>>(),
135 );
136 let output = cmd(binary_path, cmd_args)
137 .env("RUST_LOG", "info")
138 .stderr_capture()
139 .unchecked()
140 .run()?;
141 handle_command_error(&output, Error::TryRuntimeError)?;
143 if output.status.success() {
144 eprintln!("{}", String::from_utf8_lossy(&output.stderr));
145 }
146 Ok(())
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn parse_try_state_string_works() {
155 assert_eq!(parse_try_state_string(&TryStateSelect::All).unwrap(), "all");
156 assert_eq!(parse_try_state_string(&TryStateSelect::None).unwrap(), "none");
157 assert_eq!(parse_try_state_string(&TryStateSelect::RoundRobin(5)).unwrap(), "rr-5");
158 assert_eq!(
159 parse_try_state_string(&TryStateSelect::Only(vec![
160 b"System".to_vec(),
161 b"Proxy".to_vec()
162 ]))
163 .unwrap(),
164 "System,Proxy"
165 );
166 }
167
168 #[test]
169 fn try_state_label_works() {
170 for (select, label) in [
171 (TryStateSelect::All, "All"),
172 (TryStateSelect::None, "None"),
173 (TryStateSelect::RoundRobin(5), "Round Robin"),
174 (TryStateSelect::Only(vec![]), "Only Pallets"),
175 ] {
176 assert_eq!(try_state_label(&select), label);
177 }
178 }
179
180 #[test]
181 fn try_state_details_works() {
182 for (select, description) in [
183 (TryStateSelect::None, "Run no tests"),
184 (TryStateSelect::All, "Run all the state tests"),
185 (
186 TryStateSelect::RoundRobin(0),
187 "Run a fixed number of state tests in a round robin manner.",
188 ),
189 (TryStateSelect::Only(vec![]), "Run only pallets who's name matches the given list."),
190 ] {
191 assert_eq!(
192 try_state_details(&select),
193 (try_state_label(&select), description.to_string())
194 );
195 }
196 }
197}