Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: buildkite-plugins/test-collector-buildkite-plugin
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.8.0
Choose a base ref
...
head repository: buildkite-plugins/test-collector-buildkite-plugin
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.9.0
Choose a head ref

Commits on May 30, 2023

  1. Copy the full SHA
    4609958 View commit details
  2. Merge pull request #51 from buildkite-plugins/renovate/plugin-linter-3.x

    Update buildkite plugin plugin-linter to v3.2.0
    toote authored May 30, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    40eee5a View commit details
  3. Copy the full SHA
    1afb725 View commit details
  4. Merge pull request #52 from buildkite-plugins/renovate/plugin-tester-1.x

    Update buildkite plugin plugin-tester to v1.1.0
    toote authored May 30, 2023
    Copy the full SHA
    51b5a8f View commit details

Commits on Jun 1, 2023

  1. feat: Upload concurrency

    js-murph committed Jun 1, 2023
    Copy the full SHA
    03b6952 View commit details
  2. fix: Add debug logging

    js-murph committed Jun 1, 2023
    Copy the full SHA
    a5f5453 View commit details
  3. Copy the full SHA
    565ea3b View commit details
  4. fix: intentation

    js-murph committed Jun 1, 2023
    Copy the full SHA
    c8aea0b View commit details
  5. chore: Debug line

    js-murph committed Jun 1, 2023
    Copy the full SHA
    5cab305 View commit details
  6. chore: Remove tracing

    js-murph committed Jun 1, 2023
    Copy the full SHA
    bde27fc View commit details
  7. Copy the full SHA
    1f8e739 View commit details
  8. Copy the full SHA
    52de3bf View commit details
  9. chore: Re-add subshell

    js-murph committed Jun 1, 2023
    Copy the full SHA
    032a0c3 View commit details
  10. chore: Remove tracing

    js-murph committed Jun 1, 2023
    Copy the full SHA
    0d4eaef View commit details
  11. chore: More debug logs

    js-murph committed Jun 1, 2023
    Copy the full SHA
    3ea88ad View commit details
  12. Copy the full SHA
    56add33 View commit details
  13. fix: accidental char

    js-murph committed Jun 1, 2023
    Copy the full SHA
    0509e90 View commit details
  14. Copy the full SHA
    5936cb8 View commit details
  15. Copy the full SHA
    0090dfe View commit details
  16. docs: Add docs & tests

    js-murph committed Jun 1, 2023
    Copy the full SHA
    980cc62 View commit details
  17. chore: Test tests

    js-murph committed Jun 1, 2023
    Copy the full SHA
    26ce593 View commit details
  18. chore: Test tests

    js-murph committed Jun 1, 2023
    Copy the full SHA
    9e58efc View commit details
  19. chore: Test tests

    js-murph committed Jun 1, 2023
    Copy the full SHA
    712af76 View commit details
  20. chore: decrease verbosity

    js-murph committed Jun 1, 2023
    Copy the full SHA
    e6d475d View commit details

Commits on Jun 16, 2023

  1. Update tests/pre-exit-success.bats

    Co-authored-by: Matías Bellone <toote@users.noreply.github.com>
    js-murph and toote authored Jun 16, 2023
    Copy the full SHA
    47302c3 View commit details

Commits on Jun 19, 2023

  1. fix: Concurrency tests

    js-murph committed Jun 19, 2023
    Copy the full SHA
    d4b4e21 View commit details
  2. Merge pull request #1 from js-murph/johnm/fix-tests

    fix: Concurrency tests
    js-murph authored Jun 19, 2023
    Copy the full SHA
    7b96c14 View commit details
  3. Update tests/pre-exit-success.bats

    Co-authored-by: Matías Bellone <toote@users.noreply.github.com>
    js-murph and toote authored Jun 19, 2023
    Copy the full SHA
    0e15880 View commit details
  4. fix: BSD compatability

    js-murph committed Jun 19, 2023
    Copy the full SHA
    14fce48 View commit details
  5. Merge pull request #2 from js-murph/johnm/fix-bsd-compatability

    fix: Cross-platform compatability
    js-murph authored Jun 19, 2023
    Copy the full SHA
    bc84ece View commit details
  6. fix: Use timeout var instead of magic numbers for concurrency

    * fix: Use timeout var instead of magic numbers for concurrency
    js-murph authored Jun 19, 2023
    Copy the full SHA
    57b7297 View commit details

