Files
traefikoidc/id_token_memo_test.go
T
lukaszraczyloandGitHub 94a8664403 perf(session): cut yaegi allocations on authenticated requests (#164)
Under yaegi, the authenticated cookie path allocated about 3.8 MB per
request. A yaegi harness measures bytes per request with a browser-like
cookie jar. With it, these changes cut bytes by 83%, allocations by 69%
and time by about 93%.

- Replace range loops over tokens with index loops. Under yaegi, ranging
  over a string allocates O(n^2) bytes.
- Pool gzip readers for combined session cookies.
- Memoize the validated ID token within one request.
- Cache content-only token validation across requests. The key is the
  token type and SHA-256, and the cache holds at most 4096 entries. The
  entry keeps the parsed exp and iat claims. The expiry and freshness
  checks still run on every request.

New tests pin the validator results, the memo and the cache behavior.
2026-09-29 11:59:31 +01:00

51 lines
1.6 KiB
Go

package traefikoidc
import (
"net/http/httptest"
"testing"
"time"
)
func TestIDTokenMemoFollowsStoredToken(t *testing.T) {
sm, err := NewSessionManager("0123456789abcdef0123456789abcdef", false, "", "", time.Hour, NewLogger("error"))
if err != nil {
t.Fatalf("NewSessionManager: %v", err)
}
t.Cleanup(func() {
if err := sm.Shutdown(); err != nil {
t.Errorf("Shutdown: %v", err)
}
})
future := float64(time.Now().Add(time.Hour).Unix())
first := tokenWithGroups(t, map[string]interface{}{"sub": "first", "exp": future})
second := tokenWithGroups(t, map[string]interface{}{"sub": "second", "exp": future})
session, err := sm.GetSession(httptest.NewRequest("GET", "/", nil))
if err != nil {
t.Fatalf("GetSession: %v", err)
}
steps := []struct {
name string
write func()
want string
}{
{"first read", func() { session.SetIDToken(first) }, first},
{"repeat read", func() {}, first},
{"after overwrite", func() { session.SetIDToken(second) }, second},
{"after clearing", func() { session.SetIDToken("") }, ""},
{"after Reset", func() { session.SetIDToken(first); _ = session.GetIDToken(); session.Reset() }, ""},
}
for _, st := range steps {
st.write()
if got := session.GetIDToken(); got != st.want {
t.Fatalf("%s: GetIDToken = %q, want %q", st.name, got, st.want)
}
if st.name == "repeat read" && session.idTokenMemoRaw != first {
t.Fatal("repeat read did not go through the memo; the test no longer covers it")
}
}
if session.idTokenMemoRaw != "" || session.idTokenMemo != "" {
t.Fatal("Reset left an ID-token memo on the pooled session")
}
}