Skip to content

Commit b5beaf2

Browse files
authored
Increase HTTP timeout in tests to 5m (#4597)
## Changes Currently the TF provider uses the Go SDK's default HTTP timeout of 60 seconds to wait for a response from the API. This is coupled with a 60 second server-side timeout for the API proxy. However, backend services that expect to take longer to handle requests can have an increased server-side timeout. In this case, the client may need to wait for longer than 60 seconds to receive a response. As a result, some integration tests for the provider fail with errors like "request timed out after 1m0s". This PR adjusts this by configuring the SDK used by the provider to have a 10-minute timeout during integration tests. This is longer than any individual server's server-side timeout. Long-term, the SDK should be responsible for selecting the appropriate client-side timeout for a given API, but in the meantime we'll make this adjustment. This only affects tests. The default value for http_timeout_seconds is still 60 seconds. To-do: - [ ] Add doccomments to new exported methods/functions/types. ## Tests - [ ] Run integration tests, see that they pass. NO_CHANGELOG=true
1 parent 7f8effb commit b5beaf2

File tree

8 files changed

+161
-65
lines changed

8 files changed

+161
-65
lines changed

internal/acceptance/init.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ import (
2222
"github.com/databricks/terraform-provider-databricks/commands"
2323
"github.com/databricks/terraform-provider-databricks/common"
2424
"github.com/databricks/terraform-provider-databricks/internal/providers"
25+
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw"
26+
"github.com/databricks/terraform-provider-databricks/internal/providers/sdkv2"
2527
dbproviderlogger "github.com/databricks/terraform-provider-databricks/logger"
2628
"github.com/databricks/terraform-provider-databricks/qa"
29+
"github.com/hashicorp/terraform-plugin-framework/provider"
2730
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
31+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
2832
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
2933
"github.com/hashicorp/terraform-plugin-testing/terraform"
3034
)
@@ -161,6 +165,31 @@ func environmentTemplate(t *testing.T, template string, otherVars ...map[string]
161165
return commands.TrimLeadingWhitespace(template)
162166
}
163167

168+
// ProvidersWithResourceFallbacks creates test providers, falling back to the SDKv2 provider for the
169+
// specified resources. This is a convenience constructor that ensures that the resulting mux'ed provider
170+
// uses the SDKv2 implementation for the specified resources.
171+
func ProvidersWithResourceFallbacks(resourceFallbacks []string) (*schema.Provider, provider.Provider) {
172+
pluginfwOpt := pluginfw.WithSdkV2ResourceFallbacks(resourceFallbacks)
173+
pluginFrameworkProvider := PluginFrameworkProviderForTest(pluginfwOpt)
174+
175+
sdkV2Opt := sdkv2.WithSdkV2ResourceFallbacks(resourceFallbacks)
176+
sdkV2Provider := SdkV2ProviderForTest(sdkV2Opt)
177+
178+
return sdkV2Provider, pluginFrameworkProvider
179+
}
180+
181+
// SdkV2ProviderForTest creates a test provider with the default config customizer.
182+
func SdkV2ProviderForTest(sdkV2Options ...sdkv2.SdkV2ProviderOption) *schema.Provider {
183+
opts := append(sdkV2Options, sdkv2.WithConfigCustomizer(DefaultConfigCustomizer))
184+
return sdkv2.DatabricksProvider(opts...)
185+
}
186+
187+
// PluginFrameworkProviderForTest creates a test provider with the default config customizer.
188+
func PluginFrameworkProviderForTest(pluginFwOptions ...pluginfw.PluginFrameworkOption) provider.Provider {
189+
opts := append(pluginFwOptions, pluginfw.WithConfigCustomizer(DefaultConfigCustomizer))
190+
return pluginfw.GetDatabricksProviderPluginFramework(opts...)
191+
}
192+
164193
// Test wrapper over terraform testing framework. Multiple steps share the same
165194
// terraform state context.
166195
func run(t *testing.T, steps []Step) {
@@ -173,7 +202,12 @@ func run(t *testing.T, steps []Step) {
173202
"databricks": func() (tfprotov6.ProviderServer, error) {
174203
ctx := context.Background()
175204

176-
return providers.GetProviderServer(ctx)
205+
// The SDKv2 and Plugin Framework providers are customized to increase the default HTTP timeout.
206+
// Otherwise, they are no different from the production provider.
207+
sdkPluginProvider := SdkV2ProviderForTest()
208+
pluginFrameworkProvider := PluginFrameworkProviderForTest()
209+
210+
return providers.GetProviderServer(ctx, providers.WithSdkV2Provider(sdkPluginProvider), providers.WithPluginFrameworkProvider(pluginFrameworkProvider))
177211
},
178212
}
179213
cwd, err := os.Getwd()
@@ -252,6 +286,14 @@ func run(t *testing.T, steps []Step) {
252286
})
253287
}
254288

