ڪبرنيٽس سان گڏ GitLab CI ۾ JUnit

ان حقيقت جي باوجود ته هرڪو چڱيءَ طرح ڄاڻي ٿو ته توهان جي سافٽ ويئر کي جانچڻ ضروري ۽ ضروري آهي، ۽ ڪيترائي اهو پاڻمرادو هڪ ڊگهي وقت کان ڪري رهيا آهن، حبر جي وسعت ۾ اهڙين مشهور پروڊڪٽس جي ميلاپ کي ترتيب ڏيڻ لاءِ هڪ به طريقو نه هو. هي جڳهه جيئن (اسان جي پسنديده) GitLab ۽ JUnit. اچو ته هن خال کي ڀريون!

ڪبرنيٽس سان گڏ GitLab CI ۾ JUnit

تعارفي

پهرين، مون کي ڪجهه حوالو ڏيو:

  • جيئن ته اسان جون سڀئي ايپليڪيشنون Kubernetes تي هلنديون آهن، اسان مناسب انفراسٽرڪچر تي هلندڙ ٽيسٽن تي غور ڪنداسين.
  • اسيمبلي ۽ ٺهڻ لاءِ اسان استعمال ڪندا آهيون werf (بنيادي حصن جي لحاظ کان، اهو پڻ خودڪار طريقي سان مطلب آهي ته هيلم شامل آهي).
  • مان ٽيسٽن جي حقيقي تخليق جي تفصيل ۾ نه ويندس: اسان جي صورت ۾، ڪلائنٽ پاڻ ٽيسٽ لکندو آهي، ۽ اسان صرف انهن جي لانچ کي يقيني بڻائيندا آهيون (۽ انضمام جي درخواست ۾ هڪ لاڳاپيل رپورٽ جي موجودگي).


عملن جو عام سلسلو ڇا ٿيندو؟

  1. ايپليڪيشن جي تعمير - اسان هن اسٽيج جي وضاحت کي ختم ڪنداسين.
  2. ايپليڪيشن کي ڪبرنيٽس ڪلستر جي الڳ نالي واري جاءِ تي لڳايو ۽ جاچ شروع ڪريو.
  3. GitLab سان JUnit رپورٽن کي پارس ڪرڻ ۽ نمونن جي ڳولا.
  4. اڳ ۾ ٺهيل نالي جي جاء کي ختم ڪرڻ.

هاڻي - لاڳو ڪرڻ لاء!

adjustment

گٽ لاب سي

اچو ته هڪ ٽڪرا سان شروع ڪريون .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، وغيره.) انهي جي تصديق ڪرڻ لاءِ ته اهي صحيح ڪم ڪن ٿا. اسان ٽيسٽنگ کي متحد ڪريون ٿا - هن طريقي سان، اهڙين اضافي ادارن کي شامل ڪرڻ آسان ٿي وڃي ٿو. ان کان علاوه، اسان حاصل ڪريون ٿا معياري لڳائڻ جو طريقو (جيتوڻيڪ اين ايف ايس استعمال ڪندي، ڊائريڪٽرن جي اضافي اضافو).

نتيجي ۾

اسان ڇا ڏسندا سين جڏهن اسان تيار ڪيل ترتيب لاڳو ڪنداسين؟

ضم ڪرڻ جي درخواست ان جي تازي پائپ لائن ۾ هلندڙ ٽيسٽن لاءِ خلاصو انگ اکر ڏيکاريندي:

ڪبرنيٽس سان گڏ GitLab CI ۾ JUnit

هر غلطي تفصيل لاءِ هتي ڪلڪ ڪري سگهجي ٿي:

ڪبرنيٽس سان گڏ GitLab CI ۾ JUnit

NB: ڌيان ڏيڻ وارو پڙهندڙ اهو محسوس ڪندو ته اسان هڪ NodeJS ايپليڪيشن جي جانچ ڪري رهيا آهيون، ۽ اسڪرين شاٽ ۾ - .NET... حيرت نه ٿيو: اهو صرف اهو آهي ته مضمون تيار ڪرڻ وقت، پهرين ايپليڪيشن کي جانچڻ ۾ ڪا به غلطي نه ملي، پر اهي ٻئي ۾ مليا هئا.

ٿڪل

جئين توهان ڏسي سگهو ٿا، ڪجھ به پيچيده ناهي!

اصولي طور تي، جيڪڏهن توهان وٽ اڳ ۾ ئي شيل ڪليڪٽر آهي ۽ اهو ڪم ڪري ٿو، پر توهان کي ڪبرنيٽس جي ضرورت ناهي، ان کي جانچڻ سان ڳنڍڻ هڪ وڌيڪ آسان ڪم هوندو جيڪو هتي بيان ڪيو ويو آهي. ۽ اندر GitLab CI دستاويز توهان روبي، گو، گرڊل، ماون ۽ ڪجهه ٻين جا مثال ڳوليندا.

پي ايس

اسان جي بلاگ تي پڻ پڙهو:

جو ذريعو: www.habr.com

تبصرو شامل ڪريو