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