Ctrl K
ComunidadGuías…

api/handler/application_config_group_test.go

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

Archivo original ↗Preguntar a KiBot
package handler

import (
	"path/filepath"
	"testing"

	apimodel "github.com/goodrain/rainbond/api/model"
	"github.com/goodrain/rainbond/db"
	"github.com/goodrain/rainbond/db/dao"
	dbmodel "github.com/goodrain/rainbond/db/model"
	mysqldao "github.com/goodrain/rainbond/db/mysql/dao"
	"github.com/goodrain/rainbond/worker/appm/conversion"
	v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type configGroupBindingTestManager struct {
	db.Manager
	database *gorm.DB
}

func (m configGroupBindingTestManager) Begin() *gorm.DB { return m.database.Begin() }
func (m configGroupBindingTestManager) TenantServiceDao() dao.TenantServiceDao {
	return &mysqldao.TenantServicesDaoImpl{DB: m.database}
}
func (m configGroupBindingTestManager) AppConfigGroupDao() dao.AppConfigGroupDao {
	return m.AppConfigGroupDaoTransactions(m.database)
}
func (m configGroupBindingTestManager) AppConfigGroupDaoTransactions(tx *gorm.DB) dao.AppConfigGroupDao {
	return &mysqldao.AppConfigGroupDaoImpl{DB: tx}
}
func (m configGroupBindingTestManager) AppConfigGroupServiceDao() dao.AppConfigGroupServiceDao {
	return m.AppConfigGroupServiceDaoTransactions(m.database)
}
func (m configGroupBindingTestManager) AppConfigGroupServiceDaoTransactions(tx *gorm.DB) dao.AppConfigGroupServiceDao {
	return &mysqldao.AppConfigGroupServiceDaoImpl{DB: tx}
}
func (m configGroupBindingTestManager) AppConfigGroupItemDao() dao.AppConfigGroupItemDao {
	return m.AppConfigGroupItemDaoTransactions(m.database)
}
func (m configGroupBindingTestManager) AppConfigGroupItemDaoTransactions(tx *gorm.DB) dao.AppConfigGroupItemDao {
	return &mysqldao.AppConfigGroupItemDaoImpl{DB: tx}
}

// capability_id: rainbond.app-config-group.pending-component-bindings
func TestConfigGroupRetainsPendingComponentBindings(t *testing.T) {
	for _, operation := range []string{"create", "update"} {
		for _, existing := range []bool{false, true} {
			name := operation + "/pending-only"
			if existing {
				name = operation + "/mixed"
			}
			t.Run(name, func(t *testing.T) {
				database, err := gorm.Open("sqlite3", filepath.Join(t.TempDir(), "groups.db"))
				if err != nil {
					t.Fatal(err)
				}
				t.Cleanup(func() { database.Close() })
				database.LogMode(false)
				if err := database.AutoMigrate(&dbmodel.TenantServices{}, &dbmodel.ApplicationConfigGroup{}, &dbmodel.ConfigGroupService{}, &dbmodel.ConfigGroupItem{}).Error; err != nil {
					t.Fatal(err)
				}
				manager := configGroupBindingTestManager{database: database}
				old := db.GetManager()
				db.SetTestManager(manager)
				t.Cleanup(func() { db.SetTestManager(old) })
				ids := []string{"pending", ""}
				if existing {
					if err := database.Create(&dbmodel.TenantServices{ServiceID: "ready", ServiceAlias: "gr-ready", AppID: "app"}).Error; err != nil {
						t.Fatal(err)
					}
					ids = append(ids, "ready", "pending")
				}
				items := []apimodel.ConfigItem{{ItemKey: "APP_NAME", ItemValue: "${_SERVICE_NAME}"}}
				action := &ApplicationAction{}
				var response *apimodel.ApplicationConfigGroupResp
				if operation == "create" {
					response, err = action.AddConfigGroup("app", &apimodel.ApplicationConfigGroup{ConfigGroupName: "java", Enable: true, DeployType: "env", ServiceIDs: ids, ConfigItems: items})
				} else {
					if err := database.Create(&dbmodel.ApplicationConfigGroup{AppID: "app", ConfigGroupName: "java", Enable: true, DeployType: "env"}).Error; err != nil {
						t.Fatal(err)
					}
					if err := database.Create(&dbmodel.ConfigGroupService{AppID: "app", ConfigGroupName: "java", ServiceID: "removed"}).Error; err != nil {
						t.Fatal(err)
					}
					response, err = action.UpdateConfigGroup("app", "java", &apimodel.UpdateAppConfigGroupReq{Enable: true, ServiceIDs: ids, ConfigItems: items})
				}
				if err != nil {
					t.Fatal(err)
				}
				got := map[string]string{}
				for _, binding := range response.Services {
					if _, duplicate := got[binding.ServiceID]; duplicate {
						t.Fatalf("duplicate binding for %s", binding.ServiceID)
					}
					got[binding.ServiceID] = binding.ServiceAlias
				}
				if _, ok := got["pending"]; !ok {
					t.Fatalf("%s discarded component before creation: %v", operation, got)
				}
				wantCount := 1
				if existing {
					wantCount++
					if got["ready"] != "gr-ready" {
						t.Fatal("existing component alias lost")
					}
				}
				if len(got) != wantCount {
					t.Fatalf("unexpected bindings: %v", got)
				}
				// Completing component creation must make the saved group discoverable,
				// without requiring the user to save the configuration group again.
				if err := database.Create(&dbmodel.TenantServices{ServiceID: "pending", ServiceAlias: "gr-pending", AppID: "app"}).Error; err != nil {
					t.Fatal(err)
				}
				groups, err := manager.AppConfigGroupDao().ListByServiceID("pending")
				if err != nil {
					t.Fatal(err)
				}
				if len(groups) != 1 || groups[0].ConfigGroupName != "java" {
					t.Fatalf("group missing after component creation: %v", groups)
				}
				for _, appID := range []string{"app", "other-app"} {
					if err := database.Model(&dbmodel.TenantServices{}).Where("service_id = ?", "pending").Update("app_id", appID).Error; err != nil {
						t.Fatal(err)
					}
					as := &v1.AppService{}
					as.ServiceID = "pending"
					as.AppID = appID
					as.SetTenant(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-team"}})
					if err := conversion.TenantServiceConfigGroup(as, manager); err != nil {
						t.Fatal(err)
					}
					secrets := as.GetEnvVarSecrets(false)
					if appID != "app" {
						if len(secrets) != 0 {
							t.Fatal("pending binding exposed configuration to another application")
						}
						continue
					}
					if len(secrets) != 1 || string(secrets[0].Data["APP_NAME"]) != "${_SERVICE_NAME}" {
						t.Fatalf("saved binding did not reach worker after component creation: %v", secrets)
					}
				}
				if _, err := action.UpdateConfigGroup("app", "java", &apimodel.UpdateAppConfigGroupReq{Enable: true, ConfigItems: items}); err != nil {
					t.Fatal(err)
				}
				bindings, err := manager.AppConfigGroupServiceDao().GetConfigGroupServicesByID("app", "java")
				if err != nil {
					t.Fatal(err)
				}
				if len(bindings) != 0 {
					t.Fatalf("clearing selection left stale pending bindings: %v", bindings)
				}

			})
		}
	}
}