Skip to content

Commit

Permalink
addon test for health probe
Browse files Browse the repository at this point in the history
Signed-off-by: zhujian <jiazhu@redhat.com>
  • Loading branch information
zhujian7 committed Jul 4, 2023
1 parent c6d05d6 commit 9f34253
Show file tree
Hide file tree
Showing 8 changed files with 594 additions and 53 deletions.
10 changes: 6 additions & 4 deletions pkg/addonmanager/controllers/agentdeploy/default_sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ var mainfestWorkAppliedCondition = metav1.Condition{
}

type testAgent struct {
name string
objects []runtime.Object
err error
name string
objects []runtime.Object
err error
healthProber *agent.HealthProber
}

func (t *testAgent) Manifests(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) ([]runtime.Object, error) {
Expand All @@ -55,7 +56,8 @@ func (t *testAgent) Manifests(cluster *clusterv1.ManagedCluster, addon *addonapi

func (t *testAgent) GetAgentAddonOptions() agent.AgentAddonOptions {
return agent.AgentAddonOptions{
AddonName: t.name,
AddonName: t.name,
HealthProber: t.healthProber,
}
}

Expand Down
22 changes: 2 additions & 20 deletions pkg/addonmanager/controllers/agentdeploy/healthcheck_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,24 +206,6 @@ func (s *healthCheckSyncer) analyzeWorkProber(
}
}

func (s *healthCheckSyncer) deploymentAvailabilityChecker(
identifier workapiv1.ResourceIdentifier,
result workapiv1.StatusFeedbackResult) error {
if identifier.Resource != "deployments" {
return fmt.Errorf("unsupported resource type %s", identifier.Resource)
}
if identifier.Group != "apps" {
return fmt.Errorf("unsupported resource group %s", identifier.Group)
}

for _, value := range result.Values {
if value.Name == "AvailableReplicas" && value.Value.Integer != nil && *value.Value.Integer >= 1 {
return nil
}
}
return fmt.Errorf("no available replicas")
}

func (s *healthCheckSyncer) analyzeDeploymentWorkProber(
agentAddon agent.AgentAddon,
cluster *clusterv1.ManagedCluster,
Expand All @@ -238,14 +220,14 @@ func (s *healthCheckSyncer) analyzeDeploymentWorkProber(

deployments := utils.FilterDeployments(manifests)
for _, deployment := range deployments {
manifestConfig := utils.DeploymentWellKnowManifestConfig(deployment)
manifestConfig := utils.DeploymentWellKnowManifestConfig(deployment.Namespace, deployment.Name)
probeFields = append(probeFields, agent.ProbeField{
ResourceIdentifier: manifestConfig.ResourceIdentifier,
ProbeRules: manifestConfig.FeedbackRules,
})
}

return probeFields, s.deploymentAvailabilityChecker, nil
return probeFields, utils.DeploymentAvailabilityHealthCheck, nil
}

func findResultByIdentifier(identifier workapiv1.ResourceIdentifier, manifestConditions []workapiv1.ManifestCondition) *workapiv1.StatusFeedbackResult {
Expand Down
218 changes: 209 additions & 9 deletions pkg/addonmanager/controllers/agentdeploy/healthcheck_sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"testing"
"time"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -38,7 +40,8 @@ type healthCheckTestAgent struct {
}

func (t *healthCheckTestAgent) Manifests(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) ([]runtime.Object, error) {
return nil, nil

return []runtime.Object{NewFakeDeployment("test-deployment", "default")}, nil
}

func (t *healthCheckTestAgent) GetAgentAddonOptions() agent.AgentAddonOptions {
Expand All @@ -48,6 +51,39 @@ func (t *healthCheckTestAgent) GetAgentAddonOptions() agent.AgentAddonOptions {
}
}

func NewFakeDeployment(namespace, name string) *appsv1.Deployment {
var one int32 = 1
return &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
Namespace: name,
},
Spec: appsv1.DeploymentSpec{
Replicas: &one,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "test",
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"addon": "test",
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "test",
Image: "test",
},
},
},
},
},
}
}

