Skip to content

Commit 5b75e29

Browse files
committed
Tighten profile refresh coverage and docs
1 parent 4273427 commit 5b75e29

6 files changed

Lines changed: 34 additions & 21 deletions

File tree

docs/resources/browser_pool.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Kernel browser pool durable configuration.
3131
- `project_id` (String) Project this browser pool belongs to. Defaults to the provider `project_id` when unset; when neither is set, the API key's project binding determines the project. Once created the pool keeps its project, and changing this attribute replaces the pool.
3232
- `proxy_id` (String) Optional proxy ID to use for browsers created by this pool.
3333
- `rebuild_idle_browsers_on_update` (Boolean) When true, changes to profile_id, proxy_id, extension_ids, chrome_policy, viewport, headless, kiosk_mode, stealth, or start_url discard browsers that are idle when the update runs so replacements use the new configuration. Browsers that are warming or currently leased are not rebuilt. Kernel does not store this provider-local setting, so imported browser pools default to false unless configured otherwise.
34-
- `refresh_on_profile_update` (Boolean) Controls whether idle browsers are refreshed when the pool's profile is updated. Requires `profile_id` when true. When omitted, Kernel chooses its profile-dependent default when a profile is attached, changed, or removed; the API value is stored in state and preserved during unrelated updates. Explicit true or false values are sent unchanged.
34+
- `refresh_on_profile_update` (Boolean) Controls whether idle browsers are refreshed when the pool's profile is updated. Requires `profile_id` when true. When omitted, Kernel chooses the applicable default when a profile is attached, changed, or removed; the API value is stored in state and preserved during unrelated updates. Explicit true or false values are sent unchanged.
3535
- `start_url` (String) Optional URL to navigate to when a browser is warmed into the pool.
3636
- `stealth` (Boolean) Launch browsers in stealth mode.
3737
- `timeout_seconds` (Number) Default idle timeout in seconds for acquired browsers.

