Skip to content

Commit 1a4a47a

Browse files
committed
If #[itest(focus)] is encountered, fail memcheck CI jobs
Prevents accidental disabling of tests in CI (during development).
1 parent 895bc4e commit 1a4a47a

File tree

6 files changed

+63
-24
lines changed

6 files changed

+63
-24
lines changed

.github/composite/godot-install/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ inputs:
1010
required: true
1111
description: "Name of the compiled Godot artifact to download"
1212

13-
binary-filename:
13+
godot-binary:
1414
required: true
1515
description: "Filename of the Godot executable"
1616

@@ -25,7 +25,7 @@ runs:
2525
run: |
2626
runnerDir=$(echo "${{ runner.temp }}" | sed "s!\\\\!/!")
2727
echo "RUNNER_DIR=$runnerDir" >> $GITHUB_ENV
28-
echo "GODOT4_BIN=$runnerDir/godot_bin/${{ inputs.binary-filename }}" >> $GITHUB_ENV
28+
echo "GODOT4_BIN=$runnerDir/godot_bin/${{ inputs.godot-binary }}" >> $GITHUB_ENV
2929
shell: bash
3030

3131
# - name: "Check cache for installed Godot version"

.github/composite/godot-itest/action.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ inputs:
1010
required: true
1111
description: "Name of the compiled Godot artifact to download"
1212

13-
binary-filename:
13+
godot-binary:
1414
required: true
1515
description: "Filename of the Godot executable"
1616

17+
godot-args:
18+
required: false
19+
default: ''
20+
description: "Command-line arguments passed to Godot"
21+
1722
rust-toolchain:
1823
required: false
1924
default: 'stable'
@@ -26,8 +31,8 @@ inputs:
2631

2732
with-llvm:
2833
required: false
29-
description: "Set to 'true' if LLVM should be installed"
3034
default: ''
35+
description: "Set to 'true' if LLVM should be installed"
3136

3237

3338
runs:
@@ -39,7 +44,7 @@ runs:
3944
uses: ./.github/composite/godot-install
4045
with:
4146
artifact-name: ${{ inputs.artifact-name }}
42-
binary-filename: ${{ inputs.binary-filename }}
47+
godot-binary: ${{ inputs.godot-binary }}
4348

