Contents
Введение
В моем текущем проекте мне нужно написать несколько диаграмм Helm. И со временем графики Helm становятся все более и более логичными.
И поскольку сложность продолжает расти, поскольку я использую логику шаблонов Helm. Хотя это очень удобно, моя диаграмма становится более открытой для ошибок или случайных изменений в логике (регрессия!). Чтобы избежать этого, мы можем использовать юнит-тесты так же, как мы это делаем, когда пишем программное обеспечение! И решение операционных проблем с программным обеспечением для меня является очень важным аспектом в мире DevOps!
Давай катимся
Файл шаблона для тестирования
Сначала мы создаем простой сценарий, который мы хотели бы протестировать. Я создаю шаблонные ресурсы типа Deployment
и хочу проверить, правильно ли работает логика шаблона.
{{- if .Values.deployment.test.create }}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
{{- if .Values.deployment.test.initContainers }}
initContainers:
- name: busybox
image: busybox
command:
- sleep
- "3600"
{{- end }}
containers:
- image: nginx
name: nginx
resources: {}
{{- end }}
Пройдемся по логике в этом ресурсе:
Он будет отображать ресурс только в том случае, если .Values.deployment.test.create
он подтвержден как истинное значение.
Следующим пунктом является контейнер инициализации. Свойство initContainer
будет отображено только в том случае, если .Values.deployment.test.initContainers
установлено значение true
.
Выглядит values.yaml
так:
deployment:
test:
create: true
initContainers: true
Если мы сейчас запустим нашу команду шаблона, мы должны получить следующий вывод:
helm template test .
# Source: node-red/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
initContainers:
- name: busybox
image: busybox
command:
- sleep
- "3600"
containers:
- image: nginx
name: nginx
Это выглядит так, как ожидалось. Создается Deployment
и присутствует контейнер инициализации.
Но как мы можем гарантировать, что в будущем все останется так, как задумано? Мы не можем быть уверены, что все будут постоянно запускать команду helm template и проверять результаты. Подумайте, что произойдет, если файл усложнится?
Время для нашего героя: UNIT TEST и его напарник CONTINUOUS TESTING
Напишите несколько тестов
Прежде чем мы сможем начать, нам нужно установить модуль тестирования helm от Quintus :
helm plugin install https://github.com/quintush/helm-unittest
Теперь мы можем начать работать над собственно тестом.
Во-первых, вам нужно создать папку с именем тесты внутри корневой папки вашего рум-чарта. Файл нашего набора тестов теперь будет помещен в каталог test/ с суффиксом _test.yaml.
В нашем примере мы создаем deployment_test.yaml
со следующим содержимым:
suite: test nginx deployment
templates:
- deployment.yaml
Теперь мы можем начать писать настоящие тестовые задания. Здесь мы будем следовать шаблону ААА из книги Владимира Хорикова «Модульное тестирование, принципы, практики и шаблоны».
Шаблон AAA прост и обеспечивает единую структуру для всех тестов в наборе. Эта унифицированная структура является одним из ее самых больших преимуществ: как только вы привыкнете к этому шаблону, вам будет легче читать и понимать тесты. Это, в свою очередь, снижает затраты на обслуживание всего набора тестов.
- В разделе аранжировки вы настраиваете объекты для тестирования. Вы доводите тестируемую систему до желаемого состояния.
- В разделе действия вы воздействуете на тестируемую систему.
- Раздел assert позволяет вам делать заявления о результате.
Вот наши два тестовых задания более подробно:
tests:
- it: deployment should render
asserts:
- isKind:
of: Deployment
- hasDocuments:
count: 1
Давайте посмотрим, что тест делает здесь:
- Убедитесь, что ресурс имеет тип
Deployment
. - И это есть документ, оказанный.
Если мы выполним тест с помощью helm unittest
команды, мы получим следующий вывод:
❯ helm unittest charts/node-red -3
### Chart [ node-red ] charts/node-red
PASS test nginx deployment charts/node-red/tests/deployment2_test.yaml
Charts: 1 passed, 1 total
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshot: 0 passed, 0 total
Time: 12.40997ms
Большой! Всё хорошо!
Давайте также добавим тест для контейнера инициализации:
- it: init container should be present
values:
- ./values/deployment_values.yaml
asserts:
- isKind:
of: Deployment
- equal:
path: spec.template.spec.initContainers[0].name
value: busybox
То же, что и выше, но с двумя отличиями:
- мы добавляем тест
values.yaml
к тесту соvalues
свойством. - проверяем наличие имени init контейнера
Давайте снова запустим набор тестов:
PASS test nginx deployment charts/node-red/tests/deployment2_test.yaml
Charts: 1 passed, 1 total
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshot: 0 passed, 0 total
Time: 14.037046ms
Сладко!, все снова проходит!.
Теперь предположим, что кто-то изменил значение по умолчанию create на false
:
❯ helm unittest charts/node-red -3
### Chart [ node-red ] charts/node-red
FAIL test nginx deployment charts/node-red/tests/deployment2_test.yaml
- deployment should render
- asserts[0] `isKind` fail
Template: node-red/templates/deployment-2.yaml
- asserts[1] `hasDocuments` fail
Template: node-red/templates/deployment-2.yaml
Expected documents count to be:
1
Actual:
0
Charts: 1 failed, 0 passed, 1 total
Test Suites: 1 failed, 0 passed, 1 total
Tests: 1 failed, 1 passed, 2 total
Snapshot: 0 passed, 0 total
Time: 18.812819ms
Error: plugin "unittest" exited with error
Мы получаем прямую обратную связь и можем проверить, где возникает ошибка или регрессия.
GitHub Action для НЕПРЕРЫВНОГО ТЕСТИРОВАНИЯ
Чтобы включить непрерывное тестирование в своем действии GitHub, вам просто нужно добавить этот шаг в свой конвейер, и все готово:
...
- name: Run helm unittest
run: |
helm plugin install https://github.com/quintush/helm-unittest
helm unittest charts/node-red -3
...
Последние мысли
Поскольку мы продолжаем добавлять дополнительное поведение и проверки в нашу диаграмму руля, модульное тестирование — это способ убедиться, что мы не нарушаем некоторые функции и не добавляем некоторые из этих надоедливых ошибок.
Эта статья является переводом blog.ediri.io