From fd34f822d25a4038e305776687ea9276806cfdcc Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Thu, 22 May 2025 16:18:48 +0000 Subject: [PATCH 01/12] feat: add cache_invalidation parameter to prebuild resource --- docs/data-sources/workspace_preset.md | 11 +++++ integration/integration_test.go | 11 ++--- integration/test-data-source/main.tf | 4 ++ provider/workspace_preset.go | 25 ++++++++++- provider/workspace_preset_test.go | 60 +++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 6 deletions(-) diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md index 14e235f9..baf40ba3 100644 --- a/docs/data-sources/workspace_preset.md +++ b/docs/data-sources/workspace_preset.md @@ -51,3 +51,14 @@ data "coder_workspace_preset" "example" { Required: - `instances` (Number) The number of workspaces to keep in reserve for this preset. + +Optional: + +- `cache_invalidation` (Block Set, Max: 1) Configuration block that defines TTL (time-to-live) behavior for prebuilds. Use this to automatically invalidate and delete prebuilds after a certain period, ensuring they stay up-to-date. (see [below for nested schema](#nestedblock--prebuilds--cache_invalidation)) + + +### Nested Schema for `prebuilds.cache_invalidation` + +Required: + +- `invalidate_after_secs` (Number) Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup. diff --git a/integration/integration_test.go b/integration/integration_test.go index a5019635..88671b47 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -90,11 +90,12 @@ func TestIntegration(t *testing.T) { // TODO (sasswart): the cli doesn't support presets yet. // once it does, the value for workspace_parameter.value // will be the preset value. - "workspace_parameter.value": `param value`, - "workspace_parameter.icon": `param icon`, - "workspace_preset.name": `preset`, - "workspace_preset.parameters.param": `preset param value`, - "workspace_preset.prebuilds.instances": `1`, + "workspace_parameter.value": `param value`, + "workspace_parameter.icon": `param icon`, + "workspace_preset.name": `preset`, + "workspace_preset.parameters.param": `preset param value`, + "workspace_preset.prebuilds.instances": `1`, + "workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs": `86400`, }, }, { diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index f18fa347..5825ff98 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -27,6 +27,9 @@ data "coder_workspace_preset" "preset" { prebuilds { instances = 1 + cache_invalidation = { + invalidate_after_secs = 86400 + } } } @@ -52,6 +55,7 @@ locals { "workspace_preset.name" : data.coder_workspace_preset.preset.name, "workspace_preset.parameters.param" : data.coder_workspace_preset.preset.parameters.param, "workspace_preset.prebuilds.instances" : tostring(one(data.coder_workspace_preset.preset.prebuilds).instances), + "workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs" : tostring(one(data.coder_workspace_preset.preset.prebuilds.cache_invalidation).invalidate_after_secs), } } diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 78466c10..53d218f9 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -21,7 +21,12 @@ type WorkspacePreset struct { } type WorkspacePrebuild struct { - Instances int `mapstructure:"instances"` + Instances int `mapstructure:"instances"` + CacheInvalidation []CacheInvalidation `mapstructure:"cache_invalidation"` +} + +type CacheInvalidation struct { + InvalidateAfterSecs int `mapstructure:"invalidate_after_secs"` } func workspacePresetDataSource() *schema.Resource { @@ -81,6 +86,24 @@ func workspacePresetDataSource() *schema.Resource { ForceNew: true, ValidateFunc: validation.IntAtLeast(0), }, + "cache_invalidation": { + Type: schema.TypeSet, + Description: "Configuration block that defines TTL (time-to-live) behavior for prebuilds. Use this to automatically invalidate and delete prebuilds after a certain period, ensuring they stay up-to-date.", + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "invalidate_after_secs": { + Type: schema.TypeInt, + Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.", + Required: true, + ForceNew: true, + //Default: 86400, // TODO: Should we add a default value? + ValidateFunc: validation.IntAtLeast(0), + }, + }, + }, + }, }, }, }, diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index aa1ca0ce..93f9429a 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -144,6 +144,66 @@ func TestWorkspacePreset(t *testing.T) { return nil }, }, + { + Name: "Prebuilds is set with a cache_invalidation field without its required fields", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = { + "region" = "us-east1-a" + } + prebuilds { + instances = 1 + cache_invalidation {} + } + }`, + ExpectError: regexp.MustCompile("The argument \"invalidate_after_secs\" is required, but no definition was found."), + }, + { + Name: "Prebuilds is set with a cache_invalidation field with its required fields", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = { + "region" = "us-east1-a" + } + prebuilds { + instances = 1 + cache_invalidation { + invalidate_after_secs = 86400 + } + } + }`, + ExpectError: nil, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + resource := state.Modules[0].Resources["data.coder_workspace_preset.preset_1"] + require.NotNil(t, resource) + attrs := resource.Primary.Attributes + require.Equal(t, attrs["name"], "preset_1") + require.Equal(t, attrs["prebuilds.0.cache_invalidation.0.invalidate_after_secs"], "86400") + return nil + }, + }, + { + Name: "Prebuilds is set with a cache_invalidation field with its required fields and an unexpected argument", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = { + "region" = "us-east1-a" + } + prebuilds { + instances = 1 + cache_invalidation { + invalidate_after_secs = 86400 + invalid_argument = "test" + } + } + }`, + ExpectError: regexp.MustCompile("An argument named \"invalid_argument\" is not expected here."), + }, } for _, testcase := range testcases { From 4c4617106bb0cbd27612c72da3b0529f8d5f5fee Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Thu, 22 May 2025 16:28:49 +0000 Subject: [PATCH 02/12] fix: formatting --- integration/test-data-source/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 5825ff98..86cedf35 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -28,7 +28,7 @@ data "coder_workspace_preset" "preset" { prebuilds { instances = 1 cache_invalidation = { - invalidate_after_secs = 86400 + invalidate_after_secs = 86400 } } } From c6db67db1a959815c5cf085e53cb0f27900ca5e7 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Thu, 22 May 2025 16:30:27 +0000 Subject: [PATCH 03/12] fix: remove TODO comment --- provider/workspace_preset.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 53d218f9..1b709277 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -94,11 +94,10 @@ func workspacePresetDataSource() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "invalidate_after_secs": { - Type: schema.TypeInt, - Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.", - Required: true, - ForceNew: true, - //Default: 86400, // TODO: Should we add a default value? + Type: schema.TypeInt, + Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.", + Required: true, + ForceNew: true, ValidateFunc: validation.IntAtLeast(0), }, }, From 85bec3f29dc4dffe2e512429909129b8ea3e8106 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 09:36:56 +0000 Subject: [PATCH 04/12] fix: cache_invalidation block in integration tests --- integration/test-data-source/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 86cedf35..ed378044 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -27,7 +27,7 @@ data "coder_workspace_preset" "preset" { prebuilds { instances = 1 - cache_invalidation = { + cache_invalidation { invalidate_after_secs = 86400 } } From 8baec44966aa2bc301244e19ab7b6a2cbcd9ed24 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 09:46:34 +0000 Subject: [PATCH 05/12] fix: main.tf integration test --- integration/test-data-source/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index ed378044..9e5288eb 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -55,7 +55,7 @@ locals { "workspace_preset.name" : data.coder_workspace_preset.preset.name, "workspace_preset.parameters.param" : data.coder_workspace_preset.preset.parameters.param, "workspace_preset.prebuilds.instances" : tostring(one(data.coder_workspace_preset.preset.prebuilds).instances), - "workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs" : tostring(one(data.coder_workspace_preset.preset.prebuilds.cache_invalidation).invalidate_after_secs), + "workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs" : tostring(one(one(data.coder_workspace_preset.preset.prebuilds).cache_invalidation).invalidate_after_secs), } } From 17090ae60b1839fb15803cb2d38215c33af6100e Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 10:04:20 +0000 Subject: [PATCH 06/12] fix: test Prebuilds_is_set_with_a_cache_invalidation_field_without_its_required_fields --- provider/workspace_preset_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 93f9429a..17b1eda9 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -1,6 +1,7 @@ package provider_test import ( + "fmt" "regexp" "testing" @@ -157,7 +158,7 @@ func TestWorkspacePreset(t *testing.T) { cache_invalidation {} } }`, - ExpectError: regexp.MustCompile("The argument \"invalidate_after_secs\" is required, but no definition was found."), + ExpectError: regexp.MustCompile("The argument \"invalidate_after_secs\" is required,"), }, { Name: "Prebuilds is set with a cache_invalidation field with its required fields", @@ -210,6 +211,7 @@ func TestWorkspacePreset(t *testing.T) { t.Run(testcase.Name, func(t *testing.T) { t.Parallel() + fmt.Println("testcase.ExpectError: ", testcase.ExpectError) resource.Test(t, resource.TestCase{ ProviderFactories: coderFactory(), IsUnitTest: true, From aff08329e60b4126a58e875a2d83aecd284a7c4b Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 10:06:04 +0000 Subject: [PATCH 07/12] fix: remove printf --- provider/workspace_preset_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 17b1eda9..4f582a35 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -1,7 +1,6 @@ package provider_test import ( - "fmt" "regexp" "testing" @@ -210,8 +209,7 @@ func TestWorkspacePreset(t *testing.T) { for _, testcase := range testcases { t.Run(testcase.Name, func(t *testing.T) { t.Parallel() - - fmt.Println("testcase.ExpectError: ", testcase.ExpectError) + resource.Test(t, resource.TestCase{ ProviderFactories: coderFactory(), IsUnitTest: true, From 60beaea332d080f35faba15c120617b900b91e8c Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 10:27:23 +0000 Subject: [PATCH 08/12] chore: add comment about partial match in preset test --- provider/workspace_preset_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 4f582a35..95dabe9c 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -157,6 +157,9 @@ func TestWorkspacePreset(t *testing.T) { cache_invalidation {} } }`, + // Note: Match only the beginning of the error message to make the test more reliable. + // The full error message includes formatting differences like newlines, which could + // cause the test to fail unnecessarily. ExpectError: regexp.MustCompile("The argument \"invalidate_after_secs\" is required,"), }, { @@ -209,7 +212,7 @@ func TestWorkspacePreset(t *testing.T) { for _, testcase := range testcases { t.Run(testcase.Name, func(t *testing.T) { t.Parallel() - + resource.Test(t, resource.TestCase{ ProviderFactories: coderFactory(), IsUnitTest: true, From 1c1ea400ac86433a15d321108715b2aea82b6227 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 11:31:50 +0000 Subject: [PATCH 09/12] chore: add comment about cache_invalidation struct as slice --- provider/workspace_preset.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 1b709277..5b3008a8 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -21,7 +21,12 @@ type WorkspacePreset struct { } type WorkspacePrebuild struct { - Instances int `mapstructure:"instances"` + Instances int `mapstructure:"instances"` + // There should always be only one cache_invalidation block, but Terraform's type system + // still parses them as a slice, so we need to handle it as such. We could use + // an anonymous type and rd.Get to avoid a slice here, but that would not be possible + // for utilities that parse our terraform output using this type. To remain compatible + // with those cases, we use a slice here. CacheInvalidation []CacheInvalidation `mapstructure:"cache_invalidation"` } From 1ae84e8533d6fa108d6d394ebe819263ff268ec4 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 11:45:37 +0000 Subject: [PATCH 10/12] chore: add max validation of 604800 seconds (7 days) for invalidate_after_secs to prevent stale prebuilds --- provider/workspace_preset.go | 11 ++++++----- provider/workspace_preset_test.go | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 5b3008a8..537a532f 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -99,11 +99,12 @@ func workspacePresetDataSource() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "invalidate_after_secs": { - Type: schema.TypeInt, - Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.", - Required: true, - ForceNew: true, - ValidateFunc: validation.IntAtLeast(0), + Type: schema.TypeInt, + Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.", + Required: true, + ForceNew: true, + // Ensure invalidation is between 0 and 604800 seconds (7 days) to prevent stale prebuilds + ValidateFunc: validation.IntBetween(0, 604800), }, }, }, diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 95dabe9c..91545ee3 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -189,6 +189,23 @@ func TestWorkspacePreset(t *testing.T) { return nil }, }, + { + Name: "Prebuilds block with cache_invalidation.invalidate_after_secs set to 15 days (exceeds 7 days limit)", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = { + "region" = "us-east1-a" + } + prebuilds { + instances = 1 + cache_invalidation { + invalidate_after_secs = 1296000 + } + } + }`, + ExpectError: regexp.MustCompile(`expected prebuilds.0.cache_invalidation.0.invalidate_after_secs to be in the range \(0 - 604800\), got 1296000`), + }, { Name: "Prebuilds is set with a cache_invalidation field with its required fields and an unexpected argument", Config: ` From 2a34f0d27a4687fa0b8094d03f35a7adab5d1c6a Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 16:59:14 +0000 Subject: [PATCH 11/12] chores: update terraform schema to expiration_policy.ttl & update max validation ttl value to 1 year --- docs/data-sources/workspace_preset.md | 8 +++---- integration/integration_test.go | 12 +++++------ integration/test-data-source/main.tf | 6 +++--- provider/workspace_preset.go | 16 +++++++------- provider/workspace_preset_test.go | 31 ++++++++++++--------------- 5 files changed, 35 insertions(+), 38 deletions(-) diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md index baf40ba3..cd4908c2 100644 --- a/docs/data-sources/workspace_preset.md +++ b/docs/data-sources/workspace_preset.md @@ -54,11 +54,11 @@ Required: Optional: -- `cache_invalidation` (Block Set, Max: 1) Configuration block that defines TTL (time-to-live) behavior for prebuilds. Use this to automatically invalidate and delete prebuilds after a certain period, ensuring they stay up-to-date. (see [below for nested schema](#nestedblock--prebuilds--cache_invalidation)) +- `expiration_policy` (Block Set, Max: 1) Configuration block that defines TTL (time-to-live) behavior for prebuilds. Use this to automatically invalidate and delete prebuilds after a certain period, ensuring they stay up-to-date. (see [below for nested schema](#nestedblock--prebuilds--expiration_policy)) - -### Nested Schema for `prebuilds.cache_invalidation` + +### Nested Schema for `prebuilds.expiration_policy` Required: -- `invalidate_after_secs` (Number) Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup. +- `ttl` (Number) Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup. diff --git a/integration/integration_test.go b/integration/integration_test.go index 88671b47..36612904 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -90,12 +90,12 @@ func TestIntegration(t *testing.T) { // TODO (sasswart): the cli doesn't support presets yet. // once it does, the value for workspace_parameter.value // will be the preset value. - "workspace_parameter.value": `param value`, - "workspace_parameter.icon": `param icon`, - "workspace_preset.name": `preset`, - "workspace_preset.parameters.param": `preset param value`, - "workspace_preset.prebuilds.instances": `1`, - "workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs": `86400`, + "workspace_parameter.value": `param value`, + "workspace_parameter.icon": `param icon`, + "workspace_preset.name": `preset`, + "workspace_preset.parameters.param": `preset param value`, + "workspace_preset.prebuilds.instances": `1`, + "workspace_preset.prebuilds.expiration_policy.ttl": `86400`, }, }, { diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 9e5288eb..50274fff 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -27,8 +27,8 @@ data "coder_workspace_preset" "preset" { prebuilds { instances = 1 - cache_invalidation { - invalidate_after_secs = 86400 + expiration_policy { + ttl = 86400 } } } @@ -55,7 +55,7 @@ locals { "workspace_preset.name" : data.coder_workspace_preset.preset.name, "workspace_preset.parameters.param" : data.coder_workspace_preset.preset.parameters.param, "workspace_preset.prebuilds.instances" : tostring(one(data.coder_workspace_preset.preset.prebuilds).instances), - "workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs" : tostring(one(one(data.coder_workspace_preset.preset.prebuilds).cache_invalidation).invalidate_after_secs), + "workspace_preset.prebuilds.expiration_policy.ttl" : tostring(one(one(data.coder_workspace_preset.preset.prebuilds).expiration_policy).ttl), } } diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 537a532f..15e4c666 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -22,16 +22,16 @@ type WorkspacePreset struct { type WorkspacePrebuild struct { Instances int `mapstructure:"instances"` - // There should always be only one cache_invalidation block, but Terraform's type system + // There should always be only one expiration_policy block, but Terraform's type system // still parses them as a slice, so we need to handle it as such. We could use // an anonymous type and rd.Get to avoid a slice here, but that would not be possible // for utilities that parse our terraform output using this type. To remain compatible // with those cases, we use a slice here. - CacheInvalidation []CacheInvalidation `mapstructure:"cache_invalidation"` + ExpirationPolicy []ExpirationPolicy `mapstructure:"expiration_policy"` } -type CacheInvalidation struct { - InvalidateAfterSecs int `mapstructure:"invalidate_after_secs"` +type ExpirationPolicy struct { + TTL int `mapstructure:"ttl"` } func workspacePresetDataSource() *schema.Resource { @@ -91,20 +91,20 @@ func workspacePresetDataSource() *schema.Resource { ForceNew: true, ValidateFunc: validation.IntAtLeast(0), }, - "cache_invalidation": { + "expiration_policy": { Type: schema.TypeSet, Description: "Configuration block that defines TTL (time-to-live) behavior for prebuilds. Use this to automatically invalidate and delete prebuilds after a certain period, ensuring they stay up-to-date.", Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "invalidate_after_secs": { + "ttl": { Type: schema.TypeInt, Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.", Required: true, ForceNew: true, - // Ensure invalidation is between 0 and 604800 seconds (7 days) to prevent stale prebuilds - ValidateFunc: validation.IntBetween(0, 604800), + // Ensure invalidation is between 0 and 31536000 seconds (1 year) to prevent stale prebuilds + ValidateFunc: validation.IntBetween(0, 31536000), }, }, }, diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 91545ee3..d9f7da46 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -145,7 +145,7 @@ func TestWorkspacePreset(t *testing.T) { }, }, { - Name: "Prebuilds is set with a cache_invalidation field without its required fields", + Name: "Prebuilds is set with a expiration_policy field without its required fields", Config: ` data "coder_workspace_preset" "preset_1" { name = "preset_1" @@ -154,16 +154,13 @@ func TestWorkspacePreset(t *testing.T) { } prebuilds { instances = 1 - cache_invalidation {} + expiration_policy {} } }`, - // Note: Match only the beginning of the error message to make the test more reliable. - // The full error message includes formatting differences like newlines, which could - // cause the test to fail unnecessarily. - ExpectError: regexp.MustCompile("The argument \"invalidate_after_secs\" is required,"), + ExpectError: regexp.MustCompile("The argument \"ttl\" is required, but no definition was found."), }, { - Name: "Prebuilds is set with a cache_invalidation field with its required fields", + Name: "Prebuilds is set with a expiration_policy field with its required fields", Config: ` data "coder_workspace_preset" "preset_1" { name = "preset_1" @@ -172,8 +169,8 @@ func TestWorkspacePreset(t *testing.T) { } prebuilds { instances = 1 - cache_invalidation { - invalidate_after_secs = 86400 + expiration_policy { + ttl = 86400 } } }`, @@ -185,12 +182,12 @@ func TestWorkspacePreset(t *testing.T) { require.NotNil(t, resource) attrs := resource.Primary.Attributes require.Equal(t, attrs["name"], "preset_1") - require.Equal(t, attrs["prebuilds.0.cache_invalidation.0.invalidate_after_secs"], "86400") + require.Equal(t, attrs["prebuilds.0.expiration_policy.0.ttl"], "86400") return nil }, }, { - Name: "Prebuilds block with cache_invalidation.invalidate_after_secs set to 15 days (exceeds 7 days limit)", + Name: "Prebuilds block with expiration_policy.ttl set to 2 years (exceeds 1 year limit)", Config: ` data "coder_workspace_preset" "preset_1" { name = "preset_1" @@ -199,15 +196,15 @@ func TestWorkspacePreset(t *testing.T) { } prebuilds { instances = 1 - cache_invalidation { - invalidate_after_secs = 1296000 + expiration_policy { + ttl = 63072000 } } }`, - ExpectError: regexp.MustCompile(`expected prebuilds.0.cache_invalidation.0.invalidate_after_secs to be in the range \(0 - 604800\), got 1296000`), + ExpectError: regexp.MustCompile(`expected prebuilds.0.expiration_policy.0.ttl to be in the range \(0 - 31536000\), got 63072000`), }, { - Name: "Prebuilds is set with a cache_invalidation field with its required fields and an unexpected argument", + Name: "Prebuilds is set with a expiration_policy field with its required fields and an unexpected argument", Config: ` data "coder_workspace_preset" "preset_1" { name = "preset_1" @@ -216,8 +213,8 @@ func TestWorkspacePreset(t *testing.T) { } prebuilds { instances = 1 - cache_invalidation { - invalidate_after_secs = 86400 + expiration_policy { + ttl = 86400 invalid_argument = "test" } } From c309685e0c910f84f6563778edcbe07d0de9580c Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Fri, 23 May 2025 17:06:27 +0000 Subject: [PATCH 12/12] fix: comment --- provider/workspace_preset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 15e4c666..e9c697c7 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -103,7 +103,7 @@ func workspacePresetDataSource() *schema.Resource { Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.", Required: true, ForceNew: true, - // Ensure invalidation is between 0 and 31536000 seconds (1 year) to prevent stale prebuilds + // Ensure TTL is between 0 and 31536000 seconds (1 year) to prevent stale prebuilds ValidateFunc: validation.IntBetween(0, 31536000), }, },