写点什么

如何为服务网格做端到端测试

作者:Flomesh
  • 2022 年 5 月 23 日
  • 本文字数:4226 字

    阅读完需:约 14 分钟

如何为服务网格做端到端测试

在前面的文章中详细解读了 SMI 规范,以及我们引入可编程代理 Pipy 对 OSM 进行扩展。在替换了 sidecar 代理之后,不能影响服务网格已有的功能。OSM 代码库中有提供端到端的测试用例,我们通过其来验证以 Pipy 为代理的 OSM 的各项功能。


阅读本文您将收获:


  • 端到端测试的介绍

  • 服务网格端到端测试的关注点

  • 借助测试深入了解 SMI 规范

端到端测试

什么是端到端测试

端到端测试(End-to-End Testing,e2e testing) 是软件的一种测试方法,通过模拟真实用户场景来测试和验证系统及其集成和数据完整性组件。通过从头到尾(执行产品所有可以完成的操作)对整个软件产品的测试,确保应用按预期运行。


如今的软件系统很复杂,与众多的子系统相互连接。比如 Kubernetes 中的多个组件共同完成对象真实状态与期望状态相匹配。

端到端测试的好处

由于以下好处,使得端到端测试被广泛采用:


  • 扩大测试覆盖率

  • 确保应用程序的正确性

  • 所选发布时间

  • 降低成本

  • 检测错误

端到端测试的步骤

  1. 分析需求,清楚了解应用的各方面如何工作

  2. 根据需求设置测试环境

  3. 分析硬件和软件需求

  4. 列出每个系统的期望响应

  5. 列出测试这些响应的测试方法

  6. 设计测试用例

  7. 运行测试和保存结果

服务网格的端到端测试

OSM 运行在 Kubernetes 之上,实现了 SMI API 还有自定义的 API,比如 IngressBackendEgressUpstreamTrafficSetting。测试时要覆盖功能性的测试,对这些 API 进行一一的测试,以及不同网格配置对功能的影响;同时还会有非功能性的测试,测试网格的容错性、可替换组件等等。


下面列出非功能性测试和功能性测试的部分测试用例,并进行说明。

非功能性测试

  • 测试使用不同的证书管理器实现:cert-manager、Vault

  • 测试控制面重启对数据面的影响

  • 控制面配置:动态修改网格的 enableDebugServer 配置,测试能否开启控制面的 debug 端口

  • 控制面配置:动态修改网格的 enableEgress 配置,检查 egress 流量

  • 控制面配置:开启/关闭宽松模式的影响

  • 控制平面的升级对系统的影响

  • 对 Kubernetes 版本的检查和支持

  • ......

功能性测试

访问控制

tests/e2e/e2e_deployment_client_server_test.go 中模拟了多个 Deployment 作为客户端,配合 TrafficTarget 来访问同一个目标服务。


下面访问策略中配置了源服务和目标服务的 service account,同时通过 HTTPRouteGroup 的流量规格匹配所有的 HTTP 请求。在测试用例中,每个客户端(Deployment)都使用各自的 service account 进行部署,并配置独立的 TrafficTarget


apiVersion: specs.smi-spec.io/v1alpha4kind: HTTPRouteGroupmetadata:  name: client4  namespace: serverspec:  matches:  - methods:    - '*'    name: all    pathRegex: .*---apiVersion: access.smi-spec.io/v1alpha3kind: TrafficTargetmetadata:  name: client4  namespace: serverspec:  destination:    kind: ServiceAccount    name: server    namespace: server  rules:  - kind: HTTPRouteGroup    matches:    - all    name: client4  sources:  - kind: ServiceAccount    name: client4    namespace: client4    
复制代码

流量分流

tests/e2e/e2e_trafficsplit_test.go 中一共包含了三个测试用例,使用同样的分流策略进行验证:


apiVersion: split.smi-spec.io/v1alpha2kind: TrafficSplitmetadata:  creationTimestamp: "2022-05-19T08:20:20Z"  generation: 1  name: traffic-split  namespace: server  resourceVersion: "1797"  uid: db28de4b-3088-4377-90cd-775574afb876spec:  backends:  - service: server0    weight: 20  - service: server1    weight: 20  - service: server2    weight: 20  - service: server3    weight: 20  - service: server4    weight: 20  service: traffic-split
复制代码


a. 禁用宽松模式(网格配置 enablePermissiveTrafficPolicyMode 为 false)下,添加访问策略 TrafficTarget,以及分流策略 TrafficSplit 后,服务的所有后端实例(通过 TrafficSplit.Spec.Backends 指定)都可以提供 HTTP 服务,完成 HTTP 流量的分流。


apiVersion: access.smi-spec.io/v1alpha3kind: TrafficTargetmetadata:  name: client0-server4  namespace: serverspec:  destination:    kind: ServiceAccount    name: server4    namespace: server  rules:  - kind: HTTPRouteGroup    matches:    - all    name: client0-server4  sources:  - kind: ServiceAccount    name: client0    namespace: client0---     apiVersion: specs.smi-spec.io/v1alpha4kind: HTTPRouteGroupmetadata:  name: client1-server4  namespace: serverspec:  matches:  - methods:    - '*'    name: all    pathRegex: .*
复制代码


b. 同样是禁用宽松模式,对于 TCP 的流量需要配置 TCP 的访问控制策略(通过 TCPRoute 匹配目标服务的端口来匹配)。


apiVersion: access.smi-spec.io/v1alpha3kind: TrafficTargetmetadata:  creationTimestamp: "2022-05-19T08:26:31Z"  generation: 1  name: client1-server4  namespace: server  resourceVersion: "5337"  uid: ae1662a1-1abb-4f9b-90f0-3fb5b42d6af1spec:  destination:    kind: ServiceAccount    name: server4    namespace: server  rules:  - kind: TCPRoute    name: client1-server4  sources:  - kind: ServiceAccount    name: client1    namespace: client1---apiVersion: specs.smi-spec.io/v1alpha4kind: TCPRoutemetadata:  name: client1-server4  namespace: serverspec:  matches:    ports:    - 14001
复制代码


