Repository: honeycombio/terraform-provider-honeycombio
Pull request #421 (2024-01-22 14:08:57)

fix(client): fix queryspec equivalence for empty breakdowns
Reported via Pollinators ([link](https://honeycombpollinators.slack.com/archives/C017T9FFT0D/p1705836614190879)).

If `breakdowns` is provided as an empty slice DeepEqual fails to view that as equal to a queryspec without the slice defined ([]string string vs []string nil).

Adds an empty list of `orders` to be sure it didn't have a similar issue, but it pass the empty equivalence test fine.



Patch:
diff --git a/client/query_spec.go b/client/query_spec.go
index 865425c..0471a29 100644
--- a/client/query_spec.go
+++ b/client/query_spec.go
@@ -104,9 +104,15 @@ func (qs *QuerySpec) EquivalentTo(other QuerySpec) bool {
 	if ValueOrDefault(qs.FilterCombination, DefaultFilterCombination) != ValueOrDefault(other.FilterCombination, DefaultFilterCombination) {
 		return false
 	}
-	if !reflect.DeepEqual(qs.Breakdowns, other.Breakdowns) {
+
+	if !reflect.DeepEqual(qs.Breakdowns, other.Breakdowns) &&
+		// an empty Breakdowns is equivalent to a nil Breakdowns, so we need to check that
+		// as DeepEqual will not consider them equal
+		!(qs.Breakdowns == nil && len(other.Breakdowns) == 0 ||
+			len(qs.Breakdowns) == 0 && other.Breakdowns == nil) {
 		return false
 	}
+
 	// the exact order of havings does not matter, but their equvalence does
 	if !Equivalent(qs.Havings, other.Havings) {
 		return false
diff --git a/honeycombio/provider.go b/honeycombio/provider.go
index 24ad5d8..7707aa1 100644
--- a/honeycombio/provider.go
+++ b/honeycombio/provider.go
@@ -22,13 +22,13 @@ func Provider(version string) *schema.Provider {
 		Schema: map[string]*schema.Schema{
 			"api_key": {
 				Type:        schema.TypeString,
-				Description: "The Honeycomb API key to use. It can also be set using HONEYCOMB_API_KEY or HONEYCOMBIO_APIKEY environment variables.",
+				Description: "The Honeycomb API key to use. It can also be set via the `HONEYCOMB_API_KEY` or `HONEYCOMBIO_APIKEY` environment variables.",
 				Optional:    true,
 				Sensitive:   true,
 			},
 			"api_url": {
 				Type:        schema.TypeString,
-				Description: "Override the URL of the Honeycomb.io API. Defaults to https://api.honeycomb.io.",
+				Description: "Override the URL of the Honeycomb API. Defaults to `https://api.honeycomb.io`. It can also be set via the `HONEYCOMB_API_ENDPOINT` environment variable.",
 				Optional:    true,
 			},
 			"debug": {
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 79a99bc..8554380 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -43,12 +43,12 @@ func (p *HoneycombioProvider) Schema(_ context.Context, _ provider.SchemaRequest
 	resp.Schema = schema.Schema{
 		Attributes: map[string]schema.Attribute{
 			"api_key": schema.StringAttribute{
-				MarkdownDescription: "The Honeycomb API key to use. It can also be set using HONEYCOMB_API_KEY or HONEYCOMBIO_APIKEY environment variables.",
+				MarkdownDescription: "The Honeycomb API key to use. It can also be set via the `HONEYCOMB_API_KEY` or `HONEYCOMBIO_APIKEY` environment variables.",
 				Optional:            true,
 				Sensitive:           true,
 			},
 			"api_url": schema.StringAttribute{
-				MarkdownDescription: "Override the URL of the Honeycomb.io API. Defaults to https://api.honeycomb.io.",
+				MarkdownDescription: "Override the URL of the Honeycomb API. Defaults to `https://api.honeycomb.io`. It can also be set via the `HONEYCOMB_API_ENDPOINT` environment variable.",
 				Optional:            true,
 			},
 			"debug": schema.BoolAttribute{


Test patch:
diff --git a/client/query_spec_test.go b/client/query_spec_test.go
index 4367bd5..406ebc6 100644
--- a/client/query_spec_test.go
+++ b/client/query_spec_test.go
@@ -97,6 +97,8 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 				TimeRange:         client.ToPtr(client.DefaultQueryTimeRange),
 				// Granularity may be exported out of the Query Builder as '0' when not provided
 				Granularity: client.ToPtr(0),
+				Breakdowns:  []string{},
+				Orders:      []client.OrderSpec{},
 			},
 			client.QuerySpec{},
 			true,
@@ -346,6 +348,14 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 			},
 			false,
 		},
+		{
+			"Not equivalent breakdowns",
+			client.QuerySpec{
+				Breakdowns: []string{"column_1"},
+			},
+			client.QuerySpec{},
+			false,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {