github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/gcsupload/run_test.go (about) 1 /* 2 Copyright 2018 The Kubernetes 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 gcsupload 18 19 import ( 20 "io/ioutil" 21 "os" 22 "path" 23 "reflect" 24 "sort" 25 "strings" 26 "testing" 27 28 "k8s.io/apimachinery/pkg/util/diff" 29 30 "k8s.io/test-infra/prow/kube" 31 "k8s.io/test-infra/prow/pod-utils/downwardapi" 32 "k8s.io/test-infra/prow/pod-utils/gcs" 33 ) 34 35 func TestOptions_AssembleTargets(t *testing.T) { 36 var testCases = []struct { 37 name string 38 jobType kube.ProwJobType 39 options Options 40 paths []string 41 extra map[string]gcs.UploadFunc 42 expected []string 43 }{ 44 { 45 name: "no extra paths should upload infra files for presubmits", 46 jobType: kube.PresubmitJob, 47 options: Options{ 48 GCSConfiguration: &kube.GCSConfiguration{ 49 PathStrategy: kube.PathStrategyExplicit, 50 Bucket: "bucket", 51 }, 52 }, 53 expected: []string{ 54 "pr-logs/directory/job/build.txt", 55 "pr-logs/directory/job/latest-build.txt", 56 "pr-logs/pull/org_repo/1/job/latest-build.txt", 57 }, 58 }, 59 { 60 name: "no extra paths should upload infra files for postsubmits", 61 jobType: kube.PostsubmitJob, 62 options: Options{ 63 GCSConfiguration: &kube.GCSConfiguration{ 64 PathStrategy: kube.PathStrategyExplicit, 65 Bucket: "bucket", 66 }, 67 }, 68 expected: []string{ 69 "logs/job/latest-build.txt", 70 }, 71 }, 72 { 73 name: "no extra paths should upload infra files for periodics", 74 jobType: kube.PeriodicJob, 75 options: Options{ 76 GCSConfiguration: &kube.GCSConfiguration{ 77 PathStrategy: kube.PathStrategyExplicit, 78 Bucket: "bucket", 79 }, 80 }, 81 expected: []string{ 82 "logs/job/latest-build.txt", 83 }, 84 }, 85 { 86 name: "no extra paths should upload infra files for batches", 87 jobType: kube.BatchJob, 88 options: Options{ 89 GCSConfiguration: &kube.GCSConfiguration{ 90 PathStrategy: kube.PathStrategyExplicit, 91 Bucket: "bucket", 92 }, 93 }, 94 expected: []string{ 95 "pr-logs/directory/job/latest-build.txt", 96 }, 97 }, 98 { 99 name: "extra paths should be uploaded under job dir", 100 jobType: kube.PresubmitJob, 101 options: Options{ 102 GCSConfiguration: &kube.GCSConfiguration{ 103 PathStrategy: kube.PathStrategyExplicit, 104 Bucket: "bucket", 105 }, 106 }, 107 extra: map[string]gcs.UploadFunc{ 108 "something": gcs.DataUpload(strings.NewReader("data")), 109 "else": gcs.DataUpload(strings.NewReader("data")), 110 }, 111 expected: []string{ 112 "pr-logs/pull/org_repo/1/job/build/something", 113 "pr-logs/pull/org_repo/1/job/build/else", 114 "pr-logs/directory/job/build.txt", 115 "pr-logs/directory/job/latest-build.txt", 116 "pr-logs/pull/org_repo/1/job/latest-build.txt", 117 }, 118 }, 119 { 120 name: "literal files should be uploaded under job dir", 121 jobType: kube.PresubmitJob, 122 options: Options{ 123 Items: []string{"something", "else"}, 124 GCSConfiguration: &kube.GCSConfiguration{ 125 PathStrategy: kube.PathStrategyExplicit, 126 Bucket: "bucket", 127 }, 128 }, 129 paths: []string{"something", "else", "notforupload"}, 130 expected: []string{ 131 "pr-logs/pull/org_repo/1/job/build/something", 132 "pr-logs/pull/org_repo/1/job/build/else", 133 "pr-logs/directory/job/build.txt", 134 "pr-logs/directory/job/latest-build.txt", 135 "pr-logs/pull/org_repo/1/job/latest-build.txt", 136 }, 137 }, 138 { 139 name: "directories should be uploaded under job dir", 140 jobType: kube.PresubmitJob, 141 options: Options{ 142 Items: []string{"something"}, 143 GCSConfiguration: &kube.GCSConfiguration{ 144 PathStrategy: kube.PathStrategyExplicit, 145 Bucket: "bucket", 146 }, 147 }, 148 paths: []string{"something/", "something/else", "notforupload"}, 149 expected: []string{ 150 "pr-logs/pull/org_repo/1/job/build/something/else", 151 "pr-logs/directory/job/build.txt", 152 "pr-logs/directory/job/latest-build.txt", 153 "pr-logs/pull/org_repo/1/job/latest-build.txt", 154 }, 155 }, 156 } 157 158 for _, testCase := range testCases { 159 t.Run(testCase.name, func(t *testing.T) { 160 spec := &downwardapi.JobSpec{ 161 Job: "job", 162 Type: testCase.jobType, 163 Refs: kube.Refs{ 164 Org: "org", 165 Repo: "repo", 166 Pulls: []kube.Pull{ 167 { 168 Number: 1, 169 }, 170 }, 171 }, 172 BuildID: "build", 173 } 174 175 tmpDir, err := ioutil.TempDir("", testCase.name) 176 if err != nil { 177 t.Errorf("%s: error creating temp dir: %v", testCase.name, err) 178 } 179 defer func() { 180 if err := os.RemoveAll(tmpDir); err != nil { 181 t.Errorf("%s: error cleaning up temp dir: %v", testCase.name, err) 182 } 183 }() 184 185 for _, testPath := range testCase.paths { 186 if strings.HasSuffix(testPath, "/") { 187 if err := os.Mkdir(path.Join(tmpDir, testPath), 0755); err != nil { 188 t.Errorf("%s: could not create test directory: %v", testCase.name, err) 189 } 190 } else if _, err := os.Create(path.Join(tmpDir, testPath)); err != nil { 191 t.Errorf("%s: could not create test file: %v", testCase.name, err) 192 } 193 } 194 195 // no way to configure this at compile-time since tmpdir is dynamic 196 for i := range testCase.options.Items { 197 testCase.options.Items[i] = path.Join(tmpDir, testCase.options.Items[i]) 198 } 199 200 var uploadPaths []string 201 for uploadPath := range testCase.options.assembleTargets(spec, testCase.extra) { 202 uploadPaths = append(uploadPaths, uploadPath) 203 } 204 sort.Strings(uploadPaths) 205 sort.Strings(testCase.expected) 206 if actual, expected := uploadPaths, testCase.expected; !reflect.DeepEqual(actual, expected) { 207 t.Errorf("%s: did not assemble targets correctly:\n%s\n", testCase.name, diff.ObjectReflectDiff(expected, actual)) 208 } 209 210 }) 211 } 212 } 213 214 func TestBuilderForStrategy(t *testing.T) { 215 type info struct { 216 org, repo string 217 } 218 var testCases = []struct { 219 name string 220 strategy string 221 defaultOrg string 222 defaultRepo string 223 expectedPaths map[info]string 224 }{ 225 { 226 name: "explicit", 227 strategy: kube.PathStrategyExplicit, 228 expectedPaths: map[info]string{ 229 {org: "org", repo: "repo"}: "org_repo", 230 }, 231 }, 232 { 233 name: "single", 234 strategy: kube.PathStrategySingle, 235 defaultOrg: "org", 236 defaultRepo: "repo", 237 expectedPaths: map[info]string{ 238 {org: "org", repo: "repo"}: "", 239 {org: "org", repo: "repo2"}: "org_repo2", 240 {org: "org2", repo: "repo"}: "org2_repo", 241 }, 242 }, 243 { 244 name: "explicit", 245 strategy: kube.PathStrategyLegacy, 246 defaultOrg: "org", 247 defaultRepo: "repo", 248 expectedPaths: map[info]string{ 249 {org: "org", repo: "repo"}: "", 250 {org: "org", repo: "repo2"}: "repo2", 251 {org: "org2", repo: "repo"}: "org2_repo", 252 }, 253 }, 254 } 255 256 for _, testCase := range testCases { 257 builder := builderForStrategy(testCase.strategy, testCase.defaultOrg, testCase.defaultRepo) 258 for sampleInfo, expectedPath := range testCase.expectedPaths { 259 if actual, expected := builder(sampleInfo.org, sampleInfo.repo), expectedPath; actual != expected { 260 t.Errorf("%s: expected (%s,%s) -> %s, got %s", testCase.name, sampleInfo.org, sampleInfo.repo, expected, actual) 261 } 262 } 263 } 264 }