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

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package command
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"os/exec"
    11  	"runtime"
    12  	"testing"
    13  
    14  	packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
    15  	"github.com/hashicorp/packer/builder/file"
    16  	"github.com/hashicorp/packer/builder/null"
    17  	"github.com/hashicorp/packer/packer"
    18  	"github.com/hashicorp/packer/post-processor/manifest"
    19  	shell_local_pp "github.com/hashicorp/packer/post-processor/shell-local"
    20  	filep "github.com/hashicorp/packer/provisioner/file"
    21  	"github.com/hashicorp/packer/provisioner/shell"
    22  	shell_local "github.com/hashicorp/packer/provisioner/shell-local"
    23  	"github.com/hashicorp/packer/version"
    24  )
    25  
    26  // HasExec reports whether the current system can start new processes
    27  // using os.StartProcess or (more commonly) exec.Command.
    28  func HasExec() bool {
    29  	switch runtime.GOOS {
    30  	case "js":
    31  		return false
    32  	}
    33  	return true
    34  }
    35  
    36  // MustHaveExec checks that the current system can start new processes
    37  // using os.StartProcess or (more commonly) exec.Command.
    38  // If not, MustHaveExec calls t.Skip with an explanation.
    39  func MustHaveExec(t testing.TB) {
    40  	if !HasExec() {
    41  		t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH)
    42  	}
    43  }
    44  
    45  func helperCommandContext(t *testing.T, ctx context.Context, s ...string) (cmd *exec.Cmd) {
    46  	MustHaveExec(t)
    47  
    48  	cs := []string{"-test.run=TestHelperProcess", "--"}
    49  	cs = append(cs, s...)
    50  	if ctx != nil {
    51  		cmd = exec.CommandContext(ctx, os.Args[0], cs...)
    52  	} else {
    53  		cmd = exec.Command(os.Args[0], cs...)
    54  	}
    55  	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
    56  	return cmd
    57  }
    58  
    59  func helperCommand(t *testing.T, s ...string) *exec.Cmd {
    60  	return helperCommandContext(t, nil, s...)
    61  }
    62  
    63  // TestHelperProcess isn't a real test. It's used as a helper process
    64  // for TestParameterRun.
    65  func TestHelperProcess(*testing.T) {
    66  	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
    67  		return
    68  	}
    69  	defer os.Exit(0)
    70  
    71  	args := os.Args
    72  	for len(args) > 0 {
    73  		if args[0] == "--" {
    74  			args = args[1:]
    75  			break
    76  		}
    77  		args = args[1:]
    78  	}
    79  	if len(args) == 0 {
    80  		fmt.Fprintf(os.Stderr, "No command\n")
    81  		os.Exit(2)
    82  	}
    83  
    84  	cmd, args := args[0], args[1:]
    85  	switch cmd {
    86  	case "console":
    87  		os.Exit((&ConsoleCommand{Meta: commandMeta()}).Run(args))
    88  	case "fmt":
    89  		os.Exit((&FormatCommand{Meta: commandMeta()}).Run(args))
    90  	case "inspect":
    91  		os.Exit((&InspectCommand{Meta: commandMeta()}).Run(args))
    92  	case "build":
    93  		os.Exit((&BuildCommand{Meta: commandMeta()}).Run(args))
    94  	case "hcl2_upgrade":
    95  		os.Exit((&HCL2UpgradeCommand{Meta: commandMeta()}).Run(args))
    96  	default:
    97  		fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
    98  		os.Exit(2)
    99  	}
   100  }
   101  
   102  func commandMeta() Meta {
   103  	basicUi := &packersdk.BasicUi{
   104  		Reader:      os.Stdin,
   105  		Writer:      os.Stdout,
   106  		ErrorWriter: os.Stdout,
   107  	}
   108  
   109  	CommandMeta := Meta{
   110  		CoreConfig: &packer.CoreConfig{
   111  			Components: getBareComponentFinder(),
   112  			Version:    version.Version,
   113  		},
   114  		Ui: basicUi,
   115  	}
   116  	return CommandMeta
   117  }
   118  
   119  func getBareComponentFinder() packer.ComponentFinder {
   120  	return packer.ComponentFinder{
   121  		PluginConfig: &packer.PluginConfig{
   122  			Builders: packer.MapOfBuilder{
   123  				"file": func() (packersdk.Builder, error) { return &file.Builder{}, nil },
   124  				"null": func() (packersdk.Builder, error) { return &null.Builder{}, nil },
   125  			},
   126  			Provisioners: packer.MapOfProvisioner{
   127  				"shell-local": func() (packersdk.Provisioner, error) { return &shell_local.Provisioner{}, nil },
   128  				"shell":       func() (packersdk.Provisioner, error) { return &shell.Provisioner{}, nil },
   129  				"file":        func() (packersdk.Provisioner, error) { return &filep.Provisioner{}, nil },
   130  			},
   131  			PostProcessors: packer.MapOfPostProcessor{
   132  				"shell-local": func() (packersdk.PostProcessor, error) { return &shell_local_pp.PostProcessor{}, nil },
   133  				"manifest":    func() (packersdk.PostProcessor, error) { return &manifest.PostProcessor{}, nil },
   134  			},
   135  		},
   136  	}
   137  }