pkg/gkedisk/gkedisk_test.go
Rama main · réplica de lectura del repositorio original.
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)
}
}