3 // TODO Windows: Some of these tests may be salvageable and portable to Windows.
20 func removeAllPaths(paths ...string) {
21 for _, path := range paths {
26 func getTestTempDirs(t *testing.T) (tmpDirA, tmpDirB string) {
29 if tmpDirA, err = ioutil.TempDir("", "archive-copy-test"); err != nil {
33 if tmpDirB, err = ioutil.TempDir("", "archive-copy-test"); err != nil {
40 func isNotDir(err error) bool {
41 return strings.Contains(err.Error(), "not a directory")
44 func joinTrailingSep(pathElements ...string) string {
45 joined := filepath.Join(pathElements...)
47 return fmt.Sprintf("%s%c", joined, filepath.Separator)
50 func fileContentsEqual(t *testing.T, filenameA, filenameB string) (err error) {
51 t.Logf("checking for equal file contents: %q and %q\n", filenameA, filenameB)
53 fileA, err := os.Open(filenameA)
59 fileB, err := os.Open(filenameB)
65 hasher := sha256.New()
67 if _, err = io.Copy(hasher, fileA); err != nil {
71 hashA := hasher.Sum(nil)
74 if _, err = io.Copy(hasher, fileB); err != nil {
78 hashB := hasher.Sum(nil)
80 if !bytes.Equal(hashA, hashB) {
81 err = fmt.Errorf("file content hashes not equal - expected %s, got %s", hex.EncodeToString(hashA), hex.EncodeToString(hashB))
87 func dirContentsEqual(t *testing.T, newDir, oldDir string) (err error) {
88 t.Logf("checking for equal directory contents: %q and %q\n", newDir, oldDir)
92 if changes, err = ChangesDirs(newDir, oldDir); err != nil {
96 if len(changes) != 0 {
97 err = fmt.Errorf("expected no changes between directories, but got: %v", changes)
103 func logDirContents(t *testing.T, dirPath string) {
104 logWalkedPaths := filepath.WalkFunc(func(path string, info os.FileInfo, err error) error {
106 t.Errorf("stat error for path %q: %s", path, err)
111 path = joinTrailingSep(path)
119 t.Logf("logging directory contents: %q", dirPath)
121 if err := filepath.Walk(dirPath, logWalkedPaths); err != nil {
126 func testCopyHelper(t *testing.T, srcPath, dstPath string) (err error) {
127 t.Logf("copying from %q to %q (not follow symbol link)", srcPath, dstPath)
129 return CopyResource(srcPath, dstPath, false)
132 func testCopyHelperFSym(t *testing.T, srcPath, dstPath string) (err error) {
133 t.Logf("copying from %q to %q (follow symbol link)", srcPath, dstPath)
135 return CopyResource(srcPath, dstPath, true)
138 // Basic assumptions about SRC and DST:
139 // 1. SRC must exist.
140 // 2. If SRC ends with a trailing separator, it must be a directory.
141 // 3. DST parent directory must exist.
142 // 4. If DST exists as a file, it must not end with a trailing separator.
144 // First get these easy error cases out of the way.
146 // Test for error when SRC does not exist.
147 func TestCopyErrSrcNotExists(t *testing.T) {
148 tmpDirA, tmpDirB := getTestTempDirs(t)
149 defer removeAllPaths(tmpDirA, tmpDirB)
151 if _, err := CopyInfoSourcePath(filepath.Join(tmpDirA, "file1"), false); !os.IsNotExist(err) {
152 t.Fatalf("expected IsNotExist error, but got %T: %s", err, err)
156 // Test for error when SRC ends in a trailing
157 // path separator but it exists as a file.
158 func TestCopyErrSrcNotDir(t *testing.T) {
159 tmpDirA, tmpDirB := getTestTempDirs(t)
160 defer removeAllPaths(tmpDirA, tmpDirB)
162 // Load A with some sample files and directories.
163 createSampleDir(t, tmpDirA)
165 if _, err := CopyInfoSourcePath(joinTrailingSep(tmpDirA, "file1"), false); !isNotDir(err) {
166 t.Fatalf("expected IsNotDir error, but got %T: %s", err, err)
170 // Test for error when SRC is a valid file or directory,
171 // but the DST parent directory does not exist.
172 func TestCopyErrDstParentNotExists(t *testing.T) {
173 tmpDirA, tmpDirB := getTestTempDirs(t)
174 defer removeAllPaths(tmpDirA, tmpDirB)
176 // Load A with some sample files and directories.
177 createSampleDir(t, tmpDirA)
179 srcInfo := CopyInfo{Path: filepath.Join(tmpDirA, "file1"), Exists: true, IsDir: false}
181 // Try with a file source.
182 content, err := TarResource(srcInfo)
184 t.Fatalf("unexpected error %T: %s", err, err)
186 defer content.Close()
188 // Copy to a file whose parent does not exist.
189 if err = CopyTo(content, srcInfo, filepath.Join(tmpDirB, "fakeParentDir", "file1")); err == nil {
190 t.Fatal("expected IsNotExist error, but got nil instead")
193 if !os.IsNotExist(err) {
194 t.Fatalf("expected IsNotExist error, but got %T: %s", err, err)
197 // Try with a directory source.
198 srcInfo = CopyInfo{Path: filepath.Join(tmpDirA, "dir1"), Exists: true, IsDir: true}
200 content, err = TarResource(srcInfo)
202 t.Fatalf("unexpected error %T: %s", err, err)
204 defer content.Close()
206 // Copy to a directory whose parent does not exist.
207 if err = CopyTo(content, srcInfo, joinTrailingSep(tmpDirB, "fakeParentDir", "fakeDstDir")); err == nil {
208 t.Fatal("expected IsNotExist error, but got nil instead")
211 if !os.IsNotExist(err) {
212 t.Fatalf("expected IsNotExist error, but got %T: %s", err, err)
216 // Test for error when DST ends in a trailing
217 // path separator but exists as a file.
218 func TestCopyErrDstNotDir(t *testing.T) {
219 tmpDirA, tmpDirB := getTestTempDirs(t)
220 defer removeAllPaths(tmpDirA, tmpDirB)
222 // Load A and B with some sample files and directories.
223 createSampleDir(t, tmpDirA)
224 createSampleDir(t, tmpDirB)
226 // Try with a file source.
227 srcInfo := CopyInfo{Path: filepath.Join(tmpDirA, "file1"), Exists: true, IsDir: false}
229 content, err := TarResource(srcInfo)
231 t.Fatalf("unexpected error %T: %s", err, err)
233 defer content.Close()
235 if err = CopyTo(content, srcInfo, joinTrailingSep(tmpDirB, "file1")); err == nil {
236 t.Fatal("expected IsNotDir error, but got nil instead")
240 t.Fatalf("expected IsNotDir error, but got %T: %s", err, err)
243 // Try with a directory source.
244 srcInfo = CopyInfo{Path: filepath.Join(tmpDirA, "dir1"), Exists: true, IsDir: true}
246 content, err = TarResource(srcInfo)
248 t.Fatalf("unexpected error %T: %s", err, err)
250 defer content.Close()
252 if err = CopyTo(content, srcInfo, joinTrailingSep(tmpDirB, "file1")); err == nil {
253 t.Fatal("expected IsNotDir error, but got nil instead")
257 t.Fatalf("expected IsNotDir error, but got %T: %s", err, err)
261 // Possibilities are reduced to the remaining 10 cases:
263 // case | srcIsDir | onlyDirContents | dstExists | dstIsDir | dstTrSep | action
264 // ===================================================================================================
265 // A | no | - | no | - | no | create file
266 // B | no | - | no | - | yes | error
267 // C | no | - | yes | no | - | overwrite file
268 // D | no | - | yes | yes | - | create file in dst dir
269 // E | yes | no | no | - | - | create dir, copy contents
270 // F | yes | no | yes | no | - | error
271 // G | yes | no | yes | yes | - | copy dir and contents
272 // H | yes | yes | no | - | - | create dir, copy contents
273 // I | yes | yes | yes | no | - | error
274 // J | yes | yes | yes | yes | - | copy dir contents
277 // A. SRC specifies a file and DST (no trailing path separator) doesn't
278 // exist. This should create a file with the name DST and copy the
279 // contents of the source file into it.
280 func TestCopyCaseA(t *testing.T) {
281 tmpDirA, tmpDirB := getTestTempDirs(t)
282 defer removeAllPaths(tmpDirA, tmpDirB)
284 // Load A with some sample files and directories.
285 createSampleDir(t, tmpDirA)
287 srcPath := filepath.Join(tmpDirA, "file1")
288 dstPath := filepath.Join(tmpDirB, "itWorks.txt")
292 if err = testCopyHelper(t, srcPath, dstPath); err != nil {
293 t.Fatalf("unexpected error %T: %s", err, err)
296 if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
301 symlinkPath := filepath.Join(tmpDirA, "symlink3")
302 symlinkPath1 := filepath.Join(tmpDirA, "symlink4")
303 linkTarget := filepath.Join(tmpDirA, "file1")
305 if err = testCopyHelperFSym(t, symlinkPath, dstPath); err != nil {
306 t.Fatalf("unexpected error %T: %s", err, err)
309 if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
313 if err = testCopyHelperFSym(t, symlinkPath1, dstPath); err != nil {
314 t.Fatalf("unexpected error %T: %s", err, err)
317 if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
322 // B. SRC specifies a file and DST (with trailing path separator) doesn't
323 // exist. This should cause an error because the copy operation cannot
324 // create a directory when copying a single file.
325 func TestCopyCaseB(t *testing.T) {
326 tmpDirA, tmpDirB := getTestTempDirs(t)
327 defer removeAllPaths(tmpDirA, tmpDirB)
329 // Load A with some sample files and directories.
330 createSampleDir(t, tmpDirA)
332 srcPath := filepath.Join(tmpDirA, "file1")
333 dstDir := joinTrailingSep(tmpDirB, "testDir")
337 if err = testCopyHelper(t, srcPath, dstDir); err == nil {
338 t.Fatal("expected ErrDirNotExists error, but got nil instead")
341 if err != ErrDirNotExists {
342 t.Fatalf("expected ErrDirNotExists error, but got %T: %s", err, err)
345 symlinkPath := filepath.Join(tmpDirA, "symlink3")
347 if err = testCopyHelperFSym(t, symlinkPath, dstDir); err == nil {
348 t.Fatal("expected ErrDirNotExists error, but got nil instead")
350 if err != ErrDirNotExists {
351 t.Fatalf("expected ErrDirNotExists error, but got %T: %s", err, err)
356 // C. SRC specifies a file and DST exists as a file. This should overwrite
357 // the file at DST with the contents of the source file.
358 func TestCopyCaseC(t *testing.T) {
359 tmpDirA, tmpDirB := getTestTempDirs(t)
360 defer removeAllPaths(tmpDirA, tmpDirB)
362 // Load A and B with some sample files and directories.
363 createSampleDir(t, tmpDirA)
364 createSampleDir(t, tmpDirB)
366 srcPath := filepath.Join(tmpDirA, "file1")
367 dstPath := filepath.Join(tmpDirB, "file2")
371 // Ensure they start out different.
372 if err = fileContentsEqual(t, srcPath, dstPath); err == nil {
373 t.Fatal("expected different file contents")
376 if err = testCopyHelper(t, srcPath, dstPath); err != nil {
377 t.Fatalf("unexpected error %T: %s", err, err)
380 if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
385 // C. Symbol link following version:
386 // SRC specifies a file and DST exists as a file. This should overwrite
387 // the file at DST with the contents of the source file.
388 func TestCopyCaseCFSym(t *testing.T) {
389 tmpDirA, tmpDirB := getTestTempDirs(t)
390 defer removeAllPaths(tmpDirA, tmpDirB)
392 // Load A and B with some sample files and directories.
393 createSampleDir(t, tmpDirA)
394 createSampleDir(t, tmpDirB)
396 symlinkPathBad := filepath.Join(tmpDirA, "symlink1")
397 symlinkPath := filepath.Join(tmpDirA, "symlink3")
398 linkTarget := filepath.Join(tmpDirA, "file1")
399 dstPath := filepath.Join(tmpDirB, "file2")
403 // first to test broken link
404 if err = testCopyHelperFSym(t, symlinkPathBad, dstPath); err == nil {
405 t.Fatalf("unexpected error %T: %s", err, err)
408 // test symbol link -> symbol link -> target
409 // Ensure they start out different.
410 if err = fileContentsEqual(t, linkTarget, dstPath); err == nil {
411 t.Fatal("expected different file contents")
414 if err = testCopyHelperFSym(t, symlinkPath, dstPath); err != nil {
415 t.Fatalf("unexpected error %T: %s", err, err)
418 if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
423 // D. SRC specifies a file and DST exists as a directory. This should place
424 // a copy of the source file inside it using the basename from SRC. Ensure
425 // this works whether DST has a trailing path separator or not.
426 func TestCopyCaseD(t *testing.T) {
427 tmpDirA, tmpDirB := getTestTempDirs(t)
428 defer removeAllPaths(tmpDirA, tmpDirB)
430 // Load A and B with some sample files and directories.
431 createSampleDir(t, tmpDirA)
432 createSampleDir(t, tmpDirB)
434 srcPath := filepath.Join(tmpDirA, "file1")
435 dstDir := filepath.Join(tmpDirB, "dir1")
436 dstPath := filepath.Join(dstDir, "file1")
440 // Ensure that dstPath doesn't exist.
441 if _, err = os.Stat(dstPath); !os.IsNotExist(err) {
442 t.Fatalf("did not expect dstPath %q to exist", dstPath)
445 if err = testCopyHelper(t, srcPath, dstDir); err != nil {
446 t.Fatalf("unexpected error %T: %s", err, err)
449 if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
453 // Now try again but using a trailing path separator for dstDir.
455 if err = os.RemoveAll(dstDir); err != nil {
456 t.Fatalf("unable to remove dstDir: %s", err)
459 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
460 t.Fatalf("unable to make dstDir: %s", err)
463 dstDir = joinTrailingSep(tmpDirB, "dir1")
465 if err = testCopyHelper(t, srcPath, dstDir); err != nil {
466 t.Fatalf("unexpected error %T: %s", err, err)
469 if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
474 // D. Symbol link following version:
475 // SRC specifies a file and DST exists as a directory. This should place
476 // a copy of the source file inside it using the basename from SRC. Ensure
477 // this works whether DST has a trailing path separator or not.
478 func TestCopyCaseDFSym(t *testing.T) {
479 tmpDirA, tmpDirB := getTestTempDirs(t)
480 defer removeAllPaths(tmpDirA, tmpDirB)
482 // Load A and B with some sample files and directories.
483 createSampleDir(t, tmpDirA)
484 createSampleDir(t, tmpDirB)
486 srcPath := filepath.Join(tmpDirA, "symlink4")
487 linkTarget := filepath.Join(tmpDirA, "file1")
488 dstDir := filepath.Join(tmpDirB, "dir1")
489 dstPath := filepath.Join(dstDir, "symlink4")
493 // Ensure that dstPath doesn't exist.
494 if _, err = os.Stat(dstPath); !os.IsNotExist(err) {
495 t.Fatalf("did not expect dstPath %q to exist", dstPath)
498 if err = testCopyHelperFSym(t, srcPath, dstDir); err != nil {
499 t.Fatalf("unexpected error %T: %s", err, err)
502 if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
506 // Now try again but using a trailing path separator for dstDir.
508 if err = os.RemoveAll(dstDir); err != nil {
509 t.Fatalf("unable to remove dstDir: %s", err)
512 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
513 t.Fatalf("unable to make dstDir: %s", err)
516 dstDir = joinTrailingSep(tmpDirB, "dir1")
518 if err = testCopyHelperFSym(t, srcPath, dstDir); err != nil {
519 t.Fatalf("unexpected error %T: %s", err, err)
522 if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
527 // E. SRC specifies a directory and DST does not exist. This should create a
528 // directory at DST and copy the contents of the SRC directory into the DST
529 // directory. Ensure this works whether DST has a trailing path separator or
531 func TestCopyCaseE(t *testing.T) {
532 tmpDirA, tmpDirB := getTestTempDirs(t)
533 defer removeAllPaths(tmpDirA, tmpDirB)
535 // Load A with some sample files and directories.
536 createSampleDir(t, tmpDirA)
538 srcDir := filepath.Join(tmpDirA, "dir1")
539 dstDir := filepath.Join(tmpDirB, "testDir")
543 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
544 t.Fatalf("unexpected error %T: %s", err, err)
547 if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
548 t.Log("dir contents not equal")
549 logDirContents(t, tmpDirA)
550 logDirContents(t, tmpDirB)
554 // Now try again but using a trailing path separator for dstDir.
556 if err = os.RemoveAll(dstDir); err != nil {
557 t.Fatalf("unable to remove dstDir: %s", err)
560 dstDir = joinTrailingSep(tmpDirB, "testDir")
562 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
563 t.Fatalf("unexpected error %T: %s", err, err)
566 if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
571 // E. Symbol link following version:
572 // SRC specifies a directory and DST does not exist. This should create a
573 // directory at DST and copy the contents of the SRC directory into the DST
574 // directory. Ensure this works whether DST has a trailing path separator or
576 func TestCopyCaseEFSym(t *testing.T) {
577 tmpDirA, tmpDirB := getTestTempDirs(t)
578 defer removeAllPaths(tmpDirA, tmpDirB)
580 // Load A with some sample files and directories.
581 createSampleDir(t, tmpDirA)
583 srcDir := filepath.Join(tmpDirA, "dirSymlink")
584 linkTarget := filepath.Join(tmpDirA, "dir1")
585 dstDir := filepath.Join(tmpDirB, "testDir")
589 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
590 t.Fatalf("unexpected error %T: %s", err, err)
593 if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
594 t.Log("dir contents not equal")
595 logDirContents(t, tmpDirA)
596 logDirContents(t, tmpDirB)
600 // Now try again but using a trailing path separator for dstDir.
602 if err = os.RemoveAll(dstDir); err != nil {
603 t.Fatalf("unable to remove dstDir: %s", err)
606 dstDir = joinTrailingSep(tmpDirB, "testDir")
608 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
609 t.Fatalf("unexpected error %T: %s", err, err)
612 if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
617 // F. SRC specifies a directory and DST exists as a file. This should cause an
618 // error as it is not possible to overwrite a file with a directory.
619 func TestCopyCaseF(t *testing.T) {
620 tmpDirA, tmpDirB := getTestTempDirs(t)
621 defer removeAllPaths(tmpDirA, tmpDirB)
623 // Load A and B with some sample files and directories.
624 createSampleDir(t, tmpDirA)
625 createSampleDir(t, tmpDirB)
627 srcDir := filepath.Join(tmpDirA, "dir1")
628 symSrcDir := filepath.Join(tmpDirA, "dirSymlink")
629 dstFile := filepath.Join(tmpDirB, "file1")
633 if err = testCopyHelper(t, srcDir, dstFile); err == nil {
634 t.Fatal("expected ErrCannotCopyDir error, but got nil instead")
637 if err != ErrCannotCopyDir {
638 t.Fatalf("expected ErrCannotCopyDir error, but got %T: %s", err, err)
641 // now test with symbol link
642 if err = testCopyHelperFSym(t, symSrcDir, dstFile); err == nil {
643 t.Fatal("expected ErrCannotCopyDir error, but got nil instead")
646 if err != ErrCannotCopyDir {
647 t.Fatalf("expected ErrCannotCopyDir error, but got %T: %s", err, err)
651 // G. SRC specifies a directory and DST exists as a directory. This should copy
652 // the SRC directory and all its contents to the DST directory. Ensure this
653 // works whether DST has a trailing path separator or not.
654 func TestCopyCaseG(t *testing.T) {
655 tmpDirA, tmpDirB := getTestTempDirs(t)
656 defer removeAllPaths(tmpDirA, tmpDirB)
658 // Load A and B with some sample files and directories.
659 createSampleDir(t, tmpDirA)
660 createSampleDir(t, tmpDirB)
662 srcDir := filepath.Join(tmpDirA, "dir1")
663 dstDir := filepath.Join(tmpDirB, "dir2")
664 resultDir := filepath.Join(dstDir, "dir1")
668 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
669 t.Fatalf("unexpected error %T: %s", err, err)
672 if err = dirContentsEqual(t, resultDir, srcDir); err != nil {
676 // Now try again but using a trailing path separator for dstDir.
678 if err = os.RemoveAll(dstDir); err != nil {
679 t.Fatalf("unable to remove dstDir: %s", err)
682 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
683 t.Fatalf("unable to make dstDir: %s", err)
686 dstDir = joinTrailingSep(tmpDirB, "dir2")
688 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
689 t.Fatalf("unexpected error %T: %s", err, err)
692 if err = dirContentsEqual(t, resultDir, srcDir); err != nil {
697 // G. Symbol link version:
698 // SRC specifies a directory and DST exists as a directory. This should copy
699 // the SRC directory and all its contents to the DST directory. Ensure this
700 // works whether DST has a trailing path separator or not.
701 func TestCopyCaseGFSym(t *testing.T) {
702 tmpDirA, tmpDirB := getTestTempDirs(t)
703 defer removeAllPaths(tmpDirA, tmpDirB)
705 // Load A and B with some sample files and directories.
706 createSampleDir(t, tmpDirA)
707 createSampleDir(t, tmpDirB)
709 srcDir := filepath.Join(tmpDirA, "dirSymlink")
710 linkTarget := filepath.Join(tmpDirA, "dir1")
711 dstDir := filepath.Join(tmpDirB, "dir2")
712 resultDir := filepath.Join(dstDir, "dirSymlink")
716 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
717 t.Fatalf("unexpected error %T: %s", err, err)
720 if err = dirContentsEqual(t, resultDir, linkTarget); err != nil {
724 // Now try again but using a trailing path separator for dstDir.
726 if err = os.RemoveAll(dstDir); err != nil {
727 t.Fatalf("unable to remove dstDir: %s", err)
730 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
731 t.Fatalf("unable to make dstDir: %s", err)
734 dstDir = joinTrailingSep(tmpDirB, "dir2")
736 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
737 t.Fatalf("unexpected error %T: %s", err, err)
740 if err = dirContentsEqual(t, resultDir, linkTarget); err != nil {
745 // H. SRC specifies a directory's contents only and DST does not exist. This
746 // should create a directory at DST and copy the contents of the SRC
747 // directory (but not the directory itself) into the DST directory. Ensure
748 // this works whether DST has a trailing path separator or not.
749 func TestCopyCaseH(t *testing.T) {
750 tmpDirA, tmpDirB := getTestTempDirs(t)
751 defer removeAllPaths(tmpDirA, tmpDirB)
753 // Load A with some sample files and directories.
754 createSampleDir(t, tmpDirA)
756 srcDir := joinTrailingSep(tmpDirA, "dir1") + "."
757 dstDir := filepath.Join(tmpDirB, "testDir")
761 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
762 t.Fatalf("unexpected error %T: %s", err, err)
765 if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
766 t.Log("dir contents not equal")
767 logDirContents(t, tmpDirA)
768 logDirContents(t, tmpDirB)
772 // Now try again but using a trailing path separator for dstDir.
774 if err = os.RemoveAll(dstDir); err != nil {
775 t.Fatalf("unable to remove dstDir: %s", err)
778 dstDir = joinTrailingSep(tmpDirB, "testDir")
780 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
781 t.Fatalf("unexpected error %T: %s", err, err)
784 if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
785 t.Log("dir contents not equal")
786 logDirContents(t, tmpDirA)
787 logDirContents(t, tmpDirB)
792 // H. Symbol link following version:
793 // SRC specifies a directory's contents only and DST does not exist. This
794 // should create a directory at DST and copy the contents of the SRC
795 // directory (but not the directory itself) into the DST directory. Ensure
796 // this works whether DST has a trailing path separator or not.
797 func TestCopyCaseHFSym(t *testing.T) {
798 tmpDirA, tmpDirB := getTestTempDirs(t)
799 defer removeAllPaths(tmpDirA, tmpDirB)
801 // Load A with some sample files and directories.
802 createSampleDir(t, tmpDirA)
804 srcDir := joinTrailingSep(tmpDirA, "dirSymlink") + "."
805 linkTarget := filepath.Join(tmpDirA, "dir1")
806 dstDir := filepath.Join(tmpDirB, "testDir")
810 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
811 t.Fatalf("unexpected error %T: %s", err, err)
814 if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
815 t.Log("dir contents not equal")
816 logDirContents(t, tmpDirA)
817 logDirContents(t, tmpDirB)
821 // Now try again but using a trailing path separator for dstDir.
823 if err = os.RemoveAll(dstDir); err != nil {
824 t.Fatalf("unable to remove dstDir: %s", err)
827 dstDir = joinTrailingSep(tmpDirB, "testDir")
829 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
830 t.Fatalf("unexpected error %T: %s", err, err)
833 if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
834 t.Log("dir contents not equal")
835 logDirContents(t, tmpDirA)
836 logDirContents(t, tmpDirB)
841 // I. SRC specifies a directory's contents only and DST exists as a file. This
842 // should cause an error as it is not possible to overwrite a file with a
844 func TestCopyCaseI(t *testing.T) {
845 tmpDirA, tmpDirB := getTestTempDirs(t)
846 defer removeAllPaths(tmpDirA, tmpDirB)
848 // Load A and B with some sample files and directories.
849 createSampleDir(t, tmpDirA)
850 createSampleDir(t, tmpDirB)
852 srcDir := joinTrailingSep(tmpDirA, "dir1") + "."
853 symSrcDir := filepath.Join(tmpDirB, "dirSymlink")
854 dstFile := filepath.Join(tmpDirB, "file1")
858 if err = testCopyHelper(t, srcDir, dstFile); err == nil {
859 t.Fatal("expected ErrCannotCopyDir error, but got nil instead")
862 if err != ErrCannotCopyDir {
863 t.Fatalf("expected ErrCannotCopyDir error, but got %T: %s", err, err)
866 // now try with symbol link of dir
867 if err = testCopyHelperFSym(t, symSrcDir, dstFile); err == nil {
868 t.Fatal("expected ErrCannotCopyDir error, but got nil instead")
871 if err != ErrCannotCopyDir {
872 t.Fatalf("expected ErrCannotCopyDir error, but got %T: %s", err, err)
876 // J. SRC specifies a directory's contents only and DST exists as a directory.
877 // This should copy the contents of the SRC directory (but not the directory
878 // itself) into the DST directory. Ensure this works whether DST has a
879 // trailing path separator or not.
880 func TestCopyCaseJ(t *testing.T) {
881 tmpDirA, tmpDirB := getTestTempDirs(t)
882 defer removeAllPaths(tmpDirA, tmpDirB)
884 // Load A and B with some sample files and directories.
885 createSampleDir(t, tmpDirA)
886 createSampleDir(t, tmpDirB)
888 srcDir := joinTrailingSep(tmpDirA, "dir1") + "."
889 dstDir := filepath.Join(tmpDirB, "dir5")
893 // first to create an empty dir
894 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
895 t.Fatalf("unable to make dstDir: %s", err)
898 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
899 t.Fatalf("unexpected error %T: %s", err, err)
902 if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
906 // Now try again but using a trailing path separator for dstDir.
908 if err = os.RemoveAll(dstDir); err != nil {
909 t.Fatalf("unable to remove dstDir: %s", err)
912 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
913 t.Fatalf("unable to make dstDir: %s", err)
916 dstDir = joinTrailingSep(tmpDirB, "dir5")
918 if err = testCopyHelper(t, srcDir, dstDir); err != nil {
919 t.Fatalf("unexpected error %T: %s", err, err)
922 if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
927 // J. Symbol link following version:
928 // SRC specifies a directory's contents only and DST exists as a directory.
929 // This should copy the contents of the SRC directory (but not the directory
930 // itself) into the DST directory. Ensure this works whether DST has a
931 // trailing path separator or not.
932 func TestCopyCaseJFSym(t *testing.T) {
933 tmpDirA, tmpDirB := getTestTempDirs(t)
934 defer removeAllPaths(tmpDirA, tmpDirB)
936 // Load A and B with some sample files and directories.
937 createSampleDir(t, tmpDirA)
938 createSampleDir(t, tmpDirB)
940 srcDir := joinTrailingSep(tmpDirA, "dirSymlink") + "."
941 linkTarget := filepath.Join(tmpDirA, "dir1")
942 dstDir := filepath.Join(tmpDirB, "dir5")
946 // first to create an empty dir
947 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
948 t.Fatalf("unable to make dstDir: %s", err)
951 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
952 t.Fatalf("unexpected error %T: %s", err, err)
955 if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
959 // Now try again but using a trailing path separator for dstDir.
961 if err = os.RemoveAll(dstDir); err != nil {
962 t.Fatalf("unable to remove dstDir: %s", err)
965 if err = os.MkdirAll(dstDir, os.FileMode(0755)); err != nil {
966 t.Fatalf("unable to make dstDir: %s", err)
969 dstDir = joinTrailingSep(tmpDirB, "dir5")
971 if err = testCopyHelperFSym(t, srcDir, dstDir); err != nil {
972 t.Fatalf("unexpected error %T: %s", err, err)
975 if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {