- Add RemoveNamespace(ctx, ns) to executortype.ExecutorType interface - Implement RemoveNamespace in poolmgr, newdeploy, container executor types - Add per-namespace context cancellation (nsCancels map) in all three types so informer factories are stopped when namespace is removed (fixes goroutine leak) - Add PoolPodController.RemoveNamespace to clear envLister/podLister maps - Add deregisterNamespace() in executor multitenant subscriber - Switch executor/router/buildermgr watcher strategy from TrackOnly to DispatchRemove so RemoveFunc is called when fission.io/managed label is removed - Add RemoveFunc to executor/router/buildermgr namespace subscribers - Add RemoveNamespace to environmentWatcher and packageWatcher with per-NS cancel - Add RemoveNamespace to HTTPTriggerSet: cancels informers, removes from maps, calls syncTriggers - Fix ns_watcher_test.go fakeExecutorType to implement new RemoveNamespace method Fixes: - Executor dedup gap: re-added namespace was silently skipped (envLister/deplLister still present) - Goroutine/FD leak: old informer factories ran forever after namespace removal - Router stale routes: HTTPTriggers for removed namespace stayed in routing table
80 lines
3.0 KiB
Go
80 lines
3.0 KiB
Go
package multitenant
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"go.uber.org/zap"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
|
"github.com/fission/fission/pkg/executor/executortype"
|
|
"github.com/fission/fission/pkg/executor/fscache"
|
|
"github.com/fission/fission/pkg/utils/manager"
|
|
)
|
|
|
|
type fakeExecutorType struct {
|
|
addCalls int
|
|
lastNamespace string
|
|
addErr error
|
|
}
|
|
|
|
func (f *fakeExecutorType) Run(context.Context, manager.Interface) {}
|
|
func (f *fakeExecutorType) GetTypeName(context.Context) fv1.ExecutorType {
|
|
return fv1.ExecutorTypePoolmgr
|
|
}
|
|
func (f *fakeExecutorType) GetFuncSvc(context.Context, *fv1.Function) (*fscache.FuncSvc, error) {
|
|
return nil, nil
|
|
}
|
|
func (f *fakeExecutorType) GetFuncSvcFromCache(context.Context, *fv1.Function) (*fscache.FuncSvc, error) {
|
|
return nil, nil
|
|
}
|
|
func (f *fakeExecutorType) DumpDebugInfo(context.Context) error { return nil }
|
|
func (f *fakeExecutorType) DeleteFuncSvcFromCache(context.Context, *fscache.FuncSvc) {}
|
|
func (f *fakeExecutorType) TapService(context.Context, string) error { return nil }
|
|
func (f *fakeExecutorType) UnTapService(context.Context, *metav1.ObjectMeta, string) {}
|
|
func (f *fakeExecutorType) MarkSpecializationFailure(context.Context, *metav1.ObjectMeta) {}
|
|
func (f *fakeExecutorType) IsValid(context.Context, *fscache.FuncSvc) bool { return true }
|
|
func (f *fakeExecutorType) RefreshFuncPods(context.Context, *zap.Logger, fv1.Function) error {
|
|
return nil
|
|
}
|
|
func (f *fakeExecutorType) AdoptExistingResources(context.Context) {}
|
|
func (f *fakeExecutorType) CleanupOldExecutorObjects(context.Context) {}
|
|
func (f *fakeExecutorType) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) error {
|
|
f.addCalls++
|
|
f.lastNamespace = ns
|
|
return f.addErr
|
|
}
|
|
func (f *fakeExecutorType) RemoveNamespace(ctx context.Context, ns string) error { return nil }
|
|
|
|
var _ executortype.ExecutorType = (*fakeExecutorType)(nil)
|
|
|
|
func TestRegisterExecutorTypes(t *testing.T) {
|
|
poolmgr := &fakeExecutorType{}
|
|
container := &fakeExecutorType{}
|
|
err := registerExecutorTypes(context.Background(), zap.NewNop(), "tenant-executor-a", map[fv1.ExecutorType]executortype.ExecutorType{
|
|
fv1.ExecutorTypePoolmgr: poolmgr,
|
|
fv1.ExecutorTypeContainer: container,
|
|
}, nil)
|
|
if err != nil {
|
|
t.Fatalf("expected registration success: %v", err)
|
|
}
|
|
if poolmgr.addCalls != 1 || container.addCalls != 1 {
|
|
t.Fatalf("expected all executor types to receive AddNamespace")
|
|
}
|
|
}
|
|
|
|
func TestRegisterExecutorTypesAggregatesErrors(t *testing.T) {
|
|
err := registerExecutorTypes(context.Background(), zap.NewNop(), "tenant-executor-a", map[fv1.ExecutorType]executortype.ExecutorType{
|
|
fv1.ExecutorTypePoolmgr: &fakeExecutorType{addErr: errors.New("poolmgr failed")},
|
|
fv1.ExecutorTypeContainer: &fakeExecutorType{},
|
|
}, nil)
|
|
if err == nil {
|
|
t.Fatalf("expected aggregated error")
|
|
}
|
|
if err.Error() != "poolmgr failed" {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
}
|