@ -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 . Fatal f( "failed to open fake plugin binary: %v" , err )
return "" , fmt . Error f( "failed to open fake plugin binary: %v" , err )
}
defer f . Close ( )
sum , err := cs . Sum ( f )
if err != nil {
t . Fatal f( "failed to checksum fake plugin binary: %v" , err )
return "" , fmt . Error f( "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 . Fatal f( "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 . Error f( "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." )
}
}