Skip to content

Commit

Permalink
Merge pull request #1078 from Tal-or/hypershfit_client
Browse files Browse the repository at this point in the history
e2e:hypershift: helper functions
  • Loading branch information
openshift-merge-bot[bot] authored Nov 20, 2024
2 parents 1cd35d7 + e32034d commit 15c8a8e
Show file tree
Hide file tree
Showing 158 changed files with 11,889 additions and 998 deletions.
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ require (
github.com/mdomke/git-semver v1.0.0
github.com/onsi/ginkgo/v2 v2.19.1
github.com/onsi/gomega v1.34.0
github.com/openshift/api v0.0.0-20240422085825-2624175e9673
github.com/openshift/api v0.0.0-20240524162738-d899f8877d22
github.com/openshift/cluster-node-tuning-operator v0.0.0-20240611064827-2bd8891ead93
github.com/openshift/hypershift/api v0.0.0-20241115183703-d41904871380
github.com/openshift/machine-config-operator v0.0.1-0.20230724174830-7b54f1dcce4e
github.com/sergi/go-diff v1.1.0
github.com/stretchr/testify v1.9.0
golang.org/x/sync v0.7.0
golang.org/x/sync v0.8.0
k8s.io/api v0.31.2
k8s.io/apiextensions-apiserver v0.31.2
k8s.io/apimachinery v0.31.2
Expand Down Expand Up @@ -97,11 +98,11 @@ require (
go.uber.org/ratelimit v0.2.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/term v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
Expand Down
21 changes: 14 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1952,14 +1952,16 @@ github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxj
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os=
github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo=
github.com/openshift/api v0.0.0-20240422085825-2624175e9673 h1:D4qblu6z2A92fh7u9Nt1YskDtu+GySKiYP/D3tMWQ6A=
github.com/openshift/api v0.0.0-20240422085825-2624175e9673/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4=
github.com/openshift/api v0.0.0-20240524162738-d899f8877d22 h1:AW8KUN4k7qR2egrCCe3x95URHQ3N188+a/b0qpRyAHg=
github.com/openshift/api v0.0.0-20240524162738-d899f8877d22/go.mod h1:7Hm1kLJGxWT6eysOpD2zUztdn+w91eiERn6KtI5o9aw=
github.com/openshift/client-go v0.0.0-20240415214935-be70f772f157 h1:xbd4qHpyFnnOYDHHnMQa+100MR+K/DFiC1J3BFdL+tQ=
github.com/openshift/client-go v0.0.0-20240415214935-be70f772f157/go.mod h1:Q3mt/X5xrxnR5R6BE7duF2ToLioRQJYnTYaaDS4QZTs=
github.com/openshift/cluster-node-tuning-operator v0.0.0-20240611064827-2bd8891ead93 h1:w39rlA/dNNolsHBtORZPaNW4L6qdk6a2LCzfpxtVYKM=
github.com/openshift/cluster-node-tuning-operator v0.0.0-20240611064827-2bd8891ead93/go.mod h1:1nJC0uQ+XquLauGTdalV9jkYgGrTBGiq1cOgmDyvQz8=
github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 h1:cHyxR+Y8rAMT6m1jQCaYGRwikqahI0OjjUDhFNf3ySQ=
github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA=
github.com/openshift/hypershift/api v0.0.0-20241115183703-d41904871380 h1:rvDZDAURpDOO/+pf3cR6t+0J8ZT5ueP07LTW47PLy4s=
github.com/openshift/hypershift/api v0.0.0-20241115183703-d41904871380/go.mod h1:NIT2Bs83re4seKsT3Xp+ENOOCN2Gl++mguuGGhNnN/8=
github.com/openshift/machine-config-operator v0.0.1-0.20230724174830-7b54f1dcce4e h1:lgQ2Iy0NHk/iBaR9yvqSqROCiOovpkbc8MRYSIpHf+M=
github.com/openshift/machine-config-operator v0.0.1-0.20230724174830-7b54f1dcce4e/go.mod h1:xwAAOZMhwF91Ii8/yfOwp+yH5+GJS7VX90NI39RmSyo=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
Expand Down Expand Up @@ -2408,8 +2410,9 @@ golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -2473,8 +2476,9 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down Expand Up @@ -2595,8 +2599,9 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
Expand All @@ -2621,8 +2626,9 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -2645,8 +2651,9 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down
85 changes: 85 additions & 0 deletions internal/nodepools/nodepools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package nodepools

import (
"context"
"fmt"

corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/openshift-kni/numaresources-operator/test/utils/hypershift"
hypershiftv1beta1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
)

func GetByClusterName(ctx context.Context, c client.Client, hostedClusterName string) (*hypershiftv1beta1.NodePool, error) {
npList := &hypershiftv1beta1.NodePoolList{}
if err := c.List(ctx, npList); err != nil {
return nil, err
}
var np *hypershiftv1beta1.NodePool
for i := 0; i < len(npList.Items); i++ {
if npList.Items[i].Spec.ClusterName == hostedClusterName {
np = &npList.Items[i]
break
}
}
if np == nil {
return nil, fmt.Errorf("failed to find nodePool associated with cluster %q; existing nodePools are: %+v", hostedClusterName, npList.Items)
}
return np, nil
}

// AttachConfigObject is attaches a tuning object into the nodepool associated with the hosted-cluster
// The function is idempotent
func AttachConfigObject(ctx context.Context, cli client.Client, object client.Object) error {
hostedClusterName, err := hypershift.GetHostedClusterName()
if err != nil {
return err
}
np, err := GetByClusterName(ctx, cli, hostedClusterName)
if err != nil {
return err
}
np.Spec.Config = addObjectRef(object, np.Spec.Config)
if cli.Update(ctx, np) != nil {
return err
}
return nil
}

func addObjectRef(object client.Object, Config []corev1.LocalObjectReference) []corev1.LocalObjectReference {
updatedConfig := []corev1.LocalObjectReference{{Name: object.GetName()}}
for i := range Config {
config := Config[i]
if config.Name != object.GetName() {
updatedConfig = append(updatedConfig, config)
}
}
return updatedConfig
}

func removeObjectRef(object client.Object, Config []corev1.LocalObjectReference) []corev1.LocalObjectReference {
var updatedConfig []corev1.LocalObjectReference
for i := range Config {
if Config[i].Name != object.GetName() {
updatedConfig = append(updatedConfig, Config[i])
}
}
return updatedConfig
}

func DeAttachConfigObject(ctx context.Context, cli client.Client, object client.Object) error {
hostedClusterName, err := hypershift.GetHostedClusterName()
if err != nil {
return err
}
np, err := GetByClusterName(ctx, cli, hostedClusterName)
if err != nil {
return err
}
np.Spec.Config = removeObjectRef(object, np.Spec.Config)
if cli.Update(ctx, np) != nil {
return err
}
return nil
}
200 changes: 200 additions & 0 deletions internal/nodepools/nodepools_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package nodepools

import (
"context"
corev1 "k8s.io/api/core/v1"
"strings"
"testing"

k8sruntime "k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

hypershiftv1beta1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
)

var (
scheme = k8sruntime.NewScheme()
)

func TestGetByClusterName(t *testing.T) {
utilruntime.Must(hypershiftv1beta1.AddToScheme(scheme))

ctx := context.TODO()

// Mock data for NodePoolList
nodePools := []hypershiftv1beta1.NodePool{
{
ObjectMeta: metav1.ObjectMeta{
Name: "nodepool1",
Namespace: "default",
},
Spec: hypershiftv1beta1.NodePoolSpec{
ClusterName: "cluster1",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "nodepool2",
Namespace: "default",
},
Spec: hypershiftv1beta1.NodePoolSpec{
ClusterName: "cluster2",
},
},
}

testCases := []struct {
name string
clusterName string
expectedError string
expectedObjectKey string
}{
{
name: "Successfully finds NodePool by cluster name",
clusterName: "cluster1",
expectedError: "",
expectedObjectKey: client.ObjectKeyFromObject(&nodePools[0]).String(),
},
{
name: "Returns error when no NodePool matches cluster name",
clusterName: "nonexistent-cluster",
expectedError: "failed to find nodePool associated with cluster \"nonexistent-cluster\"; existing nodePools are:",
expectedObjectKey: "",
},
}

// Run testCases
t.Run("GetByClusterName Tests", func(t *testing.T) {
// Initialize a fake client with the mock data
fakeClient := fake.NewClientBuilder().WithObjects(&nodePools[0], &nodePools[1]).WithScheme(scheme).Build()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
np, err := GetByClusterName(ctx, fakeClient, tc.clusterName)
if err != nil {
if tc.expectedError == "" {
t.Errorf("no error expected to be returned; got %v", err)
}
if !strings.Contains(err.Error(), tc.expectedError) {
t.Errorf("expected error %v, got %v", tc.expectedError, err)
}
} else {
if tc.expectedObjectKey != client.ObjectKeyFromObject(np).String() {
t.Errorf("expected object key %v, got %v", tc.expectedObjectKey, client.ObjectKeyFromObject(np).String())
}
}
})
}
})
}

