packer-cn/helper/tests/acc/provisioners.go

152 lines
4.3 KiB
Go

package acc
import (
"bytes"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"testing"
testshelper "github.com/hashicorp/packer/helper/tests"
amazonEBS "github.com/hashicorp/packer/builder/amazon/ebs/acceptance"
virtualboxISO "github.com/hashicorp/packer/builder/virtualbox/iso/acceptance"
"github.com/hashicorp/packer/command"
"github.com/hashicorp/packer/packer"
)
func TestProvisionersAgainstBuilders(provisionerAcc ProvisionerAcceptance, t *testing.T) {
provisioner := provisionerAcc.GetName()
builders := checkBuilders(t)
// build template file and run a build for each builder with the provisioner
for _, builder := range builders {
builderAcc := BuildersAccTest[builder]
builderConfigs, err := builderAcc.GetConfigs()
if err != nil {
t.Fatalf("bad: failed to read builder config: %s", err.Error())
}
for vmOS, builderConfig := range builderConfigs {
if !provisionerAcc.IsCompatible(builder, vmOS) {
continue
}
testName := fmt.Sprintf("testing %s builder against %s provisioner", builder, provisioner)
t.Run(testName, func(t *testing.T) {
provisionerConfig, err := provisionerAcc.GetConfig()
if err != nil {
t.Fatalf("bad: failed to read provisioner config: %s", err.Error())
}
// Write json template
out := bytes.NewBuffer(nil)
fmt.Fprintf(out, `{"builders": [%s],"provisioners": [%s]}`, builderConfig, provisionerConfig)
fileName := fmt.Sprintf("%s_%s.json", builder, provisioner)
filePath := filepath.Join("./", fileName)
writeJsonTemplate(out, filePath, t)
// set pre-config with necessary builder and provisioner
c := buildCommand(t, builderAcc, provisionerAcc)
args := []string{
filePath,
}
err = provisionerAcc.RunTest(c, args)
// Cleanup created resources
testshelper.CleanupFiles(fileName)
cleanErr := builderAcc.CleanUp()
if cleanErr != nil {
log.Printf("bad: failed to clean up resources: %s", cleanErr.Error())
}
if err != nil {
t.Fatalf("bad: failed to to run build: %s", err.Error())
}
})
}
}
}
// TestProvisionersPreCheck checks if the Provisioner with name is set in ACC_TEST_PROVISIONERS environment variable
func TestProvisionersPreCheck(name string, t *testing.T) {
p := os.Getenv("ACC_TEST_PROVISIONERS")
if p == "all" {
return
}
provisioners := strings.Split(p, ",")
for _, provisioner := range provisioners {
if provisioner == name {
return
}
}
msg := fmt.Sprintf("Provisioner %q not defined in ACC_TEST_PROVISIONERS", name)
t.Skip(msg)
}
func checkBuilders(t *testing.T) []string {
b := os.Getenv("ACC_TEST_BUILDERS")
// validate if we want to run provisioners acc tests
if b == "" {
t.Skip("Provisioners Acceptance tests skipped unless env 'ACC_TEST_BUILDERS' is set")
}
// Get builders type to test provisioners against
var builders []string
for k := range BuildersAccTest {
// This will validate that only defined builders are executed against
if b != "all" && !strings.Contains(b, k) {
continue
}
builders = append(builders, k)
}
return builders
}
func writeJsonTemplate(out *bytes.Buffer, filePath string, t *testing.T) {
outputFile, err := os.Create(filePath)
if err != nil {
t.Fatalf("bad: failed to create template file: %s", err.Error())
}
_, err = outputFile.Write(out.Bytes())
if err != nil {
t.Fatalf("bad: failed to write template file: %s", err.Error())
}
outputFile.Sync()
}
func buildCommand(t *testing.T, builder BuilderAcceptance, provisioner ProvisionerAcceptance) *command.BuildCommand {
c := &command.BuildCommand{
Meta: testshelper.TestMetaFile(t),
}
c.CoreConfig.Components.BuilderStore = builder.GetBuilderStore()
c.CoreConfig.Components.ProvisionerStore = provisioner.GetProvisionerStore()
return c
}
type ProvisionerAcceptance interface {
GetName() string
GetConfig() (string, error)
GetProvisionerStore() packer.MapOfProvisioner
IsCompatible(builder string, vmOS string) bool
RunTest(c *command.BuildCommand, args []string) error
}
type BuilderAcceptance interface {
GetConfigs() (map[string]string, error)
GetBuilderStore() packer.MapOfBuilder
CleanUp() error
}
// List of all builders available for acceptance test
var BuildersAccTest = map[string]BuilderAcceptance{
"virtualbox-iso": new(virtualboxISO.VirtualBoxISOAccTest),
"amazon-ebs": new(amazonEBS.AmazonEBSAccTest),
}