Commits on Jun 20, 2023

  1. fix: Add missing concurrency tests (#4)

    * fix: Add missing concurrency tests
    js-murph authored Jun 20, 2023
    Copy the full SHA
    139f14e View commit details
  2. fix: Various test fixes and new timeout test (#5)

    fix: Various test fixes and new timeout test
    js-murph authored Jun 20, 2023
    Copy the full SHA
    f8ca0cf View commit details

Commits on Jun 23, 2023

  1. Copy the full SHA
    a85a3ae View commit details

Commits on Jun 29, 2023

  1. Copy the full SHA
    b9aded8 View commit details
  2. Scope badge to main branch

    pzeballos authored Jun 29, 2023
    Copy the full SHA
    734b41e View commit details
  3. Merge pull request #57 from buildkite-plugins/scope-build-badge

    Scope badge to main branch
    pzeballos authored Jun 29, 2023
    Copy the full SHA
    4ab17e0 View commit details

Commits on Jun 30, 2023

  1. Copy the full SHA
    d1f196b View commit details

Commits on Jul 2, 2023

  1. Copy the full SHA
    dbb5716 View commit details

Commits on Jul 3, 2023

  1. Merge pull request #53 from js-murph/main

    feat: Concurrent file uploads
    pzeballos authored Jul 3, 2023
    Copy the full SHA
    8b7e6e2 View commit details
Showing with 149 additions and 14 deletions.
  1. +7 −1 README.md
  2. +2 −2 buildkite.yaml
  3. +58 −11 hooks/pre-exit
  4. +2 −0 plugin.yml
  5. +80 −0 tests/pre-exit-success.bats
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Test Collector Buildkite Plugin [![Build status](https://badge.buildkite.com/e77fce33cffd9045543fdba23c51a6aec8e8b6161fa4c136a3.svg)](https://buildkite.com/buildkite/plugins-test-collector)
# Test Collector Buildkite Plugin [![Build status](https://badge.buildkite.com/e77fce33cffd9045543fdba23c51a6aec8e8b6161fa4c136a3.svg?branch=main)](https://buildkite.com/buildkite/plugins-test-collector)

A Buildkite plugin for uploading [JSON](https://buildkite.com/docs/test-analytics/importing-json) or [JUnit](https://buildkite.com/docs/test-analytics/importing-junit-xml) files to [Buildkite Test Analytics](https://buildkite.com/test-analytics)

@@ -90,6 +90,12 @@ Adds an annotation to the build run with a link to the uploaded report.

Default value: `false`

#### `upload-concurrency`(number)

The number of concurrent file uploads to perform to the Buildkite analytics API.

Default value: `1`

## Examples

### Upload a JUnit file
4 changes: 2 additions & 2 deletions buildkite.yaml
Original file line number Diff line number Diff line change
@@ -6,9 +6,9 @@ steps:

- label: ":sparkles:"
plugins:
- plugin-linter#v3.1.0:
- plugin-linter#v3.2.0:
id: test-collector

- label: ":docker: :hammer:"
plugins:
- plugin-tester#v1.0.0: ~
- plugin-tester#v1.1.0: ~
69 changes: 58 additions & 11 deletions hooks/pre-exit
Original file line number Diff line number Diff line change
@@ -6,8 +6,9 @@ FORMAT="${BUILDKITE_PLUGIN_TEST_COLLECTOR_FORMAT:-}"
TIMEOUT="${BUILDKITE_PLUGIN_TEST_COLLECTOR_TIMEOUT:-30}"
BASE_PATH="${BUILDKITE_PLUGIN_TEST_COLLECTOR_BASE_PATH:-.}"
ANNOTATE="${BUILDKITE_PLUGIN_TEST_COLLECTOR_ANNOTATION_LINK:-false}"
UPLOAD_CONCURRENCY="${BUILDKITE_PLUGIN_TEST_COLLECTOR_UPLOAD_CONCURRENCY:-1}"
REPORT_URLS_FILE=$(mktemp)
CURL_RESP_FILE="${CURL_RESP_FILE:-response.json}"
CURL_RESP_FILE="${CURL_RESP_FILE:-}"
DEBUG="false"

if [[ "${BUILDKITE_PLUGIN_TEST_COLLECTOR_DEBUG:-}" =~ ^(true|on|1|always)$ ]]; then
@@ -94,6 +95,7 @@ save-report-url() {
# Upload failures should not fail the build, and should have a sensible timeout,
# so that Test Analytics availability doesn't affect build reliability.
upload() {
local response_file="$4"
local file="$3"
local format="$2"

@@ -124,7 +126,7 @@ upload() {
fi

if [[ "$ANNOTATE" != "false" ]]; then
curl_args+=("-o" "${CURL_RESP_FILE}")
curl_args+=("-o" "${response_file}")
fi

curl_args+=("${BUILDKITE_PLUGIN_TEST_COLLECTOR_API_URL:-https://analytics-api.buildkite.com/v1/uploads}")
@@ -152,24 +154,69 @@ find_and_upload() {
matching_files=()
while IFS=$'' read -r matching_file ; do
matching_files+=("$matching_file")
done < <("${FIND_CMD[@]}" "${BASE_PATH}" -path "${BASE_PATH}/${FILES_PATTERN}")
done < <("${FIND_CMD[@]}" "${BASE_PATH}" -path "${BASE_PATH}/${FILES_PATTERN}" | sort)

if [[ "${#matching_files[@]}" -eq "0" ]]; then
echo "No files found matching '${FILES_PATTERN}'"
if [[ "${BUILDKITE_COMMAND_EXIT_STATUS:-0}" -eq "0" ]]; then
exit "${BUILDKITE_PLUGIN_TEST_COLLECTOR_MISSING_ERROR:-1}"
fi
else
declare -a uploads_in_progress=()
echo "Uploading '${#matching_files[@]}' files matching '${FILES_PATTERN}'"

# needs to be part of else for bash4.3 compatibility
for file in "${matching_files[@]}"; do
echo "Uploading '$file'..."
if ! upload "$TOKEN_VALUE" "$FORMAT" "${file}"; then
echo "Error uploading, will continue"
fi
if [[ "$ANNOTATE" != "false" ]]; then
save-report-url "${CURL_RESP_FILE}"
fi
iterations_waited=0
while [[ "${#uploads_in_progress[@]}" -ge $UPLOAD_CONCURRENCY ]]; do
iterations_waited=$((iterations_waited + 1))
if [[ "${DEBUG}" == "true" ]]; then
echo "Waiting for uploads to finish..."
fi

sleep 1

for index in "${!uploads_in_progress[@]}"; do
# Note: kill -0 does not kill the pid, it provides a *nix compatible way to test the pid is responding.
if ! kill -0 "${uploads_in_progress[index]}" > /dev/null; then
unset 'uploads_in_progress[index]'
elif [[ "$iterations_waited" -gt $TIMEOUT ]]; then
echo "Upload '${uploads_in_progress[index]}' has been running for more than '${TIMEOUT}' seconds, killing it"
kill "${uploads_in_progress[index]}"
unset 'uploads_in_progress[index]'
fi
done
done

# Spawn a subcommand group to allow parallel uploads
{
echo "Uploading '$file'..."

if [[ -n "${CURL_RESP_FILE}" ]]; then
response_file="${CURL_RESP_FILE}"
else
response_file="$(mktemp -t 'response.XXXXXX')"
fi

if ! upload "$TOKEN_VALUE" "$FORMAT" "${file}" "${response_file}"; then
echo "Error uploading, will continue"
fi

if [[ "$ANNOTATE" != "false" ]]; then
save-report-url "${response_file}"
fi

if [[ "${DEBUG}" == "true" ]]; then
echo "Finished uploading '$file'"
fi
} &

# Store the PID of the upload
uploads_in_progress+=($!)
done

# Wait for all uploads to finish
wait "${uploads_in_progress[@]}"
fi
}

@@ -194,4 +241,4 @@ else
fi
if [ "$ANNOTATE" != "false" ]; then
annotation-link "${REPORT_URLS_FILE}"
fi
fi
2 changes: 2 additions & 0 deletions plugin.yml
Original file line number Diff line number Diff line change
@@ -35,6 +35,8 @@ configuration:
type: integer
annotation-link:
type: boolean
upload-concurrency:
type: integer
required:
- files
- format
80 changes: 80 additions & 0 deletions tests/pre-exit-success.bats
Original file line number Diff line number Diff line change
@@ -57,6 +57,47 @@ COMMON_CURL_OPTIONS='--form \* --form \* --form \* --form \* --form \* --form \*
assert_output --partial "curl success 3"
}

@test "Uploads multiple files concurrently does not break basic functionality" {
# would love to test functionality but can not do so due to limitations on bats-mock :(
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES='**/*/junit-*.xml'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_UPLOAD_CONCURRENCY='3'

skip "bats-mock does not currently support concurrency, so we can't test this reliably"

stub curl "-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} \* -H \* : echo \"curl success \${10}\""

run "$PWD/hooks/pre-exit"

unstub curl

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "Uploading './tests/fixtures/junit-2.xml'..."
assert_output --partial "Uploading './tests/fixtures/junit-3.xml'..."
assert_equal "$(echo "$output" | grep -c "curl success")" "3"
}

@test "Concurrency waits when the queue is full" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES='**/*/junit-*.xml'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_UPLOAD_CONCURRENCY='2'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_DEBUG='true'

stub curl \
"-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} --form \* \* -H \* : sleep 3; echo \"curl success \${10}\"" \
"-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} --form \* \* -H \* : echo \"curl success \${10}\""

run "$PWD/hooks/pre-exit"

unstub curl

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "Uploading './tests/fixtures/junit-2.xml'..."
assert_output --partial "Waiting for uploads to finish..."
assert_output --partial "Uploading './tests/fixtures/junit-3.xml'..."
assert_equal "$(echo "$output" | grep -c "curl success")" "3"
}

@test "Single file pattern through array" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES_0='**/*/junit-1.xml'
unset BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES
@@ -149,6 +190,25 @@ COMMON_CURL_OPTIONS='--form \* --form \* --form \* --form \* --form \* --form \*
assert_output --partial "curl success"
}

@test "Concurrency gracefully handles command-group timeout" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES='**/*/junit-*.xml'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_UPLOAD_CONCURRENCY='2'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_TIMEOUT='3'

stub curl "if [ \${10} != 'data=@\"./tests/fixtures/junit-3.xml\"' ]; then echo sleeping for \${10}; sleep 10 & wait \$!; else echo curl success \${10}; fi"

run "$PWD/hooks/pre-exit"

unstub curl

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "Uploading './tests/fixtures/junit-2.xml'..."
assert_equal "$(echo "$output" | grep -c "has been running for more than")" "2"
assert_output --partial "Uploading './tests/fixtures/junit-3.xml'..."
assert_equal "$(echo "$output" | grep -c "curl success")" "1"
}

@test "Git available sends plugin version" {
stub git "rev-parse --short HEAD : echo 'some-commit-id'"
stub curl "-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} --form \* \* -H \* : echo \"curl success with \${30}\""
@@ -234,3 +294,23 @@ COMMON_CURL_OPTIONS='--form \* --form \* --form \* --form \* --form \* --form \*
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "Error uploading, will continue"
}

@test "Concurrency gracefully handles failure" {
export BUILDKITE_PLUGIN_TEST_COLLECTOR_FILES='**/*/junit-*.xml'
export BUILDKITE_PLUGIN_TEST_COLLECTOR_UPLOAD_CONCURRENCY='2'

stub curl \
"-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} \* -H \* : exit 10" \
"-X POST --silent --show-error --max-time 30 --form format=junit ${COMMON_CURL_OPTIONS} \* -H \* : echo 'curl success'"

run "$PWD/hooks/pre-exit"

unstub curl

assert_success
assert_output --partial "Uploading './tests/fixtures/junit-1.xml'..."
assert_output --partial "Uploading './tests/fixtures/junit-2.xml'..."
assert_equal "$(echo "$output" | grep -c "Error uploading, will continue")" "2"
assert_output --partial "Uploading './tests/fixtures/junit-3.xml'..."
assert_equal "$(echo "$output" | grep -c "curl success")" "1"
}