JUnit ku-GitLab CI nge-Kubernetes

Naphezu kweqiniso lokuthi wonke umuntu wazi kahle ukuthi ukuhlola isofthiwe yakho kubalulekile futhi kuyadingeka, futhi abaningi bebelokhu bekwenza ngokuzenzakalelayo isikhathi eside, ngobukhulu bukaHabr kwakungekho neyodwa iresiphi yokusetha inhlanganisela yemikhiqizo enjalo edumile. le niche njenge (intandokazi yethu) i-GitLab ne-JUnit. Asigcwalise lesi sikhala!

JUnit ku-GitLab CI nge-Kubernetes

Isingeniso

Okokuqala, ake nginikeze umongo othile:

  • Njengoba zonke izinhlelo zethu zokusebenza zisebenza ku-Kubernetes, sizocabangela ukuqalisa ukuhlolwa nengqalasizinda efanele.
  • Ukuhlanganisa nokusatshalaliswa sisebenzisa i-werf (ngokwezingxenye zengqalasizinda, lokhu futhi kusho ngokuzenzakalelayo ukuthi uHelm uyabandakanyeka).
  • Ngeke ngingene emininingwaneni yokudalwa kwangempela kokuhlolwa: esimweni sethu, iklayenti libhala izivivinyo ngokwayo, futhi siqinisekisa kuphela ukuqaliswa kwazo (kanye nokuba khona kombiko ohambisanayo esicelweni sokuhlanganisa).


Ngabe ukulandelana okuvamile kwezenzo kuzobukeka kanjani?

  1. Ukwakha isicelo - sizoyiyeka incazelo yalesi sigaba.
  2. Hambisa uhlelo lokusebenza endaweni yamagama ehlukile yeqoqo le-Kubernetes bese uqala ukuhlola.
  3. Isesha ama-artifact kanye nokuhlaziya imibiko ye-JUnit nge-GitLab.
  4. Isusa indawo yegama edalwe ngaphambilini.

Manje - ukuqaliswa!

Yenza ngokwezifiso

IGitLab CI

Ake siqale ngocezu .gitlab-ci.yaml, echaza ukuthunyelwa kohlelo lokusebenza nokwenza izivivinyo. Ukufakwa kuhlu kubonakale kukhulu kakhulu, ngakho-ke kwengezwe ngokugcwele ngamazwana:

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

Manje ohlwini lwemibhalo .helm/templates masidale i-YAML ngoJobe - tests-job.yaml - ukwenza izivivinyo kanye nezinsiza ze-Kubernetes eziyidingayo. Bona izincazelo ngemva kokufakwa kuhlu:

{{- 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 }}

Hlobo luni lwezinsiza echazwe kulokhu kumisa? Lapho sisebenzisa, sakha indawo yamagama ehlukile yephrojekthi (lokhu kukhonjisiwe ku .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) bese uyikhipha:

  1. ConfigMap ngombhalo wokuhlola;
  2. UJobe ngencazelo ye-pod kanye nomyalelo oshiwo command, ovele enze izivivinyo;
  3. I-PV ne-PVC, okukuvumela ukuthi ugcine idatha yokuhlola.

Naka isimo sesethulo nge if ekuqaleni kwe-manifest - ngokufanelekile, amanye amafayela e-YAML eshadi le-Helm anohlelo lokusebenza kufanele ahlanganiswe hlehla ukuklama ukuze bangatshalwa ngesikhathi sokuhlolwa. Leyo:

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

Nokho, uma izivivinyo zidinga ingqalasizinda ethile (isibonelo, i-Redis, i-RabbitMQ, i-Mongo, i-PostgreSQL...) - ama-YAML abo angaba hhayi vala. Zisebenzise endaweni yokuhlola futhi... uzilungise njengoba ubona kufanele, kunjalo.

ukuthinta kokugcina

Ngoba ukuhlanganisa nokusatshalaliswa kusetshenziswa imisebenzi ye-werf okwamanje kuphela kuseva yokwakha (nge-gitlab-runner), futhi i-pod enokuhlolwa yethulwa ku-master, uzodinga ukudala inkomba /mnt/tests phezu kwenkosi futhi uyinike umgijimi, isibonelo, nge-NFS. Isibonelo esinemininingwane enezincazelo singatholakala ku Imibhalo ye-K8s.

Umphumela uzoba:

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

Akekho onqabela ukwenza ukwabelana kwe-NFS ngqo ku-gitlab-runner, bese eyifaka kuma-pods.

Ukubhala

Kungenzeka ukuthi uyabuza ukuthi kungani uhlanganisa yonke into ngokudala Umsebenzi uma ungamane wenze iskripthi esinokuhlolwa ngqo kumgijimi wegobolondo? Impendulo incane impela...

Okunye ukuhlola kudinga ukufinyelela kungqalasizinda (i-MongoDB, i-RabbitMQ, i-PostgreSQL, njll.) ukuze kuqinisekiswe ukuthi zisebenza ngendlela efanele. Senza ukuhlola kuhlangane - ngale ndlela, kuba lula ukufaka amabhizinisi anjalo. Ngaphezu kwalokhu, sithola standard indlela yokuphakela (ngisho noma kusetshenziswa i-NFS, ukukhwezwa okwengeziwe kohla lwemibhalo).

Umphumela

Yini esizoyibona lapho sisebenzisa ukumisa okulungiselelwe?

Isicelo sokuhlanganisa sizobonisa izibalo ezifinyeziwe zokuhlolwa okwenziwa ngendlela yakamuva:

JUnit ku-GitLab CI nge-Kubernetes

Iphutha ngalinye lingachofozwa lapha ukuze uthole imininingwane:

JUnit ku-GitLab CI nge-Kubernetes

NB: Umfundi olalelayo uzoqaphela ukuthi sihlola uhlelo lokusebenza lwe-NodeJS, futhi kuzithombe-skrini - .NET... Ungamangali: ukuthi nje ngenkathi silungiselela isihloko, awekho amaphutha atholakele ekuhloleni isicelo sokuqala, kodwa zatholakala kwenye.

isiphetho

Njengoba ubona, akukho lutho oluyinkimbinkimbi!

Eqinisweni, uma usuvele unomqoqi wegobolondo futhi uyasebenza, kodwa awudingi i-Kubernetes, ukunamathisela ukuhlolwa kuyo kuyoba umsebenzi olula nakakhulu kunalokho okuchazwe lapha. Futhi ku Imibhalo ye-GitLab CI uzothola izibonelo zikaRuby, Go, Gradle, Maven nabanye.

PS

Funda futhi kubhulogi yethu:

Source: www.habr.com

Engeza amazwana