ሶፍትዌርዎን መሞከር አስፈላጊ እና አስፈላጊ መሆኑን ሁሉም ሰው ቢያውቅም፣ እና ብዙዎች ለረጅም ጊዜ በራስ-ሰር ሲያደርጉት ቢቆዩም፣ በዚህ ልዩ ቦታ (እንደ ተወዳጅ) GitLab እና JUnit ያሉ ታዋቂ ምርቶችን ጥምረት ለማዘጋጀት ስለ Habr አንድም መመሪያ ማግኘት አልቻልንም። ይህንን ክፍተት እንሙላ!

መግቢያ
በመጀመሪያ፣ አውዱን ላስቀምጥ፦
- ሁሉም አፕሊኬሽኖቻችን በኩበርኔትስ ላይ ስለሚሰሩ፣ በተዛማጅ መሠረተ ልማት ላይ ሙከራዎችን እናካሂዳለን።
- ለመገጣጠም እና ለማሰማራት እንጠቀማለን (በመሠረተ ልማት ክፍሎች ረገድ፣ ይህ ማለት ሄልም ተሳታፊ ነው ማለት ነው)።
- በቀጥታ ሙከራዎችን ስለመፍጠር ዝርዝር ጉዳዮች አልገባም፤ በእኛ ሁኔታ፣ ደንበኛው ፈተናዎቹን የሚጽፈው እራሳቸው ናቸው፣ እና እኛ የምናረጋግጠው እነሱ መሄዳቸውን ብቻ ነው (እና ተጓዳኝ ሪፖርቱ በውህደት ጥያቄው ውስጥ መኖሩን)።
የአጠቃላይ የድርጊቶች ቅደም ተከተል ምን ይመስላል?
- አፕሊኬሽኑን ማሰባሰብ - የዚህን ደረጃ መግለጫ እናስወግዳለን።
- መተግበሪያውን ወደተለየ የኩበርኔትስ ክላስተር የስም ቦታ ያሰማሩ እና ሙከራውን ያሂዱ።
- በGitLab የተዘጋጁ የJUnit ሪፖርቶችን መተንተን እና ቅርሶችን መፈለግ።
- ቀደም ሲል የተፈጠረ የስም ቦታን በመሰረዝ ላይ።
አሁን ወደ ተግባራዊነት እንሂድ!
በደንብ ማድረግ
GitLab CI
በአንድ ቁራጭ እንጀምር .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 ከJob ጋር 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}) እና እኛ እንገልጸዋለን፡
- ConfigMap ከሙከራ ስክሪፕት ጋር፤
- ሥራ ከፖድ መግለጫው እና ከተጠቀሰው መመሪያ ጋር
command, ይህም ፈተናዎችን የሚያካሂደው ነው; - ፒቪ እና ፒቪሲየሙከራ ውሂብን እንዲያከማቹ የሚያስችልዎ።
የመግቢያ ሁኔታውን እባክዎ ልብ ይበሉ ከ ጋር if በማኒፌስቱ መጀመሪያ ላይ - በዚህ መሠረት፣ ከመተግበሪያው ጋር የሄልም ገበታ ሌሎች የYAML ፋይሎች መጠቅለል አለባቸው። ተገላቢጦሽ በሙከራ ጊዜ እንዳይተገበሩ ዲዛይን ያድርጉ። ይህም፡
{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}
ሆኖም ግን፣ ፈተናዎች ካሉ የተወሰነ መሠረተ ልማት ይፈልጋል (ለምሳሌ፣ Redis፣ RabbitMQ፣ Mongo፣ PostgreSQL…) — የYAML ዝርዝራቸው ሊሆን ይችላል አይደለም አጥፋቸው። እንዲሁም ወደ የሙከራ አካባቢው አሰማራቸው... በእርግጥ፣ እንደፈለጉ አስተካክሏቸው።
የመጨረሻ ንክኪ
ምክንያቱም ከዌርፍ ጋር መገንባትና ማሰማራት አሁንም ይሰራል። ብቻ በግንባታ አገልጋይ (ከ gitlab-runner ጋር) ላይ፣ እና ሙከራዎች ያሉት ፖድ በዋናው ላይ ይሰራል፣ ማውጫ መፍጠር ያስፈልግዎታል። /mnt/tests በጌታው ላይ እና ለፈጣሪው ስጡት፣ ለምሳሌ፣ በNFS በኩልማብራሪያዎችን የያዘ ዝርዝር ምሳሌ በ ውስጥ ማግኘት ይቻላል .
ውጤቱም የሚከተለው ይሆናል፦
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
በ gitlab-runner ላይ የNFS ማጋራትን በቀጥታ ከመፍጠር እና ከዚያም በፖድ ውስጥ ከመጫን ማንም አያግድዎትም።
አመለከተ
ምናልባት፣ በቀጥታ በሼል ሯጭ ላይ ሙከራዎችን የያዘ ስክሪፕት ማስኬድ ሲችሉ ለምን ስራ መፍጠር ይቸገራሉ ብለህ ታስብ ይሆናል? መልሱ በጣም ቀላል ነው…
አንዳንድ ሙከራዎች ተገቢውን አሠራር ለማረጋገጥ የመሠረተ ልማት (MongoDB፣ RabbitMQ፣ PostgreSQL፣ ወዘተ) መዳረሻ ያስፈልጋቸዋል። ሙከራውን አንድ እናደርጋለን - ይህ አካሄድ እንደዚህ ያሉ ተጨማሪ አካላትን ማካተት ቀላል ያደርገዋል። በተጨማሪም፣ እናገኛለን መደበኛ የማሰማራት አቀራረብ (NFS እና ተጨማሪ ማውጫዎችን በመጫንም ቢሆን)።
ውጤት
የተዘጋጀውን ውቅር ስንተገብር ምን እናያለን?
የውህደት ጥያቄው በቅርብ ጊዜ በተሰራው የፈተና መስመር ውስጥ ለሚካሄዱት ሙከራዎች የማጠቃለያ ስታቲስቲክስን ያሳያል፡

እዚህ ላይ ለዝርዝሮች እያንዳንዱ ስህተት እዚህ ጠቅ ሊደረግ ይችላል፦

NB፦ ትኩረት የሚስብ አንባቢ የNodeJS መተግበሪያ እየሞከርን መሆኑን ያስተውላል፣ ቅጽበታዊ ገጽ እይታዎቹ .NET እየተጠቀሙ ነው... አትገረሙ፡ ይህንን ጽሑፍ በማዘጋጀት ላይ ሳለ፣ የመጀመሪያውን መተግበሪያ በመሞከር ላይ ምንም አይነት ስህተት አላገኘንም፣ ነገር ግን በሌላኛው ውስጥ አግኝተናቸዋል።
መደምደሚያ
እንደምታየው ምንም ውስብስብ ነገር የለም!
በመርህ ደረጃ፣ የሼል ገንቢ ካለዎት እና እየሰራ ከሆነ እና ኩበርኔትስ የማያስፈልግዎ ከሆነ፣ ሙከራን መጨመር እዚህ ከተገለጸው የበለጠ ቀላል ስራ ይሆናል። ለሩቢ፣ ጎ፣ ግራድል፣ ማቨን እና ሌሎችም ምሳሌዎችን ያገኛሉ።
PS
በብሎጋችን ላይ ያንብቡ፡-
- «";
- «";
- «».
ምንጭ: hab.com
