github.com/kubeshop/testkube@v1.17.23/pkg/mapper/testsuites/openapi_kube.go (about) 1 package testsuites 2 3 import ( 4 "time" 5 6 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 7 8 v1 "github.com/kubeshop/testkube-operator/api/common/v1" 9 testsuitesv3 "github.com/kubeshop/testkube-operator/api/testsuite/v3" 10 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 11 "github.com/kubeshop/testkube/pkg/types" 12 ) 13 14 // TODO move to testuites mapper 15 func MapToTestExecutionSummary(executions []testkube.TestSuiteExecution) []testkube.TestSuiteExecutionSummary { 16 result := make([]testkube.TestSuiteExecutionSummary, len(executions)) 17 18 for i, execution := range executions { 19 var executionsSummary []testkube.TestSuiteBatchStepExecutionSummary 20 21 if len(execution.StepResults) != 0 { 22 executionsSummary = make([]testkube.TestSuiteBatchStepExecutionSummary, len(execution.StepResults)) 23 for j, stepResult := range execution.StepResults { 24 executionsSummary[j] = testkube.TestSuiteBatchStepExecutionSummary{ 25 Execute: []testkube.TestSuiteStepExecutionSummary{mapStepResultV2ToStepExecutionSummary(stepResult)}, 26 } 27 } 28 } 29 30 if len(execution.ExecuteStepResults) != 0 { 31 executionsSummary = make([]testkube.TestSuiteBatchStepExecutionSummary, len(execution.ExecuteStepResults)) 32 for j, stepResult := range execution.ExecuteStepResults { 33 executionsSummary[j] = mapBatchStepResultToExecutionSummary(stepResult) 34 } 35 } 36 37 result[i] = testkube.TestSuiteExecutionSummary{ 38 Id: execution.Id, 39 Name: execution.Name, 40 TestSuiteName: execution.TestSuite.Name, 41 Status: execution.Status, 42 StartTime: execution.StartTime, 43 EndTime: execution.EndTime, 44 Duration: types.FormatDuration(execution.Duration), 45 DurationMs: types.FormatDurationMs(execution.Duration), 46 Execution: executionsSummary, 47 Labels: execution.Labels, 48 } 49 } 50 51 return result 52 } 53 54 func mapStepResultV2ToStepExecutionSummary(r testkube.TestSuiteStepExecutionResultV2) testkube.TestSuiteStepExecutionSummary { 55 var id, testName, name string 56 var status *testkube.ExecutionStatus = testkube.ExecutionStatusPassed 57 var stepType *testkube.TestSuiteStepType 58 59 if r.Test != nil { 60 testName = r.Test.Name 61 } 62 63 if r.Execution != nil { 64 id = r.Execution.Id 65 if r.Execution.ExecutionResult != nil { 66 status = r.Execution.ExecutionResult.Status 67 } 68 } 69 70 if r.Step != nil { 71 stepType = r.Step.Type() 72 name = r.Step.FullName() 73 } 74 75 return testkube.TestSuiteStepExecutionSummary{ 76 Id: id, 77 Name: name, 78 TestName: testName, 79 Status: status, 80 Type_: stepType, 81 } 82 } 83 84 func mapBatchStepResultToExecutionSummary(r testkube.TestSuiteBatchStepExecutionResult) testkube.TestSuiteBatchStepExecutionSummary { 85 batch := make([]testkube.TestSuiteStepExecutionSummary, len(r.Execute)) 86 for i := range r.Execute { 87 batch[i] = mapStepResultToStepExecutionSummary(r.Execute[i]) 88 } 89 90 return testkube.TestSuiteBatchStepExecutionSummary{ 91 Execute: batch, 92 } 93 } 94 95 func mapStepResultToStepExecutionSummary(r testkube.TestSuiteStepExecutionResult) testkube.TestSuiteStepExecutionSummary { 96 var id, testName, name string 97 var status *testkube.ExecutionStatus = testkube.ExecutionStatusPassed 98 var stepType *testkube.TestSuiteStepType 99 100 if r.Test != nil { 101 testName = r.Test.Name 102 } 103 104 if r.Execution != nil { 105 id = r.Execution.Id 106 if r.Execution.ExecutionResult != nil { 107 status = r.Execution.ExecutionResult.Status 108 } 109 } 110 111 if r.Step != nil { 112 stepType = r.Step.Type() 113 name = r.Step.FullName() 114 } 115 116 return testkube.TestSuiteStepExecutionSummary{ 117 Id: id, 118 Name: name, 119 TestName: testName, 120 Status: status, 121 Type_: stepType, 122 } 123 } 124 125 func MapTestSuiteUpsertRequestToTestCRD(request testkube.TestSuiteUpsertRequest) (testsuite testsuitesv3.TestSuite, err error) { 126 before, err := mapTestBatchStepsToCRD(request.Before) 127 if err != nil { 128 return testsuite, err 129 } 130 131 steps, err := mapTestBatchStepsToCRD(request.Steps) 132 if err != nil { 133 return testsuite, err 134 } 135 136 after, err := mapTestBatchStepsToCRD(request.After) 137 if err != nil { 138 return testsuite, err 139 } 140 141 return testsuitesv3.TestSuite{ 142 ObjectMeta: metav1.ObjectMeta{ 143 Name: request.Name, 144 Namespace: request.Namespace, 145 Labels: request.Labels, 146 }, 147 Spec: testsuitesv3.TestSuiteSpec{ 148 Repeats: int(request.Repeats), 149 Description: request.Description, 150 Before: before, 151 Steps: steps, 152 After: after, 153 Schedule: request.Schedule, 154 ExecutionRequest: MapExecutionRequestToSpecExecutionRequest(request.ExecutionRequest), 155 }, 156 }, nil 157 } 158 159 func mapTestBatchStepsToCRD(batches []testkube.TestSuiteBatchStep) (out []testsuitesv3.TestSuiteBatchStep, err error) { 160 for _, batch := range batches { 161 steps := make([]testsuitesv3.TestSuiteStepSpec, len(batch.Execute)) 162 for i := range batch.Execute { 163 steps[i], err = mapTestStepToCRD(batch.Execute[i]) 164 if err != nil { 165 return nil, err 166 } 167 } 168 169 var downloadArtifacts *testsuitesv3.DownloadArtifactOptions 170 if batch.DownloadArtifacts != nil { 171 downloadArtifacts = &testsuitesv3.DownloadArtifactOptions{ 172 AllPreviousSteps: batch.DownloadArtifacts.AllPreviousSteps, 173 PreviousStepNumbers: batch.DownloadArtifacts.PreviousStepNumbers, 174 PreviousTestNames: batch.DownloadArtifacts.PreviousTestNames, 175 } 176 } 177 178 out = append(out, testsuitesv3.TestSuiteBatchStep{ 179 StopOnFailure: batch.StopOnFailure, 180 DownloadArtifacts: downloadArtifacts, 181 Execute: steps, 182 }) 183 } 184 185 return out, nil 186 } 187 188 func mapTestStepToCRD(step testkube.TestSuiteStep) (stepSpec testsuitesv3.TestSuiteStepSpec, err error) { 189 switch step.Type() { 190 191 case testkube.TestSuiteStepTypeDelay: 192 if step.Delay != "" { 193 duration, err := time.ParseDuration(step.Delay) 194 if err != nil { 195 return stepSpec, err 196 } 197 198 stepSpec.Delay = metav1.Duration{Duration: duration} 199 } 200 case testkube.TestSuiteStepTypeExecuteTest: 201 stepSpec.Test = step.Test 202 stepSpec.ExecutionRequest = MapTestStepExecutionRequestCRD(step.ExecutionRequest) 203 } 204 205 return stepSpec, nil 206 } 207 208 // MapExecutionRequestToSpecExecutionRequest maps ExecutionRequest OpenAPI spec to ExecutionRequest CRD spec 209 func MapExecutionRequestToSpecExecutionRequest(executionRequest *testkube.TestSuiteExecutionRequest) *testsuitesv3.TestSuiteExecutionRequest { 210 if executionRequest == nil { 211 return nil 212 } 213 214 return &testsuitesv3.TestSuiteExecutionRequest{ 215 Name: executionRequest.Name, 216 Labels: executionRequest.Labels, 217 ExecutionLabels: executionRequest.ExecutionLabels, 218 Namespace: executionRequest.Namespace, 219 Variables: MapCRDVariables(executionRequest.Variables), 220 SecretUUID: executionRequest.SecretUUID, 221 Sync: executionRequest.Sync, 222 HttpProxy: executionRequest.HttpProxy, 223 HttpsProxy: executionRequest.HttpsProxy, 224 Timeout: executionRequest.Timeout, 225 JobTemplate: executionRequest.JobTemplate, 226 JobTemplateReference: executionRequest.JobTemplateReference, 227 CronJobTemplate: executionRequest.CronJobTemplate, 228 CronJobTemplateReference: executionRequest.CronJobTemplateReference, 229 ScraperTemplate: executionRequest.ScraperTemplate, 230 ScraperTemplateReference: executionRequest.ScraperTemplateReference, 231 PvcTemplate: executionRequest.PvcTemplate, 232 PvcTemplateReference: executionRequest.PvcTemplateReference, 233 } 234 } 235 236 // MapTestSuiteUpsertRequestToTestCRD maps TestSuiteUpdateRequest OpenAPI spec to TestSuite CRD spec 237 func MapTestSuiteUpdateRequestToTestCRD(request testkube.TestSuiteUpdateRequest, 238 testSuite *testsuitesv3.TestSuite) (*testsuitesv3.TestSuite, error) { 239 var fields = []struct { 240 source *string 241 destination *string 242 }{ 243 { 244 request.Name, 245 &testSuite.Name, 246 }, 247 { 248 request.Namespace, 249 &testSuite.Namespace, 250 }, 251 { 252 request.Description, 253 &testSuite.Spec.Description, 254 }, 255 { 256 request.Schedule, 257 &testSuite.Spec.Schedule, 258 }, 259 } 260 261 for _, field := range fields { 262 if field.source != nil { 263 *field.destination = *field.source 264 } 265 } 266 267 var err error 268 if request.Before != nil { 269 testSuite.Spec.Before, err = mapTestBatchStepsToCRD(*request.Before) 270 if err != nil { 271 return nil, err 272 } 273 } 274 275 if request.Steps != nil { 276 testSuite.Spec.Steps, err = mapTestBatchStepsToCRD(*request.Steps) 277 if err != nil { 278 return nil, err 279 } 280 } 281 282 if request.After != nil { 283 testSuite.Spec.After, err = mapTestBatchStepsToCRD(*request.After) 284 if err != nil { 285 return nil, err 286 } 287 } 288 289 if request.Labels != nil { 290 testSuite.Labels = *request.Labels 291 } 292 293 if request.Repeats != nil { 294 testSuite.Spec.Repeats = int(*request.Repeats) 295 } 296 297 if request.ExecutionRequest != nil { 298 testSuite.Spec.ExecutionRequest = MapExecutionUpdateRequestToSpecExecutionRequest(*request.ExecutionRequest, testSuite.Spec.ExecutionRequest) 299 } 300 301 return testSuite, nil 302 } 303 304 // MapExecutionUpdateRequestToSpecExecutionRequest maps ExecutionUpdateRequest OpenAPI spec to ExecutionRequest CRD spec 305 func MapExecutionUpdateRequestToSpecExecutionRequest(executionRequest *testkube.TestSuiteExecutionUpdateRequest, 306 request *testsuitesv3.TestSuiteExecutionRequest) *testsuitesv3.TestSuiteExecutionRequest { 307 if executionRequest == nil { 308 return nil 309 } 310 311 if request == nil { 312 request = &testsuitesv3.TestSuiteExecutionRequest{} 313 } 314 315 empty := true 316 var fields = []struct { 317 source *string 318 destination *string 319 }{ 320 { 321 executionRequest.Name, 322 &request.Name, 323 }, 324 { 325 executionRequest.Namespace, 326 &request.Namespace, 327 }, 328 { 329 executionRequest.SecretUUID, 330 &request.SecretUUID, 331 }, 332 { 333 executionRequest.HttpProxy, 334 &request.HttpProxy, 335 }, 336 { 337 executionRequest.HttpsProxy, 338 &request.HttpsProxy, 339 }, 340 { 341 executionRequest.JobTemplate, 342 &request.JobTemplate, 343 }, 344 { 345 executionRequest.JobTemplateReference, 346 &request.JobTemplateReference, 347 }, 348 { 349 executionRequest.CronJobTemplate, 350 &request.CronJobTemplate, 351 }, 352 { 353 executionRequest.CronJobTemplateReference, 354 &request.CronJobTemplateReference, 355 }, 356 { 357 executionRequest.ScraperTemplate, 358 &request.ScraperTemplate, 359 }, 360 { 361 executionRequest.ScraperTemplateReference, 362 &request.ScraperTemplateReference, 363 }, 364 { 365 executionRequest.PvcTemplate, 366 &request.PvcTemplate, 367 }, 368 { 369 executionRequest.PvcTemplateReference, 370 &request.PvcTemplateReference, 371 }, 372 } 373 374 for _, field := range fields { 375 if field.source != nil { 376 *field.destination = *field.source 377 empty = false 378 } 379 } 380 381 if executionRequest.Labels != nil { 382 request.Labels = *executionRequest.Labels 383 empty = false 384 } 385 386 if executionRequest.ExecutionLabels != nil { 387 request.ExecutionLabels = *executionRequest.ExecutionLabels 388 empty = false 389 } 390 391 if executionRequest.Sync != nil { 392 request.Sync = *executionRequest.Sync 393 empty = false 394 } 395 396 if executionRequest.Timeout != nil { 397 request.Timeout = *executionRequest.Timeout 398 empty = false 399 } 400 401 if executionRequest.Variables != nil { 402 request.Variables = MapCRDVariables(*executionRequest.Variables) 403 empty = false 404 } 405 406 if empty { 407 return nil 408 } 409 410 return request 411 } 412 413 // MapStatusToSpec maps OpenAPI spec TestSuiteStatus to CRD 414 func MapStatusToSpec(testSuiteStatus *testkube.TestSuiteStatus) (specStatus testsuitesv3.TestSuiteStatus) { 415 if testSuiteStatus == nil || testSuiteStatus.LatestExecution == nil { 416 return specStatus 417 } 418 419 specStatus.LatestExecution = &testsuitesv3.TestSuiteExecutionCore{ 420 Id: testSuiteStatus.LatestExecution.Id, 421 Status: (*testsuitesv3.TestSuiteExecutionStatus)(testSuiteStatus.LatestExecution.Status), 422 } 423 424 specStatus.LatestExecution.StartTime.Time = testSuiteStatus.LatestExecution.StartTime 425 specStatus.LatestExecution.EndTime.Time = testSuiteStatus.LatestExecution.EndTime 426 427 return specStatus 428 } 429 430 // MapExecutionToTestSuiteStatus maps OpenAPI Execution to TestSuiteStatus CRD 431 func MapExecutionToTestSuiteStatus(execution *testkube.TestSuiteExecution) (specStatus testsuitesv3.TestSuiteStatus) { 432 specStatus.LatestExecution = &testsuitesv3.TestSuiteExecutionCore{ 433 Id: execution.Id, 434 Status: (*testsuitesv3.TestSuiteExecutionStatus)(execution.Status), 435 } 436 437 specStatus.LatestExecution.StartTime.Time = execution.StartTime 438 specStatus.LatestExecution.EndTime.Time = execution.EndTime 439 440 return specStatus 441 } 442 443 func MapTestStepExecutionRequestCRD(request *testkube.TestSuiteStepExecutionRequest) *testsuitesv3.TestSuiteStepExecutionRequest { 444 if request == nil { 445 return nil 446 } 447 448 variables := map[string]testsuitesv3.Variable{} 449 for k, v := range request.Variables { 450 variables[k] = testsuitesv3.Variable{ 451 Name: v.Name, 452 Value: v.Value, 453 Type_: string(*v.Type_), 454 } 455 } 456 457 var runningContext *v1.RunningContext 458 if request.RunningContext != nil { 459 runningContext = &v1.RunningContext{ 460 Type_: v1.RunningContextType(request.RunningContext.Type_), 461 Context: request.RunningContext.Context, 462 } 463 } 464 465 return &testsuitesv3.TestSuiteStepExecutionRequest{ 466 ExecutionLabels: request.ExecutionLabels, 467 Variables: variables, 468 Args: request.Args, 469 ArgsMode: testsuitesv3.ArgsModeType(request.ArgsMode), 470 Command: request.Command, 471 Sync: request.Sync, 472 HttpProxy: request.HttpProxy, 473 HttpsProxy: request.HttpsProxy, 474 NegativeTest: request.NegativeTest, 475 JobTemplate: request.JobTemplate, 476 JobTemplateReference: request.JobTemplateReference, 477 CronJobTemplate: request.CronJobTemplate, 478 CronJobTemplateReference: request.CronJobTemplateReference, 479 ScraperTemplate: request.ScraperTemplate, 480 ScraperTemplateReference: request.ScraperTemplateReference, 481 PvcTemplate: request.PvcTemplate, 482 PvcTemplateReference: request.PvcTemplateReference, 483 RunningContext: runningContext, 484 } 485 }