Files
77d1810bb9 feat: add metadata enforcement (#1990)
* 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>
2026-07-02 13:42:08 +02:00

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")
}
}