From 394a0b4f449ac1443c2761c20e181a5a28a7d2a4 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Thu, 28 May 2026 10:10:17 +0200 Subject: [PATCH] Add regression test for #5664: account-level service_principal data source hook failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test currently fails on v1.114.0 — surfaces the exact error from the issue. Co-authored-by: Isaac --- scim/data_service_principal_test.go | 74 +++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/scim/data_service_principal_test.go b/scim/data_service_principal_test.go index 7f62763b22..cf6eac34fa 100644 --- a/scim/data_service_principal_test.go +++ b/scim/data_service_principal_test.go @@ -1,8 +1,10 @@ package scim import ( + "context" "testing" + "github.com/databricks/terraform-provider-databricks/common" "github.com/databricks/terraform-provider-databricks/qa" "github.com/stretchr/testify/assert" ) @@ -253,6 +255,78 @@ func TestDataServicePrincipalReadNoParams(t *testing.T) { }.ExpectError(t, "please specify either application_id, display_name, or scim_id") } +// TestDataServicePrincipalRead_AccountLevelNoHookFailure is a regression test +// for https://github.com/databricks/terraform-provider-databricks/issues/5664. +// When `databricks_service_principal` data source is used with an account-level +// provider, the post-Read provider_config hook used to call CurrentWorkspaceID +// and fail with: +// +// Error: cannot populate provider_config for service principal: +// failed to resolve workspace_id: failed to get the workspace_id: +// strconv.ParseInt: parsing "": invalid syntax +// +// The fix in main adds `api` to the data source schema and marks it +// `IsDual: true` so the post-Read hook is short-circuited at account level. +// +// Fixtures cover BOTH the workspace SCIM path (used by v1.114.0 where the +// `api` field does not exist and HostType falls back to WorkspaceHost) and +// the account SCIM path (used on main once `api = "account"` is set). The +// test asserts the hook does not fire by deliberately NOT stubbing +// /api/2.0/preview/scim/v2/Me — if the hook runs it will hit the test server +// with no matching fixture and the assertion fails with a missing-stub +// error referencing /Me. +func TestDataServicePrincipalRead_AccountLevelNoHookFailure(t *testing.T) { + spResources := UserList{ + Resources: []User{ + { + ID: "spid", + DisplayName: "testsp", + Active: true, + ApplicationID: "appid", + }, + }, + } + client, server, err := qa.HttpFixtureClient(t, []qa.HTTPFixture{ + { + Method: "GET", + Resource: "/api/2.0/accounts/abc/scim/v2/ServicePrincipals?excludedAttributes=roles&filter=displayName%20eq%20%22testsp%22", + ReuseRequest: true, + Response: spResources, + }, + { + Method: "GET", + Resource: "/api/2.0/preview/scim/v2/ServicePrincipals?excludedAttributes=roles&filter=displayName%20eq%20%22testsp%22", + ReuseRequest: true, + Response: spResources, + }, + // Deliberately NO fixture for /api/2.0/preview/scim/v2/Me — if the + // post-Read provider_config hook fires, it will try to call /Me and + // the test will fail with a missing-stub error. + }) + assert.NoError(t, err) + defer server.Close() + + // Simulate a real account-level provider: AccountID set and no cached + // workspace ID so the post-Read hook (if it fires) is forced to call /Me. + client.Config.AccountID = "abc" + client.SetCachedWorkspaceID(0) + + r := DataSourceServicePrincipal().ToResource() + d := r.TestResourceData() + // On main the `api` field exists and routes to account-level SCIM; on + // v1.114.0 the schema has no such field and Set returns an error which + // we deliberately ignore (the data source then falls back to workspace + // SCIM, but the bug still surfaces because the hook runs unconditionally). + _ = d.Set("api", "account") + assert.NoError(t, d.Set("display_name", "testsp")) + ctx := context.WithValue(context.Background(), common.ResourceName, "service_principal") + diags := r.ReadContext(ctx, d, client) + + assert.False(t, diags.HasError(), + "post-Read provider_config hook must be skipped for service_principal data source at account level; got: %v", diags) + assert.Equal(t, "spid", d.Id()) +} + func TestDataServicePrincipalReadInvalidConfig(t *testing.T) { qa.ResourceFixture{ Resource: DataSourceServicePrincipal(),