github.com/lusis/distribution@v2.0.1+incompatible/registry/storage/filereader_test.go (about)

     1  package storage
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"io"
     7  	mrand "math/rand"
     8  	"os"
     9  	"testing"
    10  
    11  	"github.com/docker/distribution/digest"
    12  
    13  	"github.com/docker/distribution/registry/storage/driver/inmemory"
    14  )
    15  
    16  func TestSimpleRead(t *testing.T) {
    17  	content := make([]byte, 1<<20)
    18  	n, err := rand.Read(content)
    19  	if err != nil {
    20  		t.Fatalf("unexpected error building random data: %v", err)
    21  	}
    22  
    23  	if n != len(content) {
    24  		t.Fatalf("random read did't fill buffer")
    25  	}
    26  
    27  	dgst, err := digest.FromReader(bytes.NewReader(content))
    28  	if err != nil {
    29  		t.Fatalf("unexpected error digesting random content: %v", err)
    30  	}
    31  
    32  	driver := inmemory.New()
    33  	path := "/random"
    34  
    35  	if err := driver.PutContent(path, content); err != nil {
    36  		t.Fatalf("error putting patterned content: %v", err)
    37  	}
    38  
    39  	fr, err := newFileReader(driver, path)
    40  	if err != nil {
    41  		t.Fatalf("error allocating file reader: %v", err)
    42  	}
    43  
    44  	verifier, err := digest.NewDigestVerifier(dgst)
    45  	if err != nil {
    46  		t.Fatalf("error getting digest verifier: %s", err)
    47  	}
    48  
    49  	io.Copy(verifier, fr)
    50  
    51  	if !verifier.Verified() {
    52  		t.Fatalf("unable to verify read data")
    53  	}
    54  }
    55  
    56  func TestFileReaderSeek(t *testing.T) {
    57  	driver := inmemory.New()
    58  	pattern := "01234567890ab" // prime length block
    59  	repititions := 1024
    60  	path := "/patterned"
    61  	content := bytes.Repeat([]byte(pattern), repititions)
    62  
    63  	if err := driver.PutContent(path, content); err != nil {
    64  		t.Fatalf("error putting patterned content: %v", err)
    65  	}
    66  
    67  	fr, err := newFileReader(driver, path)
    68  
    69  	if err != nil {
    70  		t.Fatalf("unexpected error creating file reader: %v", err)
    71  	}
    72  
    73  	// Seek all over the place, in blocks of pattern size and make sure we get
    74  	// the right data.
    75  	for _, repitition := range mrand.Perm(repititions - 1) {
    76  		targetOffset := int64(len(pattern) * repitition)
    77  		// Seek to a multiple of pattern size and read pattern size bytes
    78  		offset, err := fr.Seek(targetOffset, os.SEEK_SET)
    79  		if err != nil {
    80  			t.Fatalf("unexpected error seeking: %v", err)
    81  		}
    82  
    83  		if offset != targetOffset {
    84  			t.Fatalf("did not seek to correct offset: %d != %d", offset, targetOffset)
    85  		}
    86  
    87  		p := make([]byte, len(pattern))
    88  
    89  		n, err := fr.Read(p)
    90  		if err != nil {
    91  			t.Fatalf("error reading pattern: %v", err)
    92  		}
    93  
    94  		if n != len(pattern) {
    95  			t.Fatalf("incorrect read length: %d != %d", n, len(pattern))
    96  		}
    97  
    98  		if string(p) != pattern {
    99  			t.Fatalf("incorrect read content: %q != %q", p, pattern)
   100  		}
   101  
   102  		// Check offset
   103  		current, err := fr.Seek(0, os.SEEK_CUR)
   104  		if err != nil {
   105  			t.Fatalf("error checking current offset: %v", err)
   106  		}
   107  
   108  		if current != targetOffset+int64(len(pattern)) {
   109  			t.Fatalf("unexpected offset after read: %v", err)
   110  		}
   111  	}
   112  
   113  	start, err := fr.Seek(0, os.SEEK_SET)
   114  	if err != nil {
   115  		t.Fatalf("error seeking to start: %v", err)
   116  	}
   117  
   118  	if start != 0 {
   119  		t.Fatalf("expected to seek to start: %v != 0", start)
   120  	}
   121  
   122  	end, err := fr.Seek(0, os.SEEK_END)
   123  	if err != nil {
   124  		t.Fatalf("error checking current offset: %v", err)
   125  	}
   126  
   127  	if end != int64(len(content)) {
   128  		t.Fatalf("expected to seek to end: %v != %v", end, len(content))
   129  	}
   130  
   131  	// 4. Seek before start, ensure error.
   132  
   133  	// seek before start
   134  	before, err := fr.Seek(-1, os.SEEK_SET)
   135  	if err == nil {
   136  		t.Fatalf("error expected, returned offset=%v", before)
   137  	}
   138  
   139  	// 5. Seek after end,
   140  	after, err := fr.Seek(1, os.SEEK_END)
   141  	if err != nil {
   142  		t.Fatalf("unexpected error expected, returned offset=%v", after)
   143  	}
   144  
   145  	p := make([]byte, 16)
   146  	n, err := fr.Read(p)
   147  
   148  	if n != 0 {
   149  		t.Fatalf("bytes reads %d != %d", n, 0)
   150  	}
   151  
   152  	if err != io.EOF {
   153  		t.Fatalf("expected io.EOF, got %v", err)
   154  	}
   155  }
   156  
   157  // TestFileReaderNonExistentFile ensures the reader behaves as expected with a
   158  // missing or zero-length remote file. While the file may not exist, the
   159  // reader should not error out on creation and should return 0-bytes from the
   160  // read method, with an io.EOF error.
   161  func TestFileReaderNonExistentFile(t *testing.T) {
   162  	driver := inmemory.New()
   163  	fr, err := newFileReader(driver, "/doesnotexist")
   164  	if err != nil {
   165  		t.Fatalf("unexpected error initializing reader: %v", err)
   166  	}
   167  
   168  	var buf [1024]byte
   169  
   170  	n, err := fr.Read(buf[:])
   171  	if n != 0 {
   172  		t.Fatalf("non-zero byte read reported: %d != 0", n)
   173  	}
   174  
   175  	if err != io.EOF {
   176  		t.Fatalf("read on missing file should return io.EOF, got %v", err)
   177  	}
   178  }
   179  
   180  // TestLayerReadErrors covers the various error return type for different
   181  // conditions that can arise when reading a layer.
   182  func TestFileReaderErrors(t *testing.T) {
   183  	// TODO(stevvooe): We need to cover error return types, driven by the
   184  	// errors returned via the HTTP API. For now, here is a incomplete list:
   185  	//
   186  	// 	1. Layer Not Found: returned when layer is not found or access is
   187  	//        denied.
   188  	//	2. Layer Unavailable: returned when link references are unresolved,
   189  	//     but layer is known to the registry.
   190  	//  3. Layer Invalid: This may more split into more errors, but should be
   191  	//     returned when name or tarsum does not reference a valid error. We
   192  	//     may also need something to communication layer verification errors
   193  	//     for the inline tarsum check.
   194  	//	4. Timeout: timeouts to backend. Need to better understand these
   195  	//     failure cases and how the storage driver propagates these errors
   196  	//     up the stack.
   197  }