docker-compose启动微型集群获取集成测试代码覆盖率

目录

一、项目目录结构

二、docker-compose启动微型集群

1./compose/basic目录下的docker-compose.yml文件内容

2./compose/project-root目录下的docker-compose.yml文件内容

三、portainer配置可视化界面

四、执行测试用例获取测试覆盖率

五、Jenkins日常发布测试用例&服务

六、问题描述及解决方式

七、docker基础知识总结


前言:

最终方案:

步骤一:物理机上安装docker

步骤二:用docker-compose启动一个最小版本的集群,包含paas服务、hpc上的存储和计算服务以及hpc调度器 

步骤三:修改步骤二对应的服务的配置文件和数据库的配置等 

步骤四:docker-compose up -d启动所有服务

步骤五:Jenkins自动化执行测试用例流水线配置,解决脚本报错问题

步骤六:配置Jenkins自动化获取代码覆盖率流水线并运行测试环境

步骤七:通过流水线创建固定文件夹,存放生成的覆盖率HTML文件

步骤八:获取代码覆盖率并不断优化已有代码,提升覆盖率

步骤九:docker-compose down关闭所有服务


一、项目目录结构

/basic用于存放各种基础配置

/code目录下存放仓库代码

/conf目录下存放流水线执行需要的各种配置文件

/data目录下用于存放storage数据

/project-root项目目录下存放各个服务,每个服务单独目录下存放

/portainer目录下存放相关配置,用于单独起一个可视化界面

/tools目录下存放需要的工具


二、docker-compose启动微型集群

上面的项目目录结构已经非常清晰啦~

1./compose/basic目录下的docker-compose.yml文件内容

version: '3.0'
services:
  mysql:
    image: mysql:5.7
    container_name: mysql_compose
    ports:
      - "33306:3306"
    environment:
      MYSQL_DATABASE: 'mydatabase'
      MYSQL_USER: 'mysql'
      MYSQL_PASSWORD: 'mysql123'
      MYSQL_ROOT_PASSWORD: 'rootmysql'
    volumes:
      - mysql_data:/var/lib/mysql

  redis:
    image: "redis:alpine"
    container_name: redis_compose
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
  etcd:
    image: quay.io/coreos/etcd:v3.4.15
    container_name: etcd_compose
    environment:
      ETCDCTL_API: "3"
    command:
      - /usr/local/bin/etcd
      - --data-dir=/etcd-data
      - --name=node1
      - --initial-advertise-peer-urls=http://0.0.0.0:2380
      - --listen-peer-urls=http://0.0.0.0:2380
      - --advertise-client-urls=http://0.0.0.0:2379
      - --listen-client-urls=http://0.0.0.0:2379
      - --initial-cluster=node1=http://0.0.0.0:2380
    ports:
      - "2379:2379"
      - "2380:2380"
    volumes:
      - etcd_data:/etcd-data

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
    ports:
      - "9200:9200"

  kibana:
    image: docker.elastic.co/kibana/kibana:7.14.0
    container_name: kibana
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

  apm-server:
    image: docker.elastic.co/apm/apm-server:7.14.0
    container_name: apm-server
    depends_on:
      - elasticsearch
    ports:
      - "8200:8200"
    environment:
      - output.elasticsearch.hosts=["elasticsearch:9200"]

  zookeeper:
    image: 'bitnami/zookeeper:latest'
    container_name: zookeeper
    ports:
      - '2181:2181'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes

  kafka:
    image: 'bitnami/kafka:latest'
    container_name: kafka
    ports:
      - '9092:9092'
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_LISTENERS=PLAINTEXT://:9092
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - ALLOW_PLAINTEXT_LISTENER=yes
    depends_on:
      - zookeeper

volumes:
  mysql_data: {}
  redis_data: {}
  etcd_data: {}

配置了需要用到的各个基础服务,这部分可以直接使用哦~

启动镜像:

docker-compose up -d

启动成功后可以验证是否连通

比如验证mysql,本地连接:输入地址为:你的linux机器的IP地址,输入端口:33306(正常可以使用3306端口,由于小编的linux机器上已经有同事起了一个mysql镜像,3306端口已被占用,改为了33306),输入root用户、密码

2./compose/project-root目录下的docker-compose.yml文件内容

涉及到安全性问题,就简单给出其中一个服务的例子~

比如:job服务

job:
    image: job-image  #这里我直接用的公司已有的镜像,当然也可以自己build
    container_name: job
    ports:
      - "8894:8899"
      - "11214:11211"
    restart: always
    volumes:
      - /home/jenkins/compose/project-root/internal/job/config:/workspace/job/config
    environment:
      YS_ENV: "test"
      LOG_LVL: "debug"

 接下来配置好job服务后,可以看到配置的卷映射的地址,切换到具体的目录下,修改里面的配置文件:test.yml和test_custom.yml

    mysql:
      default:
        _startup: true
        dsn: "root:rootmysql@tcp(linux机器IP地址:33306)/project_root?charset=utf8"

    redis:
      default:
        _startup: true
        addr: linux机器IP地址:6379

    etcd:
      startup: false
      endpoints: ["linux机器IP地址:2379"]
      tls: false

    apm:
      apm_server_url: "http://linux机器IP地址:8200"

 上述是配置文件修改的部分内容,其他涉及公司业务不显示,但是逻辑是一样的哦~

配置成功后启动镜像:

docker-compose up -d

 上述job服务拉取镜像时提到也可以自己build,那么如何build一个go服务呢?

步骤一、编写Dockerfile文件

# 基础镜像
FROM golang:1.16 as builder

# 设置工作目录
WORKDIR /app

# 复制go module文件
COPY go.mod .
COPY go.sum .

# 下载依赖
RUN go mod download

# 复制项目文件
COPY . .

# 构建你的应用
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .

# 最终镜像
FROM alpine:latest  
RUN apk --no-cache add ca-certificates

WORKDIR /root/

# 从构建者阶段复制已编译的app到当前目录
COPY --from=builder /app/myapp .

# 运行时候的命令
CMD ["./myapp"]

步骤二:编写docker-compose.yml

version: '3.8'

services:
  webapp:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080" # 将容器中的8080端口映射到宿主机的8080端口
    environment:
      - GIN_MODE=release # 设置 Golang 应用的环境变量(如果需要)

步骤三:运行docker-compose

在 docker-compose.yml 文件所在的目录下,运行以下命令启动你的服务

docker-compose up --build

--build 选项表示 docker-compose 需要先构建(或重建)镜像。如果没有修改Dockerfile或不需要重新构建镜像,下次启动可以直接运行 docker-compose up


三、portainer配置可视化界面

查看/compose/portainer目录下的docker-compose.yml文件

version: '3.0'
services:
  portainer:
    image: 6053537/portainer-ce
    restart: always
    container_name: portainer
    ports:
      - "8000:8000"
      - "9001:9000"
      - "9443:9443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "portainer_data:/data"
volumes:
  portainer_data:

配置成功后启动镜像:

docker-compose up -d

启动成功后,通过浏览器打开:http://linux机器的IP地址:9001,可打开可视化界面,首先设置登录用户名和密码,设置成功后,可看到具体界面。

上述的界面可看作是docker-compos命令行的可视化界面,是轻量级的,请尽情的探索吧~

每个服务之间可能有依赖关系,在启动过程中遇到的问题,大概率就是配置不正确导致的,具体问题具体解决~


四、执行测试用例获取测试覆盖率

我们项目目前是用go语言,采用goc来获取代码覆盖率。

在前面的步骤中已经部署了相应的Go服务,还需要部署Goc server,并确保goc server和其他Go服务在同一网络中,这样他们之间才可以互相通信。

编写docker-compose.yml文件

   version: '3'
   
   services:
     goc-server:
       image: your-goc-server-image
       ports:
        - "7777:7777" # 确保端口映射匹配你希望goc server监听的端口
       networks:
        - goc-network
     
     go-service:
       build: .
       command: sh -c "goc build ./... && ./your-service-binary"
       ports:
         - "8080:8080"
       networks:
         - goc-network
       environment:
         - GOC_SERVER_ADDRESS=goc-server:7777

   networks:
     goc-network:
       driver: bridge

可根据项目具体替换your-service-binary为你的服务二进制文件名,替换your-goc-server-image为你的goc服务器Docker镜像。确保GOC_SERVER_ADDRESS环境变量指向goc-server服务。也可以直接在本地goc build ,将构建成功后的二进制文件传到docker-compose集群中。

拿job服务举例:

步骤1:切换到包含main.go的job服务目录下

cd /home/jenkins/compose/code/project-root/cmd/job

步骤2:   执行命令,使用agentport参数确定端口,生成job二进制文件

CGO_ENABLED=0   goc build --center=http://服务IP:port  --agentport :12321 .    

步骤3:切换到compose对应的job服务目录

  cd /home/jenkins/compose/project-root/internal/job

步骤4:复制job二进制文件

cp ../../../code/project-root/cmd/job/job ./

步骤5: 编写Dockerfile

vim Dockerfile 
FROM alpine-with-bash

