devlopment branch (#1736)
This commit is contained in:
356
pkg/models/components/components_test.go
Normal file
356
pkg/models/components/components_test.go
Normal file
@@ -0,0 +1,356 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"kubesphere.io/kubesphere/pkg/api/resource/v1alpha2"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func service(name, namespace string, selector map[string]string) runtime.Object {
|
||||
return &v1.Service{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Service",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Selector: selector,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func pods(name, namespace string, labels map[string]string, healthPods, totalPods int) []runtime.Object {
|
||||
var ps []runtime.Object
|
||||
|
||||
for index := 0; index < totalPods; index++ {
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-%d", name, index),
|
||||
Namespace: namespace,
|
||||
Labels: labels,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
{
|
||||
Name: fmt.Sprintf("%s-%d", name, index),
|
||||
Ready: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if index >= healthPods {
|
||||
pod.Status.Phase = v1.PodPending
|
||||
pod.Status.ContainerStatuses[0].Ready = false
|
||||
}
|
||||
|
||||
ps = append(ps, pod)
|
||||
}
|
||||
|
||||
return ps
|
||||
}
|
||||
|
||||
func nodes(name string, healthNodes, totalNodes int) []runtime.Object {
|
||||
var ns []runtime.Object
|
||||
|
||||
for index := 0; index < totalNodes; index++ {
|
||||
node := &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-%d", name, index),
|
||||
},
|
||||
Status: v1.NodeStatus{
|
||||
Phase: v1.NodeRunning,
|
||||
Conditions: []v1.NodeCondition{
|
||||
{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if index >= healthNodes {
|
||||
node.Status.Phase = v1.NodePending
|
||||
node.Status.Conditions[0].Status = v1.ConditionFalse
|
||||
}
|
||||
|
||||
ns = append(ns, node)
|
||||
}
|
||||
|
||||
return ns
|
||||
}
|
||||
|
||||
func TestGetSystemHealthStatus(t *testing.T) {
|
||||
var tests = []struct {
|
||||
description string
|
||||
labels map[string]string
|
||||
namespace string
|
||||
name string
|
||||
healthPods int
|
||||
totalPods int
|
||||
healthNodes int
|
||||
totalNodes int
|
||||
expected v1alpha2.HealthStatus
|
||||
}{
|
||||
{
|
||||
"no backends",
|
||||
map[string]string{"app": "foo"},
|
||||
"kube-system",
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
v1alpha2.HealthStatus{
|
||||
KubeSphereComponents: []v1alpha2.ComponentStatus{
|
||||
{
|
||||
Namespace: "kube-system",
|
||||
Label: map[string]string{"app": "foo"},
|
||||
TotalBackends: 0,
|
||||
HealthyBackends: 0,
|
||||
},
|
||||
},
|
||||
NodeStatus: v1alpha2.NodeStatus{},
|
||||
},
|
||||
},
|
||||
{
|
||||
"all healthy",
|
||||
map[string]string{"app": "foo"},
|
||||
"kubesphere-system",
|
||||
"ks-apiserver",
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
v1alpha2.HealthStatus{
|
||||
KubeSphereComponents: []v1alpha2.ComponentStatus{
|
||||
{
|
||||
Name: "ks-apiserver",
|
||||
Namespace: "kubesphere-system",
|
||||
Label: map[string]string{"app": "foo"},
|
||||
TotalBackends: 2,
|
||||
HealthyBackends: 2,
|
||||
},
|
||||
},
|
||||
NodeStatus: v1alpha2.NodeStatus{
|
||||
TotalNodes: 2,
|
||||
HealthyNodes: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"all unhealthy",
|
||||
map[string]string{"app": "foo"},
|
||||
"kubesphere-system",
|
||||
"ks-apiserver",
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
2,
|
||||
v1alpha2.HealthStatus{
|
||||
KubeSphereComponents: []v1alpha2.ComponentStatus{
|
||||
{
|
||||
Name: "ks-apiserver",
|
||||
Namespace: "kubesphere-system",
|
||||
Label: map[string]string{"app": "foo"},
|
||||
TotalBackends: 2,
|
||||
HealthyBackends: 0,
|
||||
},
|
||||
},
|
||||
NodeStatus: v1alpha2.NodeStatus{
|
||||
TotalNodes: 2,
|
||||
HealthyNodes: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"half healthy",
|
||||
map[string]string{"app": "foo"},
|
||||
"kubesphere-system",
|
||||
"ks-apiserver",
|
||||
2,
|
||||
4,
|
||||
2,
|
||||
4,
|
||||
v1alpha2.HealthStatus{
|
||||
KubeSphereComponents: []v1alpha2.ComponentStatus{
|
||||
{
|
||||
Name: "ks-apiserver",
|
||||
Namespace: "kubesphere-system",
|
||||
Label: map[string]string{"app": "foo"},
|
||||
TotalBackends: 4,
|
||||
HealthyBackends: 2,
|
||||
},
|
||||
},
|
||||
NodeStatus: v1alpha2.NodeStatus{
|
||||
TotalNodes: 4,
|
||||
HealthyNodes: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
ps := pods(test.name, test.namespace, test.labels, test.healthPods, test.totalPods)
|
||||
svc := service(test.name, test.namespace, test.labels)
|
||||
ns := nodes(test.name, test.healthNodes, test.totalNodes)
|
||||
|
||||
var objs []runtime.Object
|
||||
objs = append(objs, ps...)
|
||||
objs = append(objs, svc)
|
||||
objs = append(objs, ns...)
|
||||
|
||||
client := fake.NewSimpleClientset(objs...)
|
||||
|
||||
informer := informers.NewSharedInformerFactory(client, time.Minute*10)
|
||||
|
||||
informer.Core().V1().Services().Informer().GetIndexer().Add(svc)
|
||||
|
||||
for _, obj := range ps {
|
||||
informer.Core().V1().Pods().Informer().GetIndexer().Add(obj)
|
||||
}
|
||||
|
||||
for _, obj := range ns {
|
||||
informer.Core().V1().Nodes().Informer().GetIndexer().Add(obj)
|
||||
}
|
||||
|
||||
c := NewComponentsGetter(informer)
|
||||
healthStatus, err := c.GetSystemHealthStatus()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(healthStatus, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetComponentStatus(t *testing.T) {
|
||||
var tests = []struct {
|
||||
description string
|
||||
name string
|
||||
namespace string
|
||||
labels map[string]string
|
||||
healthPods int
|
||||
totalPods int
|
||||
expected v1alpha2.ComponentStatus
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
"no component",
|
||||
"random",
|
||||
"foo",
|
||||
map[string]string{"app": "foo"},
|
||||
2,
|
||||
4,
|
||||
v1alpha2.ComponentStatus{
|
||||
Name: "",
|
||||
Namespace: "",
|
||||
SelfLink: "",
|
||||
Label: nil,
|
||||
StartedAt: time.Time{},
|
||||
TotalBackends: 0,
|
||||
HealthyBackends: 0,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"all healthy",
|
||||
"ks-apiserver",
|
||||
"kubesphere-system",
|
||||
map[string]string{"app": "foo"},
|
||||
2,
|
||||
4,
|
||||
v1alpha2.ComponentStatus{
|
||||
Name: "ks-apiserver",
|
||||
Namespace: "kubesphere-system",
|
||||
Label: map[string]string{"app": "foo"},
|
||||
TotalBackends: 4,
|
||||
HealthyBackends: 2,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"all unhealthy",
|
||||
"ks-apiserver",
|
||||
"kubesphere-system",
|
||||
map[string]string{"app": "foo"},
|
||||
0,
|
||||
4,
|
||||
v1alpha2.ComponentStatus{
|
||||
Name: "ks-apiserver",
|
||||
Namespace: "kubesphere-system",
|
||||
Label: map[string]string{"app": "foo"},
|
||||
TotalBackends: 4,
|
||||
HealthyBackends: 0,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"half healthy",
|
||||
"ks-apiserver",
|
||||
"kubesphere-system",
|
||||
map[string]string{"app": "foo"},
|
||||
2,
|
||||
4,
|
||||
v1alpha2.ComponentStatus{
|
||||
Name: "ks-apiserver",
|
||||
Namespace: "kubesphere-system",
|
||||
Label: map[string]string{"app": "foo"},
|
||||
TotalBackends: 4,
|
||||
HealthyBackends: 2,
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
ps := pods(test.name, test.namespace, test.labels, test.healthPods, test.totalPods)
|
||||
svc := service(test.name, test.namespace, test.labels)
|
||||
|
||||
var objs []runtime.Object
|
||||
objs = append(objs, ps...)
|
||||
objs = append(objs, svc)
|
||||
|
||||
client := fake.NewSimpleClientset(objs...)
|
||||
|
||||
informer := informers.NewSharedInformerFactory(client, time.Minute*10)
|
||||
|
||||
informer.Core().V1().Services().Informer().GetIndexer().Add(svc)
|
||||
|
||||
for _, obj := range ps {
|
||||
informer.Core().V1().Pods().Informer().GetIndexer().Add(obj)
|
||||
}
|
||||
|
||||
c := NewComponentsGetter(informer)
|
||||
healthStatus, err := c.GetComponentStatus(test.name)
|
||||
if err == nil && test.expectedError {
|
||||
t.Fatalf("expected error while got nothing")
|
||||
} else if err != nil && !test.expectedError {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(healthStatus, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user