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 }