mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-09-30 23:01:14 +02:00
134 lines
4.0 KiB
Go
134 lines
4.0 KiB
Go
package controller
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/zalando/postgres-operator/v2/pkg/spec"
|
|
v1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/client-go/kubernetes/fake"
|
|
k8stesting "k8s.io/client-go/testing"
|
|
)
|
|
|
|
const (
|
|
readyLabel = "lifecycle-status"
|
|
readyValue = "ready"
|
|
)
|
|
|
|
func newNodeTestController() *Controller {
|
|
var controller = NewController(&spec.ControllerConfig{}, "node-test")
|
|
return controller
|
|
}
|
|
|
|
func makeNode(labels map[string]string, isSchedulable bool) *v1.Node {
|
|
return &v1.Node{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: v1.NamespaceDefault,
|
|
Labels: labels,
|
|
},
|
|
Spec: v1.NodeSpec{
|
|
Unschedulable: !isSchedulable,
|
|
},
|
|
}
|
|
}
|
|
|
|
var nodeTestController = newNodeTestController()
|
|
|
|
func TestNodeIsReady(t *testing.T) {
|
|
testName := "TestNodeIsReady"
|
|
var testTable = []struct {
|
|
in *v1.Node
|
|
out bool
|
|
readinessLabel map[string]string
|
|
}{
|
|
{
|
|
in: makeNode(map[string]string{"foo": "bar"}, true),
|
|
out: true,
|
|
readinessLabel: map[string]string{readyLabel: readyValue},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{"foo": "bar"}, false),
|
|
out: false,
|
|
readinessLabel: map[string]string{readyLabel: readyValue},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{readyLabel: readyValue}, false),
|
|
out: true,
|
|
readinessLabel: map[string]string{readyLabel: readyValue},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{"foo": "bar", "master": "true"}, false),
|
|
out: true,
|
|
readinessLabel: map[string]string{readyLabel: readyValue},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{"foo": "bar", "master": "true"}, false),
|
|
out: true,
|
|
readinessLabel: map[string]string{readyLabel: readyValue},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{"foo": "bar"}, true),
|
|
out: true,
|
|
readinessLabel: map[string]string{},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{"foo": "bar"}, false),
|
|
out: false,
|
|
readinessLabel: map[string]string{},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{readyLabel: readyValue}, false),
|
|
out: false,
|
|
readinessLabel: map[string]string{},
|
|
},
|
|
{
|
|
in: makeNode(map[string]string{"foo": "bar", "master": "true"}, false),
|
|
out: true,
|
|
readinessLabel: map[string]string{},
|
|
},
|
|
}
|
|
for _, tt := range testTable {
|
|
nodeTestController.opConfig.NodeReadinessLabel = tt.readinessLabel
|
|
if isReady := nodeTestController.nodeIsReady(tt.in); isReady != tt.out {
|
|
t.Errorf("%s: expected response %t does not match the actual %t for the node %#v",
|
|
testName, tt.out, isReady, tt.in)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestMoveMasterPodsOffNodeRetriesOnError ensures a failed attempt to move
|
|
// master pods off a node is retried rather than aborting the whole retry
|
|
// loop on the first error.
|
|
func TestMoveMasterPodsOffNodeRetriesOnError(t *testing.T) {
|
|
clientSet := fake.NewSimpleClientset()
|
|
clientSet.PrependReactor("list", "pods", func(action k8stesting.Action) (bool, runtime.Object, error) {
|
|
return true, nil, fmt.Errorf("could not list pods")
|
|
})
|
|
|
|
controller := newNodeTestController()
|
|
controller.KubeClient.PodsGetter = clientSet.CoreV1()
|
|
// timeout == the retry interval hardcoded in moveMasterPodsOffNode, so
|
|
// the single retry attempt resolves synchronously without a real sleep.
|
|
controller.opConfig.MasterPodMoveTimeout = &metav1.Duration{Duration: 1 * time.Minute}
|
|
|
|
var logOutput bytes.Buffer
|
|
logger := logrus.New()
|
|
logger.SetOutput(&logOutput)
|
|
controller.logger = logger.WithField("pkg", "controller")
|
|
|
|
controller.moveMasterPodsOffNode(makeNode(map[string]string{}, false))
|
|
|
|
if logOutput.Len() == 0 {
|
|
t.Fatal("expected moveMasterPodsOffNode to log a warning")
|
|
}
|
|
if !strings.Contains(logOutput.String(), "still failing after") {
|
|
t.Errorf("expected the retry loop to run out of attempts instead of aborting on the first error, got log output: %q", logOutput.String())
|
|
}
|
|
}
|