Пайплайн gitlab для Spring REST приложения. Часть 3

от автора

Для выполнения этой стадии необходимо подготовиться.

  1. Устанавливаем sonarqube на сервер. Как вы это сделаете — на ваше усмотрение, я предпочитаю везде по возможности использовать docker, поэтому просто выполняю команду docker run -d -p 9000:9000 sonarqube

  2. Авторизуемся в админке sonarqube и настраиваем токены, для этого прямо в админке есть подробная инструкция.

  1. Добавьте необходимые строки для работы проекта с sonarqube в файл build.gradle, после чего в gradle у нас появляются новые таски для sonarqube:

После подготовки добавляем новую стадию в наш пайплайн.

variables:   SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"   GIT_DEPTH: "0" stages:   - feature   - feature-artefact   - feature-clean-stand   - feature-install-stand   - test feature development:   tags:     - feature   stage: feature   image: gradle:7.5.0-jdk11   script:     - cd rest-service     - ./gradlew assemble  feature docker image:   tags:     - feature   stage: feature-artefact   script:     - cd rest-service     - ./gradlew jibDockerBuild        feature clean stand:   tags:     - feature   stage: feature-clean-stand   allow_failure: true   script:     - cd rest-service/.chart     - helm uninstall docker-compose-feature --namespace=yamangulov-feature    feature install stand:   tags:     - feature   stage: feature-install-stand   script:     - cd rest-service/.chart/     - helm install docker-compose-feature docker-compose --namespace=yamangulov-feature --values=docker-compose/values-yamangulov-feature.yaml  testing:   stage: test   image: gradle:7.5.0-jdk11   cache:     key: "${CI_JOB_NAME}"     paths:       - .sonar/cache   script:     - cd rest-service     - gradle sonarqube -Dsonar.qualitygate.wait=true   rules:     - if: '$CI_BUILD_REF_NAME != "main" && $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"' 

Стадия тестирования разворачивает приложение в docker- контейнере и затем выполняет в gradle таску для проведения unit-тестов (конечно, нужно их написать в приложении) и прочие проверки. После выполнения стадии необходимо зайти в админку и просмотреть результаты проверок (sonarqube очень подробно распишет вам, где что не так), если нужно — доработать код для устранения недостатков и запустить пайплайн снова.

Стадии для smoke и регрессионного тестирования

Сами по себе настройки этих стадий в файле gitlab-ci.yml довольно просты, мы просто поднимаем приложение в контейнере и запускаем нужные таски gradle, которые сами и выполнят нужные тесты:

variables:   SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"   GIT_DEPTH: "0" stages:   - feature   - feature-artefact   - feature-clean-stand   - feature-install-stand   - test   - smoke   - regress feature development:   tags:     - feature   stage: feature   image: gradle:7.5.0-jdk11   script:     - cd rest-service     - ./gradlew assemble  feature docker image:   tags:     - feature   stage: feature-artefact   script:     - cd rest-service     - ./gradlew jibDockerBuild        feature clean stand:   tags:     - feature   stage: feature-clean-stand   allow_failure: true   script:     - cd rest-service/.chart     - helm uninstall docker-compose-feature --namespace=yamangulov-feature    feature install stand:   tags:     - feature   stage: feature-install-stand   script:     - cd rest-service/.chart/     - helm install docker-compose-feature docker-compose --namespace=yamangulov-feature --values=docker-compose/values-yamangulov-feature.yaml  testing:   stage: test   image: gradle:7.5.0-jdk11   cache:     key: "${CI_JOB_NAME}"     paths:       - .sonar/cache   script:     - cd rest-service     - gradle sonarqube -Dsonar.qualitygate.wait=true   rules:     - if: '$CI_BUILD_REF_NAME != "main" && $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"'  smoke testing:   stage: smoke   image: gradle:7.5.0-jdk11   script:     - cd rest-service     - gradle clean integrationTest --tests "*smokeTest*"   rules:     - if: '$CI_BUILD_REF_NAME != "main" && $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"'  regression testing:   stage: regress   image: gradle:7.5.0-jdk11   script:     - cd rest-service     - gradle clean integrationTest --tests "*regressionTest*"   rules:     - if: '$CI_BUILD_REF_NAME != "main" && $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"' 

Интерес здесь представляют только строки, которые запускают выборочно одну отдельно взятую таску gradle по ее названию и выполняют в ней только один выбранный по шаблону тест.. Сложность этих стадий не в их настройке, а в выполнении самих тестов. И здесь приходят на помощь testcontainers — очень полезная библиотека, которая позволяет поднимать специальные контейнеры для интеграционных тестов. Настройки для подключения библиотеки вы можете увидеть в образце файла build.gradle из предыдущей части этой статьи. Написание самих интеграционных тестов может иногда представлять некоторую сложность и зависит от функционала вашего приложения. Как вариант, приведу в качестве образчика, два класса, описывающие, как это делал я для моего приложения:

PostgresContainerWrapper и TestContainer

В основном можно считать, что для большинства приложений выполненных стадий для пайплайна gitlab ci/cd вполне достаточно, если приложения не предполагают достаточно высокой нагрузки. Если речь идет о высоконагруженном приложении, то без нагрузочных тестов уже не обойтись. Тогда необходимо добавить еще одну стадию для них. Поэтому я планирую через некоторое время дополнить статью четвертой завершающей частью, где и будет описываться мой опыт по выполнению нагрузочного тестирования и включения его в пайплайн.

В заключение приглашаю всех на бесплатный урок от моих коллег из OTUS, где в процессе занятия пройдёмся по метрикам и конечным точкам для работы с приложением. Ощутим мощь актуатора и даже напишем свой «индикатор здоровья». Регистрация на урок доступна по ссылке ниже.


ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/695336/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *