登录
首页 >  Golang >  Go问答

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 来触发我的测试。

目前,我有两个主要问题困扰着我:

  1. 如何从 azure pipeline 导入 terratest(和其他)模块?

  2. 我需要做什么才能正确使用 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 点已得到解答)

我现在只需要:

  1. 对我的每个 terratest 模块进行 mod
  2. 使用脚本逐一触发它们

所以我的管道变成了以下内容:

- 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学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>