go.etcd.io/etcd@v3.3.27+incompatible/pkg/fileutil/purge_test.go (about) 1 // Copyright 2015 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package fileutil 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "os" 21 "path/filepath" 22 "reflect" 23 "testing" 24 "time" 25 ) 26 27 func TestPurgeFile(t *testing.T) { 28 dir, err := ioutil.TempDir("", "purgefile") 29 if err != nil { 30 t.Fatal(err) 31 } 32 defer os.RemoveAll(dir) 33 34 // minimal file set 35 for i := 0; i < 3; i++ { 36 f, ferr := os.Create(filepath.Join(dir, fmt.Sprintf("%d.test", i))) 37 if ferr != nil { 38 t.Fatal(err) 39 } 40 f.Close() 41 } 42 43 stop, purgec := make(chan struct{}), make(chan string, 10) 44 45 // keep 3 most recent files 46 errch := purgeFile(dir, "test", 3, time.Millisecond, stop, purgec, nil) 47 select { 48 case f := <-purgec: 49 t.Errorf("unexpected purge on %q", f) 50 case <-time.After(10 * time.Millisecond): 51 } 52 53 // rest of the files 54 for i := 4; i < 10; i++ { 55 go func(n int) { 56 f, ferr := os.Create(filepath.Join(dir, fmt.Sprintf("%d.test", n))) 57 if ferr != nil { 58 t.Fatal(err) 59 } 60 f.Close() 61 }(i) 62 } 63 64 // watch files purge away 65 for i := 4; i < 10; i++ { 66 select { 67 case <-purgec: 68 case <-time.After(time.Second): 69 t.Errorf("purge took too long") 70 } 71 } 72 73 fnames, rerr := ReadDir(dir) 74 if rerr != nil { 75 t.Fatal(rerr) 76 } 77 wnames := []string{"7.test", "8.test", "9.test"} 78 if !reflect.DeepEqual(fnames, wnames) { 79 t.Errorf("filenames = %v, want %v", fnames, wnames) 80 } 81 82 // no error should be reported from purge routine 83 select { 84 case f := <-purgec: 85 t.Errorf("unexpected purge on %q", f) 86 case err := <-errch: 87 t.Errorf("unexpected purge error %v", err) 88 case <-time.After(10 * time.Millisecond): 89 } 90 close(stop) 91 } 92 93 func TestPurgeFileHoldingLockFile(t *testing.T) { 94 dir, err := ioutil.TempDir("", "purgefile") 95 if err != nil { 96 t.Fatal(err) 97 } 98 defer os.RemoveAll(dir) 99 100 for i := 0; i < 10; i++ { 101 var f *os.File 102 f, err = os.Create(filepath.Join(dir, fmt.Sprintf("%d.test", i))) 103 if err != nil { 104 t.Fatal(err) 105 } 106 f.Close() 107 } 108 109 // create a purge barrier at 5 110 p := filepath.Join(dir, fmt.Sprintf("%d.test", 5)) 111 l, err := LockFile(p, os.O_WRONLY, PrivateFileMode) 112 if err != nil { 113 t.Fatal(err) 114 } 115 116 stop, purgec := make(chan struct{}), make(chan string, 10) 117 errch := purgeFile(dir, "test", 3, time.Millisecond, stop, purgec, nil) 118 119 for i := 0; i < 5; i++ { 120 select { 121 case <-purgec: 122 case <-time.After(time.Second): 123 t.Fatalf("purge took too long") 124 } 125 } 126 127 fnames, rerr := ReadDir(dir) 128 if rerr != nil { 129 t.Fatal(rerr) 130 } 131 132 wnames := []string{"5.test", "6.test", "7.test", "8.test", "9.test"} 133 if !reflect.DeepEqual(fnames, wnames) { 134 t.Errorf("filenames = %v, want %v", fnames, wnames) 135 } 136 137 select { 138 case s := <-purgec: 139 t.Errorf("unexpected purge %q", s) 140 case err = <-errch: 141 t.Errorf("unexpected purge error %v", err) 142 case <-time.After(10 * time.Millisecond): 143 } 144 145 // remove the purge barrier 146 if err = l.Close(); err != nil { 147 t.Fatal(err) 148 } 149 150 // wait for rest of purges (5, 6) 151 for i := 0; i < 2; i++ { 152 select { 153 case <-purgec: 154 case <-time.After(time.Second): 155 t.Fatalf("purge took too long") 156 } 157 } 158 159 fnames, rerr = ReadDir(dir) 160 if rerr != nil { 161 t.Fatal(rerr) 162 } 163 wnames = []string{"7.test", "8.test", "9.test"} 164 if !reflect.DeepEqual(fnames, wnames) { 165 t.Errorf("filenames = %v, want %v", fnames, wnames) 166 } 167 168 select { 169 case f := <-purgec: 170 t.Errorf("unexpected purge on %q", f) 171 case err := <-errch: 172 t.Errorf("unexpected purge error %v", err) 173 case <-time.After(10 * time.Millisecond): 174 } 175 176 close(stop) 177 }