289+
// DefaultConfigCustomizer modifies the SDK configuration, setting the HTTP timeout to 10 minutes.
290+
// Most APIs have a default timeout of 1 minute, but some have longer. Extending the HTTP timeout
291+
// ensures that tests don't fail even if individual requests take longer than 1 minute.
292+
func DefaultConfigCustomizer(cfg *config.Config) error {
293+
cfg.HTTPTimeoutSeconds = 10 * 60
294+
return nil
295+
}
296+
255297
// resourceCheck calls back a function with client and resource id
256298
func ResourceCheck(name string,
257299
cb func(ctx context.Context, client *common.DatabricksClient, id string) error) resource.TestCheckFunc {

internal/providers/pluginfw/pluginfw.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,33 @@ import (
2626
"github.com/hashicorp/terraform-plugin-log/tflog"
2727
)
2828

29-
func GetDatabricksProviderPluginFramework(sdkV2FallbackOptions ...SdkV2FallbackOption) provider.Provider {
30-
p := &DatabricksProviderPluginFramework{sdkV2Fallbacks: sdkV2FallbackOptions}
29+
func GetDatabricksProviderPluginFramework(opts ...PluginFrameworkOption) provider.Provider {
30+
providerOptions := &pluginFrameworkOptions{}
31+
for _, opt := range opts {
32+
opt.Apply(providerOptions)
33+
}
34+
p := &DatabricksProviderPluginFramework{
35+
sdkV2ResourceFallbacks: providerOptions.resourceFallbacks,
36+
sdkV2DataSourceFallbacks: providerOptions.dataSourceFallbacks,
37+
configCustomizer: providerOptions.configCustomizer,
38+
}
3139
return p
3240
}
3341

3442
type DatabricksProviderPluginFramework struct {
35-
sdkV2Fallbacks []SdkV2FallbackOption
43+
sdkV2ResourceFallbacks []string
44+
sdkV2DataSourceFallbacks []string
45+
configCustomizer func(*config.Config) error
3646
}
3747

3848
var _ provider.Provider = (*DatabricksProviderPluginFramework)(nil)
3949

4050
func (p *DatabricksProviderPluginFramework) Resources(ctx context.Context) []func() resource.Resource {
41-
return getPluginFrameworkResourcesToRegister(p.sdkV2Fallbacks...)
51+
return getPluginFrameworkResourcesToRegister(p.sdkV2ResourceFallbacks)
4252
}
4353

4454
func (p *DatabricksProviderPluginFramework) DataSources(ctx context.Context) []func() datasource.DataSource {
45-
return getPluginFrameworkDataSourcesToRegister(p.sdkV2Fallbacks...)
55+
return getPluginFrameworkDataSourcesToRegister(p.sdkV2DataSourceFallbacks)
4656
}
4757

4858
func (p *DatabricksProviderPluginFramework) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
@@ -55,7 +65,7 @@ func (p *DatabricksProviderPluginFramework) Metadata(ctx context.Context, req pr
5565
}
5666

5767
func (p *DatabricksProviderPluginFramework) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
58-
client := configureDatabricksClient_PluginFramework(ctx, req, resp)
68+
client := p.configureDatabricksClient(ctx, req, resp)
5969
resp.DataSourceData = client
6070
resp.ResourceData = client
6171
}
@@ -88,7 +98,7 @@ func providerSchemaPluginFramework() schema.Schema {
8898
}
8999
}
90100