func TestAddObjectRef(t *testing.T) {
// Mock object
mockObject := &corev1.ConfigMap{}
mockObject.SetName("object1")

testCases := []struct {
name string
initialConfig []corev1.LocalObjectReference
expected []corev1.LocalObjectReference
}{
{
name: "Add new object reference",
initialConfig: []corev1.LocalObjectReference{
{Name: "object2"},
{Name: "object3"},
},
expected: []corev1.LocalObjectReference{
{Name: "object1"},
{Name: "object2"},
{Name: "object3"},
},
},
{
name: "Replace existing object reference",
initialConfig: []corev1.LocalObjectReference{
{Name: "object1"},
{Name: "object3"},
},
expected: []corev1.LocalObjectReference{
{Name: "object1"},
{Name: "object3"},
},
},
{
name: "Add to empty configuration",
expected: []corev1.LocalObjectReference{{Name: "object1"}},
},
}

// Run test cases
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := addObjectRef(mockObject, tc.initialConfig)
if len(result) != len(tc.expected) {
t.Errorf("Test %q failed: expected length %d, got %d", tc.name, len(tc.expected), len(result))
}
for i := range result {
if result[i].Name != tc.expected[i].Name {
t.Errorf("Test %q failed: expected %v, got %v", tc.name, tc.expected[i], result[i])
}
}
})
}
}

