使用Pulumi将您的基础架构作为代码进行测试。 第二部分

大家好 今天,我们与您分享文章“使用Pulumi将基础结构作为代码进行测试”的最后一部分,该文章的翻译是专门为“ DevOps实践和工具”课程的学生准备的。



部署测试


经过测试的测试样式是一种强大的方法;它使我们能够测试白盒以检查基础结构代码的内部。 但是,这在一定程度上限制了我们可以验证的范围。 在直接部署之前,将根据Pulumi创建的内存中部署计划执行测试,因此无法对部署本身进行测试。 对于此类情况,Pulumi具有集成测试框架。 这两种方法可以很好地协同工作!

Pulumi集成测试框架是用Go编写的,借助它的帮助,我们可以测试大多数内部代码。 如果前面讨论的单元测试方法更像白盒测试,那么集成测试就是黑盒。 (也有用于全面内部测试的选项。)创建此框架是为了采用完整的Pulumi程序并对其执行各种生命周期操作,例如从头开始部署新堆栈,对其进行更新以进行更改以及删除(可能是多次)。 我们定期(例如在晚上)运行它们并作为压力测试。

(我们正在努力确保本机语言SDK中具有类似的集成测试功能。无论使用哪种Pulumi程序编写语言,都可以使用Go集成测试框架)。

通过使用此框架运行程序,您可以检查以下内容:

  • 您的项目代码在语法上是正确的,并且可以正常运行。
  • 堆栈和机密配置设置有效并且可以正确解释。
  • 您的项目可以成功部署在所选的云提供商中。
  • 您的项目可以成功地从初始状态升级到其他N个状态。
  • 您的项目可以成功销毁并从云提供商删除。

我们将很快看到,该框架也可以用于执行运行时验证。

简单的集成测试


为了了解这一点,我们将研究pulumi/examples存储库,因为我们的团队和Pulumi社区使用它来测试他们自己的请求,提交和每夜构建池。

以下是我们示例的简化测试,该示例提供了S3存储桶和其他一些对象

example_test.go:


 package test import ( "os" "path" "testing" "github.com/pulumi/pulumi/pkg/testing/integration" ) func TestExamples(t *testing.T) { awsRegion := os.Getenv("AWS_REGION") if awsRegion == "" { awsRegion = "us-west-1" } cwd, _ := os.Getwd() integration.ProgramTest(t, &integration.ProgramTestOptions{ Quick: true, SkipRefresh: true, Dir: path.Join(cwd, "..", "..", "aws-js-s3-folder"), Config: map[string]string{ "aws:region": awsRegion, }, }) } 

该测试经历了创建,修改和销毁aws-js-s3-folder的堆栈的基本生命周期。 报告通过的测试大约需要一分钟:

 $ go test . PASS ok ... 43.993s 

有许多选项可用于自定义这些测试的行为。 有关选项完整列表,请参见ProgramTestOptions 结构 。 例如,您可以将Jaeger端点配置为跟踪( Tracing ),表明您期望测试在负向测试期间ExpectFailureExpectFailure ),对程序进行一系列“编辑”以进行连续的状态转换( EditDirs ),等等。 让我们看看如何使用它们来验证应用程序部署。

检查资源属性


上面提到的集成确保我们的程序“运行”-不会崩溃。 但是,如果我们要检查结果堆栈的属性怎么办? 例如,已准备(或未准备)某些类型的资源,并且它们具有某些属性。

通过ExtraRuntimeValidation参数,我们可以查看部署后Pulumi记录的状态(部署后状态),以便我们进行其他检查。 这包括结果堆栈状态的完整快照,包括配置,导出的输出值,所有资源及其属性值以及资源之间的所有依存关系。

为了看到一个基本的例子,让我们验证程序是否创建了一个S3 Bucket

  integration.ProgramTest(t, &integration.ProgramTestOptions{ // as before... ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) { var foundBuckets int for _, res := range stack.Deployment.Resources { if res.Type == "aws:s3/bucket:Bucket" { foundBuckets++ } } assert.Equal(t, 1, foundBuckets, "Expected to find a single AWS S3 Bucket") }, }) 

现在,当我们运行go test时,它不仅要进行生命周期测试,而且还必须在成功部署堆栈之后对结果状态进行附加检查。

运行时测试


到目前为止,所有测试仅针对部署行为和Pulumi资源模型。 如果您想验证准备好的基础架构真的可以怎么办? 例如,虚拟机正在运行,S3存储桶包含我们期望的内容,依此类推。

您可能已经知道如何执行此操作: ExtraRuntimeValidation选项是一个很好的机会。 此时,您可以运行任意Go测试,并可以访问程序资源的完整状态。 此状态包括诸如虚拟机的IP地址,URL以及与接收到的云应用程序和基础架构进行真正交互所需的所有信息之类的信息。

例如,我们的测试程序导出了一个名为websiteUrlwebEndpoint存储桶属性,该属性是可获取自定义index document的完整URL。 尽管我们可以深入研究状态文件以查找bucket并直接读取此属性,但是在许多情况下,我们的堆栈会导出有用的属性,例如这样,我们可以方便地进行检查:

 integration.ProgramTest(t, &integration.ProgramTestOptions{ // as before ... ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) { url := "http://" + stack.Outputs["websiteUrl"].(string) resp, err := http.Get(url) if !assert.NoError(t, err) { return } if !assert.Equal(t, 200, resp.StatusCode) { return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if !assert.NoError(t, err) { return } assert.Contains(t, string(body), "Hello, Pulumi!") }, }) 

像我们之前的运行时检查一样,将在提升堆栈后立即执行此检查,并且所有这一切都响应于对go test的简单调用。 这只是冰山一角,您可以使用代码编写的所有Go测试功能均可用。

持续的基础架构集成


在对基础结构进行大量更改以测试它们之前,能够在便携式计算机上运行测试,然后再将其发送给代码审查是很好的。 但是我们和许多客户正在开发生命周期的各个阶段测试基础架构:

  • 在每个开放池中,合并之前的测试请求。
  • 作为对每个提交的响应,请仔细检查合并是否正确执行。
  • 定期(例如,晚上或每周)进行其他测试。
  • 作为性能测试或压力测试的一部分,通常需要长时间进行,然后并行运行测试和/或多次部署同一程序。

对于每个人,Pulumi支持与您喜欢的连续集成系统集成。 通过持续集成,这可以为您的基础架构提供与应用程序软件相同的测试范围。

Pulumi支持常见的CI系统。 以下是其中一些:


有关更多信息,请参见持续交付文档。

临时环境


开放的一个非常强大的功能是仅出于验收测试的目的而部署临时环境的能力。 Pulumi 项目和堆栈的概念旨在通过几个简单的CLI命令或通过集成测试框架轻松地部署和破坏完全隔离和独立的环境。

如果您使用的是GitHub,则Pulumi提供了GitHub App ,它将帮助您将验收测试连接到CI管道中的请求池。 只需将应用程序安装在GitHub存储库中,Pulumi就会向您的CI和请求池添加有关基础结构预览,更新和测试结果的信息:



在使用Pulumi进行基本验收测试时,您将拥有新的自动化功能,这些功能将提高团队绩效并增强变更质量。

总结


在本文中,我们看到当使用通用编程语言时,对我们的应用程序可用的许多软件开发方法都可以使用。 它们包括单元测试,集成测试以及用于进行广泛的运行时测试的交互。 测试易于按需运行或在您的CI系统中运行。

Pulumi是开源软件,可以免费使用,并且可以与您喜欢的编程语言和云一起使用-立即尝试

第一部分

Source: https://habr.com/ru/post/zh-CN463637/


All Articles