...

Source file src/github.com/google/go-containerregistry/pkg/v1/daemon/image_test.go

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

     1  // Copyright 2018 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 daemon
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"fmt"
    21  	"io"
    22  	"os"
    23  	"strings"
    24  	"testing"
    25  
    26  	"github.com/docker/docker/api/types/container"
    27  	api "github.com/docker/docker/api/types/image"
    28  
    29  	"github.com/docker/docker/api/types"
    30  	"github.com/google/go-containerregistry/internal/compare"
    31  	"github.com/google/go-containerregistry/pkg/name"
    32  	"github.com/google/go-containerregistry/pkg/v1/tarball"
    33  	"github.com/google/go-containerregistry/pkg/v1/validate"
    34  )
    35  
    36  var imagePath = "../tarball/testdata/test_image_1.tar"
    37  
    38  var inspectResp = types.ImageInspect{
    39  	ID: "sha256:6e0b05049ed9c17d02e1a55e80d6599dbfcce7f4f4b022e3c673e685789c470e",
    40  	RepoTags: []string{
    41  		"bazel/v1/tarball:test_image_1",
    42  		"test_image_2:latest",
    43  	},
    44  	Created:      "1970-01-01T00:00:00Z",
    45  	Author:       "Bazel",
    46  	Architecture: "amd64",
    47  	Os:           "linux",
    48  	Size:         8,
    49  	VirtualSize:  8,
    50  	Config:       &container.Config{},
    51  	GraphDriver: types.GraphDriverData{
    52  		Data: map[string]string{
    53  			"MergedDir": "/var/lib/docker/overlay2/988ecd005d048fd47b241dd57687231859563ba65a1dfd01ae1771ebfc4cb7c5/merged",
    54  			"UpperDir":  "/var/lib/docker/overlay2/988ecd005d048fd47b241dd57687231859563ba65a1dfd01ae1771ebfc4cb7c5/diff",
    55  			"WorkDir":   "/var/lib/docker/overlay2/988ecd005d048fd47b241dd57687231859563ba65a1dfd01ae1771ebfc4cb7c5/work",
    56  		},
    57  		Name: "overlay2",
    58  	},
    59  	RootFS: types.RootFS{
    60  		Type: "layers",
    61  		Layers: []string{
    62  			"sha256:8897395fd26dc44ad0e2a834335b33198cb41ac4d98dfddf58eced3853fa7b17",
    63  		},
    64  	},
    65  }
    66  
    67  type MockClient struct {
    68  	Client
    69  	path       string
    70  	negotiated bool
    71  
    72  	wantCtx context.Context
    73  
    74  	loadErr  error
    75  	loadBody io.ReadCloser
    76  
    77  	saveErr  error
    78  	saveBody io.ReadCloser
    79  
    80  	inspectErr  error
    81  	inspectResp types.ImageInspect
    82  	inspectBody []byte
    83  
    84  	tagErr error
    85  }
    86  
    87  func (m *MockClient) NegotiateAPIVersion(_ context.Context) {
    88  	m.negotiated = true
    89  }
    90  
    91  func (m *MockClient) ImageSave(_ context.Context, _ []string) (io.ReadCloser, error) {
    92  	if !m.negotiated {
    93  		return nil, errors.New("you forgot to call NegotiateAPIVersion before calling ImageSave")
    94  	}
    95  
    96  	if m.path != "" {
    97  		return os.Open(m.path)
    98  	}
    99  
   100  	return m.saveBody, m.saveErr
   101  }
   102  
   103  func (m *MockClient) ImageInspectWithRaw(_ context.Context, _ string) (types.ImageInspect, []byte, error) {
   104  	return m.inspectResp, m.inspectBody, m.inspectErr
   105  }
   106  
   107  func (m *MockClient) ImageHistory(_ context.Context, _ string) ([]api.HistoryResponseItem, error) {
   108  	return []api.HistoryResponseItem{
   109  		{
   110  			CreatedBy: "bazel build ...",
   111  			ID:        "sha256:6e0b05049ed9c17d02e1a55e80d6599dbfcce7f4f4b022e3c673e685789c470e",
   112  			Size:      8,
   113  			Tags: []string{
   114  				"bazel/v1/tarball:test_image_1",
   115  			},
   116  		},
   117  	}, nil
   118  }
   119  
   120  func TestImage(t *testing.T) {
   121  	for _, tc := range []struct {
   122  		name         string
   123  		buffered     bool
   124  		client       *MockClient
   125  		wantResponse string
   126  		wantErr      string
   127  	}{{
   128  		name: "success",
   129  		client: &MockClient{
   130  			path:        imagePath,
   131  			inspectResp: inspectResp,
   132  		},
   133  	}, {
   134  		name: "save err",
   135  		client: &MockClient{
   136  			saveBody:    io.NopCloser(strings.NewReader("Loaded")),
   137  			saveErr:     fmt.Errorf("locked and loaded"),
   138  			inspectResp: inspectResp,
   139  		},
   140  		wantErr: "locked and loaded",
   141  	}, {
   142  		name: "read err",
   143  		client: &MockClient{
   144  			inspectResp: inspectResp,
   145  			saveBody:    io.NopCloser(&errReader{fmt.Errorf("goodbye, world")}),
   146  		},
   147  		wantErr: "goodbye, world",
   148  	}} {
   149  		run := func(t *testing.T) {
   150  			opts := []Option{WithClient(tc.client)}
   151  			if tc.buffered {
   152  				opts = append(opts, WithBufferedOpener())
   153  			} else {
   154  				opts = append(opts, WithUnbufferedOpener())
   155  			}
   156  			img, err := tarball.ImageFromPath(imagePath, nil)
   157  			if err != nil {
   158  				t.Fatalf("error loading test image: %s", err)
   159  			}
   160  
   161  			tag, err := name.NewTag("unused", name.WeakValidation)
   162  			if err != nil {
   163  				t.Fatalf("error creating test name: %s", err)
   164  			}
   165  
   166  			dmn, err := Image(tag, opts...)
   167  			if err != nil {
   168  				if tc.wantErr == "" {
   169  					t.Errorf("Error loading daemon image: %s", err)
   170  				} else if !strings.Contains(err.Error(), tc.wantErr) {
   171  					t.Errorf("wanted %s to contain %s", err.Error(), tc.wantErr)
   172  				}
   173  				return
   174  			}
   175  
   176  			err = compare.Images(img, dmn)
   177  			if err != nil {
   178  				if tc.wantErr == "" {
   179  					t.Errorf("compare.Images: %v", err)
   180  				} else if !strings.Contains(err.Error(), tc.wantErr) {
   181  					t.Errorf("wanted %s to contain %s", err.Error(), tc.wantErr)
   182  				}
   183  			}
   184  
   185  			err = validate.Image(dmn)
   186  			if err != nil {
   187  				if tc.wantErr == "" {
   188  					t.Errorf("validate.Image: %v", err)
   189  				} else if !strings.Contains(err.Error(), tc.wantErr) {
   190  					t.Errorf("wanted %s to contain %s", err.Error(), tc.wantErr)
   191  				}
   192  			}
   193  		}
   194  
   195  		tc.buffered = true
   196  		t.Run(tc.name+" buffered", run)
   197  
   198  		tc.buffered = false
   199  		t.Run(tc.name+" unbuffered", run)
   200  	}
   201  }
   202  
   203  func TestImageDefaultClient(t *testing.T) {
   204  	wantErr := fmt.Errorf("bad client")
   205  	defaultClient = func() (Client, error) {
   206  		return nil, wantErr
   207  	}
   208  
   209  	if _, err := Image(name.MustParseReference("unused")); !errors.Is(err, wantErr) {
   210  		t.Errorf("Image(): want %v; got %v", wantErr, err)
   211  	}
   212  }
   213  

View as plain text