Skip to content

internal/testrunner/script: add script testing package#3012

Merged
efd6 merged 15 commits intoelastic:mainfrom
efd6:script_tests
Nov 19, 2025
Merged

internal/testrunner/script: add script testing package#3012
efd6 merged 15 commits intoelastic:mainfrom
efd6:script_tests

Conversation

@efd6
Copy link
Contributor

@efd6 efd6 commented Oct 21, 2025

This adds script testing for data streams. This is the MVP, future versions can be generalised to operate on input packages.

The current implementation supports:

  • pipeline testing
  • system testing
  • package upgrade testing (only to latest, not to arbitrary versions)
  • shared stack
  • independent stack
  • docker services

Not supported:

  • test coverage
  • report output configuration
  • k8s services
  • tf services (ish, these can be shimmed via docker)

Depends on a v3.5.1 of package-spec (currently shimmed in via a go.mod replace directive, to be removed)

Please take a look.

For #2944

@efd6 efd6 self-assigned this Oct 21, 2025
@efd6 efd6 added the enhancement New feature or request label Oct 21, 2025
@efd6 efd6 force-pushed the script_tests branch 5 times, most recently from 411a39e to bc55805 Compare October 21, 2025 04:31
@efd6
Copy link
Contributor Author

efd6 commented Oct 21, 2025

/test

@efd6 efd6 force-pushed the script_tests branch 2 times, most recently from d9e0c1a to 8433c67 Compare October 21, 2025 20:16
@efd6 efd6 marked this pull request as ready for review October 21, 2025 21:09
@efd6 efd6 requested a review from a team as a code owner October 21, 2025 21:09
return cmd
}

func testRunnerScriptCommandAction(cmd *cobra.Command, args []string) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The logic in this function is rudimentary and only intended to allow an MVP to be demonstrated. In order to be able to render reports and redirect to file output this needs enhancement.

@efd6 efd6 requested a review from andrewkroh October 21, 2025 21:14
@jsoriano jsoriano self-requested a review October 23, 2025 08:34
@efd6 efd6 force-pushed the script_tests branch 5 times, most recently from 7f4815f to fdc0951 Compare October 28, 2025 06:46
Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

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

Thanks! This is a pretty interesting feature.

I haven't checked the implementation in detail, added by now some comments and questions about the overall behavior.

if err != nil {
return err
}
workRoot := filepath.Join(home, filepath.FromSlash(".elastic-package/tmp/script_tests"))
Copy link
Member

Choose a reason for hiding this comment

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

Config directory should be obtained using the location manager. It can be customized with ELASTIC_PACKAGE_DATA_HOME.

The tmp directory can be obtained with loc.TempDir().

Suggested change
workRoot := filepath.Join(home, filepath.FromSlash(".elastic-package/tmp/script_tests"))
workRoot := filepath.Join(home, loc.TempDir(), "script_tests")

// root is non-zero, so just let testscript put it where it wants in the
// case that we have not requested work to be retained. This will be in
// os.MkdirTemp(os.Getenv("GOTMPDIR"), "go-test-script") which on most
// systems will be /tmp/go-test-script. However, due to… decisions, we
Copy link
Member

Choose a reason for hiding this comment

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

What decisions are you referring to? 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The use of file system jailing prevents using other paths.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe this should be part of the coment 🙂

# Only run the test if --external-stack=true.
[!external_stack] skip 'Skipping external stack test.'
# Only run the test if the jq executable is in $PATH. This is needed for a test below.
[!exec:jq] skip 'Skipping test requiring absent jq command'
Copy link
Member

Choose a reason for hiding this comment

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

It looks like several sample tests here depend on jq to compare fields in JSON files. If this is going to be frequent, maybe we can provide a function to do these comparisons? And maybe the same with basic http requests to avoid depending on curl.

This would help to avoid depending on external tools that may not be installed, specially on Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If it becomes necessary, those can be added. Both curl and jq are available in CI and I'd prefer to avoid having to reimplement and maintain tools that already exist.

Copy link
Member

Choose a reason for hiding this comment

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

Agree this can be added later.

I am not so worried about the current CI, but about future deployments where we might forget to install jq (or curl in Windows) if not required for other things, and the test would be silently skipped. Same thing for local execution.

jq and curl are powerful tools, in no case I would think on re-implement them, but the limited logic that we need, also reusing existing tools, in the form of Go code.

Copy link
Contributor

@mrodm mrodm left a comment

Choose a reason for hiding this comment

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

Added a comment about CI scripts.

The error raised in the latest Buildkite build should be fixed now, since it has been merged the new spec version #3049

