Files
capsule/pkg/utils/hashes_test.go
Oliver Bähler a6b830b1af feat: add ruleset api(#1844)
* 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(config): remove usergroups default

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* fix(config): remove usergroups default

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* sec(ghsa-2ww6-hf35-mfjm): intercept namespace subresource

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(api): add rulestatus api

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* chore: conflicts

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(api): add rulestatus api

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(api): add rulestatus api

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(api): add rulestatus api

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(api): add rulestatus api

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(api): add rulestatus api

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

* feat(api): add rulestatus api

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>

---------

Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
2026-01-27 14:28:48 +01:00

126 lines
3.2 KiB
Go

// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0
package utils_test
import (
"testing"
rbacv1 "k8s.io/api/rbac/v1"
"github.com/projectcapsule/capsule/pkg/api"
"github.com/projectcapsule/capsule/pkg/utils"
)
func TestRoleBindingHashFunc_Deterministic(t *testing.T) {
b := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{
{Kind: "User", Name: "alice"},
{Kind: "Group", Name: "devops"},
},
}
h1 := utils.RoleBindingHashFunc(b)
h2 := utils.RoleBindingHashFunc(b)
if h1 != h2 {
t.Fatalf("expected deterministic hash, got %q and %q", h1, h2)
}
if h1 == "" {
t.Fatalf("expected non-empty hash")
}
}
func TestRoleBindingHashFunc_ChangesWhenClusterRoleChanges(t *testing.T) {
b1 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
}
b2 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "view",
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
}
h1 := utils.RoleBindingHashFunc(b1)
h2 := utils.RoleBindingHashFunc(b2)
if h1 == h2 {
t.Fatalf("expected different hashes when ClusterRoleName changes, got %q", h1)
}
}
func TestRoleBindingHashFunc_ChangesWhenSubjectKindChanges(t *testing.T) {
b1 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
}
b2 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{{Kind: "Group", Name: "alice"}},
}
h1 := utils.RoleBindingHashFunc(b1)
h2 := utils.RoleBindingHashFunc(b2)
if h1 == h2 {
t.Fatalf("expected different hashes when subject Kind changes, got %q", h1)
}
}
func TestRoleBindingHashFunc_ChangesWhenSubjectNameChanges(t *testing.T) {
b1 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{{Kind: "User", Name: "alice"}},
}
b2 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{{Kind: "User", Name: "bob"}},
}
h1 := utils.RoleBindingHashFunc(b1)
h2 := utils.RoleBindingHashFunc(b2)
if h1 == h2 {
t.Fatalf("expected different hashes when subject Name changes, got %q", h1)
}
}
func TestRoleBindingHashFunc_EmptyInputsStillProduceHash(t *testing.T) {
b := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "",
Subjects: nil,
}
h := utils.RoleBindingHashFunc(b)
if h == "" {
t.Fatalf("expected non-empty hash even for empty input")
}
}
func TestRoleBindingHashFunc_SubjectOrderMatters_CurrentBehavior(t *testing.T) {
// This test documents the CURRENT behavior:
// the hash is order-dependent because subjects are written in slice order.
b1 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{
{Kind: "User", Name: "alice"},
{Kind: "Group", Name: "devops"},
},
}
b2 := api.AdditionalRoleBindingsSpec{
ClusterRoleName: "admin",
Subjects: []rbacv1.Subject{
{Kind: "Group", Name: "devops"},
{Kind: "User", Name: "alice"},
},
}
h1 := utils.RoleBindingHashFunc(b1)
h2 := utils.RoleBindingHashFunc(b2)
if h1 == h2 {
t.Fatalf("expected different hashes when subject order changes (current behavior), got %q", h1)
}
}