internal/resources/browserpool/expand_test.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func TestExpandCreateParamsMapsDurableConfigToSDK(t *testing.T) {
1919
Name: types.StringValue("pool-a"),
2020
Size: types.Int64Value(5),
2121
ProfileID: types.StringValue("profile-1"),
22+
RefreshOnProfile: types.BoolValue(false),
2223
ProxyID: types.StringValue("proxy-1"),
2324
ExtensionIDs: stringListForTest("ext-b", "ext-a"),
2425
ChromePolicy: chromePolicyValueForTest(`{"HomepageLocation":"https://example.com"}`),
@@ -38,19 +39,20 @@ func TestExpandCreateParamsMapsDurableConfigToSDK(t *testing.T) {
3839

3940
body := marshalSDKParams(t, params)
4041
want := map[string]any{
41-
"name": "pool-a",
42-
"size": float64(5),
43-
"profile": map[string]any{"id": "profile-1"},
44-
"proxy_id": "proxy-1",
45-
"extensions": []any{map[string]any{"id": "ext-b"}, map[string]any{"id": "ext-a"}},
46-
"chrome_policy": map[string]any{"HomepageLocation": "https://example.com"},
47-
"viewport": map[string]any{"width": float64(1280), "height": float64(800), "refresh_rate": float64(60)},
48-
"headless": true,
49-
"kiosk_mode": true,
50-
"stealth": false,
51-
"start_url": "https://start.example",
52-
"timeout_seconds": float64(90),
53-
"fill_rate_per_minute": float64(20),
42+
"name": "pool-a",
43+
"size": float64(5),
44+
"profile": map[string]any{"id": "profile-1"},
45+
"refresh_on_profile_update": false,
46+
"proxy_id": "proxy-1",
47+
"extensions": []any{map[string]any{"id": "ext-b"}, map[string]any{"id": "ext-a"}},
48+
"chrome_policy": map[string]any{"HomepageLocation": "https://example.com"},
49+
"viewport": map[string]any{"width": float64(1280), "height": float64(800), "refresh_rate": float64(60)},
50+
"headless": true,
51+
"kiosk_mode": true,
52+
"stealth": false,
53+
"start_url": "https://start.example",
54+
"timeout_seconds": float64(90),
55+
"fill_rate_per_minute": float64(20),
5456
}
5557

5658
if !jsonEqual(t, body, want) {
@@ -61,6 +63,7 @@ func TestExpandCreateParamsMapsDurableConfigToSDK(t *testing.T) {
6163
func TestExpandCreateParamsOmitsUnknownServerDefaults(t *testing.T) {
6264
model := browserPoolModel{
6365
Size: types.Int64Value(1),
66+
RefreshOnProfile: types.BoolUnknown(),
6467
Headless: types.BoolUnknown(),
6568
KioskMode: types.BoolUnknown(),
6669
Stealth: types.BoolUnknown(),

internal/resources/browserpool/refresh_on_profile_update_plan_modifier.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var _ planmodifier.Bool = preserveRefreshOnProfileUpdate{}
1313
type preserveRefreshOnProfileUpdate struct{}
1414

1515
func (preserveRefreshOnProfileUpdate) Description(context.Context) string {
16-
return "Preserves refresh_on_profile_update when the planned browser pool still has a profile."
16+
return "Preserves refresh_on_profile_update when profile_id is unchanged."
1717
}
1818

1919
func (m preserveRefreshOnProfileUpdate) MarkdownDescription(ctx context.Context) string {

internal/resources/browserpool/resource_acc_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func TestAccBrowserPoolLifecycle(t *testing.T) {
4141
resource.TestCheckResourceAttr(browserPoolResourceName, "headless", "true"),
4242
resource.TestCheckResourceAttr(browserPoolResourceName, "kiosk_mode", "false"),
4343
resource.TestCheckResourceAttr(browserPoolResourceName, "stealth", "false"),
44+
resource.TestCheckResourceAttr(browserPoolResourceName, "refresh_on_profile_update", "false"),
4445
resource.TestCheckResourceAttr(browserPoolResourceName, "timeout_seconds", "90"),
4546
resource.TestCheckResourceAttr(browserPoolResourceName, "fill_rate_per_minute", "0"),
4647
resource.TestCheckResourceAttr(browserPoolResourceName, "rebuild_idle_browsers_on_update", "true"),
@@ -55,6 +56,7 @@ func TestAccBrowserPoolLifecycle(t *testing.T) {
5556
resource.TestCheckResourceAttr(browserPoolResourceName, "size", "1"),
5657
resource.TestCheckResourceAttr(browserPoolResourceName, "start_url", "https://example.com/two"),
5758
resource.TestCheckResourceAttr(browserPoolResourceName, "stealth", "true"),
59+
resource.TestCheckResourceAttr(browserPoolResourceName, "refresh_on_profile_update", "false"),
5860
resource.TestCheckResourceAttr(browserPoolResourceName, "rebuild_idle_browsers_on_update", "true"),
5961
testAccCheckAcquiredBrowserStealth(t, browserPoolResourceName, true),
6062
),

internal/resources/browserpool/schema.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func BrowserPoolSchema() rschema.Schema {
7272
"refresh_on_profile_update": rschema.BoolAttribute{
7373
Optional: true,
7474
Computed: true,
75-
MarkdownDescription: "Controls whether idle browsers are refreshed when the pool's profile is updated. Requires `profile_id` when true. When omitted, Kernel chooses its profile-dependent default when a profile is attached, changed, or removed; the API value is stored in state and preserved during unrelated updates. Explicit true or false values are sent unchanged.",
75+
MarkdownDescription: "Controls whether idle browsers are refreshed when the pool's profile is updated. Requires `profile_id` when true. When omitted, Kernel chooses the applicable default when a profile is attached, changed, or removed; the API value is stored in state and preserved during unrelated updates. Explicit true or false values are sent unchanged.",
7676
PlanModifiers: []planmodifier.Bool{
7777
preserveRefreshOnProfileUpdate{},
7878
},

internal/resources/browserpool/schema_test.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,20 @@ func TestSchemaRebuildIdleBrowsersOnUpdateDefaultsFalse(t *testing.T) {
152152

153153
func TestSchemaRefreshOnProfileUpdatePreservesStateDuringUnrelatedUpdate(t *testing.T) {
154154
attr := boolAttribute(t, BrowserPoolSchema(), "refresh_on_profile_update")
155-
planned := runRefreshOnProfileUpdatePlanModifiers(t, attr,
156-
types.BoolValue(false), types.BoolUnknown(), types.BoolNull(),
157-
tftypes.NewValue(tftypes.String, "profile-1"), tftypes.NewValue(tftypes.String, "profile-1"))
155+
tests := map[string]tftypes.Value{
156+
"with profile": tftypes.NewValue(tftypes.String, "profile-1"),
157+
"without profile": tftypes.NewValue(tftypes.String, nil),
158+
}
158159

159-
if !planned.Equal(types.BoolValue(false)) {
160-
t.Fatalf("unset refresh_on_profile_update should keep the state value, got %v", planned)
160+
for name, profileID := range tests {
161+
t.Run(name, func(t *testing.T) {
162+
planned := runRefreshOnProfileUpdatePlanModifiers(t, attr,
163+
types.BoolValue(false), types.BoolUnknown(), types.BoolNull(), profileID, profileID)
164+
165+
if !planned.Equal(types.BoolValue(false)) {
166+
t.Fatalf("unset refresh_on_profile_update should keep the state value, got %v", planned)
167+
}
168+
})
161169
}
162170
}
163171

0 commit comments

Comments
 (0)