Skip to content

Commit e83324a

Browse files
authored
Merge pull request #1920 from mintlayer/trezor_tests_auto_confirmer
Auto-confirm dialogs during trezor_signer tests
2 parents 9c86f2e + 34879be commit e83324a

18 files changed

Lines changed: 925 additions & 415 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ serde = "1.0"
215215
serde_json = "1.0"
216216
serde_test = "1.0"
217217
serde_with = "3.6"
218-
serial_test = "3.0"
218+
serial_test = "3.2"
219219
sha-1 = "0.10"
220220
sha2 = "0.10"
221221
sha3 = "0.10"

logging/src/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
use std::{borrow::Cow, ffi::OsString};
1717

18-
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
18+
#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)]
1919
pub enum GetFromEnvError {
2020
#[error("Env var {var_name}'s contents are not valid unicode: {data:?}")]
2121
NotUnicode { var_name: String, data: OsString },

test-utils/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ randomness = { path = "../randomness" }
1515
serialization = { path = "../serialization" }
1616
utils = { path = "../utils" }
1717

18+
ctor.workspace = true
1819
hex.workspace = true
1920
itertools.workspace = true
2021
rand_chacha.workspace = true

test-utils/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod mock_time_getter;
1818
pub mod nft_utils;
1919
pub mod random;
2020
pub mod test_dir;
21+
pub mod threading;
2122

2223
use std::collections::BTreeMap;
2324

test-utils/src/threading.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) 2021-2025 RBB S.r.l
2+
// opensource@mintlayer.org
3+
// SPDX-License-Identifier: MIT
4+
// Licensed under the MIT License;
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://github.com/mintlayer/mintlayer-core/blob/master/LICENSE
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
use std::{
17+
backtrace::{Backtrace, BacktraceStatus},
18+
cell::Cell,
19+
thread::{self, JoinHandle},
20+
};
21+
22+
use logging::log;
23+
24+
/// Spawn a new thread; if the thread panics, abort the process immediately.
25+
pub fn spawn_thread_aborting_on_panic<F, R>(func: F) -> JoinHandle<R>
26+
where
27+
F: FnOnce() -> R + Send + std::panic::UnwindSafe + 'static,
28+
R: Send + 'static,
29+
{
30+
thread::spawn(move || {
31+
match std::panic::catch_unwind(func) {
32+
Ok(result) => result,
33+
Err(err) => {
34+
let backtrace =
35+
THREAD_LOCAL_BACKTRACE.with(|b| b.take()).expect("must be set by panic hook");
36+
37+
// Note: downcasting to `&str` is needed to catch panics like `panic!("foo")`.
38+
// And downcasting to `String` is needed to catch those like `panic!("{}", "foo")`.
39+
let msg = err
40+
.downcast_ref::<&str>()
41+
.copied()
42+
.or_else(|| err.downcast_ref::<String>().map(AsRef::as_ref))
43+
.unwrap_or("???");
44+
let backtrace = match backtrace.status() {
45+
BacktraceStatus::Captured => backtrace.to_string(),
46+
BacktraceStatus::Disabled => {
47+
" ** Backtrace disabled, set the RUST_BACKTRACE env var (e.g. to 'full') **"
48+
.to_owned()
49+
}
50+
BacktraceStatus::Unsupported => " ** Backtrace unsupported **".to_owned(),
51+
_ => " ** Unknown backtrace status **".to_owned(),
52+
};
53+
log::error!(
54+
"The thread panicked with message:\n {msg}\nand backtrace:\n{backtrace}",
55+
);
56+
std::process::abort();
57+
}
58+
}
59+
})
60+
}
61+
62+
// A hack to be able to get the backtrace if the func passed to `spawn_thread_aborting_on_panic` panics.
63+
thread_local! {
64+
static THREAD_LOCAL_BACKTRACE: Cell<Option<Backtrace>> = const { Cell::new(None) };
65+
}
66+
67+
fn setup_panic_handling() {
68+
let old_panic_hook = std::panic::take_hook();
69+
std::panic::set_hook(Box::new(move |panic_info| {
70+
let trace = Backtrace::capture();
71+
THREAD_LOCAL_BACKTRACE.with(move |b| b.set(Some(trace)));
72+
old_panic_hook(panic_info);
73+
}));
74+
}
75+
76+
#[ctor::ctor]
77+
fn init() {
78+
setup_panic_handling();
79+
}

