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  }