diff --git a/packer_test/common/commands.go b/packer_test/common/commands.go index 1002aad61c6..869a6b27811 100644 --- a/packer_test/common/commands.go +++ b/packer_test/common/commands.go @@ -66,8 +66,14 @@ func (pc *packerCommand) SetWD(dir string) *packerCommand { } // UsePluginDir sets the plugin directory in the environment to `dir` -func (pc *packerCommand) UsePluginDir(dir string) *packerCommand { - return pc.AddEnv("PACKER_PLUGIN_PATH", dir) +func (pc *packerCommand) UsePluginDir(dir *PluginDirSpec) *packerCommand { + return pc.UseRawPluginDir(dir.dirPath) +} + +// UseRawPluginDir is meant to be used for setting the plugin directory with a +// raw directory path instead of a PluginDirSpec. +func (pc *packerCommand) UseRawPluginDir(dirPath string) *packerCommand { + return pc.AddEnv("PACKER_PLUGIN_PATH", dirPath) } func (pc *packerCommand) SetArgs(args ...string) *packerCommand { diff --git a/packer_test/common/plugin.go b/packer_test/common/plugin.go index 10a7b473031..2e0a3b5bebc 100644 --- a/packer_test/common/plugin.go +++ b/packer_test/common/plugin.go @@ -125,6 +125,11 @@ func (ts *PackerTestSuite) CompilePlugin(t *testing.T, versionString string) { ts.compiledPlugins.Store(v.String(), outBin) } +type PluginDirSpec struct { + dirPath string + suite *PackerTestSuite +} + // MakePluginDir installs a list of plugins into a temporary directory and returns its path // // This can be set in the environment for a test through a function like t.SetEnv(), so @@ -134,45 +139,68 @@ func (ts *PackerTestSuite) CompilePlugin(t *testing.T, versionString string) { // // Note: all of the plugin versions specified to be installed in this plugin directory // must have been compiled beforehand. -func (ts *PackerTestSuite) MakePluginDir(pluginVersions ...string) (pluginTempDir string, cleanup func()) { - t := ts.T() +func (ts *PackerTestSuite) MakePluginDir() *PluginDirSpec { + var err error + + pluginTempDir, err := os.MkdirTemp("", "packer-plugin-dir-temp-") + if err != nil { + return nil + } - for _, version := range pluginVersions { - _ = ts.GetPluginPath(t, version) + return &PluginDirSpec{ + dirPath: pluginTempDir, + suite: ts, } +} + +// InstallPluginVersions installs several versions of the tester plugin under +// github.com/hashicorp/tester. +// +// Each version of the plugin needs to have been pre-compiled. +// +// If a plugin is missing, the temporary directory will be removed. +func (ps *PluginDirSpec) InstallPluginVersions(pluginVersions ...string) *PluginDirSpec { + t := ps.suite.T() var err error defer func() { - if err != nil { - if pluginTempDir != "" { - os.RemoveAll(pluginTempDir) + if err != nil || t.Failed() { + rmErr := os.RemoveAll(ps.Dir()) + if rmErr != nil { + t.Logf("failed to remove temporary plugin directory %q: %s. This may need manual intervention.", ps.Dir(), err) } - t.Fatalf("failed to prepare temporary plugin directory %q: %s", pluginTempDir, err) + t.Fatalf("failed to install plugins to temporary plugin directory %q: %s", ps.Dir(), err) } }() - pluginTempDir, err = os.MkdirTemp("", "packer-plugin-dir-temp-") - if err != nil { - return - } - for _, pluginVersion := range pluginVersions { - path := ts.GetPluginPath(t, pluginVersion) - cmd := ts.PackerCommand().SetArgs("plugins", "install", "--path", path, "github.com/hashicorp/tester").AddEnv("PACKER_PLUGIN_PATH", pluginTempDir) + path := ps.suite.GetPluginPath(t, pluginVersion) + cmd := ps.suite.PackerCommand().SetArgs("plugins", "install", "--path", path, "github.com/hashicorp/tester").AddEnv("PACKER_PLUGIN_PATH", ps.Dir()) cmd.Assert(check.MustSucceed()) out, stderr, cmdErr := cmd.run() if cmdErr != nil { err = fmt.Errorf("failed to install tester plugin version %q: %s\nCommand stdout: %s\nCommand stderr: %s", pluginVersion, err, out, stderr) - return } } - return pluginTempDir, func() { - err := os.RemoveAll(pluginTempDir) - if err != nil { - t.Logf("failed to remove temporary plugin directory %q: %s. This may need manual intervention.", pluginTempDir, err) - } + return ps +} + +// Dir returns the temporary plugin dir for use in other functions +func (ps PluginDirSpec) Dir() string { + return ps.dirPath +} + +func (ps *PluginDirSpec) Cleanup() { + pluginDir := ps.Dir() + if pluginDir == "" { + return + } + + err := os.RemoveAll(pluginDir) + if err != nil { + ps.suite.T().Logf("failed to remove temporary plugin directory %q: %s. This may need manual intervention.", pluginDir, err) } } diff --git a/packer_test/core_tests/local_eval_test.go b/packer_test/core_tests/local_eval_test.go index 245fe05777e..bd67da4402d 100644 --- a/packer_test/core_tests/local_eval_test.go +++ b/packer_test/core_tests/local_eval_test.go @@ -9,8 +9,8 @@ import ( func (ts *PackerCoreTestSuite) TestEvalLocalsOrder() { ts.SkipNoAcc() - pluginDir, cleanup := ts.MakePluginDir() - defer cleanup() + pluginDir := ts.MakePluginDir() + defer pluginDir.Cleanup() ts.PackerCommand().UsePluginDir(pluginDir). Runs(10). @@ -21,8 +21,8 @@ func (ts *PackerCoreTestSuite) TestEvalLocalsOrder() { } func (ts *PackerCoreTestSuite) TestLocalDuplicates() { - pluginDir, cleanup := ts.MakePluginDir() - defer cleanup() + pluginDir := ts.MakePluginDir() + defer pluginDir.Cleanup() for _, cmd := range []string{"console", "validate", "build"} { ts.Run(fmt.Sprintf("duplicate local detection with %s command - expect error", cmd), func() { diff --git a/packer_test/plugin_tests/init_test.go b/packer_test/plugin_tests/init_test.go index 31ca8dd7309..ccf60d257f9 100644 --- a/packer_test/plugin_tests/init_test.go +++ b/packer_test/plugin_tests/init_test.go @@ -7,8 +7,8 @@ import ( func (ts *PackerPluginTestSuite) TestPackerInitForce() { ts.SkipNoAcc() - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() ts.Run("installs any missing plugins", func() { ts.PackerCommand().UsePluginDir(pluginPath). @@ -26,8 +26,8 @@ func (ts *PackerPluginTestSuite) TestPackerInitForce() { func (ts *PackerPluginTestSuite) TestPackerInitUpgrade() { ts.SkipNoAcc() - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() cmd := ts.PackerCommand().UsePluginDir(pluginPath) cmd.SetArgs("plugins", "install", "github.com/hashicorp/hashicups", "1.0.1") @@ -42,8 +42,8 @@ func (ts *PackerPluginTestSuite) TestPackerInitUpgrade() { } func (ts *PackerPluginTestSuite) TestPackerInitWithNonGithubSource() { - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() ts.Run("try installing from a non-github source, should fail", func() { ts.PackerCommand().UsePluginDir(pluginPath). @@ -68,8 +68,8 @@ func (ts *PackerPluginTestSuite) TestPackerInitWithNonGithubSource() { func (ts *PackerPluginTestSuite) TestPackerInitWithMixedVersions() { ts.SkipNoAcc() - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() ts.Run("skips the plugin installation with mixed versions before exiting with an error", func() { ts.PackerCommand().UsePluginDir(pluginPath). diff --git a/packer_test/plugin_tests/install_test.go b/packer_test/plugin_tests/install_test.go index 5bc8306e5a6..305ed9c28a3 100644 --- a/packer_test/plugin_tests/install_test.go +++ b/packer_test/plugin_tests/install_test.go @@ -3,8 +3,8 @@ package plugin_tests import "github.com/hashicorp/packer/packer_test/common/check" func (ts *PackerPluginTestSuite) TestInstallPluginWithMetadata() { - tempPluginDir, cleanup := ts.MakePluginDir() - defer cleanup() + tempPluginDir := ts.MakePluginDir() + defer tempPluginDir.Cleanup() ts.Run("install plugin with metadata in version", func() { ts.PackerCommand().UsePluginDir(tempPluginDir). @@ -32,8 +32,8 @@ func (ts *PackerPluginTestSuite) TestInstallPluginWithMetadata() { } func (ts *PackerPluginTestSuite) TestInstallPluginWithPath() { - tempPluginDir, cleanup := ts.MakePluginDir() - defer cleanup() + tempPluginDir := ts.MakePluginDir() + defer tempPluginDir.Cleanup() ts.Run("install plugin with pre-release only", func() { ts.PackerCommand().UsePluginDir(tempPluginDir). @@ -60,8 +60,8 @@ func (ts *PackerPluginTestSuite) TestInstallPluginWithPath() { func (ts *PackerPluginTestSuite) TestInstallPluginPrerelease() { pluginPath := ts.GetPluginPath(ts.T(), "1.0.1-alpha1") - pluginDir, cleanup := ts.MakePluginDir() - defer cleanup() + pluginDir := ts.MakePluginDir() + defer pluginDir.Cleanup() ts.Run("try install plugin with alpha1 prerelease - should fail", func() { ts.PackerCommand().UsePluginDir(pluginDir). @@ -73,8 +73,8 @@ func (ts *PackerPluginTestSuite) TestInstallPluginPrerelease() { func (ts *PackerPluginTestSuite) TestRemoteInstallWithPluginsInstall() { ts.SkipNoAcc() - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() ts.Run("install latest version of a remote plugin with packer plugins install", func() { ts.PackerCommand().UsePluginDir(pluginPath). @@ -86,8 +86,8 @@ func (ts *PackerPluginTestSuite) TestRemoteInstallWithPluginsInstall() { func (ts *PackerPluginTestSuite) TestRemoteInstallOfPreReleasePlugin() { ts.SkipNoAcc() - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() ts.Run("try to init with a pre-release constraint - should fail", func() { ts.PackerCommand().UsePluginDir(pluginPath). diff --git a/packer_test/plugin_tests/loading_test.go b/packer_test/plugin_tests/loading_test.go index fa13ac02704..c3e87f0e7fa 100644 --- a/packer_test/plugin_tests/loading_test.go +++ b/packer_test/plugin_tests/loading_test.go @@ -11,8 +11,8 @@ import ( ) func (ts *PackerPluginTestSuite) TestLoadingOrder() { - pluginDir, cleanup := ts.MakePluginDir("1.0.9", "1.0.10") - defer cleanup() + pluginDir := ts.MakePluginDir().InstallPluginVersions("1.0.9", "1.0.10") + defer pluginDir.Cleanup() for _, command := range []string{"build", "validate"} { tests := []struct { @@ -49,12 +49,12 @@ func (ts *PackerPluginTestSuite) TestLoadingOrder() { } func (ts *PackerPluginTestSuite) TestLoadWithLegacyPluginName() { - pluginDir, cleanup := ts.MakePluginDir() - defer cleanup() + pluginDir := ts.MakePluginDir() + defer pluginDir.Cleanup() plugin := ts.GetPluginPath(ts.T(), "1.0.10") - common.CopyFile(ts.T(), filepath.Join(pluginDir, "packer-plugin-tester"), plugin) + common.CopyFile(ts.T(), filepath.Join(pluginDir.Dir(), "packer-plugin-tester"), plugin) ts.Run("only legacy plugins installed: expect build to fail", func() { ts.Run("with required_plugins - expect prompt for packer init", func() { @@ -73,10 +73,10 @@ func (ts *PackerPluginTestSuite) TestLoadWithLegacyPluginName() { }) }) - pluginDir, cleanup = ts.MakePluginDir("1.0.0") - defer cleanup() + pluginDir = ts.MakePluginDir().InstallPluginVersions("1.0.0") + defer pluginDir.Cleanup() - common.CopyFile(ts.T(), filepath.Join(pluginDir, "packer-plugin-tester"), plugin) + common.CopyFile(ts.T(), filepath.Join(pluginDir.Dir(), "packer-plugin-tester"), plugin) ts.Run("multiple plugins installed: one with no version in path, one with qualified name. Should pick-up the qualified one only.", func() { ts.PackerCommand().UsePluginDir(pluginDir). @@ -100,12 +100,12 @@ func (ts *PackerPluginTestSuite) TestLoadWithSHAMismatches() { plugin := ts.GetPluginPath(ts.T(), "1.0.10") ts.Run("move plugin with right name, but no SHA256SUM, should reject", func() { - pluginDir, cleanup := ts.MakePluginDir("1.0.9") - defer cleanup() + pluginDir := ts.MakePluginDir().InstallPluginVersions("1.0.9") + defer pluginDir.Cleanup() pluginDestName := common.ExpectedInstalledName("1.0.10") - common.CopyFile(ts.T(), filepath.Join(pluginDir, "github.com", "hashicorp", "tester", pluginDestName), plugin) + common.CopyFile(ts.T(), filepath.Join(pluginDir.Dir(), "github.com", "hashicorp", "tester", pluginDestName), plugin) ts.PackerCommand().UsePluginDir(pluginDir). SetArgs("plugins", "installed"). @@ -116,13 +116,13 @@ func (ts *PackerPluginTestSuite) TestLoadWithSHAMismatches() { }) ts.Run("move plugin with right name, invalid SHA256SUM, should reject", func() { - pluginDir, cleanup := ts.MakePluginDir("1.0.9") - defer cleanup() + pluginDir := ts.MakePluginDir().InstallPluginVersions("1.0.9") + defer pluginDir.Cleanup() pluginDestName := common.ExpectedInstalledName("1.0.10") - common.CopyFile(ts.T(), filepath.Join(pluginDir, "github.com", "hashicorp", "tester", pluginDestName), plugin) + common.CopyFile(ts.T(), filepath.Join(pluginDir.Dir(), "github.com", "hashicorp", "tester", pluginDestName), plugin) common.WriteFile(ts.T(), - filepath.Join(pluginDir, "github.com", "hashicorp", "tester", fmt.Sprintf("%s_SHA256SUM", pluginDestName)), + filepath.Join(pluginDir.Dir(), "github.com", "hashicorp", "tester", fmt.Sprintf("%s_SHA256SUM", pluginDestName)), fmt.Sprintf("%x", sha256.New().Sum([]byte("Not the plugin's contents for sure.")))) ts.PackerCommand().UsePluginDir(pluginDir). @@ -136,15 +136,15 @@ func (ts *PackerPluginTestSuite) TestLoadWithSHAMismatches() { } func (ts *PackerPluginTestSuite) TestPluginPathEnvvarWithMultiplePaths() { - pluginDirOne, cleanup := ts.MakePluginDir("1.0.10") - defer cleanup() + pluginDirOne := ts.MakePluginDir().InstallPluginVersions("1.0.10") + defer pluginDirOne.Cleanup() - pluginDirTwo, cleanup := ts.MakePluginDir("1.0.9") - defer cleanup() + pluginDirTwo := ts.MakePluginDir().InstallPluginVersions("1.0.9") + defer pluginDirTwo.Cleanup() - pluginDirVal := fmt.Sprintf("%s%c%s", pluginDirOne, os.PathListSeparator, pluginDirTwo) + pluginDirVal := fmt.Sprintf("%s%c%s", pluginDirOne.Dir(), os.PathListSeparator, pluginDirTwo.Dir()) ts.Run("load plugin with two dirs - not supported anymore, should error", func() { - ts.PackerCommand().UsePluginDir(pluginDirVal). + ts.PackerCommand().UseRawPluginDir(pluginDirVal). SetArgs("plugins", "installed"). Assert(check.MustFail(), check.Grep("Multiple paths are no longer supported for PACKER_PLUGIN_PATH"), @@ -157,11 +157,11 @@ func (ts *PackerPluginTestSuite) TestPluginPathEnvvarWithMultiplePaths() { } func (ts *PackerPluginTestSuite) TestInstallNonCanonicalPluginVersion() { - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() common.ManualPluginInstall(ts.T(), - filepath.Join(pluginPath, "github.com", "hashicorp", "tester"), + filepath.Join(pluginPath.Dir(), "github.com", "hashicorp", "tester"), ts.GetPluginPath(ts.T(), "1.0.10"), "001.00.010") @@ -175,11 +175,11 @@ func (ts *PackerPluginTestSuite) TestInstallNonCanonicalPluginVersion() { } func (ts *PackerPluginTestSuite) TestLoadPluginWithMetadataInName() { - pluginPath, cleanup := ts.MakePluginDir() - defer cleanup() + pluginPath := ts.MakePluginDir() + defer pluginPath.Cleanup() common.ManualPluginInstall(ts.T(), - filepath.Join(pluginPath, "github.com", "hashicorp", "tester"), + filepath.Join(pluginPath.Dir(), "github.com", "hashicorp", "tester"), ts.GetPluginPath(ts.T(), "1.0.10+metadata"), "1.0.10+metadata") @@ -193,8 +193,8 @@ func (ts *PackerPluginTestSuite) TestLoadPluginWithMetadataInName() { } func (ts *PackerPluginTestSuite) TestLoadWithOnlyReleaseFlag() { - pluginPath, cleanup := ts.MakePluginDir("1.0.0", "1.0.1-dev") - defer cleanup() + pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.0", "1.0.1-dev") + defer pluginPath.Cleanup() for _, cmd := range []string{"validate", "build"} { ts.Run(fmt.Sprintf("run %s without --ignore-prerelease flag - pick 1.0.1-dev by default", cmd), func() { @@ -214,8 +214,8 @@ func (ts *PackerPluginTestSuite) TestLoadWithOnlyReleaseFlag() { } func (ts *PackerPluginTestSuite) TestWithLegacyConfigAndComponents() { - pluginDir, cleanup := ts.MakePluginDir("1.0.0") - defer cleanup() + pluginDir := ts.MakePluginDir().InstallPluginVersions("1.0.0") + defer pluginDir.Cleanup() workdir, cleanup := common.TempWorkdir(ts.T(), "./sample_config.json", "./templates/simple.json", "./templates/simple.pkr.hcl") defer cleanup() diff --git a/packer_test/plugin_tests/plugins_remove_test.go b/packer_test/plugin_tests/plugins_remove_test.go index fcaad4459e0..d130a592162 100644 --- a/packer_test/plugin_tests/plugins_remove_test.go +++ b/packer_test/plugin_tests/plugins_remove_test.go @@ -8,11 +8,11 @@ import ( ) func (ts *PackerPluginTestSuite) TestPluginsRemoveWithSourceAddress() { - pluginPath, cleanup := ts.MakePluginDir("1.0.9", "1.0.10", "2.0.0") - defer cleanup() + pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9", "1.0.10", "2.0.0") + defer pluginPath.Cleanup() // Get installed plugins - if n := InstalledPlugins(ts, pluginPath); len(n) != 3 { + if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 3 { ts.T().Fatalf("Expected there to be 3 installed plugins but we got %v", n) } @@ -27,7 +27,7 @@ func (ts *PackerPluginTestSuite) TestPluginsRemoveWithSourceAddress() { }) // Get installed plugins after removal - if n := InstalledPlugins(ts, pluginPath); len(n) != 0 { + if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 0 { ts.T().Fatalf("Expected there to be 0 installed plugins but we got %v", n) } @@ -51,11 +51,11 @@ func (ts *PackerPluginTestSuite) TestPluginsRemoveWithSourceAddress() { } func (ts *PackerPluginTestSuite) TestPluginsRemoveWithSourceAddressAndVersion() { - pluginPath, cleanup := ts.MakePluginDir("1.0.9", "1.0.10", "2.0.0") - defer cleanup() + pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9", "1.0.10", "2.0.0") + defer pluginPath.Cleanup() // Get installed plugins - if n := InstalledPlugins(ts, pluginPath); len(n) != 3 { + if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 3 { ts.T().Fatalf("Expected there to be 3 installed plugins but we got %v", n) } @@ -77,17 +77,17 @@ func (ts *PackerPluginTestSuite) TestPluginsRemoveWithSourceAddressAndVersion() }) // Get installed plugins after removal - if n := InstalledPlugins(ts, pluginPath); len(n) != 2 { + if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 2 { ts.T().Fatalf("Expected there to be 2 installed plugins but we got %v", n) } } func (ts *PackerPluginTestSuite) TestPluginsRemoveWithLocalPath() { - pluginPath, cleanup := ts.MakePluginDir("1.0.9", "1.0.10") - defer cleanup() + pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9", "1.0.10") + defer pluginPath.Cleanup() // Get installed plugins - plugins := InstalledPlugins(ts, pluginPath) + plugins := InstalledPlugins(ts, pluginPath.Dir()) if len(plugins) != 2 { ts.T().Fatalf("Expected there to be 2 installed plugins but we got %v", len(plugins)) } @@ -112,7 +112,7 @@ func (ts *PackerPluginTestSuite) TestPluginsRemoveWithLocalPath() { }) // Get installed plugins after removal - if n := InstalledPlugins(ts, pluginPath); len(n) != 1 { + if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 1 { ts.T().Fatalf("Expected there to be 1 installed plugins but we got %v", n) } @@ -136,11 +136,11 @@ func (ts *PackerPluginTestSuite) TestPluginsRemoveWithLocalPath() { } func (ts *PackerPluginTestSuite) TestPluginsRemoveWithNoArguments() { - pluginPath, cleanup := ts.MakePluginDir("1.0.9") - defer cleanup() + pluginPath := ts.MakePluginDir().InstallPluginVersions("1.0.9") + defer pluginPath.Cleanup() // Get installed plugins - if n := InstalledPlugins(ts, pluginPath); len(n) != 1 { + if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 1 { ts.T().Fatalf("Expected there to be 1 installed plugins but we got %v", n) } @@ -154,7 +154,7 @@ func (ts *PackerPluginTestSuite) TestPluginsRemoveWithNoArguments() { }) // Get installed should remain the same - if n := InstalledPlugins(ts, pluginPath); len(n) != 1 { + if n := InstalledPlugins(ts, pluginPath.Dir()); len(n) != 1 { ts.T().Fatalf("Expected there to be 1 installed plugins but we got %v", n) } @@ -163,7 +163,7 @@ func (ts *PackerPluginTestSuite) TestPluginsRemoveWithNoArguments() { func InstalledPlugins(ts *PackerPluginTestSuite, dir string) []string { ts.T().Helper() - cmd := ts.PackerCommand().UsePluginDir(dir). + cmd := ts.PackerCommand().UseRawPluginDir(dir). SetArgs("plugins", "installed"). SetAssertFatal() cmd.Assert(check.MustSucceed())