Skip to content

Commit

Permalink
feat(KFLUXBUGS-1889): set ITS timeouts from annotations
Browse files Browse the repository at this point in the history
* If the ITS has any of the following annotations:
  test.appstudio.openshift.io/pipeline_timeout
  test.appstudio.openshift.io/tasks_timeout
  test.appstudio.openshift.io/finally_timeout
* Use them to overwrite the default timeouts that
  are set in configmaps

Signed-off-by: dirgim <[email protected]>

rh-pre-commit.version: 2.2.0
rh-pre-commit.check-secrets: ENABLED
  • Loading branch information
dirgim committed Dec 5, 2024
1 parent 719e750 commit 7aa5515
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 11 deletions.
14 changes: 14 additions & 0 deletions api/v1beta2/integrationtestscenario_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
// TestLabelPrefix contains the prefix applied to labels and annotations related to testing.
TestLabelPrefix = "test.appstudio.openshift.io"

// PipelineTimeoutAnnotation contains the name of the application
PipelineTimeoutAnnotation = TestLabelPrefix + "/pipeline_timeout"

// TasksTimeoutAnnotation contains the name of the application
TasksTimeoutAnnotation = TestLabelPrefix + "/tasks_timeout"

// FinallyTimeoutAnnotation contains the name of the application
FinallyTimeoutAnnotation = TestLabelPrefix + "/finally_timeout"
)

