Home Download Docs Code Community
     1	/*
     2	Copyright 2011 The Perkeep Authors
     3	
     4	Licensed under the Apache License, Version 2.0 (the "License");
     5	you may not use this file except in compliance with the License.
     6	You may obtain a copy of the License at
     7	
     8	     http://www.apache.org/licenses/LICENSE-2.0
     9	
    10	Unless required by applicable law or agreed to in writing, software
    11	distributed under the License is distributed on an "AS IS" BASIS,
    12	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13	See the License for the specific language governing permissions and
    14	limitations under the License.
    15	*/
    16	
    17	package test
    18	
    19	import (
    20		"context"
    21		"encoding/base64"
    22		"fmt"
    23		"io"
    24		"math/rand"
    25		"strings"
    26		"testing"
    27		"time"
    28	
    29		"perkeep.org/pkg/blob"
    30		"perkeep.org/pkg/blobserver"
    31	)
    32	
    33	// Blob is a utility class for unit tests.
    34	type Blob struct {
    35		Contents string // the contents of the blob
    36	}
    37	
    38	var randSrc = rand.New(rand.NewSource(time.Now().UnixNano()))
    39	
    40	// RandomBlob returns a random blob with the provided number of bytes.
    41	func RandomBlob(t *testing.T, size int64) *Blob {
    42		contents := make([]byte, size)
    43		_, err := io.ReadFull(randSrc, contents)
    44		if err != nil {
    45			t.Fatal("error reading from random source:", err)
    46		}
    47	
    48		return &Blob{
    49			Contents: base64.StdEncoding.EncodeToString(contents)[:size],
    50		}
    51	}
    52	
    53	func (tb *Blob) Blob() *blob.Blob {
    54		s := tb.Contents
    55		return blob.NewBlob(tb.BlobRef(), tb.Size(), func(ctx context.Context) ([]byte, error) {
    56			return []byte(s), nil
    57		})
    58	}
    59	
    60	func (tb *Blob) BlobRef() blob.Ref {
    61		h := blob.NewHash()
    62		io.WriteString(h, tb.Contents)
    63		return blob.RefFromHash(h)
    64	}
    65	
    66	func (tb *Blob) SizedRef() blob.SizedRef {
    67		return blob.SizedRef{Ref: tb.BlobRef(), Size: tb.Size()}
    68	}
    69	
    70	func (tb *Blob) BlobRefSlice() []blob.Ref {
    71		return []blob.Ref{tb.BlobRef()}
    72	}
    73	
    74	func (tb *Blob) Size() uint32 {
    75		// Check that it's not larger than a uint32 (possible with
    76		// 64-bit ints).  But while we're here, be more paranoid and
    77		// check for over the default max blob size of 16 MB.
    78		if len(tb.Contents) > 16<<20 {
    79			panic(fmt.Sprintf("test blob of %d bytes is larger than max 16MB allowed in testing", len(tb.Contents)))
    80		}
    81		return uint32(len(tb.Contents))
    82	}
    83	
    84	func (tb *Blob) Reader() io.Reader {
    85		return strings.NewReader(tb.Contents)
    86	}
    87	
    88	func (tb *Blob) AssertMatches(t *testing.T, sb blob.SizedRef) {
    89		if sb.Size != tb.Size() {
    90			t.Fatalf("Got size %d; expected %d", sb.Size, tb.Size())
    91		}
    92		if sb.Ref != tb.BlobRef() {
    93			t.Fatalf("Got blob %q; expected %q", sb.Ref.String(), tb.BlobRef())
    94		}
    95	}
    96	
    97	func (tb *Blob) MustUpload(t *testing.T, ds blobserver.BlobReceiver) {
    98		sb, err := ds.ReceiveBlob(context.Background(), tb.BlobRef(), tb.Reader())
    99		if err != nil {
   100			t.Fatalf("failed to upload blob %v (%q): %v", tb.BlobRef(), tb.Contents, err)
   101		}
   102		tb.AssertMatches(t, sb) // TODO: better error reporting
   103	}
Website layout inspired by memcached.
Content by the authors.