che-operator/pkg/deploy/server/server_test.go

325 lines
8.9 KiB
Go

//
// Copyright (c) 2012-2019 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package server
import (
"context"
"github.com/eclipse-che/che-operator/pkg/deploy"
"github.com/eclipse-che/che-operator/pkg/util"
routev1 "github.com/openshift/api/route/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"testing"
)
func TestSyncService(t *testing.T) {
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
corev1.SchemeBuilder.AddToScheme(scheme.Scheme)
cli := fake.NewFakeClientWithScheme(scheme.Scheme)
deployContext := &deploy.DeployContext{
CheCluster: &orgv1.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: orgv1.CheClusterSpec{
Server: orgv1.CheClusterSpecServer{
CheDebug: "true",
},
Metrics: orgv1.CheClusterSpecMetrics{
Enable: true,
},
},
},
ClusterAPI: deploy.ClusterAPI{
Client: cli,
NonCachedClient: cli,
Scheme: scheme.Scheme,
},
}
server := NewServer(deployContext)
done, err := server.SyncCheService()
if !done {
if err != nil {
t.Fatalf("Failed to sync service, error: %v", err)
} else {
t.Fatalf("Failed to sync service")
}
}
service := &corev1.Service{}
err = cli.Get(context.TODO(), types.NamespacedName{Name: deploy.CheServiceName, Namespace: "eclipse-che"}, service)
if err != nil {
t.Fatalf("Failed to get service, error: %v", err)
}
checkPort(service.Spec.Ports[0], "http", 8080, t)
checkPort(service.Spec.Ports[1], "metrics", deploy.DefaultCheMetricsPort, t)
checkPort(service.Spec.Ports[2], "debug", deploy.DefaultCheDebugPort, t)
}
func TestSyncAll(t *testing.T) {
cheCluster := &orgv1.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: orgv1.CheClusterSpec{
Server: orgv1.CheClusterSpecServer{
TlsSupport: true,
},
},
}
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
corev1.SchemeBuilder.AddToScheme(scheme.Scheme)
routev1.AddToScheme(scheme.Scheme)
cli := fake.NewFakeClientWithScheme(scheme.Scheme, cheCluster)
deployContext := &deploy.DeployContext{
CheCluster: cheCluster,
ClusterAPI: deploy.ClusterAPI{
Client: cli,
NonCachedClient: cli,
Scheme: scheme.Scheme,
},
Proxy: &deploy.Proxy{},
}
util.IsOpenShift = true
server := NewServer(deployContext)
done, err := server.ExposeCheServiceAndEndpoint()
if !done || err != nil {
t.Fatalf("Failed to sync Server: %v", err)
}
done, err = server.SyncAll()
if !done || err != nil {
t.Fatalf("Failed to sync Server: %v", err)
}
// check service
service := &corev1.Service{}
err = cli.Get(context.TODO(), types.NamespacedName{Name: deploy.CheServiceName, Namespace: "eclipse-che"}, service)
if err != nil {
t.Fatalf("Service not found: %v", err)
}
// check endpoint
route := &routev1.Route{}
err = cli.Get(context.TODO(), types.NamespacedName{Name: server.component, Namespace: "eclipse-che"}, route)
if err != nil {
t.Fatalf("Route not found: %v", err)
}
// check configmap
configMap := &corev1.ConfigMap{}
err = cli.Get(context.TODO(), types.NamespacedName{Name: server.component, Namespace: "eclipse-che"}, configMap)
if err != nil {
t.Fatalf("ConfigMap not found: %v", err)
}
// check deployment
deployment := &appsv1.Deployment{}
err = cli.Get(context.TODO(), types.NamespacedName{Name: server.component, Namespace: "eclipse-che"}, deployment)
if err != nil {
t.Fatalf("Deployment not found: %v", err)
}
if cheCluster.Status.CheURL == "" {
t.Fatalf("CheURL is not set")
}
if cheCluster.Status.CheClusterRunning == "" {
t.Fatalf("CheClusterRunning is not set")
}
if cheCluster.Status.CheVersion == "" {
t.Fatalf("CheVersion is not set")
}
}
func TestSyncLegacyConfigMap(t *testing.T) {
cheCluster := &orgv1.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: orgv1.CheClusterSpec{
Server: orgv1.CheClusterSpecServer{
TlsSupport: true,
},
},
}
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
corev1.SchemeBuilder.AddToScheme(scheme.Scheme)
routev1.AddToScheme(scheme.Scheme)
cli := fake.NewFakeClientWithScheme(scheme.Scheme, cheCluster)
deployContext := &deploy.DeployContext{
CheCluster: cheCluster,
ClusterAPI: deploy.ClusterAPI{
Client: cli,
NonCachedClient: cli,
Scheme: scheme.Scheme,
},
Proxy: &deploy.Proxy{},
}
legacyConfigMap := deploy.GetConfigMapSpec(deployContext, "custom", map[string]string{"a": "b"}, "test")
err := cli.Create(context.TODO(), legacyConfigMap)
if err != nil {
t.Fatalf("Failed to create config map: %v", err)
}
server := NewServer(deployContext)
done, err := server.SyncLegacyConfigMap()
if !done || err != nil {
t.Fatalf("Failed to sync config map: %v", err)
}
err = cli.Get(context.TODO(), types.NamespacedName{Namespace: "eclipse-che", Name: "custom"}, &corev1.ConfigMap{})
if err == nil {
t.Fatalf("Legacy configmap must be removed")
}
if cheCluster.Spec.Server.CustomCheProperties["a"] != "b" {
t.Fatalf("CheCluster wasn't updated with legacy configmap data")
}
}
func TestSyncPVC(t *testing.T) {
cheCluster := &orgv1.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: orgv1.CheClusterSpec{
Server: orgv1.CheClusterSpecServer{
CustomCheProperties: map[string]string{
"CHE_MULTIUSER": "false",
},
},
},
}
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
corev1.SchemeBuilder.AddToScheme(scheme.Scheme)
routev1.AddToScheme(scheme.Scheme)
cli := fake.NewFakeClientWithScheme(scheme.Scheme, cheCluster)
deployContext := &deploy.DeployContext{
CheCluster: cheCluster,
ClusterAPI: deploy.ClusterAPI{
Client: cli,
NonCachedClient: cli,
Scheme: scheme.Scheme,
},
}
server := NewServer(deployContext)
done, err := server.SyncPVC()
if !done || err != nil {
t.Fatalf("Failed to sync PVC: %v", err)
}
err = cli.Get(context.TODO(), types.NamespacedName{Namespace: "eclipse-che", Name: "custom"}, &corev1.PersistentVolumeClaim{})
if err == nil {
t.Fatalf("PVC not found")
}
}
func TestUpdateAvailabilityStatus(t *testing.T) {
cheDeployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "che",
Namespace: "eclipse-che",
},
Status: appsv1.DeploymentStatus{
AvailableReplicas: 1,
Replicas: 1,
},
}
cheCluster := &orgv1.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: orgv1.CheClusterSpec{},
Status: orgv1.CheClusterStatus{},
}
orgv1.SchemeBuilder.AddToScheme(scheme.Scheme)
corev1.SchemeBuilder.AddToScheme(scheme.Scheme)
routev1.AddToScheme(scheme.Scheme)
cli := fake.NewFakeClientWithScheme(scheme.Scheme, cheCluster)
deployContext := &deploy.DeployContext{
CheCluster: cheCluster,
ClusterAPI: deploy.ClusterAPI{
Client: cli,
NonCachedClient: cli,
Scheme: scheme.Scheme,
},
}
server := NewServer(deployContext)
_, err := server.UpdateAvailabilityStatus()
if err != nil {
t.Fatalf("Failed to update availability status: %v", err)
}
if cheCluster.Status.CheClusterRunning != UnavailableStatus {
t.Fatalf("Expected status: %s, actual: %s", UnavailableStatus, cheCluster.Status.CheClusterRunning)
}
err = cli.Create(context.TODO(), cheDeployment)
if err != nil {
t.Fatalf("Deployment not found: %v", err)
}
_, err = server.UpdateAvailabilityStatus()
if err != nil {
t.Fatalf("Failed to update availability status: %v", err)
}
if cheCluster.Status.CheClusterRunning != AvailableStatus {
t.Fatalf("Expected status: %s, actual: %s", AvailableStatus, cheCluster.Status.CheClusterRunning)
}
cheDeployment.Status.Replicas = 2
err = cli.Update(context.TODO(), cheDeployment)
if err != nil {
t.Fatalf("Failed to update deployment: %v", err)
}
_, err = server.UpdateAvailabilityStatus()
if err != nil {
t.Fatalf("Failed to update availability status: %v", err)
}
if cheCluster.Status.CheClusterRunning != RollingUpdateInProgressStatus {
t.Fatalf("Expected status: %s, actual: %s", RollingUpdateInProgressStatus, cheCluster.Status.CheClusterRunning)
}
}
func checkPort(actualPort corev1.ServicePort, expectedName string, expectedPort int32, t *testing.T) {
if actualPort.Name != expectedName || actualPort.Port != expectedPort {
t.Errorf("expected port name:`%s` port:`%d`, actual name:`%s` port:`%d`",
expectedName, expectedPort, actualPort.Name, actualPort.Port)
}
}