github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/local/prune_test.go (about) 1 /* 2 Copyright 2020 The Skaffold Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package local 18 19 import ( 20 "context" 21 "sort" 22 "testing" 23 24 "github.com/GoogleContainerTools/skaffold/testutil" 25 ) 26 27 func TestDiskUsage(t *testing.T) { 28 tests := []struct { 29 ctxFunc func() context.Context 30 description string 31 fails int 32 expectedUtilization uint64 33 shouldErr bool 34 }{ 35 { 36 description: "happy path", 37 fails: 0, 38 shouldErr: false, 39 expectedUtilization: testutil.TestUtilization, 40 }, 41 { 42 description: "first attempts failed", 43 fails: usageRetries - 1, 44 shouldErr: false, 45 expectedUtilization: testutil.TestUtilization, 46 }, 47 { 48 description: "all attempts failed", 49 fails: usageRetries, 50 shouldErr: true, 51 expectedUtilization: 0, 52 }, 53 { 54 description: "context cancelled", 55 fails: 1, 56 shouldErr: true, 57 expectedUtilization: 0, 58 ctxFunc: func() context.Context { 59 ctx, cancel := context.WithCancel(context.Background()) 60 cancel() 61 return ctx 62 }, 63 }, 64 } 65 66 for _, test := range tests { 67 testutil.Run(t, test.description, func(t *testutil.T) { 68 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{ 69 DUFails: test.fails, 70 }), true) 71 72 ctx := context.Background() 73 if test.ctxFunc != nil { 74 ctx = test.ctxFunc() 75 } 76 res, err := pruner.diskUsage(ctx) 77 78 t.CheckError(test.shouldErr, err) 79 if res != test.expectedUtilization { 80 t.Errorf("invalid disk usage. got %d expected %d", res, test.expectedUtilization) 81 } 82 }) 83 } 84 } 85 86 func TestRunPruneOk(t *testing.T) { 87 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{}), true) 88 err := pruner.runPrune(context.Background(), []string{"test"}) 89 if err != nil { 90 t.Fatalf("Got an error: %v", err) 91 } 92 } 93 94 func TestRunPruneDuFailed(t *testing.T) { 95 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{ 96 DUFails: -1, 97 }), true) 98 err := pruner.runPrune(context.Background(), []string{"test"}) 99 if err != nil { 100 t.Fatalf("Got an error: %v", err) 101 } 102 } 103 104 func TestRunPruneDuFailed2(t *testing.T) { 105 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{ 106 DUFails: 2, 107 }), true) 108 err := pruner.runPrune(context.Background(), []string{"test"}) 109 if err != nil { 110 t.Fatalf("Got an error: %v", err) 111 } 112 } 113 114 func TestRunPruneImageRemoveFailed(t *testing.T) { 115 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{ 116 ErrImageRemove: true, 117 }), true) 118 err := pruner.runPrune(context.Background(), []string{"test"}) 119 if err == nil { 120 t.Fatal("An error expected here") 121 } 122 } 123 124 func TestIsPruned(t *testing.T) { 125 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{}), true) 126 err := pruner.runPrune(context.Background(), 127 []string{"test1", "test2", "test1"}) 128 if err != nil { 129 t.Fatalf("Got an error: %v", err) 130 } 131 if !pruner.isPruned("test1") { 132 t.Error("Image test1 is expected to be pruned") 133 } 134 if pruner.isPruned("test3") { 135 t.Error("Image test3 is not expected to be pruned") 136 } 137 } 138 139 func TestIsPrunedFail(t *testing.T) { 140 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{ 141 ErrImageRemove: true, 142 }), true) 143 144 err := pruner.runPrune(context.Background(), []string{"test1"}) 145 if err == nil { 146 t.Fatal("An error expected here") 147 } 148 if pruner.isPruned("test1") { 149 t.Error("Image test1 is not expected to be pruned") 150 } 151 } 152 153 func TestCollectPruneImages(t *testing.T) { 154 tests := []struct { 155 description string 156 localImages map[string][]string 157 imagesToBuild []string 158 expectedToPrune []string 159 }{ 160 { 161 description: "test images to prune", 162 localImages: map[string][]string{ 163 "foo": {"111", "222", "333", "444"}, 164 "bar": {"555", "666", "777"}, 165 }, 166 imagesToBuild: []string{"foo", "bar"}, 167 expectedToPrune: []string{"111", "222", "333", "555", "666"}, 168 }, 169 { 170 description: "dup image ref", 171 localImages: map[string][]string{ 172 "foo": {"111", "222", "333", "444"}, 173 }, 174 imagesToBuild: []string{"foo", "foo"}, 175 expectedToPrune: []string{"111", "222"}, 176 }, 177 } 178 for _, test := range tests { 179 testutil.Run(t, test.description, func(t *testutil.T) { 180 pruner := newPruner(fakeLocalDaemon(&testutil.FakeAPIClient{ 181 LocalImages: test.localImages, 182 }), true) 183 184 res := pruner.collectImagesToPrune( 185 context.Background(), test.imagesToBuild) 186 sort.Strings(test.expectedToPrune) 187 sort.Strings(res) 188 t.CheckDeepEqual(res, test.expectedToPrune) 189 }) 190 } 191 }