284 lines
7.7 KiB
Go
284 lines
7.7 KiB
Go
package crdexplorer
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
|
|
|
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
|
|
)
|
|
|
|
func strPtr(s string) *string { return &s }
|
|
|
|
func int32Ptr(i int32) *int32 { return &i }
|
|
|
|
func TestHasWildcardOperation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
operations []configv1alpha1.OperationType
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "no operations",
|
|
operations: nil,
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "has wildcard operation",
|
|
operations: []configv1alpha1.OperationType{
|
|
configv1alpha1.OperationAll,
|
|
},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "no have wildcard operation",
|
|
operations: []configv1alpha1.OperationType{
|
|
configv1alpha1.ExploreReplica,
|
|
},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
result := hasWildcardOperation(test.operations)
|
|
if result != test.expected {
|
|
t.Errorf("Case: %s failed: expected get %v, but got %v", test.name, test.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsAcceptedExploreReviewVersions(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
version string
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "is accepted explore review versions",
|
|
version: acceptedExploreReviewVersions[0],
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "is not accepted explore review versions",
|
|
version: "",
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
result := isAcceptedExploreReviewVersions(test.version)
|
|
if result != test.expected {
|
|
t.Errorf("Case: %s failed: expected get %v, but got %v", test.name, test.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateRuleWithOperations(t *testing.T) {
|
|
fldPath := field.NewPath("webhooks").Child("rules")
|
|
notSupportedOperation := []configv1alpha1.OperationType{(configv1alpha1.OperationType)("notsupported")}
|
|
|
|
tests := []struct {
|
|
name string
|
|
ruleWithOperations *configv1alpha1.RuleWithOperations
|
|
expectedError string
|
|
}{
|
|
{
|
|
name: "no operations",
|
|
ruleWithOperations: &configv1alpha1.RuleWithOperations{},
|
|
expectedError: "operations: Required value",
|
|
},
|
|
{
|
|
name: "2 operations with wildcard",
|
|
ruleWithOperations: &configv1alpha1.RuleWithOperations{
|
|
Operations: []configv1alpha1.OperationType{
|
|
configv1alpha1.OperationAll,
|
|
configv1alpha1.ExploreReplica,
|
|
},
|
|
},
|
|
expectedError: "if '*' is present, must not specify other operations",
|
|
},
|
|
{
|
|
name: "not supported operations",
|
|
ruleWithOperations: &configv1alpha1.RuleWithOperations{Operations: notSupportedOperation},
|
|
expectedError: "operations[0]: Unsupported value",
|
|
},
|
|
{
|
|
name: "not validated rule",
|
|
ruleWithOperations: &configv1alpha1.RuleWithOperations{
|
|
Operations: []configv1alpha1.OperationType{
|
|
configv1alpha1.OperationAll,
|
|
},
|
|
Rule: configv1alpha1.Rule{
|
|
APIGroups: []string{""},
|
|
}},
|
|
expectedError: "apiVersions: Required value",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
errs := validateRuleWithOperations(test.ruleWithOperations, fldPath)
|
|
err := errs.ToAggregate()
|
|
if err != nil {
|
|
if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
|
|
t.Errorf("Case: %s failed: expected to contain %s, got %s", test.name, e, a)
|
|
}
|
|
} else {
|
|
if test.expectedError != "" {
|
|
t.Errorf("Case: %s failed: unexpected no error, expected to contain %s", test.name, test.expectedError)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateExploreReviewVersions(t *testing.T) {
|
|
fldPath := field.NewPath("webhooks").Child("exploreReviewVersions")
|
|
|
|
tests := []struct {
|
|
name string
|
|
versions []string
|
|
expectedError string
|
|
}{
|
|
{
|
|
name: "no versions",
|
|
versions: nil,
|
|
expectedError: fmt.Sprintf("must specify one of %v", strings.Join(acceptedExploreReviewVersions, ", ")),
|
|
},
|
|
{
|
|
name: "duplicate versions",
|
|
versions: []string{"v1", "v1"},
|
|
expectedError: "duplicate version",
|
|
},
|
|
{
|
|
name: "invalid versions",
|
|
versions: []string{"test", "test"},
|
|
expectedError: fmt.Sprintf("must include at least one of %v", strings.Join(acceptedExploreReviewVersions, ", ")),
|
|
},
|
|
{
|
|
name: "invalid DNS (RFC 1035) label",
|
|
versions: []string{"a b"},
|
|
expectedError: "a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
errs := validateExploreReviewVersions(test.versions, fldPath)
|
|
err := errs.ToAggregate()
|
|
if err != nil {
|
|
if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
|
|
t.Errorf("Case: %s failed: expected to contain %s, got %s", test.name, e, a)
|
|
}
|
|
} else {
|
|
if test.expectedError != "" {
|
|
t.Errorf("Case: %s failed: unexpected no error, expected to contain %s", test.name, test.expectedError)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateWebhook(t *testing.T) {
|
|
fldPath := field.NewPath("webhooks")
|
|
policy := admissionregistrationv1.FailurePolicyType("fake policy")
|
|
|
|
tests := []struct {
|
|
name string
|
|
hook *configv1alpha1.ResourceExploringWebhook
|
|
expectedError string
|
|
}{
|
|
{
|
|
name: "not qualified domain name",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
Name: "",
|
|
},
|
|
expectedError: "webhooks.name: Required value",
|
|
},
|
|
{
|
|
name: "invalid rules",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
Rules: []configv1alpha1.RuleWithOperations{
|
|
{
|
|
Operations: []configv1alpha1.OperationType{},
|
|
},
|
|
},
|
|
},
|
|
expectedError: "operations: Required value",
|
|
},
|
|
{
|
|
name: "invalid policy",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
FailurePolicy: &policy,
|
|
},
|
|
expectedError: "matchPolicy",
|
|
},
|
|
{
|
|
name: "invalid timeout",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
TimeoutSeconds: int32Ptr(60),
|
|
},
|
|
expectedError: "the timeout value must be between 1 and 30 seconds",
|
|
},
|
|
{
|
|
name: "ClientConfig: exactly one of url or service is required",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
ClientConfig: admissionregistrationv1.WebhookClientConfig{},
|
|
},
|
|
expectedError: "exactly one of url or service is required",
|
|
},
|
|
{
|
|
name: "ClientConfig: invalid URL",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
ClientConfig: admissionregistrationv1.WebhookClientConfig{
|
|
URL: strPtr(""),
|
|
},
|
|
},
|
|
expectedError: "host must be provided",
|
|
},
|
|
{
|
|
name: "ClientConfig: invalid service",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
ClientConfig: admissionregistrationv1.WebhookClientConfig{
|
|
Service: &admissionregistrationv1.ServiceReference{
|
|
Name: "",
|
|
Port: int32Ptr(8080),
|
|
Path: strPtr(""),
|
|
},
|
|
},
|
|
},
|
|
expectedError: "service name is required",
|
|
},
|
|
{
|
|
name: "invalid explore review versions",
|
|
hook: &configv1alpha1.ResourceExploringWebhook{
|
|
ExploreReviewVersions: []string{""},
|
|
},
|
|
expectedError: fmt.Sprintf("must include at least one of %v", strings.Join(acceptedExploreReviewVersions, ", ")),
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
errs := validateWebhook(test.hook, fldPath)
|
|
err := errs.ToAggregate()
|
|
if err != nil {
|
|
if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
|
|
t.Errorf("Case: %s failed: expected to contain %s, got %s", test.name, e, a)
|
|
}
|
|
} else {
|
|
if test.expectedError != "" {
|
|
t.Errorf("Case: %s failed: unexpected no error, expected to contain %s", test.name, test.expectedError)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|