-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #475 from qu1queee/qu1queee/conditions_br
Add conditions pkg to support Build CRDs to operate on Conditions
- Loading branch information
Showing
8 changed files
with
386 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright The Shipwright Contributors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package conditions | ||
|
||
// | ||
// This class is heavily based on | ||
// https://github.com/knative/pkg/blob/master/apis/condition_set.go | ||
// but contains a more simplified approach. | ||
// | ||
// This class is intended to enable any Build CRD that might require to | ||
// operate and support Conditions. | ||
// | ||
// For any Build CRD that requires to operate on Conditions, they should | ||
// only need to implement the StatusConditions interface. | ||
// | ||
|
||
// StatusConditions provides access to the conditions of an | ||
// object that have a Status field | ||
type StatusConditions interface { | ||
GetConditions() *Conditions | ||
SetConditions(Conditions) | ||
} | ||
|
||
// Access is the interface that allows retrieval | ||
// of a particular condition | ||
type Access interface { | ||
GetCondition(t Type) *Condition | ||
} | ||
|
||
// Manager is the interface that allows to operate | ||
// on a particular condition, by getting or setting it | ||
type Manager interface { | ||
Access | ||
SetCondition(*Condition) | ||
} | ||
|
||
// Implementor implements the Manager interface | ||
type Implementor struct { | ||
Connect StatusConditions | ||
} | ||
|
||
// Verify that Implementor implements Manager | ||
var _ Manager = (*Implementor)(nil) | ||
|
||
// Manage enables an object that implements the | ||
// StatusConditions interface to get access to the Manager | ||
func Manage(status StatusConditions) Manager { | ||
return Implementor{ | ||
Connect: status, | ||
} | ||
} | ||
|
||
// GetCondition retrieves a particular condition based | ||
// on the type | ||
func (i Implementor) GetCondition(t Type) *Condition { | ||
if i.Connect == nil { | ||
return nil | ||
} | ||
|
||
for _, c := range *i.Connect.GetConditions() { | ||
if c.Type == t { | ||
return &c | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// SetCondition updates a condition by generating the same list | ||
// of conditions with the provided one | ||
// This does not preserve the order when multiple conditions exist. | ||
func (i Implementor) SetCondition(aCondition *Condition) { | ||
if i.Connect == nil { | ||
return | ||
} | ||
|
||
var conditions Conditions | ||
|
||
for _, c := range *i.Connect.GetConditions() { | ||
if c.Type != aCondition.Type { | ||
conditions = append(conditions, c) | ||
} | ||
} | ||
conditions = append(conditions, *aCondition) | ||
|
||
i.Connect.SetConditions(conditions) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright The Shipwright Contributors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package conditions_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestConditions(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Conditions Suite") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright The Shipwright Contributors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package conditions_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
"github.com/shipwright-io/build/pkg/conditions" | ||
"github.com/shipwright-io/build/test" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
var _ = Describe("Conditions", func() { | ||
|
||
var ( | ||
ctl test.Catalog | ||
) | ||
|
||
Context("Operating on Conditions", func() { | ||
|
||
It("should be able to get a manager based on a buildrun status", func() { | ||
// BuildRun sample with an embedded condition of the type Succeeded | ||
br := ctl.BuildRunWithSucceededCondition() | ||
m := conditions.Manage(&br.Status) | ||
Expect(m).ToNot(BeNil()) | ||
|
||
c := m.GetCondition(conditions.Succeeded) | ||
Expect(c).ToNot(BeNil()) | ||
}) | ||
|
||
It("should be able to retrieve an existing condition message", func() { | ||
// BuildRun sample with an embedded condition of the type Succeeded | ||
br := ctl.BuildRunWithSucceededCondition() | ||
|
||
// BuildRun implements StatusConditions, therefore it can operate on | ||
// an existing Condition | ||
msg := br.Status.GetCondition(conditions.Succeeded).GetMessage() | ||
Expect(msg).To(Equal("foo is not bar")) | ||
}) | ||
|
||
It("should be able to retrieve an existing condition reason", func() { | ||
// BuildRun sample with an embedded condition of the type Succeeded | ||
br := ctl.BuildRunWithSucceededCondition() | ||
|
||
reason := br.Status.GetCondition(conditions.Succeeded).GetReason() | ||
Expect(reason).To(Equal("foobar")) | ||
}) | ||
|
||
It("should be able to retrieve an existing condition status", func() { | ||
// BuildRun sample with an embedded condition of the type Succeeded | ||
br := ctl.BuildRunWithSucceededCondition() | ||
|
||
status := br.Status.GetCondition(conditions.Succeeded).GetStatus() | ||
Expect(status).To(Equal(corev1.ConditionUnknown)) | ||
}) | ||
|
||
It("should return nil if a condition is not available when operating on it", func() { | ||
br := ctl.DefaultBuildRun("foo", "bar") | ||
|
||
// when getting a condition that does not exists on the BuildRun, do not | ||
// panic but rather return a nil | ||
cond := br.Status.GetCondition(conditions.Succeeded) | ||
Expect(cond).To(BeNil()) | ||
}) | ||
|
||
It("should be able to set a condition based on a type", func() { | ||
br := ctl.DefaultBuildRun("foo", "bar") | ||
|
||
// generate a condition of the type Succeeded | ||
tmpCond := &conditions.Condition{ | ||
Type: conditions.Succeeded, | ||
Status: corev1.ConditionUnknown, | ||
Message: "foobar", | ||
Reason: "foo is bar", | ||
LastTransitionTime: metav1.Now(), | ||
} | ||
|
||
// set the condition on the BuildRun resource | ||
br.Status.SetCondition(tmpCond) | ||
|
||
condType := br.Status.GetCondition(conditions.Succeeded).Type | ||
Expect(condType).To(Equal(conditions.Succeeded)) | ||
|
||
condMsg := br.Status.GetCondition(conditions.Succeeded).GetMessage() | ||
Expect(condMsg).To(Equal("foobar")) | ||
}) | ||
|
||
It("should be able to update an existing condition based on a type", func() { | ||
// BuildRun sample with an embedded condition of the type Succeeded | ||
br := ctl.BuildRunWithSucceededCondition() | ||
|
||
reason := br.Status.GetCondition(conditions.Succeeded).GetReason() | ||
Expect(reason).To(Equal("foobar")) | ||
|
||
// generate a condition in order to update the existing one | ||
tmpCond := &conditions.Condition{ | ||
Type: conditions.Succeeded, | ||
Status: corev1.ConditionUnknown, | ||
Message: "foobar was updated", | ||
Reason: "foo is bar", | ||
LastTransitionTime: metav1.Now(), | ||
} | ||
|
||
// update the condition on the BuildRun resource | ||
br.Status.SetCondition(tmpCond) | ||
|
||
condMsg := br.Status.GetCondition(conditions.Succeeded).GetMessage() | ||
Expect(condMsg).To(Equal("foobar was updated")) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.