97 lines
4.0 KiB
Plaintext
Executable File
97 lines
4.0 KiB
Plaintext
Executable File
#!/usr/bin/env -S jq -s -r -f
|
|
|
|
# Copyright The containerd Authors.
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# Takes the raw test2json as input and groups each item by package name + test name
|
|
#
|
|
# Example
|
|
# Input:
|
|
# {...}
|
|
# {...}
|
|
# {...}
|
|
# Output:
|
|
# [[{...},{...},{...}]]
|
|
def group_tests: reduce (.[] | select(.Test != null)) as $item (
|
|
{}; .["\($item.Package).\($item.Test)"] += [$item]
|
|
);
|
|
|
|
# Filter a group of tests by action.
|
|
# The way this works is for a group of tests,
|
|
# if none of the tests have an action matching the provided value, the group is
|
|
# dropped.
|
|
def filter_group_action(a): map(select(.[].Action == a));
|
|
|
|
# Filter a group of tests to just the tests that failed
|
|
def only_failed: filter_group_action("fail");
|
|
|
|
def merge_strings(s1; s2): if s1 == null then s2 else "\(s1)\(s2)" end;
|
|
|
|
# Matches an output string to find the test file and line number.
|
|
# The actual string looks something like:
|
|
# "test_foo.go:12: some failure message\n"
|
|
# There may be arbitrary whitespace at the beginning of the string.
|
|
def capture_fail_details: capture("^\\s*(?<file>\\w+_test\\.go):(?<line>\\d+): "; "x");
|
|
|
|
# Filter out all the undesirable test line outputs
|
|
def filter_test_item:
|
|
select(.Output != null)
|
|
| select(.Output | test("^\\s*=== RUN")| not)
|
|
| select(.Output | test("^\\s*=== PAUSE")| not)
|
|
| select(.Output | test("^\\s*=== CONT")| not)
|
|
| select(.Output | test("^\\s*--- FAIL:")| not)
|
|
;
|
|
|
|
# Take a list of test groups and make a map of tests keyed on the package name +
|
|
# test name with all the output concatenated.
|
|
#
|
|
# This uses the last test log message to get the the file/line number for the test (as .Details)
|
|
def merge_output: reduce (.[][] | filter_test_item) as $item (
|
|
{}; (
|
|
"\($item.Package).\($item.Test)" as $key
|
|
| merge_strings(.[$key].Output; $item.Output) as $merged
|
|
| .[$key] += {
|
|
Output: $merged | sub("^\\s*"; ""; "x"),
|
|
Test: $item.Test,
|
|
Package: $item.Package,
|
|
Details: (($item.Output | capture_fail_details) // .[$key].Details), # "//" is an operator that returns the first true/non-null value
|
|
}
|
|
) // .
|
|
);
|
|
|
|
# Used as the "title" field for error annotations
|
|
def err_title: "Failed: \(.Package).\(.Test)";
|
|
|
|
# Split the containerd root package path to get the directory name that a test belongs to.
|
|
def file_dir: .Package | split("github.com/containerd/containerd/")[-1];
|
|
|
|
def err_file: if .Details != null and .Details.file != null then "\(file_dir)/\(.Details.file)" else "" end;
|
|
|
|
# Some cases there may not be any extra details because they got filtered out.
|
|
# This can happen, for instance, if the failure log was create from a file that is not a `_test.go` file.
|
|
# In this case we'd still want the annotation but we just can't get the file/line number (without allowing non-test files to be the source of the failure).
|
|
def details_to_string: if .Details != null and .Details.file != null then ",file=\(err_file),line=\(.Details.line)" else "" end;
|
|
|
|
# Replace all occurrences of "\n" with the url-encoded version
|
|
# This allows multi-line strings to work with github annotations.
|
|
# https://github.com/actions/toolkit/issues/193#issuecomment-605394935
|
|
def encode_output: gsub("\n"; "%0A");
|
|
|
|
# Creates github actions error annotations for each input
|
|
# It is expected that the input is the output of merge_output.
|
|
def to_error: reduce .[] as $item (
|
|
""; . += "::error title=\($item | err_title)\($item | details_to_string)::\($item.Output | encode_output)\n"
|
|
);
|
|
|
|
group_tests | only_failed | merge_output | to_error |