Nahiz eta denek ondo daki zure softwarea probatzea garrantzitsua eta beharrezkoa dela, eta askok denbora luzez automatikoki egiten duten arren, Habr-en zabaltasunean ez zegoen errezeta bakar bat ere produktu ezagunen konbinazio bat ezartzeko. nitxo hau (gure gogokoena) GitLab eta JUnit gisa. Bete dezagun hutsune hau!
Sarrera
Lehenik eta behin, testuinguru bat emango dut:
Gure aplikazio guztiak Kubernetesen exekutatzen direnez, azpiegitura egokian probak egitea kontuan hartuko dugu.
Muntatzeko eta hedatzeko erabiltzen dugu werf (azpiegitura osagaiei dagokienez, honek automatikoki ere esan nahi du Helm parte hartzen duela).
Ez naiz proben benetako sorreraren xehetasunetan sartuko: gure kasuan, bezeroak berak idazten ditu probak, eta haien abiaraztearen (eta bateratze-eskaeran dagokion txostena egotea) bermatzen dugu soilik.
Nolakoa izango da ekintzen sekuentzia orokorra?
Aplikazioa eraikitzea - etapa honen deskribapena alde batera utziko dugu.
Inplementatu aplikazioa Kubernetes klusterraren izen-eremu bereizi batean eta hasi probak egiten.
Artefaktuak bilatzea eta JUnit txostenak analizatzea GitLab-ekin.
Aurretik sortutako izen-espazio bat ezabatzea.
Orain - inplementaziora!
doikuntza
GitLab CI
Has gaitezen zati batekin .gitlab-ci.yaml, aplikazioa zabaldu eta probak exekutatzen deskribatzen dituena. Zerrenda nahiko handia izan zen, beraz, iruzkinekin osatu zen:
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
Orain direktorioan .helm/templates sor dezagun YAML Jobekin - tests-job.yaml — probak eta behar dituen Kubernetes baliabideak exekutatzeko. Ikusi azalpenak zerrendatu ondoren:
Nolako baliabideak konfigurazio honetan deskribatuta? Inplementatzean, proiekturako izen-espazio esklusibo bat sortzen dugu (hau atalean adierazten da .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) eta zabaldu:
ConfigMap probako gidoiarekin;
Lana podaren deskribapenarekin eta zehaztutako zuzentarauarekin command, probak bakarrik egiten dituena;
PV eta PVC, probaren datuak gordetzeko aukera ematen dutenak.
Erreparatu hasierako baldintzarekin if manifestuaren hasieran - horren arabera, aplikazioarekin Helm diagramaren beste YAML fitxategiak bildu behar dira. alderantziz diseinatu, probak zehar hedatu ez daitezen. Hori da:
{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}
Hala ere, probak bada azpiegitura batzuk behar ditu (adibidez, Redis, RabbitMQ, Mongo, PostgreSQL...) - haien YAMLak izan daitezke ez itzali. Inplementatu itzazu proba-ingurune batean ere... egoki deritzon moduan egokituz, noski.
Azken ukitua
Zeren werf lanak erabiliz muntaia eta hedapena oraingoz bakarrik eraikitzeko zerbitzarian (gitlab-runner-ekin), eta probak dituen poda maisuan abiarazten da, direktorioa sortu beharko duzu /mnt/tests maisuaren gainean eta eman korrikalariari, adibidez, NFS bidez. Adibide zehatza azalpenekin aurki daiteke K8s dokumentazioa.
Inork ez du debekatzen NFS partekatze bat zuzenean gitlab-runner-en egitea, eta gero podetan muntatzea.
Kontuan izan
Galdetuko duzu zergatik zaildu dena Lan bat sortuz, probak dituen script bat exekutatu besterik ez baduzu shell runner-ean? Erantzuna nahiko hutsala da...
Proba batzuek azpiegiturarako sarbidea behar dute (MongoDB, RabbitMQ, PostgreSQL, etab.) behar bezala funtzionatzen dutela egiaztatzeko. Probak bateratu egiten ditugu; ikuspegi honekin, erraza da horrelako entitate gehigarriak sartzea. Honetaz gain, lortzen dugu estandarra inplementazio ikuspegia (nahiz eta NFS erabili, direktorioen muntaketa gehigarria).
Emaitza
Zer ikusiko dugu prestatutako konfigurazioa aplikatzen dugunean?
Batzeko eskaerak bere azken kanalean exekutatzen diren proben laburpen-estatistikak erakutsiko ditu:
Akats bakoitza hemen klik egin daiteke xehetasunetarako:
NB: Irakurle adiak NodeJS aplikazio bat probatzen ari garela ohartuko da, eta pantaila-argazkietan - .NET... Ez harritu: artikulua prestatzerakoan ez dela akatsik aurkitu lehen aplikazioa probatzean, baina beste batean aurkitu ziren.
Ondorioa
Ikusten duzun bezala, ezer konplikatua!
Printzipioz, lehendik shell biltzaile bat baduzu eta funtzionatzen badu, baina ez baduzu Kubernetes behar, probak eranstea hemen deskribatzen dena baino zeregin are errazagoa izango da. Eta barruan GitLab CI dokumentazioa Ruby, Go, Gradle, Maven eta beste batzuen adibideak aurkituko dituzu.