#设置工作目录
WORKDIR /home/job

#复制
COPY ./job /home/job
COPY ./config /home/job/config

# 确保二进制文件可执行
RUN chmod +x /home/job/job

ENV YS_ENV=test

# 当容器启动时运行应用
CMD ["./job"]


步骤6:  构建job服务镜像

docker build -t job-test .  

步骤7: 在容器内运行镜像

docker run -it job-test:latest   /bin/bash   

步骤8:修改之前的compose/project-root/docker-compose.yml文件内容

version: '3.0'
services:
  job:
    image: job-test:latest
    container_name: job
    ports:
      - "8894:8899"
      - "11214:11211"
      - "12321:12321"       #构建job时的端口,在这里暴露出来
    restart: always
    volumes:
      - /home/jenkins/compose/project-root/internal/job/config:/home/job/config
    environment:
      YS_ENV: "test"
      LOG_LVL: "debug"
      GOC_SERVER_ADDRESS: "http://goc-server:7777"
    depends_on:
      - goc-server  # 确保启动顺序

      
  goc-server:
    image: goc-server:latest
    container_name: goc-server
    ports:
      - "7788:7777"
    restart: always
    command: ["sh", "-c", "go install github.com/qiniu/goc@latest && goc server"]
    volumes:
      - /home/jenkins/compose/code/project-root:/go/src/project-root
    working_dir: /go/src/project-root   
    environment:
      - GO111MODULE=on

步骤9:登录9001端口进入到portainer可视化界面,也可以直接进入到goc-server中运行

也可以通过命令进入到容器内的交互界面:

docker exec -it goc-server bash

进入到goc server容器中,将已有的其他Go服务注册进去

 goc register -a 服务所在地址 -n 服务名

执行测试:

在Go服务运行时,执行测试。若是手动测试,直接访问服务;若是自动化测试,运行自动化测试脚本。

收集测试覆盖率数据:

收集测试覆盖率:

goc profile --service SERVICE_NAME -o coverage.out

goc profile -o coverage.out

生成覆盖率报告:

go tool cover -html=coverage.out -o coverage.html

gocov convert coverage.out |gocov-html >coverage.html

可查看goc-server服务的日志,可看到列出、注册、获取覆盖率都成功啦~

停止服务:

docker-compose down

五、Jenkins日常发布测试用例&服务

通过上述步骤已经能获取到覆盖率了,但是每次手工执行肯定是比较浪费人力物力的,可通过创建Jenkins流水线实现日常执行测试用例,可实现服务日常发布。

自动化实现测试用例执行这里就不讲解了,每个公司有具体的流水线。

这里简单看一下测试用例自动化执行的流水线:

接下来详细讲解下获取覆盖率的流水线,大概配置如下:

构建选项参数:SERVICE_NAME、MODULE_NAME、PRIORITY

编写jenkins的shell脚本,内容如下:

#!/bin/bash
GOC_SERVER_ADDRESS="goc-server:7788"
export GOC_SERVER_ADDRESS

TestURL="ssh://vcssh@git测试库地址.git"
repoPath="/var/jenkins_work/workspace/${JOB_NAME}/${BUILD_ID}"

ProjectPath="/home/jenkins/compose/code/project-root"
ComposePath="/home/jenkins/compose/project-root"

cov_file="${SERVICE_NAME}_TestCoverage.out"
cov_html="${SERVICE_NAME}_TestCoverage.html"

git clone  $TestURL $repoPath

cd $repoPath
cp /home/jenkins/compose/conf/.env ${repoPath}/test
cp /home/jenkins/compose/conf/.env.storage ${repoPath}/test/storage/v1/.env

go mod tidy
#执行测试用例
cd $repoPath
go test -v -timeout 30m ./test/$MODULE_NAME/...   -run="^Test"+"/Test"+$PRIORITY

# 由于在Jenkins非交互式环境,移除-it参数用来运行docker exec
docker exec goc-server bash -c "goc list"

# 清除存量覆盖率数据
docker exec goc-server bash -c "goc clear --address=$GOC_SERVER_ADDRESS"


# 收集覆盖率数据
docker exec goc-server bash -c "goc profile --service $SERVICE_NAME -o ${cov_file}"
docker exec goc-server bash -c "go tool cover -func=${cov_file}"

# 生成代码覆盖率报告
docker exec goc-server bash -c "gocov convert ${cov_file} | gocov-html > ${cov_html}"

