MCPcopy Index your code
hub / github.com/coder/coder / ExecBackground

Function ExecBackground

tailnet/test/integration/integration.go:608–674  ·  view source on GitHub ↗

ExecBackground starts a subprocess with the given flags and returns a channel that will receive the error when the subprocess exits. The returned function can be used to close the subprocess. processName is used to identify the subprocess in logs. Optionally, a network namespace can be passed to r

(t *testing.T, processName string, netNS *os.File, name string, args []string)

Source from the content-addressed store, hash-verified

606// Cleanup is handled automatically if you don't care about monitoring the
607// process manually.
608func ExecBackground(t *testing.T, processName string, netNS *os.File, name string, args []string) (<-chan error, func() error) {
609 if netNS != nil {
610 // We use nsenter to enter the namespace.
611 // We can't use `setns` easily from Golang in the parent process because
612 // you can't execute the syscall in the forked child thread before it
613 // execs.
614 // We can't use `setns` easily from Golang in the child process because
615 // by the time you call it, the process has already created multiple
616 // threads.
617 args = append([]string{"--net=/proc/self/fd/3", name}, args...)
618 name = "nsenter"
619 }
620
621 cmd := exec.Command(name, args...)
622 if netNS != nil {
623 cmd.ExtraFiles = []*os.File{netNS}
624 }
625
626 out := &testWriter{
627 name: processName,
628 t: t,
629 }
630 t.Cleanup(out.Flush)
631 cmd.Stdout = out
632 cmd.Stderr = out
633 cmd.SysProcAttr = &syscall.SysProcAttr{
634 Pdeathsig: syscall.SIGTERM,
635 }
636 err := cmd.Start()
637 require.NoError(t, err)
638
639 waitErr := make(chan error, 1)
640 go func() {
641 err := cmd.Wait()
642 if err != nil && strings.Contains(err.Error(), "signal: terminated") {
643 err = nil
644 }
645 waitErr <- err
646 close(waitErr)
647 }()
648
649 closeFn := func() error {
650 _ = cmd.Process.Signal(syscall.SIGTERM)
651 select {
652 case <-time.After(5 * time.Second):
653 _ = cmd.Process.Kill()
654 case err := <-waitErr:
655 return err
656 }
657 return <-waitErr
658 }
659
660 t.Cleanup(func() {
661 select {
662 case err := <-waitErr:
663 if err != nil {
664 t.Log("subprocess exited: " + err.Error())
665 }

Callers 3

startSubprocessFunction · 0.92
CapturePacketsMethod · 0.85
startNginxFunction · 0.85

Calls 9

CommandMethod · 0.80
LogMethod · 0.80
CleanupMethod · 0.65
StartMethod · 0.65
WaitMethod · 0.65
SignalMethod · 0.65
KillMethod · 0.65
ContainsMethod · 0.45
ErrorMethod · 0.45

Tested by 1

startSubprocessFunction · 0.74