github.com/hashicorp/packer@v1.14.3/packer/plugin_discover_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package packer
     5  
     6  import (
     7  	"crypto/sha256"
     8  	"fmt"
     9  	"os"
    10  	"os/exec"
    11  	"path"
    12  	"path/filepath"
    13  	"runtime"
    14  	"strings"
    15  	"testing"
    16  
    17  	packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
    18  	pluginsdk "github.com/hashicorp/packer-plugin-sdk/plugin"
    19  	"github.com/hashicorp/packer-plugin-sdk/tmp"
    20  	"github.com/hashicorp/packer-plugin-sdk/version"
    21  	plugingetter "github.com/hashicorp/packer/packer/plugin-getter"
    22  )
    23  
    24  func newPluginConfig() PluginConfig {
    25  	var conf PluginConfig
    26  	conf.PluginMinPort = 10000
    27  	conf.PluginMaxPort = 25000
    28  	return conf
    29  }
    30  
    31  func TestDiscoverReturnsIfMagicCookieSet(t *testing.T) {
    32  	config := newPluginConfig()
    33  
    34  	t.Setenv(pluginsdk.MagicCookieKey, pluginsdk.MagicCookieValue)
    35  
    36  	err := config.Discover()
    37  	if err != nil {
    38  		t.Fatalf("Should not have errored: %s", err)
    39  	}
    40  
    41  	if len(config.Builders.List()) != 0 {
    42  		t.Fatalf("Should not have tried to find builders")
    43  	}
    44  }
    45  
    46  func TestMultiPlugin_describe(t *testing.T) {
    47  	createMockPlugins(t, mockPlugins)
    48  	pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
    49  	defer os.RemoveAll(pluginDir)
    50  	c := PluginConfig{}
    51  	err := c.Discover()
    52  	if err != nil {
    53  		t.Fatalf("error discovering plugins; %s", err.Error())
    54  	}
    55  
    56  	for mockPluginName, plugin := range mockPlugins {
    57  		for mockBuilderName := range plugin.Builders {
    58  			expectedBuilderName := mockPluginName + "-" + mockBuilderName
    59  
    60  			if !c.Builders.Has(expectedBuilderName) {
    61  				t.Errorf("expected to find builder %q", expectedBuilderName)
    62  			}
    63  		}
    64  		for mockProvisionerName := range plugin.Provisioners {
    65  			expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
    66  			if !c.Provisioners.Has(expectedProvisionerName) {
    67  				t.Errorf("expected to find builder %q", expectedProvisionerName)
    68  			}
    69  		}
    70  		for mockPostProcessorName := range plugin.PostProcessors {
    71  			expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
    72  			if !c.PostProcessors.Has(expectedPostProcessorName) {
    73  				t.Errorf("expected to find post-processor %q", expectedPostProcessorName)
    74  			}
    75  		}
    76  		for mockDatasourceName := range plugin.Datasources {
    77  			expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
    78  			if !c.DataSources.Has(expectedDatasourceName) {
    79  				t.Errorf("expected to find datasource %q", expectedDatasourceName)
    80  			}
    81  		}
    82  	}
    83  }
    84  
    85  func TestMultiPlugin_describe_installed(t *testing.T) {
    86  	createMockInstalledPlugins(t, mockInstalledPlugins, createMockChecksumFile)
    87  	pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
    88  	defer os.RemoveAll(pluginDir)
    89  
    90  	c := PluginConfig{}
    91  	err := c.Discover()
    92  	if err != nil {
    93  		t.Fatalf("error discovering plugins; %s", err.Error())
    94  	}
    95  
    96  	for mockPluginName, plugin := range mockInstalledPlugins {
    97  		mockPluginName = strings.Split(mockPluginName, "_")[0]
    98  		for mockBuilderName := range plugin.Builders {
    99  			expectedBuilderName := mockPluginName + "-" + mockBuilderName
   100  			if !c.Builders.Has(expectedBuilderName) {
   101  				t.Fatalf("expected to find builder %q", expectedBuilderName)
   102  			}
   103  		}
   104  		for mockProvisionerName := range plugin.Provisioners {
   105  			expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
   106  			if !c.Provisioners.Has(expectedProvisionerName) {
   107  				t.Fatalf("expected to find builder %q", expectedProvisionerName)
   108  			}
   109  		}
   110  		for mockPostProcessorName := range plugin.PostProcessors {
   111  			expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
   112  			if !c.PostProcessors.Has(expectedPostProcessorName) {
   113  				t.Fatalf("expected to find post-processor %q", expectedPostProcessorName)
   114  			}
   115  		}
   116  		for mockDatasourceName := range plugin.Datasources {
   117  			expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
   118  			if !c.DataSources.Has(expectedDatasourceName) {
   119  				t.Fatalf("expected to find datasource %q", expectedDatasourceName)
   120  			}
   121  		}
   122  	}
   123  }
   124  
   125  func TestMultiPlugin_describe_installed_for_invalid(t *testing.T) {
   126  	tc := []struct {
   127  		desc                 string
   128  		installedPluginsMock map[string]pluginsdk.Set
   129  		createMockFn         func(*testing.T, map[string]pluginsdk.Set)
   130  	}{
   131  		{
   132  			desc:                 "Incorrectly named plugins",
   133  			installedPluginsMock: invalidInstalledPluginsMock,
   134  			createMockFn: func(t *testing.T, mocks map[string]pluginsdk.Set) {
   135  				createMockInstalledPlugins(t, mocks, createMockChecksumFile)
   136  			},
   137  		},
   138  		{
   139  			desc:                 "Plugins missing checksums",
   140  			installedPluginsMock: mockInstalledPlugins,
   141  			createMockFn: func(t *testing.T, mocks map[string]pluginsdk.Set) {
   142  				createMockInstalledPlugins(t, mocks)
   143  			},
   144  		},
   145  	}
   146  
   147  	for _, tt := range tc {
   148  		t.Run(tt.desc, func(t *testing.T) {
   149  			tt.createMockFn(t, tt.installedPluginsMock)
   150  			pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
   151  			defer os.RemoveAll(pluginDir)
   152  
   153  			c := PluginConfig{}
   154  			err := c.Discover()
   155  			if err != nil {
   156  				t.Fatalf("error discovering plugins; %s", err.Error())
   157  			}
   158  			if c.Builders.Has("feather") {
   159  				t.Fatalf("expected to not find builder %q", "feather")
   160  			}
   161  			for mockPluginName, plugin := range tt.installedPluginsMock {
   162  				mockPluginName = strings.Split(mockPluginName, "_")[0]
   163  				for mockBuilderName := range plugin.Builders {
   164  					expectedBuilderName := mockPluginName + "-" + mockBuilderName
   165  					if c.Builders.Has(expectedBuilderName) {
   166  						t.Fatalf("expected to not find builder %q", expectedBuilderName)
   167  					}
   168  				}
   169  				for mockProvisionerName := range plugin.Provisioners {
   170  					expectedProvisionerName := mockPluginName + "-" + mockProvisionerName
   171  					if c.Provisioners.Has(expectedProvisionerName) {
   172  						t.Fatalf("expected to not find builder %q", expectedProvisionerName)
   173  					}
   174  				}
   175  				for mockPostProcessorName := range plugin.PostProcessors {
   176  					expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName
   177  					if c.PostProcessors.Has(expectedPostProcessorName) {
   178  						t.Fatalf("expected to not find post-processor %q", expectedPostProcessorName)
   179  					}
   180  				}
   181  				for mockDatasourceName := range plugin.Datasources {
   182  					expectedDatasourceName := mockPluginName + "-" + mockDatasourceName
   183  					if c.DataSources.Has(expectedDatasourceName) {
   184  						t.Fatalf("expected to not find datasource %q", expectedDatasourceName)
   185  					}
   186  				}
   187  			}
   188  		})
   189  	}
   190  }
   191  
   192  func TestMultiPlugin_defaultName(t *testing.T) {
   193  	createMockPlugins(t, defaultNameMock)
   194  	pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
   195  	defer os.RemoveAll(pluginDir)
   196  
   197  	c := PluginConfig{}
   198  	err := c.Discover()
   199  	if err != nil {
   200  		t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock)
   201  	}
   202  
   203  	expectedBuilderNames := []string{"foo-bar", "foo-baz", "foo"}
   204  	for _, mockBuilderName := range expectedBuilderNames {
   205  		if !c.Builders.Has(mockBuilderName) {
   206  			t.Fatalf("expected to find builder %q; builders is %#v", mockBuilderName, c.Builders)
   207  		}
   208  	}
   209  }
   210  
   211  func TestMultiPlugin_IgnoreChecksumFile(t *testing.T) {
   212  	createMockPlugins(t, defaultNameMock)
   213  	pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
   214  	defer os.RemoveAll(pluginDir)
   215  
   216  	fooPluginName := fmt.Sprintf("packer-plugin-foo_v1.0.0_x5.0_%s_%s", runtime.GOOS, runtime.GOARCH)
   217  	fooPluginPath := filepath.Join(pluginDir, "github.com", "hashicorp", "foo", fooPluginName)
   218  	csFile, err := generateMockChecksumFile(fooPluginPath)
   219  	if err != nil {
   220  		t.Fatal(err.Error())
   221  	}
   222  
   223  	// Copy plugin contents into checksum file to validate that it is not only skipped but that it never gets loaded
   224  	if err := os.Rename(fooPluginPath, csFile); err != nil {
   225  		t.Fatalf("failed to rename plugin bin file to checkfum file needed for test: %s", err)
   226  	}
   227  
   228  	c := PluginConfig{}
   229  	err = c.Discover()
   230  	if err != nil {
   231  		t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock)
   232  	}
   233  	expectedBuilderNames := []string{"foo-bar", "foo-baz", "foo"}
   234  	for _, mockBuilderName := range expectedBuilderNames {
   235  		if c.Builders.Has(mockBuilderName) {
   236  			t.Fatalf("expected to not find builder %q; builders is %#v", mockBuilderName, c.Builders)
   237  		}
   238  	}
   239  }
   240  
   241  func TestMultiPlugin_defaultName_each_plugin_type(t *testing.T) {
   242  	createMockPlugins(t, doubleDefaultMock)
   243  	pluginDir := os.Getenv("PACKER_PLUGIN_PATH")
   244  	defer os.RemoveAll(pluginDir)
   245  
   246  	c := PluginConfig{}
   247  	err := c.Discover()
   248  	if err != nil {
   249  		t.Fatal("Should not have error because pluginsdk.DEFAULT_NAME is used twice but only once per plugin type.")
   250  	}
   251  }
   252  
   253  // TestHelperProcess isn't a real test. It's used as a helper process
   254  // for multi-component plugin tests.
   255  func TestHelperPlugins(t *testing.T) {
   256  	if os.Getenv("PKR_WANT_TEST_PLUGINS") != "1" {
   257  		return
   258  	}
   259  	defer os.Exit(0)
   260  
   261  	args := os.Args
   262  	for len(args) > 0 {
   263  		if args[0] == "--" {
   264  			args = args[1:]
   265  			break
   266  		}
   267  		args = args[1:]
   268  	}
   269  	if len(args) == 0 {
   270  		fmt.Fprintf(os.Stderr, "No command\n")
   271  		os.Exit(2)
   272  	}
   273  
   274  	pluginName, args := args[0], args[1:]
   275  
   276  	allMocks := []map[string]pluginsdk.Set{mockPlugins, defaultNameMock, doubleDefaultMock, badDefaultNameMock}
   277  	for _, mock := range allMocks {
   278  		plugin, found := mock[pluginName]
   279  		if found {
   280  			plugin.SetVersion(version.NewPluginVersion("1.0.0", "", ""))
   281  			err := plugin.RunCommand(args...)
   282  			if err != nil {
   283  				fmt.Fprintf(os.Stderr, "%v\n", err)
   284  				os.Exit(1)
   285  			}
   286  			os.Exit(0)
   287  		}
   288  	}
   289  
   290  	fmt.Fprintf(os.Stderr, "No %q plugin found\n", pluginName)
   291  	os.Exit(2)
   292  }
   293  
   294  // HasExec reports whether the current system can start new processes
   295  // using os.StartProcess or (more commonly) exec.Command.
   296  func HasExec() bool {
   297  	switch runtime.GOOS {
   298  	case "js":
   299  		return false
   300  	case "windows":
   301  		// TODO(azr): Fix this once versioning is added and we know more
   302  		return false
   303  	}
   304  	return true
   305  }
   306  
   307  // MustHaveExec checks that the current system can start new processes
   308  // using os.StartProcess or (more commonly) exec.Command.
   309  // If not, MustHaveExec calls t.Skip with an explanation.
   310  func MustHaveExec(t testing.TB) {
   311  	if !HasExec() {
   312  		t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH)
   313  	}
   314  }
   315  
   316  func MustHaveCommand(t testing.TB, cmd string) string {
   317  	path, err := exec.LookPath(cmd)
   318  	if err != nil {
   319  		t.Skipf("skipping test: cannot find the %q command: %v", cmd, err)
   320  	}
   321  	return path
   322  }
   323  
   324  func helperCommand(t *testing.T, s ...string) []string {
   325  	MustHaveExec(t)
   326  
   327  	cmd := []string{os.Args[0], "-test.run=TestHelperPlugins", "--"}
   328  	return append(cmd, s...)
   329  }
   330  
   331  func createMockPlugins(t *testing.T, plugins map[string]pluginsdk.Set) {
   332  	pluginDir, err := tmp.Dir("pkr-multi-component-plugin-test-*")
   333  	{
   334  		// create an exectutable file with a `sh` sheebang
   335  		// this file will look like:
   336  		// #!/bin/sh
   337  		// PKR_WANT_TEST_PLUGINS=1 ...plugin/debug.test -test.run=TestHelperPlugins -- bird $@
   338  		// 'bird' is the mock plugin we want to start
   339  		// $@ just passes all passed arguments
   340  		// This will allow to run the fake plugin from go tests which in turn
   341  		// will run go tests callback to `TestHelperPlugins`, this one will be
   342  		// transparently calling our mock multi-component plugins `mockPlugins`.
   343  		if err != nil {
   344  			t.Fatal(err)
   345  		}
   346  
   347  		t.Logf("putting temporary mock plugins in %s", pluginDir)
   348  
   349  		shPath := MustHaveCommand(t, "bash")
   350  		for name := range plugins {
   351  			pluginName := fmt.Sprintf("packer-plugin-%s_v1.0.0_x5.0_%s_%s", name, runtime.GOOS, runtime.GOARCH)
   352  			pluginSubDir := fmt.Sprintf("github.com/hashicorp/%s", name)
   353  			err := os.MkdirAll(path.Join(pluginDir, pluginSubDir), 0755)
   354  			if err != nil {
   355  				t.Fatalf("failed to create plugin hierarchy: %s", err)
   356  			}
   357  			plugin := path.Join(pluginDir, pluginSubDir, pluginName)
   358  			t.Logf("creating fake plugin %s", plugin)
   359  			fileContent := ""
   360  			fileContent = fmt.Sprintf("#!%s\n", shPath)
   361  			fileContent += strings.Join(
   362  				append([]string{"PKR_WANT_TEST_PLUGINS=1"}, helperCommand(t, name, "$@")...),
   363  				" ")
   364  			if err := os.WriteFile(plugin, []byte(fileContent), os.ModePerm); err != nil {
   365  				t.Fatalf("failed to create fake plugin binary: %v", err)
   366  			}
   367  
   368  			if _, err := generateMockChecksumFile(plugin); err != nil {
   369  				t.Fatalf("failed to create fake plugin binary checksum file: %v", err)
   370  			}
   371  		}
   372  	}
   373  	t.Setenv("PACKER_PLUGIN_PATH", pluginDir)
   374  }
   375  
   376  func createMockChecksumFile(t testing.TB, filePath string) {
   377  	t.Helper()
   378  	cs, err := generateMockChecksumFile(filePath)
   379  	if err != nil {
   380  		t.Fatalf("%s", err.Error())
   381  	}
   382  	t.Logf("created fake plugin checksum file %s", cs)
   383  }
   384  
   385  func generateMockChecksumFile(filePath string) (string, error) {
   386  	cs := plugingetter.Checksummer{
   387  		Type: "sha256",
   388  		Hash: sha256.New(),
   389  	}
   390  
   391  	f, err := os.Open(filePath)
   392  	if err != nil {
   393  		return "", fmt.Errorf("failed to open fake plugin binary: %v", err)
   394  	}
   395  	defer f.Close()
   396  
   397  	sum, err := cs.Sum(f)
   398  	if err != nil {
   399  		return "", fmt.Errorf("failed to checksum fake plugin binary: %v", err)
   400  	}
   401  
   402  	sumfile := filePath + cs.FileExt()
   403  	if err := os.WriteFile(sumfile, []byte(fmt.Sprintf("%x", sum)), os.ModePerm); err != nil {
   404  		return "", fmt.Errorf("failed to write checksum fake plugin binary: %v", err)
   405  	}
   406  	return sumfile, nil
   407  }
   408  
   409  func createMockInstalledPlugins(t *testing.T, plugins map[string]pluginsdk.Set, opts ...func(tb testing.TB, filePath string)) {
   410  	pluginDir, err := tmp.Dir("pkr-multi-component-plugin-test-*")
   411  	{
   412  		// create an exectutable file with a `sh` sheebang
   413  		// this file will look like:
   414  		// #!/bin/sh
   415  		// PKR_WANT_TEST_PLUGINS=1 ...plugin/debug.test -test.run=TestHelperPlugins -- bird $@
   416  		// 'bird' is the mock plugin we want to start
   417  		// $@ just passes all passed arguments
   418  		// This will allow to run the fake plugin from go tests which in turn
   419  		// will run go tests callback to `TestHelperPlugins`, this one will be
   420  		// transparently calling our mock multi-component plugins `mockPlugins`.
   421  		if err != nil {
   422  			t.Fatal(err)
   423  		}
   424  		dir, err := os.MkdirTemp(pluginDir, "github.com")
   425  		if err != nil {
   426  			t.Fatalf("failed to create temporary test directory: %v", err)
   427  		}
   428  		dir, err = os.MkdirTemp(dir, "hashicorp")
   429  		if err != nil {
   430  			t.Fatalf("failed to create temporary test directory: %v", err)
   431  		}
   432  		dir, err = os.MkdirTemp(dir, "plugin")
   433  		if err != nil {
   434  			t.Fatalf("failed to create temporary test directory: %v", err)
   435  		}
   436  		t.Logf("putting temporary mock installed plugins in %s", dir)
   437  
   438  		shPath := MustHaveCommand(t, "bash")
   439  		for name := range plugins {
   440  			plugin := path.Join(dir, "packer-plugin-"+name)
   441  			t.Logf("creating fake plugin %s", plugin)
   442  			fileContent := ""
   443  			fileContent = fmt.Sprintf("#!%s\n", shPath)
   444  			fileContent += strings.Join(
   445  				append([]string{"PKR_WANT_TEST_PLUGINS=1"}, helperCommand(t, strings.Split(name, "_")[0], "$@")...),
   446  				" ")
   447  			if err := os.WriteFile(plugin, []byte(fileContent), os.ModePerm); err != nil {
   448  				t.Fatalf("failed to create fake plugin binary: %v", err)
   449  			}
   450  
   451  			for _, opt := range opts {
   452  				opt(t, plugin)
   453  			}
   454  		}
   455  	}
   456  	t.Setenv("PACKER_PLUGIN_PATH", pluginDir)
   457  }
   458  
   459  func getFormattedInstalledPluginSuffix() string {
   460  	return fmt.Sprintf("v1.0.0_x5.0_%s_%s", runtime.GOOS, runtime.GOARCH)
   461  }
   462  
   463  var (
   464  	mockPlugins                 = map[string]pluginsdk.Set{}
   465  	mockInstalledPlugins        = map[string]pluginsdk.Set{}
   466  	invalidInstalledPluginsMock = map[string]pluginsdk.Set{}
   467  	defaultNameMock             = map[string]pluginsdk.Set{}
   468  	doubleDefaultMock           = map[string]pluginsdk.Set{}
   469  	badDefaultNameMock          = map[string]pluginsdk.Set{}
   470  )
   471  
   472  func init() {
   473  	mockPluginsBird := pluginsdk.NewSet()
   474  	mockPluginsBird.Builders = map[string]packersdk.Builder{
   475  		"feather":   nil,
   476  		"guacamole": nil,
   477  	}
   478  	mockPluginsChim := pluginsdk.NewSet()
   479  	mockPluginsChim.PostProcessors = map[string]packersdk.PostProcessor{
   480  		"smoke": nil,
   481  	}
   482  	mockPluginsData := pluginsdk.NewSet()
   483  	mockPluginsData.Datasources = map[string]packersdk.Datasource{
   484  		"source": nil,
   485  	}
   486  	mockPlugins["bird"] = *mockPluginsBird
   487  	mockPlugins["chimney"] = *mockPluginsChim
   488  	mockPlugins["data"] = *mockPluginsData
   489  
   490  	mockInstalledPluginsBird := pluginsdk.NewSet()
   491  	mockInstalledPluginsBird.Builders = map[string]packersdk.Builder{
   492  		"feather":   nil,
   493  		"guacamole": nil,
   494  	}
   495  	mockInstalledPluginsChim := pluginsdk.NewSet()
   496  	mockInstalledPluginsChim.PostProcessors = map[string]packersdk.PostProcessor{
   497  		"smoke": nil,
   498  	}
   499  	mockInstalledPluginsData := pluginsdk.NewSet()
   500  	mockInstalledPluginsData.Datasources = map[string]packersdk.Datasource{
   501  		"source": nil,
   502  	}
   503  	mockInstalledPlugins[fmt.Sprintf("bird_%s", getFormattedInstalledPluginSuffix())] = *mockInstalledPluginsBird
   504  	mockInstalledPlugins[fmt.Sprintf("chimney_%s", getFormattedInstalledPluginSuffix())] = *mockInstalledPluginsChim
   505  	mockInstalledPlugins[fmt.Sprintf("data_%s", getFormattedInstalledPluginSuffix())] = *mockInstalledPluginsData
   506  
   507  	invalidInstalledPluginsMockBird := pluginsdk.NewSet()
   508  	invalidInstalledPluginsMockBird.Builders = map[string]packersdk.Builder{
   509  		"feather":   nil,
   510  		"guacamole": nil,
   511  	}
   512  	invalidInstalledPluginsMockChimney := pluginsdk.NewSet()
   513  	invalidInstalledPluginsMockChimney.PostProcessors = map[string]packersdk.PostProcessor{
   514  		"smoke": nil,
   515  	}
   516  	invalidInstalledPluginsMockData := pluginsdk.NewSet()
   517  	invalidInstalledPluginsMockData.Datasources = map[string]packersdk.Datasource{
   518  		"source": nil,
   519  	}
   520  	invalidInstalledPluginsMock["bird_v0.1.1_x5.0_wrong_architecture"] = *invalidInstalledPluginsMockBird
   521  	invalidInstalledPluginsMock["chimney_cool_ranch"] = *invalidInstalledPluginsMockChimney
   522  	invalidInstalledPluginsMock["data"] = *invalidInstalledPluginsMockData
   523  
   524  	defaultNameFooSet := pluginsdk.NewSet()
   525  	defaultNameFooSet.Builders = map[string]packersdk.Builder{
   526  		"bar":                  nil,
   527  		"baz":                  nil,
   528  		pluginsdk.DEFAULT_NAME: nil,
   529  	}
   530  	defaultNameMock["foo"] = *defaultNameFooSet
   531  
   532  	doubleDefaultYoloSet := pluginsdk.NewSet()
   533  	doubleDefaultYoloSet.Builders = map[string]packersdk.Builder{
   534  		"bar":                  nil,
   535  		"baz":                  nil,
   536  		pluginsdk.DEFAULT_NAME: nil,
   537  	}
   538  	doubleDefaultYoloSet.PostProcessors = map[string]packersdk.PostProcessor{
   539  		pluginsdk.DEFAULT_NAME: nil,
   540  	}
   541  	doubleDefaultMock["yolo"] = *doubleDefaultYoloSet
   542  
   543  	badDefaultSet := pluginsdk.NewSet()
   544  	badDefaultSet.Builders = map[string]packersdk.Builder{
   545  		"bar":                  nil,
   546  		"baz":                  nil,
   547  		pluginsdk.DEFAULT_NAME: nil,
   548  	}
   549  	badDefaultNameMock["foo"] = *badDefaultSet
   550  }