cd ${repoPath}
# 创建存放覆盖率报告的目录
mkdir -p TestCoverage
# 确保已将报告文件从 docker 容器复制到指定目录
docker cp goc-server:/go/src/project-root/${cov_file} TestCoverage/
docker cp goc-server:/go/src/project-root/${cov_html} TestCoverage/

添加构建后操作:选择Publish HTML reports,配置相关参数如下:

 如果想知道每次构建的具体情况,也可以添加构建后操作:企业微信通知

执行此流水线,最后就可以看到覆盖率文件了,在浏览器中打开~


六、问题描述及解决方式

问题1

go tool cover -func=test.out 

问题描述:执行上述命令时报错没有go.mod

解决方式:需将工作目录设置在project-root项目根目录下,问题解决

问题2:

goc profile --service job -o test.out
gocov convert test.out |gocov-html >test.html

问题描述:执行上述命令时提示:gocov、gocov-html不存在,需要安装
解决方式:在之前的Dockerfile中加入以下命令并重新打镜像

RUN go install github.com/axw/gocov/gocov@latest
RUN go install github.com/AlekSi/gocov-xml@latest
RUN go install github.com/matm/gocov-html@latest

问题3:

问题描述:获取到test.out和test.html文件后,想复制到本地通过浏览器打开
解决方式:

1.在本地新建/job文件夹
2.打开本机终端,切换目录到C:/Users/admin/Desktop/job/
3.执行命令:

scp username@服务IP:项目目录/test.html .

4.文件复制成功,可通过浏览器打开查看

问题4:

问题描述:

收集覆盖率时遇到报错:FATA Goc server http://linux机器:7788 return an error: {"error":"no profiles"}
查看goc-server服务日志报错:[GIN] 2024/03/29 - 08:21:15 | 417 | 173.303µs | 127.0.0.1 | POST "/v1/cover/profile"

解决方式:后排查到是因为docker-compose没有将镜像build时的端口暴露出来,添加暴露端口后,问题解决,可获取到覆盖率


七、docker基础知识总结

镜像命令:

  • docker images: 列出本地的所有镜像。

  • docker pull <image-name>: 从远程仓库拉取镜像到本地。

  • docker build -t <tag> .: 根据当前目录的Dockerfile构建一个新镜像。

  • docker rmi <image-id>: 删除一个镜像。

容器命令:

  • docker ps: 列出正在运行的容器。

  • docker ps -a: 列出所有容器,无论状态。

  • docker run <image-name>: 基于一个镜像创建并启动一个新容器。

  • docker stop <container-id>: 停止一个容器。

  • docker start <container-id>: 启动一个已经停止的容器。

  • docker restart <container-id>: 重启容器。

  • docker rm <container-id>: 删除一个已经停止的容器。

  • docker exec -it <container-id> /bin/bash: 进入正在运行的容器内部。

网络命令:

  • docker network ls: 列出所有的网络。

  • docker network create <network-name>: 创建一个新的网络。

  • docker network rm <network-name>: 删除一个网络。

卷命令:

  • docker volume ls: 列出所有的卷。

  • docker volume create <volume-name>: 创建一个新的卷。

  • docker volume rm <volume-name>: 删除一个卷。

日志和进程查看命令:

  • docker logs <container-id>: 查看容器的输出日志。

  • docker top <container-id>: 查看容器内的进程信息。

系统命令:

  • docker system df: 显示 Docker 使用的磁盘空间。

  • docker system prune: 清理未使用的网络、挂载、镜像和构建缓存。

Docker Compose命令:

  • docker-compose up: 启动并运行整个应用。使用 -d 标志来后台运行服务。
  • docker-compose down: 停止并移除所有由 docker-compose up 创建的资源,包括网络、容器、卷。
  • docker-compose start: 启动已经存在的容器。
  • docker-compose stop: 停止已经运行的服务,不移除容器。
  • docker-compose restart: 重启服务。
  • docker-compose build: 构建或重建服务关联的镜像。
  • docker-compose pull: 拉取服务依赖的镜像。
  • docker-compose push: 推送服务镜像到镜像仓库。
  • docker-compose logs: 查看服务的日志输出。使用 -f 来跟踪实时日志。
  • docker-compose exec: 在运行的服务容器中执行命令。
  • docker-compose run: 运行一个一次性命令。例如:运行一个脚本或者执行一个服务的管理命令。
  • docker-compose ps: 列出项目中目前的所有容器。
  • docker-compose config: 验证并查看配置文件的内容。
  • docker-compose rm: 删除所有(或指定的)停止状态的服务容器。
  • docker-compose top: 显示运行中的服务容器中的进程。
  • docker-compose pause: 暂停服务容器。
  • docker-compose unpause: 恢复服务容器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值