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 }