github.imxd.top/operator-framework/operator-sdk@v0.8.2/pkg/ansible/runner/runner_test.go (about) 1 // Copyright 2018 The Operator-SDK Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runner 16 17 import ( 18 "html/template" 19 "os" 20 "path/filepath" 21 "reflect" 22 "testing" 23 "time" 24 25 "k8s.io/apimachinery/pkg/runtime/schema" 26 ) 27 28 func TestNewFromWatches(t *testing.T) { 29 cwd, err := os.Getwd() 30 if err != nil { 31 t.Fatalf("Unable to get working director: %v", err) 32 } 33 34 validTemplate := struct { 35 ValidPlaybook string 36 ValidRole string 37 }{ 38 39 ValidPlaybook: filepath.Join(cwd, "testdata", "playbook.yml"), 40 ValidRole: filepath.Join(cwd, "testdata", "roles", "role"), 41 } 42 43 tmpl, err := template.ParseFiles("testdata/valid.yaml.tmpl") 44 if err != nil { 45 } 46 f, err := os.Create("testdata/valid.yaml") 47 if err != nil { 48 t.Fatalf("Unable to create valid.yaml: %v", err) 49 } 50 err = tmpl.Execute(f, validTemplate) 51 if err != nil { 52 t.Fatalf("Unable to create valid.yaml: %v", err) 53 return 54 } 55 56 zeroSeconds := time.Duration(0) 57 twoSeconds := time.Second * 2 58 testCases := []struct { 59 name string 60 path string 61 expectedMap map[schema.GroupVersionKind]runner 62 shouldError bool 63 }{ 64 { 65 name: "error duplicate GVK", 66 path: "testdata/duplicate_gvk.yaml", 67 shouldError: true, 68 }, 69 { 70 name: "error no file", 71 path: "testdata/please_don't_create_me_gvk.yaml", 72 shouldError: true, 73 }, 74 { 75 name: "error invalid yaml", 76 path: "testdata/invalid.yaml", 77 shouldError: true, 78 }, 79 { 80 name: "error invalid playbook path", 81 path: "testdata/invalid_playbook_path.yaml", 82 shouldError: true, 83 }, 84 { 85 name: "error invalid playbook finalizer path", 86 path: "testdata/invalid_finalizer_playbook_path.yaml", 87 shouldError: true, 88 }, 89 { 90 name: "error invalid role path", 91 path: "testdata/invalid_role_path.yaml", 92 shouldError: true, 93 }, 94 { 95 name: "error invalid role finalizer path", 96 path: "testdata/invalid_finalizer_role_path.yaml", 97 shouldError: true, 98 }, 99 { 100 name: "error invalid duration", 101 path: "testdata/invalid_duration.yaml", 102 shouldError: true, 103 }, 104 { 105 name: "error invalid status", 106 path: "testdata/invalid_status.yaml", 107 shouldError: true, 108 }, 109 { 110 name: "valid watches file", 111 path: "testdata/valid.yaml", 112 expectedMap: map[schema.GroupVersionKind]runner{ 113 schema.GroupVersionKind{ 114 Version: "v1alpha1", 115 Group: "app.example.com", 116 Kind: "NoFinalizer", 117 }: runner{ 118 GVK: schema.GroupVersionKind{ 119 Version: "v1alpha1", 120 Group: "app.example.com", 121 Kind: "NoFinalizer", 122 }, 123 Path: validTemplate.ValidPlaybook, 124 manageStatus: true, 125 reconcilePeriod: &twoSeconds, 126 watchDependentResources: true, 127 watchClusterScopedResources: false, 128 }, 129 schema.GroupVersionKind{ 130 Version: "v1alpha1", 131 Group: "app.example.com", 132 Kind: "Playbook", 133 }: runner{ 134 GVK: schema.GroupVersionKind{ 135 Version: "v1alpha1", 136 Group: "app.example.com", 137 Kind: "Playbook", 138 }, 139 Path: validTemplate.ValidPlaybook, 140 manageStatus: true, 141 watchDependentResources: true, 142 watchClusterScopedResources: false, 143 Finalizer: &Finalizer{ 144 Name: "finalizer.app.example.com", 145 Role: validTemplate.ValidRole, 146 Vars: map[string]interface{}{"sentinel": "finalizer_running"}, 147 }, 148 }, 149 schema.GroupVersionKind{ 150 Version: "v1alpha1", 151 Group: "app.example.com", 152 Kind: "WatchClusterScoped", 153 }: runner{ 154 GVK: schema.GroupVersionKind{ 155 Version: "v1alpha1", 156 Group: "app.example.com", 157 Kind: "WatchClusterScoped", 158 }, 159 Path: validTemplate.ValidPlaybook, 160 manageStatus: true, 161 watchDependentResources: true, 162 watchClusterScopedResources: true, 163 }, 164 schema.GroupVersionKind{ 165 Version: "v1alpha1", 166 Group: "app.example.com", 167 Kind: "NoReconcile", 168 }: runner{ 169 GVK: schema.GroupVersionKind{ 170 Version: "v1alpha1", 171 Group: "app.example.com", 172 Kind: "NoReconcile", 173 }, 174 Path: validTemplate.ValidPlaybook, 175 reconcilePeriod: &zeroSeconds, 176 manageStatus: true, 177 }, 178 schema.GroupVersionKind{ 179 Version: "v1alpha1", 180 Group: "app.example.com", 181 Kind: "DefaultStatus", 182 }: runner{ 183 GVK: schema.GroupVersionKind{ 184 Version: "v1alpha1", 185 Group: "app.example.com", 186 Kind: "DefaultStatus", 187 }, 188 Path: validTemplate.ValidPlaybook, 189 manageStatus: true, 190 }, 191 schema.GroupVersionKind{ 192 Version: "v1alpha1", 193 Group: "app.example.com", 194 Kind: "DisableStatus", 195 }: runner{ 196 GVK: schema.GroupVersionKind{ 197 Version: "v1alpha1", 198 Group: "app.example.com", 199 Kind: "DisableStatus", 200 }, 201 Path: validTemplate.ValidPlaybook, 202 manageStatus: false, 203 }, 204 schema.GroupVersionKind{ 205 Version: "v1alpha1", 206 Group: "app.example.com", 207 Kind: "EnableStatus", 208 }: runner{ 209 GVK: schema.GroupVersionKind{ 210 Version: "v1alpha1", 211 Group: "app.example.com", 212 Kind: "EnableStatus", 213 }, 214 Path: validTemplate.ValidPlaybook, 215 manageStatus: true, 216 }, 217 schema.GroupVersionKind{ 218 Version: "v1alpha1", 219 Group: "app.example.com", 220 Kind: "Role", 221 }: runner{ 222 GVK: schema.GroupVersionKind{ 223 Version: "v1alpha1", 224 Group: "app.example.com", 225 Kind: "Role", 226 }, 227 Path: validTemplate.ValidRole, 228 manageStatus: true, 229 Finalizer: &Finalizer{ 230 Name: "finalizer.app.example.com", 231 Playbook: validTemplate.ValidPlaybook, 232 Vars: map[string]interface{}{"sentinel": "finalizer_running"}, 233 }, 234 }, 235 }, 236 }, 237 } 238 239 for _, tc := range testCases { 240 t.Run(tc.name, func(t *testing.T) { 241 m, err := NewFromWatches(tc.path) 242 if err != nil && !tc.shouldError { 243 t.Fatalf("Error occurred unexpectedly: %v", err) 244 } 245 if err != nil && tc.shouldError { 246 return 247 } 248 for k, expectedR := range tc.expectedMap { 249 r, ok := m[k] 250 if !ok { 251 t.Fatalf("Did not find expected GVK: %v", k) 252 } 253 run, ok := r.(*runner) 254 if !ok { 255 t.Fatalf("Here: %#v", r) 256 } 257 if run.Path != expectedR.Path { 258 t.Fatalf("The GVK: %v unexpected path: %v expected path: %v", k, run.Path, expectedR.Path) 259 } 260 if run.GVK != expectedR.GVK { 261 t.Fatalf("The GVK: %v\nunexpected GVK: %#v\nexpected GVK: %#v", k, run.GVK, expectedR.GVK) 262 } 263 if run.manageStatus != expectedR.manageStatus { 264 t.Fatalf("The GVK: %v\nunexpected manageStatus:%#v\nexpected manageStatus: %#v", k, run.manageStatus, expectedR.manageStatus) 265 } 266 if run.Finalizer != expectedR.Finalizer { 267 if run.Finalizer.Name != expectedR.Finalizer.Name || run.Finalizer.Playbook != expectedR.Finalizer.Playbook || run.Finalizer.Role != expectedR.Finalizer.Role || reflect.DeepEqual(run.Finalizer.Vars["sentinel"], expectedR.Finalizer.Vars["sentininel"]) { 268 t.Fatalf("The GVK: %v\nunexpected finalizer: %#v\nexpected finalizer: %#v", k, run.Finalizer, expectedR.Finalizer) 269 } 270 } 271 if expectedR.reconcilePeriod != nil { 272 if *run.reconcilePeriod != *expectedR.reconcilePeriod { 273 t.Fatalf("The GVK: %v unexpected reconcile period: %v expected reconcile period: %v", k, run.reconcilePeriod, expectedR.reconcilePeriod) 274 } 275 } 276 } 277 }) 278 } 279 }