Skip to content

Commit

Permalink
chore: improve fixture based testing
Browse files Browse the repository at this point in the history
  • Loading branch information
moshloop committed Nov 17, 2024
1 parent ee7e88e commit df8cf40
Show file tree
Hide file tree
Showing 15 changed files with 560 additions and 51 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
)

require (
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cert-manager/cert-manager v1.9.0 h1:b8kfA8dOxDQyJtFJLH6dkT6WivRuAHR21PxnywJjuGk=
github.com/cert-manager/cert-manager v1.9.0/go.mod h1:Bs3WsNX1LPKTs3boh//p7jLOn6ZRGEPz99ITeZU0g3c=
Expand Down
13 changes: 13 additions & 0 deletions pkg/health/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const (
HealthWarning Health = "warning"
)

func IsValidHealth(s string) bool {
return s == string(HealthHealthy) || s == string(HealthUnhealthy) || s == string(HealthUnknown) || s == string(HealthWarning)
}

// Represents resource health status
type HealthStatusCode string

Expand Down Expand Up @@ -132,6 +136,15 @@ func GetHealthByConfigType(configType string, obj map[string]any, states ...stri

if len(states) > 0 {
return GetHealthFromStatusName(states[0])
} else {
for k, v := range obj {
_k := strings.ToLower(k)
_v := fmt.Sprintf("%s", v)
if _k == "status" || _k == "state" ||
strings.HasSuffix(_k, "status") {
return GetHealthFromStatusName(_v)
}
}
}
return HealthStatus{
Health: HealthUnknown,
Expand Down
18 changes: 0 additions & 18 deletions pkg/health/health_aws_ecs_test.go

This file was deleted.

18 changes: 0 additions & 18 deletions pkg/health/health_cnrm_test.go

This file was deleted.

21 changes: 21 additions & 0 deletions pkg/health/health_fixtures_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package health_test

import (
"testing"

"github.com/bmatcuk/doublestar/v4"
)

func TestFixtures(t *testing.T) {
files, err := doublestar.FilepathGlob("testdata/*/**/*.yaml")
if err != nil {
t.Fatal(err)
}
if len(files) == 0 {
t.Fatal("no test files found")
}

for _, file := range files {
testFixture(t, file)
}
}
69 changes: 54 additions & 15 deletions pkg/health/health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ Package provides functionality that allows assessing the health state of a Kuber
package health_test

import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"testing"
Expand All @@ -16,6 +18,7 @@ import (
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
goyaml "gopkg.in/yaml.v3"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/util/yaml"
)
Expand Down Expand Up @@ -48,6 +51,32 @@ var (
}
)

func testFixture(t *testing.T, yamlPath string) {
t.Run(yamlPath, func(t *testing.T) {
hr, obj := getHealthStatus(yamlPath, t, make(map[string]string))

expectedHealth := health.Health(strings.ReplaceAll(filepath.Base(yamlPath), ".yaml", ""))
if health.IsValidHealth(string(expectedHealth)) {
assert.Equal(t, expectedHealth, hr.Health)
}

if v, ok := obj.GetAnnotations()["expected-health"]; ok {
assert.Equal(t, v, hr.Health)
}

if v, ok := obj.GetAnnotations()["expected-message"]; ok {
assert.Equal(t, v, hr.Message)
}
if v, ok := obj.GetAnnotations()["expected-status"]; ok {
assert.Equal(t, health.HealthStatusCode(v), hr.Status)
}

if v, ok := obj.GetAnnotations()["expected-ready"]; ok {
assert.Equal(t, v == "true", hr.Ready)
}
})
}

func assertAppHealthMsg(
t *testing.T,
yamlPath string,
Expand All @@ -69,7 +98,7 @@ func assertAppHealthMsg(
}
}
t.Run(yamlPath, func(t *testing.T) {
health := getHealthStatus(yamlPath, t, m)
health, _ := getHealthStatus(yamlPath, t, m)
assert.NotNil(t, health)
assert.Equal(t, expectedHealth, health.Health)
assert.Equal(t, expectedReady, health.Ready)
Expand All @@ -96,7 +125,7 @@ func assertAppHealth(
for i := 0; i < len(overrides); i += 2 {
m[overrides[i]] = overrides[i+1]
}
health := getHealthStatus(yamlPath, t, m)
health, _ := getHealthStatus(yamlPath, t, m)
assert.NotNil(t, health)
assert.Equal(t, expectedHealth, health.Health)
assert.Equal(t, expectedReady, health.Ready)
Expand All @@ -112,7 +141,8 @@ func assertAppHealthWithOverwriteMsg(
expectedReady bool,
expectedMsg string,
) {
health := getHealthStatus(yamlPath, t, overwrites)
health, _ := getHealthStatus(yamlPath, t, overwrites)

assert.NotNil(t, health)
assert.Equal(t, expectedHealth, health.Health)
assert.Equal(t, expectedReady, health.Ready)
Expand All @@ -128,15 +158,15 @@ func assertAppHealthWithOverwrite(
expectedHealth health.Health,
expectedReady bool,
) {
health := getHealthStatus(yamlPath, t, overwrites)
health, _ := getHealthStatus(yamlPath, t, overwrites)
assert.NotNil(t, health)
assert.Equal(t, expectedHealth, health.Health)
assert.Equal(t, expectedReady, health.Ready)
assert.Equal(t, expectedStatus, health.Status)
}

func getHealthStatus(yamlPath string, t *testing.T, overwrites map[string]string) *health.HealthStatus {
if !strings.HasPrefix(yamlPath, "./testdata/") && !strings.HasPrefix(yamlPath, "../resource_customizations") {
func getHealthStatus(yamlPath string, t *testing.T, overwrites map[string]string) (*health.HealthStatus, unstructured.Unstructured) {
if !strings.HasPrefix(yamlPath, "./testdata/") && !strings.HasPrefix(yamlPath, "testdata/") && !strings.HasPrefix(yamlPath, "../resource_customizations") {
yamlPath = "./testdata/" + yamlPath
}
var yamlBytes []byte
Expand Down Expand Up @@ -166,21 +196,30 @@ func getHealthStatus(yamlPath string, t *testing.T, overwrites map[string]string
yamlString = strings.ReplaceAll(yamlString, k, v)
}

if strings.Contains(yamlPath, "::") {
configType := strings.Split(yamlPath, "/")[2]
var obj map[string]any
err = yaml.Unmarshal([]byte(yamlString), &obj)
var obj unstructured.Unstructured
if !strings.Contains(yamlString, "apiVersion:") && !strings.Contains(yamlString, "kind:") {
configType := strings.Join(strings.Split(strings.ReplaceAll(filepath.Dir(yamlPath), "testdata/", ""), "/"), "::")
var m map[string]any
err = goyaml.Unmarshal([]byte(yamlString), &m)
require.NoError(t, err)
return lo.ToPtr(health.GetHealthByConfigType(configType, obj))
obj = unstructured.Unstructured{Object: m}
if v, ok := m["annotations"]; ok {
var a = make(map[string]string)
for k, v := range v.(map[string]any) {
a[k] = fmt.Sprintf("%s", v)
}

obj.SetAnnotations(a)
}
return lo.ToPtr(health.GetHealthByConfigType(configType, m)), obj
}

var obj unstructured.Unstructured
err = yaml.Unmarshal([]byte(yamlString), &obj)
require.NoError(t, err)

health, err := health.GetResourceHealth(&obj, health.DefaultOverrides)
require.NoError(t, err)
return health
return health, obj
}

func TestCrossplane(t *testing.T) {
Expand Down Expand Up @@ -732,7 +771,7 @@ func TestFluxResources(t *testing.T) {
)
assertAppHealth(t, "./testdata/flux-kustomization-unhealthy.yaml", "Progressing", health.HealthUnknown, false)
assertAppHealth(t, "./testdata/flux-kustomization-failed.yaml", "BuildFailed", health.HealthUnhealthy, false)
status := getHealthStatus("./testdata/flux-kustomization-failed.yaml", t, nil)
status, _ := getHealthStatus("./testdata/flux-kustomization-failed.yaml", t, nil)
assert.Contains(t, status.Message, "err='accumulating resources from 'kubernetes_resource_ingress_fail.yaml'")

assertAppHealth(
Expand All @@ -744,7 +783,7 @@ func TestFluxResources(t *testing.T) {
)
assertAppHealth(t, "./testdata/flux-helmrelease-unhealthy.yaml", "UpgradeFailed", health.HealthUnhealthy, true)
assertAppHealth(t, "./testdata/flux-helmrelease-upgradefailed.yaml", "UpgradeFailed", health.HealthUnhealthy, true)
helmreleaseStatus := getHealthStatus("./testdata/flux-helmrelease-upgradefailed.yaml", t, nil)
helmreleaseStatus, _ := getHealthStatus("./testdata/flux-helmrelease-upgradefailed.yaml", t, nil)
assert.Contains(
t,
helmreleaseStatus.Message,
Expand Down
8 changes: 8 additions & 0 deletions pkg/health/testdata/AWS/Cloudformation/Stack/healthy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CreationTime: "2023-05-09T03:59:08.629Z"
DriftInformation:
StackDriftStatus: NOT_CHECKED
StackId: arn:aws:cloudformation:eu-west-1:765618022540:stack/eksctl-mission-control-demo-cluster-addon-iamserviceaccount-kube-system-cluster-autoscaler/d94c1e20-ee1d-11ed-857e-0a810473a089
StackName: eksctl-mission-control-demo-cluster-addon-iamserviceaccount-kube-system-cluster-autoscaler
StackStatus: CREATE_COMPLETE
TemplateDescription: IAM role for serviceaccount
"kube-system/cluster-autoscaler" [created and managed by eksctl]
10 changes: 10 additions & 0 deletions pkg/health/testdata/AWS/Cloudformation/Stack/unhealthy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
annotations:
message: 'The following resource(s) failed to create: [ECSCluster].'
CreationTime: 2024-06-27T14:23:12.654Z
DriftInformation:
StackDriftStatus: NOT_CHECKED
StackId: arn:aws:cloudformation:eu-west-1:765618022540:stack/Infra-ECS-Cluster-test-aditya-d2231163/c91bc4f0-3490-11ef-ba04-0267adf9bc1d
StackName: Infra-ECS-Cluster-test-aditya-d2231163
StackStatus: CREATE_FAILED
StackStatusReason: "The following resource(s) failed to create: [ECSCluster]. "
TemplateDescription: The template used to create an ECS Cluster from the ECS Console.
13 changes: 13 additions & 0 deletions pkg/health/testdata/AWS/ECS/Cluster/healthy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
ActiveServicesCount: 1
Attachments: []
CapacityProviders: []
ClusterArn: arn:aws:ecs:eu-west-1:765618022540:cluster/demo-dev-cluster
ClusterName: demo-dev-cluster
DefaultCapacityProviderStrategy: []
PendingTasksCount: 0
RegisteredContainerInstancesCount: 0
RunningTasksCount: 1
Settings: []
Statistics: []
Status: ACTIVE
Tags: []
Loading

0 comments on commit df8cf40

Please sign in to comment.