github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/cmd/horologium/main_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 main 18 19 import ( 20 "testing" 21 "time" 22 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 25 "k8s.io/test-infra/prow/config" 26 "k8s.io/test-infra/prow/kube" 27 ) 28 29 type fakeKube struct { 30 jobs []kube.ProwJob 31 created bool 32 } 33 34 func (fk *fakeKube) ListProwJobs(s string) ([]kube.ProwJob, error) { 35 return fk.jobs, nil 36 } 37 38 func (fk *fakeKube) CreateProwJob(j kube.ProwJob) (kube.ProwJob, error) { 39 fk.created = true 40 return j, nil 41 } 42 43 type fakeCron struct { 44 jobs []string 45 } 46 47 func (fc *fakeCron) SyncConfig(cfg *config.Config) error { 48 for _, p := range cfg.Periodics { 49 if p.Cron != "" { 50 fc.jobs = append(fc.jobs, p.Name) 51 } 52 } 53 54 return nil 55 } 56 57 func (fc *fakeCron) QueuedJobs() []string { 58 res := []string{} 59 for _, job := range fc.jobs { 60 res = append(res, job) 61 } 62 fc.jobs = []string{} 63 return res 64 } 65 66 // Assumes there is one periodic job called "p" with an interval of one minute. 67 func TestSync(t *testing.T) { 68 testcases := []struct { 69 testName string 70 71 jobName string 72 jobComplete bool 73 jobStartTimeAgo time.Duration 74 75 shouldStart bool 76 }{ 77 { 78 testName: "no job", 79 shouldStart: true, 80 }, 81 { 82 testName: "job with other name", 83 jobName: "not-j", 84 jobComplete: true, 85 jobStartTimeAgo: time.Hour, 86 shouldStart: true, 87 }, 88 { 89 testName: "old, complete job", 90 jobName: "j", 91 jobComplete: true, 92 jobStartTimeAgo: time.Hour, 93 shouldStart: true, 94 }, 95 { 96 testName: "old, incomplete job", 97 jobName: "j", 98 jobComplete: false, 99 jobStartTimeAgo: time.Hour, 100 shouldStart: false, 101 }, 102 { 103 testName: "new, complete job", 104 jobName: "j", 105 jobComplete: true, 106 jobStartTimeAgo: time.Second, 107 shouldStart: false, 108 }, 109 { 110 testName: "new, incomplete job", 111 jobName: "j", 112 jobComplete: false, 113 jobStartTimeAgo: time.Second, 114 shouldStart: false, 115 }, 116 } 117 for _, tc := range testcases { 118 cfg := config.Config{ 119 JobConfig: config.JobConfig{ 120 Periodics: []config.Periodic{{Name: "j"}}, 121 }, 122 } 123 cfg.Periodics[0].SetInterval(time.Minute) 124 125 var jobs []kube.ProwJob 126 now := time.Now() 127 if tc.jobName != "" { 128 jobs = []kube.ProwJob{{ 129 Spec: kube.ProwJobSpec{ 130 Type: kube.PeriodicJob, 131 Job: tc.jobName, 132 }, 133 Status: kube.ProwJobStatus{ 134 StartTime: metav1.NewTime(now.Add(-tc.jobStartTimeAgo)), 135 }, 136 }} 137 complete := metav1.NewTime(now.Add(-time.Millisecond)) 138 if tc.jobComplete { 139 jobs[0].Status.CompletionTime = &complete 140 } 141 } 142 kc := &fakeKube{jobs: jobs} 143 fc := &fakeCron{} 144 if err := sync(kc, &cfg, fc, now); err != nil { 145 t.Fatalf("For case %s, didn't expect error: %v", tc.testName, err) 146 } 147 if tc.shouldStart != kc.created { 148 t.Errorf("For case %s, did the wrong thing.", tc.testName) 149 } 150 } 151 } 152 153 // Test sync periodic job scheduled by cron. 154 func TestSyncCron(t *testing.T) { 155 testcases := []struct { 156 testName string 157 jobName string 158 jobComplete bool 159 shouldStart bool 160 }{ 161 { 162 testName: "no job", 163 shouldStart: true, 164 }, 165 { 166 testName: "job with other name", 167 jobName: "not-j", 168 jobComplete: true, 169 shouldStart: true, 170 }, 171 { 172 testName: "job still running", 173 jobName: "j", 174 jobComplete: false, 175 shouldStart: false, 176 }, 177 { 178 testName: "job finished", 179 jobName: "j", 180 jobComplete: true, 181 shouldStart: true, 182 }, 183 } 184 for _, tc := range testcases { 185 cfg := config.Config{ 186 JobConfig: config.JobConfig{ 187 Periodics: []config.Periodic{{Name: "j", Cron: "@every 1m"}}, 188 }, 189 } 190 191 var jobs []kube.ProwJob 192 now := time.Now() 193 if tc.jobName != "" { 194 jobs = []kube.ProwJob{{ 195 Spec: kube.ProwJobSpec{ 196 Type: kube.PeriodicJob, 197 Job: tc.jobName, 198 }, 199 Status: kube.ProwJobStatus{ 200 StartTime: metav1.NewTime(now.Add(-time.Hour)), 201 }, 202 }} 203 complete := metav1.NewTime(now.Add(-time.Millisecond)) 204 if tc.jobComplete { 205 jobs[0].Status.CompletionTime = &complete 206 } 207 } 208 kc := &fakeKube{jobs: jobs} 209 fc := &fakeCron{} 210 if err := sync(kc, &cfg, fc, now); err != nil { 211 t.Fatalf("For case %s, didn't expect error: %v", tc.testName, err) 212 } 213 if tc.shouldStart != kc.created { 214 t.Errorf("For case %s, did the wrong thing.", tc.testName) 215 } 216 } 217 }