From cf8c76076b9a879266cfd39ba171bc1a36ba940d Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Tue, 15 Aug 2023 11:45:13 +1000 Subject: [PATCH] add some tests for config failures --- internal/kibana/slo_test.go | 399 +++++++++++++++++++++++------------- 1 file changed, 252 insertions(+), 147 deletions(-) diff --git a/internal/kibana/slo_test.go b/internal/kibana/slo_test.go index aac35f17e..53a048c37 100644 --- a/internal/kibana/slo_test.go +++ b/internal/kibana/slo_test.go @@ -3,6 +3,8 @@ package kibana_test import ( "context" "fmt" + "regexp" + "strings" "testing" "github.com/elastic/terraform-provider-elasticstack/internal/acctest" @@ -10,6 +12,8 @@ import ( "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana" "github.com/elastic/terraform-provider-elasticstack/internal/versionutils" "github.com/hashicorp/go-version" + + // sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" @@ -17,144 +21,6 @@ import ( func TestAccResourceSlo(t *testing.T) { sloName := sdkacctest.RandStringFromCharSet(22, sdkacctest.CharSetAlphaNum) - getIndicator := func(indicatorType string) string { - var indicator string - - switch indicatorType { - case "apm_latency_indicator": - indicator = ` - apm_latency_indicator { - environment = "production" - service = "my-service" - transaction_type = "request" - transaction_name = "GET /sup/dawg" - index = "my-index" - threshold = 500 - } - ` - - case "apm_availability_indicator": - indicator = ` - apm_availability_indicator { - environment = "production" - service = "my-service" - transaction_type = "request" - transaction_name = "GET /sup/dawg" - index = "my-index" - } - ` - - case "kql_custom_indicator": - indicator = ` - kql_custom_indicator { - index = "my-index" - good = "latency < 300" - total = "*" - filter = "labels.groupId: group-0" - timestamp_field = "custom_timestamp" - } - ` - - case "histogram_custom_indicator": - indicator = ` - histogram_custom_indicator { - index = "my-index" - good { - field = "test" - aggregation = "value_count" - filter = "latency < 300" - } - total { - field = "test" - aggregation = "value_count" - } - filter = "labels.groupId: group-0" - timestamp_field = "custom_timestamp" - } - ` - - case "metric_custom_indicator": - indicator = ` - metric_custom_indicator { - index = "my-index" - good { - metrics { - name = "A" - aggregation = "sum" - field = "processor.processed" - } - equation = "A" - } - - total { - metrics { - name = "A" - aggregation = "sum" - field = "processor.accepted" - } - equation = "A" - } - } - ` - } - return indicator - } - - getTFConfig := func(name string, indicatorType string, settingsEnabled bool) string { - var settings string - if settingsEnabled { - settings = ` - settings { - sync_delay = "5m" - frequency = "5m" - } - ` - } else { - settings = "" - } - - config := fmt.Sprintf(` - provider "elasticstack" { - elasticsearch {} - kibana {} - } - - resource "elasticstack_elasticsearch_index" "my_index" { - name = "my-index" - deletion_protection = false - } - - resource "elasticstack_kibana_slo" "test_slo" { - name = "%s" - description = "fully sick SLO" - - %s - - time_window { - duration = "7d" - type = "rolling" - } - - budgeting_method = "timeslices" - - objective { - target = 0.999 - timeslice_target = 0.95 - timeslice_window = "5m" - } - - %s - - group_by = "some.field" - - depends_on = [elasticstack_elasticsearch_index.my_index] - - } - - `, name, getIndicator(indicatorType), settings) - return config - } - resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, CheckDestroy: checkResourceSloDestroy, @@ -162,7 +28,7 @@ func TestAccResourceSlo(t *testing.T) { Steps: []resource.TestStep{ { SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.9.0"))), - Config: getTFConfig(sloName, "apm_latency_indicator", false), + Config: getSLOConfig(sloName, "apm_latency_indicator", false), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "name", sloName), resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "description", "fully sick SLO"), @@ -186,14 +52,14 @@ func TestAccResourceSlo(t *testing.T) { }, { //check that name can be updated SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.9.0"))), - Config: getTFConfig(fmt.Sprintf("Updated %s", sloName), "apm_latency_indicator", false), + Config: getSLOConfig(fmt.Sprintf("Updated %s", sloName), "apm_latency_indicator", false), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "name", fmt.Sprintf("Updated %s", sloName)), ), }, { //check that settings can be updated from api-computed defaults SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.9.0"))), - Config: getTFConfig(sloName, "apm_latency_indicator", true), + Config: getSLOConfig(sloName, "apm_latency_indicator", true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "settings.0.sync_delay", "5m"), resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "settings.0.frequency", "5m"), @@ -201,7 +67,7 @@ func TestAccResourceSlo(t *testing.T) { }, { SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.9.0"))), - Config: getTFConfig(sloName, "apm_availability_indicator", true), + Config: getSLOConfig(sloName, "apm_availability_indicator", true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "apm_availability_indicator.0.environment", "production"), resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "apm_availability_indicator.0.service", "my-service"), @@ -212,7 +78,7 @@ func TestAccResourceSlo(t *testing.T) { }, { SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.9.0"))), - Config: getTFConfig(sloName, "kql_custom_indicator", true), + Config: getSLOConfig(sloName, "kql_custom_indicator", true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "kql_custom_indicator.0.index", "my-index"), resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "kql_custom_indicator.0.good", "latency < 300"), @@ -222,8 +88,8 @@ func TestAccResourceSlo(t *testing.T) { ), }, { - SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.10.0-SNAPSHOT"))), - Config: getTFConfig(sloName, "histogram_custom_indicator", true), + SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.10.0-SNAPSHOT"))), //TODO: once 8.10.0 is released, move to 8.10.0 + Config: getSLOConfig(sloName, "histogram_custom_indicator", true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "histogram_custom_indicator.0.index", "my-index"), resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "histogram_custom_indicator.0.good.0.field", "test"), @@ -234,8 +100,8 @@ func TestAccResourceSlo(t *testing.T) { ), }, { - SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.10.0-SNAPSHOT"))), - Config: getTFConfig(sloName, "metric_custom_indicator", true), + SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.10.0-SNAPSHOT"))), //TODO: once 8.10.0 is released, move to 8.10.0 + Config: getSLOConfig(sloName, "metric_custom_indicator", true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "metric_custom_indicator.0.index", "my-index"), resource.TestCheckResourceAttr("elasticstack_kibana_slo.test_slo", "metric_custom_indicator.0.good.0.metrics.0.name", "A"), @@ -250,6 +116,88 @@ func TestAccResourceSlo(t *testing.T) { }) } +func TestAccResourceSloErrors(t *testing.T) { + multipleIndicatorsConfig := ` + provider "elasticstack" { + elasticsearch {} + kibana {} + } + + resource "elasticstack_elasticsearch_index" "my_index" { + name = "my-index" + deletion_protection = false + } + + resource "elasticstack_kibana_slo" "test_slo" { + name = "fail" + description = "multiple indicator fail" + + histogram_custom_indicator { + index = "my-index" + good { + field = "test" + aggregation = "value_count" + filter = "latency < 300" + } + total { + field = "test" + aggregation = "value_count" + } + filter = "labels.groupId: group-0" + timestamp_field = "custom_timestamp" + } + + kql_custom_indicator { + index = "my-index" + good = "latency < 300" + total = "*" + filter = "labels.groupId: group-0" + timestamp_field = "custom_timestamp" + } + + time_window { + duration = "7d" + type = "rolling" + } + + budgeting_method = "supdawg" + + objective { + target = 0.999 + timeslice_target = 0.95 + timeslice_window = "5m" + } + + depends_on = [elasticstack_elasticsearch_index.my_index] + + }` + + budgetingMethodFailConfig := getSLOConfig("budgetingMethodFail", "apm_latency_indicator", false) + budgetingMethodFailConfig = strings.Replace(budgetingMethodFailConfig, "budgeting_method = \"timeslices\"", "budgeting_method = \"supdawg\"", -1) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV5ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.9.0"))), + Config: multipleIndicatorsConfig, + ExpectError: regexp.MustCompile("Invalid combination of arguments"), + }, + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.10.0-SNAPSHOT"))), + Config: getSLOConfig("failwhale", "histogram_custom_indicator_agg_fail", false), + ExpectError: regexp.MustCompile(`expected histogram_custom_indicator.0.good.0.aggregation to be one of \[value_count range\], got supdawg`), + }, + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(version.Must(version.NewSemver("8.9.0"))), + Config: budgetingMethodFailConfig, + ExpectError: regexp.MustCompile(`expected budgeting_method to be one of \[occurrences timeslices\], got supdawg`), + }, + }, + }) +} + func checkResourceSloDestroy(s *terraform.State) error { client, err := clients.NewAcceptanceTestingClient() if err != nil { @@ -275,3 +223,160 @@ func checkResourceSloDestroy(s *terraform.State) error { } return nil } + +func getSLOConfig(name string, indicatorType string, settingsEnabled bool) string { + var settings string + if settingsEnabled { + settings = ` + settings { + sync_delay = "5m" + frequency = "5m" + } + ` + } else { + settings = "" + } + + configTemplate := ` + provider "elasticstack" { + elasticsearch {} + kibana {} + } + + resource "elasticstack_elasticsearch_index" "my_index" { + name = "my-index" + deletion_protection = false + } + + resource "elasticstack_kibana_slo" "test_slo" { + name = "%s" + description = "fully sick SLO" + + %s + + time_window { + duration = "7d" + type = "rolling" + } + + budgeting_method = "timeslices" + + objective { + target = 0.999 + timeslice_target = 0.95 + timeslice_window = "5m" + } + + %s + + group_by = "some.field" + + depends_on = [elasticstack_elasticsearch_index.my_index] + + } + ` + + getIndicator := func(indicatorType string) string { + var indicator string + + switch indicatorType { + case "apm_latency_indicator": + indicator = ` + apm_latency_indicator { + environment = "production" + service = "my-service" + transaction_type = "request" + transaction_name = "GET /sup/dawg" + index = "my-index" + threshold = 500 + } + ` + + case "apm_availability_indicator": + indicator = ` + apm_availability_indicator { + environment = "production" + service = "my-service" + transaction_type = "request" + transaction_name = "GET /sup/dawg" + index = "my-index" + } + ` + + case "kql_custom_indicator": + indicator = ` + kql_custom_indicator { + index = "my-index" + good = "latency < 300" + total = "*" + filter = "labels.groupId: group-0" + timestamp_field = "custom_timestamp" + } + ` + + case "histogram_custom_indicator": + indicator = ` + histogram_custom_indicator { + index = "my-index" + good { + field = "test" + aggregation = "value_count" + filter = "latency < 300" + } + total { + field = "test" + aggregation = "value_count" + } + filter = "labels.groupId: group-0" + timestamp_field = "custom_timestamp" + } + ` + + case "histogram_custom_indicator_agg_fail": + indicator = ` + histogram_custom_indicator { + index = "my-index" + good { + field = "test" + aggregation = "supdawg" + filter = "latency < 300" + } + total { + field = "test" + aggregation = "supdawg" + } + filter = "labels.groupId: group-0" + timestamp_field = "custom_timestamp" + } + ` + + case "metric_custom_indicator": + indicator = ` + metric_custom_indicator { + index = "my-index" + good { + metrics { + name = "A" + aggregation = "sum" + field = "processor.processed" + } + equation = "A" + } + + total { + metrics { + name = "A" + aggregation = "sum" + field = "processor.accepted" + } + equation = "A" + } + } + ` + } + return indicator + } + + config := fmt.Sprintf(configTemplate, name, getIndicator(indicatorType), settings) + return config +}