github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/builder_mux_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 build 18 19 import ( 20 "context" 21 "errors" 22 "io" 23 "testing" 24 25 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform" 26 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" 27 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" 28 "github.com/GoogleContainerTools/skaffold/testutil" 29 ) 30 31 func TestNewBuilderMux(t *testing.T) { 32 tests := []struct { 33 description string 34 pipelines []latest.Pipeline 35 pipeBuilder func(latest.Pipeline) (PipelineBuilder, error) 36 shouldErr bool 37 expectedBuilders []string 38 expectedConcurrency int 39 }{ 40 { 41 description: "only local builder", 42 pipelines: []latest.Pipeline{ 43 {Build: latest.BuildConfig{BuildType: latest.BuildType{LocalBuild: &latest.LocalBuild{Concurrency: util.IntPtr(1)}}}}, 44 }, 45 pipeBuilder: newMockPipelineBuilder, 46 expectedBuilders: []string{"local"}, 47 expectedConcurrency: 1, 48 }, 49 { 50 description: "only cluster builder", 51 pipelines: []latest.Pipeline{ 52 {Build: latest.BuildConfig{BuildType: latest.BuildType{Cluster: &latest.ClusterDetails{}}}}, 53 }, 54 pipeBuilder: newMockPipelineBuilder, 55 expectedBuilders: []string{"cluster"}, 56 }, 57 { 58 description: "only gcb builder", 59 pipelines: []latest.Pipeline{ 60 {Build: latest.BuildConfig{BuildType: latest.BuildType{GoogleCloudBuild: &latest.GoogleCloudBuild{}}}}, 61 }, 62 pipeBuilder: newMockPipelineBuilder, 63 expectedBuilders: []string{"gcb"}, 64 }, 65 { 66 description: "min non-zero concurrency", 67 pipelines: []latest.Pipeline{ 68 {Build: latest.BuildConfig{BuildType: latest.BuildType{LocalBuild: &latest.LocalBuild{Concurrency: util.IntPtr(0)}}}}, 69 {Build: latest.BuildConfig{BuildType: latest.BuildType{LocalBuild: &latest.LocalBuild{Concurrency: util.IntPtr(3)}}}}, 70 {Build: latest.BuildConfig{BuildType: latest.BuildType{Cluster: &latest.ClusterDetails{Concurrency: 2}}}}, 71 }, 72 pipeBuilder: newMockPipelineBuilder, 73 expectedBuilders: []string{"local", "local", "cluster"}, 74 expectedConcurrency: 2, 75 }, 76 } 77 for _, test := range tests { 78 testutil.Run(t, test.description, func(t *testutil.T) { 79 cfg := &mockConfig{pipelines: test.pipelines} 80 81 b, err := NewBuilderMux(cfg, nil, test.pipeBuilder) 82 t.CheckError(test.shouldErr, err) 83 if test.shouldErr { 84 return 85 } 86 t.CheckTrue(len(b.builders) == len(test.expectedBuilders)) 87 for i := range b.builders { 88 t.CheckDeepEqual(test.expectedBuilders[i], b.builders[i].(*mockPipelineBuilder).builderType) 89 } 90 t.CheckDeepEqual(test.expectedConcurrency, b.concurrency) 91 }) 92 } 93 } 94 95 func TestGetConcurrency(t *testing.T) { 96 tests := []struct { 97 description string 98 pbs []PipelineBuilder 99 cliConcurrency int 100 expectedConcurrency int 101 }{ 102 { 103 description: "default concurrency - builder and cli concurrency unset.", 104 pbs: []PipelineBuilder{ 105 &mockPipelineBuilder{concurrency: nil, builderType: "local"}, 106 &mockPipelineBuilder{concurrency: nil, builderType: "gcb"}, 107 }, 108 cliConcurrency: -1, 109 expectedConcurrency: 1, 110 }, 111 { 112 description: "builder concurrency set to less than cli concurrency", 113 pbs: []PipelineBuilder{ 114 &mockPipelineBuilder{concurrency: util.IntPtr(1), builderType: "local"}, 115 &mockPipelineBuilder{concurrency: util.IntPtr(1), builderType: "local"}, 116 &mockPipelineBuilder{concurrency: nil, builderType: "gcb"}, 117 }, 118 cliConcurrency: 2, 119 expectedConcurrency: 2, 120 }, 121 { 122 description: "builder concurrency set", 123 pbs: []PipelineBuilder{ 124 &mockPipelineBuilder{concurrency: util.IntPtr(2), builderType: "local"}, 125 &mockPipelineBuilder{concurrency: util.IntPtr(2), builderType: "local"}, 126 // As per docs https://github.com/GoogleContainerTools/skaffold/blob/dbd18994955f5805e80c6354ed0fd424ec4d987b/pkg/skaffold/schema/v2beta26/config.go#L287 127 // nil concurrency defaults to 1 128 &mockPipelineBuilder{concurrency: nil, builderType: "local"}, 129 }, 130 cliConcurrency: -1, 131 expectedConcurrency: 1, 132 }, 133 { 134 description: "builder concurrency set to 0 and cli concurrency set to 1", 135 pbs: []PipelineBuilder{ 136 // build all in parallel 137 &mockPipelineBuilder{concurrency: util.IntPtr(0), builderType: "local"}, 138 &mockPipelineBuilder{concurrency: util.IntPtr(0), builderType: "gcb"}, 139 }, 140 cliConcurrency: 1, 141 expectedConcurrency: 1, 142 }, 143 { 144 description: "builder concurrency set to 0 and cli concurrency unset", 145 pbs: []PipelineBuilder{ 146 // build all in parallel 147 &mockPipelineBuilder{concurrency: util.IntPtr(0), builderType: "local"}, 148 &mockPipelineBuilder{concurrency: util.IntPtr(0), builderType: "gcb"}, 149 }, 150 cliConcurrency: -1, 151 expectedConcurrency: 0, 152 }, 153 { 154 description: "builder concurrency set to default 0 for gcb", 155 pbs: []PipelineBuilder{ 156 // build all in parallel 157 &mockPipelineBuilder{concurrency: util.IntPtr(0), builderType: "gcb"}, 158 &mockPipelineBuilder{concurrency: util.IntPtr(0), builderType: "gcb"}, 159 }, 160 cliConcurrency: -1, 161 expectedConcurrency: 0, 162 }, 163 { 164 description: "min non-zero concurrency", 165 pbs: []PipelineBuilder{ 166 &mockPipelineBuilder{concurrency: util.IntPtr(0), builderType: "local"}, 167 &mockPipelineBuilder{concurrency: util.IntPtr(3), builderType: "gcb"}, 168 &mockPipelineBuilder{concurrency: util.IntPtr(2), builderType: "gcb"}, 169 }, 170 cliConcurrency: -1, 171 expectedConcurrency: 2, 172 }, 173 } 174 for _, test := range tests { 175 testutil.Run(t, test.description, func(t *testutil.T) { 176 actual := getConcurrency(test.pbs, test.cliConcurrency) 177 t.CheckDeepEqual(test.expectedConcurrency, actual) 178 }) 179 } 180 } 181 182 type mockConfig struct { 183 pipelines []latest.Pipeline 184 optRepo string 185 } 186 187 func (m *mockConfig) GetPipelines() []latest.Pipeline { return m.pipelines } 188 func (m *mockConfig) GlobalConfig() string { return "" } 189 func (m *mockConfig) DefaultRepo() *string { 190 if m.optRepo != "" { 191 return &m.optRepo 192 } 193 return nil 194 } 195 func (m *mockConfig) MultiLevelRepo() *bool { return nil } 196 func (m *mockConfig) BuildConcurrency() int { return -1 } 197 198 type mockPipelineBuilder struct { 199 concurrency *int 200 builderType string 201 } 202 203 func (m *mockPipelineBuilder) PreBuild(ctx context.Context, out io.Writer) error { return nil } 204 205 func (m *mockPipelineBuilder) Build(ctx context.Context, out io.Writer, artifact *latest.Artifact) ArtifactBuilder { 206 return nil 207 } 208 209 func (m *mockPipelineBuilder) PostBuild(ctx context.Context, out io.Writer) error { return nil } 210 211 func (m *mockPipelineBuilder) Concurrency() *int { return m.concurrency } 212 213 func (m *mockPipelineBuilder) Prune(context.Context, io.Writer) error { return nil } 214 215 func (m *mockPipelineBuilder) PushImages() bool { return false } 216 217 func (m *mockPipelineBuilder) SupportedPlatforms() platform.Matcher { return platform.All } 218 219 func newMockPipelineBuilder(p latest.Pipeline) (PipelineBuilder, error) { 220 switch { 221 case p.Build.BuildType.LocalBuild != nil: 222 return &mockPipelineBuilder{builderType: "local", concurrency: p.Build.LocalBuild.Concurrency}, nil 223 case p.Build.BuildType.Cluster != nil: 224 return &mockPipelineBuilder{builderType: "cluster", concurrency: util.IntPtr(p.Build.Cluster.Concurrency)}, nil 225 case p.Build.BuildType.GoogleCloudBuild != nil: 226 return &mockPipelineBuilder{builderType: "gcb", concurrency: util.IntPtr(p.Build.GoogleCloudBuild.Concurrency)}, nil 227 default: 228 return nil, errors.New("invalid config") 229 } 230 }