Skip to content

Commit

Permalink
packer_test: make PluginTestDir a structure
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lbajolet-hashicorp committed Sep 12, 2024
1 parent 31b6109 commit 3c44943
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 93 deletions.
10 changes: 8 additions & 2 deletions packer_test/common/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
70 changes: 49 additions & 21 deletions packer_test/common/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
}

Expand Down
8 changes: 4 additions & 4 deletions packer_test/core_tests/local_eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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() {
Expand Down
16 changes: 8 additions & 8 deletions packer_test/plugin_tests/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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")
Expand All @@ -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).
Expand All @@ -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).
Expand Down
20 changes: 10 additions & 10 deletions packer_test/plugin_tests/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -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).
Expand All @@ -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).
Expand All @@ -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).
Expand All @@ -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).
Expand Down
62 changes: 31 additions & 31 deletions packer_test/plugin_tests/loading_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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() {
Expand All @@ -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).
Expand All @@ -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").
Expand All @@ -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).
Expand All @@ -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"),
Expand All @@ -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")

Expand All @@ -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")

Expand All @@ -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() {
Expand All @@ -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()
Expand Down
Loading

0 comments on commit 3c44943

Please sign in to comment.