JUnit gudaha GitLab CI oo leh Kubernetes

In kasta oo xaqiiqda ah in qof kastaa uu si fiican u garanayo in tijaabinta software-kaagu ay muhiim tahay oo lagama maarmaan tahay, qaar badanna ay si toos ah u sameynayaan muddo dheer, baaxadda Habr ma jirin hal cunto oo loogu talagalay isku-darka alaabooyinka caanka ah ee sida Niche-kan sida (aan ugu jecelnahay) GitLab iyo JUnit . Aan buuxino farqigaan!

JUnit gudaha GitLab CI oo leh Kubernetes

Hordhac

Marka hore, aan ka bixiyo macnaha guud:

  • Maadaama dhammaan codsiyadayagu ay ku shaqeeyaan Kubernetes, waxaan tixgelin doonaa inaan tijaabino kaabayaal ku habboon.
  • Isku-dubarid iyo geyn waxaan isticmaalnaa werf (Marka la eego qaybaha kaabayaasha, tani waxay sidoo kale si toos ah uga dhigan tahay in Helm uu ku lug leeyahay).
  • Anigu ma geli doono faahfaahinta abuurista dhabta ah ee imtixaannada: kiiskeena, macmiilku wuxuu qoraa imtixaannada laftiisa, waxaanan hubineynaa oo kaliya inay bilaabaan (iyo joogitaanka warbixinta u dhiganta codsiga isku-dhafka ah).


Sidee buu u ekaan doonaa taxanaha guud ee falku?

  1. Dhisida codsiga - waxaan ka tagi doonaa sharaxaadda marxaladan.
  2. Geli arjiga meel magac gaar ah oo kutlada Kubernetes ah oo bilow tijaabinta.
  3. Raadinta farshaxanimada iyo kala-saarista warbixinnada JUnit ee GitLab.
  4. Tirtiraya meel hore loo abuuray

Hadda - si loo hirgeliyo!

sixitaanka

GitLab CI

Aan ku bilowno jajab .gitlab-ci.yaml, kaas oo sharxaya meel marinta arjiga iyo imtixaanada socda. Liiskii wuxuu noqday mid aad u badan, sidaa darteed si fiican ayaa loogu kabay faallooyin:

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

Kubureteska

Hadda ku jira tusaha .helm/templates aynu ku abuurno YAML shaqo - tests-job.yaml - in la sameeyo imtixaanada iyo agabka Kubernetes ee ay u baahan tahay. Fiiri sharraxaadda liiska ka dib:

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

Waa maxay nooca kheyraadka lagu tilmaamay qaabeyntan? Marka la dirayo, waxaan u abuurnaa meel magac gaar ah mashruuca (tani waxa lagu tilmaamay .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) oo soo rogo:

  1. ConfigMap oo leh qoraalka tijaabada;
  2. Job oo leh sharraxaad boodhka iyo dardaaranka la cayimay command, Kaas oo kaliya sameeya imtixaanada;
  3. PV iyo PVC, kaas oo kuu ogolaanaya inaad kaydiso xogta imtixaanka.

U fiirso xaalada hordhaca ah ee leh if bilowga bayaanka - sidaas darteed, faylasha kale ee YAML ee jaantuska Helm ee codsiga waa in lagu duuduubo rogasho naqshadeynta si aan loo geynin inta lagu jiro tijaabada. Taasi waa:

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

Si kastaba ha ahaatee, haddii imtixaanada u baahan kaabayaasha qaar (tusaale ahaan, Redis, RabbitMQ, Mongo, PostgreSQL...) - YAMLs-kooda waxay noqon karaan ma dami. Geli deegaan imtixaan sidoo kale... u habaynta sidaad u aragto inay ku habboon tahay, dabcan.

Taabashada kama dambaysta ah

Sababtoo ah isu-ururinta iyo geynta iyadoo la adeegsanayo werf shaqooyinka hadda oo keliya on server-ka dhismaha (oo leh gitlab-runner), iyo boodhka leh imtixaannada ayaa lagu bilaabay sayidkii, waxaad u baahan doontaa inaad abuurto hagaha /mnt/tests dushii sayidkii oo u dhiib orodyahanka. tusaale ahaan, iyada oo loo marayo NFS. Tusaal faahfaahsan oo sharraxaad leh ayaa laga heli karaa Dukumentiyada K8s.

Natiijadu waxay noqon doontaa:

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

Qofna ma mamnuucayo samaynta wadaagga NFS si toos ah gitlab-runner, ka dibna ku dhejinta sanduuqyada.

tacliiq

Waxaa laga yaabaa inaad weydiiso sababta ay wax walba u adkeynayaan adoo abuuraya Shaqo haddii aad si fudud u maamuli karto qoraal leh imtixaanno toos ah orodyahanka qolofka? Jawaabtu waa mid fudud...

Imtixaanada qaar waxay u baahan yihiin marin u helka kaabayaasha (MongoDB, RabbitMQ, PostgreSQL, iwm.) si loo xaqiijiyo inay si sax ah u shaqeeyaan. Waxaan ka dhigaynaa imtixaan midaysan - habkan, way fududahay in lagu daro qaybaha dheeraadka ah. Waxa intaa dheer in this, waxaan helnaa heerka habka geynta (xitaa haddii la isticmaalayo NFS, kordhin dheeraad ah oo hagisyada).

natiijada

Maxaan arki doonaa markaan codsano qaabeynta diyaarsan?

Codsiga isku darka waxa uu tusi doonaa tirokoobkooban ee imtixaanada lagu wado dhuumihii ugu dambeeyay:

JUnit gudaha GitLab CI oo leh Kubernetes

Qalad kasta waxaa lagu dhejin karaa halkan faahfaahinta:

JUnit gudaha GitLab CI oo leh Kubernetes

NB: Akhristaha fiiro gaar ah ayaa ogaan doona inaan tijaabineyno codsiga NodeJS, iyo shaashadaha - .NET ... Ha la yaabin: waa in markii la diyaarinayo maqaalka, wax qalad ah laguma helin tijaabinta codsigii ugu horreeyay, laakiin waxay ahaayeen mid kale ayaa laga helay.

gunaanad

Sida aad arki karto, ma jiraan wax adag!

Mabda 'ahaan, haddii aad hore u haysatid qolofka qolofka oo ay shaqeyso, laakiin uma baahnid Kubernetes, ku dhejinta tijaabinta waxay noqon doontaa hawl ka fudud tan halkan lagu sharaxay. Oo gudaha Dukumentiyada GitLab CI Waxaad tusaale u heli doontaa Ruby, Go, Gradle, Maven iyo qaar kale.

PS

Sidoo kale ka akhri boggayaga:

Source: www.habr.com

Add a comment