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 }