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  }