c. 在宽松模式下,只需配置 TrafficSplit 即可实现流量分流,而无需设置 TrafficTarget

Ingress

tests/e2e/e2e_ingressbackend.go 中,验证在只有 Ingress 的情况下,是无法访问到目标服务的。只有在添加了从(src)Ingress 到(dst)目标服务的 IngressBackend 之后才会允许访问,否则会被 backend 服务拒绝。


apiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: service-dede0003-31db-49fe-ad90-6e2c8d1f6e1a  namespace: server-d71ba86b-eebc-44ff-90d3-109a3ab0f08bspec:  ingressClassName: nginx  rules:  - http:      paths:      - backend:          service:            name: service-dede0003-31db-49fe-ad90-6e2c8d1f6e1a            port:              number: 80        path: /status/200        pathType: ImplementationSpecific---apiVersion: policy.openservicemesh.io/v1alpha1kind: IngressBackendmetadata:  name: httpbin-http  namespace: server-d71ba86b-eebc-44ff-90d3-109a3ab0f08bspec:  backends:  - name: service-dede0003-31db-49fe-ad90-6e2c8d1f6e1a    port:       protocol: http      number: 80  sources:           - kind: Service    name: ingress-nginx-controller    namespace: ingress-ns
复制代码

Egress

tests/e2e/e2e_egress_policy_test.go 中对 Egress 的功能进行的测试。下面的策略中配置 Egress 访问策略的使用范围:


  • 使用指定 service account 部署的源服务

  • 访问目标的 hosthttpbin.org

  • 访问目标的端口为 80,且是 HTTP 协议

  • 满足 httpbin-status 中的流量匹配条件,即访问的路径是 /status


因此访问 http://httpbin.org:80/status/200 的请求是被允许的,而访问 https://httpbin.org:443/status/403 的请求被拒绝。


apiVersion: specs.smi-spec.io/v1alpha4kind: HTTPRouteGroupmetadata:  name: httpbin-status  namespace: clientspec:  matches:  - name: status    pathRegex: /status.*---apiVersion: policy.openservicemesh.io/v1alpha1kind: Egressmetadata:  name: httpbin-80  namespace: clientspec:  hosts:  - httpbin.org  matches:  - apiGroup: specs.smi-spec.io/v1alpha4    kind: HTTPRouteGroup    name: httpbin-status  ports:  - number: 80    protocol: http  sources:  - kind: ServiceAccount    name: serviceaccount-435e6b64-43e2-4095-988e-fad107a65304    namespace: client    
复制代码

实施

OSM 中使用 Ginkgo 作为测试框架。Ginkgo 是个为 Go 设计的 BDD 风格的测试框架,可与匹配器 Gomega 配合使用,帮助开发人员编写富有表现力的全方位测试。


  • 在每一个用例开始时,都要进行环境的初始化,保证各个测试用例的独立性;同样,在测试结束都要对数据进行清理,防止影响后续的测试。

  • 用例中的每一步操作,比如启动集群、创建 Deployment、模拟请求的结果等,都要对操作的结果借助 Gomega 进行断言。


接下来,我们看下如何为 Flomesh OSM 执行 e2e 测试。

操作

下面的步骤展示了从克隆源码到执行 e2e 测试的整个流程,运行环境:


  • Ubuntu 20.04

  • Go 1.17


下载源码:


$ git clone https://github.com/flomesh-io/osm.git -b v1.1.0-arm
复制代码


安装环境:Docker、K8s、Go 等:


$ cd osm/pipy/#安装docker和k8s工具等基础环境$ make k8s-tools #安装golang$ make golang 
复制代码


初始化 osm 的编译环境,并缓存依赖的镜像。


#初始化osm编译环境,只需执行一次$ make once #缓存相关依赖的镜像$ make cache 
复制代码


将 OSM 的 sidecar 镜像替换为 Pipy,并构建 OSM 组件镜像和 CLI:


#将sidecar切换为pipy$ make pipy #编译osm的images和cli$ make build #无需在 e2e 中再次构建镜像$ make disable-test-e2e-docker-build 
复制代码


回到项目根目录,使用 kind 创建集群:


$ cd ../# 使用 kind 创建集群,测试结束后通过 make kind-reset 销毁集群$ make kind-up# 设置节点可以调度 ingress$ kubectl label node osm-worker ingress-ready=true
复制代码


接下来就可以运行测试用例了,由于 Pipy 在本月底(5 月)支持 HTTP/2 以及不需要 WASM 来对 sidecar 进行扩展,如果直接执行命令 make test-e2e,相关的测试会失败。这时我们可以通过指定用例来逐个运行:


E2E_FLAGS="xxxx" make test-e2e
复制代码


在 wiki E2E TEST REPORT 中,可以下载完整的测试报告,从中可以找到用例的名字来手动运行测试。

总结

相信通过本文您应该对服务网格的端到端测试有一定的了解。当前 OSM 一共有 50 多个测试用例,但是对于复杂的服务网格系统来说,不一定能覆盖所有的功能场景(比如上面提到的 UpstreamTrafficSetting API),这也是端到端测试需要不断完善以增加覆盖率的原因。

发布于: 刚刚阅读数: 2
用户头像

Flomesh

关注

微信订阅号:flomesh 2022.04.07 加入

一站式云原生应用流量管理供应商 官网:https://flomesh.io

评论

发布
暂无评论
如何为服务网格做端到端测试_测试_Flomesh_InfoQ写作社区