为了账号安全,请及时绑定邮箱和手机立即绑定

Kubernetes 假客户端不处理对象Meta中的生成名称

Kubernetes 假客户端不处理对象Meta中的生成名称

Go
拉风的咖菲猫 2022-09-19 21:10:40
当使用 Kubernetes 假客户端编写单元测试时,我注意到它无法创建两个相同的对象,这些对象将其 ObjectMeta.GenerateName 字段设置为某个字符串。真正的集群接受此规范,并为每个对象生成唯一的名称。运行以下测试代码:package mainimport (    "context"    "testing"    "github.com/stretchr/testify/assert"    corev1 "k8s.io/api/core/v1"    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"    "k8s.io/client-go/kubernetes/fake")func TestFake(t *testing.T) {    ctx := context.Background()    client := fake.NewSimpleClientset()    _, err := client.CoreV1().Secrets("default").Create(ctx, &corev1.Secret{        ObjectMeta: metav1.ObjectMeta{            GenerateName: "generated",        },        StringData: map[string]string{"foo": "bar"},    }, metav1.CreateOptions{})    assert.NoError(t, err)    _, err = client.CoreV1().Secrets("default").Create(ctx, &corev1.Secret{        ObjectMeta: metav1.ObjectMeta{            GenerateName: "generated",        },        StringData: map[string]string{"foo": "bar"},    }, metav1.CreateOptions{})    assert.NoError(t, err)}失败与--- FAIL: TestFake (0.00s)    /Users/mihaitodor/Projects/kubernetes/main_test.go:44:             Error Trace:    main_test.go:44            Error:          Received unexpected error:                            secrets "" already exists            Test:           TestFakeFAILFAIL    kubernetes  0.401sFAIL
查看完整描述

1 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

根据这个 GitHub 问题评论:

假客户端不会尝试复制服务器端行为,如验证,名称生成,uid分配等,如果你想测试这样的东西,你可以添加反应堆来模拟该行为。

要添加所需的反应器,我们可以在创建对象之前插入以下代码:corev1.Secret

client.PrependReactor(

    "create", "*",

    func(action k8sTesting.Action) (handled bool, ret runtime.Object, err error) {

        ret = action.(k8sTesting.CreateAction).GetObject()

        meta, ok := ret.(metav1.Object)

        if !ok {

            return

        }


        if meta.GetName() == "" && meta.GetGenerateName() != "" {

            meta.SetName(names.SimpleNameGenerator.GenerateName(meta.GetGenerateName()))

        }


        return

    },

)

那里有一些陷阱:

  • 包含一个嵌入式 Fake 结构,该结构具有我们需要为此用例调用的前置反应器方法(还有其他一些方法)。此处的此代码在创建此类对象时调用。Clientset

  • 该方法有 3 个参数:、和 。对于 ,我找不到任何命名常量,所以,在这种情况下,“创建”和“secrets”(奇怪的是它不是“秘密”)似乎是它们的正确值,如果我们想要超级具体,但在这种情况下设置为“*”应该是可以接受的。PrependReactorverbresourcereactionverbresourceresource

  • 该参数的类型为反应符,它将操作作为参数并返回 、 和 。经过一番挖掘,我注意到该参数将被转换为Creaction,它具有返回实例的方法,该实例可以转换为metav1。对象。此接口允许我们获取和设置基础对象的各种元数据字段。根据需要设置对象字段后,我们必须返回 ,并指示调用代码执行剩余的反应堆。reactionhandledreterractionGetObject()runtime.ObjectNamehandled = falseret = mutatedObjecterr = nil

  • 通过浏览代码,我注意到该字段是使用名称从字段生成的。简单名称生成器.生成名称实用程序。apiserverObjectMeta.NameObjectMeta.GenerateName


查看完整回答
反对 回复 2022-09-19
  • 1 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信