github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/testing/targz.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package testing 5 6 import ( 7 "archive/tar" 8 "bytes" 9 "compress/gzip" 10 "crypto/sha256" 11 "fmt" 12 "io" 13 "os" 14 ) 15 16 // TarFile represents a file to be archived. 17 type TarFile struct { 18 Header tar.Header 19 Contents string 20 } 21 22 var modes = map[os.FileMode]byte{ 23 os.ModeDir: tar.TypeDir, 24 os.ModeSymlink: tar.TypeSymlink, 25 0: tar.TypeReg, 26 } 27 28 // NewTarFile returns a new TarFile instance with the given file 29 // mode and contents. 30 func NewTarFile(name string, mode os.FileMode, contents string) *TarFile { 31 ftype := modes[mode&os.ModeType] 32 if ftype == 0 { 33 panic(fmt.Errorf("unexpected mode %v", mode)) 34 } 35 // NOTE: Do not set attributes (e.g. times) dynamically, as various 36 // tests expect the contents of fake tools archives to be unchanging. 37 return &TarFile{ 38 Header: tar.Header{ 39 Typeflag: ftype, 40 Name: name, 41 Size: int64(len(contents)), 42 Mode: int64(mode & 0777), 43 Uname: "ubuntu", 44 Gname: "ubuntu", 45 }, 46 Contents: contents, 47 } 48 } 49 50 // TarGz returns the given files in gzipped tar-archive format, along with the sha256 checksum. 51 func TarGz(files ...*TarFile) ([]byte, string) { 52 var buf bytes.Buffer 53 sha256hash := sha256.New() 54 gzw := gzip.NewWriter(io.MultiWriter(&buf, sha256hash)) 55 tarw := tar.NewWriter(gzw) 56 57 for _, f := range files { 58 err := tarw.WriteHeader(&f.Header) 59 if err != nil { 60 panic(err) 61 } 62 _, err = tarw.Write([]byte(f.Contents)) 63 if err != nil { 64 panic(err) 65 } 66 } 67 err := tarw.Close() 68 if err != nil { 69 panic(err) 70 } 71 err = gzw.Close() 72 if err != nil { 73 panic(err) 74 } 75 checksum := fmt.Sprintf("%x", sha256hash.Sum(nil)) 76 return buf.Bytes(), checksum 77 }