Может возникнуть вопрос - что такое groovy.lang.Script? По сути это аналог Object для Groovy скриптов. Да, в Groovy код может быть не только в классах, но и в скриптах https://docs.groovy-lang.org/latest/html/documentation/#_scripts_versus_classes
5) В API своих классов не используем def, всегда объявляем типы явно.
def - это как var в Java, но опаснее, т.к в отличие от Java его можно использовать везде вместо указания типа. Как по мне - использовать def можно только для локальных переменных, т.е по сути я за подход Java.
6) кроме подсветки синтаксиса рекомендую периодически вызывать Inspect Code в IDEA, а лучше повесить его на commit. Не все проверки по умолчанию актуальны для Jenkins pipeline кода, лишние можно отключить.
7) ну и возвращаясь к тестам - по максимуму покрываем код в src тестами. Можно использовать JUnit и Mockito. Тесты при этом пишем на Groovy, чтобы воспользоваться преимуществом компактного синтаксиса Groovy.
to be continued
#devops #ci #unittests #jenkins #groovy
5) В API своих классов не используем def, всегда объявляем типы явно.
def - это как var в Java, но опаснее, т.к в отличие от Java его можно использовать везде вместо указания типа. Как по мне - использовать def можно только для локальных переменных, т.е по сути я за подход Java.
6) кроме подсветки синтаксиса рекомендую периодически вызывать Inspect Code в IDEA, а лучше повесить его на commit. Не все проверки по умолчанию актуальны для Jenkins pipeline кода, лишние можно отключить.
7) ну и возвращаясь к тестам - по максимуму покрываем код в src тестами. Можно использовать JUnit и Mockito. Тесты при этом пишем на Groovy, чтобы воспользоваться преимуществом компактного синтаксиса Groovy.
to be continued
#devops #ci #unittests #jenkins #groovy
Продолжим про тестирование кода джобов Jenkins.
Что еще у нас есть для тестирования.
8) JenkinsPipelineUnit - https://github.com/jenkinsci/JenkinsPipelineUnit По сути набор моков для запуска кода pipeline.
Что может:
а) запуск пайплайн из файла и из строки
б) передача параметров и переменных среды
в) проверка статуса выполнения джобы
г) моки для ряда методов pipeline
д) загрузка shared library
е) возможность добавлять свои моки на команды pipeline или конкретные вызовы sh
ж) печать стектрейса выполнения pipeline
з) сравнение стректрейсов, поиск по вхождению - можно искать были ли выполнена та или иная команда
Из мелких косяков - требует наследования тестового класса от BasePipelineTest, что вышло из моды с появлением Unit 4)))
Из более крупных косяков - по умолчанию многие команды Jenkins DSL не замоканы, при появлении такой команды джоба падает.
То что падает - это правильно, мы же тестируем pipeline. Но часто приходится писать свои mock, примеры: readYaml, readProperties, findFiles.
Mock по умолчанию - ничего не делать. echo выводит данные в лог на машине разработчика.
Могу рекомендовать с ремаркой - моки придется дописывать.
9) Jenkins Test Harness - https://www.jenkins.io/doc/developer/testing/,
Это интеграционное тестирование pipeline. В документации фреймворк предлагается для тех, кто разрабатывает Jenkins или плагины для него.
Можно ли использовать для тестирования своего pipeline и shared libraries - вопрос, дам на него ответ позже.
Коммиты в репозитории есть с 2016 года, но в документации по ссылке выше до сих пор встречаются TODO.
Подключение к тестам в примерах происходит через Rule из JUnit 4 - что тоже намекает.
Что он может:
а) б) в) из списка выше
г) мок для загрузки из SCM
д) проверка записей в логе - как я понял, это в большинстве случаев будет заменой Assert
е) загрузка файлов из среды разработки в workspace
Пока рекомендовать не могу, буду исследовать.
10) com.mkobit.jenkins.pipelines.shared-library - https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin,
Это плагин Gradle для разработки shared libraries. Включает в себя два предыдущих фреймворка. Есть тестовый репо https://github.com/mkobit/jenkins-pipeline-shared-library-example, если взять его как основу для своего проекта - получите из коробки подключение ряда библиотек Jenkins для declarative pipeline, некую версию gdsl и готовый проект, который содержит модульные и интеграционные тесты и проходит build.
Выглядит интересно для начала разработки, я к сожалению в свое время его упустил, по сути сделав аналогичный каркас)
Причем для разработки scripted pipeline мой каркас подходит лучше)
Пока рекомендовать не могу, учитывая комментарии выше.
11) любые тесты не на 100% заменяют запуск с реальными интеграциями. Как организовать интеграционное и функциональное тестирование pipeline, что для этого нужно?
а) создаем или копируем тестовый Java проект, который будем собирать. Ключевое требование - небольшой размер кода, чтобы сборка была быстрой и максимальное использование фичей pipeline. Использование настоящих проектов - плохо, т.к. создаются левые tags, build statuses, что может вводить разработчиков в заблуждение
б) тестовые джобы на Jenkins для всех созданных вами pipeline. Можно даже создать джобу, запускающую в параллель все эти джобы
в) тестовый проект SonarQube
г) тестовые репозитории в Nexus\Artifactory
д) тестовый проект на вашем Git сервере если джобы что-то делают в Git
е) важно: описываем в документации чек-лист - что и когда нужно тестировать при внесении изменений в pipeline
ж) придеживаемся описанных нами правил, это важно)
#devops #ci #unittests #jenkins #groovy
Что еще у нас есть для тестирования.
8) JenkinsPipelineUnit - https://github.com/jenkinsci/JenkinsPipelineUnit По сути набор моков для запуска кода pipeline.
Что может:
а) запуск пайплайн из файла и из строки
б) передача параметров и переменных среды
в) проверка статуса выполнения джобы
г) моки для ряда методов pipeline
д) загрузка shared library
е) возможность добавлять свои моки на команды pipeline или конкретные вызовы sh
ж) печать стектрейса выполнения pipeline
з) сравнение стректрейсов, поиск по вхождению - можно искать были ли выполнена та или иная команда
Из мелких косяков - требует наследования тестового класса от BasePipelineTest, что вышло из моды с появлением Unit 4)))
Из более крупных косяков - по умолчанию многие команды Jenkins DSL не замоканы, при появлении такой команды джоба падает.
То что падает - это правильно, мы же тестируем pipeline. Но часто приходится писать свои mock, примеры: readYaml, readProperties, findFiles.
Mock по умолчанию - ничего не делать. echo выводит данные в лог на машине разработчика.
Могу рекомендовать с ремаркой - моки придется дописывать.
9) Jenkins Test Harness - https://www.jenkins.io/doc/developer/testing/,
Это интеграционное тестирование pipeline. В документации фреймворк предлагается для тех, кто разрабатывает Jenkins или плагины для него.
Можно ли использовать для тестирования своего pipeline и shared libraries - вопрос, дам на него ответ позже.
Коммиты в репозитории есть с 2016 года, но в документации по ссылке выше до сих пор встречаются TODO.
Подключение к тестам в примерах происходит через Rule из JUnit 4 - что тоже намекает.
Что он может:
а) б) в) из списка выше
г) мок для загрузки из SCM
д) проверка записей в логе - как я понял, это в большинстве случаев будет заменой Assert
е) загрузка файлов из среды разработки в workspace
Пока рекомендовать не могу, буду исследовать.
10) com.mkobit.jenkins.pipelines.shared-library - https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin,
Это плагин Gradle для разработки shared libraries. Включает в себя два предыдущих фреймворка. Есть тестовый репо https://github.com/mkobit/jenkins-pipeline-shared-library-example, если взять его как основу для своего проекта - получите из коробки подключение ряда библиотек Jenkins для declarative pipeline, некую версию gdsl и готовый проект, который содержит модульные и интеграционные тесты и проходит build.
Выглядит интересно для начала разработки, я к сожалению в свое время его упустил, по сути сделав аналогичный каркас)
Причем для разработки scripted pipeline мой каркас подходит лучше)
Пока рекомендовать не могу, учитывая комментарии выше.
11) любые тесты не на 100% заменяют запуск с реальными интеграциями. Как организовать интеграционное и функциональное тестирование pipeline, что для этого нужно?
а) создаем или копируем тестовый Java проект, который будем собирать. Ключевое требование - небольшой размер кода, чтобы сборка была быстрой и максимальное использование фичей pipeline. Использование настоящих проектов - плохо, т.к. создаются левые tags, build statuses, что может вводить разработчиков в заблуждение
б) тестовые джобы на Jenkins для всех созданных вами pipeline. Можно даже создать джобу, запускающую в параллель все эти джобы
в) тестовый проект SonarQube
г) тестовые репозитории в Nexus\Artifactory
д) тестовый проект на вашем Git сервере если джобы что-то делают в Git
е) важно: описываем в документации чек-лист - что и когда нужно тестировать при внесении изменений в pipeline
ж) придеживаемся описанных нами правил, это важно)
#devops #ci #unittests #jenkins #groovy
GitHub
GitHub - jenkinsci/JenkinsPipelineUnit: Framework for unit testing Jenkins pipelines
Framework for unit testing Jenkins pipelines . Contribute to jenkinsci/JenkinsPipelineUnit development by creating an account on GitHub.
Всем привет!
Чтобы после моей предыдущей статьи о тестировании пайплайнов Jenkins не сложилось впечатления, что проблем нет и провалидированный IDEA, скомпилированный и оттестированный JUnit и Pipeline Unit тестами код сразу заработает в Jenkins - вот три больших ложки дегтя. Уточню, речь про scripted pipeline.
1) CPS. Детально что это за зверь написано тут https://www.jenkins.io/doc/book/pipeline/cps-method-mismatches/
Суть в том, что при выполнении код пайпа интерпретируется специальным образом, чтобы в любой момент на диске лежал актуальный слепок текущего состояния пайпа и можно было восстановить состояние после рестарта Jenkins. К слову, по моему опыту это не всегда работает, возможно пайпы кривые, возможно есть проблемы с плагинами. При этом далеко не весь вызываемый в runtime код можно так трасформировать, т.е. весь код делится на CPS и NonCPS. Не трансформируется Java standart library код, конструкторы и методы, помеченные @NonCPS. И есть правило - NonCPS код не может вызывать CPS код.
На модульном тесте это проверить невозможно, функционал PipelineUnit для этого по факту не работает.
2) Groovy DSL. Код пишется не на Groovy, а на Groovy DSL, а это две большие разницы) ну может не совсем большие, но точно разницы. Т.е. почитав доки по Groovy ты видишь там разные крутые фичи, думаешь - о, а у него есть плюсы по сравнению в Java, пробуешь их использовать - и облом. Вот некоторые примеры:
а) не работает with
б) не работают traits
в) не работает ссылка на метод через .& - используем {}. В принципе это даже более Groovish, но факт остается фактом
г) переопределять методы enum в пайпе нельзя https://issues.jenkins.io/browse/JENKINS-48722
д) использовать @MapConstructor тоже нельзя https://issues.jenkins.io/browse/JENKINS-45901
е) без аннотации map constructor тоже не работает
Как видно, на некоторые проблемы заведены баги, которые не решаются годами. Подозреваю, по двум причинам - разработчики фокусируются на declarative pipeline и трудоемкость исправления
3) Sandbox. В целях безопасности на большинстве нормально настроенных Jenkins включен режим Sandbox https://www.jenkins.io/doc/book/managing/script-approval/
Суть в том, что код запускается в песочнице, где разрешен вызов методов по whilelist. Есть возможность добавить в whitelist новые методы, но нужно апрувить каждый (!) метод. В зависимости от типа среды и компании это может быть трудоемко. Предположим, решили вы использовать новый Java DataTime API, написали 10 строк кода, вызвали пяток метод и все пять приходится апрувить. И узнаешь об этом также только когда выполнение кода дошло до нужного метода.
По моему опыту именно на разруливание этих трех проблем тратится максимум времени при отладке пайпа.
#devops #jenkins #unittest #debug
Чтобы после моей предыдущей статьи о тестировании пайплайнов Jenkins не сложилось впечатления, что проблем нет и провалидированный IDEA, скомпилированный и оттестированный JUnit и Pipeline Unit тестами код сразу заработает в Jenkins - вот три больших ложки дегтя. Уточню, речь про scripted pipeline.
1) CPS. Детально что это за зверь написано тут https://www.jenkins.io/doc/book/pipeline/cps-method-mismatches/
Суть в том, что при выполнении код пайпа интерпретируется специальным образом, чтобы в любой момент на диске лежал актуальный слепок текущего состояния пайпа и можно было восстановить состояние после рестарта Jenkins. К слову, по моему опыту это не всегда работает, возможно пайпы кривые, возможно есть проблемы с плагинами. При этом далеко не весь вызываемый в runtime код можно так трасформировать, т.е. весь код делится на CPS и NonCPS. Не трансформируется Java standart library код, конструкторы и методы, помеченные @NonCPS. И есть правило - NonCPS код не может вызывать CPS код.
На модульном тесте это проверить невозможно, функционал PipelineUnit для этого по факту не работает.
2) Groovy DSL. Код пишется не на Groovy, а на Groovy DSL, а это две большие разницы) ну может не совсем большие, но точно разницы. Т.е. почитав доки по Groovy ты видишь там разные крутые фичи, думаешь - о, а у него есть плюсы по сравнению в Java, пробуешь их использовать - и облом. Вот некоторые примеры:
а) не работает with
б) не работают traits
в) не работает ссылка на метод через .& - используем {}. В принципе это даже более Groovish, но факт остается фактом
г) переопределять методы enum в пайпе нельзя https://issues.jenkins.io/browse/JENKINS-48722
д) использовать @MapConstructor тоже нельзя https://issues.jenkins.io/browse/JENKINS-45901
е) без аннотации map constructor тоже не работает
Как видно, на некоторые проблемы заведены баги, которые не решаются годами. Подозреваю, по двум причинам - разработчики фокусируются на declarative pipeline и трудоемкость исправления
3) Sandbox. В целях безопасности на большинстве нормально настроенных Jenkins включен режим Sandbox https://www.jenkins.io/doc/book/managing/script-approval/
Суть в том, что код запускается в песочнице, где разрешен вызов методов по whilelist. Есть возможность добавить в whitelist новые методы, но нужно апрувить каждый (!) метод. В зависимости от типа среды и компании это может быть трудоемко. Предположим, решили вы использовать новый Java DataTime API, написали 10 строк кода, вызвали пяток метод и все пять приходится апрувить. И узнаешь об этом также только когда выполнение кода дошло до нужного метода.
По моему опыту именно на разруливание этих трех проблем тратится максимум времени при отладке пайпа.
#devops #jenkins #unittest #debug
Pipeline CPS Method Mismatches
Jenkins – an open source automation server which enables developers around the world to reliably build, test, and deploy their software
Всем привет!
Возвращаясь к вопросу отладки пайплайнов Jenkins. Я уже писал о проблеме CPS - https://t.me/javaKotlinDevOps/42
Если вкратце - весь исполняемый на Jenkins код делится на 2 вида, код А может вызывать А и Б, а код Б - только Б.
И на тестах ошибки вызова не ловятся.
Так вот - это все полбеды. Jenkins не следует очень важному принципу fail fast и часто при ошибке вызова CPS пишет warning в лог, но не фейлит джоб. Т.е. по сути не вызван какой-то метод Х из пайплайна, но джоба идет дальше. К каким последствиям это может привести - можно пофантазировать) Но что очевидно: найти корни такой проблемы сложно.
Мораль: не делайте как Jenkins)
#ci #jenkins #groovy_dsl
Возвращаясь к вопросу отладки пайплайнов Jenkins. Я уже писал о проблеме CPS - https://t.me/javaKotlinDevOps/42
Если вкратце - весь исполняемый на Jenkins код делится на 2 вида, код А может вызывать А и Б, а код Б - только Б.
И на тестах ошибки вызова не ловятся.
Так вот - это все полбеды. Jenkins не следует очень важному принципу fail fast и часто при ошибке вызова CPS пишет warning в лог, но не фейлит джоб. Т.е. по сути не вызван какой-то метод Х из пайплайна, но джоба идет дальше. К каким последствиям это может привести - можно пофантазировать) Но что очевидно: найти корни такой проблемы сложно.
Мораль: не делайте как Jenkins)
#ci #jenkins #groovy_dsl
Telegram
(java || kotlin) && devOps
Всем привет!
Чтобы после моей предыдущей статьи о тестировании пайплайнов Jenkins не сложилось впечатления, что проблем нет и провалидированный IDEA, скомпилированный и оттестированный JUnit и Pipeline Unit тестами код сразу заработает в Jenkins - вот три…
Чтобы после моей предыдущей статьи о тестировании пайплайнов Jenkins не сложилось впечатления, что проблем нет и провалидированный IDEA, скомпилированный и оттестированный JUnit и Pipeline Unit тестами код сразу заработает в Jenkins - вот три…