JUnit hauv GitLab CI nrog Kubernetes

Txawm hais tias txhua tus paub zoo tias kev sim koj cov software yog qhov tseem ceeb thiab tsim nyog, thiab ntau tus tau ua nws tau ntev, nyob rau hauv qhov loj ntawm Habr tsis muaj ib daim ntawv qhia rau kev teeb tsa ua ke ntawm cov khoom nrov hauv no niche li (peb nyiam) GitLab thiab JUnit . Cia peb sau qhov sib txawv no!

JUnit hauv GitLab CI nrog Kubernetes

Taw qhia

Ua ntej, cia kuv muab qee qhov ntsiab lus:

  • Txij li thaum tag nrho peb cov ntawv thov khiav ntawm Kubernetes, peb yuav txiav txim siab khiav cov kev xeem ntawm cov txheej txheem tsim nyog.
  • Rau kev sib dhos thiab xa tawm peb siv werf (nyob rau hauv cov nqe lus ntawm infrastructure Cheebtsam, qhov no kuj cia li txhais tau tias Helm koom nrog).
  • Kuv yuav tsis mus rau hauv cov ntsiab lus ntawm qhov tseeb creation ntawm kev ntsuam xyuas: nyob rau hauv peb cov ntaub ntawv, tus neeg siv sau cov kev ntsuam xyuas nws tus kheej, thiab peb tsuas yog xyuas kom meej lawv lub community launch (thiab lub xub ntiag ntawm ib tug coj daim ntawv qhia nyob rau hauv lub merge thov).


Yuav ua li cas yog ib feem ntawm kev ua zoo li cas?

  1. Tsim daim ntawv thov - peb yuav tshem tawm cov lus piav qhia ntawm theem no.
  2. Muab daim ntawv thov mus rau qhov chaw cais ntawm Kubernetes pawg thiab pib sim.
  3. Tshawb nrhiav cov khoom qub thiab txheeb xyuas JUnit cov ntaub ntawv nrog GitLab.
  4. Rho tawm lub npe chaw tsim yav dhau los.

Tam sim no - rau kev siv!

hloov

GitLab CI

Cia peb pib nrog ib feem .gitlab-ci.yaml, uas piav qhia txog kev siv cov ntawv thov thiab kev sim ua haujlwm. Cov npe tau dhau los ua voluminous, yog li nws tau ua tiav nrog cov lus pom:

variables:
# объявляем версию werf, которую собираемся использовать
  WERF_VERSION: "1.0 beta"

.base_deploy: &base_deploy
  script:
# создаем namespace в K8s, если его нет
    - kubectl --context="${WERF_KUBE_CONTEXT}" get ns ${CI_ENVIRONMENT_SLUG} || kubectl create ns ${CI_ENVIRONMENT_SLUG}
# загружаем werf и деплоим — подробнее об этом см. в документации
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#deploy-stage)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf deploy --stages-storage :local
      --namespace ${CI_ENVIRONMENT_SLUG}
      --set "global.commit_ref_slug=${CI_COMMIT_REF_SLUG:-''}"
# передаем переменную `run_tests`
# она будет использоваться в рендере Helm-релиза
      --set "global.run_tests=${RUN_TESTS:-no}"
      --set "global.env=${CI_ENVIRONMENT_SLUG}"
# изменяем timeout (бывают долгие тесты) и передаем его в релиз
      --set "global.ci_timeout=${CI_TIMEOUT:-900}"
     --timeout ${CI_TIMEOUT:-900}
  dependencies:
    - Build

.test-base: &test-base
  extends: .base_deploy
  before_script:
# создаем директорию для будущего отчета, исходя из $CI_COMMIT_REF_SLUG
    - mkdir /mnt/tests/${CI_COMMIT_REF_SLUG} || true
# вынужденный костыль, т.к. GitLab хочет получить артефакты в своем build-dir’е
    - mkdir ./tests || true
    - ln -s /mnt/tests/${CI_COMMIT_REF_SLUG} ./tests/${CI_COMMIT_REF_SLUG}
  after_script:
# после окончания тестов удаляем релиз вместе с Job’ом
# (и, возможно, его инфраструктурой)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf dismiss --namespace ${CI_ENVIRONMENT_SLUG} --with-namespace
# мы разрешаем падения, но вы можете сделать иначе
  allow_failure: true
  variables:
    RUN_TESTS: 'yes'
# задаем контекст в werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#infrastructure)
    WERF_KUBE_CONTEXT: 'admin@stage-cluster'
  tags:
# используем раннер с тегом `werf-runner`
    - werf-runner
  artifacts:
# требуется собрать артефакт для того, чтобы его можно было увидеть
# в пайплайне и скачать — например, для более вдумчивого изучения
    paths:
      - ./tests/${CI_COMMIT_REF_SLUG}/*
# артефакты старше недели будут удалены
    expire_in: 7 day
# важно: эти строки отвечают за парсинг отчета GitLab’ом
    reports:
      junit: ./tests/${CI_COMMIT_REF_SLUG}/report.xml

# для упрощения здесь показаны всего две стадии
# в реальности же у вас их будет больше — как минимум из-за деплоя
stages:
  - build
  - tests

build:
  stage: build
  script:
# сборка — снова по документации по werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#build-stage)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf build-and-publish --stages-storage :local
  tags:
    - werf-runner
  except:
    - schedules

run tests:
  <<: *test-base
  environment:
# "сама соль" именования namespace’а
# (https://docs.gitlab.com/ce/ci/variables/predefined_variables.html)
    name: tests-${CI_COMMIT_REF_SLUG}
  stage: tests
  except:
    - schedules

Kubernetes

Tam sim no hauv phau ntawv qhia .helm/templates Cia peb tsim YAML nrog Txoj Haujlwm - tests-job.yaml - txhawm rau khiav kev sim thiab Kubernetes cov peev txheej nws xav tau. Saib cov lus piav qhia tom qab sau npe:

{{- if eq .Values.global.run_tests "yes" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tests-script
data:
  tests.sh: |
    echo "======================"
    echo "${APP_NAME} TESTS"
    echo "======================"

    cd /app
    npm run test:ci
    cp report.xml /app/test_results/${CI_COMMIT_REF_SLUG}/

    echo ""
    echo ""
    echo ""

    chown -R 999:999 /app/test_results/${CI_COMMIT_REF_SLUG}
---
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Chart.Name }}-test
  annotations:
    "helm.sh/hook": post-install,post-upgrade
    "helm.sh/hook-weight": "2"
    "werf/watch-logs": "true"
spec:
  activeDeadlineSeconds: {{ .Values.global.ci_timeout }}
  backoffLimit: 1
  template:
    metadata:
      name: {{ .Chart.Name }}-test
    spec:
      containers:
      - name: test
        command: ['bash', '-c', '/app/tests.sh']
{{ tuple "application" . | include "werf_container_image" | indent 8 }}
        env:
        - name: env
          value: {{ .Values.global.env }}
        - name: CI_COMMIT_REF_SLUG
          value: {{ .Values.global.commit_ref_slug }}
       - name: APP_NAME
          value: {{ .Chart.Name }}
{{ tuple "application" . | include "werf_container_env" | indent 8 }}
        volumeMounts:
        - mountPath: /app/test_results/
          name: data
        - mountPath: /app/tests.sh
          name: tests-script
          subPath: tests.sh
      tolerations:
      - key: dedicated
        operator: Exists
      - key: node-role.kubernetes.io/master
        operator: Exists
      restartPolicy: OnFailure
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: {{ .Chart.Name }}-pvc
      - name: tests-script
        configMap:
          name: tests-script
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ .Chart.Name }}-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi
  storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }}
  volumeName: {{ .Values.global.commit_ref_slug }}

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: {{ .Values.global.commit_ref_slug }}
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Mi
  local:
    path: /mnt/tests/
  nodeAffinity:
   required:
     nodeSelectorTerms:
     - matchExpressions:
       - key: kubernetes.io/hostname
         operator: In
         values:
         - kube-master
  persistentVolumeReclaimPolicy: Delete
  storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }}
{{- end }}

Yam kev pab twg piav nyob rau hauv no configuration? Thaum xa tawm, peb tsim ib lub npe tshwj xeeb rau qhov project (qhov no yog qhia hauv .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) thiab rub nws tawm:

  1. ConfigMap nrog cov ntawv xeem;
  2. txoj hauj lwm nrog cov lus piav qhia ntawm lub plhaub thiab cov lus qhia tshwj xeeb command, uas tsuas yog khiav cov kev xeem;
  3. PV thiab PVC, uas tso cai rau koj khaws cov ntaub ntawv xeem.

Them mloog mus rau qhov pib mob nrog if Thaum pib ntawm qhov tshwm sim - raws li, lwm cov ntaub ntawv YAML ntawm Helm daim ntawv nrog daim ntawv thov yuav tsum tau muab qhwv rau hauv thim rov qab tsim kom lawv tsis txhob siv thaum lub sij hawm sim. Ntawd yog:

{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}

Txawm li cas los xij, yog cov kev xeem xav tau ib co infrastructure (piv txwv li, Redis, RabbitMQ, Mongo, PostgreSQL...) - lawv YAMLs tuaj yeem yog tsis tig tawm. Muab lawv tso rau hauv qhov chaw sim ib yam nkaus ... kho lawv raws li koj pom haum, tau kawg.

kov kawg

Vim Kev sib dhos thiab xa tawm siv werf ua haujlwm rau tam sim no tsuas ntawm tus tsim server (nrog gitlab-khiav), thiab cov pod nrog cov kev ntsuam xyuas yog launched rau tus tswv, koj yuav tsum tau tsim ib tug directory /mnt/tests ntawm tus tswv thiab muab nws rau tus khiav, Piv txwv li, ntawm NFS. Ib qho piv txwv ntxaws nrog cov lus piav qhia tuaj yeem pom hauv K8s cov ntaub ntawv.

Qhov tshwm sim yuav yog:

user@kube-master:~$ cat /etc/exports | grep tests
/mnt/tests    IP_gitlab-builder/32(rw,nohide,insecure,no_subtree_check,sync,all_squash,anonuid=999,anongid=998)

user@gitlab-runner:~$ cat /etc/fstab | grep tests
IP_kube-master:/mnt/tests    /mnt/tests   nfs4    _netdev,auto  0       0

Tsis muaj leej twg txwv tsis pub ua NFS qhia ncaj qha rau ntawm gitlab-khiav, thiab tom qab ntawd txuas rau hauv pods.

Примечание

Tej zaum koj yuav nug yog vim li cas thiaj ua rau txhua yam nyuaj los ntawm kev tsim Txoj Haujlwm yog tias koj tuaj yeem khiav ib tsab ntawv nrog cov kev ntsuam xyuas ncaj qha ntawm lub plhaub khiav? Cov lus teb yog qhov tsis tseem ceeb ...

Qee qhov kev xeem yuav tsum tau nkag mus rau hauv cov txheej txheem (MongoDB, RabbitMQ, PostgreSQL, thiab lwm yam) kom paub tseeb tias lawv ua haujlwm raug. Peb ua kev sim sib koom ua ke - nrog rau txoj hauv kev no, nws yooj yim kom suav nrog cov koom haum ntxiv. Ntxiv rau qhov no, peb tau txais tus qauv Kev xa mus kom ze (txawm tias siv NFS, txuas ntxiv ntawm cov npe).

tshwm sim

Peb yuav pom dab tsi thaum peb siv qhov kev teeb tsa npaj?

Qhov kev thov sib koom ua ke yuav qhia cov ntaub ntawv sau tseg rau cov kev xeem khiav hauv nws cov kav dej tshiab:

JUnit hauv GitLab CI nrog Kubernetes

Txhua qhov yuam kev tuaj yeem nyem rau ntawm no kom paub meej:

JUnit hauv GitLab CI nrog Kubernetes

NB: Tus neeg nyeem zoo yuav pom tias peb tab tom sim NodeJS daim ntawv thov, thiab hauv cov screenshots - .NET... Tsis txhob xav tsis thoob: nws tsuas yog tias thaum npaj tsab xov xwm, tsis muaj qhov yuam kev hauv kev sim thawj daim ntawv thov, tab sis lawv tau pom nyob rau lwm qhov.

xaus

Raws li koj tau pom, tsis muaj dab tsi nyuab!

Hauv txoj ntsiab cai, yog tias koj twb muaj lub plhaub ntim khoom thiab nws ua haujlwm, tab sis koj tsis xav tau Kubernetes, txuas kev sim rau nws yuav yog ib txoj haujlwm yooj yim dua li tau piav qhia ntawm no. Thiab hauv GitLab CI cov ntaub ntawv Koj yuav pom cov piv txwv rau Ruby, Mus, Gradle, Maven thiab lwm yam.

PS

Nyeem kuj ntawm peb blog:

Tau qhov twg los: www.hab.com

Ntxiv ib saib