summaryrefslogtreecommitdiffstats
path: root/pkg/v1/mutate/rebase_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/v1/mutate/rebase_test.go')
-rw-r--r--pkg/v1/mutate/rebase_test.go179
1 files changed, 179 insertions, 0 deletions
diff --git a/pkg/v1/mutate/rebase_test.go b/pkg/v1/mutate/rebase_test.go
new file mode 100644
index 0000000..250b6bf
--- /dev/null
+++ b/pkg/v1/mutate/rebase_test.go
@@ -0,0 +1,179 @@
+// Copyright 2018 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mutate_test
+
+import (
+ "testing"
+ "time"
+
+ v1 "github.com/google/go-containerregistry/pkg/v1"
+ "github.com/google/go-containerregistry/pkg/v1/mutate"
+ "github.com/google/go-containerregistry/pkg/v1/random"
+)
+
+func layerDigests(t *testing.T, img v1.Image) []string {
+ layers, err := img.Layers()
+ if err != nil {
+ t.Fatalf("oldBase.Layers: %v", err)
+ }
+ layerDigests := make([]string, len(layers))
+ for i, l := range layers {
+ dig, err := l.Digest()
+ if err != nil {
+ t.Fatalf("layer.Digest %d: %v", i, err)
+ }
+ t.Log(dig)
+ layerDigests[i] = dig.String()
+ }
+ return layerDigests
+}
+
+// TestRebase tests that layer digests are expected when performing a rebase on
+// random.Image layers.
+func TestRebase(t *testing.T) {
+ // Create a random old base image of 5 layers and get those layers' digests.
+ const oldBaseLayerCount = 5
+ oldBase, err := random.Image(100, oldBaseLayerCount)
+ if err != nil {
+ t.Fatalf("random.Image (oldBase): %v", err)
+ }
+ t.Log("Old base:")
+ _ = layerDigests(t, oldBase)
+
+ // Construct an image with 2 layers on top of oldBase (an empty layer and a random layer).
+ top, err := random.Image(100, 1)
+ if err != nil {
+ t.Fatalf("random.Image (top): %v", err)
+ }
+ topLayers, err := top.Layers()
+ if err != nil {
+ t.Fatalf("top.Layers: %v", err)
+ }
+ orig, err := mutate.Append(oldBase,
+ mutate.Addendum{
+ Layer: nil,
+ History: v1.History{
+ Author: "me",
+ Created: v1.Time{Time: time.Now()},
+ CreatedBy: "test-empty",
+ Comment: "this is an empty test",
+ EmptyLayer: true,
+ },
+ },
+ mutate.Addendum{
+ Layer: topLayers[0],
+ History: v1.History{
+ Author: "me",
+ Created: v1.Time{Time: time.Now()},
+ CreatedBy: "test",
+ Comment: "this is a test",
+ },
+ },
+ )
+ if err != nil {
+ t.Fatalf("Append: %v", err)
+ }
+
+ t.Log("Original:")
+ origLayerDigests := layerDigests(t, orig)
+
+ // Create a random new base image of 3 layers.
+ newBase, err := random.Image(100, 3)
+ if err != nil {
+ t.Fatalf("random.Image (newBase): %v", err)
+ }
+ t.Log("New base:")
+ newBaseLayerDigests := layerDigests(t, newBase)
+
+ // Add config file os/arch property fields
+ newBaseConfigFile, err := newBase.ConfigFile()
+ if err != nil {
+ t.Fatalf("newBase.ConfigFile: %v", err)
+ }
+ newBaseConfigFile.Architecture = "arm"
+ newBaseConfigFile.OS = "windows"
+ newBaseConfigFile.OSVersion = "10.0.17763.1339"
+
+ newBase, err = mutate.ConfigFile(newBase, newBaseConfigFile)
+ if err != nil {
+ t.Fatalf("ConfigFile (newBase): %v", err)
+ }
+
+ // Rebase original image onto new base.
+ rebased, err := mutate.Rebase(orig, oldBase, newBase)
+ if err != nil {
+ t.Fatalf("Rebase: %v", err)
+ }
+
+ rebasedBaseLayers, err := rebased.Layers()
+ if err != nil {
+ t.Fatalf("rebased.Layers: %v", err)
+ }
+ rebasedLayerDigests := make([]string, len(rebasedBaseLayers))
+ t.Log("Rebased image layer digests:")
+ for i, l := range rebasedBaseLayers {
+ dig, err := l.Digest()
+ if err != nil {
+ t.Fatalf("layer.Digest (rebased base layer %d): %v", i, err)
+ }
+ t.Log(dig)
+ rebasedLayerDigests[i] = dig.String()
+ }
+
+ // Compare rebased layers.
+ wantLayerDigests := append(newBaseLayerDigests, origLayerDigests[len(origLayerDigests)-1])
+ if len(rebasedLayerDigests) != len(wantLayerDigests) {
+ t.Fatalf("Rebased image contained %d layers, want %d", len(rebasedLayerDigests), len(wantLayerDigests))
+ }
+ for i, rl := range rebasedLayerDigests {
+ if got, want := rl, wantLayerDigests[i]; got != want {
+ t.Errorf("Layer %d mismatch, got %q, want %q", i, got, want)
+ }
+ }
+
+ // Compare rebased history.
+ origConfig, err := orig.ConfigFile()
+ if err != nil {
+ t.Fatalf("orig.ConfigFile: %v", err)
+ }
+ newBaseConfig, err := newBase.ConfigFile()
+ if err != nil {
+ t.Fatalf("newBase.ConfigFile: %v", err)
+ }
+ rebasedConfig, err := rebased.ConfigFile()
+ if err != nil {
+ t.Fatalf("rebased.ConfigFile: %v", err)
+ }
+ wantHistories := append(newBaseConfig.History, origConfig.History[oldBaseLayerCount:]...)
+ if len(wantHistories) != len(rebasedConfig.History) {
+ t.Fatalf("Rebased image contained %d history, want %d", len(rebasedConfig.History), len(wantHistories))
+ }
+ for i, rh := range rebasedConfig.History {
+ if got, want := rh.Comment, wantHistories[i].Comment; got != want {
+ t.Errorf("Layer %d mismatch, got %q, want %q", i, got, want)
+ }
+ }
+
+ // Compare ConfigFile property fields copied from new base.
+ if rebasedConfig.Architecture != newBaseConfig.Architecture {
+ t.Errorf("ConfigFile property Architecture mismatch, got %q, want %q", rebasedConfig.Architecture, newBaseConfig.Architecture)
+ }
+ if rebasedConfig.OS != newBaseConfig.OS {
+ t.Errorf("ConfigFile property OS mismatch, got %q, want %q", rebasedConfig.OS, newBaseConfig.OS)
+ }
+ if rebasedConfig.OSVersion != newBaseConfig.OSVersion {
+ t.Errorf("ConfigFile property OSVersion mismatch, got %q, want %q", rebasedConfig.OSVersion, newBaseConfig.OSVersion)
+ }
+}