2024-06-12 15:38:21 -04:00
|
|
|
package plugin_tests
|
2024-05-16 09:21:46 -04:00
|
|
|
|
|
|
|
|
import (
|
2024-05-16 09:48:23 -04:00
|
|
|
"path/filepath"
|
2024-05-16 09:21:46 -04:00
|
|
|
"strings"
|
2024-06-12 15:38:21 -04:00
|
|
|
|
2024-08-15 10:05:27 -04:00
|
|
|
"github.com/hashicorp/packer/packer_test/common/check"
|
2024-05-16 09:21:46 -04:00
|
|
|
)
|
|
|
|
|
|
2024-06-12 15:38:21 -04:00
|
|
|
func (ts *PackerPluginTestSuite) TestPluginsRemoveWithSourceAddress() {
|
2024-08-15 14:09:33 -04:00
|
|
|
pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9", "1.0.10", "2.0.0")
|
|
|
|
|
defer pluginPath.Cleanup()
|
2024-05-16 09:21:46 -04:00
|
|
|
|
|
|
|
|
// Get installed plugins
|
2024-08-15 14:09:33 -04:00
|
|
|
if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 3 {
|
2024-05-16 09:21:46 -04:00
|
|
|
ts.T().Fatalf("Expected there to be 3 installed plugins but we got %v", n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ts.Run("plugins remove with source address removes all installed plugin versions", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove", "github.com/hashicorp/tester").
|
2024-08-15 10:05:27 -04:00
|
|
|
Assert(check.MustSucceed(),
|
|
|
|
|
check.Grep("packer-plugin-tester_v1.0.9", check.GrepStdout),
|
|
|
|
|
check.Grep("packer-plugin-tester_v1.0.10", check.GrepStdout),
|
|
|
|
|
check.Grep("packer-plugin-tester_v2.0.0", check.GrepStdout),
|
2024-05-16 09:21:46 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Get installed plugins after removal
|
2024-08-15 14:09:33 -04:00
|
|
|
if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 0 {
|
2024-05-16 09:21:46 -04:00
|
|
|
ts.T().Fatalf("Expected there to be 0 installed plugins but we got %v", n)
|
|
|
|
|
}
|
2024-05-16 09:48:23 -04:00
|
|
|
|
|
|
|
|
ts.Run("plugins remove with incorrect source address exits non found error", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove", "github.com/hashicorp/testerONE").
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustFail(),
|
|
|
|
|
check.Grep("No installed plugin found matching the plugin constraints github.com/hashicorp/testerONE"),
|
2024-05-16 09:48:23 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ts.Run("plugins remove with invalid source address exits with non-zero code", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove", "github.com/hashicorp/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/tester").
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustFail(),
|
|
|
|
|
check.Grep("The source URL must have at most 16 components"),
|
2024-05-16 09:48:23 -04:00
|
|
|
)
|
|
|
|
|
})
|
2024-05-16 09:21:46 -04:00
|
|
|
}
|
|
|
|
|
|
2024-06-12 15:38:21 -04:00
|
|
|
func (ts *PackerPluginTestSuite) TestPluginsRemoveWithSourceAddressAndVersion() {
|
2024-08-15 14:09:33 -04:00
|
|
|
pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9", "1.0.10", "2.0.0")
|
|
|
|
|
defer pluginPath.Cleanup()
|
2024-05-16 09:21:46 -04:00
|
|
|
|
|
|
|
|
// Get installed plugins
|
2024-08-15 14:09:33 -04:00
|
|
|
if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 3 {
|
2024-05-16 09:21:46 -04:00
|
|
|
ts.T().Fatalf("Expected there to be 3 installed plugins but we got %v", n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ts.Run("plugins remove with source address and version removes only the versioned plugin", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove", "github.com/hashicorp/tester", ">= 2.0.0").
|
2024-08-15 10:05:27 -04:00
|
|
|
Assert(check.MustSucceed(), check.Grep("packer-plugin-tester_v2.0.0", check.GrepStdout))
|
2024-05-16 09:21:46 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ts.Run("plugins installed after single plugins remove outputs remaining installed plugins", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "installed").
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustSucceed(),
|
|
|
|
|
check.Grep("packer-plugin-tester_v1.0.9", check.GrepStdout),
|
|
|
|
|
check.Grep("packer-plugin-tester_v1.0.10", check.GrepStdout),
|
|
|
|
|
check.GrepInverted("packer-plugin-tester_v2.0.0", check.GrepStdout),
|
2024-05-16 09:21:46 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Get installed plugins after removal
|
2024-08-15 14:09:33 -04:00
|
|
|
if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 2 {
|
2024-05-16 09:21:46 -04:00
|
|
|
ts.T().Fatalf("Expected there to be 2 installed plugins but we got %v", n)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-12 15:38:21 -04:00
|
|
|
func (ts *PackerPluginTestSuite) TestPluginsRemoveWithLocalPath() {
|
2024-08-15 14:09:33 -04:00
|
|
|
pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9", "1.0.10")
|
|
|
|
|
defer pluginPath.Cleanup()
|
2024-05-16 09:21:46 -04:00
|
|
|
|
|
|
|
|
// Get installed plugins
|
2024-08-15 14:09:33 -04:00
|
|
|
plugins := InstalledPlugins(ts, pluginPath.Dir())
|
2024-05-16 09:21:46 -04:00
|
|
|
if len(plugins) != 2 {
|
|
|
|
|
ts.T().Fatalf("Expected there to be 2 installed plugins but we got %v", len(plugins))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ts.Run("plugins remove with a local path removes only the specified plugin", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove", plugins[0]).
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustSucceed(),
|
|
|
|
|
check.Grep("packer-plugin-tester_v1.0.9", check.GrepStdout),
|
|
|
|
|
check.GrepInverted("packer-plugin-tester_v1.0.10", check.GrepStdout),
|
2024-05-16 09:21:46 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
ts.Run("plugins installed after calling plugins remove outputs remaining installed plugins", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "installed").
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustSucceed(),
|
|
|
|
|
check.Grep("packer-plugin-tester_v1.0.10", check.GrepStdout),
|
|
|
|
|
check.GrepInverted("packer-plugin-tester_v1.0.9", check.GrepStdout),
|
2024-05-16 09:21:46 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Get installed plugins after removal
|
2024-08-15 14:09:33 -04:00
|
|
|
if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 1 {
|
2024-05-16 09:21:46 -04:00
|
|
|
ts.T().Fatalf("Expected there to be 1 installed plugins but we got %v", n)
|
|
|
|
|
}
|
2024-05-16 09:48:23 -04:00
|
|
|
|
|
|
|
|
ts.Run("plugins remove with incomplete local path exits with a non-zero code", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove", filepath.Base(plugins[0])).
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustFail(),
|
|
|
|
|
check.Grep("A source URL must at least contain a host and a path with 2 components", check.GrepStdout),
|
2024-05-16 09:48:23 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ts.Run("plugins remove with fake local path exits with a non-zero code", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove", ts.T().TempDir()).
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustFail(),
|
|
|
|
|
check.Grep("is not under the plugin directory inferred by Packer", check.GrepStdout),
|
2024-05-16 09:48:23 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-12 15:38:21 -04:00
|
|
|
func (ts *PackerPluginTestSuite) TestPluginsRemoveWithNoArguments() {
|
2024-08-15 14:09:33 -04:00
|
|
|
pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9")
|
|
|
|
|
defer pluginPath.Cleanup()
|
2024-05-16 09:48:23 -04:00
|
|
|
|
|
|
|
|
// Get installed plugins
|
2024-08-15 14:09:33 -04:00
|
|
|
if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 1 {
|
2024-05-16 09:48:23 -04:00
|
|
|
ts.T().Fatalf("Expected there to be 1 installed plugins but we got %v", n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ts.Run("plugins remove with no options returns non-zero with help text", func() {
|
|
|
|
|
ts.PackerCommand().UsePluginDir(pluginPath).
|
|
|
|
|
SetArgs("plugins", "remove").
|
|
|
|
|
Assert(
|
2024-08-15 10:05:27 -04:00
|
|
|
check.MustFail(),
|
|
|
|
|
check.Grep("Usage: packer plugins remove <plugin>", check.GrepStdout),
|
2024-05-16 09:48:23 -04:00
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Get installed should remain the same
|
2024-08-15 14:09:33 -04:00
|
|
|
if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 1 {
|
2024-05-16 09:48:23 -04:00
|
|
|
ts.T().Fatalf("Expected there to be 1 installed plugins but we got %v", n)
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 09:21:46 -04:00
|
|
|
}
|
|
|
|
|
|
2024-06-12 15:38:21 -04:00
|
|
|
func InstalledPlugins(ts *PackerPluginTestSuite, dir string) []string {
|
2024-05-16 09:21:46 -04:00
|
|
|
ts.T().Helper()
|
|
|
|
|
|
2024-08-15 14:09:33 -04:00
|
|
|
cmd := ts.PackerCommand().UseRawPluginDir(dir).
|
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:21:35 -04:00
|
|
|
SetArgs("plugins", "installed").
|
|
|
|
|
SetAssertFatal()
|
2024-08-15 10:05:27 -04:00
|
|
|
cmd.Assert(check.MustSucceed())
|
2024-05-16 09:21:46 -04:00
|
|
|
|
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:25:43 -04:00
|
|
|
out, _, _ := cmd.Output()
|
2024-05-16 09:21:46 -04:00
|
|
|
// Output will be split on '\n' after trimming all other white space
|
|
|
|
|
out = strings.TrimSpace(out)
|
|
|
|
|
plugins := strings.Fields(out)
|
|
|
|
|
n := len(plugins)
|
|
|
|
|
if n == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return plugins
|
|
|
|
|
}
|