Go开发Kubernetes控制器:Result.RequeueAfter与envTest适配问题求助
解决Kubernetes控制器RequeueAfter替换Requeue后的envTest超时问题
将重试时间配置化
把原本硬编码的10秒重试时间改成可配置项,通过控制器构造参数或环境变量注入。生产环境用10秒,测试环境直接设为1秒以内,让测试里的Eventually()(2秒超时)能捕获到重试后的状态。示例代码:
type MyReconciler struct { client.Client Scheme *runtime.Scheme requeueAfter time.Duration // 可配置的重试时间 } // 初始化时传入参数,生产环境传10*time.Second,测试环境传1*time.Second func NewMyReconciler(client client.Client, scheme *runtime.Scheme, requeueAfter time.Duration) *MyReconciler { return &MyReconciler{ Client: client, Scheme: scheme, requeueAfter: requeueAfter, } } // Reconcile逻辑中使用配置的重试时间 func (r *MyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { // ... 业务逻辑处理 ... return ctrl.Result{RequeueAfter: r.requeueAfter}, nil }测试中Mock外部系统状态
如果控制器重试是因为等待外部系统就绪,就用接口抽象外部系统调用,测试时用Mock实现直接返回预期状态,让控制器一次Reconcile就能完成,无需依赖RequeueAfter等待。示例代码:
// 定义外部系统交互接口 type ExternalSystem interface { IsResourceReady(resourceID string) (bool, error) } // 生产环境实现 type RealExternalSystem struct{} func (r *RealExternalSystem) IsResourceReady(resourceID string) (bool, error) { // 实际调用外部系统的逻辑 } // 测试用Mock实现 type MockExternalSystem struct { isReady bool } func (m *MockExternalSystem) IsResourceReady(resourceID string) (bool, error) { return m.isReady, nil } // 控制器依赖注入该接口 type MyReconciler struct { client.Client Scheme *runtime.Scheme ExternalSys ExternalSystem requeueAfter time.Duration } // 测试时设置Mock为就绪状态,跳过重试逻辑 func TestMyReconciler(t *testing.T) { mockSys := &MockExternalSystem{isReady: true} reconciler := NewMyReconciler(client, scheme, 10*time.Second) reconciler.ExternalSys = mockSys // ... 执行测试逻辑 ... }临时调整测试超时(可选)
若不想修改控制器代码,可临时把测试里的Eventually()超时时间设为11秒,但这会增加测试耗时。更推荐结合配置化方案,测试用短重试时间,既能保证测试通过,又不拉长测试时长。
内容的提问来源于stack exchange,提问作者guettli
相关产品推荐
相关产品推荐

