Skip to content

Commit 0bf4db6

Browse files
authored
Improve execution time of should_pass E2E tests (#5757)
## Description This PR improves the execution time of `should_pass` E2E tests by making ~33% of them use a stripped-down version of the `std` library. This approach brings noticable speed gains as demonstrated in the below comparison table. (The tests are executed on my local machine in Rust `release` and Sway `debug` build. Running them in Sway `release` build brings additional but small gain.) | Test filter | Before (mm:ss) | After (mm:ss) | | ------------- | ------------- |------------- | | should_pass/language/ | 14:26 | 04:23 | | should_pass/language/references | 04:10 | 00:56 | | should_pass/language/main_args | 01:10 | 00:12 | | should_pass/language/match | 00:57 | 00:09 | | should_pass.*enum | 00:51 | 00:28 | The improvement approach is based on the following observations: - most of the time in `should_pass` tests is spent on compiling `std`. - out of ~480 `should_pass` tests, ~160 use `std` just because of `assert`. - in addition, ~10 tests need `Option` and/or `Result`. Thus, the PR provides two stripped-down versions of the `std`, one containing only support for `assert`, and another one containing `assert` and `Option` and `Result`. The compilation time of those two libraries is negligible compared to the compilation time of the whole `std`. This apporach is: - easy to use and enforce in new tests - compatible with whichever solution for running tests in parallel we come up with - trivial to remove once we implement incremental compilation or caching of `std` in tests Therefore, proposal is to use this approach for the time being to improve the efficiency of our inner loop. ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] 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.
1 parent f063a78 commit 0bf4db6

File tree

182 files changed

+1282
-198
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+1282
-198
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[[package]]
2+
name = "core"
3+
source = "path+from-root-5863B5D56901589E"
4+
5+
[[package]]
6+
name = "std"
7+
source = "member"
8+
dependencies = ["core"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[project]
2+
authors = ["Fuel Labs <contact@fuel.sh>"]
3+
entry = "lib.sw"
4+
license = "Apache-2.0"
5+
name = "std"
6+
7+
[dependencies]
8+
core = { path = "../../../../../sway-lib-core" }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Reduced Sway Standard Library
2+
3+
This is a reduced version of the Sway Standard Library meant to be used in tests that need only the following `std` functionality:
4+
- asserts
5+
- logging
6+
- revert
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//! Functions to assert a given condition.
2+
library;
3+
4+
use ::logging::log;
5+
use ::revert::revert;
6+
use ::error_signals::{FAILED_ASSERT_EQ_SIGNAL, FAILED_ASSERT_NE_SIGNAL, FAILED_ASSERT_SIGNAL};
7+
8+
/// Asserts that the given `condition` will always be `true` during runtime.
9+
///
10+
/// # Additional Information
11+
///
12+
/// To check for conditions that may not be `true`, use `std::revert::require` instead.
13+
/// For more information, see the Wiki article on [Assertion](https://en.wikipedia.org/wiki/Assertion_(software_development)#Comparison_with_error_handling).
14+
///
15+
/// # Arguments
16+
///
17+
/// * `condition`: [bool] - The condition which will be asserted to be `true`.
18+
///
19+
/// # Reverts
20+
///
21+
/// * Reverts when `condition` is `false`.
22+
///
23+
/// # Examples
24+
///
25+
/// ```sway
26+
/// fn foo(a: u64, b: u64) {
27+
/// assert(a == b);
28+
/// // if code execution continues, that means a was equal to b
29+
/// log("a is equal to b");
30+
/// }
31+
/// ```
32+
pub fn assert(condition: bool) {
33+
if !condition {
34+
revert(FAILED_ASSERT_SIGNAL);
35+
}
36+
}
37+
38+
/// Asserts that the given values `v1` & `v2` will always be equal during runtime.
39+
///
40+
/// # Arguments
41+
///
42+
/// * `v1`: [T] - The first value to compare.
43+
/// * `v2`: [T] - The second value to compare.
44+
///
45+
/// # Reverts
46+
///
47+
/// * Reverts when `v1` != `v2`.
48+
///
49+
/// # Examples
50+
///
51+
/// ```sway
52+
/// fn foo(a: u64, b: u64) {
53+
/// assert_eq(a, b);
54+
/// // if code execution continues, that means `a` is equal to `b`
55+
/// log("a is equal to b");
56+
/// }
57+
/// ```
58+
#[cfg(experimental_new_encoding = false)]
59+
pub fn assert_eq<T>(v1: T, v2: T)
60+
where
61+
T: Eq,
62+
{
63+
if (v1 != v2) {
64+
log(v1);
65+
log(v2);
66+
revert(FAILED_ASSERT_EQ_SIGNAL);
67+
}
68+
}
69+
70+
#[cfg(experimental_new_encoding = true)]
71+
pub fn assert_eq<T>(v1: T, v2: T)
72+
where
73+
T: Eq + AbiEncode,
74+
{
75+
if (v1 != v2) {
76+
log(v1);
77+
log(v2);
78+
revert(FAILED_ASSERT_EQ_SIGNAL);
79+
}
80+
}
81+
82+
/// Asserts that the given values `v1` & `v2` will never be equal during runtime.
83+
///
84+
/// # Arguments
85+
///
86+
/// * `v1`: [T] - The first value to compare.
87+
/// * `v2`: [T] - The second value to compare.
88+
///
89+
/// # Reverts
90+
///
91+
/// * Reverts when `v1` == `v2`.
92+
///
93+
/// # Examples
94+
///
95+
/// ```sway
96+
/// fn foo(a: u64, b: u64) {
97+
/// assert_ne(a, b);
98+
/// // if code execution continues, that means `a` is not equal to `b`
99+
/// log("a is not equal to b");
100+
/// }
101+
/// ```
102+
#[cfg(experimental_new_encoding = false)]
103+
pub fn assert_ne<T>(v1: T, v2: T)
104+
where
105+
T: Eq,
106+
{
107+
if (v1 == v2) {
108+
log(v1);
109+
log(v2);
110+
revert(FAILED_ASSERT_NE_SIGNAL);
111+
}
112+
}
113+
114+
#[cfg(experimental_new_encoding = true)]
115+
pub fn assert_ne<T>(v1: T, v2: T)
116+
where
117+
T: Eq + AbiEncode,
118+
{
119+
if (v1 == v2) {
120+
log(v1);
121+
log(v2);
122+
revert(FAILED_ASSERT_NE_SIGNAL);
123+
}
124+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//! Values which signify special types of errors when passed to `std::revert::revert`.
2+
library;
3+
4+
/// A revert with this value signals that it was caused by a failing call to `std::revert::require`.
5+
///
6+
/// # Additional Information
7+
///
8+
/// The value is: 18446744073709486080
9+
pub const FAILED_REQUIRE_SIGNAL = 0xffff_ffff_ffff_0000;
10+
11+
/// A revert with this value signals that it was caused by a failing call to `std::asset::transfer_to_address`.
12+
///
13+
/// # Additional Information
14+
///
15+
/// The value is: 18446744073709486081
16+
pub const FAILED_TRANSFER_TO_ADDRESS_SIGNAL = 0xffff_ffff_ffff_0001;
17+
18+
/// A revert with this value signals that it was caused by a failing call to `std::assert::assert_eq`.
19+
///
20+
/// # Additional Information
21+
///
22+
/// The value is: 18446744073709486083
23+
pub const FAILED_ASSERT_EQ_SIGNAL = 0xffff_ffff_ffff_0003;
24+
25+
/// A revert with this value signals that it was caused by a failing call to `std::assert::assert`.
26+
///
27+
/// # Additional Information
28+
///
29+
/// The value is: 18446744073709486084
30+
pub const FAILED_ASSERT_SIGNAL = 0xffff_ffff_ffff_0004;
31+
32+
/// A revert with this value signals that it was caused by a failing call to `std::assert::assert_ne`.
33+
///
34+
/// # Additional Information
35+
///
36+
/// The value is: 18446744073709486085
37+
pub const FAILED_ASSERT_NE_SIGNAL = 0xffff_ffff_ffff_0005;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
library;
2+
3+
pub mod error_signals;
4+
pub mod logging;
5+
pub mod revert;
6+
pub mod assert;
7+
pub mod prelude;
8+
9+
use core::*;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//! Allows logging of arbitrary stack types, emitted as either `Log` or `Logd` receipts.
2+
library;
3+
4+
/// Log any stack type.
5+
///
6+
/// # Additional Information
7+
///
8+
/// If the type is a reference type, `log` is used.
9+
/// Otherwise `logd` is used.'
10+
///
11+
/// # Arguments
12+
///
13+
/// * `value`: [T] - The value to log.
14+
///
15+
/// # Examples
16+
///
17+
/// ```sway
18+
/// fn foo() {
19+
/// log("Fuel is blazingly fast");
20+
/// }
21+
/// ```
22+
#[cfg(experimental_new_encoding = false)]
23+
pub fn log<T>(value: T) {
24+
__log::<T>(value);
25+
}
26+
27+
#[cfg(experimental_new_encoding = true)]
28+
pub fn log<T>(value: T)
29+
where
30+
T: AbiEncode,
31+
{
32+
__log::<T>(value);
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//! Defines the Sway standard library prelude.
2+
//! The prelude consists of implicitly available items,
3+
//! for which `use` is not required.
4+
library;
5+
6+
// Error handling
7+
use ::assert::{assert, assert_eq, assert_ne};
8+
use ::revert::{require, revert};
9+
10+
// Logging
11+
use ::logging::log;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//! Functions to panic or revert with a given error code.
2+
library;
3+
4+
use ::logging::log;
5+
use ::error_signals::FAILED_REQUIRE_SIGNAL;
6+
7+
/// Will either panic or revert with a given number depending on the context.
8+
///
9+
/// # Additional Information
10+
///
11+
/// If used in a predicate, it will panic.
12+
/// If used in a contract, it will revert.
13+
///
14+
/// # Arguments
15+
///
16+
/// * `code`: [u64] - The code with which to revert the program.
17+
///
18+
/// # Reverts
19+
///
20+
/// * Reverts unconditionally.
21+
///
22+
/// # Examples
23+
///
24+
/// ```sway
25+
/// fn foo(should_revert: bool) {
26+
/// match should_revert {
27+
/// true => revert(0),
28+
/// false => {},
29+
/// }
30+
/// }
31+
/// ```
32+
pub fn revert(code: u64) -> ! {
33+
__revert(code)
34+
}
35+
36+
/// Checks if the given `condition` is `true` and if not, logs `value` and reverts.
37+
///
38+
/// # Arguments
39+
///
40+
/// * `condition`: [bool] - The condition upon which to decide whether to revert or not.
41+
/// * `value`: [T] - The value which will be logged in case `condition` is `false`.
42+
///
43+
/// # Reverts
44+
///
45+
/// * Reverts when `condition` is `false`.
46+
///
47+
/// # Examples
48+
///
49+
/// ```sway
50+
/// fn foo(a: u64, b: u64) {
51+
/// require(a == b, "a was not equal to b");
52+
/// // If the condition was true, code execution will continue
53+
/// log("The require function did not revert");
54+
/// }
55+
/// ```
56+
#[cfg(experimental_new_encoding = false)]
57+
pub fn require<T>(condition: bool, value: T) {
58+
if !condition {
59+
log(value);
60+
revert(FAILED_REQUIRE_SIGNAL)
61+
}
62+
}
63+
64+
#[cfg(experimental_new_encoding = true)]
65+
pub fn require<T>(condition: bool, value: T)
66+
where
67+
T: AbiEncode,
68+
{
69+
if !condition {
70+
log(value);
71+
revert(FAILED_REQUIRE_SIGNAL)
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[[package]]
2+
name = "core"
3+
source = "path+from-root-5863B5D56901589E"
4+
5+
[[package]]
6+
name = "std"
7+
source = "member"
8+
dependencies = ["core"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[project]
2+
authors = ["Fuel Labs <contact@fuel.sh>"]
3+
entry = "lib.sw"
4+
license = "Apache-2.0"
5+
name = "std"
6+
7+
[dependencies]
8+
core = { path = "../../../../../sway-lib-core" }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Reduced Sway Standard Library
2+
3+
This is a reduced version of the Sway Standard Library meant to be used in tests that need only the following `std` functionality:
4+
- asserts
5+
- logging
6+
- revert
7+
- `Option` type
8+
- `Result` type

0 commit comments

Comments
 (0)