// IntegrationTestScenarioSpec defines the desired state of IntegrationScenario
type IntegrationTestScenarioSpec struct {
// Application that's associated with the IntegrationTestScenario
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/snapshot/snapshot_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ func (a *Adapter) createIntegrationPipelineRun(application *applicationapiv1alph
WithApplication(a.application).
WithExtraParams(integrationTestScenario.Spec.Params).
WithFinalizer(h.IntegrationPipelineRunFinalizer).
WithDefaultIntegrationTimeouts(a.logger.Logger)
WithIntegrationTimeouts(integrationTestScenario, a.logger.Logger)

if shouldUpdateIntegrationTestGitResolver(integrationTestScenario, snapshot) {
pipelineRunBuilder.WithUpdatedTestsGitResolver(getGitResolverUpdateMap(snapshot))
Expand Down
22 changes: 16 additions & 6 deletions tekton/integration_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,35 +264,45 @@ func (r *IntegrationPipelineRun) WithApplication(application *applicationapiv1al
return r
}

// WithDefaultIntegrationTimeouts fetches the default Integration timeouts from the environment variables and adds them
// to the integration PipelineRun.
func (r *IntegrationPipelineRun) WithDefaultIntegrationTimeouts(logger logr.Logger) *IntegrationPipelineRun {
// WithIntegrationTimeouts fetches the Integration timeouts from either the integrationTestScenario annotations or
// the environment variables and adds them to the integration PipelineRun.
func (r *IntegrationPipelineRun) WithIntegrationTimeouts(integrationTestScenario *v1beta2.IntegrationTestScenario, logger logr.Logger) *IntegrationPipelineRun {
pipelineTimeoutStr := os.Getenv("PIPELINE_TIMEOUT")
if metadata.HasAnnotation(integrationTestScenario, v1beta2.PipelineTimeoutAnnotation) {
pipelineTimeoutStr = integrationTestScenario.Annotations[v1beta2.PipelineTimeoutAnnotation]
}
taskTimeoutStr := os.Getenv("TASKS_TIMEOUT")
if metadata.HasAnnotation(integrationTestScenario, v1beta2.TasksTimeoutAnnotation) {
taskTimeoutStr = integrationTestScenario.Annotations[v1beta2.TasksTimeoutAnnotation]
}
finallyTimeoutStr := os.Getenv("FINALLY_TIMEOUT")
if metadata.HasAnnotation(integrationTestScenario, v1beta2.FinallyTimeoutAnnotation) {
finallyTimeoutStr = integrationTestScenario.Annotations[v1beta2.FinallyTimeoutAnnotation]
}

r.Spec.Timeouts = &tektonv1.TimeoutFields{}
if pipelineTimeoutStr != "" {
pipelineRunTimeout, err := time.ParseDuration(pipelineTimeoutStr)
if err == nil {
r.Spec.Timeouts.Pipeline = &metav1.Duration{Duration: pipelineRunTimeout}
} else {
logger.Error(err, "failed to parse default PIPELINE_TIMEOUT")
logger.Error(err, "failed to parse the PIPELINE_TIMEOUT")
}
}
if taskTimeoutStr != "" {
taskTimeout, err := time.ParseDuration(taskTimeoutStr)
if err == nil {
r.Spec.Timeouts.Tasks = &metav1.Duration{Duration: taskTimeout}
} else {
logger.Error(err, "failed to parse default TASKS_TIMEOUT")
logger.Error(err, "failed to parse the TASKS_TIMEOUT")
}
}
if finallyTimeoutStr != "" {
finallyTimeout, err := time.ParseDuration(finallyTimeoutStr)
if err == nil {
r.Spec.Timeouts.Finally = &metav1.Duration{Duration: finallyTimeout}
} else {
logger.Error(err, "failed to parse default FINALLY_TIMEOUT")
logger.Error(err, "failed to parse the FINALLY_TIMEOUT")
}
}

Expand Down
46 changes: 42 additions & 4 deletions tekton/integration_pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ var _ = Describe("Integration pipeline", func() {
It("can add timeouts to the IntegrationPipelineRun according to the environment variables", func() {
var buf bytes.Buffer
expectedDuration, _ := time.ParseDuration("2h")
newIntegrationPipelineRun.WithDefaultIntegrationTimeouts(buflogr.NewWithBuffer(&buf))
newIntegrationPipelineRun.WithIntegrationTimeouts(integrationTestScenarioGit, buflogr.NewWithBuffer(&buf))

Expect(newIntegrationPipelineRun.Spec.Timeouts.Pipeline.Duration).To(Equal(expectedDuration))
Expect(newIntegrationPipelineRun.Spec.Timeouts.Tasks.Duration).To(Equal(expectedDuration))
Expand All @@ -290,7 +290,7 @@ var _ = Describe("Integration pipeline", func() {
os.Setenv("PIPELINE_TIMEOUT", "")
os.Setenv("TASKS_TIMEOUT", "")
os.Setenv("FINALLY_TIMEOUT", "")
newIntegrationPipelineRun.WithDefaultIntegrationTimeouts(buflogr.NewWithBuffer(&buf))
newIntegrationPipelineRun.WithIntegrationTimeouts(integrationTestScenarioGit, buflogr.NewWithBuffer(&buf))

Expect(newIntegrationPipelineRun.Spec.Timeouts.Pipeline).To(BeNil())
Expect(newIntegrationPipelineRun.Spec.Timeouts.Tasks).To(BeNil())
Expand All @@ -300,13 +300,51 @@ var _ = Describe("Integration pipeline", func() {
os.Setenv("PIPELINE_TIMEOUT", "thisIsNotAValidDuration!")
os.Setenv("TASKS_TIMEOUT", "thisIsNotAValidDuration!")
os.Setenv("FINALLY_TIMEOUT", "thisIsNotAValidDuration!")
newIntegrationPipelineRun.WithDefaultIntegrationTimeouts(buflogr.NewWithBuffer(&buf))
newIntegrationPipelineRun.WithIntegrationTimeouts(integrationTestScenarioGit, buflogr.NewWithBuffer(&buf))

Expect(newIntegrationPipelineRun.Spec.Timeouts.Pipeline).To(BeNil())
Expect(newIntegrationPipelineRun.Spec.Timeouts.Tasks).To(BeNil())
Expect(newIntegrationPipelineRun.Spec.Timeouts.Finally).To(BeNil())

expectedLogEntryPrefix := "failed to parse default"
expectedLogEntryPrefix := "failed to parse the"
Expect(buf.String()).Should(ContainSubstring(expectedLogEntryPrefix + " PIPELINE_TIMEOUT"))
Expect(buf.String()).Should(ContainSubstring(expectedLogEntryPrefix + " TASKS_TIMEOUT"))
Expect(buf.String()).Should(ContainSubstring(expectedLogEntryPrefix + " FINALLY_TIMEOUT"))
})

It("can add timeouts to the IntegrationPipelineRun according to the integrationTestScenario annotations", func() {
var buf bytes.Buffer
// Use the environment variables by default, override if annotations are set
expectedDurationFromEnv, _ := time.ParseDuration("2h")
expectedDurationFromScenario, _ := time.ParseDuration("8h")
integrationTestScenarioGit.Annotations = map[string]string{}
integrationTestScenarioGit.Annotations[v1beta2.PipelineTimeoutAnnotation] = "8h"
newIntegrationPipelineRun.WithIntegrationTimeouts(integrationTestScenarioGit, buflogr.NewWithBuffer(&buf))

Expect(newIntegrationPipelineRun.Spec.Timeouts.Pipeline.Duration).To(Equal(expectedDurationFromScenario))
Expect(newIntegrationPipelineRun.Spec.Timeouts.Tasks.Duration).To(Equal(expectedDurationFromEnv))
Expect(newIntegrationPipelineRun.Spec.Timeouts.Finally.Duration).To(Equal(expectedDurationFromEnv))

// Override the environment if all annotations are set
integrationTestScenarioGit.Annotations[v1beta2.TasksTimeoutAnnotation] = "8h"
integrationTestScenarioGit.Annotations[v1beta2.FinallyTimeoutAnnotation] = "8h"
newIntegrationPipelineRun.WithIntegrationTimeouts(integrationTestScenarioGit, buflogr.NewWithBuffer(&buf))

Expect(newIntegrationPipelineRun.Spec.Timeouts.Pipeline.Duration).To(Equal(expectedDurationFromScenario))
Expect(newIntegrationPipelineRun.Spec.Timeouts.Tasks.Duration).To(Equal(expectedDurationFromScenario))
Expect(newIntegrationPipelineRun.Spec.Timeouts.Finally.Duration).To(Equal(expectedDurationFromScenario))

// Set the timeouts to invalid strings, which should skip setting the timeouts
integrationTestScenarioGit.Annotations[v1beta2.PipelineTimeoutAnnotation] = "thisIsNotAValidDuration!"
integrationTestScenarioGit.Annotations[v1beta2.TasksTimeoutAnnotation] = "thisIsNotAValidDuration!"
integrationTestScenarioGit.Annotations[v1beta2.FinallyTimeoutAnnotation] = "thisIsNotAValidDuration!"
newIntegrationPipelineRun.WithIntegrationTimeouts(integrationTestScenarioGit, buflogr.NewWithBuffer(&buf))

Expect(newIntegrationPipelineRun.Spec.Timeouts.Pipeline).To(BeNil())
Expect(newIntegrationPipelineRun.Spec.Timeouts.Tasks).To(BeNil())
Expect(newIntegrationPipelineRun.Spec.Timeouts.Finally).To(BeNil())

expectedLogEntryPrefix := "failed to parse the"
Expect(buf.String()).Should(ContainSubstring(expectedLogEntryPrefix + " PIPELINE_TIMEOUT"))
Expect(buf.String()).Should(ContainSubstring(expectedLogEntryPrefix + " TASKS_TIMEOUT"))
Expect(buf.String()).Should(ContainSubstring(expectedLogEntryPrefix + " FINALLY_TIMEOUT"))
Expand Down

0 comments on commit 7aa5515

Please sign in to comment.