github.com/searKing/golang/go@v1.2.117/io/copy_test.go (about) 1 // Copyright 2022 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package io_test 6 7 import ( 8 "bytes" 9 "fmt" 10 "math/rand" 11 "os" 12 "path/filepath" 13 "testing" 14 15 io_ "github.com/searKing/golang/go/io" 16 ) 17 18 func TestCopy(t *testing.T) { 19 copyWithFileRange := true 20 copyWithFileClone := true 21 doCopyTest(t, ©WithFileRange, ©WithFileClone) 22 } 23 24 func TestCopyWithoutRange(t *testing.T) { 25 copyWithFileRange := false 26 copyWithFileClone := false 27 doCopyTest(t, ©WithFileRange, ©WithFileClone) 28 } 29 30 func TestCopyDir(t *testing.T) { 31 srcDir, err := os.MkdirTemp("", "srcDir") 32 if err != nil { 33 t.Errorf("expect nil, got %v", err) 34 } 35 populateSrcDir(t, srcDir, 3) 36 37 dstDir, err := os.MkdirTemp("", "testdst") 38 if err != nil { 39 t.Errorf("expect nil, got %v", err) 40 } 41 defer os.RemoveAll(dstDir) 42 43 err = io_.CopyDir(srcDir, dstDir, io_.Content) 44 if err != nil { 45 t.Errorf("expect nil, got %v", err) 46 } 47 48 err = filepath.Walk(srcDir, func(srcPath string, f os.FileInfo, err error) error { 49 if err != nil { 50 return err 51 } 52 53 // Rebase path 54 relPath, err := filepath.Rel(srcDir, srcPath) 55 if err != nil { 56 t.Errorf("expect nil, got %v", err) 57 } 58 if relPath == "." { 59 return nil 60 } 61 62 dstPath := filepath.Join(dstDir, relPath) 63 if err != nil { 64 t.Errorf("expect nil, got %v", err) 65 } 66 67 // If we add non-regular dirs and files to the test 68 // then we need to add more checks here. 69 _, err = os.Lstat(dstPath) 70 if err != nil { 71 t.Errorf("expect nil, got %v", err) 72 } 73 74 return nil 75 }) 76 if err != nil { 77 t.Errorf("expect nil, got %v", err) 78 } 79 } 80 81 func randomMode(baseMode int) os.FileMode { 82 for i := 0; i < 7; i++ { 83 baseMode = baseMode | (1&rand.Intn(2))<<uint(i) 84 } 85 return os.FileMode(baseMode) 86 } 87 88 func populateSrcDir(t *testing.T, srcDir string, remainingDepth int) { 89 if remainingDepth == 0 { 90 return 91 } 92 93 for i := 0; i < 10; i++ { 94 dirName := filepath.Join(srcDir, fmt.Sprintf("srcdir-%d", i)) 95 // Owner all bits set 96 err := os.Mkdir(dirName, randomMode(0700)) 97 if err != nil { 98 t.Errorf("expect nil, got %v", err) 99 } 100 populateSrcDir(t, dirName, remainingDepth-1) 101 } 102 103 for i := 0; i < 10; i++ { 104 fileName := filepath.Join(srcDir, fmt.Sprintf("srcfile-%d", i)) 105 // Owner read bit set 106 err := os.WriteFile(fileName, []byte{}, randomMode(0400)) 107 if err != nil { 108 t.Errorf("expect nil, got %v", err) 109 } 110 } 111 } 112 113 func doCopyTest(t *testing.T, copyWithFileRange, copyWithFileClone *bool) { 114 dir, err := os.MkdirTemp("", "docker-copy-check") 115 if err != nil { 116 t.Errorf("expect nil, got %v", err) 117 } 118 defer os.RemoveAll(dir) 119 srcFilename := filepath.Join(dir, "srcFilename") 120 dstFilename := filepath.Join(dir, "dstilename") 121 122 r := rand.New(rand.NewSource(0)) 123 buf := make([]byte, 1024) 124 _, err = r.Read(buf) 125 if err != nil { 126 t.Errorf("expect nil, got %v", err) 127 } 128 err = os.WriteFile(srcFilename, buf, 0777) 129 if err != nil { 130 t.Errorf("expect nil, got %v", err) 131 } 132 fileinfo, err := os.Stat(srcFilename) 133 if err != nil { 134 t.Errorf("expect nil, got %v", err) 135 } 136 137 err = io_.CopyRegular(srcFilename, dstFilename, fileinfo) 138 if err != nil { 139 t.Errorf("expect nil, got %v", err) 140 } 141 readBuf, err := os.ReadFile(dstFilename) 142 if err != nil { 143 t.Errorf("expect nil, got %v", err) 144 } 145 146 if !bytes.Equal(buf, readBuf) { 147 t.Errorf("expect true, got %v", false) 148 } 149 } 150 151 func TestCopyHardlink(t *testing.T) { 152 var srcFile1FileInfo, srcFile2FileInfo, dstFile1FileInfo, dstFile2FileInfo os.FileInfo 153 154 srcDir, err := os.MkdirTemp("", "srcDir") 155 if err != nil { 156 t.Errorf("expect nil, got %v", err) 157 } 158 defer os.RemoveAll(srcDir) 159 160 dstDir, err := os.MkdirTemp("", "dstDir") 161 if err != nil { 162 t.Errorf("expect nil, got %v", err) 163 } 164 defer os.RemoveAll(dstDir) 165 166 srcFile1 := filepath.Join(srcDir, "file1") 167 srcFile2 := filepath.Join(srcDir, "file2") 168 dstFile1 := filepath.Join(dstDir, "file1") 169 dstFile2 := filepath.Join(dstDir, "file2") 170 err = os.WriteFile(srcFile1, []byte{}, 0777) 171 if err != nil { 172 t.Errorf("expect nil, got %v", err) 173 } 174 err = os.Link(srcFile1, srcFile2) 175 if err != nil { 176 t.Errorf("expect nil, got %v", err) 177 } 178 179 err = io_.CopyDir(srcDir, dstDir, io_.Content) 180 if err != nil { 181 t.Errorf("expect nil, got %v", err) 182 } 183 184 srcFile1FileInfo, err = os.Stat(srcFile1) 185 if err != nil { 186 t.Errorf("expect nil, got %v", err) 187 } 188 dstFile1FileInfo, err = os.Stat(dstFile1) 189 if err != nil { 190 t.Errorf("expect nil, got %v", err) 191 } 192 srcFile2FileInfo, err = os.Stat(srcFile2) 193 if err != nil { 194 t.Errorf("expect nil, got %v", err) 195 } 196 dstFile2FileInfo, err = os.Stat(dstFile2) 197 if err != nil { 198 t.Errorf("expect nil, got %v", err) 199 } 200 201 if srcFile1FileInfo.Name() != dstFile1FileInfo.Name() { 202 t.Error("expect equal, got unequal") 203 } 204 if srcFile1FileInfo.Size() != dstFile1FileInfo.Size() { 205 t.Error("expect equal, got unequal") 206 } 207 if srcFile1FileInfo.IsDir() != dstFile1FileInfo.IsDir() { 208 t.Error("expect equal, got unequal") 209 } 210 if srcFile1FileInfo.Mode() != dstFile1FileInfo.Mode() { 211 t.Error("expect equal, got unequal") 212 } 213 if srcFile2FileInfo.Name() != dstFile2FileInfo.Name() { 214 t.Error("expect equal, got unequal") 215 } 216 if srcFile2FileInfo.Size() != dstFile2FileInfo.Size() { 217 t.Error("expect equal, got unequal") 218 } 219 if srcFile2FileInfo.IsDir() != dstFile2FileInfo.IsDir() { 220 t.Error("expect equal, got unequal") 221 } 222 if srcFile2FileInfo.Mode() != dstFile2FileInfo.Mode() { 223 t.Error("expect equal, got unequal") 224 } 225 }