mirror of
https://github.com/hashicorp/packer.git
synced 2026-06-12 10:10:06 -04:00
Update plugin discover testing
* Add test case for loading plugin in CWD * Add test case to validate checksume files are ignored * Update Discover to include CWD "." in PluginFolders if KnowPluginFolders is unset
This commit is contained in:
parent
a96584fb56
commit
848039dcdb
2 changed files with 244 additions and 183 deletions
|
|
@ -85,7 +85,8 @@ func (c *PluginConfig) Discover() error {
|
|||
}
|
||||
|
||||
if len(c.KnownPluginFolders) == 0 {
|
||||
c.KnownPluginFolders = PluginFolders()
|
||||
//PluginFolders should match the call in github.com/hahicorp/packer/main.go#loadConfig
|
||||
c.KnownPluginFolders = PluginFolders(".")
|
||||
}
|
||||
|
||||
// TODO after JSON is deprecated remove support for legacy component plugins.
|
||||
|
|
|
|||
|
|
@ -154,6 +154,233 @@ func TestDiscoverDatasource(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMultiPlugin_describe(t *testing.T) {
|
||||
createMockPlugins(t, mockPlugins)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s", err.Error())
|
||||
}
|
||||
|
||||
for mockPluginName, plugin := range mockPlugins {
|
||||
for mockBuilderName := range plugin.Builders {
|
||||
expectedBuilderName := mockPluginName + "-" + mockBuilderName
|
||||
|
||||
if !c.Builders.Has(expectedBuilderName) {
|
||||
t.Fatalf("expected to find builder %q", expectedBuilderName)
|
||||
}
|
||||
}
|
||||
for mockProvisionerName := range plugin.Provisioners {
|
||||
expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
|
||||
if !c.Provisioners.Has(expectedProvisionerName) {
|
||||
t.Fatalf("expected to find builder %q", expectedProvisionerName)
|
||||
}
|
||||
}
|
||||
for mockPostProcessorName := range plugin.PostProcessors {
|
||||
expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
|
||||
if !c.PostProcessors.Has(expectedPostProcessorName) {
|
||||
t.Fatalf("expected to find post-processor %q", expectedPostProcessorName)
|
||||
}
|
||||
}
|
||||
for mockDatasourceName := range plugin.Datasources {
|
||||
expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
|
||||
if !c.DataSources.Has(expectedDatasourceName) {
|
||||
t.Fatalf("expected to find datasource %q", expectedDatasourceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiPlugin_describe_installed(t *testing.T) {
|
||||
createMockInstalledPlugins(t, mockInstalledPlugins, createMockChecksumFile)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s", err.Error())
|
||||
}
|
||||
|
||||
for mockPluginName, plugin := range mockInstalledPlugins {
|
||||
mockPluginName = strings.Split(mockPluginName, "_")[0]
|
||||
for mockBuilderName := range plugin.Builders {
|
||||
expectedBuilderName := mockPluginName + "-" + mockBuilderName
|
||||
if !c.Builders.Has(expectedBuilderName) {
|
||||
t.Fatalf("expected to find builder %q", expectedBuilderName)
|
||||
}
|
||||
}
|
||||
for mockProvisionerName := range plugin.Provisioners {
|
||||
expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
|
||||
if !c.Provisioners.Has(expectedProvisionerName) {
|
||||
t.Fatalf("expected to find builder %q", expectedProvisionerName)
|
||||
}
|
||||
}
|
||||
for mockPostProcessorName := range plugin.PostProcessors {
|
||||
expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
|
||||
if !c.PostProcessors.Has(expectedPostProcessorName) {
|
||||
t.Fatalf("expected to find post-processor %q", expectedPostProcessorName)
|
||||
}
|
||||
}
|
||||
for mockDatasourceName := range plugin.Datasources {
|
||||
expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
|
||||
if !c.DataSources.Has(expectedDatasourceName) {
|
||||
t.Fatalf("expected to find datasource %q", expectedDatasourceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiPlugin_describe_installed_for_invalid(t *testing.T) {
|
||||
tc := []struct {
|
||||
desc string
|
||||
installedPluginsMock map[string]pluginsdk.Set
|
||||
createMockFn func(*testing.T, map[string]pluginsdk.Set)
|
||||
}{
|
||||
{
|
||||
desc: "Incorrectly named plugins",
|
||||
installedPluginsMock: invalidInstalledPluginsMock,
|
||||
createMockFn: func(t *testing.T, mocks map[string]pluginsdk.Set) {
|
||||
createMockInstalledPlugins(t, mocks, createMockChecksumFile)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Plugins missing checksums",
|
||||
installedPluginsMock: mockInstalledPlugins,
|
||||
createMockFn: func(t *testing.T, mocks map[string]pluginsdk.Set) {
|
||||
createMockInstalledPlugins(t, mocks)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tc {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
tt.createMockFn(t, tt.installedPluginsMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s", err.Error())
|
||||
}
|
||||
if c.Builders.Has("feather") {
|
||||
t.Fatalf("expected to not find builder %q", "feather")
|
||||
}
|
||||
for mockPluginName, plugin := range tt.installedPluginsMock {
|
||||
mockPluginName = strings.Split(mockPluginName, "_")[0]
|
||||
for mockBuilderName := range plugin.Builders {
|
||||
expectedBuilderName := mockPluginName + "-" + mockBuilderName
|
||||
if c.Builders.Has(expectedBuilderName) {
|
||||
t.Fatalf("expected to not find builder %q", expectedBuilderName)
|
||||
}
|
||||
}
|
||||
for mockProvisionerName := range plugin.Provisioners {
|
||||
expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
|
||||
if c.Provisioners.Has(expectedProvisionerName) {
|
||||
t.Fatalf("expected to not find builder %q", expectedProvisionerName)
|
||||
}
|
||||
}
|
||||
for mockPostProcessorName := range plugin.PostProcessors {
|
||||
expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
|
||||
if c.PostProcessors.Has(expectedPostProcessorName) {
|
||||
t.Fatalf("expected to not find post-processor %q", expectedPostProcessorName)
|
||||
}
|
||||
}
|
||||
for mockDatasourceName := range plugin.Datasources {
|
||||
expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
|
||||
if c.DataSources.Has(expectedDatasourceName) {
|
||||
t.Fatalf("expected to not find datasource %q", expectedDatasourceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiPlugin_defaultName(t *testing.T) {
|
||||
createMockPlugins(t, defaultNameMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock)
|
||||
}
|
||||
|
||||
expectedBuilderNames := []string{"foo-bar", "foo-baz", "foo"}
|
||||
for _, mockBuilderName := range expectedBuilderNames {
|
||||
if !c.Builders.Has(mockBuilderName) {
|
||||
t.Fatalf("expected to find builder %q; builders is %#v", mockBuilderName, c.Builders)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no T.Parallel using os.Chdir
|
||||
func TestMultiPlugin_CWD(t *testing.T) {
|
||||
createMockPlugins(t, defaultNameMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
// Unset PACKER_PLUGIN_PATH to test CWD loading
|
||||
os.Unsetenv("PACKER_PLUGIN_PATH")
|
||||
if err := os.Chdir(pluginDir); err != nil {
|
||||
t.Fatalf("failed to change directory to test loading from CWD: %s", err)
|
||||
}
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock)
|
||||
}
|
||||
expectedBuilderNames := []string{"foo-bar", "foo-baz", "foo"}
|
||||
for _, mockBuilderName := range expectedBuilderNames {
|
||||
if !c.Builders.Has(mockBuilderName) {
|
||||
t.Fatalf("expected to find builder %q; builders is %#v", mockBuilderName, c.Builders)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiPlugin_IgnoreChecksumFile(t *testing.T) {
|
||||
createMockPlugins(t, defaultNameMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
csFile, err := generateMockChecksumFile(filepath.Join(pluginDir, "packer-plugin-foo"))
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
// Copy plugin contents into checksum file to validate that it is not only skipped but that it never gets loaded
|
||||
if err := os.Rename(filepath.Join(pluginDir, "packer-plugin-foo"), csFile); err != nil {
|
||||
t.Fatalf("failed to rename plugin bin file to checkfum file needed for test: %s", err)
|
||||
}
|
||||
|
||||
c := PluginConfig{}
|
||||
err = c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock)
|
||||
}
|
||||
expectedBuilderNames := []string{"foo-bar", "foo-baz", "foo"}
|
||||
for _, mockBuilderName := range expectedBuilderNames {
|
||||
if c.Builders.Has(mockBuilderName) {
|
||||
t.Fatalf("expected to not find builder %q; builders is %#v", mockBuilderName, c.Builders)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiPlugin_defaultName_each_plugin_type(t *testing.T) {
|
||||
createMockPlugins(t, doubleDefaultMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatal("Should not have error because pluginsdk.DEFAULT_NAME is used twice but only once per plugin type.")
|
||||
}
|
||||
}
|
||||
|
||||
func generateFakePlugins(dirname string, pluginNames []string) (string, []string, func(), error) {
|
||||
dir, err := os.MkdirTemp("", dirname)
|
||||
if err != nil {
|
||||
|
|
@ -296,6 +523,15 @@ func createMockPlugins(t *testing.T, plugins map[string]pluginsdk.Set) {
|
|||
}
|
||||
|
||||
func createMockChecksumFile(t testing.TB, filePath string) {
|
||||
t.Helper()
|
||||
cs, err := generateMockChecksumFile(filePath)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
t.Logf("created fake plugin checksum file %s", cs)
|
||||
}
|
||||
|
||||
func generateMockChecksumFile(filePath string) (string, error) {
|
||||
cs := plugingetter.Checksummer{
|
||||
Type: "sha256",
|
||||
Hash: sha256.New(),
|
||||
|
|
@ -303,19 +539,20 @@ func createMockChecksumFile(t testing.TB, filePath string) {
|
|||
|
||||
f, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open fake plugin binary: %v", err)
|
||||
return "", fmt.Errorf("failed to open fake plugin binary: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
sum, err := cs.Sum(f)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to checksum fake plugin binary: %v", err)
|
||||
return "", fmt.Errorf("failed to checksum fake plugin binary: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("creating fake plugin checksum file %s with contents %x", filePath+cs.FileExt(), string(sum))
|
||||
if err := os.WriteFile(filePath+cs.FileExt(), []byte(fmt.Sprintf("%x", sum)), os.ModePerm); err != nil {
|
||||
t.Fatalf("failed to write checksum fake plugin binary: %v", err)
|
||||
sumfile := filePath + cs.FileExt()
|
||||
if err := os.WriteFile(sumfile, []byte(fmt.Sprintf("%x", sum)), os.ModePerm); err != nil {
|
||||
return "", fmt.Errorf("failed to write checksum fake plugin binary: %v", err)
|
||||
}
|
||||
return sumfile, nil
|
||||
}
|
||||
|
||||
func createMockInstalledPlugins(t *testing.T, plugins map[string]pluginsdk.Set, opts ...func(tb testing.TB, filePath string)) {
|
||||
|
|
@ -461,180 +698,3 @@ var (
|
|||
},
|
||||
}
|
||||
)
|
||||
|
||||
func Test_multiplugin_describe(t *testing.T) {
|
||||
createMockPlugins(t, mockPlugins)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s", err.Error())
|
||||
}
|
||||
|
||||
for mockPluginName, plugin := range mockPlugins {
|
||||
for mockBuilderName := range plugin.Builders {
|
||||
expectedBuilderName := mockPluginName + "-" + mockBuilderName
|
||||
|
||||
if !c.Builders.Has(expectedBuilderName) {
|
||||
t.Fatalf("expected to find builder %q", expectedBuilderName)
|
||||
}
|
||||
}
|
||||
for mockProvisionerName := range plugin.Provisioners {
|
||||
expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
|
||||
if !c.Provisioners.Has(expectedProvisionerName) {
|
||||
t.Fatalf("expected to find builder %q", expectedProvisionerName)
|
||||
}
|
||||
}
|
||||
for mockPostProcessorName := range plugin.PostProcessors {
|
||||
expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
|
||||
if !c.PostProcessors.Has(expectedPostProcessorName) {
|
||||
t.Fatalf("expected to find post-processor %q", expectedPostProcessorName)
|
||||
}
|
||||
}
|
||||
for mockDatasourceName := range plugin.Datasources {
|
||||
expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
|
||||
if !c.DataSources.Has(expectedDatasourceName) {
|
||||
t.Fatalf("expected to find datasource %q", expectedDatasourceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_multiplugin_describe_installed(t *testing.T) {
|
||||
createMockInstalledPlugins(t, mockInstalledPlugins, createMockChecksumFile)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s", err.Error())
|
||||
}
|
||||
|
||||
for mockPluginName, plugin := range mockInstalledPlugins {
|
||||
mockPluginName = strings.Split(mockPluginName, "_")[0]
|
||||
for mockBuilderName := range plugin.Builders {
|
||||
expectedBuilderName := mockPluginName + "-" + mockBuilderName
|
||||
if !c.Builders.Has(expectedBuilderName) {
|
||||
t.Fatalf("expected to find builder %q", expectedBuilderName)
|
||||
}
|
||||
}
|
||||
for mockProvisionerName := range plugin.Provisioners {
|
||||
expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
|
||||
if !c.Provisioners.Has(expectedProvisionerName) {
|
||||
t.Fatalf("expected to find builder %q", expectedProvisionerName)
|
||||
}
|
||||
}
|
||||
for mockPostProcessorName := range plugin.PostProcessors {
|
||||
expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
|
||||
if !c.PostProcessors.Has(expectedPostProcessorName) {
|
||||
t.Fatalf("expected to find post-processor %q", expectedPostProcessorName)
|
||||
}
|
||||
}
|
||||
for mockDatasourceName := range plugin.Datasources {
|
||||
expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
|
||||
if !c.DataSources.Has(expectedDatasourceName) {
|
||||
t.Fatalf("expected to find datasource %q", expectedDatasourceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_multiplugin_describe_installed_for_invalid(t *testing.T) {
|
||||
tc := []struct {
|
||||
desc string
|
||||
installedPluginsMock map[string]pluginsdk.Set
|
||||
createMockFn func(*testing.T, map[string]pluginsdk.Set)
|
||||
}{
|
||||
{
|
||||
desc: "Incorrectly named plugins",
|
||||
installedPluginsMock: invalidInstalledPluginsMock,
|
||||
createMockFn: func(t *testing.T, mocks map[string]pluginsdk.Set) {
|
||||
createMockInstalledPlugins(t, mocks, createMockChecksumFile)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Plugins missing checksums",
|
||||
installedPluginsMock: mockInstalledPlugins,
|
||||
createMockFn: func(t *testing.T, mocks map[string]pluginsdk.Set) {
|
||||
createMockInstalledPlugins(t, mocks)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tc {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
tt.createMockFn(t, tt.installedPluginsMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s", err.Error())
|
||||
}
|
||||
if c.Builders.Has("feather") {
|
||||
t.Fatalf("expected to not find builder %q", "feather")
|
||||
}
|
||||
for mockPluginName, plugin := range tt.installedPluginsMock {
|
||||
mockPluginName = strings.Split(mockPluginName, "_")[0]
|
||||
for mockBuilderName := range plugin.Builders {
|
||||
expectedBuilderName := mockPluginName + "-" + mockBuilderName
|
||||
if c.Builders.Has(expectedBuilderName) {
|
||||
t.Fatalf("expected to not find builder %q", expectedBuilderName)
|
||||
}
|
||||
}
|
||||
for mockProvisionerName := range plugin.Provisioners {
|
||||
expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
|
||||
if c.Provisioners.Has(expectedProvisionerName) {
|
||||
t.Fatalf("expected to not find builder %q", expectedProvisionerName)
|
||||
}
|
||||
}
|
||||
for mockPostProcessorName := range plugin.PostProcessors {
|
||||
expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
|
||||
if c.PostProcessors.Has(expectedPostProcessorName) {
|
||||
t.Fatalf("expected to not find post-processor %q", expectedPostProcessorName)
|
||||
}
|
||||
}
|
||||
for mockDatasourceName := range plugin.Datasources {
|
||||
expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
|
||||
if c.DataSources.Has(expectedDatasourceName) {
|
||||
t.Fatalf("expected to not find datasource %q", expectedDatasourceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_multiplugin_defaultName(t *testing.T) {
|
||||
createMockPlugins(t, defaultNameMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock)
|
||||
}
|
||||
|
||||
expectedBuilderNames := []string{"foo-bar", "foo-baz", "foo"}
|
||||
for _, mockBuilderName := range expectedBuilderNames {
|
||||
if !c.Builders.Has(mockBuilderName) {
|
||||
t.Fatalf("expected to find builder %q; builders is %#v", mockBuilderName, c.Builders)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_only_one_multiplugin_defaultName_each_plugin_type(t *testing.T) {
|
||||
createMockPlugins(t, doubleDefaultMock)
|
||||
pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
|
||||
defer os.RemoveAll(pluginDir)
|
||||
|
||||
c := PluginConfig{}
|
||||
err := c.Discover()
|
||||
if err != nil {
|
||||
t.Fatal("Should not have error because pluginsdk.DEFAULT_NAME is used twice but only once per plugin type.")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue