Skip to content

Commit

Permalink
feat: Upon test failure, output revert code with human-readable label…
Browse files Browse the repository at this point in the history
… and associated logs (FuelLabs#3999)

## Description

closes FuelLabs#3952.

This PR adds:

1. Revert code for failing tests
2. Known error signals for failing tests
3. Logs for failing tests


## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
  • Loading branch information
kayagokalp authored Feb 17, 2023
1 parent 7f95449 commit 812608c
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 14 deletions.
12 changes: 7 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions forc-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ description = "A library for building and running Sway unit tests within Forc pa
[dependencies]
anyhow = "1"
forc-pkg = { version = "0.35.1", path = "../forc-pkg" }
fuel-abi-types = "0.2"
fuel-tx = { workspace = true, features = ["builder"] }
fuel-vm = { workspace = true, features = ["random"] }
rand = "0.8"
Expand Down
25 changes: 23 additions & 2 deletions forc-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use std::collections::HashSet;
use std::{collections::HashMap, fs, path::PathBuf, sync::Arc};
use std::{
collections::{HashMap, HashSet},
fs,
path::PathBuf,
sync::Arc,
};

use forc_pkg as pkg;
use fuel_abi_types::error_codes::ErrorSignal;
use fuel_tx as tx;
use fuel_vm::checked_transaction::builder::TransactionBuilderExt;
use fuel_vm::gas::GasCosts;
Expand Down Expand Up @@ -284,6 +289,22 @@ impl TestResult {
}
}

/// Return the revert code for this `TestResult` if the test is reverted.
pub fn revert_code(&self) -> Option<u64> {
match self.state {
vm::state::ProgramState::Revert(revert_code) => Some(revert_code),
_ => None,
}
}

/// Return a `ErrorSignal` for this `TestResult` if the test is failed to pass.
pub fn error_signal(&self) -> anyhow::Result<ErrorSignal> {
let revert_code = self.revert_code().ok_or_else(|| {
anyhow::anyhow!("there is no revert code to convert to `ErrorSignal`")
})?;
ErrorSignal::try_from_revert_code(revert_code).map_err(|e| anyhow::anyhow!(e))
}

/// Return `TestDetails` from the span of the function declaring this test.
pub fn details(&self) -> anyhow::Result<TestDetails> {
let file_path = self
Expand Down
28 changes: 21 additions & 7 deletions forc/src/cli/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub(crate) fn exec(cmd: Command) -> Result<()> {
fn print_tested_pkg(pkg: &TestedPackage, test_print_opts: &TestPrintOpts) -> Result<()> {
let succeeded = pkg.tests.iter().filter(|t| t.passed()).count();
let failed = pkg.tests.len() - succeeded;
let mut failed_test_details = Vec::new();
let mut failed_tests = Vec::new();
for test in &pkg.tests {
let test_passed = test.passed();
let (state, color) = match test_passed {
Expand All @@ -98,10 +98,9 @@ fn print_tested_pkg(pkg: &TestedPackage, test_print_opts: &TestPrintOpts) -> Res
info!("{}", formatted_logs);
}

// If the test is failing, save details.
// If the test is failing, save the test result for printing the details later on.
if !test_passed {
let details = test.details()?;
failed_test_details.push((test.name.clone(), details));
failed_tests.push(test);
}
}
let (state, color) = match succeeded == pkg.tests.len() {
Expand All @@ -110,13 +109,28 @@ fn print_tested_pkg(pkg: &TestedPackage, test_print_opts: &TestPrintOpts) -> Res
};
if failed != 0 {
info!("\n failures:");
for (failed_test_name, failed_test_detail) in failed_test_details {
let path = &*failed_test_detail.file_path;
let line_number = failed_test_detail.line_number;
for failed_test in failed_tests {
let failed_test_name = &failed_test.name;
let failed_test_details = failed_test.details()?;
let path = &*failed_test_details.file_path;
let line_number = failed_test_details.line_number;
let logs = &failed_test.logs;
let formatted_logs = format_log_receipts(logs, test_print_opts.pretty_print)?;
info!(
" - test {}, {:?}:{} ",
failed_test_name, path, line_number
);
if let Some(revert_code) = failed_test.revert_code() {
// If we have a revert_code, try to get a known error signal
let mut failed_info_str = format!(" revert code: {revert_code:x}");
let error_signal = failed_test.error_signal().ok();
if let Some(error_signal) = error_signal {
let error_signal_str = error_signal.to_string();
failed_info_str.push_str(&format!(" -- {error_signal_str}"));
}
info!("{failed_info_str}");
}
info!(" Logs: {}", formatted_logs);
}
info!("\n");
}
Expand Down

0 comments on commit 812608c

Please sign in to comment.