Commit Graph
60 Commits
Author SHA1 Message Date
Lucas Bajolet 615c0a1cf2 packer_test: add PackerCommand on TestDirSpec
Instead of manually invoking ts.PackerCommand().UsePluginDir(), we
introduce a new PackerCommand() function on TestDirSpec which
fast-tracks this common use-case.
2024-08-15 14:28:16 -04:00
Lucas Bajolet 465ec8bae0 packer_test: make PluginTestDir a structure
In order for the creation of a temporary directory to install plugins
into to be simpler to understand and use, we change how the directory is
created, cleaned-up, and installs plugins into.

Now, instead of a tuple of a string (path) and a cleanup function, we
return a structure that comprises the test suite, and the temporary
directory, along with methods to handle those steps independently.
2024-08-15 14:09:33 -04:00
Lucas Bajolet e91558f4d4 packer_test: hide run and introduce Output
When using a PackerCommand, the Run function was made public as a way to
access the contents of an execution.

This was clumsy as it had too many responsabilities, and was not needed
strictly as Assert was performing the executions, as many times as
required.

This could introduce cases in which one run as spent by the caller, then
the remainder were executed through Assert.

Therefore, we change this convention.

Now, run is private to the type, and only through Assert can a command
be executed.
If a test needs access to a command's output, stderr, or error, it can
do so through the Output function, which requires Assert to be called
first.
2024-08-15 10:51:30 -04:00
Lucas Bajolet ae792299dc packer_test: add func to change assert behaviour
When a command asserts its output with checkers, by default it will
register errors through a t.Errorf.

While this works, in some cases we would want to stop execution
immediately if a function's Assert fails, as the rest of the test may
depend on the assertion being valid.

