Skip to content

Commit 020c9c9

Browse files
committed
fix(barbican): propagate context cancellation and fix data race in tests
- doRequestWithRetry now checks ctx.Err() before wrapping the final error, so callers see a context cancellation instead of a generic 'maximum retry attempts' API error. - TestEncryptMultiRegion guards shared secretStores/secretCounters maps with a sync.Mutex to eliminate the data race detected by -race.
1 parent 11b494b commit 020c9c9

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

barbican/client.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,12 @@ func (c *BarbicanClient) doRequestWithRetry(ctx context.Context, method, path st
686686
log.WithError(err).WithField("attempt", attempt+1).Debug("Retryable error occurred")
687687
}
688688

689+
// If the context was cancelled or timed out, surface that directly
690+
// so callers can distinguish cancellation from server-side failures.
691+
if ctx.Err() != nil {
692+
return NewTimeoutError("Request cancelled by context", ctx.Err())
693+
}
694+
689695
return NewAPIError("Request failed after maximum retry attempts", 0).
690696
WithCause(lastErr).
691697
WithDetails(fmt.Sprintf("Failed after %d attempts", c.config.MaxRetries+1))

barbican/keysource_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"net/http"
1111
"net/http/httptest"
1212
"strings"
13+
"sync"
1314
"sync/atomic"
1415
"testing"
1516
"testing/quick"
@@ -843,17 +844,22 @@ func TestEncryptMultiRegion(t *testing.T) {
843844
// Create mock servers for different regions
844845
secretStores := make(map[string]map[string][]byte) // region -> secretUUID -> payload
845846
secretCounters := make(map[string]int) // region -> counter
847+
var mu sync.Mutex // protects secretStores and secretCounters
846848

847849
createMockServer := func(region string) *httptest.Server {
850+
mu.Lock()
848851
secretStores[region] = make(map[string][]byte)
849852
secretCounters[region] = 0
853+
mu.Unlock()
850854

851855
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
852856
switch r.Method {
853857
case "POST":
854858
if strings.HasSuffix(r.URL.Path, "/secrets") {
859+
mu.Lock()
855860
secretCounters[region]++
856861
secretUUID := fmt.Sprintf("550e8400-e29b-41d4-a716-%012d", secretCounters[region])
862+
mu.Unlock()
857863
secretRef := fmt.Sprintf("https://barbican-%s.example.com:9311/v1/secrets/%s", region, secretUUID)
858864

859865
body, err := io.ReadAll(r.Body)
@@ -874,7 +880,9 @@ func TestEncryptMultiRegion(t *testing.T) {
874880
return
875881
}
876882

883+
mu.Lock()
877884
secretStores[region][secretUUID] = payload
885+
mu.Unlock()
878886

879887
w.Header().Set("Content-Type", "application/json")
880888
w.WriteHeader(http.StatusCreated)

0 commit comments

Comments
 (0)