github.com/redhat-appstudio/e2e-tests@v0.0.0-20230619105049-9a422b2094d7/pkg/utils/build/task_results.go (about) 1 package build 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 8 "github.com/redhat-appstudio/e2e-tests/pkg/constants" 9 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" 10 "k8s.io/apimachinery/pkg/types" 11 12 crclient "sigs.k8s.io/controller-runtime/pkg/client" 13 ) 14 15 var taskNames = []string{"clair-scan", "clamav-scan", "deprecated-base-image-check", "inspect-image", "label-check", "sbom-json-check"} 16 17 type TestOutput struct { 18 Result string `json:"result"` 19 Timestamp string `json:"timestamp"` 20 Note string `json:"note"` 21 Namespace string `json:"namespace"` 22 Successes int `json:"successes"` 23 Failures int `json:"failures"` 24 Warnings int `json:"warnings"` 25 } 26 27 type ClairScanResult struct { 28 Vulnerabilities Vulnerabilities `json:"vulnerabilities"` 29 } 30 31 type Vulnerabilities struct { 32 Critical int `json:"critical"` 33 High int `json:"high"` 34 Medium int `json:"medium"` 35 Low int `json:"low"` 36 } 37 38 func ValidateBuildPipelineTestResults(pipelineRun *v1beta1.PipelineRun, c crclient.Client) error { 39 for _, taskName := range taskNames { 40 results, err := fetchTaskRunResults(c, pipelineRun, taskName) 41 if err != nil { 42 return err 43 } 44 45 resultsToValidate := []string{constants.TektonTaskTestOutputName} 46 47 switch taskName { 48 case "clair-scan": 49 resultsToValidate = append(resultsToValidate, "CLAIR_SCAN_RESULT") 50 case "deprecated-image-check": 51 resultsToValidate = append(resultsToValidate, "PYXIS_HTTP_CODE") 52 case "inspect-image": 53 resultsToValidate = append(resultsToValidate, "BASE_IMAGE", "BASE_IMAGE_REPOSITORY") 54 } 55 56 if err := validateTaskRunResult(results, resultsToValidate, taskName); err != nil { 57 return err 58 } 59 60 } 61 return nil 62 } 63 64 func fetchTaskRunResults(c crclient.Client, pr *v1beta1.PipelineRun, pipelineTaskName string) ([]v1beta1.TaskRunResult, error) { 65 for _, chr := range pr.Status.ChildReferences { 66 if chr.PipelineTaskName != pipelineTaskName { 67 continue 68 } 69 taskRun := &v1beta1.TaskRun{} 70 taskRunKey := types.NamespacedName{Namespace: pr.Namespace, Name: chr.Name} 71 if err := c.Get(context.TODO(), taskRunKey, taskRun); err != nil { 72 return nil, err 73 } 74 return taskRun.Status.TaskRunResults, nil 75 } 76 return nil, fmt.Errorf( 77 "pipelineTaskName %q not found in PipelineRun %s/%s", pipelineTaskName, pr.GetName(), pr.GetNamespace()) 78 } 79 80 func validateTaskRunResult(trResults []v1beta1.TaskRunResult, expectedResultNames []string, taskName string) error { 81 for _, rn := range expectedResultNames { 82 found := false 83 for _, r := range trResults { 84 if rn == r.Name { 85 found = true 86 switch r.Name { 87 case constants.TektonTaskTestOutputName: 88 var testOutput = &TestOutput{} 89 err := json.Unmarshal([]byte(r.Value.StringVal), &testOutput) 90 if err != nil { 91 return fmt.Errorf("cannot parse %q result: %+v", constants.TektonTaskTestOutputName, err) 92 } 93 // If the test result isn't SUCCESS, the overall outcome is a failure 94 if taskName == "sbom-json-check" { 95 if testOutput.Result == "FAILURE" { 96 return fmt.Errorf("expected Result for Task name %q to be SUCCESS: %+v", taskName, testOutput) 97 } 98 } 99 case "CLAIR_SCAN_RESULT": 100 var testOutput = &ClairScanResult{} 101 err := json.Unmarshal([]byte(r.Value.StringVal), &testOutput) 102 if err != nil { 103 return fmt.Errorf("cannot parse CLAIR_SCAN_RESULT result: %+v", err) 104 } 105 case "PYXIS_HTTP_CODE", "BASE_IMAGE", "BASE_IMAGE_REPOSITORY": 106 if len(r.Value.StringVal) < 1 { 107 return fmt.Errorf("value of %q result is empty", r.Name) 108 } 109 } 110 } 111 } 112 if !found { 113 return fmt.Errorf("expected result name %q not found in Task %q result", rn, taskName) 114 } 115 } 116 return nil 117 }