...

Source file src/k8s.io/kubernetes/test/integration/pvc/upgrade_test.go

Documentation: k8s.io/kubernetes/test/integration/pvc

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package pvc
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	v1 "k8s.io/api/core/v1"
    24  	"k8s.io/apimachinery/pkg/api/resource"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/apimachinery/pkg/types"
    28  	utilfeature "k8s.io/apiserver/pkg/util/feature"
    29  	"k8s.io/client-go/kubernetes"
    30  	featuregatetesting "k8s.io/component-base/featuregate/testing"
    31  
    32  	kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
    33  	"k8s.io/kubernetes/pkg/api/legacyscheme"
    34  	"k8s.io/kubernetes/pkg/features"
    35  	"k8s.io/kubernetes/test/integration/framework"
    36  )
    37  
    38  func Test_UpgradePVC(t *testing.T) {
    39  	t.Run("feature_enabled", func(t *testing.T) { test_UpgradePVC(t, true) })
    40  	t.Run("feature_disabled", func(t *testing.T) { test_UpgradePVC(t, false) })
    41  }
    42  
    43  func test_UpgradePVC(t *testing.T, featureEnabled bool) {
    44  	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AnyVolumeDataSource, featureEnabled)()
    45  
    46  	etcdOptions := framework.SharedEtcd()
    47  	apiServerOptions := kubeapiservertesting.NewDefaultTestServerOptions()
    48  	s := kubeapiservertesting.StartTestServerOrDie(t, apiServerOptions, nil, etcdOptions)
    49  	defer s.TearDownFn()
    50  	pvcName := "test-old-pvc"
    51  	ns := "old-pvc-ns"
    52  
    53  	kubeclient, err := kubernetes.NewForConfig(s.ClientConfig)
    54  	if err != nil {
    55  		t.Fatalf("Unexpected error: %v", err)
    56  	}
    57  	if _, err := kubeclient.CoreV1().Namespaces().Create(context.TODO(), (&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}}), metav1.CreateOptions{}); err != nil {
    58  		t.Fatal(err)
    59  	}
    60  
    61  	// Create a pvc and store it in etcd with missing fields representing an old version
    62  	pvc := &v1.PersistentVolumeClaim{
    63  		ObjectMeta: metav1.ObjectMeta{
    64  			Name:              pvcName,
    65  			Namespace:         ns,
    66  			CreationTimestamp: metav1.Now(),
    67  			UID:               "08675309-9376-9376-9376-086753099999",
    68  		},
    69  		Spec: v1.PersistentVolumeClaimSpec{
    70  			Resources: v1.VolumeResourceRequirements{
    71  				Requests: v1.ResourceList{
    72  					v1.ResourceName(v1.ResourceStorage): resource.MustParse("10G"),
    73  				},
    74  			},
    75  			DataSource: &v1.TypedLocalObjectReference{
    76  				APIGroup: nil,
    77  				Kind:     "PersistentVolumeClaim",
    78  				Name:     "foo",
    79  			},
    80  			AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
    81  		},
    82  	}
    83  	pvcJSON, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), pvc)
    84  	if err != nil {
    85  		t.Fatalf("Failed creating pvc JSON: %v", err)
    86  	}
    87  	key := "/" + etcdOptions.Prefix + "/persistentvolumeclaims/" + ns + "/" + pvcName
    88  	if _, err := s.EtcdClient.Put(context.Background(), key, string(pvcJSON)); err != nil {
    89  		t.Error(err)
    90  	}
    91  	t.Logf("PVC stored in etcd %v", string(pvcJSON))
    92  
    93  	// Try to update the pvc as a no-op write of the original content
    94  	{
    95  		_, err := kubeclient.CoreV1().PersistentVolumeClaims(ns).Update(context.TODO(), pvc, metav1.UpdateOptions{DryRun: []string{"All"}})
    96  		if err != nil {
    97  			t.Errorf("write of original content failed: %v", err)
    98  		}
    99  	}
   100  
   101  	// Try to update the pvc as an internal server no-op patch of the original content
   102  	{
   103  		_, err := kubeclient.CoreV1().PersistentVolumeClaims(ns).Patch(context.TODO(), pvc.Name, types.MergePatchType, []byte(`{}`), metav1.PatchOptions{DryRun: []string{"All"}})
   104  		if err != nil {
   105  			t.Errorf("no-op patch failed: %v", err)
   106  		}
   107  	}
   108  
   109  	// Try to update the pvc as a no-op get/update
   110  	{
   111  		getPVC, err := kubeclient.CoreV1().PersistentVolumeClaims(ns).Get(context.TODO(), pvc.Name, metav1.GetOptions{})
   112  		if err != nil {
   113  			t.Fatal(err)
   114  		}
   115  		_, err = kubeclient.CoreV1().PersistentVolumeClaims(ns).Update(context.TODO(), getPVC, metav1.UpdateOptions{DryRun: []string{"All"}})
   116  		if err != nil {
   117  			t.Errorf("no-op get/put failed: %v", err)
   118  		}
   119  	}
   120  }
   121  

View as plain text