リソースのテストをしていて思うこと
リソースのテストって、実質Accテストだと思うんですよ、Terraformの世界では。
でも、このテストって、 正常系のテストしかないのでは?
・・・ と開発をはじめてからずっと思っていました。
今回、 準正常系
くらいのテストをするにはどうするか・・・というのを書いてみます。
まずは ConflictsWith
編です。
(もう1つ ForceNew編
というのがありますので、そのうち書きます)
ConflictsWith とは?
特定のパラメータ同士を同時に指定されたくない(されてはいけない)というようなケースで使います。
例えばこういうときです。
func resourceSomething() *schema.Resource {
return &schema.Resource{
Create: xxxx
(省略)
Schema: map[string]*schema.Schema{
"param_a": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"paramB"},
},
"param_b": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"paramA"},
}
(省略)
こう書いておくと、 paramA
と paramB
を同時に指定した時にエラーとなります。
で、これをAccテストで試験したいというケースです。
まぁ、こういう部分ってそうそう変わる設定ではないと思いますが、うっかりリソース定義を変えちゃって、でCI的に試験してなくてミスった・・・みたいのを防止したいと考えたのが発端です。
実際のテスト
判定部分はもっといろいろな手法があるとは思いますが、 resource.TestStep
の ExpectError
を使っていわゆる assertRaises
的なことをやってます。
今回は双方向(param_a <-> param_b)でConflictsWithを入れているので、エラー的には2行出るんで、それぞれ pattern1
, pattern2
で判定しています。
func TestValidateConflictsParamAAndParamB(t *testing.T) {
pattern1 := "\"param_a\": conflicts with param_b"
pattern2 := "\"param_b\": conflicts with param_a"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: sampleConfig,
ExpectError: regexp.MustCompile(pattern1),
},
resource.TestStep{
Config: sampleConfig,
ExpectError: regexp.MustCompile(pattern2),
},
},
})
}
const sampleConfig = `
resource "my_something_v1" "something_1" {
param_a = "this is param a"
param_b = "this is param b"
}
`
ちなみに、例えば上記の pattern1
, pattern2
を適当な値にしておくと、こんなエラーになります。
config is invalid: 2 problems:
- my_something_v1.something_1: "param_a": conflicts with param_b
- my_something_v1.something_1: "param_b": conflicts with param_a
To match:
(なんか適当に変えた値)
本来のテストでは、この文字列を正規表現で拾っている感じです。
次回、 ForceNew
編書きます。