一篇带你kubebuilder 进阶: 测试

开发 项目管理
今天我们大概看一下单元测试和集成测试怎么做。单元测试和 golang 的单元测试没有什么太大的区别,一般可以通过单元测试搞定的首先使用单元测试,因为单元测试写起来最容易。

[[399666]]

Operator 的测试是一个比较头疼的问题,在 kubernetes 资源是在不断变化的,并且想要在测试的时候跑一整套的 kubernetes 环境也不是一件容易的事情,今天我们大概看一下单元测试和集成测试怎么做。

单元测试

单元测试和 golang 的单元测试没有什么太大的区别,一般可以通过单元测试搞定的首先使用单元测试,因为单元测试写起来最容易,例如下面这一段对节点标签更新逻辑进行测试

func TestNodePoolSpec_ApplyNode(t *testing.T) { 
 type fields struct { 
  Taints  []corev1.Taint 
  Labels  map[string]string 
  Handler string 
 } 
 type args struct { 
  node v1.Node 
 } 
 tests := []struct { 
  name   string 
  fields fields 
  args   args 
  want   *corev1.Node 
 }{ 
  { 
   name"label"
   fields: fields{ 
    Labels: map[string]string{ 
     "node-pool.lailin.xyz/test"""
    }, 
   }, 
   args: args{ 
    node: v1.Node{ 
     ObjectMeta: metav1.ObjectMeta{ 
      Name"worker"
      Labels: map[string]string{ 
       "kubernetes.io/arch""amd64"
       "a":                  "b"
      }, 
     }, 
    }, 
   }, 
   want: &v1.Node{ 
    ObjectMeta: metav1.ObjectMeta{ 
     Name"worker"
     Labels: map[string]string{ 
      "kubernetes.io/arch":        "amd64"
      "node-pool.lailin.xyz/test"""
     }, 
    }, 
   }, 
  }, 
 } 
 for _, tt := range tests { 
  t.Run(tt.name, func(t *testing.T) { 
   s := &NodePoolSpec{ 
    Taints:  tt.fields.Taints, 
    Labels:  tt.fields.Labels, 
    Handler: tt.fields.Handler, 
   } 
   assert.Equal(t, tt.want, s.ApplyNode(tt.args.node)) 
  }) 
 } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.

集成测试

controller-runtime 提供 envtest ,这个包可以帮助你为你在 etcd 和 Kubernetes API server 中设置并启动的 controllers 实例来写集成测试,不需要 kubelet,controller-manager 或者其他组件。

envtest

一个 envtest 的简单例子如下

import sigs.k8s.io/controller-runtime/pkg/envtest 
 
//指定 testEnv 配置 
testEnv = &envtest.Environment{ 
    CRDDirectoryPaths: []string{filepath.Join("..""config""crd""bases")}, 

 
//启动 testEnv 
cfg, err = testEnv.Start() 
 
//编写测试逻辑 
 
//停止 testEnv 
err = testEnv.Stop() 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

envtest 在启动的时候需要设置一些环境变量来说明我们使用什么控制平面来进行测试

  • USE_EXISTING_CLUSTER表示使用一个已经存在的控制平面
  • KUBEBUILDER_ASSETS 本地控制平面二进制文件的文件夹路径,里面包含了 kubectl apiserver和 etcd
  • KUBEBUILDER_CONTROLPLANE_START_TIMEOUT控制平面启动的超时时间
  • KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT控制平面停止的超时时间

编写测试

kubebuilder 在生成代码的时候已经帮我们生成好了相关的脚手架,已经环境配置,我们只需要写具体的测试逻辑就行了

下面我们就以创建一个 NodePool 为例子看看集成测试怎么写

controllers/suite_test.go 
  • 1.
var _ = Describe("node labels", func() { 
 pool := &nodesv1.NodePool{ 
  ObjectMeta: metav1.ObjectMeta{ 
   Name"test"
  }, 
  Spec: nodesv1.NodePoolSpec{ 
   Labels: map[string]string{ 
    "node-pool.lailin.xyz/xxx"""
   }, 
   Handler: ""
  }, 
 } 
 
 It("create pool", func() { 
  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second
  defer cancel() 
  err := k8sClient.Create(ctx, pool) 
  Expect(err).NotTo(HaveOccurred()) 
 }) 
}) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

使用 make test 执行测试

Using cached envtest tools from blog-code/k8s-operator/07-node-pool-operator/testbin 
setting up env vars 
?       github.com/mohuishou/blog-code/k8s-operator/node-pool-operator  [no test files] 
ok      github.com/mohuishou/blog-code/k8s-operator/node-pool-operator/api/v1   9.403s  coverage: 24.5% of statements 
ok      github.com/mohuishou/blog-code/k8s-operator/node-pool-operator/controllers      10.390s coverage: 0.0% of statements 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

总结

今天这篇文章主要还是希望起一个抛砖引玉的作用,没有过多的去深入具体改如何写单元测试和集成测试,只是给了两个例子,关于集成测试如果感兴趣可以看看 https://onsi.github.io/ginkgo 和 envtest 的相关文档。

对于 Operator 来说建议能写单元测试的还是写单元测试,能够本地写集成测试的就写集成测试这样我们在实际上线的时候就会减少 bug 的概率,因为相对于业务代码来说 Operator 的测试实在是比较麻烦,对于测试同学的要求也比较高,一不小心就有可能遗漏一些问题。

 

责任编辑:姜华 来源: mohuishou
相关推荐

2021-05-18 05:40:27

kubebuilderwebhook进阶

2021-05-12 06:18:19

KubeBuilderOperatork8s

2021-05-16 10:52:58

kubebuilderstatus event

2021-05-08 09:02:48

KubeBuilderOperatork8s

2021-01-01 09:20:20

操作DjangoORM

2021-05-20 06:57:16

RabbitMQ开源消息

2023-04-20 08:00:00

ES搜索引擎MySQL

2021-07-26 09:31:09

自动化测试编程语言手机编程

2021-06-16 08:28:25

unary 方法函数技术

2022-03-10 08:31:51

REST接口规范设计Restful架构

2025-01-17 07:00:00

2022-02-24 07:56:42

开发Viteesbuild

2021-10-27 09:59:35

存储

2021-07-28 10:02:54

建造者模式代码

2022-02-21 09:44:45

Git开源分布式

2023-05-12 08:19:12

Netty程序框架

2022-04-08 08:32:40

mobx状态管理库redux

2021-07-14 08:24:23

TCPIP 通信协议

2021-06-30 00:20:12

Hangfire.NET平台

2021-08-11 07:02:21

npm包管理器工具
点赞
收藏

51CTO技术栈公众号