Skip to content

Commit be61d3d

Browse files
committed
fix(grafana): stabilize org preferences acc test (401 after new org)
- Poll GET /org/preferences until OK before PUT on create (up to 4m, 401 retry) - Tune PUT retries (30 x 5s) - Run TestAccResourceOrganizationPreferences serially (resource.Test) CI: 11.6.13 oss-other failed Step 2 with PUT 401 Unauthorized.
1 parent 8de88d8 commit be61d3d

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

internal/resources/grafana/resource_organization_preferences.go

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,13 @@ func (v weekStartValidator) ValidateString(ctx context.Context, req validator.St
7979
}
8080

8181
// Grafana may return 401 briefly after creating a new org until the creating user's membership is propagated.
82-
// We use an initial delay on Create and retry on 401.
83-
const orgPrefsRetryAttempts = 25
84-
const orgPrefsRetryDelay = 6 * time.Second
82+
// We poll GET until it succeeds, then PUT with 401 retries (CI: parallel acc tests + new orgs).
83+
const (
84+
orgPrefsReadinessTimeout = 4 * time.Minute
85+
orgPrefsReadinessPoll = 2 * time.Second
86+
orgPrefsRetryAttempts = 30
87+
orgPrefsRetryDelay = 5 * time.Second
88+
)
8589

8690
func isRetryableOrgPrefs401(err error) bool {
8791
if err == nil {
@@ -96,8 +100,29 @@ func isRetryableOrgPrefs401(err error) bool {
96100
return strings.Contains(errStr, "401") || strings.Contains(errStr, "Unauthorized")
97101
}
98102

103+
// waitForOrgPreferencesReadable polls GET /org/preferences until it succeeds or a non-retryable error occurs.
104+
func waitForOrgPreferencesReadable(ctx context.Context, client *goapi.GrafanaHTTPAPI) error {
105+
deadline := time.Now().Add(orgPrefsReadinessTimeout)
106+
var lastErr error
107+
for time.Now().Before(deadline) {
108+
_, err := client.OrgPreferences.GetOrgPreferences()
109+
if err == nil {
110+
return nil
111+
}
112+
lastErr = err
113+
if !isRetryableOrgPrefs401(err) {
114+
return err
115+
}
116+
select {
117+
case <-ctx.Done():
118+
return ctx.Err()
119+
case <-time.After(orgPrefsReadinessPoll):
120+
}
121+
}
122+
return lastErr
123+
}
124+
99125
// updateOrgPreferencesWithRetryWithDelay calls UpdateOrgPreferences with optional initial delay and retries on 401.
100-
// initialDelay is used on Create to give new orgs time for membership to propagate before the first attempt.
101126
func updateOrgPreferencesWithRetryWithDelay(ctx context.Context, client *goapi.GrafanaHTTPAPI, body *models.UpdatePrefsCmd, initialDelay time.Duration) error {
102127
if initialDelay > 0 {
103128
select {
@@ -185,13 +210,16 @@ func (r *organizationPreferencesResource) Create(ctx context.Context, req resour
185210
timezone := data.Timezone.ValueString()
186211
weekStart := data.WeekStart.ValueString()
187212

188-
// Initial delay for new orgs so Grafana can propagate membership before first API call.
213+
if err := waitForOrgPreferencesReadable(ctx, client); err != nil {
214+
resp.Diagnostics.AddError("Organization is not ready to update preferences yet", err.Error())
215+
return
216+
}
189217
err = updateOrgPreferencesWithRetryWithDelay(ctx, client, &models.UpdatePrefsCmd{
190218
Theme: theme,
191219
HomeDashboardUID: homeDashboardUID,
192220
Timezone: timezone,
193221
WeekStart: weekStart,
194-
}, 15*time.Second)
222+
}, 0)
195223
if err != nil {
196224
resp.Diagnostics.AddError("Failed to update organization preferences", err.Error())
197225
return

internal/resources/grafana/resource_organization_preferences_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ func TestAccResourceOrganizationPreferences(t *testing.T) {
8080

8181
testRandName := acctest.RandString(10)
8282

83-
resource.ParallelTest(t, resource.TestCase{
83+
// Serial: avoids 401 on PUT /org/preferences when other acc tests run with -parallel >1 against the same Grafana.
84+
resource.Test(t, resource.TestCase{
8485
ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
8586
CheckDestroy: orgCheckExists.destroyed(&org, nil),
8687
Steps: []resource.TestStep{

0 commit comments

Comments
 (0)