github.com/bigcommerce/nomad@v0.9.3-bc/client/lib/fifo/fifo_test.go (about)

     1  package fifo
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"runtime"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/hashicorp/nomad/helper/uuid"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  // TestFIFO tests basic behavior, and that reader closes when writer closes
    20  func TestFIFO(t *testing.T) {
    21  	require := require.New(t)
    22  	var path string
    23  
    24  	if runtime.GOOS == "windows" {
    25  		path = "//./pipe/fifo"
    26  	} else {
    27  		dir, err := ioutil.TempDir("", "")
    28  		require.NoError(err)
    29  		defer os.RemoveAll(dir)
    30  
    31  		path = filepath.Join(dir, "fifo")
    32  	}
    33  
    34  	readerOpenFn, err := CreateAndRead(path)
    35  	require.NoError(err)
    36  
    37  	var reader io.ReadCloser
    38  
    39  	toWrite := [][]byte{
    40  		[]byte("abc\n"),
    41  		[]byte(""),
    42  		[]byte("def\n"),
    43  		[]byte("nomad"),
    44  		[]byte("\n"),
    45  	}
    46  
    47  	var readBuf bytes.Buffer
    48  	var wait sync.WaitGroup
    49  	wait.Add(1)
    50  	go func() {
    51  		defer wait.Done()
    52  
    53  		var err error
    54  		reader, err = readerOpenFn()
    55  		assert.NoError(t, err)
    56  		if err != nil {
    57  			return
    58  		}
    59  
    60  		_, err = io.Copy(&readBuf, reader)
    61  		assert.NoError(t, err)
    62  	}()
    63  
    64  	writer, err := OpenWriter(path)
    65  	require.NoError(err)
    66  	for _, b := range toWrite {
    67  		n, err := writer.Write(b)
    68  		require.NoError(err)
    69  		require.Equal(n, len(b))
    70  	}
    71  	require.NoError(writer.Close())
    72  	time.Sleep(500 * time.Millisecond)
    73  
    74  	wait.Wait()
    75  	require.NoError(reader.Close())
    76  
    77  	expected := "abc\ndef\nnomad\n"
    78  	require.Equal(expected, readBuf.String())
    79  
    80  	require.NoError(Remove(path))
    81  }
    82  
    83  // TestWriteClose asserts that when writer closes, subsequent Write() fails
    84  func TestWriteClose(t *testing.T) {
    85  	require := require.New(t)
    86  	var path string
    87  
    88  	if runtime.GOOS == "windows" {
    89  		path = "//./pipe/" + uuid.Generate()[:4]
    90  	} else {
    91  		dir, err := ioutil.TempDir("", "")
    92  		require.NoError(err)
    93  		defer os.RemoveAll(dir)
    94  
    95  		path = filepath.Join(dir, "fifo")
    96  	}
    97  
    98  	readerOpenFn, err := CreateAndRead(path)
    99  	require.NoError(err)
   100  	var reader io.ReadCloser
   101  
   102  	var readBuf bytes.Buffer
   103  	var wait sync.WaitGroup
   104  	wait.Add(1)
   105  	go func() {
   106  		defer wait.Done()
   107  
   108  		var err error
   109  		reader, err = readerOpenFn()
   110  		assert.NoError(t, err)
   111  		if err != nil {
   112  			return
   113  		}
   114  
   115  		_, err = io.Copy(&readBuf, reader)
   116  		assert.NoError(t, err)
   117  	}()
   118  
   119  	writer, err := OpenWriter(path)
   120  	require.NoError(err)
   121  
   122  	var count int
   123  	wait.Add(1)
   124  	go func() {
   125  		defer wait.Done()
   126  		for count = 0; count < int(^uint16(0)); count++ {
   127  			_, err := writer.Write([]byte(","))
   128  			if err != nil && IsClosedErr(err) {
   129  				break
   130  			}
   131  			require.NoError(err)
   132  			time.Sleep(5 * time.Millisecond)
   133  		}
   134  	}()
   135  
   136  	time.Sleep(500 * time.Millisecond)
   137  	require.NoError(writer.Close())
   138  	wait.Wait()
   139  
   140  	require.Equal(count, len(readBuf.String()))
   141  }