علیرغم این واقعیت که همه به خوبی میدانند که تست نرمافزار شما مهم و ضروری است و بسیاری مدتهاست که این کار را به صورت خودکار انجام میدهند، اما در وسعت هابر حتی یک دستورالعمل برای راهاندازی ترکیبی از چنین محصولات محبوبی وجود نداشت. این طاقچه به عنوان (مورد علاقه ما) 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 در ابتدای مانیفست - بر این اساس، سایر فایل های YAML نمودار Helm با برنامه باید در بسته بندی شوند معکوس طوری طراحی کنید که در طول آزمایش مستقر نشوند. به این معنا که:
{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}
با این حال، اگر آزمایشات نیاز به زیرساخت (به عنوان مثال، Redis، RabbitMQ، Mongo، PostgreSQL...) - YAML های آنها می تواند باشد هیچ خاموش کردن آنها را در یک محیط آزمایشی نیز مستقر کنید... البته آنها را به دلخواه تنظیم کنید.
لمس نهایی
زیرا مونتاژ و استقرار با استفاده از werf در حال حاضر کار می کند تنها در سرور بیلد (با gitlab-runner)، و پاد با تستها روی Master راهاندازی میشود، باید یک دایرکتوری ایجاد کنید. /mnt/tests روی استاد و آن را به دونده بدهید، به عنوان مثال، از طریق NFS. یک مثال مفصل با توضیحات را می توان در اینجا یافت مستندات K8s.
هیچ کس ایجاد اشتراک NFS را مستقیماً روی gitlab-runner و سپس نصب آن در پادها را ممنوع نمی کند.
یادداشت
ممکن است بپرسید که چرا همه چیز را با ایجاد یک Job پیچیده میکنید، اگر به سادگی میتوانید یک اسکریپت را با آزمایشهایی مستقیماً روی شلرانر اجرا کنید؟ پاسخ کاملاً پیش پا افتاده است ...
برخی از تستها نیاز به دسترسی به زیرساخت (MongoDB، RabbitMQ، PostgreSQL، و غیره) دارند تا بررسی شود که درست کار میکنند. ما آزمایش را یکپارچه می کنیم - با این رویکرد، گنجاندن چنین موجودیت های اضافی آسان می شود. علاوه بر این، ما دریافت می کنیم استاندارد رویکرد استقرار (حتی در صورت استفاده از NFS، نصب اضافی دایرکتوری ها).
نتیجه
وقتی پیکربندی آماده شده را اعمال می کنیم چه خواهیم دید؟
درخواست ادغام، آمار خلاصه ای را برای آزمایش های انجام شده در آخرین خط لوله خود نشان می دهد:
هر خطا را می توان برای جزئیات اینجا کلیک کرد:
NB: خواننده با دقت متوجه می شود که ما در حال آزمایش یک برنامه NodeJS هستیم و در تصاویر - .NET... تعجب نکنید: فقط در هنگام آماده سازی مقاله، هیچ خطایی در آزمایش برنامه اول مشاهده نشد، اما آنها در دیگری یافت شدند.
نتیجه
همانطور که می بینید، هیچ چیز پیچیده ای نیست!
در اصل، اگر قبلاً یک کلکتور پوسته دارید و کار می کند، اما به Kubernetes نیاز ندارید، اتصال آزمایش به آن ساده تر از آنچه در اینجا توضیح داده شده است، خواهد بود. و در مستندات GitLab CI نمونه هایی برای Ruby، Go، Gradle، Maven و برخی دیگر را خواهید یافت.