github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/deploy/docker/deploy_test.go (about)

     1  /*
     2  Copyright 2021 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 docker
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/docker/docker/api/types/container"
    24  	"github.com/docker/go-connections/nat"
    25  
    26  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
    27  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/debug/types"
    28  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/label"
    29  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker/debugger"
    30  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
    31  	"github.com/GoogleContainerTools/skaffold/testutil"
    32  )
    33  
    34  type debugArtifact struct {
    35  	image            string
    36  	debug            bool
    37  	expectedBindings nat.PortMap
    38  }
    39  
    40  func TestDebugBindings(t *testing.T) {
    41  	// essentially, emulates pairing an image name with a detected runtime (and a default debugger port)
    42  	testDebugPorts := map[string]uint32{
    43  		"go":     uint32(56268),
    44  		"nodejs": uint32(9229),
    45  	}
    46  
    47  	tests := []struct {
    48  		name      string
    49  		artifacts []debugArtifact
    50  	}{
    51  		{
    52  			name: "one artifact one binding",
    53  			artifacts: []debugArtifact{
    54  				{
    55  					image: "go",
    56  					debug: true,
    57  					expectedBindings: nat.PortMap{
    58  						"56268/tcp": {{HostIP: "127.0.0.1", HostPort: "56268"}},
    59  					},
    60  				},
    61  			},
    62  		},
    63  		{
    64  			name: "two artifacts two bindings",
    65  			artifacts: []debugArtifact{
    66  				{
    67  					image: "go",
    68  					debug: true,
    69  					expectedBindings: nat.PortMap{
    70  						"56268/tcp": {{HostIP: "127.0.0.1", HostPort: "56268"}},
    71  					},
    72  				},
    73  				{
    74  					image: "nodejs",
    75  					debug: true,
    76  					expectedBindings: nat.PortMap{
    77  						"9229/tcp": {{HostIP: "127.0.0.1", HostPort: "9229"}},
    78  					},
    79  				},
    80  			},
    81  		},
    82  		{
    83  			name: "two artifacts but one not configured for debugging",
    84  			artifacts: []debugArtifact{
    85  				{
    86  					image: "go",
    87  					debug: true,
    88  					expectedBindings: nat.PortMap{
    89  						"56268/tcp": {{HostIP: "127.0.0.1", HostPort: "56268"}},
    90  					},
    91  				},
    92  				{
    93  					image: "nodejs",
    94  					debug: false,
    95  				},
    96  			},
    97  		},
    98  		{
    99  			name: "two artifacts with same runtime - port collision",
   100  			artifacts: []debugArtifact{
   101  				{
   102  					image: "go",
   103  					debug: true,
   104  					expectedBindings: nat.PortMap{
   105  						"56268/tcp": {{HostIP: "127.0.0.1", HostPort: "56268"}},
   106  					},
   107  				},
   108  				{
   109  					image: "go",
   110  					debug: true,
   111  					expectedBindings: nat.PortMap{
   112  						"56268/tcp": {{HostIP: "127.0.0.1", HostPort: "56269"}},
   113  					},
   114  				},
   115  			},
   116  		},
   117  	}
   118  
   119  	for _, test := range tests {
   120  		testutil.Run(t, test.name, func(tt *testutil.T) {
   121  			// this override ensures that the returned debug configurations are set on the DebugManager
   122  			tt.Override(&debugger.TransformImage, func(ctx context.Context, artifact graph.Artifact, cfg *container.Config, insecureRegistries map[string]bool, debugHelpersRegistry string) (map[string]types.ContainerDebugConfiguration, []*container.Config, error) {
   123  				configs := make(map[string]types.ContainerDebugConfiguration)
   124  				ports := make(map[string]uint32)
   125  				// tie the provided debug port to the artifact's image name to emulate this image being configured for debugging
   126  				// the debug runtime is not relevant for this test, and neither is the port key.
   127  				ports["ignored"] = testDebugPorts[artifact.ImageName]
   128  				configs[artifact.ImageName] = types.ContainerDebugConfiguration{
   129  					Ports: ports,
   130  				}
   131  				return configs, nil, nil
   132  			})
   133  			d, _ := NewDeployer(context.TODO(), mockConfig{}, &label.DefaultLabeller{}, nil, nil)
   134  
   135  			for _, a := range test.artifacts {
   136  				config := container.Config{
   137  					Image: a.image,
   138  				}
   139  				var (
   140  					debugBindings nat.PortMap
   141  					err           error
   142  				)
   143  
   144  				if a.debug {
   145  					debugBindings, err = d.setupDebugging(context.TODO(), nil, graph.Artifact{ImageName: a.image}, &config)
   146  				}
   147  				testutil.CheckErrorAndFailNow(t, false, err)
   148  
   149  				bindings, err := d.portManager.allocatePorts(a.image, d.resources, &config, debugBindings)
   150  				testutil.CheckErrorAndFailNow(t, false, err)
   151  
   152  				// CheckDeepEqual unfortunately doesn't work when the map elements are slices
   153  				for k, v := range a.expectedBindings {
   154  					testutil.CheckDeepEqual(t, v, bindings[k])
   155  				}
   156  			}
   157  		})
   158  	}
   159  }
   160  
   161  type mockConfig struct{}
   162  
   163  func (m mockConfig) ContainerDebugging() bool               { return true }
   164  func (m mockConfig) GetInsecureRegistries() map[string]bool { return nil }
   165  func (m mockConfig) GetKubeContext() string                 { return "" }
   166  func (m mockConfig) GlobalConfig() string                   { return "" }
   167  func (m mockConfig) MinikubeProfile() string                { return "" }
   168  func (m mockConfig) Mode() config.RunMode                   { return "" }
   169  func (m mockConfig) Prune() bool                            { return false }