github.com/influxdata/telegraf@v1.30.3/internal/process/process_test.go (about)

     1  //go:build !windows
     2  
     3  package process
     4  
     5  import (
     6  	"bufio"
     7  	"flag"
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  	"sync/atomic"
    12  	"syscall"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/influxdata/telegraf/testutil"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  // test that a restarting process resets pipes properly
    21  func TestRestartingRebindsPipes(t *testing.T) {
    22  	if testing.Short() {
    23  		t.Skip("Skipping long running test in short mode")
    24  	}
    25  
    26  	exe, err := os.Executable()
    27  	require.NoError(t, err)
    28  
    29  	p, err := New([]string{exe, "-external"}, []string{"INTERNAL_PROCESS_MODE=application"})
    30  	p.RestartDelay = 100 * time.Nanosecond
    31  	p.Log = testutil.Logger{}
    32  	require.NoError(t, err)
    33  
    34  	linesRead := int64(0)
    35  	p.ReadStdoutFn = func(r io.Reader) {
    36  		scanner := bufio.NewScanner(r)
    37  
    38  		for scanner.Scan() {
    39  			atomic.AddInt64(&linesRead, 1)
    40  		}
    41  	}
    42  
    43  	require.NoError(t, p.Start())
    44  
    45  	for atomic.LoadInt64(&linesRead) < 1 {
    46  		time.Sleep(1 * time.Millisecond)
    47  	}
    48  
    49  	require.NoError(t, syscall.Kill(p.Pid(), syscall.SIGKILL))
    50  
    51  	for atomic.LoadInt64(&linesRead) < 2 {
    52  		time.Sleep(1 * time.Millisecond)
    53  	}
    54  
    55  	// the mainLoopWg.Wait() call p.Stop() makes takes multiple seconds to complete
    56  	p.Stop()
    57  }
    58  
    59  var external = flag.Bool("external", false,
    60  	"if true, run externalProcess instead of tests")
    61  
    62  func TestMain(m *testing.M) {
    63  	flag.Parse()
    64  	runMode := os.Getenv("INTERNAL_PROCESS_MODE")
    65  	if *external && runMode == "application" {
    66  		externalProcess()
    67  		os.Exit(0)
    68  	}
    69  	code := m.Run()
    70  	os.Exit(code)
    71  }
    72  
    73  // externalProcess is an external "misbehaving" process that won't exit
    74  // cleanly.
    75  func externalProcess() {
    76  	wait := make(chan int)
    77  	fmt.Fprintln(os.Stdout, "started")
    78  	<-wait
    79  	os.Exit(2) //nolint:revive // os.Exit called intentionally
    80  }