oras.land/oras-go/v2@v2.5.1-0.20240520045656-aef90e4d04c4/content/reader_test.go (about)

     1  /*
     2  Copyright The ORAS Authors.
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6  
     7  http://www.apache.org/licenses/LICENSE-2.0
     8  
     9  Unless required by applicable law or agreed to in writing, software
    10  distributed under the License is distributed on an "AS IS" BASIS,
    11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  See the License for the specific language governing permissions and
    13  limitations under the License.
    14  */
    15  
    16  package content
    17  
    18  import (
    19  	"bytes"
    20  	_ "crypto/sha256"
    21  	"errors"
    22  	"io"
    23  	"testing"
    24  
    25  	"github.com/opencontainers/go-digest"
    26  	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
    27  )
    28  
    29  func TestVerifyReader_Read(t *testing.T) {
    30  	// matched content and descriptor with small buffer
    31  	content := []byte("example content")
    32  	desc := NewDescriptorFromBytes("test", content)
    33  	r := bytes.NewReader(content)
    34  	vr := NewVerifyReader(r, desc)
    35  	buf := make([]byte, 5)
    36  	n, err := vr.Read(buf)
    37  	if err != nil {
    38  		t.Fatal("Read() error = ", err)
    39  	}
    40  	if !bytes.Equal(buf, []byte("examp")) {
    41  		t.Fatalf("incorrect read content: %s", buf)
    42  	}
    43  	if n != 5 {
    44  		t.Fatalf("incorrect number of bytes read: %d", n)
    45  	}
    46  
    47  	// matched content and descriptor with sufficient buffer
    48  	content = []byte("foo foo")
    49  	desc = NewDescriptorFromBytes("test", content)
    50  	r = bytes.NewReader(content)
    51  	vr = NewVerifyReader(r, desc)
    52  	buf = make([]byte, len(content))
    53  	n, err = vr.Read(buf)
    54  	if err != nil {
    55  		t.Fatal("Read() error = ", err)
    56  	}
    57  	if n != len(content) {
    58  		t.Fatalf("incorrect number of bytes read: %d", n)
    59  	}
    60  	if !bytes.Equal(buf, content) {
    61  		t.Fatalf("incorrect read content: %s", buf)
    62  	}
    63  
    64  	// mismatched content and descriptor with sufficient buffer
    65  	r = bytes.NewReader([]byte("bar"))
    66  	vr = NewVerifyReader(r, desc)
    67  	buf = make([]byte, 5)
    68  	n, err = vr.Read(buf)
    69  	if err != nil {
    70  		t.Fatal("Read() error = ", err)
    71  	}
    72  	if n != 3 {
    73  		t.Fatalf("incorrect number of bytes read: %d", n)
    74  	}
    75  }
    76  
    77  func TestVerifyReader_Verify(t *testing.T) {
    78  	// matched content and descriptor
    79  	content := []byte("example content")
    80  	desc := NewDescriptorFromBytes("test", content)
    81  	r := bytes.NewReader(content)
    82  	vr := NewVerifyReader(r, desc)
    83  	buf := make([]byte, len(content))
    84  	if _, err := vr.Read(buf); err != nil {
    85  		t.Fatal("Read() error = ", err)
    86  	}
    87  	if err := vr.Verify(); err != nil {
    88  		t.Fatal("Verify() error = ", err)
    89  	}
    90  	if !bytes.Equal(buf, content) {
    91  		t.Fatalf("incorrect read content: %s", buf)
    92  	}
    93  
    94  	// mismatched content and descriptor, read size larger than descriptor size
    95  	content = []byte("foo")
    96  	r = bytes.NewReader(content)
    97  	desc = ocispec.Descriptor{
    98  		MediaType: ocispec.MediaTypeImageLayer,
    99  		Digest:    digest.FromBytes(content),
   100  		Size:      int64(len(content)) - 1}
   101  	vr = NewVerifyReader(r, desc)
   102  	buf = make([]byte, len(content))
   103  	if _, err := vr.Read(buf); err != nil {
   104  		t.Fatal("Read() error = ", err)
   105  	}
   106  	if err := vr.Verify(); !errors.Is(err, ErrTrailingData) {
   107  		t.Fatalf("Verify() error = %v, want %v", err, ErrTrailingData)
   108  	}
   109  	// call vr.Verify again, the result should be the same
   110  	if err := vr.Verify(); !errors.Is(err, ErrTrailingData) {
   111  		t.Fatalf("2nd Verify() error = %v, want %v", err, ErrTrailingData)
   112  	}
   113  
   114  	// mismatched content and descriptor, read size smaller than descriptor size
   115  	content = []byte("foo")
   116  	r = bytes.NewReader(content)
   117  	desc = ocispec.Descriptor{
   118  		MediaType: ocispec.MediaTypeImageLayer,
   119  		Digest:    digest.FromBytes(content),
   120  		Size:      int64(len(content)) + 1}
   121  	vr = NewVerifyReader(r, desc)
   122  	buf = make([]byte, len(content))
   123  	if _, err := vr.Read(buf); err != nil {
   124  		t.Fatal("Read() error = ", err)
   125  	}
   126  	if err := vr.Verify(); !errors.Is(err, errEarlyVerify) {
   127  		t.Fatalf("Verify() error = %v, want %v", err, errEarlyVerify)
   128  	}
   129  	// call vr.Verify again, the result should be the same
   130  	if err := vr.Verify(); !errors.Is(err, errEarlyVerify) {
   131  		t.Fatalf("Verify() error = %v, want %v", err, errEarlyVerify)
   132  	}
   133  
   134  	// mismatched content and descriptor, wrong digest
   135  	content = []byte("bar")
   136  	r = bytes.NewReader(content)
   137  	desc = NewDescriptorFromBytes("test", []byte("foo"))
   138  	vr = NewVerifyReader(r, desc)
   139  	buf = make([]byte, len(content))
   140  	if _, err := vr.Read(buf); err != nil {
   141  		t.Fatal("Read() error = ", err)
   142  	}
   143  	if err := vr.Verify(); !errors.Is(err, ErrMismatchedDigest) {
   144  		t.Fatalf("Verify() error = %v, want %v", err, ErrMismatchedDigest)
   145  	}
   146  	// call vr.Verify again, the result should be the same
   147  	if err := vr.Verify(); !errors.Is(err, ErrMismatchedDigest) {
   148  		t.Fatalf("2nd Verify() error = %v, want %v", err, ErrMismatchedDigest)
   149  	}
   150  }
   151  
   152  func TestReadAll_CorrectDescriptor(t *testing.T) {
   153  	content := []byte("example content")
   154  	desc := NewDescriptorFromBytes("test", content)
   155  	r := bytes.NewReader([]byte(content))
   156  	got, err := ReadAll(r, desc)
   157  	if err != nil {
   158  		t.Fatal("ReadAll() error = ", err)
   159  	}
   160  	if !bytes.Equal(got, content) {
   161  		t.Errorf("ReadAll() = %v, want %v", got, content)
   162  	}
   163  }
   164  
   165  func TestReadAll_ReadSizeSmallerThanDescriptorSize(t *testing.T) {
   166  	content := []byte("example content")
   167  	desc := ocispec.Descriptor{
   168  		MediaType: ocispec.MediaTypeImageLayer,
   169  		Digest:    digest.FromBytes(content),
   170  		Size:      int64(len(content) + 1)}
   171  	r := bytes.NewReader([]byte(content))
   172  	_, err := ReadAll(r, desc)
   173  	if err == nil || !errors.Is(err, io.ErrUnexpectedEOF) {
   174  		t.Errorf("ReadAll() error = %v, want %v", err, io.ErrUnexpectedEOF)
   175  	}
   176  }
   177  
   178  func TestReadAll_ReadSizeLargerThanDescriptorSize(t *testing.T) {
   179  	content := []byte("example content")
   180  	desc := ocispec.Descriptor{
   181  		MediaType: ocispec.MediaTypeImageLayer,
   182  		Digest:    digest.FromBytes(content),
   183  		Size:      int64(len(content) - 1)}
   184  	r := bytes.NewReader([]byte(content))
   185  	_, err := ReadAll(r, desc)
   186  	if err == nil || !errors.Is(err, ErrTrailingData) {
   187  		t.Errorf("ReadAll() error = %v, want %v", err, ErrTrailingData)
   188  	}
   189  }
   190  
   191  func TestReadAll_InvalidDigest(t *testing.T) {
   192  	content := []byte("example content")
   193  	desc := NewDescriptorFromBytes("test", []byte("another content"))
   194  	r := bytes.NewReader([]byte(content))
   195  	_, err := ReadAll(r, desc)
   196  	if err == nil || !errors.Is(err, ErrMismatchedDigest) {
   197  		t.Errorf("ReadAll() error = %v, want %v", err, ErrMismatchedDigest)
   198  	}
   199  }
   200  
   201  func TestReadAll_EmptyContent(t *testing.T) {
   202  	content := []byte("")
   203  	desc := NewDescriptorFromBytes("test", content)
   204  	r := bytes.NewReader([]byte(content))
   205  	got, err := ReadAll(r, desc)
   206  	if err != nil {
   207  		t.Fatal("ReadAll() error = ", err)
   208  	}
   209  	if !bytes.Equal(got, content) {
   210  		t.Errorf("ReadAll() = %v, want %v", got, content)
   211  	}
   212  }
   213  
   214  func TestReadAll_InvalidDescriptorSize(t *testing.T) {
   215  	content := []byte("example content")
   216  	desc := ocispec.Descriptor{
   217  		MediaType: ocispec.MediaTypeImageLayer,
   218  		Digest:    digest.FromBytes(content),
   219  		Size:      -1,
   220  	}
   221  	r := bytes.NewReader([]byte(content))
   222  	_, err := ReadAll(r, desc)
   223  	if err == nil || !errors.Is(err, ErrInvalidDescriptorSize) {
   224  		t.Errorf("ReadAll() error = %v, want %v", err, ErrInvalidDescriptorSize)
   225  	}
   226  }