github.com/bigcommerce/nomad@v0.9.3-bc/client/logmon/logmon_test.go (about)

     1  package logmon
     2  
     3  import (
     4  	"crypto/rand"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"github.com/hashicorp/nomad/client/lib/fifo"
    12  	"github.com/hashicorp/nomad/helper/testlog"
    13  	"github.com/hashicorp/nomad/testutil"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestLogmon_Start_rotate(t *testing.T) {
    18  	require := require.New(t)
    19  	dir, err := ioutil.TempDir("", "nomadtest")
    20  	require.NoError(err)
    21  	defer os.RemoveAll(dir)
    22  	stdoutLog := "stdout"
    23  	stdoutFifoPath := filepath.Join(dir, "stdout.fifo")
    24  	stderrLog := "stderr"
    25  	stderrFifoPath := filepath.Join(dir, "stderr.fifo")
    26  
    27  	cfg := &LogConfig{
    28  		LogDir:        dir,
    29  		StdoutLogFile: stdoutLog,
    30  		StdoutFifo:    stdoutFifoPath,
    31  		StderrLogFile: stderrLog,
    32  		StderrFifo:    stderrFifoPath,
    33  		MaxFiles:      2,
    34  		MaxFileSizeMB: 1,
    35  	}
    36  
    37  	lm := NewLogMon(testlog.HCLogger(t))
    38  	require.NoError(lm.Start(cfg))
    39  
    40  	stdout, err := fifo.OpenWriter(stdoutFifoPath)
    41  	require.NoError(err)
    42  
    43  	// Write enough bytes such that the log is rotated
    44  	bytes1MB := make([]byte, 1024*1024)
    45  	_, err = rand.Read(bytes1MB)
    46  	require.NoError(err)
    47  
    48  	_, err = stdout.Write(bytes1MB)
    49  	require.NoError(err)
    50  
    51  	testutil.WaitForResult(func() (bool, error) {
    52  		_, err = os.Stat(filepath.Join(dir, "stdout.0"))
    53  		return err == nil, err
    54  	}, func(err error) {
    55  		require.NoError(err)
    56  	})
    57  	testutil.WaitForResult(func() (bool, error) {
    58  		_, err = os.Stat(filepath.Join(dir, "stdout.1"))
    59  		return err == nil, err
    60  	}, func(err error) {
    61  		require.NoError(err)
    62  	})
    63  	_, err = os.Stat(filepath.Join(dir, "stdout.2"))
    64  	require.Error(err)
    65  	require.NoError(lm.Stop())
    66  	require.NoError(lm.Stop())
    67  }
    68  
    69  // asserts that calling Start twice restarts the log rotator
    70  func TestLogmon_Start_restart(t *testing.T) {
    71  	require := require.New(t)
    72  	dir, err := ioutil.TempDir("", "nomadtest")
    73  	require.NoError(err)
    74  	defer os.RemoveAll(dir)
    75  	stdoutLog := "stdout"
    76  	stdoutFifoPath := filepath.Join(dir, "stdout.fifo")
    77  	stderrLog := "stderr"
    78  	stderrFifoPath := filepath.Join(dir, "stderr.fifo")
    79  
    80  	cfg := &LogConfig{
    81  		LogDir:        dir,
    82  		StdoutLogFile: stdoutLog,
    83  		StdoutFifo:    stdoutFifoPath,
    84  		StderrLogFile: stderrLog,
    85  		StderrFifo:    stderrFifoPath,
    86  		MaxFiles:      2,
    87  		MaxFileSizeMB: 1,
    88  	}
    89  
    90  	lm := NewLogMon(testlog.HCLogger(t))
    91  	impl, ok := lm.(*logmonImpl)
    92  	require.True(ok)
    93  	require.NoError(lm.Start(cfg))
    94  
    95  	stdout, err := fifo.OpenWriter(stdoutFifoPath)
    96  	require.NoError(err)
    97  	stderr, err := fifo.OpenWriter(stderrFifoPath)
    98  	require.NoError(err)
    99  
   100  	// Write a string and assert it was written to the file
   101  	_, err = stdout.Write([]byte("test\n"))
   102  	require.NoError(err)
   103  
   104  	testutil.WaitForResult(func() (bool, error) {
   105  		raw, err := ioutil.ReadFile(filepath.Join(dir, "stdout.0"))
   106  		if err != nil {
   107  			return false, err
   108  		}
   109  		return "test\n" == string(raw), fmt.Errorf("unexpected stdout %q", string(raw))
   110  	}, func(err error) {
   111  		require.NoError(err)
   112  	})
   113  	require.True(impl.tl.IsRunning())
   114  
   115  	// Close stdout and assert that logmon no longer writes to the file
   116  	require.NoError(stdout.Close())
   117  	require.NoError(stderr.Close())
   118  
   119  	testutil.WaitForResult(func() (bool, error) {
   120  		return !impl.tl.IsRunning(), fmt.Errorf("logmon is still running")
   121  	}, func(err error) {
   122  		require.NoError(err)
   123  	})
   124  
   125  	stdout, err = fifo.OpenWriter(stdoutFifoPath)
   126  	require.NoError(err)
   127  	stderr, err = fifo.OpenWriter(stderrFifoPath)
   128  	require.NoError(err)
   129  
   130  	_, err = stdout.Write([]byte("te"))
   131  	require.NoError(err)
   132  
   133  	testutil.WaitForResult(func() (bool, error) {
   134  		raw, err := ioutil.ReadFile(filepath.Join(dir, "stdout.0"))
   135  		if err != nil {
   136  			return false, err
   137  		}
   138  		return "test\n" == string(raw), fmt.Errorf("unexpected stdout %q", string(raw))
   139  	}, func(err error) {
   140  		require.NoError(err)
   141  	})
   142  
   143  	// Start logmon again and assert that it appended to the file
   144  	require.NoError(lm.Start(cfg))
   145  
   146  	stdout, err = fifo.OpenWriter(stdoutFifoPath)
   147  	require.NoError(err)
   148  	stderr, err = fifo.OpenWriter(stderrFifoPath)
   149  	require.NoError(err)
   150  
   151  	_, err = stdout.Write([]byte("st\n"))
   152  	require.NoError(err)
   153  	testutil.WaitForResult(func() (bool, error) {
   154  		raw, err := ioutil.ReadFile(filepath.Join(dir, "stdout.0"))
   155  		if err != nil {
   156  			return false, err
   157  		}
   158  
   159  		expected := "test\ntest\n" == string(raw)
   160  		return expected, fmt.Errorf("unexpected stdout %q", string(raw))
   161  	}, func(err error) {
   162  		require.NoError(err)
   163  	})
   164  }