mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
Merge pull request #59879 from humblec/gluster-dp-test-latest_1
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Add tests for GlusterFS dynamic provisioner. This bring up a heketi server pod and the server will be running in mock mode, the PVC creation should work, however the volume attachment to a pod and read/write is not part of this test. Due to the same reason the tests are marked as [fast]. Signed-off-by: Humble Chirammal <hchiramm@redhat.com> **What this PR does / why we need it**: **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: **Release note**: ```release-note ```
This commit is contained in:
commit
34706b79e4
@ -56,6 +56,7 @@ type storageClassTest struct {
|
|||||||
expectedSize string
|
expectedSize string
|
||||||
pvCheck func(volume *v1.PersistentVolume) error
|
pvCheck func(volume *v1.PersistentVolume) error
|
||||||
nodeName string
|
nodeName string
|
||||||
|
attach bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -98,10 +99,14 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
|
|||||||
pv, err := client.CoreV1().PersistentVolumes().Get(claim.Spec.VolumeName, metav1.GetOptions{})
|
pv, err := client.CoreV1().PersistentVolumes().Get(claim.Spec.VolumeName, metav1.GetOptions{})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
if class.Provisioner == "kubernetes.io/glusterfs" && framework.ProviderIs("gke", "gce") {
|
||||||
|
framework.Logf("Skipping glusterfs dynamic test for cloud provider %v", "GCE/GKE")
|
||||||
|
} else {
|
||||||
// Check sizes
|
// Check sizes
|
||||||
expectedCapacity := resource.MustParse(t.expectedSize)
|
expectedCapacity := resource.MustParse(t.expectedSize)
|
||||||
pvCapacity := pv.Spec.Capacity[v1.ResourceName(v1.ResourceStorage)]
|
pvCapacity := pv.Spec.Capacity[v1.ResourceName(v1.ResourceStorage)]
|
||||||
Expect(pvCapacity.Value()).To(Equal(expectedCapacity.Value()), "pvCapacity is not equal to expectedCapacity")
|
Expect(pvCapacity.Value()).To(Equal(expectedCapacity.Value()), "pvCapacity is not equal to expectedCapacity")
|
||||||
|
}
|
||||||
|
|
||||||
requestedCapacity := resource.MustParse(t.claimSize)
|
requestedCapacity := resource.MustParse(t.claimSize)
|
||||||
claimCapacity := claim.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
claimCapacity := claim.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
@ -126,6 +131,7 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if t.attach {
|
||||||
// We start two pods:
|
// We start two pods:
|
||||||
// - The first writes 'hello word' to the /mnt/test (= the volume).
|
// - The first writes 'hello word' to the /mnt/test (= the volume).
|
||||||
// - The second one runs grep 'hello world' on /mnt/test.
|
// - The second one runs grep 'hello world' on /mnt/test.
|
||||||
@ -143,7 +149,7 @@ func testDynamicProvisioning(t storageClassTest, client clientset.Interface, cla
|
|||||||
|
|
||||||
By("checking the created volume is readable and retains data")
|
By("checking the created volume is readable and retains data")
|
||||||
runInPodWithVolume(client, claim.Namespace, claim.Name, t.nodeName, "grep 'hello world' /mnt/test/data")
|
runInPodWithVolume(client, claim.Namespace, claim.Name, t.nodeName, "grep 'hello world' /mnt/test/data")
|
||||||
|
}
|
||||||
By(fmt.Sprintf("deleting claim %q/%q", claim.Namespace, claim.Name))
|
By(fmt.Sprintf("deleting claim %q/%q", claim.Namespace, claim.Name))
|
||||||
framework.ExpectNoError(client.CoreV1().PersistentVolumeClaims(claim.Namespace).Delete(claim.Name, nil))
|
framework.ExpectNoError(client.CoreV1().PersistentVolumeClaims(claim.Namespace).Delete(claim.Name, nil))
|
||||||
|
|
||||||
@ -781,6 +787,30 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() {
|
|||||||
Expect(claim.Status.Phase).To(Equal(v1.ClaimPending))
|
Expect(claim.Status.Phase).To(Equal(v1.ClaimPending))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
framework.KubeDescribe("GlusterDynamicProvisioner", func() {
|
||||||
|
It("should create and delete persistent volumes [fast]", func() {
|
||||||
|
By("creating a Gluster DP server Pod")
|
||||||
|
pod := startGlusterDpServerPod(c, ns)
|
||||||
|
serverUrl := "https://" + pod.Status.PodIP + ":8081"
|
||||||
|
By("creating a StorageClass")
|
||||||
|
test := storageClassTest{
|
||||||
|
name: "Gluster Dynamic provisioner test",
|
||||||
|
provisioner: "kubernetes.io/glusterfs",
|
||||||
|
claimSize: "2Gi",
|
||||||
|
expectedSize: "2Gi",
|
||||||
|
parameters: map[string]string{"resturl": serverUrl},
|
||||||
|
attach: false,
|
||||||
|
}
|
||||||
|
suffix := fmt.Sprintf("glusterdptest")
|
||||||
|
class := newStorageClass(test, ns, suffix)
|
||||||
|
|
||||||
|
By("creating a claim object with a suffix for gluster dynamic provisioner")
|
||||||
|
claim := newClaim(test, ns, suffix)
|
||||||
|
|
||||||
|
testDynamicProvisioning(test, c, claim, class)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
func getDefaultStorageClassName(c clientset.Interface) string {
|
func getDefaultStorageClassName(c clientset.Interface) string {
|
||||||
@ -967,6 +997,55 @@ func newBetaStorageClass(t storageClassTest, suffix string) *storagebeta.Storage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func startGlusterDpServerPod(c clientset.Interface, ns string) *v1.Pod {
|
||||||
|
podClient := c.CoreV1().Pods(ns)
|
||||||
|
|
||||||
|
provisionerPod := &v1.Pod{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "Pod",
|
||||||
|
APIVersion: "v1",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
GenerateName: "glusterdynamic-provisioner-",
|
||||||
|
},
|
||||||
|
|
||||||
|
Spec: v1.PodSpec{
|
||||||
|
Containers: []v1.Container{
|
||||||
|
{
|
||||||
|
Name: "glusterdynamic-provisioner",
|
||||||
|
Image: "docker.io/humblec/glusterdynamic-provisioner:v1.0",
|
||||||
|
Args: []string{
|
||||||
|
"-config=" + "/etc/heketi/heketi.json",
|
||||||
|
},
|
||||||
|
Ports: []v1.ContainerPort{
|
||||||
|
{Name: "heketi", ContainerPort: 8081},
|
||||||
|
},
|
||||||
|
Env: []v1.EnvVar{
|
||||||
|
{
|
||||||
|
Name: "POD_IP",
|
||||||
|
ValueFrom: &v1.EnvVarSource{
|
||||||
|
FieldRef: &v1.ObjectFieldSelector{
|
||||||
|
FieldPath: "status.podIP",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ImagePullPolicy: v1.PullIfNotPresent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
provisionerPod, err := podClient.Create(provisionerPod)
|
||||||
|
framework.ExpectNoError(err, "Failed to create %s pod: %v", provisionerPod.Name, err)
|
||||||
|
|
||||||
|
framework.ExpectNoError(framework.WaitForPodRunningInNamespace(c, provisionerPod))
|
||||||
|
|
||||||
|
By("locating the provisioner pod")
|
||||||
|
pod, err := podClient.Get(provisionerPod.Name, metav1.GetOptions{})
|
||||||
|
framework.ExpectNoError(err, "Cannot locate the provisioner pod %v: %v", provisionerPod.Name, err)
|
||||||
|
return pod
|
||||||
|
}
|
||||||
|
|
||||||
func startExternalProvisioner(c clientset.Interface, ns string) *v1.Pod {
|
func startExternalProvisioner(c clientset.Interface, ns string) *v1.Pod {
|
||||||
podClient := c.CoreV1().Pods(ns)
|
podClient := c.CoreV1().Pods(ns)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user