Sfoglia il codice sorgente

tarsum: adding benchmarks

to cover a couple of use-cases:
* 1mb file, using no compression
* 1mb file, using compression
* 1024 1k files, using no compression
* 1024 1k files, using compression

Docker-DCO-1.1-Signed-off-by: Vincent Batts <vbatts@redhat.com> (github: vbatts)
Vincent Batts 11 anni fa
parent
commit
d153740d9c
1 ha cambiato i file con 165 aggiunte e 4 eliminazioni
  1. 165 4
      utils/tarsum_test.go

+ 165 - 4
utils/tarsum_test.go

@@ -1,6 +1,10 @@
 package utils
 
 import (
+	"bytes"
+	"crypto/rand"
+	"fmt"
+	"github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
 	"io"
 	"io/ioutil"
 	"os"
@@ -9,6 +13,7 @@ import (
 
 type testLayer struct {
 	filename string
+	options  *sizedOptions
 	jsonfile string
 	gzip     bool
 	tarsum   string
@@ -19,20 +24,100 @@ var testLayers = []testLayer{
 		filename: "testdata/46af0962ab5afeb5ce6740d4d91652e69206fc991fd5328c1a94d364ad00e457/layer.tar",
 		jsonfile: "testdata/46af0962ab5afeb5ce6740d4d91652e69206fc991fd5328c1a94d364ad00e457/json",
 		tarsum:   "tarsum+sha256:e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b"},
+	{
+		filename: "testdata/46af0962ab5afeb5ce6740d4d91652e69206fc991fd5328c1a94d364ad00e457/layer.tar",
+		jsonfile: "testdata/46af0962ab5afeb5ce6740d4d91652e69206fc991fd5328c1a94d364ad00e457/json",
+		gzip:     true,
+		tarsum:   "tarsum+sha256:e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b"},
 	{
 		filename: "testdata/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158/layer.tar",
 		jsonfile: "testdata/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158/json",
 		tarsum:   "tarsum+sha256:ac672ee85da9ab7f9667ae3c32841d3e42f33cc52c273c23341dabba1c8b0c8b"},
+	{
+		options: &sizedOptions{1, 1024 * 1024, false, false}, // a 1mb file (in memory)
+		tarsum:  "tarsum+sha256:8bf12d7e67c51ee2e8306cba569398b1b9f419969521a12ffb9d8875e8836738"},
+}
+
+type sizedOptions struct {
+	num      int64
+	size     int64
+	isRand   bool
+	realFile bool
+}
+
+// make a tar:
+// * num is the number of files the tar should have
+// * size is the bytes per file
+// * isRand is whether the contents of the files should be a random chunk (otherwise it's all zeros)
+// * realFile will write to a TempFile, instead of an in memory buffer
+func sizedTar(opts sizedOptions) io.Reader {
+	var (
+		fh  io.ReadWriter
+		err error
+	)
+	if opts.realFile {
+		fh, err = ioutil.TempFile("", "tarsum")
+		if err != nil {
+			return nil
+		}
+	} else {
+		fh = bytes.NewBuffer([]byte{})
+	}
+	tarW := tar.NewWriter(fh)
+	for i := int64(0); i < opts.num; i++ {
+		err := tarW.WriteHeader(&tar.Header{
+			Name: fmt.Sprintf("/testdata%d", i),
+			Mode: 0755,
+			Uid:  0,
+			Gid:  0,
+			Size: opts.size,
+		})
+		if err != nil {
+			return nil
+		}
+		var rBuf []byte
+		if opts.isRand {
+			rBuf = make([]byte, 8)
+			_, err = rand.Read(rBuf)
+			if err != nil {
+				return nil
+			}
+		} else {
+			rBuf = []byte{0, 0, 0, 0, 0, 0, 0, 0}
+		}
+
+		for i := int64(0); i < opts.size/int64(8); i++ {
+			tarW.Write(rBuf)
+		}
+	}
+	return fh
 }
 
 func TestTarSums(t *testing.T) {
 	for _, layer := range testLayers {
-		fh, err := os.Open(layer.filename)
-		if err != nil {
-			t.Errorf("failed to open %s: %s", layer.filename, err)
+		var (
+			fh  io.Reader
+			err error
+		)
+		if len(layer.filename) > 0 {
+			fh, err = os.Open(layer.filename)
+			if err != nil {
+				t.Errorf("failed to open %s: %s", layer.filename, err)
+				continue
+			}
+		} else if layer.options != nil {
+			fh = sizedTar(*layer.options)
+		} else {
+			// What else is there to test?
+			t.Errorf("what to do with %#V", layer)
 			continue
 		}
-		ts := &TarSum{Reader: fh}
+		if file, ok := fh.(*os.File); ok {
+			defer file.Close()
+		}
+
+		//                                  double negatives!
+		ts := &TarSum{Reader: fh, DisableCompression: !layer.gzip}
 		_, err = io.Copy(ioutil.Discard, ts)
 		if err != nil {
 			t.Errorf("failed to copy from %s: %s", layer.filename, err)
@@ -58,6 +143,82 @@ func TestTarSums(t *testing.T) {
 		if layer.tarsum != gotSum {
 			t.Errorf("expecting [%s], but got [%s]", layer.tarsum, gotSum)
 		}
+	}
+}
+
+func Benchmark9kTar(b *testing.B) {
+	buf := bytes.NewBuffer([]byte{})
+	fh, err := os.Open("testdata/46af0962ab5afeb5ce6740d4d91652e69206fc991fd5328c1a94d364ad00e457/layer.tar")
+	if err != nil {
+		b.Error(err)
+		return
+	}
+	n, err := io.Copy(buf, fh)
+	fh.Close()
+
+	b.SetBytes(n)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		ts := &TarSum{Reader: buf, DisableCompression: true}
+		io.Copy(ioutil.Discard, ts)
+		ts.Sum(nil)
+	}
+}
+
+func Benchmark9kTarGzip(b *testing.B) {
+	buf := bytes.NewBuffer([]byte{})
+	fh, err := os.Open("testdata/46af0962ab5afeb5ce6740d4d91652e69206fc991fd5328c1a94d364ad00e457/layer.tar")
+	if err != nil {
+		b.Error(err)
+		return
+	}
+	n, err := io.Copy(buf, fh)
+	fh.Close()
+
+	b.SetBytes(n)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		ts := &TarSum{Reader: buf, DisableCompression: false}
+		io.Copy(ioutil.Discard, ts)
+		ts.Sum(nil)
+	}
+}
+
+// this is a single big file in the tar archive
+func Benchmark1mbSingleFileTar(b *testing.B) {
+	benchmarkTar(b, sizedOptions{1, 1024 * 1024, true, true}, false)
+}
+
+// this is a single big file in the tar archive
+func Benchmark1mbSingleFileTarGzip(b *testing.B) {
+	benchmarkTar(b, sizedOptions{1, 1024 * 1024, true, true}, true)
+}
+
+// this is 1024 1k files in the tar archive
+func Benchmark1kFilesTar(b *testing.B) {
+	benchmarkTar(b, sizedOptions{1024, 1024, true, true}, false)
+}
+
+// this is 1024 1k files in the tar archive
+func Benchmark1kFilesTarGzip(b *testing.B) {
+	benchmarkTar(b, sizedOptions{1024, 1024, true, true}, true)
+}
+
+func benchmarkTar(b *testing.B, opts sizedOptions, isGzip bool) {
+	var fh *os.File
+	tarReader := sizedTar(opts)
+	if br, ok := tarReader.(*os.File); ok {
+		fh = br
+	}
+	defer os.Remove(fh.Name())
+	defer fh.Close()
 
+	b.SetBytes(opts.size * opts.num)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		ts := &TarSum{Reader: fh, DisableCompression: !isGzip}
+		io.Copy(ioutil.Discard, ts)
+		ts.Sum(nil)
+		fh.Seek(0, 0)
 	}
 }