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, &copyWithFileRange, &copyWithFileClone)
    22  }
    23  
    24  func TestCopyWithoutRange(t *testing.T) {
    25  	copyWithFileRange := false
    26  	copyWithFileClone := false
    27  	doCopyTest(t, &copyWithFileRange, &copyWithFileClone)
    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  }