github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/fileutil/fileutil_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package fileutil 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "os" 13 "path/filepath" 14 "testing" 15 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestFileExists(t *testing.T) { 20 t.Run("non-existent-file", func(t *testing.T) { 21 exists, size, err := FileExists("/non-existent-file") 22 require.NoError(t, err) 23 require.False(t, exists) 24 require.Equal(t, int64(0), size) 25 }) 26 27 t.Run("dir-path", func(t *testing.T) { 28 testPath := testPath(t) 29 defer os.RemoveAll(testPath) 30 31 exists, size, err := FileExists(testPath) 32 require.EqualError(t, err, fmt.Sprintf("the supplied path [%s] is a dir", testPath)) 33 require.False(t, exists) 34 require.Equal(t, int64(0), size) 35 }) 36 37 t.Run("empty-file", func(t *testing.T) { 38 testPath := testPath(t) 39 defer os.RemoveAll(testPath) 40 41 file := filepath.Join(testPath, "empty-file") 42 f, err := os.Create(file) 43 require.NoError(t, err) 44 defer f.Close() 45 46 exists, size, err := FileExists(file) 47 require.NoError(t, err) 48 require.True(t, exists) 49 require.Equal(t, int64(0), size) 50 }) 51 52 t.Run("file-with-content", func(t *testing.T) { 53 testPath := testPath(t) 54 defer os.RemoveAll(testPath) 55 56 file := filepath.Join(testPath, "empty-file") 57 contents := []byte("some random contents") 58 ioutil.WriteFile(file, []byte(contents), 0o644) 59 exists, size, err := FileExists(file) 60 require.NoError(t, err) 61 require.True(t, exists) 62 require.Equal(t, int64(len(contents)), size) 63 }) 64 } 65 66 func TestDirExists(t *testing.T) { 67 t.Run("non-existent-path", func(t *testing.T) { 68 testPath := testPath(t) 69 defer os.RemoveAll(testPath) 70 71 exists, err := DirExists(filepath.Join(testPath, "non-existent-path")) 72 require.NoError(t, err) 73 require.False(t, exists) 74 }) 75 76 t.Run("dir-exists", func(t *testing.T) { 77 testPath := testPath(t) 78 defer os.RemoveAll(testPath) 79 80 exists, err := DirExists(testPath) 81 require.NoError(t, err) 82 require.True(t, exists) 83 }) 84 85 t.Run("file-exists", func(t *testing.T) { 86 testPath := testPath(t) 87 defer os.RemoveAll(testPath) 88 89 file := filepath.Join(testPath, "empty-file") 90 f, err := os.Create(file) 91 require.NoError(t, err) 92 defer f.Close() 93 94 exists, err := DirExists(file) 95 require.EqualError(t, err, fmt.Sprintf("the supplied path [%s] exists but is not a dir", file)) 96 require.False(t, exists) 97 }) 98 } 99 100 func TestDirEmpty(t *testing.T) { 101 t.Run("non-existent-dir", func(t *testing.T) { 102 testPath := testPath(t) 103 defer os.RemoveAll(testPath) 104 105 dir := filepath.Join(testPath, "non-existent-dir") 106 _, err := DirEmpty(dir) 107 require.EqualError(t, err, fmt.Sprintf("error opening dir [%s]: open %s: no such file or directory", dir, dir)) 108 }) 109 110 t.Run("empty-dir", func(t *testing.T) { 111 testPath := testPath(t) 112 defer os.RemoveAll(testPath) 113 114 dir := filepath.Join(testPath, "empty-dir") 115 require.NoError(t, os.MkdirAll(dir, 0o755)) 116 empty, err := DirEmpty(dir) 117 require.NoError(t, err) 118 require.True(t, empty) 119 }) 120 121 t.Run("dir-has-file", func(t *testing.T) { 122 testPath := testPath(t) 123 defer os.RemoveAll(testPath) 124 125 dir := filepath.Join(testPath, "non-empty-dir") 126 require.NoError(t, os.MkdirAll(dir, 0o755)) 127 file := filepath.Join(testPath, "non-empty-dir", "some-random-file") 128 require.NoError(t, ioutil.WriteFile(file, []byte("some-random-text"), 0o644)) 129 empty, err := DirEmpty(dir) 130 require.NoError(t, err) 131 require.False(t, empty) 132 }) 133 134 t.Run("dir-has-subdir", func(t *testing.T) { 135 testPath := testPath(t) 136 defer os.RemoveAll(testPath) 137 138 dir := filepath.Join(testPath, "non-empty-dir") 139 subdir := filepath.Join(testPath, "non-empty-dir", "some-random-dir") 140 require.NoError(t, os.MkdirAll(subdir, 0o755)) 141 empty, err := DirEmpty(dir) 142 require.NoError(t, err) 143 require.False(t, empty) 144 }) 145 } 146 147 func TestCreateDirIfMissing(t *testing.T) { 148 t.Run("non-existent-dir", func(t *testing.T) { 149 testPath := testPath(t) 150 defer os.RemoveAll(testPath) 151 152 dir := filepath.Join(testPath, "non-existent-dir") 153 empty, err := CreateDirIfMissing(dir) 154 require.NoError(t, err) 155 require.True(t, empty) 156 }) 157 158 t.Run("existing-dir", func(t *testing.T) { 159 testPath := testPath(t) 160 defer os.RemoveAll(testPath) 161 162 dir := filepath.Join(testPath, "empty-dir") 163 require.NoError(t, os.MkdirAll(dir, 0o755)) 164 165 empty, err := CreateDirIfMissing(dir) 166 require.NoError(t, err) 167 require.True(t, empty) 168 169 require.NoError(t, ioutil.WriteFile(filepath.Join(dir, "some-random-file"), []byte("some-random-text"), 0o644)) 170 empty, err = CreateDirIfMissing(dir) 171 require.NoError(t, err) 172 require.False(t, empty) 173 }) 174 175 t.Run("cannot-create-dir", func(t *testing.T) { 176 testPath := testPath(t) 177 defer os.RemoveAll(testPath) 178 179 path := filepath.Join(testPath, "some-random-file") 180 require.NoError(t, ioutil.WriteFile(path, []byte("some-random-text"), 0o644)) 181 empty, err := CreateDirIfMissing(path) 182 require.EqualError(t, err, fmt.Sprintf("error while creating dir: %s: mkdir %s: not a directory", path, path)) 183 require.False(t, empty) 184 }) 185 } 186 187 func TestListSubdirs(t *testing.T) { 188 t.Run("only-subdirs", func(t *testing.T) { 189 testPath := testPath(t) 190 defer os.RemoveAll(testPath) 191 192 childFolders := []string{".childFolder1", "childFolder2", "childFolder3"} 193 for _, folder := range childFolders { 194 require.NoError(t, os.MkdirAll(filepath.Join(testPath, folder), 0o755)) 195 } 196 subFolders, err := ListSubdirs(testPath) 197 require.NoError(t, err) 198 require.Equal(t, subFolders, childFolders) 199 }) 200 201 t.Run("only-file", func(t *testing.T) { 202 testPath := testPath(t) 203 defer os.RemoveAll(testPath) 204 205 require.NoError(t, ioutil.WriteFile(filepath.Join(testPath, "some-random-file"), []byte("random-text"), 0o644)) 206 subFolders, err := ListSubdirs(testPath) 207 require.NoError(t, err) 208 require.Len(t, subFolders, 0) 209 }) 210 211 t.Run("empty-dir", func(t *testing.T) { 212 testPath := testPath(t) 213 defer os.RemoveAll(testPath) 214 215 subFolders, err := ListSubdirs(testPath) 216 require.NoError(t, err) 217 require.Len(t, subFolders, 0) 218 }) 219 220 t.Run("non-existent-dir", func(t *testing.T) { 221 testPath := testPath(t) 222 defer os.RemoveAll(testPath) 223 224 dir := filepath.Join(testPath, "non-existent-dir") 225 _, err := ListSubdirs(dir) 226 require.EqualError(t, err, fmt.Sprintf("error reading dir %s: open %s: no such file or directory", dir, dir)) 227 }) 228 } 229 230 func TestCreateAndSyncFileAtomically(t *testing.T) { 231 t.Run("green-path", func(t *testing.T) { 232 testPath := testPath(t) 233 defer os.RemoveAll(testPath) 234 235 content := []byte("some random content") 236 err := CreateAndSyncFileAtomically(testPath, "tmpFile", "finalFile", content, 0o644) 237 require.NoError(t, err) 238 require.NoFileExists(t, filepath.Join(testPath, "tmpFile")) 239 contentRetrieved, err := ioutil.ReadFile(filepath.Join(testPath, "finalFile")) 240 require.NoError(t, err) 241 require.Equal(t, content, contentRetrieved) 242 }) 243 244 t.Run("dir-doesnot-exist", func(t *testing.T) { 245 testPath := testPath(t) 246 defer os.RemoveAll(testPath) 247 248 content := []byte("some random content") 249 dir := filepath.Join(testPath, "non-exitent-dir") 250 tmpFile := filepath.Join(dir, "tmpFile") 251 err := CreateAndSyncFileAtomically(dir, "tmpFile", "finalFile", content, 0o644) 252 require.EqualError(t, err, fmt.Sprintf("error while creating file:%s: open %s: no such file or directory", tmpFile, tmpFile)) 253 }) 254 255 t.Run("tmp-file-already-exists", func(t *testing.T) { 256 testPath := testPath(t) 257 defer os.RemoveAll(testPath) 258 259 content := []byte("some random content") 260 tmpFile := filepath.Join(testPath, "tmpFile") 261 err := ioutil.WriteFile(tmpFile, []byte("existing-contents"), 0o644) 262 require.NoError(t, err) 263 err = CreateAndSyncFileAtomically(testPath, "tmpFile", "finalFile", content, 0o644) 264 require.EqualError(t, err, fmt.Sprintf("error while creating file:%s: open %s: file exists", tmpFile, tmpFile)) 265 }) 266 267 t.Run("final-file-already-exists", func(t *testing.T) { 268 testPath := testPath(t) 269 defer os.RemoveAll(testPath) 270 271 content := []byte("some random content") 272 finalFile := filepath.Join(testPath, "finalFile") 273 err := ioutil.WriteFile(finalFile, []byte("existing-contents"), 0o644) 274 require.NoError(t, err) 275 err = CreateAndSyncFileAtomically(testPath, "tmpFile", "finalFile", content, 0o644) 276 require.NoError(t, err) 277 contentRetrieved, err := ioutil.ReadFile(filepath.Join(testPath, "finalFile")) 278 require.NoError(t, err) 279 require.Equal(t, content, contentRetrieved) 280 }) 281 282 t.Run("rename-returns-error", func(t *testing.T) { 283 testPath := testPath(t) 284 defer os.RemoveAll(testPath) 285 286 content := []byte("some random content") 287 tmpFile := filepath.Join(testPath, "tmpFile") 288 finalFile := filepath.Join(testPath, "finalFile") 289 require.NoError(t, os.Mkdir(finalFile, 0o644)) 290 err := CreateAndSyncFileAtomically(testPath, "tmpFile", "finalFile", content, 0o644) 291 require.EqualError(t, err, fmt.Sprintf("rename %s %s: file exists", tmpFile, finalFile)) 292 }) 293 } 294 295 func TestSyncDir(t *testing.T) { 296 t.Run("green-path", func(t *testing.T) { 297 testPath := testPath(t) 298 defer os.RemoveAll(testPath) 299 300 require.NoError(t, SyncDir(testPath)) 301 require.NoError(t, SyncParentDir(testPath)) 302 }) 303 304 t.Run("non-existent-dir", func(t *testing.T) { 305 require.EqualError(t, SyncDir("non-existent-dir"), "error while opening dir:non-existent-dir: open non-existent-dir: no such file or directory") 306 }) 307 } 308 309 func TestRemoveContents(t *testing.T) { 310 t.Run("non-empty-dir", func(t *testing.T) { 311 testPath := testPath(t) 312 defer os.RemoveAll(testPath) 313 314 // create files and a non-empty subdir under testPath to test RemoveContents 315 require.NoError(t, CreateAndSyncFile(filepath.Join(testPath, "file1"), []byte("test-removecontents"), 0o644)) 316 require.NoError(t, CreateAndSyncFile(filepath.Join(testPath, "file2"), []byte("test-removecontents"), 0o644)) 317 require.NoError(t, os.MkdirAll(filepath.Join(testPath, "non-empty-dir", "some-random-dir"), 0o755)) 318 require.NoError(t, ioutil.WriteFile(filepath.Join(testPath, "non-empty-dir", "some-random-file"), []byte("test-subdir-removecontents"), 0o644)) 319 320 require.NoError(t, RemoveContents(testPath)) 321 empty, err := DirEmpty(testPath) 322 require.NoError(t, err) 323 require.True(t, empty) 324 }) 325 326 t.Run("empty-dir", func(t *testing.T) { 327 testPath := testPath(t) 328 defer os.RemoveAll(testPath) 329 330 require.NoError(t, RemoveContents(testPath)) 331 empty, err := DirEmpty(testPath) 332 require.NoError(t, err) 333 require.True(t, empty) 334 }) 335 336 t.Run("non-existent-dir", func(t *testing.T) { 337 testPath := testPath(t) 338 defer os.RemoveAll(testPath) 339 require.NoError(t, RemoveContents(filepath.Join(testPath, "non-existent-dir"))) 340 }) 341 } 342 343 func testPath(t *testing.T) string { 344 path, err := ioutil.TempDir("", "fileutiltest-") 345 require.NoError(t, err) 346 return path 347 }