mirror of
https://github.com/hashicorp/packer.git
synced 2026-06-09 16:50:08 -04:00
Compiling plugins was originally intended to be an idempotent operation. This however starts to change as we introduce build customisations, which have the unfortunate side-effect of changing the state of the plugin directory, leading to conflicts between concurrent compilation jobs. Therefore to mitigate this problem, this commit changes how compilation jobs are processed, by introducing a global compilation queue, and processing plugins' compilation one-by-one from this queue. This however makes such requests asynchronous, so test suites that require plugins to be compiled will now have to wait on their completion before they can start their tests. To this effect, we introduce one more convenience function that processes those errors, and automatically fails the test should one compilation job fail for any reason.
95 lines
2.7 KiB
Go
95 lines
2.7 KiB
Go
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
type PackerTestSuite struct {
|
|
suite.Suite
|
|
// pluginsDirectory is the directory in which plugins are compiled.
|
|
//
|
|
// Those binaries are not necessarily meant to be used as-is, but
|
|
// instead should be used for composing plugin installation directories.
|
|
pluginsDirectory string
|
|
// packerPath is the location in which the Packer executable is compiled
|
|
//
|
|
// Since we don't necessarily want to manually compile Packer beforehand,
|
|
// we compile it on demand, and use this executable for the tests.
|
|
packerPath string
|
|
// compiledPlugins is the map of each compiled plugin to its path.
|
|
//
|
|
// This used to be global, but should be linked to the suite instead, as
|
|
// we may have multiple suites that exist, each with its own repo of
|
|
// plugins compiled for the purposes of the test, so as they all run
|
|
// within the same process space, they should be separate instances.
|
|
compiledPlugins sync.Map
|
|
}
|
|
|
|
// CompileTestPluginVersions batch compiles a series of plugins
|
|
func (ts *PackerTestSuite) CompileTestPluginVersions(t *testing.T, versions ...string) {
|
|
results := []chan CompilationResult{}
|
|
for _, ver := range versions {
|
|
results = append(results, ts.CompilePlugin(ver))
|
|
}
|
|
|
|
Ready(t, results)
|
|
}
|
|
|
|
// SkipNoAcc is a pre-condition that skips the test if the PACKER_ACC environment
|
|
// variable is unset, or set to "0".
|
|
//
|
|
// This allows us to build tests with a potential for long runs (or errors like
|
|
// rate-limiting), so we can still test them, but only in a longer timeouted
|
|
// context.
|
|
func (ts *PackerTestSuite) SkipNoAcc() {
|
|
acc := os.Getenv("PACKER_ACC")
|
|
if acc == "" || acc == "0" {
|
|
ts.T().Logf("Skipping test as `PACKER_ACC` is unset.")
|
|
ts.T().Skip()
|
|
}
|
|
}
|
|
|
|
func InitBaseSuite(t *testing.T) (*PackerTestSuite, func()) {
|
|
ts := &PackerTestSuite{
|
|
compiledPlugins: sync.Map{},
|
|
}
|
|
|
|
tempDir, err := os.MkdirTemp("", "packer-core-acc-test-")
|
|
if err != nil {
|
|
panic(fmt.Sprintf("failed to create temporary directory for compiled plugins: %s", err))
|
|
}
|
|
ts.pluginsDirectory = tempDir
|
|
|
|
packerPath := os.Getenv("PACKER_CUSTOM_PATH")
|
|
if packerPath == "" {
|
|
var err error
|
|
t.Logf("Building test packer binary...")
|
|
packerPath, err = BuildTestPacker(t)
|
|
if err != nil {
|
|
t.Fatalf("failed to build Packer binary: %s", err)
|
|
}
|
|
}
|
|
ts.packerPath = packerPath
|
|
t.Logf("Done")
|
|
|
|
return ts, func() {
|
|
err := os.RemoveAll(ts.pluginsDirectory)
|
|
if err != nil {
|
|
t.Logf("failed to cleanup directory %q: %s. This will need manual action", ts.pluginsDirectory, err)
|
|
}
|
|
|
|
if os.Getenv("PACKER_CUSTOM_PATH") != "" {
|
|
return
|
|
}
|
|
|
|
err = os.Remove(ts.packerPath)
|
|
if err != nil {
|
|
t.Logf("failed to cleanup compiled packer binary %q: %s. This will need manual action", packerPath, err)
|
|
}
|
|
}
|
|
}
|