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  }