91-
func configureDatabricksClient_PluginFramework(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) any {
101+
func (p *DatabricksProviderPluginFramework) configureDatabricksClient(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) any {
92102
cfg := &config.Config{}
93103
attrsUsed := []string{}
94104
for _, attr := range config.ConfigAttributes {
@@ -150,6 +160,13 @@ func configureDatabricksClient_PluginFramework(ctx context.Context, req provider
150160
cfg.AuthType = newer
151161
}
152162
}
163+
if p.configCustomizer != nil {
164+
err := p.configCustomizer(cfg)
165+
if err != nil {
166+
resp.Diagnostics.AddError("Failed to customize config", err.Error())
167+
return nil
168+
}
169+
}
153170
client, err := client.New(cfg)
154171
if err != nil {
155172
resp.Diagnostics.Append(diag.NewErrorDiagnostic(err.Error(), ""))

internal/providers/pluginfw/pluginfw_rollout_utils.go

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"slices"
1313
"strings"
1414

15+
"github.com/databricks/databricks-sdk-go/config"
1516
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/app"
1617
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/catalog"
1718
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/cluster"
@@ -70,42 +71,56 @@ var pluginFwOnlyDataSources = append(
7071
autoGeneratedDataSources...,
7172
)
7273

73-
type sdkV2FallbackOptions struct {
74+
type pluginFrameworkOptions struct {
7475
resourceFallbacks []string
7576
dataSourceFallbacks []string
77+
configCustomizer func(*config.Config) error
7678
}
7779

78-
// SdkV2FallbackOption is an interface for acceptance tests to specify resources / data sources to fallback to SDK V2
79-
type SdkV2FallbackOption interface {
80-
Apply(*sdkV2FallbackOptions)
80+
// PluginFrameworkOption is an interface for acceptance tests to specify resources / data sources to fallback to SDK V2
81+
type PluginFrameworkOption interface {
82+
Apply(*pluginFrameworkOptions)
8183
}
8284

8385
type sdkV2ResourceFallback struct {
8486
resourceFallbacks []string
8587
}
8688

87-
func (o *sdkV2ResourceFallback) Apply(options *sdkV2FallbackOptions) {
89+
func (o *sdkV2ResourceFallback) Apply(options *pluginFrameworkOptions) {
8890
options.resourceFallbacks = o.resourceFallbacks
8991
}
9092

9193
// WithSdkV2ResourceFallbacks is a helper function to specify resources to fallback to SDK V2
92-
func WithSdkV2ResourceFallbacks(fallbacks ...string) SdkV2FallbackOption {
94+
func WithSdkV2ResourceFallbacks(fallbacks []string) PluginFrameworkOption {
9395
return &sdkV2ResourceFallback{resourceFallbacks: fallbacks}
9496
}
9597

9698
type sdkv2DataSourceFallback struct {
9799
dataSourceFallbacks []string
98100
}
99101

100-
func (o *sdkv2DataSourceFallback) Apply(options *sdkV2FallbackOptions) {
102+
func (o *sdkv2DataSourceFallback) Apply(options *pluginFrameworkOptions) {
101103
options.dataSourceFallbacks = o.dataSourceFallbacks
102104
}
103105

104106
// WithSdkV2DataSourceFallbacks is a helper function to specify data sources to fallback to SDK V2
105-
func WithSdkV2DataSourceFallbacks(fallbacks []string) SdkV2FallbackOption {
107+
func WithSdkV2DataSourceFallbacks(fallbacks []string) PluginFrameworkOption {
106108
return &sdkv2DataSourceFallback{dataSourceFallbacks: fallbacks}
107109
}
108110

111+
type configCustomizer struct {
112+
configCustomizer func(*config.Config) error
113+
}
114+
115+
func (o *configCustomizer) Apply(options *pluginFrameworkOptions) {
116+
options.configCustomizer = o.configCustomizer
117+
}
118+
119+
// WithConfigCustomizer allows the caller to customize the SDK config after config resolution.
120+
func WithConfigCustomizer(customizer func(*config.Config) error) PluginFrameworkOption {
121+
return &configCustomizer{configCustomizer: customizer}
122+
}
123+
109124
// GetUseSdkV2DataSources is a helper function to get name of resources that should use SDK V2 instead of plugin framework
110125
func getUseSdkV2Resources() []string {
111126
useSdkV2 := os.Getenv("USE_SDK_V2_RESOURCES")
@@ -137,18 +152,13 @@ func shouldUseSdkV2DataSource(dataSourceName string) bool {
137152
}
138153

139154
// getPluginFrameworkResourcesToRegister is a helper function to get the list of resources that are migrated away from sdkv2 to plugin framework
140-
func getPluginFrameworkResourcesToRegister(sdkV2Fallbacks ...SdkV2FallbackOption) []func() resource.Resource {
141-
fallbackOption := sdkV2FallbackOptions{}
142-
for _, o := range sdkV2Fallbacks {
143-
o.Apply(&fallbackOption)
144-
}
145-
155+
func getPluginFrameworkResourcesToRegister(resourceFallbacks []string) []func() resource.Resource {
146156
var resources []func() resource.Resource
147157

148158
// Loop through the map and add resources if they're not specifically marked to use the SDK V2
149159
for _, resourceFunc := range migratedResources {
150160
name := getResourceName(resourceFunc)
151-
if !shouldUseSdkV2Resource(name) && !slices.Contains(fallbackOption.resourceFallbacks, name) {
161+
if !shouldUseSdkV2Resource(name) && !slices.Contains(resourceFallbacks, name) {
152162
resources = append(resources, resourceFunc)
153163
}
154164
}
@@ -157,18 +167,13 @@ func getPluginFrameworkResourcesToRegister(sdkV2Fallbacks ...SdkV2FallbackOption
157167
}
158168

159169
// getPluginFrameworkDataSourcesToRegister is a helper function to get the list of data sources that are migrated away from sdkv2 to plugin framework
160-
func getPluginFrameworkDataSourcesToRegister(sdkV2Fallbacks ...SdkV2FallbackOption) []func() datasource.DataSource {
161-
fallbackOption := sdkV2FallbackOptions{}
162-
for _, o := range sdkV2Fallbacks {
163-
o.Apply(&fallbackOption)
164-
}
165-
170+
func getPluginFrameworkDataSourcesToRegister(dataSourceFallbacks []string) []func() datasource.DataSource {
166171
var dataSources []func() datasource.DataSource
167172

168173
// Loop through the map and add data sources if they're not specifically marked to use the SDK V2
169174
for _, dataSourceFunc := range migratedDataSources {
170175
name := getDataSourceName(dataSourceFunc)
171-
if !shouldUseSdkV2DataSource(name) && !slices.Contains(fallbackOption.dataSourceFallbacks, name) {
176+
if !shouldUseSdkV2DataSource(name) && !slices.Contains(dataSourceFallbacks, name) {
172177
dataSources = append(dataSources, dataSourceFunc)
173178
}
174179
}
@@ -189,33 +194,23 @@ func getDataSourceName(dataSourceFunc func() datasource.DataSource) string {
189194
}
190195

191196
// GetSdkV2ResourcesToRemove is a helper function to get the list of resources that are migrated away from sdkv2 to plugin framework
192-
func GetSdkV2ResourcesToRemove(sdkV2Fallbacks ...SdkV2FallbackOption) []string {
193-
fallbackOption := sdkV2FallbackOptions{}
194-
for _, o := range sdkV2Fallbacks {
195-
o.Apply(&fallbackOption)
196-
}
197-
197+
func GetSdkV2ResourcesToRemove(resourceFallbacks []string) []string {
198198
resourcesToRemove := []string{}
199199
for _, resourceFunc := range migratedResources {
200200
name := getResourceName(resourceFunc)
201-
if !shouldUseSdkV2Resource(name) && !slices.Contains(fallbackOption.resourceFallbacks, name) {
201+
if !shouldUseSdkV2Resource(name) && !slices.Contains(resourceFallbacks, name) {
202202
resourcesToRemove = append(resourcesToRemove, name)
203203
}
204204
}
205205
return resourcesToRemove
206206
}
207207

208208
// GetSdkV2DataSourcesToRemove is a helper function to get the list of data sources that are migrated away from sdkv2 to plugin framework
209-
func GetSdkV2DataSourcesToRemove(sdkV2Fallbacks ...SdkV2FallbackOption) []string {
210-
fallbackOption := sdkV2FallbackOptions{}
211-
for _, o := range sdkV2Fallbacks {
212-
o.Apply(&fallbackOption)
213-
}
214-
209+
func GetSdkV2DataSourcesToRemove(dataSourceFallbacks []string) []string {
215210
dataSourcesToRemove := []string{}
216211
for _, dataSourceFunc := range migratedDataSources {
217212
name := getDataSourceName(dataSourceFunc)
218-
if !shouldUseSdkV2DataSource(name) && !slices.Contains(fallbackOption.dataSourceFallbacks, name) {
213+
if !shouldUseSdkV2DataSource(name) && !slices.Contains(dataSourceFallbacks, name) {
219214
dataSourcesToRemove = append(dataSourcesToRemove, name)
220215
}
221216
}

internal/providers/pluginfw/products/library/resource_library_acc_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/databricks/databricks-sdk-go/service/compute"
1313
"github.com/databricks/terraform-provider-databricks/internal/acceptance"
1414
"github.com/databricks/terraform-provider-databricks/internal/providers"
15-
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw"
1615
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
1716
"github.com/hashicorp/terraform-plugin-testing/terraform"
1817
)
@@ -156,7 +155,8 @@ func TestAccLibraryUpdate(t *testing.T) {
156155

157156
var sdkV2FallbackFactory = map[string]func() (tfprotov6.ProviderServer, error){
158157
"databricks": func() (tfprotov6.ProviderServer, error) {
159-
return providers.GetProviderServer(context.Background(), providers.WithSdkV2FallbackOptions(pluginfw.WithSdkV2ResourceFallbacks("databricks_library")))
158+
sdkv2Provider, pluginfwProvider := acceptance.ProvidersWithResourceFallbacks([]string{"databricks_library"})
159+
return providers.GetProviderServer(context.Background(), providers.WithSdkV2Provider(sdkv2Provider), providers.WithPluginFrameworkProvider(pluginfwProvider))
160160
},
161161
}
162162

internal/providers/pluginfw/products/qualitymonitor/resource_quality_monitor_acc_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"github.com/databricks/terraform-provider-databricks/internal/acceptance"
99
"github.com/databricks/terraform-provider-databricks/internal/providers"
10-
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw"
1110
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
1211
)
1312

@@ -168,7 +167,8 @@ func TestUcAccUpdateQualityMonitor(t *testing.T) {
168167

169168
var sdkV2FallbackFactory = map[string]func() (tfprotov6.ProviderServer, error){
170169
"databricks": func() (tfprotov6.ProviderServer, error) {
171-
return providers.GetProviderServer(context.Background(), providers.WithSdkV2FallbackOptions(pluginfw.WithSdkV2ResourceFallbacks("databricks_quality_monitor")))
170+
sdkv2Provider, pluginfwProvider := acceptance.ProvidersWithResourceFallbacks([]string{"databricks_quality_monitor"})
171+
return providers.GetProviderServer(context.Background(), providers.WithSdkV2Provider(sdkv2Provider), providers.WithPluginFrameworkProvider(pluginfwProvider))
172172
},
173173
}
174174

internal/providers/providers.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
type serverOptions struct {
2121
sdkV2Provider *schema.Provider
2222
pluginFrameworkProvider provider.Provider
23-
sdkV2fallbacks []pluginfw.SdkV2FallbackOption
2423
}
2524

2625
// ServerOption is a common interface for overriding providers in GetProviderServer functino call.
@@ -42,18 +41,18 @@ func WithSdkV2Provider(sdkV2Provider *schema.Provider) ServerOption {
4241
return &sdkV2ProviderOption{sdkV2Provider: sdkV2Provider}
4342
}
4443

45-
type sdkV2FallbackOption struct {
46-
sdkV2fallbacks []pluginfw.SdkV2FallbackOption
44+
type pluginFrameworkProviderOption struct {
45+
pluginFrameworkProvider provider.Provider
4746
}
4847

49-
func (o *sdkV2FallbackOption) Apply(options *serverOptions) {
50-
options.sdkV2fallbacks = o.sdkV2fallbacks
48+
func (o *pluginFrameworkProviderOption) Apply(options *serverOptions) {
49+
options.pluginFrameworkProvider = o.pluginFrameworkProvider
5150
}
5251

53-
// WithSdkV2FallbackOptions allows overriding the SDKv2 fallback options used when creating a Terraform provider with muxing.
54-
// This is typically used in acceptance test for testing the compatibility between sdkv2 and plugin framework.
55-
func WithSdkV2FallbackOptions(options ...pluginfw.SdkV2FallbackOption) ServerOption {
56-
return &sdkV2FallbackOption{sdkV2fallbacks: options}
52+
// WithPluginFrameworkProvider allows overriding the plugin framework provider used when creating a Terraform provider with muxing.
53+
// This is typically used in acceptance test for a test step to have a custom provider override.
54+
func WithPluginFrameworkProvider(pluginFrameworkProvider provider.Provider) ServerOption {
55+
return &pluginFrameworkProviderOption{pluginFrameworkProvider: pluginFrameworkProvider}
5756
}
5857

5958
// GetProviderServer initializes and returns a Terraform Protocol v6 ProviderServer.
@@ -75,11 +74,11 @@ func GetProviderServer(ctx context.Context, options ...ServerOption) (tfprotov6.
7574
}
7675
sdkPluginProvider := serverOptions.sdkV2Provider
7776
if sdkPluginProvider == nil {
78-
sdkPluginProvider = sdkv2.DatabricksProvider(serverOptions.sdkV2fallbacks...)
77+
sdkPluginProvider = sdkv2.DatabricksProvider()
7978
}
8079
pluginFrameworkProvider := serverOptions.pluginFrameworkProvider
8180
if pluginFrameworkProvider == nil {
82-
pluginFrameworkProvider = pluginfw.GetDatabricksProviderPluginFramework(serverOptions.sdkV2fallbacks...)
81+
pluginFrameworkProvider = pluginfw.GetDatabricksProviderPluginFramework()
8382
}
8483

8584
upgradedSdkPluginProvider, err := tf5to6server.UpgradeServer(

0 commit comments

Comments
 (0)