4449
# The chmod seems still necessary, although applied before uploading artifact. Possibly modes are not preserved.
4550
# The `| xargs` pattern trims the output, since printed version may contain extra newline, which causes problems in env vars.
@@ -94,7 +99,7 @@ runs:
9499
run: |
95100
cd itest/godot
96101
echo "OUTCOME=itest" >> $GITHUB_ENV
97-
$GODOT4_BIN --headless 2>&1 | tee "${{ runner.temp }}/log.txt" | tee >(grep "SCRIPT ERROR:" -q && {
102+
$GODOT4_BIN --headless ${{ inputs.godot-args }} 2>&1 | tee "${{ runner.temp }}/log.txt" | tee >(grep "SCRIPT ERROR:" -q && {
98103
printf "\n -- Godot engine encountered error, abort...\n";
99104
pkill godot
100105
echo "OUTCOME=godot-runtime" >> $GITHUB_ENV

.github/workflows/full-ci.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
uses: ./.github/composite/godot-install
5858
with:
5959
artifact-name: godot-linux
60-
binary-filename: godot.linuxbsd.editor.dev.x86_64
60+
godot-binary: godot.linuxbsd.editor.dev.x86_64
6161

6262
- name: "Check clippy"
6363
run: |
@@ -126,7 +126,7 @@ jobs:
126126
uses: ./.github/composite/godot-install
127127
with:
128128
artifact-name: godot-${{ matrix.name }}
129-
binary-filename: ${{ matrix.godot-binary }}
129+
godot-binary: ${{ matrix.godot-binary }}
130130

131131
- name: "Compile tests"
132132
run: cargo test $GDEXT_FEATURES --no-run
@@ -168,15 +168,19 @@ jobs:
168168
# Additionally, the Godot source is patched to make dlclose() a no-op, as unloading dynamic libraries loses stacktrace and
169169
# cause false positives like println!. See https://github.com/google/sanitizers/issues/89.
170170
# The gcc version can possibly be removed later, as it is slower and needs a larger artifact than the clang one.
171+
172+
# --disallow-focus: fail if #[itest(focus)] is encountered, to prevent running only a few tests for full CI
171173
- name: linux-memcheck-gcc
172174
os: ubuntu-20.04
173175
rust-toolchain: stable
174176
godot-binary: godot.linuxbsd.editor.dev.x86_64.san
177+
godot-args: -- --disallow-focus
175178

176179
- name: linux-memcheck-clang
177180
os: ubuntu-20.04
178181
rust-toolchain: stable
179182
godot-binary: godot.linuxbsd.editor.dev.x86_64.llvm.san
183+
godot-args: -- --disallow-focus
180184

181185
steps:
182186
- uses: actions/checkout@v3
@@ -185,7 +189,8 @@ jobs:
185189
uses: ./.github/composite/godot-itest
186190
with:
187191
artifact-name: godot-${{ matrix.name }}
188-
binary-filename: ${{ matrix.godot-binary }}
192+
godot-binary: ${{ matrix.godot-binary }}
193+
godot-args: ${{ matrix.godot-args }}
189194
with-llvm: ${{ matrix.name == 'macos' }}
190195

191196

.github/workflows/minimal-ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
uses: ./.github/composite/godot-install
5858
with:
5959
artifact-name: godot-linux
60-
binary-filename: godot.linuxbsd.editor.dev.x86_64
60+
godot-binary: godot.linuxbsd.editor.dev.x86_64
6161

6262
- name: "Check clippy"
6363
run: |
@@ -78,7 +78,7 @@ jobs:
7878
uses: ./.github/composite/godot-install
7979
with:
8080
artifact-name: godot-linux
81-
binary-filename: godot.linuxbsd.editor.dev.x86_64
81+
godot-binary: godot.linuxbsd.editor.dev.x86_64
8282

8383
- name: "Compile tests"
8484
run: cargo test $GDEXT_FEATURES --no-run
@@ -98,7 +98,7 @@ jobs:
9898
uses: ./.github/composite/godot-itest
9999
with:
100100
artifact-name: godot-linux
101-
binary-filename: godot.linuxbsd.editor.dev.x86_64
101+
godot-binary: godot.linuxbsd.editor.dev.x86_64
102102
#godot_ver: ${{ matrix.godot }}
103103

104104

itest/godot/TestRunner.gd

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
extends Node
66

77
func _ready():
8+
var allow_focus := true
9+
var unrecognized_args: Array = []
10+
for arg in OS.get_cmdline_user_args():
11+
match arg:
12+
"--disallow-focus":
13+
allow_focus = false
14+
_:
15+
unrecognized_args.push_back(arg)
16+
17+
if unrecognized_args:
18+
push_error("Unrecognized arguments: ", unrecognized_args)
19+
get_tree().quit(2)
20+
return
21+
822
var rust_runner = IntegrationTests.new()
923

1024
var gdscript_suites: Array = [
@@ -19,7 +33,7 @@ func _ready():
1933
if method_name.begins_with("test_"):
2034
gdscript_tests.push_back(GDScriptTestCase.new(suite, method_name))
2135

22-
var success: bool = rust_runner.run_all_tests(gdscript_tests, gdscript_suites.size())
36+
var success: bool = rust_runner.run_all_tests(gdscript_tests, gdscript_suites.size(), allow_focus)
2337

2438
var exit_code: int = 0 if success else 1
2539
get_tree().quit(exit_code)

itest/rust/src/runner.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ pub(crate) struct IntegrationTests {
2323
impl IntegrationTests {
2424
#[allow(clippy::uninlined_format_args)]
2525
#[func]
26-
fn run_all_tests(&mut self, gdscript_tests: Array, gdscript_file_count: i64) -> bool {
27-
println!(
28-
"{}Run{} Godot integration tests...",
29-
FMT_GREEN_BOLD, FMT_END
30-
);
26+
fn run_all_tests(
27+
&mut self,
28+
gdscript_tests: Array,
29+
gdscript_file_count: i64,
30+
allow_focus: bool,
31+
) -> bool {
32+
println!("{}Run{} Godot integration tests...", FMT_CYAN_BOLD, FMT_END);
3133

3234
let (rust_tests, rust_file_count, focus_run) = super::collect_rust_tests();
3335
self.focus_run = focus_run;
3436
if focus_run {
35-
println!(" Focused run -- execute only selected Rust tests.")
37+
println!(" {FMT_CYAN}Focused run{FMT_END} -- execute only selected Rust tests.")
3638
}
3739
println!(
3840
" Rust: found {} tests in {} files.",
@@ -57,7 +59,7 @@ impl IntegrationTests {
5759
None
5860
};
5961

60-
self.conclude(rust_time, gdscript_time)
62+
self.conclude(rust_time, gdscript_time, allow_focus)
6163
}
6264

6365
fn run_rust_tests(&mut self, tests: Vec<RustTestCase>) {
@@ -87,7 +89,12 @@ impl IntegrationTests {
8789
}
8890
}
8991

90-
fn conclude(&self, rust_time: Duration, gdscript_time: Option<Duration>) -> bool {
92+
fn conclude(
93+
&self,
94+
rust_time: Duration,
95+
gdscript_time: Option<Duration>,
96+
allow_focus: bool,
97+
) -> bool {
9198
let Self {
9299
total,
93100
passed,
@@ -103,10 +110,11 @@ impl IntegrationTests {
103110

104111
let rust_time = rust_time.as_secs_f32();
105112
let gdscript_time = gdscript_time.map(|t| t.as_secs_f32());
113+
let focused_run = gdscript_time.is_none();
106114

107115
let extra = if skipped > 0 {
108116
format!(", {skipped} skipped")
109-
} else if gdscript_time.is_none() {
117+
} else if focused_run {
110118
" (focused run)".to_string()
111119
} else {
112120
"".to_string()
@@ -121,7 +129,13 @@ impl IntegrationTests {
121129
} else {
122130
println!(" Time: {rust_time:.2}s.");
123131
}
124-
all_passed
132+
133+
if focused_run && !allow_focus {
134+
println!(" {FMT_YELLOW}Focus run disallowed; return failure.{FMT_END}");
135+
false
136+
} else {
137+
all_passed
138+
}
125139
}
126140

127141
fn update_stats(&mut self, outcome: &TestOutcome) {
@@ -139,7 +153,8 @@ impl IntegrationTests {
139153
// use rand::seq::SliceRandom;
140154
// let outcome = [TestOutcome::Passed, TestOutcome::Failed, TestOutcome::Skipped];
141155
// let outcome = outcome.choose(&mut rand::thread_rng()).unwrap();
142-
const FMT_GREEN_BOLD: &str = "\x1b[32;1;1m";
156+
const FMT_CYAN_BOLD: &str = "\x1b[36;1;1m";
157+
const FMT_CYAN: &str = "\x1b[36m";
143158
const FMT_GREEN: &str = "\x1b[32m";
144159
const FMT_YELLOW: &str = "\x1b[33m";
145160
const FMT_RED: &str = "\x1b[31m";

0 commit comments

Comments
 (0)