Skip to content

Commit

Permalink
Init OSS Conformance Test Suite
Browse files Browse the repository at this point in the history
This commit initiates the OSS conformance test suite. It sets the
standards for incrementing the V1 conformance test with the two simple
test cases.

/kind misc
  • Loading branch information
JeromeJu committed Apr 3, 2024
1 parent 34673be commit 9845ffe
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 0 deletions.
122 changes: 122 additions & 0 deletions test/conformance/conformance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//go:build conformance
// +build conformance

/*
Copyright 2024 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*
The following tests are the OSS conformance test suite.
For a more detailed reference of the Tekton Conformance API spec please refer
to https://github.com/tektoncd/pipeline/blob/main/docs/api-spec.md.
Please implement the `ProcessAndSendToTekton` with the respective conformant
Tekton service corresponding to the function signature below:
// ProcessAndSendToTekton takes in vanilla Tekton PipelineRun and TaskRun,
// waits for the object to succeed and outputs the final PipelineRun and
// TaskRun with status.
// The parameters are inputYAML and its Primitive type {PipelineRun, TaskRun}
// And the return values will be the output YAML string and errors.
func ProcessAndSendToTekton(inputYAML, primitiveType string, customInputs ...interface{}) (string, error) {
}
Once `ProcessAndSendToTekton` is implemented, please use the following for
triggering the test and record the corresponding outputs:
go test -v -tags=conformance -count=1 ./test -run ^Test
*/

package conformance_test

import (
"fmt"
"testing"

"github.com/tektoncd/pipeline/test/parse"
"knative.dev/pkg/test/helpers"
)

const (
succeedConditionStatus = "True"
conformanceVersion = "v1"
)

// TestTaskRunConditions examines population of Conditions
// fields. It creates the a TaskRun with minimal specifications and checks the
// required Condition Status and Type.
func TestTaskRunConditions(t *testing.T) {
t.Parallel()

inputYAML := fmt.Sprintf(`
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
name: %s
spec:
taskSpec:
steps:
- name: add
image: ubuntu
script: |
echo Hello world!
`, helpers.ObjectNameForTest(t))

// The execution of Pipeline CRDs that should be implemented by Vendor service
outputYAML, err := ProcessAndSendToTekton(inputYAML, TaskRunInputType, t)
if err != nil {
t.Fatalf("Vendor service failed processing inputYAML: %s", err)
}

// Parse and validate output YAML
resolvedTR := parse.MustParseV1TaskRun(t, outputYAML)

if err := checkTaskRunConditionSucceeded(resolvedTR.Status, succeedConditionStatus, "Succeeded"); err != nil {
t.Error(err)
}
}

// TestPipelineRunConditions examines population of Conditions
// fields. It creates the a PipelineRun with minimal specifications and checks the
// required Condition Status and Type.
func TestPipelineRunConditions(t *testing.T) {
t.Parallel()

inputYAML := fmt.Sprintf(`
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: %s
spec:
pipelineSpec:
tasks:
- name: pipeline-task-0
taskSpec:
steps:
- name: add
image: ubuntu
script: |
echo Hello world!
`, helpers.ObjectNameForTest(t))

// The execution of Pipeline CRDs that should be implemented by Vendor service
outputYAML, err := ProcessAndSendToTekton(inputYAML, PipelineRunInputType, t)
if err != nil {
t.Fatalf("Vendor service failed processing inputYAML: %s", err)
}

// Parse and validate output YAML
resolvedPR := parse.MustParseV1PipelineRun(t, outputYAML)

if err := checkPipelineRunConditionSucceeded(resolvedPR.Status, succeedConditionStatus, "Succeeded"); err != nil {
t.Error(err)
}
}
75 changes: 75 additions & 0 deletions test/conformance/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//go:build conformance
// +build conformance

/*
Copyright 2024 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package conformance_test

import (
"fmt"

v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
)

// checkTaskRunConditionSucceeded checks the TaskRun Succeeded Condition;
// expectedSucceeded is a corev1.ConditionStatus(string), which is either "True" or "False"
// expectedReason is string, the expected Condition.Reason
func checkTaskRunConditionSucceeded(trStatus v1.TaskRunStatus, expectedSucceededStatus string, expectedReason string) error {
hasSucceededConditionType := false

for _, cond := range trStatus.Conditions {
if cond.Type == "Succeeded" {
if string(cond.Status) != expectedSucceededStatus {
return fmt.Errorf("Expect vendor service to populate Condition %s but got: %s", expectedSucceededStatus, cond.Status)
}
if cond.Reason != expectedReason {
return fmt.Errorf("Expect vendor service to populate Condition Reason %s but got: %s", expectedReason, cond.Reason)
}

hasSucceededConditionType = true
}
}

if !hasSucceededConditionType {
return fmt.Errorf("Expect vendor service to populate Succeeded Condition but not apparent in TaskRunStatus")
}

return nil
}

// checkPipelineRunConditionSucceeded checks the PipelineRun Succeeded Condition;
// expectedSucceeded is a corev1.ConditionStatus(string), which is either "True" or "False"
// expectedReason is string, the expected Condition.Reason
func checkPipelineRunConditionSucceeded(prStatus v1.PipelineRunStatus, expectedSucceededStatus string, expectedReason string) error {
hasSucceededConditionType := false

for _, cond := range prStatus.Conditions {
if cond.Type == "Succeeded" {
if string(cond.Status) != expectedSucceededStatus {
return fmt.Errorf("Expect vendor service to populate Condition %s but got: %s", expectedSucceededStatus, cond.Status)
}
if cond.Reason != expectedReason {
return fmt.Errorf("Expect vendor service to populate Condition Reason %s but got: %s", expectedReason, cond.Reason)
}

hasSucceededConditionType = true
}
}

if !hasSucceededConditionType {
return fmt.Errorf("Expect vendor service to populate Succeeded Condition but not apparent in PipelineRunStatus")
}

return nil
}

0 comments on commit 9845ffe

Please sign in to comment.