handler_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package lock
  2. import (
  3. "fmt"
  4. "testing"
  5. "time"
  6. "github.com/coreos/etcd/server"
  7. "github.com/coreos/etcd/tests"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. // Ensure that a lock can be acquired and released.
  11. func TestModLockAcquireAndRelease(t *testing.T) {
  12. tests.RunServer(func(s *server.Server) {
  13. // Acquire lock.
  14. body, err := testAcquireLock(s, "foo", 10)
  15. assert.NoError(t, err)
  16. assert.Equal(t, body, "2")
  17. // Check that we have the lock.
  18. body, err = testGetLockIndex(s, "foo")
  19. assert.NoError(t, err)
  20. assert.Equal(t, body, "2")
  21. // Release lock.
  22. body, err = testReleaseLock(s, "foo", 2)
  23. assert.NoError(t, err)
  24. assert.Equal(t, body, "")
  25. // Check that we have the lock.
  26. body, err = testGetLockIndex(s, "foo")
  27. assert.NoError(t, err)
  28. assert.Equal(t, body, "")
  29. })
  30. }
  31. // Ensure that a lock can be acquired and another process is blocked until released.
  32. func TestModLockBlockUntilAcquire(t *testing.T) {
  33. tests.RunServer(func(s *server.Server) {
  34. c := make(chan bool)
  35. // Acquire lock #1.
  36. go func() {
  37. body, err := testAcquireLock(s, "foo", 10)
  38. assert.NoError(t, err)
  39. assert.Equal(t, body, "2")
  40. c <- true
  41. }()
  42. <- c
  43. // Acquire lock #2.
  44. go func() {
  45. c <- true
  46. body, err := testAcquireLock(s, "foo", 10)
  47. assert.NoError(t, err)
  48. assert.Equal(t, body, "4")
  49. }()
  50. <- c
  51. time.Sleep(1 * time.Second)
  52. // Check that we have the lock #1.
  53. body, err := testGetLockIndex(s, "foo")
  54. assert.NoError(t, err)
  55. assert.Equal(t, body, "2")
  56. // Release lock #1.
  57. body, err = testReleaseLock(s, "foo", 2)
  58. assert.NoError(t, err)
  59. // Check that we have lock #2.
  60. body, err = testGetLockIndex(s, "foo")
  61. assert.NoError(t, err)
  62. assert.Equal(t, body, "4")
  63. // Release lock #2.
  64. body, err = testReleaseLock(s, "foo", 4)
  65. assert.NoError(t, err)
  66. // Check that we have no lock.
  67. body, err = testGetLockIndex(s, "foo")
  68. assert.NoError(t, err)
  69. assert.Equal(t, body, "")
  70. })
  71. }
  72. // Ensure that a lock will be released after the TTL.
  73. func TestModLockExpireAndRelease(t *testing.T) {
  74. tests.RunServer(func(s *server.Server) {
  75. c := make(chan bool)
  76. // Acquire lock #1.
  77. go func() {
  78. body, err := testAcquireLock(s, "foo", 2)
  79. assert.NoError(t, err)
  80. assert.Equal(t, body, "2")
  81. c <- true
  82. }()
  83. <- c
  84. // Acquire lock #2.
  85. go func() {
  86. c <- true
  87. body, err := testAcquireLock(s, "foo", 10)
  88. assert.NoError(t, err)
  89. assert.Equal(t, body, "4")
  90. }()
  91. <- c
  92. time.Sleep(1 * time.Second)
  93. // Check that we have the lock #1.
  94. body, err := testGetLockIndex(s, "foo")
  95. assert.NoError(t, err)
  96. assert.Equal(t, body, "2")
  97. // Wait for lock #1 TTL.
  98. time.Sleep(2 * time.Second)
  99. // Check that we have lock #2.
  100. body, err = testGetLockIndex(s, "foo")
  101. assert.NoError(t, err)
  102. assert.Equal(t, body, "4")
  103. })
  104. }
  105. // Ensure that a lock can be renewed.
  106. func TestModLockRenew(t *testing.T) {
  107. tests.RunServer(func(s *server.Server) {
  108. // Acquire lock.
  109. body, err := testAcquireLock(s, "foo", 3)
  110. assert.NoError(t, err)
  111. assert.Equal(t, body, "2")
  112. time.Sleep(2 * time.Second)
  113. // Check that we have the lock.
  114. body, err = testGetLockIndex(s, "foo")
  115. assert.NoError(t, err)
  116. assert.Equal(t, body, "2")
  117. // Renew lock.
  118. body, err = testRenewLock(s, "foo", 2, 3)
  119. assert.NoError(t, err)
  120. assert.Equal(t, body, "")
  121. time.Sleep(2 * time.Second)
  122. // Check that we still have the lock.
  123. body, err = testGetLockIndex(s, "foo")
  124. assert.NoError(t, err)
  125. assert.Equal(t, body, "2")
  126. time.Sleep(2 * time.Second)
  127. // Check that lock was released.
  128. body, err = testGetLockIndex(s, "foo")
  129. assert.NoError(t, err)
  130. assert.Equal(t, body, "")
  131. })
  132. }
  133. func testAcquireLock(s *server.Server, key string, ttl int) (string, error) {
  134. resp, err := tests.PostForm(fmt.Sprintf("%s/mod/v2/lock/%s?ttl=%d", s.URL(), key, ttl), nil)
  135. ret := tests.ReadBody(resp)
  136. return string(ret), err
  137. }
  138. func testGetLockIndex(s *server.Server, key string) (string, error) {
  139. resp, err := tests.Get(fmt.Sprintf("%s/mod/v2/lock/%s", s.URL(), key))
  140. ret := tests.ReadBody(resp)
  141. return string(ret), err
  142. }
  143. func testReleaseLock(s *server.Server, key string, index int) (string, error) {
  144. resp, err := tests.DeleteForm(fmt.Sprintf("%s/mod/v2/lock/%s/%d", s.URL(), key, index), nil)
  145. ret := tests.ReadBody(resp)
  146. return string(ret), err
  147. }
  148. func testRenewLock(s *server.Server, key string, index int, ttl int) (string, error) {
  149. resp, err := tests.PutForm(fmt.Sprintf("%s/mod/v2/lock/%s/%d?ttl=%d", s.URL(), key, index, ttl), nil)
  150. ret := tests.ReadBody(resp)
  151. return string(ret), err
  152. }