Skip to content

Commit

Permalink
[#1315] Fix for workload prematurely being declared unhealthy
Browse files Browse the repository at this point in the history
Co-authored-by: Waciuma Wanjohi <[email protected]>
  • Loading branch information
Todd Ritchie and waciumawanjohi committed Aug 16, 2023
1 parent 8b024b4 commit 46202e4
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 5 deletions.
7 changes: 7 additions & 0 deletions pkg/realizer/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,15 @@ func (r *resourceRealizer) doImmutable(ctx context.Context, resource OwnerResour
if latestSuccessfulObject == nil {
for _, obj := range allRunnableStampedObjects {
log.V(logger.DEBUG).Info("failed to retrieve output from any object", "considered", obj)

// terminate without error early if an Unknown health is discovered as it may become healthy later
if healthcheck.DetermineStampedObjectHealth(healthRule, obj) == "Unknown" {
log.V(logger.DEBUG).Info("immutable object still has unknown dependents, halting render")
return template, stampedObject, nil, passThrough, templateName, nil
}
}

log.V(logger.DEBUG).Info("no objects are in an unknown state and none are healthy, cannot proceed")
return template, stampedObject, nil, passThrough, templateName, errors.NoHealthyImmutableObjectsError{
Err: fmt.Errorf("failed to find any healthy object in the set of immutable stamped objects"),
ResourceName: resource.Name,
Expand Down
81 changes: 76 additions & 5 deletions pkg/realizer/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/vmware-tanzu/cartographer/tests/resources"
"reflect"
"time"

Expand Down Expand Up @@ -271,13 +272,14 @@ var _ = Describe("Resource", func() {
fakeOwnerRepo.ListUnstructuredReturns([]*unstructured.Unstructured{stampedObjectWithTime}, nil)
})

When("no returned object meets the healthRule", func() {
When("at least one returned object has unknown health", func() {
BeforeEach(func() {
templateAPI.Spec.TemplateSpec.HealthRule = &v1alpha1.HealthRule{
SingleConditionType: "Ready",
}
})
It("creates a stamped object, but returns an error and no output", func() {

It("does not error", func() {
template, returnedStampedObject, out, isPassThrough, templateRefName, err := r.Do(ctx, resource, blueprintName, outputs, fakeMapper)
Expect(template).ToNot(BeNil())
Expect(isPassThrough).To(BeFalse())
Expand Down Expand Up @@ -308,9 +310,78 @@ var _ = Describe("Resource", func() {
Expect(stampedObject.Object["data"]).To(Equal(map[string]interface{}{"player_current_lives": "some-url", "some_other_info": "some-revision"}))
Expect(metadataValues["labels"]).To(Equal(map[string]interface{}{"expected-labels-from-labeler-placeholder": "labeler"}))

Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("unable to retrieve outputs for resource [resource-1] in supply chain [supply-chain-name]: failed to find any healthy object in the set of immutable stamped objects"))
Expect(reflect.TypeOf(err).String()).To(Equal("errors.NoHealthyImmutableObjectsError"))
Expect(err).NotTo(HaveOccurred())
})
})

When("no returned object has unknown health", func() {
When("no returned object meets the healthRule", func() {
BeforeEach(func() {
templateAPI.Spec.TemplateSpec.HealthRule = &v1alpha1.HealthRule{
SingleConditionType: "Succeeded",
}

status := resources.TestStatus{
ObservedGeneration: 1,
Conditions: []metav1.Condition{{
Type: "Succeeded",
Status: "False",
LastTransitionTime: metav1.Now(),
Reason: "",
}},
}

obj := unstructured.Unstructured{}
json.Unmarshal(templateAPI.Spec.TemplateSpec.Template.Raw, &obj)

Check failure on line 335 in pkg/realizer/component_test.go

View workflow job for this annotation

GitHub Actions / build

Error return value of `json.Unmarshal` is not checked (errcheck)

// easiest way to stitch the status into the unstructured.unstructured is to
// marshal and unmarshal so it's in the same state as the stamped object in the mock
statusObj, _ := json.Marshal(status)
var statusUnstructured map[string]interface{}
json.Unmarshal(statusObj, &statusUnstructured)

Check failure on line 341 in pkg/realizer/component_test.go

View workflow job for this annotation

GitHub Actions / build

Error return value of `json.Unmarshal` is not checked (errcheck)

obj.SetUnstructuredContent(map[string]interface{}{
"status": statusUnstructured,
})

fakeOwnerRepo.ListUnstructuredReturns([]*unstructured.Unstructured{&obj}, nil)
})

It("creates a stamped object, but returns an error and no output", func() {
template, _, out, isPassThrough, templateRefName, err := r.Do(ctx, resource, blueprintName, outputs, fakeMapper)
Expect(template).ToNot(BeNil())
Expect(isPassThrough).To(BeFalse())
Expect(templateRefName).To(Equal("image-template-1"))
//Expect(returnedStampedObject.Object).To(Equal(expectedObject.Object))
Expect(out).To(BeNil())

Expect(fakeOwnerRepo.EnsureImmutableObjectExistsOnClusterCallCount()).To(Equal(1))

_, stampedObject, _ := fakeOwnerRepo.EnsureImmutableObjectExistsOnClusterArgsForCall(0)

//Expect(returnedStampedObject).To(Equal(stampedObject))

metadata := stampedObject.Object["metadata"]
metadataValues, ok := metadata.(map[string]interface{})
Expect(ok).To(BeTrue())
Expect(metadataValues["name"]).To(Equal("example-config-map"))
Expect(metadataValues["ownerReferences"]).To(Equal([]interface{}{
map[string]interface{}{
"apiVersion": "",
"kind": "",
"name": "",
"uid": "",
"controller": true,
"blockOwnerDeletion": true,
},
}))
Expect(stampedObject.Object["data"]).To(Equal(map[string]interface{}{"player_current_lives": "some-url", "some_other_info": "some-revision"}))
Expect(metadataValues["labels"]).To(Equal(map[string]interface{}{"expected-labels-from-labeler-placeholder": "labeler"}))

Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("unable to retrieve outputs for resource [resource-1] in supply chain [supply-chain-name]: failed to find any healthy object in the set of immutable stamped objects"))
Expect(reflect.TypeOf(err).String()).To(Equal("errors.NoHealthyImmutableObjectsError"))
})
})
})

Expand Down

0 comments on commit 46202e4

Please sign in to comment.