JUnit په GitLab CI کې د Kubernetes سره

د دې حقیقت سره سره چې هرڅوک ښه پوهیږي چې ستاسو د سافټویر ازموینه مهمه او اړینه ده، او ډیری یې دا د اوږدې مودې لپاره په اوتومات ډول ترسره کوي، د هابر په پراخه کچه کې د داسې مشهور محصولاتو ترکیب ترتیب کولو لپاره یو ترکیب شتون نلري. دا ځای د (زموږ غوره) GitLab او JUnit په توګه. راځئ چې دا تشه ډکه کړو!

JUnit په GitLab CI کې د Kubernetes سره

تعارفي

لومړی، اجازه راکړئ یو څه شرایط وړاندې کړم:

  • څرنګه چې زموږ ټول غوښتنلیکونه په Kubernetes کې پرمخ ځي، موږ به په مناسبو زیربناوو کې د ازموینې چلولو په اړه غور وکړو.
  • د اسمبلۍ او پلي کولو لپاره موږ کاروو werf (د زیربنایي برخو په برخه کې، دا په اتوماتيک ډول د دې معنی لري چې هیلم دخیل دی).
  • زه به د ازموینو ریښتیني رامینځته کولو توضیحاتو ته لاړ نه شم: زموږ په قضیه کې ، پیرودونکي پخپله ازموینې لیکي ، او موږ یوازې د دوی پیل تضمین کوو (او د ادغام غوښتنه کې د ورته راپور شتون).


د کړنو عمومي ترتیب به څه ډول ښکاري؟

  1. د غوښتنلیک جوړول - موږ به د دې مرحلې توضیحات پریږدو.
  2. غوښتنلیک د Kubernetes کلستر جلا نوم ځای ته ځای په ځای کړئ او ازموینه پیل کړئ.
  3. د هنري آثارو لټون کول او د GitLab سره د JUnit راپورونه تحلیل کول.
  4. مخکې جوړ شوی نوم ځای ړنګول.

اوس - د پلي کولو لپاره!

تعدیلات

ګیت لیب سی آی

راځئ چې د یوې ټوټې سره پیل وکړو .gitlab-ci.yaml، کوم چې د غوښتنلیک پلي کول او د ازموینو چلولو تشریح کوي. لیست خورا لوی و ، نو دا په بشپړ ډول د نظرونو سره ضمیمه شوی و:

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

کوبنیټس

اوس په لارښود کې .helm/templates راځئ چې د دندې سره YAML جوړ کړو - tests-job.yaml - د ازموینو چلولو لپاره او د کوبرنیټس سرچینې ورته اړتیا لري. د لیست کولو وروسته توضیحات وګورئ:

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

څه ډول سرچینې په دې ترتیب کې تشریح شوي؟ کله چې ځای پرځای کول، موږ د پروژې لپاره یو ځانګړی نوم ځای جوړوو (دا په دې کې اشاره شوې .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) او راوګرځوئ:

  1. ConfigMap د ازموینې سکریپټ سره؛
  2. دنده د پوډ تشریح او ټاکل شوي لارښود سره command، کوم چې یوازې ازموینې پرمخ وړي؛
  3. PV او PVC، کوم چې تاسو ته اجازه درکوي د ازموینې ډاټا ذخیره کړئ.

د ابتدايي حالت ته پام وکړئ if د منشور په پیل کې - په دې اساس، د غوښتنلیک سره د هیلم چارټ نورې YAML فایلونه باید لپاس شي بيرته ډیزاین ترڅو دوی د ازموینې پرمهال ځای په ځای نشي. هغه دی:

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

په هرصورت، که ازموینې یو څه زیربنا ته اړتیا لري (د مثال په توګه، Redis، RabbitMQ، Mongo، PostgreSQL...) - د دوی YAMLs کیدی شي نه بندول. دوی د ازموینې چاپیریال کې هم ځای په ځای کړئ ... د دوی تنظیم کول لکه څنګه چې تاسو مناسب ګورئ، البته.

وروستی لمس

ځکه د اوس لپاره د werf کار کولو په کارولو سره مجلس او ځای پرځای کول یوازې په جوړ سرور کې (د ګیټلاب-رنر سره) ، او د ازموینو سره پوډ په ماسټر کې پیل شوی ، تاسو به اړتیا ولرئ لارښود جوړ کړئ /mnt/tests په ماسټر باندې او منډې ته یې ورکړئ، د مثال په توګه، د NFS له لارې. یو مفصل مثال د توضیحاتو سره موندل کیدی شي د K8s اسناد.

پایله به دا وي:

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

هیڅوک د NFS شریکولو څخه په مستقیم ډول په ګیټلاب-رنر کې منع نه کوي، او بیا یې په پوډونو کې نصب کړي.

تبصره

تاسو شاید پوښتنه وکړئ چې ولې د دندې رامینځته کولو سره هرڅه پیچلي کوئ که تاسو کولی شئ په ساده ډول د شیل رنر کې د ازموینې سره سکریپټ چلولی شئ؟ ځواب خورا کوچنی دی ...

ځینې ​​​​ازموینې زیربنا ته لاسرسی ته اړتیا لري (MongoDB، RabbitMQ، PostgreSQL، او نور) ترڅو تصدیق کړي چې دوی سم کار کوي. موږ ازموینه متحد کوو - د دې طریقې سره، د داسې اضافي ادارو شاملول اسانه کیږي. د دې سربیره، موږ ترلاسه کوو معياري د ګمارلو طریقه (حتی که د NFS کارول، د لارښودونو اضافي نصب کول).

نتيجه

موږ به څه وګورو کله چې موږ چمتو شوي ترتیب پلي کړو؟

د ادغام غوښتنه به په وروستي پایپ لاین کې د ازموینو لپاره لنډیز احصایې وښیې:

JUnit په GitLab CI کې د Kubernetes سره

هره تېروتنه د جزیاتو لپاره دلته کلیک کیدی شي:

JUnit په GitLab CI کې د Kubernetes سره

NB: پام لرونکی لوستونکی به په دې پوه شي چې موږ د NodeJS غوښتنلیک ازموینه کوو، او په سکرین شاټونو کې - .NET... حیرانتیا مه کوئ: دا یوازې د مقالې چمتو کولو پرمهال د لومړي غوښتنلیک په ازموینه کې کومه تېروتنه ونه موندل شوه، مګر دوی په بل کې وموندل شول.

پایلې

لکه څنګه چې تاسو لیدلی شئ، هیڅ شی پیچلي ندي!

په اصولو کې ، که تاسو دمخه د شیل راټولونکی لرئ او دا کار کوي ، مګر تاسو کوبرنیټس ته اړتیا نلرئ ، پدې کې د ازموینې ضمیمه کول به د دې په پرتله خورا ساده کار وي چې دلته تشریح شوي. او په د GitLab CI اسناد تاسو به د روبي، Go، Gradle، Maven او ځینو نورو لپاره مثالونه ومومئ.

PS

زموږ په بلاګ کې هم ولولئ:

سرچینه: www.habr.com

Add a comment