JUnit a cikin GitLab CI tare da Kubernetes

Duk da cewa kowa ya sani sarai cewa gwada software ɗinku yana da mahimmanci kuma ya zama dole, kuma da yawa sun daɗe suna yin ta kai tsaye, a cikin faɗuwar Habr babu wani girke-girke na kafa haɗin irin waɗannan shahararrun samfuran a ciki. wannan alkuki azaman (abin da muka fi so) GitLab da JUnit. Mu cike wannan gibin!

JUnit a cikin GitLab CI tare da Kubernetes

Gabatarwa

Da farko, bari in ba da wani mahallin:

  • Tun da duk aikace-aikacenmu suna gudana akan Kubernetes, za mu yi la'akari da gudanar da gwaje-gwaje akan abubuwan da suka dace.
  • Don taro da turawa muna amfani da su wuf (dangane da abubuwan abubuwan more rayuwa, wannan kuma yana nufin kai tsaye cewa Helm ya shiga).
  • Ba zan shiga cikin cikakkun bayanai game da ainihin halittar gwaje-gwaje ba: a cikin yanayinmu, abokin ciniki ya rubuta gwaje-gwajen da kansa, kuma muna tabbatar da ƙaddamar da su kawai (da kuma kasancewar rahoton da ya dace a cikin buƙatar haɗuwa).


Yaya jerin ayyuka na gaba ɗaya zai yi kama?

  1. Gina aikace-aikacen - za mu bar bayanin wannan mataki.
  2. Aiwatar da aikace-aikacen zuwa keɓan wurin suna na Kubernetes cluster kuma fara gwaji.
  3. Neman kayan tarihi da rarraba rahotannin JUnit tare da GitLab.
  4. Share filin suna da aka ƙirƙira a baya.

Yanzu - don aiwatarwa!

gyara

GitLab CI

Bari mu fara da guntu .gitlab-ci.yaml, wanda ke bayyana ƙaddamar da aikace-aikacen da gwaje-gwaje masu gudana. Lissafin ya zama mai girma sosai, don haka an cika shi da sharhi sosai:

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

Yanzu a cikin directory .helm/templates bari mu kirkiro YAML tare da Ayuba - tests-job.yaml - don gudanar da gwaje-gwaje da albarkatun Kubernetes da yake buƙata. Dubi bayani bayan jeri:

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

Wani irin albarkatun aka bayyana a cikin wannan tsarin? Lokacin turawa, muna ƙirƙira keɓancewar suna don aikin (an nuna wannan a ciki .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) da kuma fitar da shi:

  1. ConfigMap tare da rubutun gwaji;
  2. Aiki tare da bayanin kwafsa da ƙayyadadden umarnin command, wanda kawai ke gudanar da gwaje-gwaje;
  3. PV da PVC, wanda ke ba ka damar adana bayanan gwaji.

Kula da yanayin gabatarwa tare da if a farkon bayyanar - saboda haka, sauran fayilolin YAML na taswirar Helm tare da aikace-aikacen dole ne a nannade su baya tsara don kada a tura su yayin gwaji. Wato:

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

Duk da haka, idan gwaje-gwaje bukatar wasu kayayyakin more rayuwa (misali, Redis, RabbitMQ, Mongo, PostgreSQL...) - su YAMLs na iya zama ba kashe. Sanya su cikin yanayin gwaji kuma… daidaita su yadda kuka ga dama, ba shakka.

Taɓawar ƙarshe

Domin taro da turawa ta amfani da werf aiki a yanzu kawai akan uwar garken ginawa (tare da gitlab-mai gudu), kuma an ƙaddamar da kwas ɗin tare da gwaje-gwaje akan maigidan, kuna buƙatar ƙirƙirar kundin adireshi. /mnt/tests a kan maigidan kuma a ba shi ga mai gudu. misali, ta hanyar NFS. Ana iya samun cikakken misali tare da bayani a ciki Takardar bayanan K8.

Sakamakon zai kasance:

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

Babu wanda ya hana yin rabon NFS kai tsaye akan gitlab-mai gudu, sannan a dora shi a cikin kwasfa.

Примечание

Kuna iya tambayar dalilin da yasa ke dagula komai ta hanyar ƙirƙirar Ayuba idan zaku iya gudanar da rubutun kawai tare da gwaje-gwaje kai tsaye akan mai gudu harsashi? Amsar ba ta da yawa...

Wasu gwaje-gwaje na buƙatar samun dama ga kayan aikin (MongoDB, RabbitMQ, PostgreSQL, da sauransu) don tabbatar da cewa suna aiki daidai. Mun sanya gwaji ya zama haɗin kai - tare da wannan hanyar, yana da sauƙi a haɗa irin waɗannan ƙarin abubuwan. Baya ga wannan, muna samun misali tsarin ƙaddamarwa (ko da yin amfani da NFS, ƙarin hawan kundayen adireshi).

sakamakon

Menene za mu gani lokacin da muka yi amfani da tsarin da aka shirya?

Buƙatar haɗakarwa za ta nuna taƙaitaccen ƙididdiga don gwaje-gwajen da aka gudanar a cikin sabon bututunsa:

JUnit a cikin GitLab CI tare da Kubernetes

Ana iya danna kowace kuskure a nan don cikakkun bayanai:

JUnit a cikin GitLab CI tare da Kubernetes

NB: Mai karatu mai hankali zai lura cewa muna gwada aikace-aikacen NodeJS, kuma a cikin hotunan kariyar kwamfuta - .NET aka samu a wani.

ƙarshe

Kamar yadda kake gani, babu wani abu mai rikitarwa!

A ka'ida, idan kun riga kuna da mai tattara harsashi kuma yana aiki, amma ba ku buƙatar Kubernetes, haɗa gwaji zuwa gare shi zai zama aiki mafi sauƙi fiye da yadda aka kwatanta a nan. Kuma a cikin Takardun GitLab CI Za ku sami misalan Ruby, Go, Gradle, Maven da sauran su.

PS

Karanta kuma a kan shafinmu:

source: www.habr.com

Add a comment