github.com/hashicorp/packer@v1.14.3/post-processor/shell-local/post-processor_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package shell_local
     5  
     6  import (
     7  	"os"
     8  	"runtime"
     9  	"testing"
    10  
    11  	packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestPostProcessor_ImplementsPostProcessor(t *testing.T) {
    16  	var _ packersdk.PostProcessor = new(PostProcessor)
    17  }
    18  
    19  func testConfig() map[string]interface{} {
    20  	return map[string]interface{}{
    21  		"inline": []interface{}{"foo", "bar"},
    22  	}
    23  }
    24  
    25  func TestPostProcessor_Impl(t *testing.T) {
    26  	var raw interface{}
    27  	raw = &PostProcessor{}
    28  	if _, ok := raw.(packersdk.PostProcessor); !ok {
    29  		t.Fatalf("must be a post processor")
    30  	}
    31  }
    32  
    33  func TestPostProcessorPrepare_Defaults(t *testing.T) {
    34  	var p PostProcessor
    35  	raws := testConfig()
    36  
    37  	err := p.Configure(raws)
    38  	if err != nil {
    39  		t.Fatalf("err: %s", err)
    40  	}
    41  }
    42  
    43  func TestPostProcessorPrepare_InlineShebang(t *testing.T) {
    44  	raws := testConfig()
    45  
    46  	delete(raws, "inline_shebang")
    47  	p := new(PostProcessor)
    48  	err := p.Configure(raws)
    49  	if err != nil {
    50  		t.Fatalf("should not have error: %s", err)
    51  	}
    52  	expected := ""
    53  	if runtime.GOOS != "windows" {
    54  		expected = "/bin/sh -e"
    55  	}
    56  	if p.config.InlineShebang != expected {
    57  		t.Fatalf("bad value: %s", p.config.InlineShebang)
    58  	}
    59  
    60  	// Test with a good one
    61  	raws["inline_shebang"] = "foo"
    62  	p = new(PostProcessor)
    63  	err = p.Configure(raws)
    64  	if err != nil {
    65  		t.Fatalf("should not have error: %s", err)
    66  	}
    67  
    68  	if p.config.InlineShebang != "foo" {
    69  		t.Fatalf("bad value: %s", p.config.InlineShebang)
    70  	}
    71  }
    72  
    73  func TestPostProcessorPrepare_InvalidKey(t *testing.T) {
    74  	var p PostProcessor
    75  	raws := testConfig()
    76  
    77  	// Add a random key
    78  	raws["i_should_not_be_valid"] = true
    79  	err := p.Configure(raws)
    80  	if err == nil {
    81  		t.Fatal("should have error")
    82  	}
    83  }
    84  
    85  func TestPostProcessorPrepare_Script(t *testing.T) {
    86  	raws := testConfig()
    87  	delete(raws, "inline")
    88  
    89  	raws["script"] = "/this/should/not/exist"
    90  	p := new(PostProcessor)
    91  	err := p.Configure(raws)
    92  	if err == nil {
    93  		t.Fatal("should have error")
    94  	}
    95  
    96  	// Test with a good one
    97  	tf, err := os.CreateTemp("", "packer")
    98  	if err != nil {
    99  		t.Fatalf("error tempfile: %s", err)
   100  	}
   101  	defer os.Remove(tf.Name())
   102  
   103  	raws["script"] = tf.Name()
   104  	p = new(PostProcessor)
   105  	err = p.Configure(raws)
   106  	if err != nil {
   107  		t.Fatalf("should not have error: %s", err)
   108  	}
   109  }
   110  
   111  func TestPostProcessorPrepare_ExecuteCommand(t *testing.T) {
   112  	// Check that passing a string will work (Backwards Compatibility)
   113  	p := new(PostProcessor)
   114  	raws := testConfig()
   115  	raws["execute_command"] = "foo bar"
   116  	err := p.Configure(raws)
   117  	expected := []string{"sh", "-c", "foo bar"}
   118  	if err != nil {
   119  		t.Fatalf("should handle backwards compatibility: %s", err)
   120  	}
   121  	assert.Equal(t, p.config.ExecuteCommand, expected,
   122  		"Did not get expected execute_command: expected: %#v; received %#v", expected, p.config.ExecuteCommand)
   123  
   124  	// Check that passing a list will work
   125  	p = new(PostProcessor)
   126  	raws = testConfig()
   127  	raws["execute_command"] = []string{"foo", "bar"}
   128  	err = p.Configure(raws)
   129  	if err != nil {
   130  		t.Fatalf("should handle backwards compatibility: %s", err)
   131  	}
   132  	expected = []string{"foo", "bar"}
   133  	assert.Equal(t, p.config.ExecuteCommand, expected,
   134  		"Did not get expected execute_command: expected: %#v; received %#v", expected, p.config.ExecuteCommand)
   135  
   136  	// Check that default is as expected
   137  	raws = testConfig()
   138  	delete(raws, "execute_command")
   139  	p = new(PostProcessor)
   140  	p.Configure(raws)
   141  	if runtime.GOOS != "windows" {
   142  		expected = []string{"/bin/sh", "-c", "{{.Vars}} {{.Script}}"}
   143  	} else {
   144  		expected = []string{"cmd", "/V", "/C", "{{.Vars}}", "call", "{{.Script}}"}
   145  	}
   146  	assert.Equal(t, p.config.ExecuteCommand, expected,
   147  		"Did not get expected default: expected: %#v; received %#v", expected, p.config.ExecuteCommand)
   148  }
   149  
   150  func TestPostProcessorPrepare_ScriptAndInline(t *testing.T) {
   151  	var p PostProcessor
   152  	raws := testConfig()
   153  
   154  	// Error if no scripts/inline commands provided
   155  	delete(raws, "inline")
   156  	delete(raws, "script")
   157  	delete(raws, "command")
   158  	delete(raws, "scripts")
   159  	err := p.Configure(raws)
   160  	if err == nil {
   161  		t.Fatalf("should error when no scripts/inline commands are provided")
   162  	}
   163  
   164  	// Test with both
   165  	tf, err := os.CreateTemp("", "packer")
   166  	if err != nil {
   167  		t.Fatalf("error tempfile: %s", err)
   168  	}
   169  	defer os.Remove(tf.Name())
   170  
   171  	raws["inline"] = []interface{}{"foo"}
   172  	raws["script"] = tf.Name()
   173  	err = p.Configure(raws)
   174  	if err == nil {
   175  		t.Fatal("should have error")
   176  	}
   177  }
   178  
   179  func TestPostProcessorPrepare_ScriptAndScripts(t *testing.T) {
   180  	var p PostProcessor
   181  	raws := testConfig()
   182  
   183  	// Test with both
   184  	tf, err := os.CreateTemp("", "packer")
   185  	if err != nil {
   186  		t.Fatalf("error tempfile: %s", err)
   187  	}
   188  	defer os.Remove(tf.Name())
   189  
   190  	raws["inline"] = []interface{}{"foo"}
   191  	raws["scripts"] = []string{tf.Name()}
   192  	err = p.Configure(raws)
   193  	if err == nil {
   194  		t.Fatal("should have error")
   195  	}
   196  }
   197  
   198  func TestPostProcessorPrepare_Scripts(t *testing.T) {
   199  	raws := testConfig()
   200  	delete(raws, "inline")
   201  
   202  	raws["scripts"] = []string{}
   203  	p := new(PostProcessor)
   204  	err := p.Configure(raws)
   205  	if err == nil {
   206  		t.Fatal("should have error")
   207  	}
   208  
   209  	// Test with a good one
   210  	tf, err := os.CreateTemp("", "packer")
   211  	if err != nil {
   212  		t.Fatalf("error tempfile: %s", err)
   213  	}
   214  	defer os.Remove(tf.Name())
   215  
   216  	raws["scripts"] = []string{tf.Name()}
   217  	p = new(PostProcessor)
   218  	err = p.Configure(raws)
   219  	if err != nil {
   220  		t.Fatalf("should not have error: %s", err)
   221  	}
   222  }
   223  
   224  func TestPostProcessorPrepare_EnvironmentVars(t *testing.T) {
   225  	raws := testConfig()
   226  
   227  	// Test with a bad case
   228  	raws["environment_vars"] = []string{"badvar", "good=var"}
   229  	p := new(PostProcessor)
   230  	err := p.Configure(raws)
   231  	if err == nil {
   232  		t.Fatal("should have error")
   233  	}
   234  
   235  	// Test with a trickier case
   236  	raws["environment_vars"] = []string{"=bad"}
   237  	p = new(PostProcessor)
   238  	err = p.Configure(raws)
   239  	if err == nil {
   240  		t.Fatal("should have error")
   241  	}
   242  
   243  	// Test with a good case
   244  	// Note: baz= is a real env variable, just empty
   245  	raws["environment_vars"] = []string{"FOO=bar", "baz="}
   246  	p = new(PostProcessor)
   247  	err = p.Configure(raws)
   248  	if err != nil {
   249  		t.Fatalf("should not have error: %s", err)
   250  	}
   251  
   252  	// Test when the env variable value contains an equals sign
   253  	raws["environment_vars"] = []string{"good=withequals=true"}
   254  	p = new(PostProcessor)
   255  	err = p.Configure(raws)
   256  	if err != nil {
   257  		t.Fatalf("should not have error: %s", err)
   258  	}
   259  
   260  	// Test when the env variable value starts with an equals sign
   261  	raws["environment_vars"] = []string{"good==true"}
   262  	p = new(PostProcessor)
   263  	err = p.Configure(raws)
   264  	if err != nil {
   265  		t.Fatalf("should not have error: %s", err)
   266  	}
   267  }