...

Source file src/github.com/google/go-containerregistry/pkg/v1/partial/uncompressed_test.go

Documentation: github.com/google/go-containerregistry/pkg/v1/partial

     1  // Copyright 2019 Google LLC All Rights Reserved.
     2  //
     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  package partial_test
    16  
    17  import (
    18  	"io"
    19  	"os"
    20  	"testing"
    21  
    22  	"github.com/google/go-containerregistry/internal/compare"
    23  	legacy "github.com/google/go-containerregistry/pkg/legacy/tarball"
    24  	"github.com/google/go-containerregistry/pkg/name"
    25  	v1 "github.com/google/go-containerregistry/pkg/v1"
    26  	"github.com/google/go-containerregistry/pkg/v1/mutate"
    27  	"github.com/google/go-containerregistry/pkg/v1/partial"
    28  	"github.com/google/go-containerregistry/pkg/v1/random"
    29  	"github.com/google/go-containerregistry/pkg/v1/tarball"
    30  	"github.com/google/go-containerregistry/pkg/v1/types"
    31  	"github.com/google/go-containerregistry/pkg/v1/validate"
    32  )
    33  
    34  // foreignLayer implements both partial.Describable and partial.UncompressedLayer.
    35  type foreignLayer struct {
    36  	wrapped v1.Layer
    37  }
    38  
    39  func (l *foreignLayer) Digest() (v1.Hash, error) {
    40  	return l.wrapped.Digest()
    41  }
    42  
    43  func (l *foreignLayer) Size() (int64, error) {
    44  	return l.wrapped.Size()
    45  }
    46  
    47  func (l *foreignLayer) MediaType() (types.MediaType, error) {
    48  	return types.DockerForeignLayer, nil
    49  }
    50  
    51  func (l *foreignLayer) Uncompressed() (io.ReadCloser, error) {
    52  	return l.wrapped.Uncompressed()
    53  }
    54  
    55  func (l *foreignLayer) DiffID() (v1.Hash, error) {
    56  	return l.wrapped.DiffID()
    57  }
    58  
    59  func (l *foreignLayer) Descriptor() (*v1.Descriptor, error) {
    60  	r, err := l.wrapped.Compressed()
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	h, sz, err := v1.SHA256(r)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  	return &v1.Descriptor{
    69  		Digest:    h,
    70  		Size:      sz,
    71  		MediaType: types.DockerForeignLayer,
    72  		URLs:      []string{"http://example.com"},
    73  	}, nil
    74  }
    75  
    76  func (l *foreignLayer) UncompressedSize() (int64, error) {
    77  	return partial.UncompressedSize(l.wrapped)
    78  }
    79  
    80  func TestUncompressedLayer(t *testing.T) {
    81  	randLayer, err := random.Layer(1024, types.DockerForeignLayer)
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	l := &foreignLayer{randLayer}
    86  
    87  	desc, err := partial.Descriptor(l)
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	if want, got := desc.URLs[0], "http://example.com"; want != got {
    93  		t.Errorf("URLs[0] = %s != %s", got, want)
    94  	}
    95  
    96  	layer, err := partial.UncompressedToLayer(l)
    97  	if err != nil {
    98  		t.Fatal(err)
    99  	}
   100  
   101  	if err := validate.Layer(layer); err != nil {
   102  		t.Errorf("validate.Layer: %v", err)
   103  	}
   104  	if _, err := partial.UncompressedSize(layer); err != nil {
   105  		t.Errorf("partial.UncompressedSize: %v", err)
   106  	}
   107  }
   108  
   109  // legacy/tarball.Write + tarball.Image leverages a lot of uncompressed partials.
   110  //
   111  // This is cribbed from pkg/legacy/tarball just to get intra-package coverage.
   112  func TestLegacyWrite(t *testing.T) {
   113  	// Make a tempfile for tarball writes.
   114  	fp, err := os.CreateTemp("", "")
   115  	if err != nil {
   116  		t.Fatalf("Error creating temp file.")
   117  	}
   118  	t.Log(fp.Name())
   119  	defer fp.Close()
   120  	defer os.Remove(fp.Name())
   121  
   122  	// Make a random image + layer with Descriptor().
   123  	randImage, err := random.Image(256, 2)
   124  	if err != nil {
   125  		t.Fatalf("Error creating random image: %v", err)
   126  	}
   127  	randLayer, err := random.Layer(1024, types.DockerForeignLayer)
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  	l, err := partial.UncompressedToLayer(&foreignLayer{randLayer})
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	img, err := mutate.AppendLayers(randImage, l)
   136  	if err != nil {
   137  		t.Fatal(err)
   138  	}
   139  	tag, err := name.NewTag("gcr.io/foo/bar:latest", name.StrictValidation)
   140  	if err != nil {
   141  		t.Fatalf("Error creating test tag: %v", err)
   142  	}
   143  	o, err := os.Create(fp.Name())
   144  	if err != nil {
   145  		t.Fatalf("Error creating %q to write image tarball: %v", fp.Name(), err)
   146  	}
   147  	defer o.Close()
   148  	if err := legacy.Write(tag, img, o); err != nil {
   149  		t.Fatalf("Unexpected error writing tarball: %v", err)
   150  	}
   151  
   152  	// Make sure the image is valid and can be loaded.
   153  	// Load it both by nil and by its name.
   154  	for _, it := range []*name.Tag{nil, &tag} {
   155  		tarImage, err := tarball.ImageFromPath(fp.Name(), it)
   156  		if err != nil {
   157  			t.Fatalf("Unexpected error reading tarball: %v", err)
   158  		}
   159  		if err := validate.Image(tarImage); err != nil {
   160  			t.Errorf("validate.Image: %v", err)
   161  		}
   162  		if err := compare.Images(img, tarImage); err != nil {
   163  			t.Errorf("compare.Images: %v", err)
   164  		}
   165  	}
   166  
   167  	// Try loading a different tag, it should error.
   168  	fakeTag, err := name.NewTag("gcr.io/notthistag:latest", name.StrictValidation)
   169  	if err != nil {
   170  		t.Fatalf("Error generating tag: %v", err)
   171  	}
   172  	if _, err := tarball.ImageFromPath(fp.Name(), &fakeTag); err == nil {
   173  		t.Errorf("Expected error loading tag %v from image", fakeTag)
   174  	}
   175  }
   176  
   177  type uncompressedImage struct {
   178  	img v1.Image
   179  }
   180  
   181  func (i *uncompressedImage) RawConfigFile() ([]byte, error) {
   182  	return i.img.RawConfigFile()
   183  }
   184  
   185  func (i *uncompressedImage) MediaType() (types.MediaType, error) {
   186  	return i.img.MediaType()
   187  }
   188  
   189  func (i *uncompressedImage) LayerByDiffID(h v1.Hash) (partial.UncompressedLayer, error) {
   190  	return i.img.LayerByDiffID(h)
   191  }
   192  
   193  func (i *uncompressedImage) Descriptor() (*v1.Descriptor, error) {
   194  	return partial.Descriptor(i.img)
   195  }
   196  
   197  func TestUncompressed(t *testing.T) {
   198  	rnd, err := random.Image(1024, 1)
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  
   203  	core := &uncompressedImage{rnd}
   204  
   205  	img, err := partial.UncompressedToImage(core)
   206  	if err != nil {
   207  		t.Fatal(err)
   208  	}
   209  
   210  	if err := validate.Image(img); err != nil {
   211  		t.Fatalf("validate.Image: %v", err)
   212  	}
   213  	if _, err := partial.Descriptor(img); err != nil {
   214  		t.Fatalf("partial.Descriptor: %v", err)
   215  	}
   216  
   217  	layers, err := img.Layers()
   218  	if err != nil {
   219  		t.Fatal(err)
   220  	}
   221  	layer, err := partial.UncompressedToLayer(&fastpathLayer{layers[0]})
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  
   226  	ok, err := partial.Exists(layer)
   227  	if err != nil {
   228  		t.Fatal(err)
   229  	}
   230  	if got, want := ok, true; got != want {
   231  		t.Errorf("Exists() = %t != %t", got, want)
   232  	}
   233  }
   234  

View as plain text