github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/backend/remote-state/kubernetes/backend_test.go (about) 1 package kubernetes 2 3 import ( 4 "fmt" 5 "math/rand" 6 "os" 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/iaas-resource-provision/iaas-rpc/internal/backend" 12 "github.com/iaas-resource-provision/iaas-rpc/internal/states/statemgr" 13 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 ) 15 16 const ( 17 secretSuffix = "test-state" 18 ) 19 20 var namespace string 21 22 // verify that we are doing ACC tests or the k8s tests specifically 23 func testACC(t *testing.T) { 24 skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_K8S_TEST") == "" 25 if skip { 26 t.Log("k8s backend tests require setting TF_ACC or TF_K8S_TEST") 27 t.Skip() 28 } 29 30 ns := os.Getenv("KUBE_NAMESPACE") 31 32 if ns != "" { 33 namespace = ns 34 } else { 35 namespace = "default" 36 } 37 38 cleanupK8sResources(t) 39 } 40 41 func TestBackend_impl(t *testing.T) { 42 var _ backend.Backend = new(Backend) 43 } 44 45 func TestBackend(t *testing.T) { 46 testACC(t) 47 defer cleanupK8sResources(t) 48 49 b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{ 50 "secret_suffix": secretSuffix, 51 })) 52 53 // Test 54 backend.TestBackendStates(t, b1) 55 } 56 57 func TestBackendLocks(t *testing.T) { 58 testACC(t) 59 defer cleanupK8sResources(t) 60 61 // Get the backend. We need two to test locking. 62 b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{ 63 "secret_suffix": secretSuffix, 64 })) 65 66 b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{ 67 "secret_suffix": secretSuffix, 68 })) 69 70 // Test 71 backend.TestBackendStateLocks(t, b1, b2) 72 backend.TestBackendStateForceUnlock(t, b1, b2) 73 } 74 75 func TestBackendLocksSoak(t *testing.T) { 76 testACC(t) 77 defer cleanupK8sResources(t) 78 79 clientCount := 100 80 lockAttempts := 100 81 82 lockers := []statemgr.Locker{} 83 for i := 0; i < clientCount; i++ { 84 b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{ 85 "secret_suffix": secretSuffix, 86 })) 87 88 s, err := b.StateMgr(backend.DefaultStateName) 89 if err != nil { 90 t.Fatalf("Error creating state manager: %v", err) 91 } 92 93 lockers = append(lockers, s.(statemgr.Locker)) 94 } 95 96 wg := sync.WaitGroup{} 97 for i, l := range lockers { 98 wg.Add(1) 99 go func(locker statemgr.Locker, n int) { 100 defer wg.Done() 101 102 li := statemgr.NewLockInfo() 103 li.Operation = "test" 104 li.Who = fmt.Sprintf("client-%v", n) 105 106 for i := 0; i < lockAttempts; i++ { 107 id, err := locker.Lock(li) 108 if err != nil { 109 continue 110 } 111 112 // hold onto the lock for a little bit 113 time.Sleep(time.Duration(rand.Intn(10)) * time.Microsecond) 114 115 err = locker.Unlock(id) 116 if err != nil { 117 t.Errorf("failed to unlock: %v", err) 118 } 119 } 120 }(l, i) 121 } 122 123 wg.Wait() 124 } 125 126 func cleanupK8sResources(t *testing.T) { 127 // Get a backend to use the k8s client 128 b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{ 129 "secret_suffix": secretSuffix, 130 })) 131 132 b := b1.(*Backend) 133 134 sClient, err := b.KubernetesSecretClient() 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 // Delete secrets 140 opts := metav1.ListOptions{LabelSelector: tfstateKey + "=true"} 141 secrets, err := sClient.List(opts) 142 if err != nil { 143 t.Fatal(err) 144 } 145 146 delProp := metav1.DeletePropagationBackground 147 delOps := &metav1.DeleteOptions{PropagationPolicy: &delProp} 148 var errs []error 149 150 for _, secret := range secrets.Items { 151 labels := secret.GetLabels() 152 key, ok := labels[tfstateSecretSuffixKey] 153 if !ok { 154 continue 155 } 156 157 if key == secretSuffix { 158 err = sClient.Delete(secret.GetName(), delOps) 159 if err != nil { 160 errs = append(errs, err) 161 } 162 } 163 } 164 165 leaseClient, err := b.KubernetesLeaseClient() 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 // Delete leases 171 leases, err := leaseClient.List(opts) 172 if err != nil { 173 t.Fatal(err) 174 } 175 176 for _, lease := range leases.Items { 177 labels := lease.GetLabels() 178 key, ok := labels[tfstateSecretSuffixKey] 179 if !ok { 180 continue 181 } 182 183 if key == secretSuffix { 184 err = leaseClient.Delete(lease.GetName(), delOps) 185 if err != nil { 186 errs = append(errs, err) 187 } 188 } 189 } 190 191 if len(errs) > 0 { 192 t.Fatal(errs) 193 } 194 }