JUnit ann an GitLab CI le Kubernetes

A dh 'aindeoin gu bheil fios aig a h-uile duine gu math gu bheil deuchainn air a' bhathar-bog agad cudromach agus riatanach, agus tha mòran air a bhith ga dhèanamh gu fèin-obrachail airson ùine mhòr, ann am farsaingeachd Habr cha robh aon reasabaidh ann airson a bhith a 'stèidheachadh measgachadh de thoraidhean cho measail ann an an àite seo mar (am fear as fheàrr leinn) GitLab agus JUnit . Nach lìon sinn a’ bheàrn seo!

JUnit ann an GitLab CI le Kubernetes

Ro-ràdhach

An toiseach, leig dhomh beagan co-theacsa a thoirt seachad:

  • Leis gu bheil na tagraidhean againn uile a’ ruith air Kubernetes, beachdaichidh sinn air deuchainnean a ruith air a’ bhun-structar iomchaidh.
  • Airson co-chruinneachadh agus cleachdadh bidh sinn a 'cleachdadh gaoir (a thaobh co-phàirtean bun-structair, tha seo cuideachd a 'ciallachadh gu bheil Helm an sàs).
  • Cha tèid mi a-steach don fhiosrachadh mu chruthachadh fìor dheuchainnean: anns a ’chùis againn, bidh an neach-dèiligidh a’ sgrìobhadh na deuchainnean e fhèin, agus cha bhith sinn a ’dèanamh cinnteach ach gun tèid an cur air bhog (agus làthaireachd aithisg co-fhreagarrach san iarrtas aonaidh).


Cò ris a bhios an t-sreath choitcheann de ghnìomhan coltach?

  1. A 'togail an tagraidh - fàgaidh sinn an tuairisgeul air an ìre seo.
  2. Cuir an tagradh gu àite ainm air leth de bhuidheann Kubernetes agus tòisich air deuchainn.
  3. A’ lorg artifacts agus a’ parsadh aithisgean JUnit le GitLab.
  4. A' sguabadh às àite ainm a chaidh a chruthachadh roimhe.

A-nis - gu buileachadh!

adjustment

GitLab CI

Feuch an tòisich sinn le criomag .gitlab-ci.yaml, a tha a 'toirt cunntas air cleachdadh an tagraidh agus a' ruith dheuchainnean. Bha an liosta gu math mòr, agus mar sin chaidh a chur ris gu mionaideach le beachdan:

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

A-nis anns an eòlaire .helm/templates cruthaichidh sinn YAML le Job - tests-job.yaml - gus deuchainnean a ruith agus na goireasan Kubernetes a dh’ fheumas e. Faic mìneachaidhean às deidh an liostadh:

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

Dè an seòrsa goireasan air a mhìneachadh san rèiteachadh seo? Nuair a bhios sinn ga chleachdadh, bidh sinn a’ cruthachadh àite-ainm sònraichte airson a’ phròiseict (tha seo air a chomharrachadh ann an .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) agus cuir a-mach e:

  1. Mapa config le sgriobt deuchainn;
  2. Dreuchd le tuairisgeul air a’ pod agus an stiùireadh ainmichte command, a tha dìreach a 'ruith nan deuchainnean;
  3. PV agus PVC, a leigeas leat dàta deuchainn a stòradh.

Thoir aire don t-suidheachadh tòiseachaidh le if aig toiseach an fhollaiseach - a rèir sin, feumaidh faidhlichean YAML eile den chairt Helm leis an tagradh a bhith air am pasgadh a-steach air ais dealbhadh gus nach tèid an cleachdadh aig àm deuchainn. S e sin:

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

Ach, ma tha na deuchainnean feumach air beagan bun-structair (mar eisimpleir, Redis, RabbitMQ, Mongo, PostgreSQL ...) - faodaidh na YAMLn aca a bhith chan eil Tionndaidh dheth. Cuir a-steach iad ann an àrainneachd deuchainn cuideachd ... gan atharrachadh mar a chì thu iomchaidh, gu dearbh.

Cuairt mu dheireadh

Air sgàth tha co-chruinneachadh agus cleachdadh a’ cleachdadh werf fhathast ag obair a-mhàin air an t-seirbheisiche togail (le gitlab-runner), agus tha am pod le deuchainnean air a chuir air bhog air a’ mhaighstir, feumaidh tu eòlaire a chruthachadh /mnt/tests air a' mhaighstir, agus thoir do'n fhear-ruith e, mar eisimpleir, tro NFS. Gheibhear eisimpleir mionaideach le mìneachadh ann an Sgrìobhainnean airson K8.

Bidh an toradh:

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

Chan eil duine a’ toirmeasg co-roinn NFS a dhèanamh gu dìreach air gitlab-runner, agus an uairsin ga chuir suas ann am pods.

thuirt

Is dòcha gu bheil thu a ’faighneachd carson a nì thu a h-uile càil le bhith a’ cruthachadh Iob mas urrainn dhut dìreach sgriobt a ruith le deuchainnean gu dìreach air an ruitheadair sligean? Tha am freagairt gu math tearc ...

Feumaidh cuid de dheuchainnean faighinn chun bhun-structair (MongoDB, RabbitMQ, PostgreSQL, msaa) gus dearbhadh gu bheil iad ag obair gu ceart. Bidh sinn a’ dèanamh deuchainnean aonaichte - leis an dòigh-obrach seo, bidh e furasta a leithid de bhuidhnean a bharrachd a thoirt a-steach. A bharrachd air an seo, gheibh sinn àbhaisteach dòigh-obrach cleachdadh (eadhon ged a bhiodh tu a’ cleachdadh NFS, cur suas a bharrachd de chlàran).

thoradh air

Dè a chì sinn nuair a chuireas sinn an rèiteachadh ullaichte an sàs?

Seallaidh an t-iarrtas aonaidh geàrr-chunntasan airson deuchainnean a chaidh a ruith san loidhne-phìoban as ùire aige:

JUnit ann an GitLab CI le Kubernetes

Faodar gach mearachd a bhriogadh an seo airson mion-fhiosrachadh:

JUnit ann an GitLab CI le Kubernetes

NB: Mothaichidh an leughadair furachail gu bheil sinn a’ dèanamh deuchainn air tagradh NodeJS, agus anns na seallaidhean-sgrìn - .NET… Na gabh iongnadh: is e dìreach nuair a bha thu ag ullachadh an artaigil, cha deach mearachdan sam bith a lorg ann a bhith a’ dèanamh deuchainn air a’ chiad iarrtas, ach tha iad lorgadh ann an tè eile.

co-dhùnadh

Mar a chì thu, chan eil dad iom-fhillte!

Ann am prionnsapal, ma tha neach-cruinneachaidh shligean agad mu thràth agus gu bheil e ag obair, ach nach eil feum agad air Kubernetes, bidh e na obair eadhon nas sìmplidhe a bhith a’ ceangal deuchainn ris na tha air a mhìneachadh an seo. Agus anns Sgrìobhainnean GitLab CI gheibh thu eisimpleirean airson Ruby, Go, Gradle, Maven agus cuid eile.

PS

Leugh cuideachd air ar blog:

Source: www.habr.com

Cuir beachd ann