lease_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // Copyright 2016 CoreOS, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package integration
  15. import (
  16. "testing"
  17. "time"
  18. "github.com/coreos/etcd/clientv3"
  19. "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
  20. "github.com/coreos/etcd/integration"
  21. "github.com/coreos/etcd/pkg/testutil"
  22. "golang.org/x/net/context"
  23. "google.golang.org/grpc"
  24. "google.golang.org/grpc/codes"
  25. )
  26. func TestLeastNotFoundError(t *testing.T) {
  27. defer testutil.AfterTest(t)
  28. clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
  29. defer clus.Terminate(t)
  30. lapi := clientv3.NewLease(clus.RandClient())
  31. defer lapi.Close()
  32. kv := clientv3.NewKV(clus.RandClient())
  33. _, err := kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(500)))
  34. if err != rpctypes.ErrLeaseNotFound {
  35. t.Fatalf("expected %v, got %v", rpctypes.ErrLeaseNotFound, err)
  36. }
  37. }
  38. func TestLeaseGrant(t *testing.T) {
  39. defer testutil.AfterTest(t)
  40. clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
  41. defer clus.Terminate(t)
  42. lapi := clientv3.NewLease(clus.RandClient())
  43. defer lapi.Close()
  44. kv := clientv3.NewKV(clus.RandClient())
  45. resp, err := lapi.Grant(context.Background(), 10)
  46. if err != nil {
  47. t.Errorf("failed to create lease %v", err)
  48. }
  49. _, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(resp.ID))
  50. if err != nil {
  51. t.Fatalf("failed to create key with lease %v", err)
  52. }
  53. }
  54. func TestLeaseRevoke(t *testing.T) {
  55. defer testutil.AfterTest(t)
  56. clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
  57. defer clus.Terminate(t)
  58. lapi := clientv3.NewLease(clus.RandClient())
  59. defer lapi.Close()
  60. kv := clientv3.NewKV(clus.RandClient())
  61. resp, err := lapi.Grant(context.Background(), 10)
  62. if err != nil {
  63. t.Errorf("failed to create lease %v", err)
  64. }
  65. _, err = lapi.Revoke(context.Background(), clientv3.LeaseID(resp.ID))
  66. if err != nil {
  67. t.Errorf("failed to revoke lease %v", err)
  68. }
  69. _, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(resp.ID))
  70. if err != rpctypes.ErrLeaseNotFound {
  71. t.Fatalf("err = %v, want %v", err, rpctypes.ErrLeaseNotFound)
  72. }
  73. }
  74. func TestLeaseKeepAliveOnce(t *testing.T) {
  75. defer testutil.AfterTest(t)
  76. clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
  77. defer clus.Terminate(t)
  78. lapi := clientv3.NewLease(clus.RandClient())
  79. defer lapi.Close()
  80. resp, err := lapi.Grant(context.Background(), 10)
  81. if err != nil {
  82. t.Errorf("failed to create lease %v", err)
  83. }
  84. _, err = lapi.KeepAliveOnce(context.Background(), resp.ID)
  85. if err != nil {
  86. t.Errorf("failed to keepalive lease %v", err)
  87. }
  88. _, err = lapi.KeepAliveOnce(context.Background(), clientv3.LeaseID(0))
  89. if grpc.Code(err) != codes.NotFound {
  90. t.Errorf("invalid error returned %v", err)
  91. }
  92. }
  93. func TestLeaseKeepAlive(t *testing.T) {
  94. defer testutil.AfterTest(t)
  95. clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
  96. defer clus.Terminate(t)
  97. lapi := clientv3.NewLease(clus.RandClient())
  98. resp, err := lapi.Grant(context.Background(), 10)
  99. if err != nil {
  100. t.Errorf("failed to create lease %v", err)
  101. }
  102. rc, kerr := lapi.KeepAlive(context.Background(), resp.ID)
  103. if kerr != nil {
  104. t.Errorf("failed to keepalive lease %v", kerr)
  105. }
  106. kresp, ok := <-rc
  107. if !ok {
  108. t.Errorf("chan is closed, want not closed")
  109. }
  110. if kresp.ID != resp.ID {
  111. t.Errorf("ID = %x, want %x", kresp.ID, resp.ID)
  112. }
  113. lapi.Close()
  114. _, ok = <-rc
  115. if ok {
  116. t.Errorf("chan is not closed, want lease Close() closes chan")
  117. }
  118. }
  119. // TODO: add a client that can connect to all the members of cluster via unix sock.
  120. // TODO: test handle more complicated failures.
  121. func TestLeaseKeepAliveHandleFailure(t *testing.T) {
  122. t.Skip("test it when we have a cluster client")
  123. defer testutil.AfterTest(t)
  124. clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
  125. defer clus.Terminate(t)
  126. // TODO: change this line to get a cluster client
  127. lapi := clientv3.NewLease(clus.RandClient())
  128. resp, err := lapi.Grant(context.Background(), 10)
  129. if err != nil {
  130. t.Errorf("failed to create lease %v", err)
  131. }
  132. rc, kerr := lapi.KeepAlive(context.Background(), resp.ID)
  133. if kerr != nil {
  134. t.Errorf("failed to keepalive lease %v", kerr)
  135. }
  136. kresp := <-rc
  137. if kresp.ID != resp.ID {
  138. t.Errorf("ID = %x, want %x", kresp.ID, resp.ID)
  139. }
  140. // restart the connected member.
  141. clus.Members[0].Stop(t)
  142. select {
  143. case <-rc:
  144. t.Fatalf("unexpected keepalive")
  145. case <-time.After(10*time.Second/3 + 1):
  146. }
  147. // recover the member.
  148. clus.Members[0].Restart(t)
  149. kresp = <-rc
  150. if kresp.ID != resp.ID {
  151. t.Errorf("ID = %x, want %x", kresp.ID, resp.ID)
  152. }
  153. lapi.Close()
  154. _, ok := <-rc
  155. if ok {
  156. t.Errorf("chan is not closed, want lease Close() closes chan")
  157. }
  158. }
  159. type leaseCh struct {
  160. lid clientv3.LeaseID
  161. ch <-chan *clientv3.LeaseKeepAliveResponse
  162. }
  163. // TestLeaseKeepAliveNotFound ensures a revoked lease won't stop other keep alives
  164. func TestLeaseKeepAliveNotFound(t *testing.T) {
  165. defer testutil.AfterTest(t)
  166. clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
  167. defer clus.Terminate(t)
  168. cli := clus.RandClient()
  169. lchs := []leaseCh{}
  170. for i := 0; i < 3; i++ {
  171. resp, rerr := cli.Grant(context.TODO(), 5)
  172. if rerr != nil {
  173. t.Fatal(rerr)
  174. }
  175. kach, kaerr := cli.KeepAlive(context.Background(), resp.ID)
  176. if kaerr != nil {
  177. t.Fatal(kaerr)
  178. }
  179. lchs = append(lchs, leaseCh{resp.ID, kach})
  180. }
  181. if _, err := cli.Revoke(context.TODO(), lchs[1].lid); err != nil {
  182. t.Fatal(err)
  183. }
  184. <-lchs[0].ch
  185. if _, ok := <-lchs[0].ch; !ok {
  186. t.Fatalf("closed keepalive on wrong lease")
  187. }
  188. timec := time.After(5 * time.Second)
  189. for range lchs[1].ch {
  190. select {
  191. case <-timec:
  192. t.Fatalf("revoke did not close keep alive")
  193. default:
  194. }
  195. }
  196. }