test: add integration test for NSWatcher with fake Kubernetes client
TestStartManagedNamespaceWatcherIntegration проверяет полный маршрут горячей регистрации namespace без real cluster: 1. RunManagedNamespaceWatcher запускается с k8sfake.NewSimpleClientset() 2. В fake client создаётся Namespace с label fission.io/managed=true 3. Kubernetes informer детектирует событие (без polling, через Watch) 4. SubscriberFuncs.OnNamespaceAdd вызывается 5. NamespaceManager содержит запись со статусом Active Тест доказывает, что вся цепочка fake k8s event → informer → AddFunc → subscriber → manager работает корректно без rolling restart процесса. Также добавлен import metav1 в test file (требовался для CreateOptions).
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zaptest/observer"
|
"go.uber.org/zap/zaptest/observer"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
k8sfake "k8s.io/client-go/kubernetes/fake"
|
k8sfake "k8s.io/client-go/kubernetes/fake"
|
||||||
k8sCache "k8s.io/client-go/tools/cache"
|
k8sCache "k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
@@ -818,6 +819,76 @@ func TestNamespaceManagerDispatchRemoveFailure(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestStartManagedNamespaceWatcherIntegration проверяет полный маршрут:
|
||||||
|
// fake k8s client → информер → AddFunc → subscriber.OnNamespaceAdd.
|
||||||
|
// Это интеграционный тест без real cluster — использует k8sfake.
|
||||||
|
func TestStartManagedNamespaceWatcherIntegration(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
fakeClient := k8sfake.NewSimpleClientset()
|
||||||
|
mgr := managerPkg.New()
|
||||||
|
router := &testNamespaceSubscriber{name: "router"}
|
||||||
|
|
||||||
|
// Запускаем watcher — не Bootstrap, только informer.
|
||||||
|
// config.Namespaces пусто, чтобы не было pre-loaded namespace-ов.
|
||||||
|
manager, err := RunManagedNamespaceWatcher(ctx, zap.NewNop(), fakeClient, mgr, ManagedNamespaceWatcherConfig{
|
||||||
|
Component: "router.NSWatcher",
|
||||||
|
Namespaces: nil,
|
||||||
|
RemovalStrategy: NamespaceRemovalStrategyTrackOnly,
|
||||||
|
Subscriber: router,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("RunManagedNamespaceWatcher failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создаём namespace с managed label в fake client.
|
||||||
|
ns := &corev1.Namespace{}
|
||||||
|
ns.Name = "tenant-integration-a"
|
||||||
|
ns.Labels = map[string]string{ManagedNamespaceLabelKey: ManagedNamespaceLabelValue}
|
||||||
|
if _, err := fakeClient.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}); err != nil {
|
||||||
|
t.Fatalf("failed to create test namespace in fake client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ждём, пока informer обработает event и subscriber получит вызов.
|
||||||
|
// Timeout намеренно короткий (3 секунды) — fake client синхронный.
|
||||||
|
deadline := time.Now().Add(3 * time.Second)
|
||||||
|
for time.Now().Before(deadline) {
|
||||||
|
if router.addCalls >= 1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
if router.addCalls == 0 {
|
||||||
|
t.Fatalf("expected subscriber.OnNamespaceAdd to be called after namespace creation, got 0 calls")
|
||||||
|
}
|
||||||
|
if router.addCalls != 1 {
|
||||||
|
t.Fatalf("expected exactly 1 add call (namespace is new), got %d", router.addCalls)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Namespace должен быть в manager snapshot.
|
||||||
|
snapshot := manager.Snapshot()
|
||||||
|
found := false
|
||||||
|
for _, name := range snapshot {
|
||||||
|
if name == ns.Name {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Fatalf("expected %s in manager snapshot after informer event, got %v", ns.Name, snapshot)
|
||||||
|
}
|
||||||
|
|
||||||
|
record, ok := manager.Get(ns.Name)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected record for %s in manager", ns.Name)
|
||||||
|
}
|
||||||
|
if record.Phase != NamespacePhaseActive {
|
||||||
|
t.Fatalf("expected active phase after informer add, got %s", record.Phase)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNamespaceSubscriberFuncs(t *testing.T) {
|
func TestNamespaceSubscriberFuncs(t *testing.T) {
|
||||||
addCalls := 0
|
addCalls := 0
|
||||||
removeCalls := 0
|
removeCalls := 0
|
||||||
|
|||||||
Reference in New Issue
Block a user