api/handler/cleanup_service_mesh_test.go
Rama main · réplica de lectura del repositorio original.
package handler
import (
"errors"
"testing"
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/model"
guard "github.com/goodrain/rainbond/pkg/cleanup"
"k8s.io/apimachinery/pkg/runtime"
dynamicfake "k8s.io/client-go/dynamic/fake"
ktesting "k8s.io/client-go/testing"
)
type meshTenantFixture struct{ TenantHandler }
func (meshTenantFixture) GetTenantsByUUID(string) (*model.Tenants, error) {
return &model.Tenants{Namespace: "team"}, nil
}
// capability_id: rainbond.cleanup.service-mesh-mutation-admission
func TestServiceMeshMutationsHoldCleanupAdmission(t *testing.T) {
for _, method := range []string{"create", "update"} {
for _, scenario := range []string{"blocked", "success", "uncertain", "draining", "db-failed"} {
t.Run(method+"/"+scenario, func(t *testing.T) {
oldTenant := defaultTenantHandler
defaultTenantHandler = meshTenantFixture{}
defer func() { defaultTenantHandler = oldTenant }()
database := namespaceAdmissionDB(t)
if err := database.AutoMigrate(&model.K8sResource{}).Error; err != nil {
t.Fatal(err)
}
old := db.GetManager()
db.SetTestManager(testManager{Manager: workloadTestManager{database: database}, tenantDao: &testTenantDao{tenant: &model.Tenants{Namespace: "team"}}})
defer db.SetTestManager(old)
app := &model.Application{AppID: "application", K8sApp: "app", TenantID: "tenant"}
if method == "update" {
if err := database.Create(&model.K8sResource{AppID: app.AppID, Name: app.K8sApp, Kind: "ServiceMesh", Content: "old"}).Error; err != nil {
t.Fatal(err)
}
}
deletion := guard.CoordinationRequest{StorageID: "store", Generation: "one", OperationID: "selected", Owner: "test", Kind: "delete", Scope: "app", Target: "manifest", Fingerprint: "selection"}
if scenario == "blocked" {
if _, err := guard.AcquireOperation(database, deletion); err != nil {
t.Fatal(err)
}
}
client := dynamicfake.NewSimpleDynamicClient(runtime.NewScheme())
calls := 0
for _, verb := range []string{"create", "update"} {
client.PrependReactor(verb, "servicemeshes", func(ktesting.Action) (bool, runtime.Object, error) {
calls++
if _, err := guard.AcquireOperation(database, deletion); err != guard.ErrCoordinationBusy {
t.Error("CR mutation outside producer admission", err)
}
if scenario == "uncertain" {
return true, nil, errors.New("lost response")
}
if scenario == "draining" && calls == 1 {
gc := guard.CoordinationRequest{StorageID: "store", Generation: "one", OperationID: "gc", Owner: "test", Kind: "gc", Scope: "*", Fingerprint: "manual"}
if _, err := guard.RequestMaintenance(database, gc); err != nil {
t.Fatal(err)
}
}
if scenario == "db-failed" && calls == 1 {
if err := database.DropTable(&model.K8sResource{}).Error; err != nil {
t.Fatal(err)
}
}
return false, nil, nil
})
}
handler := &ApplicationAction{dynamicClient: client}
var err error
if method == "create" {
_, err = handler.CreateServiceMeshCR(app, "native")
} else {
_, err = handler.UpdateServiceMeshCR(app, "native")
}
if scenario == "blocked" {
if calls != 0 || err == nil {
t.Fatal("cleanup did not block CR mutation", calls, err)
}
return
}
if scenario == "uncertain" || scenario == "db-failed" {
if err == nil {
t.Fatal("lost response accepted")
}
} else if err != nil {
t.Fatal(err)
}
var producers []model.CleanupOperation
if err := database.Where("kind = ?", "producer").Find(&producers).Error; err != nil {
t.Fatal(err)
}
expected := "finished"
if scenario == "uncertain" || scenario == "db-failed" {
expected = "uncertain"
}
if len(producers) != 1 || producers[0].State != expected {
t.Fatal("incorrect original producer outcome", producers)
}
})
}
}
}