Skip to content

Commit

Permalink
operator/pkg: test apiservice
Browse files Browse the repository at this point in the history
Signed-off-by: Mohamed Awnallah <[email protected]>
  • Loading branch information
mohamedawnallah committed Sep 23, 2024
1 parent 4c8bcd4 commit 239e2c1
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 5 deletions.
8 changes: 4 additions & 4 deletions operator/pkg/karmadaresource/apiservice/apiservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ func init() {
}

// EnsureAggregatedAPIService creates aggregated APIService and a service
func EnsureAggregatedAPIService(aggregatorClient *aggregator.Clientset, client clientset.Interface, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, hostClusterServiceName, hostClusterNamespace, caBundle string) error {
func EnsureAggregatedAPIService(aggregatorClient aggregator.Interface, client clientset.Interface, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, hostClusterServiceName, hostClusterNamespace, caBundle string) error {
if err := aggregatedApiserverService(client, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, hostClusterServiceName, hostClusterNamespace); err != nil {
return err
}

return aggregatedAPIService(aggregatorClient, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, caBundle)
}

func aggregatedAPIService(client *aggregator.Clientset, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, caBundle string) error {
func aggregatedAPIService(client aggregator.Interface, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, caBundle string) error {
apiServiceBytes, err := util.ParseTemplate(KarmadaAggregatedAPIService, struct {
Namespace string
ServiceName string
Expand Down Expand Up @@ -101,15 +101,15 @@ func aggregatedApiserverService(client clientset.Interface, karmadaControlPlaneS
}

// EnsureMetricsAdapterAPIService creates APIService and a service for karmada-metrics-adapter
func EnsureMetricsAdapterAPIService(aggregatorClient *aggregator.Clientset, client clientset.Interface, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, hostClusterServiceName, hostClusterNamespace, caBundle string) error {
func EnsureMetricsAdapterAPIService(aggregatorClient aggregator.Interface, client clientset.Interface, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, hostClusterServiceName, hostClusterNamespace, caBundle string) error {
if err := karmadaMetricsAdapterService(client, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, hostClusterServiceName, hostClusterNamespace); err != nil {
return err
}

return karmadaMetricsAdapterAPIService(aggregatorClient, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, caBundle)
}

func karmadaMetricsAdapterAPIService(client *aggregator.Clientset, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, caBundle string) error {
func karmadaMetricsAdapterAPIService(client aggregator.Interface, karmadaControlPlaneServiceName, karmadaControlPlaneNamespace, caBundle string) error {
for _, gv := range constants.KarmadaMetricsAdapterAPIServices {
// The APIService name to metrics adapter is "$version.$group"
apiServiceName := fmt.Sprintf("%s.%s", gv.Version, gv.Group)
Expand Down
188 changes: 188 additions & 0 deletions operator/pkg/karmadaresource/apiservice/apiservice_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
Copyright 2024 The Karmada Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package apiservice

import (
"encoding/base64"
"fmt"
"testing"

"github.com/karmada-io/karmada/operator/pkg/util"
corev1 "k8s.io/api/core/v1"
fakeclientset "k8s.io/client-go/kubernetes/fake"
coretesting "k8s.io/client-go/testing"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
fakeAggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake"

Check failure on line 29 in operator/pkg/karmadaresource/apiservice/apiservice_test.go

View workflow job for this annotation

GitHub Actions / unit test

cannot find module providing package k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake: import lookup disabled by -mod=vendor

Check failure on line 29 in operator/pkg/karmadaresource/apiservice/apiservice_test.go

View workflow job for this annotation

GitHub Actions / unit test

cannot find module providing package k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake: import lookup disabled by -mod=vendor
)

func TestEnsureAggregatedAPIService(t *testing.T) {
name, namespace := "karmada-demo", "test"

// Base64 encoding of the dummy certificate data.
caTestData := "test-ca-data"
caBundle := base64.StdEncoding.EncodeToString([]byte(caTestData))

fakeAggregatorClient := fakeAggregator.NewSimpleClientset()
fakeClient := fakeclientset.NewSimpleClientset()
err := EnsureAggregatedAPIService(
fakeAggregatorClient, fakeClient, name, namespace, name, namespace, caBundle,
)
if err != nil {
t.Fatalf("failed to ensure aggregated api service: %v", err)
}

// Ensure the expected action (aggregated apiserver service creation) occurred on the fake clientset.
actions := fakeClient.Actions()
if len(actions) != 1 {
t.Fatalf("expected 1 action, but got %d", len(actions))
}

// Ensure the expected action (aggregated api service creation) occurred on the fake aggregator clientset.
actions = fakeAggregatorClient.Actions()
if len(actions) != 1 {
t.Fatalf("expected 1 action, but got %d", len(actions))
}
}

func TestAggregatedAPIService(t *testing.T) {
name, namespace := "karmada-demo", "test"

// Base64 encoding of the dummy certificate data.
caTestData := "test-ca-data"
caBundle := base64.StdEncoding.EncodeToString([]byte(caTestData))

fakeClient := fakeAggregator.NewSimpleClientset()
err := aggregatedAPIService(fakeClient, name, namespace, caBundle)
if err != nil {
t.Fatalf("failed to create aggregated api service: %v", err)
}

// Ensure the expected action (service creation) occurred.
actions := fakeClient.Actions()
if len(actions) != 1 {
t.Fatalf("expected 1 action, but got %d", len(actions))
}

// Validate the action is a CreateAction and it's for the correct resource (apiregistrationv1.APIService).
createAction, ok := actions[0].(coretesting.CreateAction)
if !ok {
t.Fatalf("expected CreateAction, but got %T", actions[0])
}

if createAction.GetResource().Resource != "apiservices" {
t.Fatalf("expected action on 'apiservices', but got '%s'", createAction.GetResource().Resource)
}

// Validate the created apiregistrationv1.APIService object.
service := createAction.GetObject().(*apiregistrationv1.APIService)
expectedServiceName := util.KarmadaAggregatedAPIServerName(name)
if service.Spec.Service.Name != expectedServiceName {
t.Fatalf("expected service name '%s', but got '%s'", expectedServiceName, service.Name)
}

if service.Spec.Service.Namespace != namespace {
t.Fatalf("expected service namespace '%s', but got '%s'", namespace, service.Namespace)
}

if string(service.Spec.CABundle) != caTestData {
t.Fatalf("expected service caBundle %s, but got %s", caTestData, string(service.Spec.CABundle))
}
}

func TestAggregatedAPIServerService(t *testing.T) {
name, namespace := "karmada-demo", "test"

fakeClient := fakeclientset.NewSimpleClientset()
err := aggregatedApiserverService(fakeClient, name, namespace, name, namespace)
if err != nil {
t.Fatalf("failed to create aggregated apiserver service: %v", err)
}

// Ensure the expected action (service creation) occurred.
actions := fakeClient.Actions()
if len(actions) != 1 {
t.Fatalf("expected 1 action, but got %d", len(actions))
}

// Validate the action is a CreateAction and it's for the correct resource (Service).
createAction, ok := actions[0].(coretesting.CreateAction)
if !ok {
t.Fatalf("expected CreateAction, but got %T", actions[0])
}

if createAction.GetResource().Resource != "services" {
t.Fatalf("expected action on 'services', but got '%s'", createAction.GetResource().Resource)
}

// Validate the created service object.
service := createAction.GetObject().(*corev1.Service)
expectedServiceName := util.KarmadaAggregatedAPIServerName(name)
if service.Name != expectedServiceName {
t.Fatalf("expected service name '%s', but got '%s'", expectedServiceName, service.Name)
}

if service.Namespace != namespace {
t.Fatalf("expected service namespace '%s', but got '%s'", namespace, service.Namespace)
}

serviceExternalNameExpected := fmt.Sprintf("%s.%s.svc", expectedServiceName, namespace)
if service.Spec.ExternalName != serviceExternalNameExpected {
t.Fatalf("expected service external name '%s', but got '%s'", serviceExternalNameExpected, service.Spec.ExternalName)
}
}

func TestKarmadaMetricsAdapterService(t *testing.T) {
name, namespace := "karmada-demo", "test"

fakeClient := fakeclientset.NewSimpleClientset()
err := karmadaMetricsAdapterService(fakeClient, name, namespace, name, namespace)
if err != nil {
t.Fatalf("failed to create karmada metrics adapter service: %v", err)
}

// Ensure the expected action (service creation) occurred.
actions := fakeClient.Actions()
if len(actions) != 1 {
t.Fatalf("expected 1 action, but got %d", len(actions))
}

// Validate the action is a CreateAction and it's for the correct resource (Service).
createAction, ok := actions[0].(coretesting.CreateAction)
if !ok {
t.Fatalf("expected CreateAction, but got %T", actions[0])
}

if createAction.GetResource().Resource != "services" {
t.Fatalf("expected action on 'services', but got '%s'", createAction.GetResource().Resource)
}

// Validate the created service object.
service := createAction.GetObject().(*corev1.Service)
expectedServiceName := util.KarmadaMetricsAdapterName(name)
if service.Name != expectedServiceName {
t.Fatalf("expected service name '%s', but got '%s'", expectedServiceName, service.Name)
}

if service.Namespace != namespace {
t.Fatalf("expected service namespace '%s', but got '%s'", namespace, service.Namespace)
}

serviceExternalNameExpected := fmt.Sprintf("%s.%s.svc", expectedServiceName, namespace)
if service.Spec.ExternalName != serviceExternalNameExpected {
t.Fatalf("expected service external name '%s', but got '%s'", serviceExternalNameExpected, service.Spec.ExternalName)
}
}
2 changes: 1 addition & 1 deletion operator/pkg/util/apiclient/idempotency.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func CreateOrUpdateValidatingWebhookConfiguration(client clientset.Interface, vw
}

// CreateOrUpdateAPIService creates a APIService if the target resource doesn't exist. If the resource exists already, this function will update the resource instead.
func CreateOrUpdateAPIService(apiRegistrationClient *aggregator.Clientset, apiservice *apiregistrationv1.APIService) error {
func CreateOrUpdateAPIService(apiRegistrationClient aggregator.Interface, apiservice *apiregistrationv1.APIService) error {
_, err := apiRegistrationClient.ApiregistrationV1().APIServices().Create(context.TODO(), apiservice, metav1.CreateOptions{})
if err != nil {
if !apierrors.IsAlreadyExists(err) {
Expand Down

0 comments on commit 239e2c1

Please sign in to comment.