Ctrl K
ComunidadGuías…

api/handler/application_handler_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package handler

import (
	"context"
	"testing"

	apimodel "github.com/goodrain/rainbond/api/model"
	"github.com/goodrain/rainbond/api/util/bcode"
	"github.com/goodrain/rainbond/db"
	dbdao "github.com/goodrain/rainbond/db/dao"
	dbmodel "github.com/goodrain/rainbond/db/model"
	"github.com/stretchr/testify/assert"
	corev1 "k8s.io/api/core/v1"
	k8serrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	k8sfake "k8s.io/client-go/kubernetes/fake"
)

type applicationPortsTestManager struct {
	db.Manager
	tenantServiceDao      dbdao.TenantServiceDao
	tenantServicesPortDao dbdao.TenantServicesPortDao
}

func (m applicationPortsTestManager) TenantServiceDao() dbdao.TenantServiceDao {
	return m.tenantServiceDao
}

func (m applicationPortsTestManager) TenantServicesPortDao() dbdao.TenantServicesPortDao {
	return m.tenantServicesPortDao
}

type applicationPortsTenantServiceDao struct {
	dbdao.TenantServiceDao
	services       []*dbmodel.TenantServices
	err            error
	requestedAppID string
}

func (d *applicationPortsTenantServiceDao) ListByAppID(appID string) ([]*dbmodel.TenantServices, error) {
	d.requestedAppID = appID
	return d.services, d.err
}

type applicationPortsTenantServicesPortDao struct {
	dbdao.TenantServicesPortDao
	ports          []*dbmodel.TenantServicesPort
	err            error
	requestedNames []string
}

func (d *applicationPortsTenantServicesPortDao) ListByK8sServiceNames(names []string) ([]*dbmodel.TenantServicesPort, error) {
	d.requestedNames = append([]string(nil), names...)
	return d.ports, d.err
}

// capability_id: rainbond.application.check-port-k8s-service-name-duplicate
func TestApplicationActionCheckPortsRejectsDuplicateK8sServiceName(t *testing.T) {
	tenantServiceDao := &applicationPortsTenantServiceDao{
		services: []*dbmodel.TenantServices{
			{ServiceID: "service-1"},
			{ServiceID: "service-2"},
		},
	}
	tenantServicesPortDao := &applicationPortsTenantServicesPortDao{
		ports: []*dbmodel.TenantServicesPort{
			{
				ServiceID:      "service-2",
				ContainerPort:  5000,
				K8sServiceName: "shared-service",
			},
		},
	}
	db.SetTestManager(applicationPortsTestManager{
		tenantServiceDao:      tenantServiceDao,
		tenantServicesPortDao: tenantServicesPortDao,
	})
	defer db.SetTestManager(nil)

	action := &ApplicationAction{}
	err := action.checkPorts("app-1", []*apimodel.AppPort{
		{
			ServiceID:      "service-1",
			ContainerPort:  5000,
			PortAlias:      "WEB",
			K8sServiceName: "shared-service",
		},
	})

	assert.Equal(t, "app-1", tenantServiceDao.requestedAppID)
	assert.Equal(t, []string{"shared-service"}, tenantServicesPortDao.requestedNames)
	assert.Error(t, err)
	assert.True(t, bcode.ErrK8sServiceNameExists.Equal(err))
}

