github.com/npaton/distribution@v2.3.1-rc.0+incompatible/testutil/tarfile.go (about) 1 package testutil 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "crypto/rand" 7 "fmt" 8 "io" 9 mrand "math/rand" 10 "time" 11 12 "github.com/docker/distribution/digest" 13 ) 14 15 // CreateRandomTarFile creates a random tarfile, returning it as an 16 // io.ReadSeeker along with its digest. An error is returned if there is a 17 // problem generating valid content. 18 func CreateRandomTarFile() (rs io.ReadSeeker, dgst digest.Digest, err error) { 19 nFiles := mrand.Intn(10) + 10 20 target := &bytes.Buffer{} 21 wr := tar.NewWriter(target) 22 23 // Perturb this on each iteration of the loop below. 24 header := &tar.Header{ 25 Mode: 0644, 26 ModTime: time.Now(), 27 Typeflag: tar.TypeReg, 28 Uname: "randocalrissian", 29 Gname: "cloudcity", 30 AccessTime: time.Now(), 31 ChangeTime: time.Now(), 32 } 33 34 for fileNumber := 0; fileNumber < nFiles; fileNumber++ { 35 fileSize := mrand.Int63n(1<<20) + 1<<20 36 37 header.Name = fmt.Sprint(fileNumber) 38 header.Size = fileSize 39 40 if err := wr.WriteHeader(header); err != nil { 41 return nil, "", err 42 } 43 44 randomData := make([]byte, fileSize) 45 46 // Fill up the buffer with some random data. 47 n, err := rand.Read(randomData) 48 49 if n != len(randomData) { 50 return nil, "", fmt.Errorf("short read creating random reader: %v bytes != %v bytes", n, len(randomData)) 51 } 52 53 if err != nil { 54 return nil, "", err 55 } 56 57 nn, err := io.Copy(wr, bytes.NewReader(randomData)) 58 if nn != fileSize { 59 return nil, "", fmt.Errorf("short copy writing random file to tar") 60 } 61 62 if err != nil { 63 return nil, "", err 64 } 65 66 if err := wr.Flush(); err != nil { 67 return nil, "", err 68 } 69 } 70 71 if err := wr.Close(); err != nil { 72 return nil, "", err 73 } 74 75 dgst = digest.FromBytes(target.Bytes()) 76 77 return bytes.NewReader(target.Bytes()), dgst, nil 78 }