github.com/Files-com/files-sdk-go/v2@v2.1.2/file/pathspec_test.go (about) 1 package file 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "strings" 10 "sync" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 15 "github.com/stretchr/testify/assert" 16 ) 17 18 type pathSpecEntry struct { 19 dir bool 20 path string 21 preexisting bool 22 } 23 type pathSpecArgs struct { 24 src string 25 dest string 26 } 27 28 type pathSpecTest struct { 29 name string 30 args pathSpecArgs 31 dest []pathSpecEntry 32 src []pathSpecEntry 33 } 34 35 func pathSpec(srcPathSeparator string, destPathSeparator string) []pathSpecTest { 36 return []pathSpecTest{ 37 { 38 name: "copy foo to dest", 39 args: pathSpecArgs{ 40 src: join(srcPathSeparator, "src", "foo"), 41 dest: "dest", 42 }, 43 src: []pathSpecEntry{ 44 {dir: true, path: "src"}, 45 {dir: true, path: join(srcPathSeparator, "src", "foo")}, 46 {dir: false, path: join(srcPathSeparator, "src", "foo", "baz.txt")}, 47 }, 48 dest: []pathSpecEntry{ 49 {dir: true, path: "dest", preexisting: true}, 50 {dir: true, path: join(destPathSeparator, "dest", "foo")}, 51 {dir: false, path: join(destPathSeparator, "dest", "foo", "baz.txt")}, 52 }, 53 }, 54 { 55 name: "copy contents of foo to dest/foo", 56 args: pathSpecArgs{ 57 src: join(srcPathSeparator, "src", "foo") + srcPathSeparator, 58 dest: join(destPathSeparator, "dest", "foo"), 59 }, 60 src: []pathSpecEntry{ 61 {dir: true, path: "src"}, 62 {dir: true, path: join(srcPathSeparator, "src", "foo")}, 63 {dir: false, path: join(srcPathSeparator, "src", "foo", "baz.txt")}, 64 }, 65 dest: []pathSpecEntry{ 66 {dir: true, path: "dest", preexisting: true}, 67 {dir: true, path: join(destPathSeparator, "dest", "foo"), preexisting: true}, 68 {dir: false, path: join(destPathSeparator, "dest", "foo", "baz.txt")}, 69 }, 70 }, 71 { 72 name: "copy contents of foo to dest/bar", 73 args: pathSpecArgs{ 74 src: join(srcPathSeparator, "src", "foo") + srcPathSeparator, 75 dest: join(destPathSeparator, "dest", "bar"), 76 }, 77 src: []pathSpecEntry{ 78 {dir: true, path: "src"}, 79 {dir: true, path: join(srcPathSeparator, "src", "foo")}, 80 {dir: false, path: join(srcPathSeparator, "src", "foo", "baz.txt")}, 81 }, 82 dest: []pathSpecEntry{ 83 {dir: true, path: "dest", preexisting: true}, 84 {dir: true, path: join(destPathSeparator, "dest", "bar"), preexisting: true}, 85 {dir: false, path: join(destPathSeparator, "dest", "bar", "baz.txt")}, 86 }, 87 }, 88 { 89 name: "copy baz.txt to dest", 90 args: pathSpecArgs{ 91 src: join(srcPathSeparator, "src", "foo", "baz.txt"), 92 dest: join(destPathSeparator, "dest", "baz.txt"), 93 }, 94 src: []pathSpecEntry{ 95 {dir: true, path: join(srcPathSeparator, "src")}, 96 {dir: true, path: join(srcPathSeparator, "src", "foo")}, 97 {dir: false, path: join(srcPathSeparator, "src", "foo", "baz.txt")}, 98 }, 99 dest: []pathSpecEntry{ 100 {dir: true, path: "dest", preexisting: true}, 101 {dir: false, path: join(destPathSeparator, "dest", "baz.txt")}, 102 }, 103 }, 104 { 105 name: "copy baz.txt to dest without name", 106 args: pathSpecArgs{ 107 src: join(srcPathSeparator, "src", "foo", "baz.txt"), 108 dest: "dest" + destPathSeparator, 109 }, 110 src: []pathSpecEntry{ 111 {dir: true, path: "src"}, 112 {dir: true, path: join(srcPathSeparator, "src", "foo")}, 113 {dir: false, path: join(srcPathSeparator, "src", "foo", "baz.txt")}, 114 }, 115 dest: []pathSpecEntry{ 116 {dir: true, path: "dest", preexisting: true}, 117 {dir: false, path: join(destPathSeparator, "dest", "baz.txt")}, 118 }, 119 }, 120 { 121 name: "copy baz.txt to dest with rename", 122 args: pathSpecArgs{ 123 src: join(srcPathSeparator, "src", "foo", "baz.txt"), 124 dest: join(destPathSeparator, "dest", "taz.txt"), 125 }, 126 src: []pathSpecEntry{ 127 {dir: true, path: "src"}, 128 {dir: true, path: join(srcPathSeparator, "src", "foo")}, 129 {dir: false, path: join(srcPathSeparator, "src", "foo", "baz.txt")}, 130 }, 131 dest: []pathSpecEntry{ 132 {dir: true, path: "dest", preexisting: true}, 133 {dir: false, path: join(destPathSeparator, "dest/taz.txt")}, 134 }, 135 }, 136 { 137 name: "copy baz.txt to current working directory", 138 args: pathSpecArgs{ 139 src: join(srcPathSeparator, "src", "foo", "baz.txt"), 140 dest: "", 141 }, 142 src: []pathSpecEntry{ 143 {dir: true, path: "src"}, 144 {dir: true, path: join(srcPathSeparator, "src", "foo")}, 145 {dir: false, path: join(srcPathSeparator, "src", "foo", "baz.txt")}, 146 }, 147 dest: []pathSpecEntry{ 148 {dir: false, path: "baz.txt"}, 149 }, 150 }, 151 } 152 } 153 154 func TestRsync(t *testing.T) { 155 _, err := exec.LookPath("rsync") 156 if err != nil { 157 t.Log(err) 158 return 159 } 160 161 t.Run("rsync", func(t *testing.T) { 162 mutex := &sync.Mutex{} 163 for _, tt := range pathSpec(string(os.PathSeparator), string(os.PathSeparator)) { 164 t.Run(tt.name, func(t *testing.T) { 165 rsyncSrc, err := ioutil.TempDir("", "rsync-src") 166 assert.NoError(t, err) 167 rsyncDest, err := ioutil.TempDir("", "rsync-dest") 168 assert.NoError(t, err) 169 170 for _, e := range tt.src { 171 if e.dir { 172 err = os.MkdirAll(filepath.Join(rsyncSrc, e.path), 0750) 173 } else { 174 _, err = os.Create(filepath.Join(rsyncSrc, e.path)) 175 } 176 require.NoError(t, err) 177 } 178 for _, e := range tt.dest { 179 if !e.preexisting { 180 continue 181 } 182 if e.dir { 183 err = os.MkdirAll(filepath.Join(rsyncDest, e.path), 0750) 184 } else { 185 _, err = os.Create(filepath.Join(rsyncDest, e.path)) 186 } 187 require.NoError(t, err) 188 } 189 190 source := join(string(os.PathSeparator), rsyncSrc, tt.args.src) 191 destination := join(string(os.PathSeparator), rsyncDest, tt.args.dest) 192 if tt.args.dest == "" { 193 destination = "" 194 } 195 originalDir, err := os.Getwd() 196 require.NoError(t, err) 197 mutex.Lock() 198 err = os.Chdir(rsyncDest) 199 require.NoError(t, err) 200 cmd := exec.Command("rsync", "-av", source, destination) 201 var cleanedArgs []string 202 203 for _, arg := range cmd.Args { 204 arg = strings.Replace(arg, rsyncSrc, "", 1) 205 arg = strings.Replace(arg, rsyncDest, "", 1) 206 cleanedArgs = append(cleanedArgs, arg) 207 } 208 t.Log(cleanedArgs) 209 stdout := bytes.NewBufferString("") 210 stderr := bytes.NewBufferString("") 211 cmd.Stderr = stderr 212 cmd.Stdout = stdout 213 err = cmd.Run() 214 assert.NoError(t, err) 215 if stderr.String() != "" { 216 t.Log(stderr.String()) 217 } 218 err = os.Chdir(originalDir) 219 require.NoError(t, err) 220 mutex.Unlock() 221 for _, e := range tt.dest { 222 fileInfo, err := os.Stat(filepath.Join(rsyncDest, e.path)) 223 require.NoError(t, err, e.path) 224 assert.Equal(t, e.dir, fileInfo.IsDir(), e.path) 225 } 226 227 assert.NoError(t, os.RemoveAll(rsyncSrc)) 228 assert.NoError(t, os.RemoveAll(rsyncDest)) 229 }) 230 } 231 }) 232 } 233 234 func join(pathSeparator string, parts ...string) string { 235 if parts[len(parts)-1] == pathSeparator { 236 return strings.Join(parts, pathSeparator) + pathSeparator 237 } else { 238 return strings.Join(parts, pathSeparator) 239 } 240 }