PACKAGE_TEST_TYPE=other ./scripts/test-check-packages.sh

test-check-packages-independent-script:
elastic-package test script -C test/packages/other/with_script --external-stack=false --defer-cleanup 1s
Copy link
Contributor

Choose a reason for hiding this comment

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

I would create a new folder for this test package like test/packages/independent-script/ and just keep (move) that new test package into this new folder.

The reasoning of this is that currently, this with_script test package is being tested twice in Buildkite builds. In these two steps:

  • Integration test: other
  • Integration test: independent-script

So, I would create a new folder and update this target:

Suggested change
elastic-package test script -C test/packages/other/with_script --external-stack=false --defer-cleanup 1s
elastic-package test script -C test/packages/independent-script/with_script --external-stack=false --defer-cleanup 1s

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would create a new folder for this test package like test/packages/independent-script/ and just keep (move) that new test package into this new folder.

The twice use of this is intentional.

Copy link
Contributor

Choose a reason for hiding this comment

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

The twice use of this is intentional.

Why is it needed? Within the other step, what is it different from the other CI step (independent-script)?
Maybe it is tested with the stack triggered by the CI itself ? I mean not using this external-stack=false ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When external-stack=false, the script brings up a stack. This would fail if a stack is already running due to port collision. The external and non-external stack tests need to be in the same package to ensure that the conditional is correctly implemented.

@efd6 efd6 force-pushed the script_tests branch 5 times, most recently from d5eced9 to 054ae48 Compare November 6, 2025 21:05
@efd6
Copy link
Contributor Author

efd6 commented Nov 6, 2025

/test

Copy link
Member

@andrewkroh andrewkroh left a comment

Choose a reason for hiding this comment

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

LGTM. I left a few minor comments and have two questions:

  1. When we run dump_logs, it captures logs like $WORK/logs/elastic-agent-internal/elastic-agent-YYYYMMDD.ndjson and $WORK/logs/elastic-agent-internal/cel/cel-UUID-URL.ndjson. Will these less predictable file names make it difficult to write assertions on their file contents from testscript?

  2. Can we add a mechanism to capture the registry files from the Elastic Agent container? I would like to be able to run assertions on their contents, like checking that the httpjson cursor contains a specific timestamp or pagination token after test completion.

@efd6
Copy link
Contributor Author

efd6 commented Nov 17, 2025

  1. When we run dump_logs, it captures logs like $WORK/logs/elastic-agent-internal/elastic-agent-YYYYMMDD.ndjson and $WORK/logs/elastic-agent-internal/cel/cel-UUID-URL.ndjson. Will these less predictable file names make it difficult to write assertions on their file contents from testscript?

It will to a degree; from what I can see elastic-package's testing was not written with a concern for bit-reproducible testing. The filenames there are a consequence of the way that logs are written by the underlying routines in elastic-agent though AFAICS. At the moment, the way to handle these would be to have a helper shell script or maybe jq over the glob. If this is seen as too complex, we can maybe harmonise all the files in those directories into single file collections that have been temporally ordered and written to a file with a known name.

The current situation does not make it impossible, but depending on the threshold for "difficult", yes, no or maybe.

  1. Can we add a mechanism to capture the registry files from the Elastic Agent container? I would like to be able to run assertions on their contents, like checking that the httpjson cursor contains a specific timestamp or pagination token after test completion.

We can; in fact that is one of my unchecked TODO boxes. Would you like that added in this change, or can it be added in a follow-up?

@efd6
Copy link
Contributor Author

efd6 commented Nov 17, 2025

If this is seen as too complex, we can maybe harmonise all the files in those directories into single file collections that have been temporally ordered and written to a file with a known name.

I've done this.

@andrewkroh
Copy link
Member

In a follow-up would be best.

Copy link
Contributor

@mrodm mrodm left a comment

Choose a reason for hiding this comment

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

LGTM
Just added a few comments.

It would be interesting to wait also for @jsoriano's review before merging, since he had some comments here too.

While the testscript package allows reference to paths outside the configuration
root and the package's root, the backing `elastic-package` infrastructure does
not, so it is advised that tests only refer to paths within the `$WORK` and
`$PKG_ROOT` directories. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking into the environment variables listed above, should this be PACKAGE_ROOT?

Suggested change
`$PKG_ROOT` directories.
`$PACKAGE_ROOT` directories.


While the testscript package allows reference to paths outside the configuration
root and the package's root, the backing `elastic-package` infrastructure does
not, so it is advised that tests only refer to paths within the `$WORK` and
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

cc @efd6

@efd6 efd6 merged commit bd294f5 into elastic:main Nov 19, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants