Skip to content

Commit

Permalink
Adding unit testing (comment from Brandon)
Browse files Browse the repository at this point in the history
  • Loading branch information
edcdavid committed Nov 27, 2023
1 parent 44818d3 commit f61d617
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 15 deletions.
17 changes: 8 additions & 9 deletions pkg/provider/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
)

const (
Expand Down Expand Up @@ -409,7 +410,7 @@ func (p *Pod) IsRunAsUserID(uid int64) bool {
// Get the list of top owners of pods
func (p *Pod) GetTopOwner() (topOwners map[string]TopOwner, err error) {
topOwners = make(map[string]TopOwner)
err = followOwnerReferences(topOwners, p.Namespace, p.OwnerReferences)
err = followOwnerReferences(clientsholder.GetClientsHolder().GroupResources, clientsholder.GetClientsHolder().DynamicClient, topOwners, p.Namespace, p.OwnerReferences)
if err != nil {
return topOwners, fmt.Errorf("could not get top owners, err=%s", err)
}
Expand All @@ -424,14 +425,13 @@ type TopOwner struct {
}

// Recursively follow the ownership tree to find the top owners
func followOwnerReferences(topOwners map[string]TopOwner, namespace string, ownerRefs []metav1.OwnerReference) (err error) {
clients := clientsholder.GetClientsHolder()
func followOwnerReferences(resourceList []*metav1.APIResourceList, dynamicClient dynamic.Interface, topOwners map[string]TopOwner, namespace string, ownerRefs []metav1.OwnerReference) (err error) {
for _, ownerRef := range ownerRefs {
fmt.Printf("-> Owner: %s/%s\n", ownerRef.Kind, ownerRef.Name)
// Get group resource version
gvr := getResourceSchema(ownerRef.APIVersion, ownerRef.Kind)
gvr := getResourceSchema(resourceList, ownerRef.APIVersion, ownerRef.Kind)
// Get the owner resources
resource, err := clients.DynamicClient.Resource(gvr).Namespace(namespace).Get(context.Background(), ownerRef.Name, metav1.GetOptions{})
resource, err := dynamicClient.Resource(gvr).Namespace(namespace).Get(context.Background(), ownerRef.Name, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("could not get object indicated by owner references")
}
Expand All @@ -446,7 +446,7 @@ func followOwnerReferences(topOwners map[string]TopOwner, namespace string, owne
topOwners[ownerRef.Name] = TopOwner{Kind: ownerRef.Kind, Name: ownerRef.Name, Namespace: namespace}
}
// if not continue following other branches
err = followOwnerReferences(topOwners, namespace, ownerReferences)
err = followOwnerReferences(resourceList, dynamicClient, topOwners, namespace, ownerReferences)
if err != nil {
return fmt.Errorf("error following owners")
}
Expand All @@ -455,10 +455,9 @@ func followOwnerReferences(topOwners map[string]TopOwner, namespace string, owne
}

// Get the Group Version Resource based on APIVersion and kind
func getResourceSchema(apiVersion, kind string) (gvr schema.GroupVersionResource) {
func getResourceSchema(resourceList []*metav1.APIResourceList, apiVersion, kind string) (gvr schema.GroupVersionResource) {
const groupVersionComponentsNumber = 2
clients := clientsholder.GetClientsHolder()
for _, gr := range clients.GroupResources {
for _, gr := range resourceList {
for i := 0; i < len(gr.APIResources); i++ {
if gr.APIResources[i].Kind == kind && gr.GroupVersion == apiVersion {
groupSplit := strings.Split(gr.GroupVersion, "/")
Expand Down
92 changes: 86 additions & 6 deletions pkg/provider/pods_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@
package provider

import (
"testing"

"errors"
"reflect"
"testing"

corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/runtime"

olmv1Alpha "github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/stretchr/testify/assert"
"github.com/test-network-function/cnf-certification-test/internal/clientsholder"
v1app "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
v1 "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
k8sDynamicFake "k8s.io/client-go/dynamic/fake"
k8sfake "k8s.io/client-go/kubernetes/fake"
k8stesting "k8s.io/client-go/testing"
)

func TestPod_CheckResourceOnly2MiHugePages(t *testing.T) {
Expand Down Expand Up @@ -515,3 +518,80 @@ func TestIsRunAsUserID(t *testing.T) {
assert.Equal(t, tc.expectedOutput, tc.testPod.IsRunAsUserID(tc.testUID))
}
}

func Test_followOwnerReferences(t *testing.T) {
type args struct {
topOwners map[string]TopOwner
namespace string
ownerRefs []metav1.OwnerReference
}

csv1 := &olmv1Alpha.ClusterServiceVersion{
TypeMeta: metav1.TypeMeta{Kind: "ClusterServiceVersion", APIVersion: "operators.coreos.com/v1alpha1"},
ObjectMeta: metav1.ObjectMeta{
Name: "csv1",
Namespace: "ns1",
OwnerReferences: []metav1.OwnerReference{},
},
}
dep1 := &v1app.Deployment{
TypeMeta: metav1.TypeMeta{Kind: "Deployment", APIVersion: "apps/v1"},
ObjectMeta: metav1.ObjectMeta{
Name: "dep1",
Namespace: "ns1",
OwnerReferences: []metav1.OwnerReference{{APIVersion: "operators.coreos.com/v1alpha1", Kind: "ClusterServiceVersion", Name: "csv1"}},
},
}
rep1 := &v1app.ReplicaSet{
TypeMeta: metav1.TypeMeta{Kind: "ReplicaSet", APIVersion: "apps/v1"},
ObjectMeta: metav1.ObjectMeta{
Name: "rep1",
Namespace: "ns1",
OwnerReferences: []metav1.OwnerReference{{APIVersion: "apps/v1", Kind: "Deployment", Name: "dep1"}},
},
}

resourceList := []*metav1.APIResourceList{
{GroupVersion: "operators.coreos.com/v1alpha1", APIResources: []metav1.APIResource{{Name: "clusterserviceversions", Kind: "ClusterServiceVersion"}}},
{GroupVersion: "apps/v1", APIResources: []metav1.APIResource{{Name: "deployments", Kind: "Deployment"}}},
{GroupVersion: "apps/v1", APIResources: []metav1.APIResource{{Name: "replicasets", Kind: "ReplicaSet"}}},
{GroupVersion: "apps/v1", APIResources: []metav1.APIResource{{Name: "pods", Kind: "Pod"}}},
}

tests := []struct {
name string
args args
wantErr bool
}{
{
name: "test1",
args: args{topOwners: map[string]TopOwner{"csv1": {Namespace: "ns1", Kind: "ClusterServiceVersion", Name: "csv1"}},
namespace: "ns1",
ownerRefs: []metav1.OwnerReference{{APIVersion: "apps/v1", Kind: "ReplicaSet", Name: "rep1"}},
},
},
}

// Spoof the get and update functions
client := k8sDynamicFake.NewSimpleDynamicClient(runtime.NewScheme(), rep1, dep1, csv1)
client.Fake.AddReactor("get", "ClusterServiceVersion", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
return true, csv1, nil
})
client.Fake.AddReactor("get", "Deployment", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
return true, dep1, nil
})
client.Fake.AddReactor("get", "ReplicaSet", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
return true, rep1, nil
})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotResults := map[string]TopOwner{}
if err := followOwnerReferences(resourceList, client, gotResults, tt.args.namespace, tt.args.ownerRefs); (err != nil) != tt.wantErr {
t.Errorf("followOwnerReferences() error = %v, wantErr %v", err, tt.wantErr)
}
if !reflect.DeepEqual(gotResults, tt.args.topOwners) {
t.Errorf("followOwnerReferences() = %v, want %v", gotResults, tt.args.topOwners)
}
})
}
}

0 comments on commit f61d617

Please sign in to comment.