繁体   English   中英

为休息映射器 k8s 创建假数据

[英]Create fake data for rest mapper k8s

我运行以下代码,该代码在提供 kubeconfig 时有效,我能够获得“gr”的值

func (o *ApplyOptions) RestMapper() (meta.RESTMapper, error) {
    gr, err := restmapper.GetAPIGroupResources(o.discoveryClient)
    if err != nil {
        return nil, err
    }
    mapper := restmapper.NewDiscoveryRESTMapper(gr)
    return mapper, nil
}

我用下面的代码启动了它

var kubeconfig *string

kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")

flag.Parse()

// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
    panic(err.Error())
}

dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
    panic(err.Error())
}
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
    panic(err.Error())
}

applyOptions := apply.NewApplyOptions(dynamicClient, discoveryClient)
if err := applyOptions.Apply(context.Background(), []byte(applyStr)); err != nil {
    log.Fatalf("apply error: %v", err)
}

现在我将它用于单元测试,并且在调试它时我得到了上面的gr空(来自restmapper.GetAPIGroupResources(o.discoveryClient) ),我如何添加一些假以使其在测试中也能正常工作?

var _ = DescribeTable(“test”, func(applyOptions *ApplyOptions, filename string, isExpectedErr bool, expectedErrMsg string) {


    applyOptions = ApplyOptions{
        discoveryClient: clientset.Discovery() ,
        //discoveryClient: &k8sfake.Clientset,
        dynamicClient:   dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()),

    }

   // Here I need to initiate some fake data
    restmapper, err := applyOptions.RestMapper()
    if err != nil {
        Fail(err.Error())
    }

我得到的错误是“ k8s.io/apimachinery/pkg/api/meta.NoKindMatchError

更新

为了更清楚,我只是尝试使用kind: deployment为这个函数创建一个单元测试,我得到了上面的错误。

https://github.com/pytimer/k8sutil/blob/main/apply/apply.go#L119

一种可能的方法是将restmapper抽象出来,这将使ApplyOptions依赖于抽象,因此您可以模拟它。 假设你是单元测试。

我们可以把它叫做RESTMapperDiscovery这个类型将封装restmapper通过使用功能ApplyOptions 它基本上是一个包装器。

type RESTMapperDiscovery struct {}
func (RESTMapperDiscovery) FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error)

FromGroupResources将具体实现func (o *ApplyOptions) RestMapper()当前部分的代码。

为了实现多态,我们只需要一个接口。

type DiscoveryRESTMapper interface {
    FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error)
}

在这个阶段ApplyOptions也将依赖DiscoveryRESTMapper

type ApplyOptions struct {
    //... other fields
    restMapper DiscoveryRESTMapper
}
func (o *ApplyOptions) RestMapper() (meta.RESTMapper, error) {
    return o.restMapper.FromGroupResources(o.discoveryClient)
}

测试时,您可以使用满足该接口的类型并返回一些假数据。 meta.RESTMapper也是一个接口,你的假数据必须实现。

type mockRESTMapper struct {}
func (mockRESTMapper) FromGroupResources(cl discovery.DiscoveryInterface) (meta.RESTMapper, error) {
    // return the fake meta.RESTMapper
}

applyOptions = &ApplyOptions{
    discoveryClient: clientset.Discovery() ,
    dynamicClient:   dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()),
    restMapper: mockRESTMapper{},

}

// here you have the fake data
restmapper, err := applyOptions.RestMapper()
if err != nil {
    Fail(err.Error())
}

这种方法依赖于组合和接口来解耦外部依赖。 作为restmapper k8s apis 似乎依赖于相同的机制,因此您也可以从ApplyOptions的当前依赖项中模拟所有这些。 这里的权衡是您的解决方案与 k8s api 紧密耦合,这可能会导致restmapper版本和/或维护负担的中断更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM