一篇带你kubebuilder 进阶: 测试

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

[[399666]]

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

单元测试

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

  1. func TestNodePoolSpec_ApplyNode(t *testing.T) { 
  2.  type fields struct { 
  3.   Taints  []corev1.Taint 
  4.   Labels  map[string]string 
  5.   Handler string 
  6.  } 
  7.  type args struct { 
  8.   node v1.Node 
  9.  } 
  10.  tests := []struct { 
  11.   name   string 
  12.   fields fields 
  13.   args   args 
  14.   want   *corev1.Node 
  15.  }{ 
  16.   { 
  17.    name"label"
  18.    fields: fields{ 
  19.     Labels: map[string]string{ 
  20.      "node-pool.lailin.xyz/test"""
  21.     }, 
  22.    }, 
  23.    args: args{ 
  24.     node: v1.Node{ 
  25.      ObjectMeta: metav1.ObjectMeta{ 
  26.       Name"worker"
  27.       Labels: map[string]string{ 
  28.        "kubernetes.io/arch""amd64"
  29.        "a":                  "b"
  30.       }, 
  31.      }, 
  32.     }, 
  33.    }, 
  34.    want: &v1.Node{ 
  35.     ObjectMeta: metav1.ObjectMeta{ 
  36.      Name"worker"
  37.      Labels: map[string]string{ 
  38.       "kubernetes.io/arch":        "amd64"
  39.       "node-pool.lailin.xyz/test"""
  40.      }, 
  41.     }, 
  42.    }, 
  43.   }, 
  44.  } 
  45.  for _, tt := range tests { 
  46.   t.Run(tt.name, func(t *testing.T) { 
  47.    s := &NodePoolSpec{ 
  48.     Taints:  tt.fields.Taints, 
  49.     Labels:  tt.fields.Labels, 
  50.     Handler: tt.fields.Handler, 
  51.    } 
  52.    assert.Equal(t, tt.want, s.ApplyNode(tt.args.node)) 
  53.   }) 
  54.  } 

集成测试

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

envtest

一个 envtest 的简单例子如下

  1. import sigs.k8s.io/controller-runtime/pkg/envtest 
  2.  
  3. //指定 testEnv 配置 
  4. testEnv = &envtest.Environment{ 
  5.     CRDDirectoryPaths: []string{filepath.Join("..""config""crd""bases")}, 
  6.  
  7. //启动 testEnv 
  8. cfg, err = testEnv.Start() 
  9.  
  10. //编写测试逻辑 
  11.  
  12. //停止 testEnv 
  13. err = testEnv.Stop() 

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

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

编写测试

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

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

  1. controllers/suite_test.go 

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

使用 make test 执行测试

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

总结

今天这篇文章主要还是希望起一个抛砖引玉的作用,没有过多的去深入具体改如何写单元测试和集成测试,只是给了两个例子,关于集成测试如果感兴趣可以看看 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-05-20 06:57:16

RabbitMQ开源消息

2023-04-20 08:00:00

ES搜索引擎MySQL

2021-01-01 09:20:20

操作DjangoORM

2022-03-10 08:31:51

REST接口规范设计Restful架构

2022-02-24 07:56:42

开发Viteesbuild

2021-10-27 09:59:35

存储

2021-07-26 09:31:09

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

2023-02-28 23:04:15

2021-08-02 06:34:55

Redis删除策略开源

2021-11-24 08:51:32

Node.js监听函数

2021-11-08 08:42:44

CentOS Supervisor运维

2021-11-16 14:09:58

Containerd Dockerk8s

2021-12-15 11:52:34

GPLLinuxGNU

2023-04-21 08:11:54

KubernetesPod

2020-11-27 08:02:41

Promise

2021-05-17 09:50:06

Kubebuilde源码CURD
点赞
收藏

51CTO技术栈公众号