90 lines
2.4 KiB
Go
90 lines
2.4 KiB
Go
//go:build integration
|
||
|
||
package bootstrap
|
||
|
||
import (
|
||
"context"
|
||
"os"
|
||
"path/filepath"
|
||
"testing"
|
||
"time"
|
||
|
||
bao "github.com/openbao/openbao/api/v2"
|
||
|
||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||
)
|
||
|
||
func TestBootstrapWithRealAPIServer(t *testing.T) {
|
||
environment := &envtest.Environment{
|
||
CRDDirectoryPaths: []string{"../../config/crd/bases"},
|
||
ErrorIfCRDPathMissing: true,
|
||
}
|
||
config, err := environment.Start()
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
t.Cleanup(func() {
|
||
if err := environment.Stop(); err != nil {
|
||
t.Error(err)
|
||
}
|
||
})
|
||
user, err := environment.AddUser(envtest.User{Name: "bootstrap-fixture", Groups: []string{"system:masters"}}, config)
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
data, err := user.KubeConfig()
|
||
if err != nil {
|
||
t.Fatal("cannot generate isolated fixture kubeconfig")
|
||
}
|
||
// 仅写临时 envtest 身份,不读取现场 kubeconfig;t.TempDir 会自动清理。
|
||
path := filepath.Join(t.TempDir(), "kubeconfig")
|
||
if err := os.WriteFile(path, data, 0600); err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
t.Setenv("KUBECONFIG", path)
|
||
t.Setenv("POD_NAMESPACE", "")
|
||
options := parseTestOptions(t, "--metrics-bind-address=0", "--health-probe-bind-address=0", "--webhook-port=-1")
|
||
manager, err := newManager(options)
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
baoClient, err := setupOpenBaoAuthentication(manager, options.openBao)
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
ctx, cancel := context.WithTimeout(t.Context(), 30*time.Second)
|
||
defer cancel()
|
||
cleanup, err := setupDatabase(ctx, manager, options.database, baoClient)
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
defer cleanup()
|
||
// 空 API 中没有供应目标;此处验证启用路径确实注册 controller,不访问外部 Bao。
|
||
fixtureConfig := bao.NewConfig()
|
||
fixtureConfig.Address = "http://127.0.0.1:1"
|
||
fixtureClient, err := bao.NewClient(fixtureConfig)
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
options.database.credentialMount = "secret"
|
||
if err := setupCredentialPreparation(manager, options.database, fixtureClient); err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
done := make(chan error, 1)
|
||
go func() { done <- manager.Start(ctx) }()
|
||
defer func() {
|
||
cancel()
|
||
select {
|
||
case err := <-done:
|
||
if err != nil {
|
||
t.Error(err)
|
||
}
|
||
case <-time.After(20 * time.Second):
|
||
t.Error("manager did not stop before component cleanup")
|
||
}
|
||
}()
|
||
if !manager.GetCache().WaitForCacheSync(ctx) {
|
||
t.Fatal("assembled controller cache did not synchronize")
|
||
}
|
||
}
|