mirror of
https://github.com/stakater/Reloader.git
synced 2026-02-14 09:59:50 +00:00
214 lines
6.4 KiB
Go
214 lines
6.4 KiB
Go
package leadership
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/stakater/Reloader/internal/pkg/constants"
|
|
"github.com/stakater/Reloader/internal/pkg/controller"
|
|
"github.com/stakater/Reloader/internal/pkg/handler"
|
|
"github.com/stakater/Reloader/internal/pkg/metrics"
|
|
"github.com/stakater/Reloader/internal/pkg/options"
|
|
"github.com/stakater/Reloader/internal/pkg/testutil"
|
|
"github.com/stakater/Reloader/pkg/common"
|
|
"github.com/stakater/Reloader/pkg/kube"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
testutil.CreateNamespace(testutil.Namespace, testutil.Clients.KubernetesClient)
|
|
|
|
logrus.Infof("Running Testcases")
|
|
retCode := m.Run()
|
|
|
|
testutil.DeleteNamespace(testutil.Namespace, testutil.Clients.KubernetesClient)
|
|
|
|
os.Exit(retCode)
|
|
}
|
|
|
|
func TestHealthz(t *testing.T) {
|
|
request, err := http.NewRequest(http.MethodGet, "/live", nil)
|
|
if err != nil {
|
|
t.Fatalf(("failed to create request"))
|
|
}
|
|
|
|
response := httptest.NewRecorder()
|
|
|
|
healthz(response, request)
|
|
got := response.Code
|
|
want := 200
|
|
|
|
if got != want {
|
|
t.Fatalf("got: %d, want: %d", got, want)
|
|
}
|
|
|
|
// Have the liveness probe serve a 500
|
|
healthy = false
|
|
|
|
request, err = http.NewRequest(http.MethodGet, "/live", nil)
|
|
if err != nil {
|
|
t.Fatalf(("failed to create request"))
|
|
}
|
|
|
|
response = httptest.NewRecorder()
|
|
|
|
healthz(response, request)
|
|
got = response.Code
|
|
want = 500
|
|
|
|
if got != want {
|
|
t.Fatalf("got: %d, want: %d", got, want)
|
|
}
|
|
}
|
|
|
|
// TestRunLeaderElection validates that the liveness endpoint serves 500 when
|
|
// leadership election fails
|
|
func TestRunLeaderElection(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.TODO())
|
|
|
|
lock := GetNewLock(testutil.Clients.KubernetesClient.CoordinationV1(), constants.LockName, testutil.Pod, testutil.Namespace)
|
|
|
|
go RunLeaderElection(lock, ctx, cancel, testutil.Pod, []*controller.Controller{})
|
|
|
|
// Liveness probe should be serving OK
|
|
request, err := http.NewRequest(http.MethodGet, "/live", nil)
|
|
if err != nil {
|
|
t.Fatalf(("failed to create request"))
|
|
}
|
|
|
|
response := httptest.NewRecorder()
|
|
|
|
healthz(response, request)
|
|
got := response.Code
|
|
want := 500
|
|
|
|
if got != want {
|
|
t.Fatalf("got: %d, want: %d", got, want)
|
|
}
|
|
|
|
// Cancel the leader election context, so leadership is released and
|
|
// live endpoint serves 500
|
|
cancel()
|
|
|
|
request, err = http.NewRequest(http.MethodGet, "/live", nil)
|
|
if err != nil {
|
|
t.Fatalf(("failed to create request"))
|
|
}
|
|
|
|
response = httptest.NewRecorder()
|
|
|
|
healthz(response, request)
|
|
got = response.Code
|
|
want = 500
|
|
|
|
if got != want {
|
|
t.Fatalf("got: %d, want: %d", got, want)
|
|
}
|
|
}
|
|
|
|
// TestRunLeaderElectionWithControllers tests that leadership election works
|
|
// with real controllers and that on context cancellation the controllers stop
|
|
// running.
|
|
func TestRunLeaderElectionWithControllers(t *testing.T) {
|
|
t.Logf("Creating controller")
|
|
var controllers []*controller.Controller
|
|
for k := range kube.ResourceMap {
|
|
c, err := controller.NewController(testutil.Clients.KubernetesClient, k, testutil.Namespace, []string{}, "", "", metrics.NewCollectors())
|
|
if err != nil {
|
|
logrus.Fatalf("%s", err)
|
|
}
|
|
|
|
controllers = append(controllers, c)
|
|
}
|
|
time.Sleep(3 * time.Second)
|
|
|
|
lock := GetNewLock(testutil.Clients.KubernetesClient.CoordinationV1(), fmt.Sprintf("%s-%d", constants.LockName, 1), testutil.Pod, testutil.Namespace)
|
|
|
|
ctx, cancel := context.WithCancel(context.TODO())
|
|
|
|
// Start running leadership election, this also starts the controllers
|
|
go RunLeaderElection(lock, ctx, cancel, testutil.Pod, controllers)
|
|
time.Sleep(3 * time.Second)
|
|
|
|
// Create some stuff and do a thing
|
|
configmapName := testutil.ConfigmapNamePrefix + "-update-" + testutil.RandSeq(5)
|
|
configmapClient, err := testutil.CreateConfigMap(testutil.Clients.KubernetesClient, testutil.Namespace, configmapName, "www.google.com")
|
|
if err != nil {
|
|
t.Fatalf("Error while creating the configmap %v", err)
|
|
}
|
|
|
|
// Creating deployment
|
|
_, err = testutil.CreateDeployment(testutil.Clients.KubernetesClient, configmapName, testutil.Namespace, true)
|
|
if err != nil {
|
|
t.Fatalf("Error in deployment creation: %v", err)
|
|
}
|
|
|
|
// Updating configmap for first time
|
|
updateErr := testutil.UpdateConfigMap(configmapClient, testutil.Namespace, configmapName, "", "www.stakater.com")
|
|
if updateErr != nil {
|
|
t.Fatalf("Configmap was not updated")
|
|
}
|
|
time.Sleep(3 * time.Second)
|
|
|
|
// Verifying deployment update
|
|
logrus.Infof("Verifying pod envvars has been created")
|
|
shaData := testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, testutil.Namespace, configmapName, "www.stakater.com")
|
|
config := common.Config{
|
|
Namespace: testutil.Namespace,
|
|
ResourceName: configmapName,
|
|
SHAValue: shaData,
|
|
Annotation: options.ConfigmapUpdateOnChangeAnnotation,
|
|
}
|
|
deploymentFuncs := handler.GetDeploymentRollingUpgradeFuncs()
|
|
updated := testutil.VerifyResourceEnvVarUpdate(testutil.Clients, config, constants.ConfigmapEnvVarPostfix, deploymentFuncs)
|
|
if !updated {
|
|
t.Fatalf("Deployment was not updated")
|
|
}
|
|
time.Sleep(testutil.SleepDuration)
|
|
|
|
// Cancel the leader election context, so leadership is released
|
|
logrus.Info("shutting down controller from test")
|
|
cancel()
|
|
time.Sleep(5 * time.Second)
|
|
|
|
// Updating configmap again
|
|
updateErr = testutil.UpdateConfigMap(configmapClient, testutil.Namespace, configmapName, "", "www.stakater.com/new")
|
|
if updateErr != nil {
|
|
t.Fatalf("Configmap was not updated")
|
|
}
|
|
|
|
// Verifying that the deployment was not updated as leadership has been lost
|
|
logrus.Infof("Verifying pod envvars has not been updated")
|
|
shaData = testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, testutil.Namespace, configmapName, "www.stakater.com/new")
|
|
config = common.Config{
|
|
Namespace: testutil.Namespace,
|
|
ResourceName: configmapName,
|
|
SHAValue: shaData,
|
|
Annotation: options.ConfigmapUpdateOnChangeAnnotation,
|
|
}
|
|
deploymentFuncs = handler.GetDeploymentRollingUpgradeFuncs()
|
|
updated = testutil.VerifyResourceEnvVarUpdate(testutil.Clients, config, constants.ConfigmapEnvVarPostfix, deploymentFuncs)
|
|
if updated {
|
|
t.Fatalf("Deployment was updated")
|
|
}
|
|
|
|
// Deleting deployment
|
|
err = testutil.DeleteDeployment(testutil.Clients.KubernetesClient, testutil.Namespace, configmapName)
|
|
if err != nil {
|
|
logrus.Errorf("Error while deleting the deployment %v", err)
|
|
}
|
|
|
|
// Deleting configmap
|
|
err = testutil.DeleteConfigMap(testutil.Clients.KubernetesClient, testutil.Namespace, configmapName)
|
|
if err != nil {
|
|
logrus.Errorf("Error while deleting the configmap %v", err)
|
|
}
|
|
time.Sleep(testutil.SleepDuration)
|
|
}
|