mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-08-19 04:26:45 +00:00
* fix(controller): decode old object for delete requests Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * chore: modernize golang Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * chore: modernize golang Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * chore: modernize golang Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * fix: preserve ca-bundles injected from external providers Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat: add metadata enforcement Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * feat: add metadata enforcement Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * fix: add resourcepoolclaim validation Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * fix: add resourcepoolclaim validation Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * fix: add resourcepoolclaim validation Signed-off-by: Oliver Baehler <oliver@sudo-i.net> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: add resourcepoolclaim validation Signed-off-by: Oliver Baehler <oliver@sudo-i.net> --------- Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> Signed-off-by: Oliver Baehler <oliver@sudo-i.net> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
300 lines
6.5 KiB
Go
300 lines
6.5 KiB
Go
// Copyright 2020-2026 Project Capsule Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package cache
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/projectcapsule/capsule/pkg/api/runtime"
|
|
)
|
|
|
|
func TestCompiledRegexMatchString(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
expression runtime.ExpressionRegex
|
|
value string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "normal expression matches matching value",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: "trusted/.*",
|
|
},
|
|
value: "trusted/team/app:1",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "normal expression does not match non matching value",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: "trusted/.*",
|
|
},
|
|
value: "docker.io/team/app:1",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "negated expression does not match matching value",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: "trusted/.*",
|
|
Negate: true,
|
|
},
|
|
value: "trusted/team/app:1",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "negated expression matches non matching value",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: "trusted/.*",
|
|
Negate: true,
|
|
},
|
|
value: "docker.io/team/app:1",
|
|
want: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cache := NewRegexCache()
|
|
|
|
compiled, _, err := cache.GetOrCompile(tt.expression)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if got := compiled.MatchString(tt.value); got != tt.want {
|
|
t.Fatalf("MatchString() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRegexCache_GetOrCompile(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
expression runtime.ExpressionRegex
|
|
value string
|
|
wantMatch bool
|
|
wantErr bool
|
|
wantCached bool
|
|
wantEntries int
|
|
}{
|
|
{
|
|
name: "compile matching regex",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/projectcapsule/.*`,
|
|
},
|
|
value: "ghcr.io/projectcapsule/capsule:latest",
|
|
wantMatch: true,
|
|
wantErr: false,
|
|
wantCached: false,
|
|
wantEntries: 1,
|
|
},
|
|
{
|
|
name: "compile non matching regex",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/projectcapsule/.*`,
|
|
},
|
|
value: "docker.io/library/nginx:latest",
|
|
wantMatch: false,
|
|
wantErr: false,
|
|
wantCached: false,
|
|
wantEntries: 1,
|
|
},
|
|
{
|
|
name: "compile negated matching regex",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/projectcapsule/.*`,
|
|
Negate: true,
|
|
},
|
|
value: "ghcr.io/projectcapsule/capsule:latest",
|
|
wantMatch: false,
|
|
wantErr: false,
|
|
wantCached: false,
|
|
wantEntries: 1,
|
|
},
|
|
{
|
|
name: "compile negated non matching regex",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/projectcapsule/.*`,
|
|
Negate: true,
|
|
},
|
|
value: "docker.io/library/nginx:latest",
|
|
wantMatch: true,
|
|
wantErr: false,
|
|
wantCached: false,
|
|
wantEntries: 1,
|
|
},
|
|
{
|
|
name: "reject empty expression",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: "",
|
|
},
|
|
value: "ghcr.io/projectcapsule/capsule:latest",
|
|
wantErr: true,
|
|
wantEntries: 0,
|
|
},
|
|
{
|
|
name: "reject invalid regex",
|
|
expression: runtime.ExpressionRegex{
|
|
Expression: `[`,
|
|
},
|
|
value: "ghcr.io/projectcapsule/capsule:latest",
|
|
wantErr: true,
|
|
wantEntries: 0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
c := NewRegexCache()
|
|
|
|
compiled, fromCache, err := c.GetOrCompile(tt.expression)
|
|
if tt.wantErr {
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
|
|
if compiled != nil {
|
|
t.Fatalf("expected nil compiled regex on error, got %#v", compiled)
|
|
}
|
|
|
|
if got := c.Stats(); got != tt.wantEntries {
|
|
t.Fatalf("expected %d cache entries, got %d", tt.wantEntries, got)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if compiled == nil {
|
|
t.Fatal("expected compiled regex, got nil")
|
|
}
|
|
|
|
if fromCache != tt.wantCached {
|
|
t.Fatalf("expected fromCache=%t, got %t", tt.wantCached, fromCache)
|
|
}
|
|
|
|
if got := compiled.MatchString(tt.value); got != tt.wantMatch {
|
|
t.Fatalf("expected match=%t, got %t", tt.wantMatch, got)
|
|
}
|
|
|
|
if got := c.Stats(); got != tt.wantEntries {
|
|
t.Fatalf("expected %d cache entries, got %d", tt.wantEntries, got)
|
|
}
|
|
|
|
if !c.Has(compiled.ID) {
|
|
t.Fatalf("expected cache to contain regex id %q", compiled.ID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRegexCache_GetOrCompile_ReusesCachedRegex(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
c := NewRegexCache()
|
|
|
|
expr := runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/projectcapsule/.*`,
|
|
}
|
|
|
|
first, fromCache, err := c.GetOrCompile(expr)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if fromCache {
|
|
t.Fatal("expected first lookup to build regex, got cache hit")
|
|
}
|
|
|
|
second, fromCache, err := c.GetOrCompile(expr)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if !fromCache {
|
|
t.Fatal("expected second lookup to hit cache")
|
|
}
|
|
|
|
if first != second {
|
|
t.Fatal("expected cached regex pointer to be reused")
|
|
}
|
|
|
|
if got := c.Stats(); got != 1 {
|
|
t.Fatalf("expected 1 cache entry, got %d", got)
|
|
}
|
|
}
|
|
|
|
func TestRegexCache_HashRegex_UsesNegate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
positive := HashRegex(runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/.*`,
|
|
})
|
|
|
|
negative := HashRegex(runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/.*`,
|
|
Negate: true,
|
|
})
|
|
|
|
if positive == negative {
|
|
t.Fatal("expected different hashes for negated and non-negated expressions")
|
|
}
|
|
}
|
|
|
|
func TestRegexCache_Reset(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
c := NewRegexCache()
|
|
|
|
compiled, _, err := c.GetOrCompile(runtime.ExpressionRegex{
|
|
Expression: `^ghcr\.io/.*`,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if got := c.Stats(); got != 1 {
|
|
t.Fatalf("expected 1 cache entry, got %d", got)
|
|
}
|
|
|
|
c.Reset()
|
|
|
|
if got := c.Stats(); got != 0 {
|
|
t.Fatalf("expected 0 cache entries after reset, got %d", got)
|
|
}
|
|
|
|
if c.Has(compiled.ID) {
|
|
t.Fatalf("expected regex id %q to be removed after reset", compiled.ID)
|
|
}
|
|
}
|
|
|
|
func TestCompiledRegex_MatchString_NilSafe(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var compiled *CompiledRegex
|
|
|
|
if compiled.MatchString("ghcr.io/projectcapsule/capsule:latest") {
|
|
t.Fatal("expected nil compiled regex to return false")
|
|
}
|
|
|
|
compiled = &CompiledRegex{}
|
|
|
|
if compiled.MatchString("ghcr.io/projectcapsule/capsule:latest") {
|
|
t.Fatal("expected compiled regex with nil RE to return false")
|
|
}
|
|
}
|