Terratest 测试在使用 Go Task 的 Yaml Azure 管道时遇到子文件夹触发问题
来源:stackoverflow
时间:2024-02-13 08:54:23 218浏览 收藏
Golang不知道大家是否熟悉?今天我将给大家介绍《Terratest 测试在使用 Go Task 的 Yaml Azure 管道时遇到子文件夹触发问题》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论指出,谢谢!希望我们能一起加油进步!
我在通过 azure yaml 管道安装 terratest 时遇到此问题:
c:\hostedtoolcache\windows\go\1.17.1\x64\bin\go.exe install -v github.com/gruntwork-io/[email protected] go: downloading github.com/gruntwork-io/terratest v0.40.6 go install: github.com/gruntwork-io/[email protected]: module github.com/gruntwork-io/[email protected] found, but does not contain package github.com/gruntwork-io/terratest ##[error]the go task failed with an error: error: the process 'c:\hostedtoolcache\windows\go\1.17.1\x64\bin\go.exe' failed with exit code 1 finishing: install go terratest module - v0.40.6
我的安装代码如下:
- task: go@0
displayname: install go terratest module - v$(terratest_version)
inputs:
command: custom
customcommand: install
arguments: $(tf_log) github.com/gruntwork-io/terratest@v$(terratest_version)
workingdirectory: $(pipeline_artefact_folder_extract)/$(pathtoterraformrootmodule)
但是peharps我在使用terratest时犯了错误。
以下是我的代码树的屏幕截图:
我在(例如)terraform\azure_v2_x\resourcemodules 子目录中有 terraform 代码,在 terraform\azure_v2_x\tests_unit_resourcemodules 子目录中有 terratest 测试(在屏幕截图 app_configuration 测试中)对于app_configuration资源模块)。
在我的terratest模块中,我调用我的resourcemodule,如以下代码所示:
######test in a un isolated resource group defined in locals
module "app_configuration_tobetested" {
source = "../../resourcemodules/app_configuration"
resource_group_name = local.rg_name
location = local.location
environment = var.environment
sku = "standard"
// rem : here app_service_shared prefix and app_config_shared prefix are the same !
app_service_prefix = module.app_configuration_list_fortests.settings.frontend_prefix
# stage = var.stage
app_config_list = module.app_configuration_list_fortests.settings.list_app_config
}
在我的 go 文件中,我测试了关于我想要的预期结果的模块结果:
package rm_app_configuration_test
import (
"os"
"testing"
// "github.com/gruntwork-io/terratest/modules/azure"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
var (
globalbackendconf = make(map[string]interface{})
globalenvvars = make(map[string]string)
)
func testterraform_rm_app_configuration(t *testing.t) {
t.parallel()
// terraform directory
fixturefolder := "./"
// backend specification
strlocal := "rmapcfg_"
// input value
inputstage := "sbx_we"
inputenvironment := "sbx"
inputapplication := "demo"
// expected value
expectedrsgname := "z-adf-ftnd-shrd-sbx-ew1-rgp01"
// expectedappcfgprefix := "z-adf-ftnd-shrd"
expectedappconfigreader_id := "[/subscriptions/f04c8fd5-d013-41c3-9102-43b25880d2e2/resourcegroups/z-adf-ftnd-shrd-sbx-ew1-rgp01/providers/microsoft.appconfiguration/configurationstores/z-adf-ftnd-shrd-sbx-ew1-blue-sbx-cfg01 /subscriptions/f04c8fd5-d013-41c3-9102-43b25880d2e2/resourcegroups/z-adf-ftnd-shrd-sbx-ew1-rgp01/providers/microsoft.appconfiguration/configurationstores/z-adf-ftnd-shrd-sbx-ew1-green-sbx-cfg01]"
// getting envars from environment variables
/*
go and terraform uses two differents methods for azure authentification.
** terraform authentification is explained bellow :
- https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret#configuring-the-service-principal-in-terraform
** go authentification is explained bellow
- https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authorization#use-environment-based-authentication
** terratest is using both authentification methods regarding the work it has to be done :
- azure existences tests uses go azure authentification :
- https://github.com/gruntwork-io/terratest/blob/master/modules/azure/authorizer.go#l11
- terraform commands uses terraform authentification :
- https://github.com/gruntwork-io/terratest/blob/0d654bd2ab781a52e495f61230cf892dfba9731b/modules/terraform/cmd.go#l12
- https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret#configuring-the-service-principal-in-terraform
so both authentification methods have to be implemented
*/
// getting terraform envvars from azure go environment variables
arm_client_id := os.getenv("azure_client_id")
arm_client_secret := os.getenv("azure_client_secret")
arm_tenant_id := os.getenv("azure_tenant_id")
arm_subscription_id := os.getenv("arm_subscription_id")
if arm_client_id != "" {
globalenvvars["arm_client_id"] = arm_client_id
globalenvvars["arm_client_secret"] = arm_client_secret
globalenvvars["arm_subscription_id"] = arm_subscription_id
globalenvvars["arm_tenant_id"] = arm_tenant_id
}
// getting terraform backend from environment variables
resource_group_name := os.getenv("resource_group_name")
storage_account_name := os.getenv("storage_account_name")
container_name := os.getenv("container_name")
key := strlocal + os.getenv("key")
if resource_group_name != "" {
globalbackendconf["resource_group_name"] = resource_group_name
globalbackendconf["storage_account_name"] = storage_account_name
globalbackendconf["container_name"] = container_name
globalbackendconf["key"] = key
}
// user terratest to deploy the infrastructure
terraformoptions := terraform.withdefaultretryableerrors(t, &terraform.options{
// website::tag::1::set the path to the terraform code that will be tested.
// the path to where our terraform code is located
terraformdir: fixturefolder,
// variables to pass to our terraform code using -var options
vars: map[string]interface{}{
"stage": inputstage,
"environment": inputenvironment,
"application": inputapplication,
},
envvars: globalenvvars,
// backend values to set when initialziing terraform
backendconfig: globalbackendconf,
// disable colors in terraform commands so its easier to parse stdout/stderr
nocolor: true,
})
// website::tag::4::clean up resources with "terraform destroy". using "defer" runs the command at the end of the test, whether the test succeeds or fails.
// at the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.destroy(t, terraformoptions)
// website::tag::2::run "terraform init" and "terraform apply".
// this will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.initandapply(t, terraformoptions)
// tests the resource_group for the app_configuration
/*
actualappconfigreaderprefix := terraform.output(t, terraformoptions, "app_configuration_tested_prefix")
assert.equal(t, expectedappcfgprefix, actualappconfigreaderprefix)
*/
actualrsgreadername := terraform.output(t, terraformoptions, "app_configuration_tested_rg_name")
assert.equal(t, expectedrsgname, actualrsgreadername)
actualappconfigreader_id := terraform.output(t, terraformoptions, "app_configuration_tobetested_id")
assert.equal(t, expectedappconfigreader_id, actualappconfigreader_id)
}
事实是在本地,我可以从我的主文件夹 terraform\azure_v2_x\tests_unit_resourcemodules 执行以下命令来触发原始的所有测试:
- (来自 go v1.11)
Go test ./...
使用 go 版本 1.12,我可以设置 go111module=auto 以获得相同的结果。 但在 go 1.17 中,我现在必须设置 go111module=off 来触发我的测试。
目前,我有两个主要问题困扰着我:
如何从 azure pipeline 导入 terratest(和其他)模块?
我需要做什么才能正确使用 terratest 的 go 模块? 我的主文件夹 _terraform\azure_v2_x\tests_unit_resourcemodules_ 中没有 go 代码,并且希望在 azure pipeline 中的简单命令行中触发所有子文件夹 go 测试。
感谢您提供的任何帮助。
最诚挚的问候,
正确答案
我将再次回答我自己的问题。 :d
所以,现在使用以下版本:
- -- 政府:1.17.1
- -- terraform_version:1.1.7
- -- terratest_version:0.40.6
关于 terratest 测试,文件夹层次结构已进行以下更改:
我不再尝试导入我的 terratest 模块。(显然,上面的第 1 点已得到解答)
我现在只需要:
- 对我的每个 terratest 模块进行 mod
- 使用脚本逐一触发它们
所以我的管道变成了以下内容:
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.terraforminstaller@0
displayname: install terraform $(terraform_version)
inputs:
terraformversion: $(terraform_version)
- task: gotool@0
displayname: 'use go $(goversion)'
inputs:
version: $(goversion)
gopath: $(gopath)
gobin: $(gobin)
- task: powershell@2
displayname: run terratest for $(pathtoterraformrootmodule)
inputs:
targettype : 'filepath'
filepath: $(pipeline_artefact_folder_extract)/$(pathtoterraformrootmodule)/$(run_terratest_script)
workingdirectory: $(pipeline_artefact_folder_extract)/$(pathtoterraformrootmodule)
env:
# see https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authorization#use-environment-based-authentication
# for azure authentification with go
arm_subscription_id: $(tf_var_arm_subscription_id)
azure_client_id: $(tf_var_arm_client_id)
azure_tenant_id: $(tf_var_arm_tenant_id)
azure_client_secret: $(tf_var_arm_client_secret) # set as pipeline secret
resource_group_name: $(storageaccountresourcegroup)
storage_account_name: $(storageaccount)
container_name: $(stateblobcontainer)
key: '$(module)-$(tf_var_application)-$(tf_var_environment).tfstate'
go111module: 'auto'
在我的 terratest 子文件夹的主文件夹中,我有 run_terratests.ps1 脚本和 terratests 列表文件,如下所示:
run_terratests.ps1
# this file is based on https://github.com/google/go-cloud/blob/master/internal/testing/runchecks.sh
#
# this script runs all go terratest suites,
# compatibility checks, consistency checks, wire, etc.
$modulelistfile = "./terratests"
# regex to filter : not began with #
$regexfilter = "^[^#]"
# read the modulelistfile
[object] $arrayfromfile = get-content -path $modulelistfile | where-object { $_ -match $regexfilter} | convertfrom-string -propertynames folder, totest
$result = 0 # set no error by default
# get the actual folder
$main_path = get-location | select -expandproperty "path"
#read the array to show if to be tested !
foreach ($line in $arrayfromfile) {
# write-host $line
if ($line.totest -eq "yes") {
$path = $line.folder
set-location $main_path\$path
$mypath = get-location
# write-host $mypath
# trigger terratest for files
go test ./...
}
if ($false -eq $?)
{
$result = 1
}
}
# back to school :d
set-location $main_path
if ($result -eq 1)
{
write-error "msbuild exit code indicate test failure."
write-host "##vso[task.logissue type=error]msbuild exit code indicate test failure."
exit(1)
}
代码
if ($false -eq $?)
{
$result = 1
}
对于使管道在测试错误时失败而不逃避其他测试很有用。
地形测试
# this file lists all the modules to be tested in the "tests_unit_confighelpers" repository. # it us used by the "run_terratest.ps1" powershell script to trigger terratest for each test. # # any line that doesn't begin with a '#' character and isn't empty is treated # as a path relative to the top of the repository that has a module in it. # the 'tobetested' field specifies whether this is a module that have to be tested. # # this file is based on https://github.com/google/go-cloud/blob/master/allmodules # module-directory tobetested azure_constants yes configure_app_srv_etc yes configure_frontdoor_etc yes configure_hostnames yes constants yes frontend_appservice_slots/_main yes frontend_appservice_slots/settings yes merge_maps_of_strings yes name yes name_template yes network/hostname_generator yes network/hostnames_generator yes replace_2vars_into_string_etc yes replace_var_into_string_etc yes sorting_map_with_an_other_map yes
每个 terratest 文件夹中的更改是我将添加 go.mod 和 go.sum 文件:
$ go mod init mytest go: creating new go.mod: module mytest go: to add module requirements and sums: go mod tidy
和
$ go mod tidy # link each of the go modules needed for your terratest module
因此,powershell 脚本中的 go 测试 ./... 将下载所需的 go 模块并运行该特定测试的测试。
感谢您的阅读,如果您认为有帮助,请投票:)
文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Terratest 测试在使用 Go Task 的 Yaml Azure 管道时遇到子文件夹触发问题》文章吧,也可关注golang学习网公众号了解相关技术文章。
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
478 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习