$ 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
t,
url,
&tls.Config{},
expectedStatus,
expectedBody,
maxRetries,
timeBetweenRetries,
)
}
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии