Ctrl K
ComunidadGuías…

pkg/gkedisk/gkedisk_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package gkedisk

import (
	"strings"
	"testing"

	corev1 "k8s.io/api/core/v1"
	storagev1 "k8s.io/api/storage/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestHyperdiskOnly(t *testing.T) {
	for machineType, want := range map[string]bool{
		"n4d-standard-4":   true,
		"n4-custom-4-8192": true,
		"c4a-highcpu-8":    true,
		"C4-standard-2":    true,
		"e2-standard-2":    false,
		"n2d-standard-4":   false,
		"c3-standard-4":    false, // partial PD support: never flagged
		"":                 false,
	} {
		if got := HyperdiskOnly(machineType); got != want {
			t.Errorf("HyperdiskOnly(%q) = %v, want %v", machineType, got, want)
		}
	}
}

func TestParseIncompatibleAttach(t *testing.T) {
	msg := `AttachVolume.Attach failed for volume "pvc-d28294a7" : rpc error: code = Internal desc = Failed to Attach: failed cloud service attach disk call: googleapi: Error 400: pd-ssd disk type cannot be used by n4d-standard-4 machine type., badRequest`
	disk, machine, ok := ParseIncompatibleAttach(msg)
	if !ok || disk != "pd-ssd" || machine != "n4d-standard-4" {
		t.Fatalf("got %q %q %v", disk, machine, ok)
	}
	if _, _, ok := ParseIncompatibleAttach(`ControllerPublish not permitted on node "x" due to backoff condition`); ok {
		t.Fatal("backoff echo must not parse as an incompatibility")
	}
}

func TestIsAttachBackoffEcho(t *testing.T) {
	if !IsAttachBackoffEcho(`rpc error: code = InvalidArgument desc = ControllerPublish not permitted on node "projects/p/zones/z/instances/n" due to backoff condition`) {
		t.Fatal("expected backoff echo")
	}
	if IsAttachBackoffEcho("googleapi: Error 400: pd-ssd disk type cannot be used by n4d-standard-4 machine type.") {
		t.Fatal("real error must not be a backoff echo")
	}
}

func TestDiskType(t *testing.T) {
	classes := map[string]*storagev1.StorageClass{
		"premium-rwo":  {ObjectMeta: metav1.ObjectMeta{Name: "premium-rwo"}, Provisioner: CSIDriver, Parameters: map[string]string{"type": "pd-ssd"}},
		"standard":     {ObjectMeta: metav1.ObjectMeta{Name: "standard"}, Provisioner: InTreeProvision},
		"hyperdisk":    {ObjectMeta: metav1.ObjectMeta{Name: "hyperdisk"}, Provisioner: CSIDriver, Parameters: map[string]string{"type": "hyperdisk-balanced"}},
		"mixed-case":   {ObjectMeta: metav1.ObjectMeta{Name: "mixed-case"}, Provisioner: CSIDriver, Parameters: map[string]string{"Type": "hyperdisk-balanced"}},
		"ebs":          {ObjectMeta: metav1.ObjectMeta{Name: "ebs"}, Provisioner: "ebs.csi.aws.com", Parameters: map[string]string{"type": "gp3"}},
		"mismatch-csi": {ObjectMeta: metav1.ObjectMeta{Name: "mismatch-csi"}, Provisioner: "ebs.csi.aws.com"},
	}
	lookup := func(name string) *storagev1.StorageClass { return classes[name] }
	csiPV := func(sc string) *corev1.PersistentVolume {
		return &corev1.PersistentVolume{ObjectMeta: provisioned(CSIDriver), Spec: corev1.PersistentVolumeSpec{
			StorageClassName:       sc,
			PersistentVolumeSource: corev1.PersistentVolumeSource{CSI: &corev1.CSIPersistentVolumeSource{Driver: CSIDriver}},
		}}
	}
	inTreePV := &corev1.PersistentVolume{ObjectMeta: provisioned(InTreeProvision), Spec: corev1.PersistentVolumeSpec{
		StorageClassName:       "standard",
		PersistentVolumeSource: corev1.PersistentVolumeSource{GCEPersistentDisk: &corev1.GCEPersistentDiskVolumeSource{PDName: "d"}},
	}}
	staticPV := csiPV("premium-rwo")
	staticPV.Annotations = nil
	ebsPV := &corev1.PersistentVolume{ObjectMeta: provisioned("ebs.csi.aws.com"), Spec: corev1.PersistentVolumeSpec{
		StorageClassName:       "ebs",
		PersistentVolumeSource: corev1.PersistentVolumeSource{CSI: &corev1.CSIPersistentVolumeSource{Driver: "ebs.csi.aws.com"}},
	}}

	cases := []struct {
		name   string
		pv     *corev1.PersistentVolume
		want   string
		wantOK bool
	}{
		{"csi pd-ssd", csiPV("premium-rwo"), "pd-ssd", true},
		{"csi hyperdisk", csiPV("hyperdisk"), "hyperdisk-balanced", true},
		{"csi case-insensitive parameter key", csiPV("mixed-case"), "hyperdisk-balanced", true},
		{"in-tree default type", inTreePV, "pd-standard", true},
		{"static PV borrowing a class name", staticPV, "", false},
		{"other cloud", ebsPV, "", false},
		{"unknown class", csiPV("gone"), "", false},
		{"class from another provisioner", csiPV("mismatch-csi"), "", false},
		{"no class", csiPV(""), "", false},
		{"nil", nil, "", false},
	}
	for _, tc := range cases {
		got, ok := DiskType(tc.pv, lookup)
		if got != tc.want || ok != tc.wantOK {
			t.Errorf("%s: DiskType = %q, %v; want %q, %v", tc.name, got, ok, tc.want, tc.wantOK)
		}
	}
}

// A rejected Hyperdisk type must not be told its machine "supports only
// Hyperdisk", nor be advised to move to Hyperdisk.
func TestIncompatibilityForHyperdiskTypes(t *testing.T) {
	cause := IncompatibilityCause("hyperdisk-extreme", "n4-standard-4")
	if strings.Contains(cause, "only Hyperdisk") || !strings.Contains(cause, "hyperdisk-extreme disks on n4-standard-4") {
		t.Errorf("cause = %q", cause)
	}
	action := IncompatibilityAction("hyperdisk-balanced")
	if strings.Contains(action, "Hyperdisk StorageClass") || !strings.Contains(action, "supports hyperdisk-balanced") {
		t.Errorf("action = %q", action)
	}
	if !strings.Contains(IncompatibilityAction("pd-ssd"), "Hyperdisk StorageClass") {
		t.Error("PD types should still be offered the Hyperdisk move")
	}
}

func provisioned(by string) metav1.ObjectMeta {
	return metav1.ObjectMeta{Annotations: map[string]string{"pv.kubernetes.io/provisioned-by": by}}
}

func TestIncompatibilityCause(t *testing.T) {
	if got := IncompatibilityCause("pd-ssd", "n4d-standard-4"); !strings.Contains(got, "N4D machine series supports only Hyperdisk") {
		t.Errorf("Hyperdisk-only cause = %q", got)
	}
	if got := IncompatibilityCause("pd-standard", "c3-standard-4"); strings.Contains(got, "only Hyperdisk") || !strings.Contains(got, "pd-standard disks on c3-standard-4") {
		t.Errorf("partial-support cause must not claim Hyperdisk-only: %q", got)
	}
}