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 }