github.com/thanos-io/thanos@v0.32.5/pkg/runutil/runutil_test.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package runutil
     5  
     6  import (
     7  	"io"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/efficientgo/core/testutil"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  type testCloser struct {
    18  	err error
    19  }
    20  
    21  func (c testCloser) Close() error {
    22  	return c.err
    23  }
    24  
    25  func TestCloseWithErrCapture(t *testing.T) {
    26  	for _, tcase := range []struct {
    27  		err    error
    28  		closer io.Closer
    29  
    30  		expectedErrStr string
    31  	}{
    32  		{
    33  			err:            nil,
    34  			closer:         testCloser{err: nil},
    35  			expectedErrStr: "",
    36  		},
    37  		{
    38  			err:            errors.New("test"),
    39  			closer:         testCloser{err: nil},
    40  			expectedErrStr: "test",
    41  		},
    42  		{
    43  			err:            nil,
    44  			closer:         testCloser{err: errors.New("test")},
    45  			expectedErrStr: "close: test",
    46  		},
    47  		{
    48  			err:            errors.New("test"),
    49  			closer:         testCloser{err: errors.New("test")},
    50  			expectedErrStr: "2 errors: test; close: test",
    51  		},
    52  	} {
    53  		if ok := t.Run("", func(t *testing.T) {
    54  			ret := tcase.err
    55  			CloseWithErrCapture(&ret, tcase.closer, "close")
    56  
    57  			if tcase.expectedErrStr == "" {
    58  				if ret != nil {
    59  					t.Error("Expected error to be nil")
    60  					t.Fail()
    61  				}
    62  			} else {
    63  				if ret == nil {
    64  					t.Error("Expected error to be not nil")
    65  					t.Fail()
    66  				}
    67  
    68  				if tcase.expectedErrStr != ret.Error() {
    69  					t.Errorf("%s != %s", tcase.expectedErrStr, ret.Error())
    70  					t.Fail()
    71  				}
    72  			}
    73  
    74  		}); !ok {
    75  			return
    76  		}
    77  	}
    78  }
    79  
    80  type loggerCapturer struct {
    81  	// WasCalled is true if the Log() function has been called.
    82  	WasCalled bool
    83  }
    84  
    85  func (lc *loggerCapturer) Log(keyvals ...interface{}) error {
    86  	lc.WasCalled = true
    87  	return nil
    88  }
    89  
    90  type emulatedCloser struct {
    91  	io.Reader
    92  
    93  	calls int
    94  }
    95  
    96  func (e *emulatedCloser) Close() error {
    97  	e.calls++
    98  	if e.calls == 1 {
    99  		return nil
   100  	}
   101  	if e.calls == 2 {
   102  		return errors.Wrap(os.ErrClosed, "can even be a wrapped one")
   103  	}
   104  	return errors.New("something very bad happened")
   105  }
   106  
   107  // newEmulatedCloser returns a ReadCloser with a Close method
   108  // that at first returns success but then returns that
   109  // it has been closed already. After that, it returns that
   110  // something very bad had happened.
   111  func newEmulatedCloser(r io.Reader) io.ReadCloser {
   112  	return &emulatedCloser{Reader: r}
   113  }
   114  
   115  func TestCloseMoreThanOnce(t *testing.T) {
   116  	lc := &loggerCapturer{}
   117  	r := newEmulatedCloser(strings.NewReader("somestring"))
   118  
   119  	CloseWithLogOnErr(lc, r, "should not be called")
   120  	CloseWithLogOnErr(lc, r, "should not be called")
   121  	testutil.Equals(t, false, lc.WasCalled)
   122  
   123  	CloseWithLogOnErr(lc, r, "should be called")
   124  	testutil.Equals(t, true, lc.WasCalled)
   125  }
   126  
   127  func TestDeleteAll(t *testing.T) {
   128  	dir := t.TempDir()
   129  
   130  	f, err := os.Create(filepath.Join(dir, "file1"))
   131  	testutil.Ok(t, err)
   132  	testutil.Ok(t, f.Close())
   133  
   134  	testutil.Ok(t, os.MkdirAll(filepath.Join(dir, "a"), os.ModePerm))
   135  	testutil.Ok(t, os.MkdirAll(filepath.Join(dir, "b"), os.ModePerm))
   136  	testutil.Ok(t, os.MkdirAll(filepath.Join(dir, "c", "innerc"), os.ModePerm))
   137  	f, err = os.Create(filepath.Join(dir, "a", "file2"))
   138  	testutil.Ok(t, err)
   139  	testutil.Ok(t, f.Close())
   140  	f, err = os.Create(filepath.Join(dir, "c", "file3"))
   141  	testutil.Ok(t, err)
   142  	testutil.Ok(t, f.Close())
   143  
   144  	testutil.Ok(t, DeleteAll(dir, "file1", "a", filepath.Join("c", "innerc")))
   145  
   146  	// Deleted.
   147  	_, err = os.Stat(filepath.Join(dir, "file1"))
   148  	testutil.Assert(t, os.IsNotExist(err))
   149  	_, err = os.Stat(filepath.Join(dir, "b/"))
   150  	testutil.Assert(t, os.IsNotExist(err))
   151  	_, err = os.Stat(filepath.Join(dir, "file3"))
   152  	testutil.Assert(t, os.IsNotExist(err))
   153  
   154  	// Exists.
   155  	_, err = os.Stat(filepath.Join(dir, "a", "file2"))
   156  	testutil.Ok(t, err)
   157  	_, err = os.Stat(filepath.Join(dir, "a/"))
   158  	testutil.Ok(t, err)
   159  	_, err = os.Stat(filepath.Join(dir, "c", "innerc"))
   160  	testutil.Ok(t, err)
   161  }
   162  
   163  func TestDeleteAll_ShouldReturnNoErrorIfDirectoryDoesNotExists(t *testing.T) {
   164  	dir := t.TempDir()
   165  	testutil.Ok(t, os.RemoveAll(dir))
   166  
   167  	// Calling DeleteAll() on a non-existent directory should return no error.
   168  	testutil.Ok(t, DeleteAll(dir))
   169  }