Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/unreleased/BUG FIXES-20230210-175832.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: BUG FIXES
body: 'datasource/timeouts: Use default for null and unknown ([#35](https://github.com/hashicorp/terraform-plugin-framework-timeouts/pull/35)).'
time: 2023-02-10T17:58:32.928723089+01:00
custom:
Issue: "35"
5 changes: 5 additions & 0 deletions .changes/unreleased/BUG FIXES-20230210-175852.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: BUG FIXES
body: 'resource/timeouts: Use default for null and unknown ([#35](https://github.com/hashicorp/terraform-plugin-framework-timeouts/pull/35)).'
time: 2023-02-10T17:58:52.979389154+01:00
custom:
Issue: "35"
6 changes: 6 additions & 0 deletions datasource/timeouts/timeouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ func (t Value) getTimeout(ctx context.Context, timeoutName string, defaultTimeou
return defaultTimeout, diags
}

if value.IsNull() || value.IsUnknown() {
tflog.Info(ctx, timeoutName+" timeout configuration is null or unknown, using provided default")

return defaultTimeout, diags
}

// No type assertion check is required as the schema guarantees that the object attributes
// are types.String.
timeout, err := time.ParseDuration(value.(types.String).ValueString())
Expand Down
26 changes: 26 additions & 0 deletions datasource/timeouts/timeouts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,32 @@ func TestTimeoutsValueRead(t *testing.T) {
},
expectedTimeout: 20 * time.Minute,
},
"read-null": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"read": types.StringType,
},
map[string]attr.Value{
"read": types.StringNull(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"read-unknown": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"read": types.StringType,
},
map[string]attr.Value{
"read": types.StringUnknown(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"read-not-parseable-as-time-duration": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
Expand Down
6 changes: 6 additions & 0 deletions resource/timeouts/timeouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ func (t Value) getTimeout(ctx context.Context, timeoutName string, defaultTimeou
return defaultTimeout, diags
}

if value.IsNull() || value.IsUnknown() {
tflog.Info(ctx, timeoutName+" timeout configuration is null or unknown, using provided default")

return defaultTimeout, diags
}

// No type assertion check is required as the schema guarantees that the object attributes
// are types.String.
timeout, err := time.ParseDuration(value.(types.String).ValueString())
Expand Down
104 changes: 104 additions & 0 deletions resource/timeouts/timeouts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,32 @@ func TestTimeoutsValueCreate(t *testing.T) {
},
expectedTimeout: 20 * time.Minute,
},
"create-null": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"create": types.StringType,
},
map[string]attr.Value{
"create": types.StringNull(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"create-unknown": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"create": types.StringType,
},
map[string]attr.Value{
"create": types.StringUnknown(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"create-not-parseable-as-time-duration": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
Expand Down Expand Up @@ -248,6 +274,32 @@ func TestTimeoutsValueRead(t *testing.T) {
},
expectedTimeout: 20 * time.Minute,
},
"read-null": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"read": types.StringType,
},
map[string]attr.Value{
"read": types.StringNull(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"read-unknown": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"read": types.StringType,
},
map[string]attr.Value{
"read": types.StringUnknown(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"read-not-parseable-as-time-duration": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
Expand Down Expand Up @@ -316,6 +368,32 @@ func TestTimeoutsValueUpdate(t *testing.T) {
},
expectedTimeout: 20 * time.Minute,
},
"update-null": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"update": types.StringType,
},
map[string]attr.Value{
"update": types.StringNull(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"update-unknown": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"update": types.StringType,
},
map[string]attr.Value{
"update": types.StringUnknown(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"update-not-parseable-as-time-duration": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
Expand Down Expand Up @@ -384,6 +462,32 @@ func TestTimeoutsValueDelete(t *testing.T) {
},
expectedTimeout: 20 * time.Minute,
},
"delete-null": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"delete": types.StringType,
},
map[string]attr.Value{
"delete": types.StringNull(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"delete-unknown": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
map[string]attr.Type{
"delete": types.StringType,
},
map[string]attr.Value{
"delete": types.StringUnknown(),
},
),
},
expectedTimeout: 20 * time.Minute,
},
"delete-not-parseable-as-time-duration": {
timeoutsValue: timeouts.Value{
Object: types.ObjectValueMust(
Expand Down