func TestRemoveObjectRef(t *testing.T) {
// Mock object
mockObject := &corev1.ConfigMap{}
mockObject.SetName("object1")

testCases := []struct {
name string
initialConfig []corev1.LocalObjectReference
expected []corev1.LocalObjectReference
}{
{
name: "Remove existing object reference",
initialConfig: []corev1.LocalObjectReference{
{Name: "object1"},
{Name: "object2"},
},
expected: []corev1.LocalObjectReference{
{Name: "object2"},
},
},
{
name: "Do nothing if object reference does not exist",
initialConfig: []corev1.LocalObjectReference{
{Name: "object2"},
{Name: "object3"},
},
expected: []corev1.LocalObjectReference{
{Name: "object2"},
{Name: "object3"},
},
},
{
name: "Handle empty configuration",
expected: []corev1.LocalObjectReference{},
},
}

// Run test cases
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := removeObjectRef(mockObject, tc.initialConfig)
if len(result) != len(tc.expected) {
t.Errorf("Test %q failed: expected length %d, got %d", tc.name, len(tc.expected), len(result))
}
for i := range result {
if result[i].Name != tc.expected[i].Name {
t.Errorf("Test %q failed: expected %v, got %v", tc.name, tc.expected[i], result[i])
}
}
})
}
}
Loading

0 comments on commit 15c8a8e

Please sign in to comment.