func TestApplicationActionGetPVCDiskRequestsKBByAppID(t *testing.T) {
	kubeClient := k8sfake.NewSimpleClientset(
		&corev1.PersistentVolumeClaim{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "data-mysql-0",
				Namespace: "demo",
				Labels: map[string]string{
					"app_id": "app-1",
				},
			},
			Spec: corev1.PersistentVolumeClaimSpec{
				Resources: corev1.VolumeResourceRequirements{
					Requests: corev1.ResourceList{
						corev1.ResourceStorage: resource.MustParse("10Gi"),
					},
				},
			},
		},
		&corev1.PersistentVolumeClaim{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "data-other-0",
				Namespace: "demo",
				Labels: map[string]string{
					"app_id": "app-2",
				},
			},
			Spec: corev1.PersistentVolumeClaimSpec{
				Resources: corev1.VolumeResourceRequirements{
					Requests: corev1.ResourceList{
						corev1.ResourceStorage: resource.MustParse("20Gi"),
					},
				},
			},
		},
	)
	action := &ApplicationAction{kubeClient: kubeClient}

	got, err := action.getPVCDiskRequestsKB(context.Background(), "app-1")

	assert.NoError(t, err)
	assert.Equal(t, int64(10*1024*1024), got)
}

func TestApplicationActionGetPVCDiskRequestsKBFromAppPods(t *testing.T) {
	kubeClient := k8sfake.NewSimpleClientset(
		&corev1.PersistentVolumeClaim{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "data-mysql-0",
				Namespace: "demo",
			},
			Spec: corev1.PersistentVolumeClaimSpec{
				Resources: corev1.VolumeResourceRequirements{
					Requests: corev1.ResourceList{
						corev1.ResourceStorage: resource.MustParse("10Gi"),
					},
				},
			},
		},
		&corev1.Pod{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "mysql-0",
				Namespace: "demo",
				Labels: map[string]string{
					"app_id": "app-1",
				},
			},
			Spec: corev1.PodSpec{
				Volumes: []corev1.Volume{
					{
						Name: "data",
						VolumeSource: corev1.VolumeSource{
							PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
								ClaimName: "data-mysql-0",
							},
						},
					},
				},
			},
		},
	)
	action := &ApplicationAction{kubeClient: kubeClient}

	got, err := action.getPVCDiskRequestsKB(context.Background(), "app-1")

	assert.NoError(t, err)
	assert.Equal(t, int64(10*1024*1024), got)
}

// capability_id: rainbond.application.delete-config-secrets
func TestApplicationActionDeleteApplicationConfigSecrets(t *testing.T) {
	t.Run("delete named config group secret", func(t *testing.T) {
		kubeClient := k8sfake.NewSimpleClientset(
			&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "settings-app-1", Namespace: "demo", Labels: map[string]string{"app_id": "app-1"}}},
			&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "other-app-1", Namespace: "demo", Labels: map[string]string{"app_id": "app-1"}}},
		)
		action := &ApplicationAction{kubeClient: kubeClient}

		err := action.deleteApplicationConfigSecrets(context.Background(), "demo", "app-1", []string{"settings"})

		assert.NoError(t, err)
		_, err = kubeClient.CoreV1().Secrets("demo").Get(context.Background(), "settings-app-1", metav1.GetOptions{})
		assert.True(t, k8serrors.IsNotFound(err))
		_, err = kubeClient.CoreV1().Secrets("demo").Get(context.Background(), "other-app-1", metav1.GetOptions{})
		assert.NoError(t, err)
	})

	t.Run("delete all app labelled secrets", func(t *testing.T) {
		kubeClient := k8sfake.NewSimpleClientset(
			&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "settings-app-1", Namespace: "demo", Labels: map[string]string{"app_id": "app-1"}}},
			&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "runtime-app-1", Namespace: "demo", Labels: map[string]string{"app_id": "app-1"}}},
			&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "settings-app-2", Namespace: "demo", Labels: map[string]string{"app_id": "app-2"}}},
		)
		action := &ApplicationAction{kubeClient: kubeClient}

		err := action.deleteApplicationConfigSecrets(context.Background(), "demo", "app-1", nil)

		assert.NoError(t, err)
		remaining, err := kubeClient.CoreV1().Secrets("demo").List(context.Background(), metav1.ListOptions{})
		assert.NoError(t, err)
		assert.Len(t, remaining.Items, 1)
		assert.Equal(t, "settings-app-2", remaining.Items[0].Name)
	})
}