Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment: Reporting test failures as annotations #10821

Draft
wants to merge 12 commits into
base: develop
Choose a base branch
from
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"rust-analyzer.linkedProjects": [
"./app/gui2/rust-ffi/Cargo.toml"
"./app/rust-ffi/Cargo.toml"
],
"vue.complete.casing.status": false,
"vue.complete.casing.props": "camel",
Expand Down
1 change: 1 addition & 0 deletions build/build/src/engine/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ impl RunContext {
ide_ci::programs::graalpy::GraalPy.require_present().await?;

prepare_simple_library_server.await??;

Ok(())
}

Expand Down
6 changes: 4 additions & 2 deletions build/build/src/enso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ impl BuiltEnso {

let futures = std_tests.into_iter().map(|test_path| {
let command = self.run_test(test_path, ir_caches);
async move { command?.run_ok().await }
async move { command?.run_ok_preserve_stdout().await }
});

// We need to join all the test tasks here, as they require postgres and httpbin alive.
Expand All @@ -223,7 +223,9 @@ impl BuiltEnso {
if errors.is_empty() {
Ok(())
} else {
error!("{} test suit(s) failed.", errors.len());
let summary = errors.as_slice().iter().map(|e| e.to_string()).collect::<Vec<_>>().join(", ");
println!("::error title=Failed Standard Library Tests::{} test suite(s) failed: {}", errors.len(), summary);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a line starting with :: - that must be a GitHub Actions command line! Where is the syntax documented?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am glad we ended up doing the same - e.g. using println! to print the command line without a prefix. Just like at my PR.

error!("{} test suite(s) failed.", errors.len());
for error in &errors {
error!("{}", error);
}
Expand Down
45 changes: 45 additions & 0 deletions build/ci_utils/src/program/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,51 @@ impl Command {
.boxed()
}

// FIXME DRY!
pub fn spawn_intercepting_stderr(&mut self) -> Result<Child> {
self.stdout(Stdio::inherit());
self.stderr(Stdio::piped());

let program = self.pretty_name.clone().unwrap_or_else(|| {
let program = self.inner.as_std().get_program();
let program = Path::new(program).file_stem().unwrap_or_default().to_os_string();
program.to_string_lossy().to_string()
});

let mut child = self.spawn()?;

// FIXME unwraps
//spawn_log_processor("".into(), child.stdout.take().unwrap());
spawn_log_processor(format!("{program} ⚠️"), child.stderr.take().unwrap());
Ok(child)
}

// FIXME DRY!
pub fn run_ok_preserve_stdout(&mut self) -> BoxFuture<'static, Result<()>> {
let pretty = self.describe();
let span = info_span!(
"Running process.",
status = field::Empty,
pid = field::Empty,
command = field::Empty,
)
.entered();
let child = self.spawn_intercepting_stderr();
let status_checker = self.status_checker.clone();
async move {
let mut child = child?;
let status = child
.wait()
.inspect_ok(|exit_status| {
tracing::Span::current().record("status", exit_status.code());
})
.await?;
status_checker(status).context(format!("Command failed: {pretty}"))
}
.instrument(span.exit())
.boxed()
}

pub fn output_ok(&mut self) -> BoxFuture<'static, Result<Output>> {
let pretty = self.describe();
let span = info_span!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -823,9 +823,9 @@ type File
list_immediate_children self = Vector.from_polyglot_array (self.list_immediate_children_array)

## PRIVATE
Return the absolute path of this File
Return the path that this file represents.
to_text : Text
to_text self = self.absolute . path
to_text self = self.path

## PRIVATE
Convert to a display representation of this File.
Expand Down
17 changes: 17 additions & 0 deletions distribution/lib/Standard/Test/0.0.0-dev/src/Test_Reporter.enso
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ print_single_result (test_result : Test_Result) (config : Suite_Config) =
txt = " - " + test_result.spec_name + " " + times_suffix
IO.println (maybe_green_text txt config)
Spec_Result.Failure msg details ->
report_github_error_message test_result.spec_name msg
IO.println ""
txt = " - [FAILED] " + test_result.spec_name + " " + times_suffix
IO.println (maybe_red_text txt config)
Expand All @@ -87,6 +88,22 @@ print_single_result (test_result : Test_Result) (config : Suite_Config) =
IO.println (maybe_grey_text (" - [PENDING] " + test_result.spec_name) config)
IO.println (" Reason: " + reason)

## PRIVATE
Reports an error message to show up as a note in GitHub Actions,
only if running in the GitHub Actions environment.
report_github_error_message (title : Text) (message : Text) =
is_enabled = Environment.get "GITHUB_ACTIONS" == "true"
sanitize_message txt = txt.replace '\n' '%0A'
sanitize_parameter txt = txt . replace '\n' '%0A' . replace ',' '%2C'
if is_enabled then
location_match = Regex.compile "at ((?:[A-Za-z]:)?[^:]+):([0-9]+):" . match message
location_part = if location_match.is_nothing then "" else
repo_root = enso_project.root.parent.parent.absolute.normalize
path = File.new (location_match.get 1)
relative_path = repo_root.relativize path
line = location_match.get 2
",file="+(sanitize_parameter relative_path.path)+",line="+(sanitize_parameter line)+""
IO.println "::error title="+(sanitize_parameter title)+location_part+"::"+(sanitize_message message)

## Prints all the results, optionally writing them to a jUnit XML output.

Expand Down
2 changes: 1 addition & 1 deletion test/Base_Tests/src/Data/Text_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
sentence_words = ['I', 'have', 'a', 'very', 'long', 'block', 'of', 'text', ',', 'here', '.', 'It', 'goes', 'on', 'and', 'on', ',', 'containing', 'things', 'like', 'decimal', 'points', '(', '1.0314e3', ')', 'and', 'other', 'language', 'scripts', 'as', 'well', '건반', '(', 'Korean', ')', '.']

group_builder.specify "should allow naive length computation over grapheme clusters" <|
kshi.length . should_equal 1
kshi.length . should_equal 10015500005345

Check failure on line 74 in test/Base_Tests/src/Data/Text_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (linux, x86_64)

should allow naive length computation over grapheme clusters

1 did not equal 10015500005345 (at /runner/_work/enso/enso/test/Base_Tests/src/Data/Text_Spec.enso:74:13-53).

Check failure on line 74 in test/Base_Tests/src/Data/Text_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (macos, x86_64)

should allow naive length computation over grapheme clusters

1 did not equal 10015500005345 (at /Users/runner/work/enso/enso/test/Base_Tests/src/Data/Text_Spec.enso:74:13-53).
facepalm.length . should_equal 1

group_builder.specify "should be able to tell if Text is normalized" <|
Expand Down
2 changes: 1 addition & 1 deletion test/Base_Tests/src/Data/Vector_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"Can't run Python tests, Python is not installed."

group_builder.specify "text bytes" <|
"Lore".utf_8 . should_equal [76, 111, 114, 101]
"Lore".utf_8 . should_equal []

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (linux, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /runner/_work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (linux, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /runner/_work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (linux, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /runner/_work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (linux, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /runner/_work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (linux, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /runner/_work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (macos, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /Users/runner/work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (macos, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /Users/runner/work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (macos, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /Users/runner/work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (macos, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /Users/runner/work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

Check failure on line 86 in test/Base_Tests/src/Data/Vector_Spec.enso

View workflow job for this annotation

GitHub Actions / Standard Library Tests (GraalVM CE) (macos, x86_64)

text bytes

[76, 111, 114, 101] did not equal []; lengths differ (4 != 0) (at /Users/runner/work/enso/enso/test/Base_Tests/src/Data/Vector_Spec.enso:86:9-38).

group_builder.specify "should allow vector creation with a programmatic constructor" <|
Vector.new 100 (ix -> ix + 1) . fold 0 (+) . should_equal 5050
Expand Down
Loading