github.com/saymoon/flop@v0.1.6-0.20201205092451-00912199cc96/copy_linux_test.go (about)

     1  // +build linux
     2  
     3  package flop
     4  
     5  import (
     6  	"fmt"
     7  	"github.com/stretchr/testify/assert"
     8  	"io/ioutil"
     9  	"os"
    10  	"testing"
    11  )
    12  
    13  func TestFileCopyOnDstWithInvalidPermissionsReturnsNoErrorWhenAtomic(t *testing.T) {
    14  	assert := assert.New(t)
    15  	// create and write to source inFile
    16  	src := tmpFile()
    17  	content := []byte("foo")
    18  	assert.Nil(ioutil.WriteFile(src, content, 0644))
    19  
    20  	dst := tmpFile()
    21  	// explicitly set our dst inFile perms so that we cannot copy
    22  	assert.Nil(os.Chmod(dst, 0040))
    23  
    24  	assert.Nil(Copy(src, dst, Options{Atomic: true}))
    25  
    26  	// make sure we can read out the correct content
    27  	assert.Nil(os.Chmod(dst, 0655))
    28  	b, err := ioutil.ReadFile(dst)
    29  	assert.Nil(err)
    30  	assert.Equal(content, b)
    31  
    32  	// change perms back to ensure we can read to verify content
    33  	assert.Nil(os.Chmod(dst, 0655))
    34  }
    35  
    36  func TestFileIsSymlink(t *testing.T) {
    37  	assert := assert.New(t)
    38  	old := tmpFile()
    39  	new := tmpFilePathUnused()
    40  	assert.Nil(os.Symlink(old, new))
    41  
    42  	newFileInfo, err := os.Lstat(new)
    43  	assert.Nil(err)
    44  	f := File{
    45  		Path:           new,
    46  		fileInfoOnInit: newFileInfo,
    47  	}
    48  	assert.True(f.isSymlink())
    49  }
    50  
    51  func TestIsSymlinkFailsWithRegularFile(t *testing.T) {
    52  	assert := assert.New(t)
    53  	tmp := tmpFile()
    54  	f := NewFile(tmp)
    55  	f.setInfo()
    56  	assert.False(f.isSymlink())
    57  }
    58  
    59  func TestPermissionsAfterCopy(t *testing.T) {
    60  	assert := assert.New(t)
    61  	tests := []struct {
    62  		name             string
    63  		atomic           bool
    64  		dstShouldExist   bool
    65  		srcPerms         os.FileMode
    66  		expectedDstPerms os.FileMode
    67  	}{
    68  		{
    69  			name:             "preserve_src_perms_when_dst_not_exist_0655",
    70  			dstShouldExist:   false,
    71  			srcPerms:         os.FileMode(0655),
    72  			expectedDstPerms: os.FileMode(0655),
    73  		},
    74  		{
    75  			name:             "preserve_src_perms_when_dst_not_exist_0777",
    76  			dstShouldExist:   false,
    77  			srcPerms:         os.FileMode(0777),
    78  			expectedDstPerms: os.FileMode(0777),
    79  		},
    80  		{
    81  			name:             "preserve_src_perms_when_dst_not_exist_0741",
    82  			dstShouldExist:   false,
    83  			srcPerms:         os.FileMode(0741),
    84  			expectedDstPerms: os.FileMode(0741),
    85  		},
    86  		{
    87  			name:             "preserve_dst_perms_when_dst_exists_0654",
    88  			dstShouldExist:   true,
    89  			srcPerms:         os.FileMode(0655),
    90  			expectedDstPerms: os.FileMode(0654),
    91  		},
    92  		{
    93  			name:             "preserve_dst_perms_when_dst_exists_0651",
    94  			dstShouldExist:   true,
    95  			srcPerms:         os.FileMode(0655),
    96  			expectedDstPerms: os.FileMode(0651),
    97  		},
    98  		{
    99  			name:             "preserve_dst_perms_when_dst_exists_0777",
   100  			dstShouldExist:   true,
   101  			srcPerms:         os.FileMode(0655),
   102  			expectedDstPerms: os.FileMode(0777),
   103  		},
   104  		{
   105  			name:             "preserve_dst_perms_when_dst_exists_0666",
   106  			atomic:           false,
   107  			dstShouldExist:   true,
   108  			srcPerms:         os.FileMode(0655),
   109  			expectedDstPerms: os.FileMode(0666),
   110  		},
   111  	}
   112  
   113  	for _, tt := range tests {
   114  		t.Run(tt.name, func(t *testing.T) {
   115  			src := tmpFile()
   116  			assert.Nil(os.Chmod(src, tt.srcPerms))
   117  			var dst string
   118  			if tt.dstShouldExist {
   119  				dst = tmpFile()
   120  				// set dst perms to ensure they are distinct beforehand
   121  				assert.Nil(os.Chmod(dst, tt.expectedDstPerms))
   122  			} else {
   123  				dst = tmpFilePathUnused()
   124  			}
   125  
   126  			assert.Nil(Copy(src, dst, Options{
   127  				Atomic:       tt.atomic,
   128  				InfoLogFunc:  infoLogger,
   129  				DebugLogFunc: debugLogger,
   130  			}), "name: %s", tt.name)
   131  
   132  			// check our perms
   133  			d, err := os.Stat(dst)
   134  			assert.Nil(err)
   135  			dstPerms := d.Mode()
   136  			assert.Equal(fmt.Sprint(tt.expectedDstPerms), fmt.Sprint(dstPerms))
   137  		})
   138  	}
   139  }
   140  
   141  func TestCopyingSymLinks(t *testing.T) {
   142  	assert := assert.New(t)
   143  	src := tmpFile()
   144  	content := []byte("foo")
   145  	assert.Nil(ioutil.WriteFile(src, content, 0655))
   146  	srcSym := tmpFilePathUnused()
   147  	assert.Nil(os.Symlink(src, srcSym))
   148  
   149  	dstSym := tmpFilePathUnused()
   150  
   151  	// copy sym link
   152  	assert.Nil(SimpleCopy(srcSym, dstSym))
   153  
   154  	// verify that dst is a sym link
   155  	sfi, err := os.Lstat(dstSym)
   156  	assert.Nil(err)
   157  	assert.True(sfi.Mode()&os.ModeSymlink != 0)
   158  
   159  	// verify content is the same in symlinked file
   160  	b, err := ioutil.ReadFile(dstSym)
   161  	assert.Nil(err)
   162  	assert.Equal(content, b)
   163  }
   164  
   165  func TestCreatingHardLinksWithLinkOpt(t *testing.T) {
   166  	assert := assert.New(t)
   167  	tests := []struct {
   168  		name string
   169  		src  string
   170  		dst  string
   171  		opts Options
   172  	}{
   173  		{
   174  			name: "absent_dst",
   175  			src:  tmpFile(),
   176  			dst:  tmpFilePathUnused(),
   177  			opts: Options{Link: true},
   178  		},
   179  		//{  // TODO setup when force is implemented
   180  		//	name: " existing_dst",
   181  		//	src: tmpFile(),
   182  		//	dst: tmpFile(),
   183  		//	opts: Options{Link: true, Force: true},
   184  		//},
   185  	}
   186  	for _, tt := range tests {
   187  		t.Run(tt.name, func(t *testing.T) {
   188  			content := []byte("foo")
   189  			assert.Nil(ioutil.WriteFile(tt.src, content, 0655))
   190  
   191  			assert.Nil(Copy(tt.src, tt.dst, tt.opts))
   192  
   193  			sFI, err := os.Stat(tt.src)
   194  			assert.Nil(err)
   195  			dFI, err := os.Stat(tt.dst)
   196  			assert.Nil(err)
   197  			assert.True(os.SameFile(sFI, dFI))
   198  		})
   199  	}
   200  }