github.com/smithx10/nomad@v0.9.1-rc1/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  		reader, err = readerOpenFn()
    54  		assert.NoError(t, err)
    55  		if err != nil {
    56  			return
    57  		}
    58  
    59  		_, err = io.Copy(&readBuf, reader)
    60  		assert.NoError(t, err)
    61  	}()
    62  
    63  	writer, err := OpenWriter(path)
    64  	require.NoError(err)
    65  	for _, b := range toWrite {
    66  		n, err := writer.Write(b)
    67  		require.NoError(err)
    68  		require.Equal(n, len(b))
    69  	}
    70  	require.NoError(writer.Close())
    71  	time.Sleep(500 * time.Millisecond)
    72  
    73  	wait.Wait()
    74  	require.NoError(reader.Close())
    75  
    76  	expected := "abc\ndef\nnomad\n"
    77  	require.Equal(expected, readBuf.String())
    78  
    79  	require.NoError(Remove(path))
    80  }
    81  
    82  // TestWriteClose asserts that when writer closes, subsequent Write() fails
    83  func TestWriteClose(t *testing.T) {
    84  	require := require.New(t)
    85  	var path string
    86  
    87  	if runtime.GOOS == "windows" {
    88  		path = "//./pipe/" + uuid.Generate()[:4]
    89  	} else {
    90  		dir, err := ioutil.TempDir("", "")
    91  		require.NoError(err)
    92  		defer os.RemoveAll(dir)
    93  
    94  		path = filepath.Join(dir, "fifo")
    95  	}
    96  
    97  	readerOpenFn, err := CreateAndRead(path)
    98  	require.NoError(err)
    99  	var reader io.ReadCloser
   100  
   101  	var readBuf bytes.Buffer
   102  	var wait sync.WaitGroup
   103  	wait.Add(1)
   104  	go func() {
   105  		defer wait.Done()
   106  
   107  		reader, err = readerOpenFn()
   108  		assert.NoError(t, err)
   109  		if err != nil {
   110  			return
   111  		}
   112  
   113  		_, err = io.Copy(&readBuf, reader)
   114  		assert.NoError(t, err)
   115  	}()
   116  
   117  	writer, err := OpenWriter(path)
   118  	require.NoError(err)
   119  
   120  	var count int
   121  	wait.Add(1)
   122  	go func() {
   123  		defer wait.Done()
   124  		for count = 0; count < int(^uint16(0)); count++ {
   125  			_, err := writer.Write([]byte(","))
   126  			if err != nil && IsClosedErr(err) {
   127  				break
   128  			}
   129  			require.NoError(err)
   130  			time.Sleep(5 * time.Millisecond)
   131  		}
   132  	}()
   133  
   134  	time.Sleep(500 * time.Millisecond)
   135  	require.NoError(writer.Close())
   136  	wait.Wait()
   137  
   138  	require.Equal(count, len(readBuf.String()))
   139  }