github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/prow/pjutil/pjutil_test.go (about)

     1  /*
     2  Copyright 2017 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 pjutil
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"k8s.io/test-infra/prow/kube"
    24  )
    25  
    26  func TestEnvironmentForSpec(t *testing.T) {
    27  	var tests = []struct {
    28  		name     string
    29  		spec     kube.ProwJobSpec
    30  		expected map[string]string
    31  	}{
    32  		{
    33  			name: "periodic job",
    34  			spec: kube.ProwJobSpec{
    35  				Type: kube.PeriodicJob,
    36  				Job:  "job-name",
    37  			},
    38  			expected: map[string]string{
    39  				"JOB_NAME": "job-name",
    40  			},
    41  		},
    42  		{
    43  			name: "postsubmit job",
    44  			spec: kube.ProwJobSpec{
    45  				Type: kube.PostsubmitJob,
    46  				Job:  "job-name",
    47  				Refs: kube.Refs{
    48  					Org:     "org-name",
    49  					Repo:    "repo-name",
    50  					BaseRef: "base-ref",
    51  					BaseSHA: "base-sha",
    52  				},
    53  			},
    54  			expected: map[string]string{
    55  				"JOB_NAME":      "job-name",
    56  				"REPO_OWNER":    "org-name",
    57  				"REPO_NAME":     "repo-name",
    58  				"PULL_BASE_REF": "base-ref",
    59  				"PULL_BASE_SHA": "base-sha",
    60  				"PULL_REFS":     "base-ref:base-sha",
    61  			},
    62  		},
    63  		{
    64  			name: "batch job",
    65  			spec: kube.ProwJobSpec{
    66  				Type: kube.BatchJob,
    67  				Job:  "job-name",
    68  				Refs: kube.Refs{
    69  					Org:     "org-name",
    70  					Repo:    "repo-name",
    71  					BaseRef: "base-ref",
    72  					BaseSHA: "base-sha",
    73  					Pulls: []kube.Pull{{
    74  						Number: 1,
    75  						Author: "author-name",
    76  						SHA:    "pull-sha",
    77  					}, {
    78  						Number: 2,
    79  						Author: "other-author-name",
    80  						SHA:    "second-pull-sha",
    81  					}},
    82  				},
    83  			},
    84  			expected: map[string]string{
    85  				"JOB_NAME":      "job-name",
    86  				"REPO_OWNER":    "org-name",
    87  				"REPO_NAME":     "repo-name",
    88  				"PULL_BASE_REF": "base-ref",
    89  				"PULL_BASE_SHA": "base-sha",
    90  				"PULL_REFS":     "base-ref:base-sha,1:pull-sha,2:second-pull-sha",
    91  			},
    92  		},
    93  		{
    94  			name: "presubmit job",
    95  			spec: kube.ProwJobSpec{
    96  				Type: kube.PresubmitJob,
    97  				Job:  "job-name",
    98  				Refs: kube.Refs{
    99  					Org:     "org-name",
   100  					Repo:    "repo-name",
   101  					BaseRef: "base-ref",
   102  					BaseSHA: "base-sha",
   103  					Pulls: []kube.Pull{{
   104  						Number: 1,
   105  						Author: "author-name",
   106  						SHA:    "pull-sha",
   107  					}},
   108  				},
   109  			},
   110  			expected: map[string]string{
   111  				"JOB_NAME":      "job-name",
   112  				"REPO_OWNER":    "org-name",
   113  				"REPO_NAME":     "repo-name",
   114  				"PULL_BASE_REF": "base-ref",
   115  				"PULL_BASE_SHA": "base-sha",
   116  				"PULL_REFS":     "base-ref:base-sha,1:pull-sha",
   117  				"PULL_NUMBER":   "1",
   118  				"PULL_PULL_SHA": "pull-sha",
   119  			},
   120  		},
   121  	}
   122  
   123  	for _, test := range tests {
   124  		if actual, expected := EnvForSpec(test.spec), test.expected; !reflect.DeepEqual(actual, expected) {
   125  			t.Errorf("%s: got environment:\n\t%v\n\tbut expected:\n\t%v", test.name, actual, expected)
   126  		}
   127  	}
   128  }
   129  
   130  func TestProwJobToPod(t *testing.T) {
   131  	tests := []struct {
   132  		podName string
   133  		buildID string
   134  		pjSpec  kube.ProwJobSpec
   135  
   136  		expected *kube.Pod
   137  	}{
   138  		{
   139  			podName: "pod",
   140  			buildID: "blabla",
   141  			pjSpec: kube.ProwJobSpec{
   142  				Type: kube.PresubmitJob,
   143  				Job:  "job-name",
   144  				Refs: kube.Refs{
   145  					Org:     "org-name",
   146  					Repo:    "repo-name",
   147  					BaseRef: "base-ref",
   148  					BaseSHA: "base-sha",
   149  					Pulls: []kube.Pull{{
   150  						Number: 1,
   151  						Author: "author-name",
   152  						SHA:    "pull-sha",
   153  					}},
   154  				},
   155  				PodSpec: kube.PodSpec{
   156  					Containers: []kube.Container{
   157  						{
   158  							Image: "tester",
   159  							Env: []kube.EnvVar{
   160  								{Name: "MY_ENV", Value: "rocks"},
   161  							},
   162  						},
   163  					},
   164  				},
   165  			},
   166  
   167  			expected: &kube.Pod{
   168  				Metadata: kube.ObjectMeta{
   169  					Name: "pod",
   170  					Labels: map[string]string{
   171  						kube.CreatedByProw: "true",
   172  						"type":             "presubmit",
   173  					},
   174  					Annotations: map[string]string{
   175  						"job": "job-name",
   176  					},
   177  				},
   178  				Spec: kube.PodSpec{
   179  					RestartPolicy: "Never",
   180  					Containers: []kube.Container{
   181  						{
   182  							Name:  "pod-0",
   183  							Image: "tester",
   184  							Env: []kube.EnvVar{
   185  								{Name: "MY_ENV", Value: "rocks"},
   186  								{Name: "BUILD_NUMBER", Value: "blabla"},
   187  								{Name: "JOB_NAME", Value: "job-name"},
   188  								{Name: "PULL_BASE_REF", Value: "base-ref"},
   189  								{Name: "REPO_OWNER", Value: "org-name"},
   190  								{Name: "REPO_NAME", Value: "repo-name"},
   191  								{Name: "PULL_BASE_SHA", Value: "base-sha"},
   192  								{Name: "PULL_REFS", Value: "base-ref:base-sha,1:pull-sha"},
   193  								{Name: "PULL_NUMBER", Value: "1"},
   194  								{Name: "PULL_PULL_SHA", Value: "pull-sha"},
   195  							},
   196  						},
   197  					},
   198  				},
   199  			},
   200  		},
   201  	}
   202  
   203  	for i, test := range tests {
   204  		t.Logf("test run #%d", i)
   205  		pj := kube.ProwJob{Metadata: kube.ObjectMeta{Name: test.podName}, Spec: test.pjSpec}
   206  		got := ProwJobToPod(pj, test.buildID)
   207  		// TODO: For now I am just comparing fields manually, eventually we
   208  		// should port the semantic.DeepEqual helper from the api-machinery
   209  		// repo, which is basically a fork of the reflect package.
   210  		// if !semantic.DeepEqual(got, test.expected) {
   211  		//	 t.Errorf("got pod:\n%#v\n\nexpected pod:\n%#v\n", got, test.expected)
   212  		// }
   213  		var foundCreatedByLabel, foundTypeLabel, foundJobAnnotation bool
   214  		for key, value := range got.Metadata.Labels {
   215  			if key == kube.CreatedByProw && value == "true" {
   216  				foundCreatedByLabel = true
   217  			}
   218  			if key == "type" && value == string(pj.Spec.Type) {
   219  				foundTypeLabel = true
   220  			}
   221  		}
   222  		for key, value := range got.Metadata.Annotations {
   223  			if key == "job" && value == pj.Spec.Job {
   224  				foundJobAnnotation = true
   225  			}
   226  		}
   227  		if !foundCreatedByLabel {
   228  			t.Errorf("expected a created-by-prow=true label in %v", got.Metadata.Labels)
   229  		}
   230  		if !foundTypeLabel {
   231  			t.Errorf("expected a type=%s label in %v", pj.Spec.Type, got.Metadata.Labels)
   232  		}
   233  		if !foundJobAnnotation {
   234  			t.Errorf("expected a job=%s annotation in %v", pj.Spec.Job, got.Metadata.Annotations)
   235  		}
   236  
   237  		expectedContainer := test.expected.Spec.Containers[i]
   238  		gotContainer := got.Spec.Containers[i]
   239  
   240  		dumpGotEnv := false
   241  		for _, expectedEnv := range expectedContainer.Env {
   242  			found := false
   243  			for _, gotEnv := range gotContainer.Env {
   244  				if expectedEnv.Name == gotEnv.Name && expectedEnv.Value == gotEnv.Value {
   245  					found = true
   246  					break
   247  				}
   248  			}
   249  			if !found {
   250  				dumpGotEnv = true
   251  				t.Errorf("could not find expected env %s=%s", expectedEnv.Name, expectedEnv.Value)
   252  			}
   253  		}
   254  		if dumpGotEnv {
   255  			t.Errorf("expected env:\n%#v\ngot:\n%#v\n", expectedContainer.Env, gotContainer.Env)
   256  		}
   257  		if expectedContainer.Image != gotContainer.Image {
   258  			t.Errorf("expected image: %s, got: %s", expectedContainer.Image, gotContainer.Image)
   259  		}
   260  		if test.expected.Spec.RestartPolicy != got.Spec.RestartPolicy {
   261  			t.Errorf("expected restart policy: %s, got: %s", test.expected.Spec.RestartPolicy, got.Spec.RestartPolicy)
   262  		}
   263  	}
   264  }
   265  
   266  func TestPartitionPending(t *testing.T) {
   267  	tests := []struct {
   268  		pjs []kube.ProwJob
   269  
   270  		pending    map[string]struct{}
   271  		nonPending map[string]struct{}
   272  	}{
   273  		{
   274  			pjs: []kube.ProwJob{
   275  				{
   276  					Metadata: kube.ObjectMeta{
   277  						Name: "foo",
   278  					},
   279  					Status: kube.ProwJobStatus{
   280  						State: kube.TriggeredState,
   281  					},
   282  				},
   283  				{
   284  					Metadata: kube.ObjectMeta{
   285  						Name: "bar",
   286  					},
   287  					Status: kube.ProwJobStatus{
   288  						State: kube.PendingState,
   289  					},
   290  				},
   291  				{
   292  					Metadata: kube.ObjectMeta{
   293  						Name: "baz",
   294  					},
   295  					Status: kube.ProwJobStatus{
   296  						State: kube.SuccessState,
   297  					},
   298  				},
   299  				{
   300  					Metadata: kube.ObjectMeta{
   301  						Name: "error",
   302  					},
   303  					Status: kube.ProwJobStatus{
   304  						State: kube.ErrorState,
   305  					},
   306  				},
   307  				{
   308  					Metadata: kube.ObjectMeta{
   309  						Name: "bak",
   310  					},
   311  					Status: kube.ProwJobStatus{
   312  						State: kube.PendingState,
   313  					},
   314  				},
   315  			},
   316  			pending: map[string]struct{}{
   317  				"bar": {}, "bak": {},
   318  			},
   319  			nonPending: map[string]struct{}{
   320  				"foo": {}, "baz": {}, "error": {},
   321  			},
   322  		},
   323  	}
   324  
   325  	for i, test := range tests {
   326  		t.Logf("test run #%d", i)
   327  		pendingCh, nonPendingCh := PartitionPending(test.pjs)
   328  		for job := range pendingCh {
   329  			if _, ok := test.pending[job.Metadata.Name]; !ok {
   330  				t.Errorf("didn't find pending job %#v", job)
   331  			}
   332  		}
   333  		for job := range nonPendingCh {
   334  			if _, ok := test.nonPending[job.Metadata.Name]; !ok {
   335  				t.Errorf("didn't find non-pending job %#v", job)
   336  			}
   337  		}
   338  	}
   339  }