160 lines
3.7 KiB
Go
160 lines
3.7 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package testutil
|
|
|
|
import (
|
|
"archive/tar"
|
|
"archive/zip"
|
|
"bytes"
|
|
"crypto/rand"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// ConstructRandomBytes constructs random bytes of given size
|
|
func ConstructRandomBytes(t testing.TB, size int) []byte {
|
|
value := make([]byte, size)
|
|
_, err := rand.Read(value)
|
|
if err != nil {
|
|
t.Fatalf("Error while generating random bytes: %s", err)
|
|
}
|
|
return value
|
|
}
|
|
|
|
// TarFileEntry is a structure for adding test index files to an tar
|
|
type TarFileEntry struct {
|
|
Name, Body string
|
|
}
|
|
|
|
// CreateTarBytesForTest creates a tar byte array for unit testing
|
|
func CreateTarBytesForTest(testFiles []*TarFileEntry) []byte {
|
|
// Create a buffer for the tar file
|
|
buffer := new(bytes.Buffer)
|
|
tarWriter := tar.NewWriter(buffer)
|
|
|
|
for _, file := range testFiles {
|
|
tarHeader := &tar.Header{
|
|
Name: file.Name,
|
|
Mode: 0o600,
|
|
Size: int64(len(file.Body)),
|
|
}
|
|
err := tarWriter.WriteHeader(tarHeader)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
_, err = tarWriter.Write([]byte(file.Body))
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
}
|
|
// Make sure to check the error on Close.
|
|
tarWriter.Close()
|
|
return buffer.Bytes()
|
|
}
|
|
|
|
// CopyDir creates a copy of a dir
|
|
func CopyDir(srcroot, destroot string, copyOnlySubdirs bool) error {
|
|
if !copyOnlySubdirs {
|
|
_, lastSegment := filepath.Split(srcroot)
|
|
destroot = filepath.Join(destroot, lastSegment)
|
|
}
|
|
|
|
walkFunc := func(srcpath string, info os.FileInfo, errDummy error) error {
|
|
srcsubpath, err := filepath.Rel(srcroot, srcpath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
destpath := filepath.Join(destroot, srcsubpath)
|
|
|
|
if info.IsDir() { // its a dir, make corresponding dir in the dest
|
|
if err = os.MkdirAll(destpath, info.Mode()); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// its a file, copy to corresponding path in the dest
|
|
if err = copyFile(srcpath, destpath); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
return filepath.Walk(srcroot, walkFunc)
|
|
}
|
|
|
|
func copyFile(srcpath, destpath string) error {
|
|
var srcFile, destFile *os.File
|
|
var err error
|
|
if srcFile, err = os.Open(srcpath); err != nil {
|
|
return err
|
|
}
|
|
if destFile, err = os.Create(destpath); err != nil {
|
|
return err
|
|
}
|
|
if _, err = io.Copy(destFile, srcFile); err != nil {
|
|
return err
|
|
}
|
|
if err = srcFile.Close(); err != nil {
|
|
return err
|
|
}
|
|
if err = destFile.Close(); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Unzip will decompress the src zip file to the dest directory.
|
|
// If createTopLevelDirInZip is true, it creates the top level dir when unzipped.
|
|
// Otherwise, it trims off the top level dir when unzipped. For example, ledersData/historydb/abc will become historydb/abc.
|
|
func Unzip(src string, dest string, createTopLevelDirInZip bool) error {
|
|
r, err := zip.OpenReader(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer r.Close()
|
|
|
|
// iterate all the dirs and files in the zip file
|
|
for _, file := range r.File {
|
|
filePath := file.Name
|
|
if !createTopLevelDirInZip {
|
|
// trim off the top level dir - for example, trim ledgersData/historydb/abc to historydb/abc
|
|
index := strings.Index(filePath, string(filepath.Separator))
|
|
filePath = filePath[index+1:]
|
|
}
|
|
|
|
fullPath := filepath.Join(dest, filePath)
|
|
if file.FileInfo().IsDir() {
|
|
os.MkdirAll(fullPath, os.ModePerm)
|
|
continue
|
|
}
|
|
if err = os.MkdirAll(filepath.Dir(fullPath), os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
outFile, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rc, err := file.Open()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = io.Copy(outFile, rc)
|
|
|
|
outFile.Close()
|
|
rc.Close()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|