...

Source file src/github.com/google/go-containerregistry/pkg/v1/mutate/rebase_test.go

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

     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 mutate_test
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	v1 "github.com/google/go-containerregistry/pkg/v1"
    22  	"github.com/google/go-containerregistry/pkg/v1/mutate"
    23  	"github.com/google/go-containerregistry/pkg/v1/random"
    24  )
    25  
    26  func layerDigests(t *testing.T, img v1.Image) []string {
    27  	layers, err := img.Layers()
    28  	if err != nil {
    29  		t.Fatalf("oldBase.Layers: %v", err)
    30  	}
    31  	layerDigests := make([]string, len(layers))
    32  	for i, l := range layers {
    33  		dig, err := l.Digest()
    34  		if err != nil {
    35  			t.Fatalf("layer.Digest %d: %v", i, err)
    36  		}
    37  		t.Log(dig)
    38  		layerDigests[i] = dig.String()
    39  	}
    40  	return layerDigests
    41  }
    42  
    43  // TestRebase tests that layer digests are expected when performing a rebase on
    44  // random.Image layers.
    45  func TestRebase(t *testing.T) {
    46  	// Create a random old base image of 5 layers and get those layers' digests.
    47  	const oldBaseLayerCount = 5
    48  	oldBase, err := random.Image(100, oldBaseLayerCount)
    49  	if err != nil {
    50  		t.Fatalf("random.Image (oldBase): %v", err)
    51  	}
    52  	t.Log("Old base:")
    53  	_ = layerDigests(t, oldBase)
    54  
    55  	// Construct an image with 2 layers on top of oldBase (an empty layer and a random layer).
    56  	top, err := random.Image(100, 1)
    57  	if err != nil {
    58  		t.Fatalf("random.Image (top): %v", err)
    59  	}
    60  	topLayers, err := top.Layers()
    61  	if err != nil {
    62  		t.Fatalf("top.Layers: %v", err)
    63  	}
    64  	orig, err := mutate.Append(oldBase,
    65  		mutate.Addendum{
    66  			Layer: nil,
    67  			History: v1.History{
    68  				Author:     "me",
    69  				Created:    v1.Time{Time: time.Now()},
    70  				CreatedBy:  "test-empty",
    71  				Comment:    "this is an empty test",
    72  				EmptyLayer: true,
    73  			},
    74  		},
    75  		mutate.Addendum{
    76  			Layer: topLayers[0],
    77  			History: v1.History{
    78  				Author:    "me",
    79  				Created:   v1.Time{Time: time.Now()},
    80  				CreatedBy: "test",
    81  				Comment:   "this is a test",
    82  			},
    83  		},
    84  	)
    85  	if err != nil {
    86  		t.Fatalf("Append: %v", err)
    87  	}
    88  
    89  	t.Log("Original:")
    90  	origLayerDigests := layerDigests(t, orig)
    91  
    92  	// Create a random new base image of 3 layers.
    93  	newBase, err := random.Image(100, 3)
    94  	if err != nil {
    95  		t.Fatalf("random.Image (newBase): %v", err)
    96  	}
    97  	t.Log("New base:")
    98  	newBaseLayerDigests := layerDigests(t, newBase)
    99  
   100  	// Add config file os/arch property fields
   101  	newBaseConfigFile, err := newBase.ConfigFile()
   102  	if err != nil {
   103  		t.Fatalf("newBase.ConfigFile: %v", err)
   104  	}
   105  	newBaseConfigFile.Architecture = "arm"
   106  	newBaseConfigFile.OS = "windows"
   107  	newBaseConfigFile.OSVersion = "10.0.17763.1339"
   108  
   109  	newBase, err = mutate.ConfigFile(newBase, newBaseConfigFile)
   110  	if err != nil {
   111  		t.Fatalf("ConfigFile (newBase): %v", err)
   112  	}
   113  
   114  	// Rebase original image onto new base.
   115  	rebased, err := mutate.Rebase(orig, oldBase, newBase)
   116  	if err != nil {
   117  		t.Fatalf("Rebase: %v", err)
   118  	}
   119  
   120  	rebasedBaseLayers, err := rebased.Layers()
   121  	if err != nil {
   122  		t.Fatalf("rebased.Layers: %v", err)
   123  	}
   124  	rebasedLayerDigests := make([]string, len(rebasedBaseLayers))
   125  	t.Log("Rebased image layer digests:")
   126  	for i, l := range rebasedBaseLayers {
   127  		dig, err := l.Digest()
   128  		if err != nil {
   129  			t.Fatalf("layer.Digest (rebased base layer %d): %v", i, err)
   130  		}
   131  		t.Log(dig)
   132  		rebasedLayerDigests[i] = dig.String()
   133  	}
   134  
   135  	// Compare rebased layers.
   136  	wantLayerDigests := append(newBaseLayerDigests, origLayerDigests[len(origLayerDigests)-1])
   137  	if len(rebasedLayerDigests) != len(wantLayerDigests) {
   138  		t.Fatalf("Rebased image contained %d layers, want %d", len(rebasedLayerDigests), len(wantLayerDigests))
   139  	}
   140  	for i, rl := range rebasedLayerDigests {
   141  		if got, want := rl, wantLayerDigests[i]; got != want {
   142  			t.Errorf("Layer %d mismatch, got %q, want %q", i, got, want)
   143  		}
   144  	}
   145  
   146  	// Compare rebased history.
   147  	origConfig, err := orig.ConfigFile()
   148  	if err != nil {
   149  		t.Fatalf("orig.ConfigFile: %v", err)
   150  	}
   151  	newBaseConfig, err := newBase.ConfigFile()
   152  	if err != nil {
   153  		t.Fatalf("newBase.ConfigFile: %v", err)
   154  	}
   155  	rebasedConfig, err := rebased.ConfigFile()
   156  	if err != nil {
   157  		t.Fatalf("rebased.ConfigFile: %v", err)
   158  	}
   159  	wantHistories := append(newBaseConfig.History, origConfig.History[oldBaseLayerCount:]...)
   160  	if len(wantHistories) != len(rebasedConfig.History) {
   161  		t.Fatalf("Rebased image contained %d history, want %d", len(rebasedConfig.History), len(wantHistories))
   162  	}
   163  	for i, rh := range rebasedConfig.History {
   164  		if got, want := rh.Comment, wantHistories[i].Comment; got != want {
   165  			t.Errorf("Layer %d mismatch, got %q, want %q", i, got, want)
   166  		}
   167  	}
   168  
   169  	// Compare ConfigFile property fields copied from new base.
   170  	if rebasedConfig.Architecture != newBaseConfig.Architecture {
   171  		t.Errorf("ConfigFile property Architecture mismatch, got %q, want %q", rebasedConfig.Architecture, newBaseConfig.Architecture)
   172  	}
   173  	if rebasedConfig.OS != newBaseConfig.OS {
   174  		t.Errorf("ConfigFile property OS mismatch, got %q, want %q", rebasedConfig.OS, newBaseConfig.OS)
   175  	}
   176  	if rebasedConfig.OSVersion != newBaseConfig.OSVersion {
   177  		t.Errorf("ConfigFile property OSVersion mismatch, got %q, want %q", rebasedConfig.OSVersion, newBaseConfig.OSVersion)
   178  	}
   179  }
   180  

View as plain text