func TestHealthCheckReconcile(t *testing.T) {
cases := []struct {
name string
Expand Down Expand Up @@ -137,7 +173,6 @@ func TestHealthCheckReconcile(t *testing.T) {
},
Spec: v1.ManifestWorkSpec{},
Status: v1.ManifestWorkStatus{

Conditions: []metav1.Condition{
{
Type: v1.WorkAvailable,
Expand Down Expand Up @@ -257,6 +292,169 @@ func TestHealthCheckReconcile(t *testing.T) {
Message: "Addon is available",
},
},

{
name: "Health check mode is deployment availability but manifestApplied condition is not true",
testAddon: &healthCheckTestAgent{name: "test",
health: &agent.HealthProber{Type: agent.HealthProberTypeDeploymentAvailability},
},
addon: addontesting.NewAddon("test", "cluster1"),
expectedErr: nil,
expectedHealthCheckMode: addonapiv1alpha1.HealthCheckModeCustomized,
expectAvailableCondition: metav1.Condition{},
},
{
name: "Health check mode is deployment availability but no work",
testAddon: &healthCheckTestAgent{name: "test",
health: &agent.HealthProber{Type: agent.HealthProberTypeDeploymentAvailability},
},
addon: addontesting.NewAddonWithConditions("test", "cluster1", manifestAppliedCondition),
expectedErr: nil,
expectedHealthCheckMode: addonapiv1alpha1.HealthCheckModeCustomized,
expectAvailableCondition: metav1.Condition{
Type: addonapiv1alpha1.ManagedClusterAddOnConditionAvailable,
Status: metav1.ConditionUnknown,
Reason: addonapiv1alpha1.AddonAvailableReasonWorkNotFound,
Message: "Work for addon is not found",
},
},
{
name: "Health check mode is deployment availability but work is unavailable",
testAddon: &healthCheckTestAgent{name: "test",
health: &agent.HealthProber{Type: agent.HealthProberTypeDeploymentAvailability},
},
addon: addontesting.NewAddonWithConditions("test", "cluster1", manifestAppliedCondition),
existingWork: []runtime.Object{
&v1.ManifestWork{
ObjectMeta: metav1.ObjectMeta{
Name: "addon-test-deploy-01",
Namespace: "cluster1",
Labels: map[string]string{
"open-cluster-management.io/addon-name": "test",
},
},
Spec: v1.ManifestWorkSpec{},
Status: v1.ManifestWorkStatus{
Conditions: []metav1.Condition{
{
Type: v1.WorkAvailable,
Status: metav1.ConditionFalse,
Message: "failed to apply",
},
},
},
},
},
expectedErr: nil,
expectedHealthCheckMode: addonapiv1alpha1.HealthCheckModeCustomized,
expectAvailableCondition: metav1.Condition{
Type: addonapiv1alpha1.ManagedClusterAddOnConditionAvailable,
Status: metav1.ConditionFalse,
Reason: addonapiv1alpha1.AddonAvailableReasonWorkNotApply,
Message: "failed to apply",
},
},
{
name: "Health check mode is deployment availability but no result",
testAddon: &healthCheckTestAgent{name: "test",
health: &agent.HealthProber{Type: agent.HealthProberTypeDeploymentAvailability},
},
addon: addontesting.NewAddonWithConditions("test", "cluster1", manifestAppliedCondition),
existingWork: []runtime.Object{
&v1.ManifestWork{
ObjectMeta: metav1.ObjectMeta{
Name: "addon-test-deploy-01",
Namespace: "cluster1",
Labels: map[string]string{
"open-cluster-management.io/addon-name": "test",
},
},
Spec: v1.ManifestWorkSpec{},
Status: v1.ManifestWorkStatus{
Conditions: []metav1.Condition{
{
Type: v1.WorkAvailable,
Status: metav1.ConditionTrue,
},
},
},
},
},
expectedErr: nil,
expectedHealthCheckMode: addonapiv1alpha1.HealthCheckModeCustomized,
expectAvailableCondition: metav1.Condition{
Type: addonapiv1alpha1.ManagedClusterAddOnConditionAvailable,
Status: metav1.ConditionUnknown,
Reason: addonapiv1alpha1.AddonAvailableReasonNoProbeResult,
Message: "Probe results are not returned",
},
},
{
name: "Health check mode is deployment availability but WorkProber check pass",
testAddon: &healthCheckTestAgent{name: "test",
health: &agent.HealthProber{Type: agent.HealthProberTypeDeploymentAvailability},
},
addon: addontesting.NewAddonWithConditions("test", "cluster1", manifestAppliedCondition),
existingWork: []runtime.Object{
&v1.ManifestWork{
ObjectMeta: metav1.ObjectMeta{
Name: "addon-test-deploy-01",
Namespace: "cluster1",
Labels: map[string]string{
"open-cluster-management.io/addon-name": "test",
},
},
Spec: v1.ManifestWorkSpec{},
Status: v1.ManifestWorkStatus{
ResourceStatus: v1.ManifestResourceStatus{
Manifests: []v1.ManifestCondition{
{
ResourceMeta: v1.ManifestResourceMeta{
Ordinal: 0,
Group: "apps",
Version: "",
Kind: "",
Resource: "deployments",
Name: "test-deployment",
Namespace: "default",
},
StatusFeedbacks: v1.StatusFeedbackResult{
Values: []v1.FeedbackValue{
{
Name: "Replicas",
Value: v1.FieldValue{
Integer: boolPtr(1),
},
},
{
Name: "ReadyReplicas",
Value: v1.FieldValue{
Integer: boolPtr(2),
},
},
},
},
},
},
},
Conditions: []metav1.Condition{
{
Type: v1.WorkAvailable,
Status: metav1.ConditionTrue,
},
},
},
},
},
expectedErr: nil,
expectedHealthCheckMode: addonapiv1alpha1.HealthCheckModeCustomized,
expectAvailableCondition: metav1.Condition{
Type: addonapiv1alpha1.ManagedClusterAddOnConditionAvailable,
Status: metav1.ConditionTrue,
Reason: addonapiv1alpha1.AddonAvailableReasonProbeAvailable,
Message: "Addon is available",
},
},
}

for _, c := range cases {
Expand Down Expand Up @@ -291,28 +489,30 @@ func TestHealthCheckReconcile(t *testing.T) {

addon, err := healthCheckSyncer.sync(context.TODO(), addontesting.NewFakeSyncContext(t), nil, c.addon)
if (err == nil && c.expectedErr != nil) || (err != nil && c.expectedErr == nil) {
t.Errorf("expected err %v, but got %v", c.expectedErr, err)
t.Errorf("name %s, expected err %v, but got %v", c.name, c.expectedErr, err)
} else if err != nil && c.expectedErr != nil && err.Error() != c.expectedErr.Error() {
t.Errorf("expected err %v, but got %v", c.expectedErr, err)
t.Errorf("name %s, expected err %v, but got %v", c.name, c.expectedErr, err)
}

if !equality.Semantic.DeepEqual(addon.Status.HealthCheck.Mode, c.expectedHealthCheckMode) {
t.Errorf("expected err %v, but got %v", addon.Status.HealthCheck.Mode, c.expectedHealthCheckMode)
t.Errorf("name %s, expected err %v, but got %v",
c.name, addon.Status.HealthCheck.Mode, c.expectedHealthCheckMode)
}

if c.expectAvailableCondition.Type != "" {
cond := meta.FindStatusCondition(addon.Status.Conditions, c.expectAvailableCondition.Type)
if cond == nil {
t.Errorf("expected condition %v, but connot get", c.expectAvailableCondition.Type)
t.Fatalf("name %s, expected condition %v, but connot get", c.name, c.expectAvailableCondition.Type)
}
if cond.Status != c.expectAvailableCondition.Status {
t.Errorf("expected condition status %v, but connot get %v", c.expectAvailableCondition.Status, cond.Status)
t.Errorf("name %s, expected condition status %v, but got %v",
c.name, c.expectAvailableCondition.Status, cond.Status)
}
if cond.Reason != c.expectAvailableCondition.Reason {
t.Errorf("expected condition reason %v, but connot get %v", c.expectAvailableCondition.Reason, cond.Reason)
t.Errorf("name %s, expected condition reason %v, but got %v",
c.name, c.expectAvailableCondition.Reason, cond.Reason)
}
}
})
}

}
Loading

0 comments on commit 9f34253

Please sign in to comment.