github.com/maxnasonov/afero@v1.8.4/mem/file_test.go (about) 1 package mem 2 3 import ( 4 "bytes" 5 "io" 6 "testing" 7 "time" 8 ) 9 10 func TestFileDataNameRace(t *testing.T) { 11 t.Parallel() 12 const someName = "someName" 13 const someOtherName = "someOtherName" 14 d := FileData{ 15 name: someName, 16 } 17 18 if d.Name() != someName { 19 t.Errorf("Failed to read correct Name, was %v", d.Name()) 20 } 21 22 ChangeFileName(&d, someOtherName) 23 if d.Name() != someOtherName { 24 t.Errorf("Failed to set Name, was %v", d.Name()) 25 } 26 27 go func() { 28 ChangeFileName(&d, someName) 29 }() 30 31 if d.Name() != someName && d.Name() != someOtherName { 32 t.Errorf("Failed to read either Name, was %v", d.Name()) 33 } 34 } 35 36 func TestFileDataModTimeRace(t *testing.T) { 37 t.Parallel() 38 someTime := time.Now() 39 someOtherTime := someTime.Add(1 * time.Minute) 40 41 d := FileData{ 42 modtime: someTime, 43 } 44 45 s := FileInfo{ 46 FileData: &d, 47 } 48 49 if s.ModTime() != someTime { 50 t.Errorf("Failed to read correct value, was %v", s.ModTime()) 51 } 52 53 SetModTime(&d, someOtherTime) 54 if s.ModTime() != someOtherTime { 55 t.Errorf("Failed to set ModTime, was %v", s.ModTime()) 56 } 57 58 go func() { 59 SetModTime(&d, someTime) 60 }() 61 62 if s.ModTime() != someTime && s.ModTime() != someOtherTime { 63 t.Errorf("Failed to read either modtime, was %v", s.ModTime()) 64 } 65 } 66 67 func TestFileDataModeRace(t *testing.T) { 68 t.Parallel() 69 const someMode = 0777 70 const someOtherMode = 0660 71 72 d := FileData{ 73 mode: someMode, 74 } 75 76 s := FileInfo{ 77 FileData: &d, 78 } 79 80 if s.Mode() != someMode { 81 t.Errorf("Failed to read correct value, was %v", s.Mode()) 82 } 83 84 SetMode(&d, someOtherMode) 85 if s.Mode() != someOtherMode { 86 t.Errorf("Failed to set Mode, was %v", s.Mode()) 87 } 88 89 go func() { 90 SetMode(&d, someMode) 91 }() 92 93 if s.Mode() != someMode && s.Mode() != someOtherMode { 94 t.Errorf("Failed to read either mode, was %v", s.Mode()) 95 } 96 } 97 98 // See https://github.com/spf13/afero/issues/286. 99 func TestFileWriteAt(t *testing.T) { 100 t.Parallel() 101 102 data := CreateFile("abc.txt") 103 f := NewFileHandle(data) 104 105 testData := []byte{1, 2, 3, 4, 5} 106 offset := len(testData) 107 108 // 5 zeros + testdata 109 _, err := f.WriteAt(testData, int64(offset)) 110 if err != nil { 111 t.Fatal(err) 112 } 113 114 // 2 * testdata 115 _, err = f.WriteAt(testData, 0) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 // 3 * testdata 121 _, err = f.WriteAt(testData, int64(offset*2)) 122 if err != nil { 123 t.Fatal(err) 124 } 125 126 // 3 * testdata + 5 zeros + testdata 127 _, err = f.WriteAt(testData, int64(offset*4)) 128 if err != nil { 129 t.Fatal(err) 130 } 131 132 // 5 * testdata 133 _, err = f.WriteAt(testData, int64(offset*3)) 134 if err != nil { 135 t.Fatal(err) 136 } 137 138 err = f.Close() 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 expected := bytes.Repeat(testData, 5) 144 if !bytes.Equal(expected, data.data) { 145 t.Fatalf("expected: %v, got: %v", expected, data.data) 146 } 147 } 148 149 func TestFileDataIsDirRace(t *testing.T) { 150 t.Parallel() 151 152 d := FileData{ 153 dir: true, 154 } 155 156 s := FileInfo{ 157 FileData: &d, 158 } 159 160 if s.IsDir() != true { 161 t.Errorf("Failed to read correct value, was %v", s.IsDir()) 162 } 163 164 go func() { 165 s.Lock() 166 d.dir = false 167 s.Unlock() 168 }() 169 170 //just logging the value to trigger a read: 171 t.Logf("Value is %v", s.IsDir()) 172 } 173 174 func TestFileDataSizeRace(t *testing.T) { 175 t.Parallel() 176 177 const someData = "Hello" 178 const someOtherDataSize = "Hello World" 179 180 d := FileData{ 181 data: []byte(someData), 182 dir: false, 183 } 184 185 s := FileInfo{ 186 FileData: &d, 187 } 188 189 if s.Size() != int64(len(someData)) { 190 t.Errorf("Failed to read correct value, was %v", s.Size()) 191 } 192 193 go func() { 194 s.Lock() 195 d.data = []byte(someOtherDataSize) 196 s.Unlock() 197 }() 198 199 //just logging the value to trigger a read: 200 t.Logf("Value is %v", s.Size()) 201 202 //Testing the Dir size case 203 d.dir = true 204 if s.Size() != int64(42) { 205 t.Errorf("Failed to read correct value for dir, was %v", s.Size()) 206 } 207 } 208 209 func TestFileReadAtSeekOffset(t *testing.T) { 210 t.Parallel() 211 212 fd := CreateFile("foo") 213 f := NewFileHandle(fd) 214 215 _, err := f.WriteString("TEST") 216 if err != nil { 217 t.Fatal(err) 218 } 219 offset, err := f.Seek(0, io.SeekStart) 220 if err != nil { 221 t.Fatal(err) 222 } 223 if offset != 0 { 224 t.Fail() 225 } 226 227 offsetBeforeReadAt, err := f.Seek(0, io.SeekCurrent) 228 if err != nil { 229 t.Fatal(err) 230 } 231 if offsetBeforeReadAt != 0 { 232 t.Fatal("expected 0") 233 } 234 235 b := make([]byte, 4) 236 n, err := f.ReadAt(b, 0) 237 if err != nil { 238 t.Fatal(err) 239 } 240 if n != 4 { 241 t.Fail() 242 } 243 if string(b) != "TEST" { 244 t.Fail() 245 } 246 247 offsetAfterReadAt, err := f.Seek(0, io.SeekCurrent) 248 if err != nil { 249 t.Fatal(err) 250 } 251 if offsetAfterReadAt != offsetBeforeReadAt { 252 t.Fatal("ReadAt should not affect offset") 253 } 254 255 err = f.Close() 256 if err != nil { 257 t.Fatal(err) 258 } 259 } 260 261 func TestFileWriteAndSeek(t *testing.T) { 262 fd := CreateFile("foo") 263 f := NewFileHandle(fd) 264 265 assert := func(expected bool, v ...interface{}) { 266 if !expected { 267 t.Helper() 268 t.Fatal(v...) 269 } 270 } 271 272 data4 := []byte{0, 1, 2, 3} 273 data20 := bytes.Repeat(data4, 5) 274 var off int64 275 276 for i := 0; i < 100; i++ { 277 // write 20 bytes 278 n, err := f.Write(data20) 279 assert(err == nil, err) 280 off += int64(n) 281 assert(n == len(data20), n) 282 assert(off == int64((i+1)*len(data20)), off) 283 284 // rewind to start and write 4 bytes there 285 cur, err := f.Seek(-off, io.SeekCurrent) 286 assert(err == nil, err) 287 assert(cur == 0, cur) 288 289 n, err = f.Write(data4) 290 assert(err == nil, err) 291 assert(n == len(data4), n) 292 293 // back at the end 294 cur, err = f.Seek(off-int64(n), io.SeekCurrent) 295 assert(err == nil, err) 296 assert(cur == off, cur, off) 297 } 298 }