Читаем Terraform: инфраструктура на уровне кода полностью

$ dep ensure -add github.com/gruntwork-io/terratest/modules/terraform

Следующий этап автоматического тестирования — выполнение команд terraforminit и terraformapply, которые развернут ваш код. У Terratest для этого есть вспомогательные средства:

func TestAlbExample(t *testing.T) {

        opts := &terraform.Options{

                // Сделайте так, чтобы этот относительный путь

                // вел к папке с примерами для alb!

                TerraformDir: "../examples/alb",

        }

        terraform.Init(t, opts)

        terraform.Apply(t, opts)

}

Выполнение команд init и apply в Terratest — настолько рутинная операция, что для этого предусмотрен удобный вспомогательный метод, который делает все одной командой:

func TestAlbExample(t *testing.T) {

        opts := &terraform.Options{

                // Сделайте так, чтобы этот относительный путь

                // вел к папке с примерами для alb!

                TerraformDir: "../examples/alb",

        }

        // Развертываем пример

        terraform.InitAndApply(t, opts)

}

Код выше уже представляет собой довольно функциональный модульный тест: он выполняет terraforminit и terraformapply и проваливает тест, если эти команды­ не завершаются успешно (например, из-за проблем в вашем коде Terraform). Но вы можете пойти еще дальше и выполнить HTTP-запросы к развернутому балансировщику нагрузки, чтобы убедиться, что он возвращает нужные вам данные. Для этого вам надо как-то получить доменное имя развернутого балансировщика. К счастью, пример alb возвращает его в виде выходной переменной:

output "alb_dns_name" {

  value       = module.alb.alb_dns_name

  description = "The domain name of the load balancer"

}

У Terratest есть встроенные вспомогательные средства для чтения вывода из кода Terraform:

func TestAlbExample(t *testing.T) {

        opts := &terraform.Options{

                // Сделайте так, чтобы этот относительный путь

                // вел к папке с примерами для alb!

                TerraformDir: "../examples/alb",

        }

        // Развертываем пример

        terraform.InitAndApply(t, opts)

        // Получаем URL-адрес ALB

        albDnsName := terraform.OutputRequired(t, opts, "alb_dns_name")

        url := fmt.Sprintf("http://%s", albDnsName)

}

Функция OutputRequired возвращает вывод с заданным именем или проваливает тест, если этот вывод пустой или не существует. Предыдущий листинг формирует на основе этого вывода URL-адрес, используя встроенную в Go функцию ­fmt.Sprintf (не забудьте импортировать пакет fmt). Следующим шагом будет выполнение HTTP-запросов по этому URL-адресу:

package test

import (

        "fmt"

        "crypto/tls"

        "github.com/gruntwork-io/terratest/modules/http-helper"

        "github.com/gruntwork-io/terratest/modules/terraform"

        "testing"

)

func TestAlbExample(t *testing.T) {

        opts := &terraform.Options{

                // Сделайте так, чтобы этот относительный путь

                // вел к папке с примерами для alb!

                TerraformDir: "../examples/alb",

        }

        // Развертываем пример

        terraform.InitAndApply(t, opts)

        // Получаем URL-адрес ALB

        albDnsName := terraform.OutputRequired(t, opts, "alb_dns_name")

        url := fmt.Sprintf("http://%s", albDnsName)

        // Проверяем в ALB действие по умолчанию, которое должно вернуть 404

        expectedStatus := 404

        expectedBody := "404: page not found"

        http_helper.HttpGetWithValidation(t, url, expectedStatus, expectedBody)

}

Этот код импортирует из Terratest новый пакет, http_helper. Чтобы его загрузить, нужно еще раз выполнить rundep. Метод http_helper.HttpGetWithValidation сделает HTTP-запрос типа GET по переданному вами URL-адресу и провалит тест, если код состояния и тело ответа не совпадают с теми, которые вы указали.

У этого кода есть одна проблема: между завершением команды terraformapply и тем, когда доменное имя балансировщика нагрузки становится доступным (то есть распространилось по системе), проходит время. Если вызвать http_helper.HttpGetWithValidation незамедлительно, он, вполне вероятно, окажется неудачным, хотя через 30 секунд или минуту ALB заработает в нормальном режиме. Как уже обсуждалось в подразделе «Отложенная согласованность согласуется… с отлагательством» на с. 211, такого рода асинхронное поведение с отложенной согласованностью является для AWS (а точнее, для большинства распределенных систем) нормальным и решением будет повторное выполнение вызовов. У Terratest есть вспомогательный метод и для этого:

func TestAlbExample(t *testing.T) {

        opts := &terraform.Options{

                // Сделайте так, чтобы этот относительный путь

                // вел к папке с примерами для alb!

                TerraformDir: "../examples/alb",

        }

        // Развертываем пример

        terraform.InitAndApply(t, opts)

        // Получаем URL-адрес ALB

        albDnsName := terraform.OutputRequired(t, opts, "alb_dns_name")

        url := fmt.Sprintf("http://%s", albDnsName)

        // Проверяем в ALB действие по умолчанию, которое должно вернуть 404

        expectedStatus := 404

        expectedBody := "404: page not found"

        maxRetries := 10

        timeBetweenRetries := 10 * time.Second

        http_helper.HttpGetWithRetry(

                t,

                url,

                &tls.Config{},

                expectedStatus,

                expectedBody,

                maxRetries,

                timeBetweenRetries,

        )

}

Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Искусство управления IT-проектами
Искусство управления IT-проектами

В отличие от множества трудов, посвященных руководству проектами и командами, в этой книге не проповедуются никакие новые учения и не превозносятся великие теории. Скотт Беркун считает залогом успеха практику и разнообразие подходов. В книге описываются основные сложности и проблемные ситуации, возникающие в работе менеджера проекта, даны рекомендации по выходу из них.Издание предназначено не только для лидеров команд и менеджеров высшего звена, но и для программистов, тестеров и других исполнителей конкретных проектных заданий. Также оно будет полезно студентам, изучающим бизнес-менеджмент, проектирование изделий или программную инженерию.Текст нового издания значительно переработан автором с целью добиться большей ясности, кроме того, книга дополнена новым приложением и более чем 120 практическими упражнениями.

Скотт Беркун

Деловая литература
iOS. Приемы программирования
iOS. Приемы программирования

Книга, которую вы держите в руках, представляет собой новый, полностью переписанный сборник приемов программирования по работе с iOS. Он поможет вам справиться с наболевшими проблемами, с которыми приходится сталкиваться при разработке приложений для iPhone, iPad и iPod Touch. Вы быстро освоите всю информацию, необходимую для начала работы с iOS 7 SDK, в частности познакомитесь с решениями для добавления в ваши приложения реалистичной физики или движений — в этом вам помогут API UIKit Dynamics.Вы изучите новые многочисленные способы хранения и защиты данных, отправки и получения уведомлений, улучшения и анимации графики, управления файлами и каталогами, а также рассмотрите многие другие темы. При описании каждого приема программирования приводятся образцы кода, которые вы можете смело использовать.

Вандад Нахавандипур

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги