Merge candidate 20260909T233511Z-core-runtime

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-09-10 00:55:55 +01:00
4 changed files with 84 additions and 5 deletions
+5 -5
View File
@@ -18,7 +18,7 @@ require (
github.com/klauspost/compress v1.19.1
github.com/moby/moby/api v1.56.0
github.com/moby/moby/client v0.6.0
github.com/oklog/ulid/v2 v2.1.1
github.com/oklog/ulid/v2 v2.1.2
github.com/opencontainers/image-spec v1.1.1
github.com/prometheus/client_golang v1.24.1
github.com/prometheus/client_model v0.6.3
@@ -27,11 +27,11 @@ require (
github.com/rs/zerolog v1.35.1
github.com/shirou/gopsutil/v4 v4.26.8
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
github.com/stretchr/testify v1.12.1
github.com/stripe/stripe-go/v82 v82.5.1
golang.org/x/crypto v0.56.0
golang.org/x/oauth2 v0.36.0
golang.org/x/sync v0.22.0
golang.org/x/oauth2 v0.37.0
golang.org/x/sync v0.23.0
golang.org/x/sys v0.48.0
golang.org/x/term v0.45.0
gopkg.in/yaml.v3 v3.0.1
@@ -109,7 +109,7 @@ require (
go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/net v0.57.0 // indirect
golang.org/x/text v0.41.0 // indirect
golang.org/x/time v0.15.0 // indirect
+10
View File
@@ -160,6 +160,8 @@ github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOF
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/oklog/ulid/v2 v2.1.2 h1:IEclFb9JNvzYA6MW2SCxbLzcHTVsfqm3PrqGQJH5zec=
github.com/oklog/ulid/v2 v2.1.2/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
@@ -222,6 +224,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/stripe/stripe-go/v82 v82.5.1 h1:05q6ZDKoe8PLMpQV072obF74HCgP4XJeJYoNuRSX2+8=
github.com/stripe/stripe-go/v82 v82.5.1/go.mod h1:majCQX6AfObAvJiHraPi/5udwHi4ojRvJnnxckvHrX8=
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
@@ -254,6 +258,8 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y=
golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I=
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
@@ -262,9 +268,13 @@ golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98=
golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -4,6 +4,7 @@ import (
"context"
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"io"
"net/http"
@@ -510,3 +511,48 @@ func TestGenerateRandomURLString_ErrorSize(t *testing.T) {
t.Fatalf("expected no error for size 0, got %v", err)
}
}
// TestOIDCRefreshDependencyContract exercises the real OAuth transport through
// Pulse's adapter, including providers that do not rotate refresh tokens.
func TestOIDCRefreshDependencyContract(t *testing.T) {
for _, rotate := range []bool{false, true} {
t.Run(fmt.Sprint("rotate=", rotate), func(t *testing.T) {
server := newIPv4HTTPServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
t.Error(err)
w.WriteHeader(400)
return
}
if r.Form.Get("grant_type") != "refresh_token" || r.Form.Get("refresh_token") != "old-refresh" {
t.Error("refresh request lost grant or token")
w.WriteHeader(400)
return
}
w.Header().Set("Content-Type", "application/json")
extra := ""
if rotate {
extra = `,"refresh_token":"rotated"`
}
fmt.Fprintf(w, `{"access_token":"access","token_type":"Bearer","expires_in":3600%s}`, extra)
}))
defer server.Close()
svc := &OIDCService{oauth2Cfg: &oauth2.Config{ClientID: "client", Endpoint: oauth2.Endpoint{TokenURL: server.URL}}, httpClient: server.Client()}
result, err := svc.RefreshToken(context.Background(), "old-refresh")
if err != nil {
t.Fatal(err)
}
want := "old-refresh"
if rotate {
want = "rotated"
}
if result.RefreshToken != want || result.AccessToken != "access" || !result.Expiry.After(time.Now()) {
t.Fatal("refresh response was not preserved")
}
ctx, cancel := context.WithCancel(context.Background())
cancel()
if _, err := svc.RefreshToken(ctx, "old-refresh"); !errors.Is(err, context.Canceled) {
t.Fatalf("cancelled refresh error = %v", err)
}
})
}
}
+23
View File
@@ -7,6 +7,9 @@ import (
"path/filepath"
"testing"
"time"
"github.com/oklog/ulid/v2"
"github.com/stretchr/testify/require"
)
func TestNewUpdateHistory(t *testing.T) {
@@ -865,3 +868,23 @@ func contains(s, substr string) bool {
}
return false
}
// TestUpdateHistoryIDDependencyContract protects persisted ID encoding and
// uniqueness rather than only checking that the generated string is nonempty.
func TestUpdateHistoryIDDependencyContract(t *testing.T) {
h, err := NewUpdateHistory(t.TempDir())
require.NoError(t, err)
seen := make(map[string]bool)
for range 64 {
id, err := h.CreateEntry(context.Background(), UpdateHistoryEntry{Action: "update", Status: StatusInProgress})
require.NoError(t, err)
parsed, err := ulid.ParseStrict(id)
require.NoError(t, err)
require.Equal(t, id, parsed.String())
require.False(t, seen[id], "duplicate history ID")
seen[id] = true
entry, err := h.GetEntry(id)
require.NoError(t, err)
require.Equal(t, id, entry.EventID)
}
}