github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/build_problems_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  	"fmt"
    21  	"testing"
    22  
    23  	"google.golang.org/protobuf/testing/protocmp"
    24  
    25  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
    26  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
    27  	sErrors "github.com/GoogleContainerTools/skaffold/pkg/skaffold/errors"
    28  	"github.com/GoogleContainerTools/skaffold/proto/v1"
    29  	"github.com/GoogleContainerTools/skaffold/testutil"
    30  )
    31  
    32  func TestMakeAuthSuggestionsForRepo(t *testing.T) {
    33  	testutil.CheckDeepEqual(t, &proto.Suggestion{
    34  		SuggestionCode: proto.SuggestionCode_DOCKER_AUTH_CONFIGURE,
    35  		Action:         "try `docker login`",
    36  	}, makeAuthSuggestionsForRepo(""), protocmp.Transform())
    37  	testutil.CheckDeepEqual(t, &proto.Suggestion{
    38  		SuggestionCode: proto.SuggestionCode_GCLOUD_DOCKER_AUTH_CONFIGURE,
    39  		Action:         "try `gcloud auth configure-docker gcr.io`",
    40  	}, makeAuthSuggestionsForRepo("gcr.io/test"), protocmp.Transform())
    41  	testutil.CheckDeepEqual(t, &proto.Suggestion{
    42  		SuggestionCode: proto.SuggestionCode_GCLOUD_DOCKER_AUTH_CONFIGURE,
    43  		Action:         "try `gcloud auth configure-docker eu.gcr.io`",
    44  	}, makeAuthSuggestionsForRepo("eu.gcr.io/test"), protocmp.Transform())
    45  	testutil.CheckDeepEqual(t, &proto.Suggestion{
    46  		SuggestionCode: proto.SuggestionCode_GCLOUD_DOCKER_AUTH_CONFIGURE,
    47  		Action:         "try `gcloud auth configure-docker us-docker.pkg.dev`",
    48  	}, makeAuthSuggestionsForRepo("us-docker.pkg.dev/k8s-skaffold/skaffold"), protocmp.Transform())
    49  }
    50  
    51  func TestBuildProblems(t *testing.T) {
    52  	tests := []struct {
    53  		description string
    54  		context     config.ContextConfig
    55  		optRepo     string
    56  		err         error
    57  		expected    string
    58  		expectedAE  *proto.ActionableErr
    59  	}{
    60  		{
    61  			description: "Push access denied when neither default repo or global config is defined",
    62  			err:         fmt.Errorf("skaffold build failed: could not push image: denied: push access to resource"),
    63  			expected:    "Build Failed. No push access to specified image repository. Try running with `--default-repo` flag.",
    64  			expectedAE: &proto.ActionableErr{
    65  				ErrCode: proto.StatusCode_BUILD_PUSH_ACCESS_DENIED,
    66  				Message: "skaffold build failed: could not push image: denied: push access to resource",
    67  				Suggestions: []*proto.Suggestion{{
    68  					SuggestionCode: proto.SuggestionCode_ADD_DEFAULT_REPO,
    69  					Action:         "Try running with `--default-repo` flag",
    70  				},
    71  				}},
    72  		},
    73  		{
    74  			description: "Push access denied when default repo is defined",
    75  			optRepo:     "gcr.io/test",
    76  			err:         fmt.Errorf("skaffold build failed: could not push image image1 : denied: push access to resource"),
    77  			expected:    "Build Failed. No push access to specified image repository. Check your `--default-repo` value or try `gcloud auth configure-docker gcr.io`.",
    78  			expectedAE: &proto.ActionableErr{
    79  				ErrCode: proto.StatusCode_BUILD_PUSH_ACCESS_DENIED,
    80  				Message: "skaffold build failed: could not push image image1 : denied: push access to resource",
    81  				Suggestions: []*proto.Suggestion{{
    82  					SuggestionCode: proto.SuggestionCode_CHECK_DEFAULT_REPO,
    83  					Action:         "Check your `--default-repo` value",
    84  				}, {
    85  					SuggestionCode: proto.SuggestionCode_GCLOUD_DOCKER_AUTH_CONFIGURE,
    86  					Action:         "try `gcloud auth configure-docker gcr.io`",
    87  				},
    88  				},
    89  			},
    90  		},
    91  		{
    92  			description: "Push access denied when global repo is defined",
    93  			context:     config.ContextConfig{DefaultRepo: "docker.io/global"},
    94  			err:         fmt.Errorf("skaffold build failed: could not push image: denied: push access to resource"),
    95  			expected:    "Build Failed. No push access to specified image repository. Check your default-repo setting in skaffold config or try `docker login docker.io`.",
    96  			expectedAE: &proto.ActionableErr{
    97  				ErrCode: proto.StatusCode_BUILD_PUSH_ACCESS_DENIED,
    98  				Message: "skaffold build failed: could not push image: denied: push access to resource",
    99  				Suggestions: []*proto.Suggestion{{
   100  					SuggestionCode: proto.SuggestionCode_CHECK_DEFAULT_REPO_GLOBAL_CONFIG,
   101  					Action:         "Check your default-repo setting in skaffold config",
   102  				}, {
   103  					SuggestionCode: proto.SuggestionCode_DOCKER_AUTH_CONFIGURE,
   104  					Action:         "try `docker login docker.io`",
   105  				},
   106  				},
   107  			},
   108  		},
   109  		{
   110  			description: "unknown project error",
   111  			err:         fmt.Errorf("build failed: could not push image: unknown: Project test"),
   112  			expected:    "Build Failed. could not push image: unknown: Project test. Check your GCR project.",
   113  			expectedAE: &proto.ActionableErr{
   114  				ErrCode: proto.StatusCode_BUILD_PROJECT_NOT_FOUND,
   115  				Message: "build failed: could not push image: unknown: Project test",
   116  				Suggestions: []*proto.Suggestion{{
   117  					SuggestionCode: proto.SuggestionCode_CHECK_GCLOUD_PROJECT,
   118  					Action:         "Check your GCR project",
   119  				},
   120  				},
   121  			},
   122  		},
   123  		{
   124  			description: "build error when docker is not running with minikube local cluster",
   125  			err: fmt.Errorf(`creating runner: creating builder: getting docker client: getting minikube env: running [/Users/tejaldesai/Downloads/google-cloud-sdk2/bin/minikube docker-env --shell none -p minikube]
   126   - stdout: "\n\n"
   127   - stderr: "! Executing \"docker container inspect minikube --format={{.State.Status}}\" took an unusually long time: 7.36540945s\n* Restarting the docker service may improve performance.\nX Exiting due to GUEST_STATUS: state: unknown state \"minikube\": docker container inspect minikube --format=: exit status 1\nstdout:\n\n\nstderr:\nCannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\n\n* \n* If the above advice does not help, please let us know: \n  - https://github.com/kubernetes/minikube/issues/new/choose\n"
   128   - cause: exit status 80`),
   129  			expected: "Build Failed. Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Check if docker is running.",
   130  			expectedAE: &proto.ActionableErr{
   131  				ErrCode: proto.StatusCode_BUILD_DOCKER_DAEMON_NOT_RUNNING,
   132  				Message: "creating runner: creating builder: getting docker client: getting minikube env: running [/Users/tejaldesai/Downloads/google-cloud-sdk2/bin/minikube docker-env --shell none -p minikube]\n - stdout: \"\\n\\n\"\n - stderr: \"! Executing \\\"docker container inspect minikube --format={{.State.Status}}\\\" took an unusually long time: 7.36540945s\\n* Restarting the docker service may improve performance.\\nX Exiting due to GUEST_STATUS: state: unknown state \\\"minikube\\\": docker container inspect minikube --format=: exit status 1\\nstdout:\\n\\n\\nstderr:\\nCannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\\n\\n* \\n* If the above advice does not help, please let us know: \\n  - https://github.com/kubernetes/minikube/issues/new/choose\\n\"\n - cause: exit status 80",
   133  				Suggestions: []*proto.Suggestion{{
   134  					SuggestionCode: proto.SuggestionCode_CHECK_DOCKER_RUNNING,
   135  					Action:         "Check if docker is running",
   136  				},
   137  				},
   138  			},
   139  		},
   140  		{
   141  			description: "build error when docker is not running and deploying to GKE",
   142  			err:         fmt.Errorf(`exiting dev mode because first build failed: docker build: Cannot connect to the Docker daemon at tcp://127.0.0.1:32770. Is the docker daemon running?`),
   143  			expected:    "Build Failed. Cannot connect to the Docker daemon at tcp://127.0.0.1:32770. Check if docker is running.",
   144  			expectedAE: &proto.ActionableErr{
   145  				ErrCode: proto.StatusCode_BUILD_DOCKER_DAEMON_NOT_RUNNING,
   146  				Message: "exiting dev mode because first build failed: docker build: Cannot connect to the Docker daemon at tcp://127.0.0.1:32770. Is the docker daemon running?",
   147  				Suggestions: []*proto.Suggestion{{
   148  					SuggestionCode: proto.SuggestionCode_CHECK_DOCKER_RUNNING,
   149  					Action:         "Check if docker is running",
   150  				},
   151  				},
   152  			},
   153  		},
   154  
   155  		{
   156  			description: "build error when docker is not and no host information",
   157  			// See https://github.com/moby/moby/blob/master/client/errors.go#L20
   158  			err:      fmt.Errorf(`exiting dev mode because first build failed: docker build: Cannot connect to the Docker daemon. Is the docker daemon running on this host?`),
   159  			expected: "Build Failed. Cannot connect to the Docker daemon. Check if docker is running.",
   160  			expectedAE: &proto.ActionableErr{
   161  				ErrCode: proto.StatusCode_BUILD_DOCKER_DAEMON_NOT_RUNNING,
   162  				Message: "exiting dev mode because first build failed: docker build: Cannot connect to the Docker daemon. Is the docker daemon running on this host?",
   163  				Suggestions: []*proto.Suggestion{{
   164  					SuggestionCode: proto.SuggestionCode_CHECK_DOCKER_RUNNING,
   165  					Action:         "Check if docker is running",
   166  				},
   167  				},
   168  			},
   169  		},
   170  		{
   171  			description: "build cancelled",
   172  			// See https://github.com/moby/moby/blob/master/client/errors.go#L20
   173  			err:      fmt.Errorf(`docker build: error during connect: Post \"https://127.0.0.1:32770/v1.24/build?buildargs=:  context canceled`),
   174  			expected: "Build Cancelled",
   175  			expectedAE: &proto.ActionableErr{
   176  				ErrCode: proto.StatusCode_BUILD_CANCELLED,
   177  				Message: `docker build: error during connect: Post \"https://127.0.0.1:32770/v1.24/build?buildargs=:  context canceled`,
   178  			},
   179  		},
   180  	}
   181  	for _, test := range tests {
   182  		testutil.Run(t, test.description, func(t *testutil.T) {
   183  			t.Override(&getConfigForCurrentContext, func(string) (*config.ContextConfig, error) {
   184  				return &test.context, nil
   185  			})
   186  			t.Override(&sErrors.GetProblemCatalogCopy, func() sErrors.ProblemCatalog {
   187  				pc := sErrors.NewProblemCatalog()
   188  				pc.AddPhaseProblems(constants.Build, problems)
   189  				return pc
   190  			})
   191  			cfg := mockConfig{optRepo: test.optRepo}
   192  			actual := sErrors.ShowAIError(&cfg, test.err)
   193  			t.CheckDeepEqual(test.expected, actual.Error())
   194  			actualAE := sErrors.ActionableErr(&cfg, constants.Build, test.err)
   195  			t.CheckDeepEqual(test.expectedAE, actualAE, protocmp.Transform())
   196  		})
   197  	}
   198  }