146 lines
4.5 KiB
Go
146 lines
4.5 KiB
Go
package controllers
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"time"
|
|
|
|
. "github.com/onsi/gomega"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
kubefloworgv1alpha1 "github.com/kubeflow/kubeflow/components/pvc-viewer/api/v1alpha1"
|
|
)
|
|
|
|
// Variables required for the tests utilities and passed by the test suite
|
|
type TestHelper struct {
|
|
namespace string
|
|
|
|
ctx context.Context
|
|
k8sClient client.Client
|
|
}
|
|
|
|
// Define utility constants for object names and testing timeouts/durations and intervals.
|
|
const (
|
|
// Used for Eventually test
|
|
timeout = time.Second * 10
|
|
// Use for consistently test
|
|
duration = time.Second * 5
|
|
// Defines the interval for the Eventually/Consistency tests
|
|
interval = time.Millisecond * 250
|
|
)
|
|
|
|
// Extracts the node name from the affinity of the PVCViewer
|
|
func (t *TestHelper) ExtractNodeName(affinity *corev1.Affinity) string {
|
|
if affinity == nil || affinity.NodeAffinity == nil || affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution == nil {
|
|
return ""
|
|
}
|
|
return affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchExpressions[0].Values[0]
|
|
}
|
|
|
|
// Creates a Pod that mounts the PVC with the given name
|
|
func (t *TestHelper) CreatePod(name string, nodeName string, mountedPVCName string) {
|
|
pod := &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
Namespace: t.namespace,
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
NodeName: nodeName,
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "main",
|
|
Image: "busybox",
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: "pvc",
|
|
MountPath: "/pvc",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "pvc",
|
|
VolumeSource: corev1.VolumeSource{
|
|
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
|
ClaimName: mountedPVCName,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
Expect(t.k8sClient.Create(t.ctx, pod)).Should(Succeed())
|
|
}
|
|
|
|
// CreateViewer is a helper function that creates a PVCViewer and returns the created object
|
|
func (t *TestHelper) CreatePVC(name string, accessMode corev1.PersistentVolumeAccessMode) {
|
|
pvc := &corev1.PersistentVolumeClaim{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
Namespace: t.namespace,
|
|
},
|
|
Spec: corev1.PersistentVolumeClaimSpec{
|
|
AccessModes: []corev1.PersistentVolumeAccessMode{
|
|
accessMode,
|
|
},
|
|
Resources: corev1.ResourceRequirements{
|
|
Requests: corev1.ResourceList{
|
|
corev1.ResourceStorage: resource.MustParse("1Gi"),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
Expect(t.k8sClient.Create(t.ctx, pvc)).Should(Succeed())
|
|
}
|
|
|
|
// We cannot test deletions directly, as we are in a testing environment
|
|
// However, testing the ownerReferences is a good proxy for testing deletion
|
|
// See: https://book.kubebuilder.io/reference/envtest.html#testing-considerations
|
|
func (t *TestHelper) ExpectMatchingOwnerReferences(pvcViewer *kubefloworgv1alpha1.PVCViewer, ownerReferences []metav1.OwnerReference) {
|
|
expectedOwnerReferences := metav1.OwnerReference{
|
|
APIVersion: "kubeflow.org/v1alpha1",
|
|
Kind: "PVCViewer",
|
|
Name: pvcViewer.Name,
|
|
UID: pvcViewer.UID,
|
|
Controller: &[]bool{true}[0],
|
|
BlockOwnerDeletion: &[]bool{true}[0],
|
|
}
|
|
Expect(ownerReferences).To(ContainElement(expectedOwnerReferences))
|
|
}
|
|
|
|
// Wrap the client.Get method to automatically set the correct lookupKey when getting resources the controller creates
|
|
func (t *TestHelper) GetRelatedResource(pvcViewer *kubefloworgv1alpha1.PVCViewer, obj client.Object) error {
|
|
key := types.NamespacedName{Name: resourcePrefix + pvcViewer.Name, Namespace: t.namespace}
|
|
if reflect.TypeOf(obj) == reflect.TypeOf(&kubefloworgv1alpha1.PVCViewer{}) {
|
|
key.Name = pvcViewer.Name
|
|
}
|
|
return t.k8sClient.Get(t.ctx, key, obj)
|
|
}
|
|
|
|
// CreateViewer is a helper function that creates a PVCViewer and returns the created object
|
|
func (t *TestHelper) CreateViewer(viewerSpec *kubefloworgv1alpha1.PVCViewerSpec) *kubefloworgv1alpha1.PVCViewer {
|
|
pvcViewer := &kubefloworgv1alpha1.PVCViewer{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test-pvcviewer",
|
|
Namespace: t.namespace,
|
|
},
|
|
Spec: *viewerSpec,
|
|
}
|
|
Expect(t.k8sClient.Create(t.ctx, pvcViewer)).Should(Succeed())
|
|
|
|
createdPVCViewer := &kubefloworgv1alpha1.PVCViewer{}
|
|
Eventually(func() error {
|
|
return t.GetRelatedResource(pvcViewer, createdPVCViewer)
|
|
}, timeout, interval).Should(Succeed())
|
|
Expect(createdPVCViewer).ShouldNot(BeNil())
|
|
|
|
return createdPVCViewer
|
|
}
|