utils/src/env_utils.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright (c) 2021-2025 RBB S.r.l
2+
// opensource@mintlayer.org
3+
// SPDX-License-Identifier: MIT
4+
// Licensed under the MIT License;
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://github.com/mintlayer/mintlayer-core/blob/master/LICENSE
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
pub fn get_from_env(var_name: &str) -> Result<Option<String>, Error> {
17+
Ok(logging::get_from_env(var_name)?)
18+
}
19+
20+
pub fn bool_from_env(var_name: &str) -> Result<Option<bool>, Error> {
21+
let Some(val) = get_from_env(var_name)? else {
22+
return Ok(None);
23+
};
24+
25+
let true_vals = ["1", "yes", "true"];
26+
let false_vals = ["0", "no", "false"];
27+
28+
if true_vals.iter().any(|true_val| val.eq_ignore_ascii_case(true_val)) {
29+
Ok(Some(true))
30+
} else if false_vals.iter().any(|false_val| val.eq_ignore_ascii_case(false_val)) {
31+
Ok(Some(false))
32+
} else {
33+
Err(Error::NonBoolValue {
34+
var_name: var_name.to_owned(),
35+
value: val,
36+
})
37+
}
38+
}
39+
40+
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
41+
pub enum Error {
42+
#[error("Env var {var_name}'s value '{value}' cannot be interpreted as a bool")]
43+
NonBoolValue { var_name: String, value: String },
44+
45+
#[error("Error obtaining env var value: {0}")]
46+
GetFromEnvError(#[from] logging::GetFromEnvError),
47+
}
48+
49+
#[cfg(test)]
50+
mod tests {
51+
use super::*;
52+
53+
#[test]
54+
fn test_bool_from_env() {
55+
let var_name = "TEST_BOOL_FROM_ENV_TEST_VAR_NAME";
56+
57+
let result = bool_from_env(var_name);
58+
assert_eq!(result, Ok(None));
59+
60+
let true_vals = ["1", "yes", "yEs", "true", "TruE"];
61+
let false_vals = ["0", "no", "nO", "false", "fALSE"];
62+
let bad_vals = ["2", "noo", "yess"];
63+
64+
for val in true_vals {
65+
std::env::set_var(var_name, val);
66+
let result = bool_from_env(var_name);
67+
assert_eq!(result, Ok(Some(true)));
68+
}
69+
70+
for val in false_vals {
71+
std::env::set_var(var_name, val);
72+
let result = bool_from_env(var_name);
73+
assert_eq!(result, Ok(Some(false)));
74+
}
75+
76+
for val in bad_vals {
77+
std::env::set_var(var_name, val);
78+
let result = bool_from_env(var_name);
79+
assert_eq!(
80+
result,
81+
Err(Error::NonBoolValue {
82+
var_name: var_name.to_owned(),
83+
value: val.to_owned()
84+
})
85+
);
86+
}
87+
}
88+
}

utils/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub mod debug_panic;
2727
pub mod default_data_dir;
2828
pub mod displayable_option;
2929
pub mod ensure;
30+
pub mod env_utils;
3031
pub mod eventhandler;
3132
pub mod exp_rand;
3233
pub mod graph_traversals;

wallet/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ zeroize.workspace = true
4040
chainstate-test-framework = { path = "../chainstate/test-framework" }
4141
test-utils = { path = "../test-utils" }
4242

43-
serial_test = "3.2"
44-
43+
ctor.workspace = true
4544
rstest.workspace = true
45+
serde_json.workspace = true
46+
serial_test.workspace = true
4647
tempfile.workspace = true
4748

4849
[features]

wallet/src/signer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// limitations under the License.
1515

1616
#[cfg(test)]
17-
mod signer_test_helpers;
17+
mod tests;
1818

1919
use std::sync::Arc;
2020

0 commit comments

Comments
 (0)