In the current state, this means either getting the result of the run to
check if an error was returned (not fully reliable as if the command was
run multiple times, and the last run succeeded, we won't get an error),
or relying on t.IsFailed() (completely reliable).

Instead, we introduce a new function on packerCommand, that lets users
change how Assert behaves, so that if an error was reported, instead of
logging the error and flagging the test as failed, we can use t.Fatalf,
so that the test immedately fails and stops execution.
2024-08-15 10:51:30 -04:00
Lucas Bajolet c3ef682a8b packer_test: rename/split lib into common/check
The lib name for the common components for writing packer_test suites
was not clear, and did not follow the convention established in Packer
core and plugins.
Therefore this commit does two things: first the lib is renamed into
common as to follow this convention, and clearly document which
components are common to all tests.
Also checkers are placed in a subpackage of common, common/check, so
that it is clearer what is meant to be used as checks for a command's
execution status after it's been run, as part of Assert.
2024-08-15 10:05:27 -04:00
Lucas Bajolet 098737aef9 packer_test: rename core test run function
The function's name was the same as the plugins test suite runner/init
function, making it impossible to differentiate between the two when
looking at the logs, or when attempting to filter which tests to run
using the suite function's name.
2024-08-14 16:19:22 -04:00
Lucas Bajolet 16de9e059c packer_test: reorganise plugins test suite init 2024-08-14 16:18:24 -04:00
Lucas Bajolet 1332690828 packer_test: remove empty defer func in suite init 2024-08-14 16:17:49 -04:00
Lucas Bajolet 7d176daef0 packer_test: split BuildPackerPlugin in build/get
The interface for building a plugin through the test suite was
confusing, as it would build the plugin and return its path, cache the
path for the version built, and return the path regardless if something
was built or not.

While in the current state this is harmless as builds are idempotent,
since the state of the plugin package/module does not change, this will
in the future as we introduce customisation techniques on the plugin's
directory and files, making this double-use potentially dangerous.

Furthermore, the current behaviour is unclear, as the function hides
that caching mechanism, which could come as a surprise for users
attempting to build a plugin for the duration of a test, while the built
plugin is linked to the test suite being run, and not the unit test
being evaluated.

Therefore this commit changes the sequence in which plugins are built
and used. Now the `CompilePlugin` function builds a plugin, and does not
return its path anymore, instead terminating the tests immediately if
they fail.
In normal test usage, a new `GetPluginPath` function is introduced,
which looks-up the path in the suite's cache, failing immediately if
invoked before the plugin is built.

With this change, it is heavily advised to build plugins when
initialising the suite, then in the tests, the GetPluginPath function
should be used to get a plugin's path for interacting with packer
commands.
2024-08-14 16:12:53 -04:00
Lucas Bajolet 728a5fc19e packer_test: replace compiledPlugins by a sync.Map
The compiledPlugins map with a mutex was essentially a glorified
sync.Map, and therefore did not need to be defined as such.
Instead, this commit replaces its uses by a normal sync.Map, and keeps
it in the base test suite.
2024-08-14 16:06:46 -04:00
Lucas Bajolet 950c255d03 packer_test: rename init function for base suite 2024-08-14 15:51:47 -04:00
Lucas Bajolet b4814354c0 packer_test: add convenience func for invert grep
As inverted grep is something we do rather often, we add a convenience
function to create an inverted grep gadget.
2024-08-14 15:50:53 -04:00
Lucas Bajolet ded0500109 packer_test: add plugins used gadget
When testing a packer build or validate, one common use case is to check
which plugins are loaded and used by Packer to run a command.

This is generally done through Grep, but repeating the same pattern can
be redundant, and if the output changes, all those need to be updated.

Therefore, this commit introduces a PluginsUsed gadget, which can be
orchestrated to ensure a plugin is used, or not used, allowing to check
for multiple plugins at once.
2024-08-13 14:52:43 -04:00
Lucas Bajolet 6b158c5c24 packer_test: move some plugin functions to fs.go
As a small reorganisation attempt, this commit moves some file-system
oriented functions from plugin.go into its own file so they are more
logically grouped.
2024-08-13 14:52:43 -04:00
Lucas Bajolet 96b4ae4767 packer_test: move BuildSimplePlugin to plugin.go
In terms of organisation, we keep functions that interact with plugins
into its own file, therefore the function that build plugin versions
should really be in plugin.go, not in suite.go.
2024-08-13 14:52:43 -04:00
Lucas Bajolet 2fe11fb967 packer_test: move compiledPlugins to attribute
The compiledPlugins map used to be a global variable, which can be
problematic as we move to independent test suites, since those test
suites run in the same process space, the global variable could point to
now deleted plugin versions/paths in separate suites, which would make
tests fail with random errors.

To avoid this, the map is now scoped to the test suite, and a new copy
is created lazily if used by the test suite.
2024-08-13 14:52:43 -04:00
Lucas Bajolet 9e4452329f packer_test: make packer test suite modular
Having only one test suite for the whole of Packer makes it harder to
segregate between test types, and makes for a longer runtime as no tests
run in parallel by default.

This commit splits the packer_test suite into several components in
order to make extension easier.

First we have `lib`: this package embeds the core for running Packer
test suites. This ships facilities to build your own test suite for
Packer core, and exposes convenience methods and structures for building
plugins, packer core, and use it to run a test suite in a temporary
directory.

Then we have two separate test suites: one for plugins, and one for core
itself, the latter of which does not depend on plugins being compiled at
all.

This sets the stage for more specialised test suites in the future, each
of which can run in parallel on different parts of the code.
2024-08-13 14:52:43 -04:00
dependabot[bot] 7425ef3a45 build(deps): bump github.com/hashicorp/go-retryablehttp
Bumps [github.com/hashicorp/go-retryablehttp](https://github.com/hashicorp/go-retryablehttp) from 0.7.0 to 0.7.7.
- [Changelog](https://github.com/hashicorp/go-retryablehttp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/go-retryablehttp/compare/v0.7.0...v0.7.7)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-retryablehttp
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-07-01 12:50:39 -04:00
dependabot[bot] 0f223cc9ac build(deps): bump google.golang.org/protobuf
Bumps google.golang.org/protobuf from 1.28.1 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-06-21 15:48:19 -04:00
dependabot[bot] 5843c86c7e build(deps): bump google.golang.org/grpc in /packer_test/plugin_tester
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.50.1 to 1.56.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.50.1...v1.56.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-06-17 16:57:01 -04:00
Lucas Bajolet 13c52124de packer_test: check for a panic during execution
When a command is run, it is the expectation that no test should make
Packer panic. If it did, something is wrong and Packer should be fixed
so it doesn't panic anymore in that situation.

The way we did the check before was adding a PanicCheck after the
command ran, so we could make sure of that during `Assert`.

However, since we introduced the possibility to have multiple runs,
having this addition as part of the run loop meant that the PanicCheck
would be run as many times as there were runs.

While this worked, this implied that we'd do the same check multiple
times on a single command output, which is not optimal.

Instead, this commit moves the check to within the `Run` function, this
way for each run of the command we do the check once, and then we can
assert the results of the command on what output it produced.
2024-06-17 16:51:58 -04:00
Lucas Bajolet 36e43e30ee hcl2template: detect duplicate locals during parse
Previously duplicate detection for local variables happened during
`Initialise`, through a call to `checkForDuplicateLocalDefinition`.

This works in a majority of cases, but for commands like `console`, this
was not detected as the return diagnostics for `Initialise` are ignored.

That check can be done as early as during parsing however, as the names
of blocks are not dynamic in the slightest (no interpolation possible),
so we move that detection logic into `Parse`, so that the behaviour is
coherent between all commands.
2024-06-17 16:51:58 -04:00
Lucas Bajolet 14cf4b40d4 hcl2template: recursively evaluate local variables
The logic for evaluating local variables used to rely on their
definition order, with some edge cases. Typically `locals` blocks define
multiple local variables, which don't necessarily appear in the same
order at evaluation as within the template, leading to inconsistent
behaviour, as the order in which those are added to the list of local
variables is non-deterministic.

To avoid this problem, we change how local variables are evaluated, and
we're adopting a workflow similar to datasources, where the local
variables first build a list of direct dependencies. Then when
evaluation happens, we evaluate all the dependencies recursively for
each local variable, which takes care of this issue.

As with Datasources, we add a cap to the recursion: 10. I.e. if the
evaluation of a single variable provokes an infinite recursion, we stop
at that point and return an error to the user, telling them to fix their
template.
2024-06-17 16:51:58 -04:00
Lucas Bajolet 9d1dc7d41d packer_test: disable checkpoint for test cmds 2024-06-17 16:51:58 -04:00
Lucas Bajolet dbaaab512a packer_test: add SkipNoAcc function
The SkipNoAcc function on PackerTestSuite allows to mark a test run as
not to be run every time we run `make test`, but only when PACKER_ACC=1
is set in the environment.

This allows us to skip executing tests that are either long-running, or
that depend on external dependencies (typically Github), which have a
higher potential to fail on a normal run of Packer tests.
2024-06-17 16:51:58 -04:00
Lucas Bajolet d65074c05c packer_test: dump command outs in case of failure
When a test fails to exert its assertions on the command-line output, a
test fails, but we don't necessarily can troubleshoot what happened,
especially when this happens in a CI environment.

Therefore, for convenience, we add the faculty for packerCommand.Assert
to automatically dump a command's output (both stdout and stderr) if a
test fails.
2024-06-17 16:51:58 -04:00
Lucas Bajolet 4a05d19a89 packer_test: add capability to provide stdin
Some commands need to have an input in order to work.
For those, we add the capability for the packerCommand struct to have
their stdin defined from a string, which is then fed to the command
being executed.
2024-06-17 16:51:58 -04:00
Lucas Bajolet 39a483f762 packer_test: add func to test a cmd multiple times
When a Packer command is created for testing the tool, we generally run
it once, then the command is essentially nooping.

This change allows us to run Packer multiple times with the same
parameters, and make sure all runs conform to a specific list of checks.

This allows us to more reliably test non-deterministic behaviours.
2024-06-17 16:51:58 -04:00
dependabot[bot] e6acdd5f52 build(deps): bump golang.org/x/net in /packer_test/plugin_tester
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-06-12 11:55:32 -04:00
dependabot[bot] 5e7607184d build(deps): bump github.com/go-jose/go-jose/v3
Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.0 to 3.0.3.
- [Release notes](https://github.com/go-jose/go-jose/releases)
- [Changelog](https://github.com/go-jose/go-jose/blob/v3.0.3/CHANGELOG.md)
- [Commits](https://github.com/go-jose/go-jose/compare/v3.0.0...v3.0.3)

---
updated-dependencies:
- dependency-name: github.com/go-jose/go-jose/v3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-06-10 14:59:17 -04:00
Lucas Bajolet 6e45bf3c31 packer_test: add remote install with pre-rel test
Remotely installing plugins with a pre-release as part of the constraint
is unsupported by Packer, and should error if that happens.
This test makes sure that this gets treated as an error if that's the
case, even before attempting to connect to the source.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 8d7a8f126d packer_test: remove %d from workdir path
'%d' gets output as-is in the temporary workdir we create. This is
unnecessary and could even be problematic in some cases, so we scrub it
from the MkdirTemp call.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 8402e00222 packer_test: add test with config.json/components
Since legacy config files may declare single plugin components, we need
to warn that they're not supported anymore.
This is in process of being PR'd into main, but to ensure the config
works as intended and we do get the error, we add some tests for that.
2024-06-10 09:59:32 -04:00
Wilken Rivera 1d65ad676f Add test cases for init command
These changes include a series of test cases for validating packer init
using the force and upgrade flag. Include in this test is a test case
for validating the plugin installation error when init encounters a
plugin whose reported version does not match the version within the
plugin name.

```
--- PASS: Test_PackerCoreSuite (18.66s)
    --- PASS: Test_PackerCoreSuite/TestPackerInitForce (4.91s)
        --- PASS: Test_PackerCoreSuite/TestPackerInitForce/installs_any_missing_plugins (2.76s)
        --- PASS: Test_PackerCoreSuite/TestPackerInitForce/reinstalls_plugins_matching_version_constraints (2.14s)
    --- PASS: Test_PackerCoreSuite/TestPackerInitUpgrade (3.70s)
        --- PASS: Test_PackerCoreSuite/TestPackerInitUpgrade/upgrades_a_plugin_to_the_latest_matching_version_constraints (2.02s)
    --- PASS: Test_PackerCoreSuite/TestPackerInitWithMixedVersions (1.96s)
        --- PASS: Test_PackerCoreSuite/TestPackerInitWithMixedVersions/skips_the_plugin_installation_with_mixed_versions_before_exiting_with_an_error (1.96s)
    --- PASS: Test_PackerCoreSuite/TestPackerInitWithNonGithubSource (1.22s)
        --- PASS: Test_PackerCoreSuite/TestPackerInitWithNonGithubSource/try_installing_from_a_non-github_source,_should_fail (0.07s)
        --- PASS: Test_PackerCoreSuite/TestPackerInitWithNonGithubSource/manually_install_plugin_to_the_expected_source (0.59s)
        --- PASS: Test_PackerCoreSuite/TestPackerInitWithNonGithubSource/re-run_packer_init_on_same_template,_should_succeed_silently (0.55s)
```
2024-06-10 09:59:32 -04:00
Lucas Bajolet 19594be808 packer_test: add test with both pre/meta in plugin
To make sure we do scrub the metadata in the plugin name when installing
it from a local binary, we add a test that does that installation with
both alternatives: 1.0.0-dev and 1.0.0-dev+metadata, which should result
in only one alternative being installed (the last one that succeeded).
2024-06-10 09:59:32 -04:00
Lucas Bajolet 51cdd9c4a9 packer_test: amend installation with meta test
The installation with a metadata part in the version for a plugin had
one test that relied on the plugin directories being populated with
packer plugins install --path.
This could change in the future, while the command should remain
functional, so we explicitely call it in the test instead of through the
function that creates/populates a temp plugin dir.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 3661d97fc0 packer_test: add convenience func for line count
When building a pipeline to count the number of lines returned by
Packer, it can be a bit cumbersome to have to chain the calls to
MkPipeCheck to do that check, so we add one convenience function for the
simplest case: counting the number of lines on stdout, without any kind
of filtering.
2024-06-10 09:59:32 -04:00
Wilken Rivera c6388d4680 packer_test: Add tests for invalid plugin remove use cases 2024-06-10 09:59:32 -04:00
Wilken Rivera 1cace90289 packer_test: Add tests for valid plugin remove use cases 2024-06-10 09:59:32 -04:00
Lucas Bajolet 9f7098b230 packer_test: fix typo in error message for cleanup 2024-06-10 09:59:32 -04:00
Lucas Bajolet a2e08329a3 packer_test: fix shasum file name for tests
When manually installing a plugin to the plugin directory, we compute a
SHA256SUM file from the plugin binary, and install it alongside it so we
can test the loading process for Packer.

In the introduction of the function, we added a check that if we were
running on Windows, we'd remove the extension of the sumfile's name
before writing it.

This is actually not necessary (and breaks the loading logic) as Packer
looks for the name of the plugin with extension, followed by
_SHA256SUM in order to compare the effective digest of the file to the
one written to this file.

Since this prevents the tests that use this function from succeeding in
a Windows environment, we remove this extra step.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 2a414af35f packer_test: set TMP envvar for commands
Windows relies on the `TMP` (or alternatives) being set in the
environment in order to be able to create temporary directories and
files.

If this is not set, the `os.TempDir` function defaults on the windows
installation root directory (typically C:\Windows), leading to
permission errors when running Packer in the context of a test, as we're
installing plugins in a temporary directory.

To avoid this problem, we get the current setting from the test's
invocation environment, and forward it to the subcommand we execute for
our tests.
2024-06-10 09:59:32 -04:00
Lucas Bajolet f77da46b3f packer_test: compile packer with .exe for Windows
Since on Windows extensions are mandatory in order to have something
executable, we compile Packer with a `.exe` suffix during tests, so we
can use the executable afterwards to run tests with.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 7124cf81fa packer_test: test build/validate with ignore flag
As we're introducing a --ignore-prerelease-plugins flag to both the
validate and build subcommands, we need to make sure they work as we
expect it to, so we add a test case for that.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 66e70a863d packer_test: add test for plugin with meta in name
Plugins with metadata information in their file name (i.e.
v1.0.0+metadata) should be ignored by Packer as they could introduce
ambiguity since the metadata is free-form, so we add that test to make
sure Packer behaves coherently.
2024-06-10 09:59:32 -04:00
Lucas Bajolet a49da98350 packer_test: test non-canonical plugin loading
If a plugin is installed with a non-canonical version in its name (e.g.
01.01.01), Packer rejects it with a message to that effect in stderr, so
we add a test for this use-case.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 707e40e2e6 packer_test: add func for "manual" plugin install
Installing a plugin manually to a directory is something needed for some
tests, especially those not relying on packer commands to install
plugins as they reject/correct the path/version.

Therefore this function is introduced so we have an easy way to install
a binary as a plugin somewhere on the provided plugin directory.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 901f31ad82 packer_test: fix ExpectedName to not clean version
The ExpectedInstalledName function used to compute the expected name of
a plugin binary for a given version, based on the invoker's environment,
used to cleanup the version string passed in parameter of the function,
which could be problematic.
Besides the logic applied would produce some invalid binary names as the
prerelease plugin would not have a `-` separator, so the resulting
plugin would be ignored, and we couldn't test metadata rejection with
this logic.

This commit therefore changes how the function works: the version string
is still parsed to account for manipulation errors, but the string is
left as-is for the final binary name.
2024-06-10 09:59:32 -04:00
Lucas Bajolet 7e0b27adaa packer_test: add init test on non-gh source URI 2024-06-10 09:59:32 -04:00
Lucas Bajolet 4e20956bae packer_test: don't error on empty pipeline
If for some reason we only want to run a test on either stream without
doing some manipulation beforehand, we can run a PipeChecker, however
these would error if no pipe gadget was defined, preventing this
use-case.

Instead of errorring then, this commit just ignores if no pipe is
present, as none is required for the test to run.
2024-06-10 09:59:32 -04:00