Как провести модульное тестирование ваших диаграмм Helm

by moiseevrus

Введение

В моем текущем проекте мне нужно написать несколько диаграмм 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

Напишите несколько тестов

изображение.png

Прежде чем мы сможем начать, нам нужно установить модуль тестирования 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

You may also like

Leave a Comment