github.com/ZuluSpl0it/Sia@v1.3.7/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 }