gitlab.com/SiaPrime/SiaPrime@v1.4.1/build/testing.go (about)

     1  package build
     2  
     3  import (
     4  	"archive/tar"
     5  	"compress/gzip"
     6  	"errors"
     7  	"io"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"time"
    12  )
    13  
    14  var (
    15  	// SiaTestingDir is the directory that contains all of the files and
    16  	// folders created during testing.
    17  	SiaTestingDir = filepath.Join(os.TempDir(), "SiaTesting")
    18  )
    19  
    20  // TempDir joins the provided directories and prefixes them with the Sia
    21  // testing directory.
    22  func TempDir(dirs ...string) string {
    23  	path := filepath.Join(SiaTestingDir, filepath.Join(dirs...))
    24  	os.RemoveAll(path) // remove old test data
    25  	return path
    26  }
    27  
    28  // CopyFile copies a file from a source to a destination.
    29  func CopyFile(source, dest string) error {
    30  	sf, err := os.Open(source)
    31  	if err != nil {
    32  		return err
    33  	}
    34  	defer sf.Close()
    35  
    36  	df, err := os.Create(dest)
    37  	if err != nil {
    38  		return err
    39  	}
    40  	defer df.Close()
    41  
    42  	_, err = io.Copy(df, sf)
    43  	if err != nil {
    44  		return err
    45  	}
    46  	return nil
    47  }
    48  
    49  // CopyDir copies a directory and all of its contents to the destination
    50  // directory.
    51  func CopyDir(source, dest string) error {
    52  	stat, err := os.Stat(source)
    53  	if err != nil {
    54  		return err
    55  	}
    56  	if !stat.IsDir() {
    57  		return errors.New("source is not a directory")
    58  	}
    59  
    60  	err = os.MkdirAll(dest, stat.Mode())
    61  	if err != nil {
    62  		return err
    63  	}
    64  	files, err := ioutil.ReadDir(source)
    65  	if err != nil {
    66  		return err
    67  	}
    68  	for _, file := range files {
    69  		newSource := filepath.Join(source, file.Name())
    70  		newDest := filepath.Join(dest, file.Name())
    71  		if file.IsDir() {
    72  			err = CopyDir(newSource, newDest)
    73  			if err != nil {
    74  				return err
    75  			}
    76  		} else {
    77  			err = CopyFile(newSource, newDest)
    78  			if err != nil {
    79  				return err
    80  			}
    81  		}
    82  	}
    83  
    84  	return nil
    85  }
    86  
    87  // ExtractTarGz extracts the specified .tar.gz file to dir, overwriting
    88  // existing files in the event of a name conflict.
    89  func ExtractTarGz(filename, dir string) error {
    90  	// Open the zipped archive.
    91  	file, err := os.Open(filename)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	defer file.Close()
    96  	z, err := gzip.NewReader(file)
    97  	if err != nil {
    98  		return err
    99  	}
   100  	defer z.Close()
   101  	t := tar.NewReader(z)
   102  
   103  	// Create the output directory if it does not exist.
   104  	if err := os.MkdirAll(dir, 0700); err != nil {
   105  		return err
   106  	}
   107  
   108  	// Read the file entries, writing each to dir.
   109  	for {
   110  		// Read header.
   111  		hdr, err := t.Next()
   112  		if err == io.EOF {
   113  			return nil
   114  		} else if err != nil {
   115  			return err
   116  		}
   117  
   118  		path := filepath.Join(dir, hdr.Name)
   119  		info := hdr.FileInfo()
   120  		if info.IsDir() {
   121  			// Create directory.
   122  			if err := os.MkdirAll(path, info.Mode()); err != nil {
   123  				return err
   124  			}
   125  		} else {
   126  			// Create file.
   127  			tf, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
   128  			if err != nil {
   129  				return err
   130  			}
   131  			_, err = io.Copy(tf, t)
   132  			tf.Close()
   133  			if err != nil {
   134  				return err
   135  			}
   136  		}
   137  	}
   138  }
   139  
   140  // Retry will call 'fn' 'tries' times, waiting 'durationBetweenAttempts'
   141  // between each attempt, returning 'nil' the first time that 'fn' returns nil.
   142  // If 'nil' is never returned, then the final error returned by 'fn' is
   143  // returned.
   144  func Retry(tries int, durationBetweenAttempts time.Duration, fn func() error) (err error) {
   145  	for i := 1; i < tries; i++ {
   146  		err = fn()
   147  		if err == nil {
   148  			return nil
   149  		}
   150  		time.Sleep(durationBetweenAttempts)
   151  	}
   152  	return fn()
   153  }