Չնայած այն հանգամանքին, որ բոլորը հիանալի գիտեն, որ ձեր ծրագրաշարի փորձարկումը կարևոր և անհրաժեշտ է, և շատերը դա անում են ավտոմատ կերպով երկար ժամանակ, Habr-ի հսկայական տարածքում չկար նման հանրաճանաչ արտադրանքների համադրություն ստեղծելու ոչ մի բաղադրատոմս: այս տեղը որպես (մեր սիրելի) GitLab և JUnit: Եկեք լրացնենք այս բացը։
Ներածական
Նախ, թույլ տվեք որոշակի ենթատեքստ տալ.
Քանի որ մեր բոլոր հավելվածներն աշխատում են Kubernetes-ով, մենք կքննարկենք համապատասխան ենթակառուցվածքի վրա թեստերի անցկացումը:
Հավաքման և տեղակայման համար մենք օգտագործում ենք վերֆ (ենթակառուցվածքի բաղադրիչների առումով սա նաև ինքնաբերաբար նշանակում է, որ Helm-ը ներգրավված է):
Ես չեմ խորանա թեստերի իրական ստեղծման մանրամասների մեջ. մեր դեպքում հաճախորդը ինքն է գրում թեստերը, և մենք միայն ապահովում ենք դրանց գործարկումը (և միաձուլման հարցումում համապատասխան զեկույցի առկայությունը):
Ինչպիսի՞ն կլինի գործողությունների ընդհանուր հաջորդականությունը:
Հավելվածի կառուցում - մենք բաց կթողնենք այս փուլի նկարագրությունը:
Տեղադրեք հավելվածը Kubernetes կլաստերի առանձին անվանատարածքում և սկսեք փորձարկումը:
Արտեֆակտների որոնում և JUnit հաշվետվությունների վերլուծություն GitLab-ի հետ:
Նախկինում ստեղծված անվանատարածքի ջնջում:
Այժմ՝ դեպի իրականացում:
հարմարեցում
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 եկեք ստեղծենք YAML Job-ի հետ - tests-job.yaml — թեստեր և Kubernetes-ի համար անհրաժեշտ ռեսուրսներ գործարկելու համար: Դիտեք բացատրությունները ցուցակագրելուց հետո.
Ինչպիսի ռեսուրսներ նկարագրված է այս կազմաձևում. Տեղադրելիս մենք ստեղծում ենք եզակի անվանատարածք նախագծի համար (սա նշված է .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) և տարածիր այն.
ConfigMap թեստային սցենարով;
Աշխատանք պատի նկարագրությամբ և նշված հրահանգով command, որը պարզապես կատարում է թեստերը;
PV և PVC, որը թույլ է տալիս պահպանել թեստի տվյալները:
Ուշադրություն դարձրեք ներածական պայմանի հետ if մանիֆեստի սկզբում, համապատասխանաբար, Helm աղյուսակի այլ YAML ֆայլերը դիմումի հետ պետք է փաթաթվեն հակադարձ նախագծել այնպես, որ դրանք չտեղակայվեն փորձարկման ընթացքում: Այն է:
{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}
Այնուամենայնիվ, եթե թեստերը պահանջում են որոշակի ենթակառուցվածք (օրինակ՝ Redis, RabbitMQ, Mongo, PostgreSQL...) - նրանց YAML-ները կարող են լինել. ոչ անջատել. Տեղադրեք դրանք նաև թեստային միջավայրում…, իհարկե, հարմարեցնելով դրանք, ինչպես ձեզ հարմար է:
Վերջնական հպում
Որովհետեւ հավաքում և տեղակայում` օգտագործելով werf-ի աշխատանքները միայն build սերվերի վրա (gitlab-runner-ով), և թեստերով pod-ը գործարկվում է վարպետի վրա, ձեզ հարկավոր է ստեղծել գրացուցակ /mnt/tests վարպետի վրա և տվեք այն վազորդին, օրինակ՝ NFS-ի միջոցով. Բացատրություններով մանրամասն օրինակ կարելի է գտնել այստեղ K8s փաստաթղթեր.
Ոչ ոք չի արգելում NFS-ի բաժնետոմս պատրաստել անմիջապես gitlab-runner-ում, այնուհետև տեղադրել այն pods-ում:
Նշում
Դուք կարող եք հարցնել, թե ինչու՞ ամեն ինչ բարդացնել՝ ստեղծելով Աշխատանք, եթե դուք կարող եք պարզապես գործարկել սկրիպտը թեստերով անմիջապես shell runner-ի վրա: Պատասխանը բավականին տրիվիալ է...
Որոշ թեստեր պահանջում են մուտք դեպի ենթակառուցվածք (MongoDB, RabbitMQ, PostgreSQL և այլն)՝ ստուգելու, որ դրանք ճիշտ են աշխատում: Մենք թեստավորումը դարձնում ենք միասնական. այս մոտեցմամբ հեշտ է դառնում նման լրացուցիչ սուբյեկտների ընդգրկումը: Բացի սրանից, մենք ստանում ենք ստանդարտ տեղակայման մոտեցումը (նույնիսկ եթե օգտագործում եք NFS, դիրեկտորիաների լրացուցիչ տեղադրում):
Արդյունք
Ի՞նչ կտեսնենք, երբ կիրառենք պատրաստված կոնֆիգուրացիան:
Միաձուլման հարցումը ցույց կտա ամփոփ վիճակագրություն իր վերջին խողովակաշարում իրականացվող թեստերի համար.
Մանրամասների համար յուրաքանչյուր սխալ կարող եք սեղմել այստեղ՝
NBՈւշադիր ընթերցողը կնկատի, որ մենք փորձարկում ենք NodeJS հավելվածը, իսկ սքրինշոթներում՝ .NET... Չզարմանաք, պարզապես հոդվածը պատրաստելիս սխալներ չեն հայտնաբերվել առաջին հավելվածի փորձարկման ժամանակ, սակայն դրանք. հայտնաբերվել են մեկ այլ.
Ամփոփում
Ինչպես տեսնում եք, ոչ մի բարդ բան չկա:
Սկզբունքորեն, եթե դուք արդեն ունեք կեղևի կոլեկցիոներ, և այն աշխատում է, բայց ձեզ Kubernetes-ի կարիք չկա, դրա վրա թեստավորումը կցելը նույնիսկ ավելի պարզ խնդիր կլինի, քան նկարագրված է այստեղ: Եվ մեջ GitLab CI փաստաթղթեր Դուք կգտնեք օրինակներ Ruby-ի, Go-ի, Gradle-ի, Maven-ի և մի քանիսի համար: