mod_lock_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. waiting := true
  45. go func() {
  46. c <- true
  47. body, err := testAcquireLock(s, "foo", "", 10)
  48. assert.NoError(t, err)
  49. assert.Equal(t, body, "4")
  50. waiting = false
  51. }()
  52. <- c
  53. time.Sleep(1 * time.Second)
  54. // Check that we have the lock #1.
  55. body, err := testGetLockIndex(s, "foo")
  56. assert.NoError(t, err)
  57. assert.Equal(t, body, "2")
  58. // Check that we are still waiting for lock #2.
  59. assert.Equal(t, waiting, true)
  60. // Release lock #1.
  61. body, err = testReleaseLock(s, "foo", "2", "")
  62. assert.NoError(t, err)
  63. // Check that we have lock #2.
  64. body, err = testGetLockIndex(s, "foo")
  65. assert.NoError(t, err)
  66. assert.Equal(t, body, "4")
  67. // Release lock #2.
  68. body, err = testReleaseLock(s, "foo", "4", "")
  69. assert.NoError(t, err)
  70. // Check that we have no lock.
  71. body, err = testGetLockIndex(s, "foo")
  72. assert.NoError(t, err)
  73. assert.Equal(t, body, "")
  74. })
  75. }
  76. // Ensure that a lock will be released after the TTL.
  77. func TestModLockExpireAndRelease(t *testing.T) {
  78. tests.RunServer(func(s *server.Server) {
  79. c := make(chan bool)
  80. // Acquire lock #1.
  81. go func() {
  82. body, err := testAcquireLock(s, "foo", "", 2)
  83. assert.NoError(t, err)
  84. assert.Equal(t, body, "2")
  85. c <- true
  86. }()
  87. <- c
  88. // Acquire lock #2.
  89. go func() {
  90. c <- true
  91. body, err := testAcquireLock(s, "foo", "", 10)
  92. assert.NoError(t, err)
  93. assert.Equal(t, body, "4")
  94. }()
  95. <- c
  96. time.Sleep(1 * time.Second)
  97. // Check that we have the lock #1.
  98. body, err := testGetLockIndex(s, "foo")
  99. assert.NoError(t, err)
  100. assert.Equal(t, body, "2")
  101. // Wait for lock #1 TTL.
  102. time.Sleep(2 * time.Second)
  103. // Check that we have lock #2.
  104. body, err = testGetLockIndex(s, "foo")
  105. assert.NoError(t, err)
  106. assert.Equal(t, body, "4")
  107. })
  108. }
  109. // Ensure that a lock can be renewed.
  110. func TestModLockRenew(t *testing.T) {
  111. tests.RunServer(func(s *server.Server) {
  112. // Acquire lock.
  113. body, err := testAcquireLock(s, "foo", "", 3)
  114. assert.NoError(t, err)
  115. assert.Equal(t, body, "2")
  116. time.Sleep(2 * time.Second)
  117. // Check that we have the lock.
  118. body, err = testGetLockIndex(s, "foo")
  119. assert.NoError(t, err)
  120. assert.Equal(t, body, "2")
  121. // Renew lock.
  122. body, err = testRenewLock(s, "foo", "2", "", 3)
  123. assert.NoError(t, err)
  124. assert.Equal(t, body, "")
  125. time.Sleep(2 * time.Second)
  126. // Check that we still have the lock.
  127. body, err = testGetLockIndex(s, "foo")
  128. assert.NoError(t, err)
  129. assert.Equal(t, body, "2")
  130. time.Sleep(2 * time.Second)
  131. // Check that lock was released.
  132. body, err = testGetLockIndex(s, "foo")
  133. assert.NoError(t, err)
  134. assert.Equal(t, body, "")
  135. })
  136. }
  137. // Ensure that a lock can be acquired with a value and released by value.
  138. func TestModLockAcquireAndReleaseByValue(t *testing.T) {
  139. tests.RunServer(func(s *server.Server) {
  140. // Acquire lock.
  141. body, err := testAcquireLock(s, "foo", "XXX", 10)
  142. assert.NoError(t, err)
  143. assert.Equal(t, body, "2")
  144. // Check that we have the lock.
  145. body, err = testGetLockValue(s, "foo")
  146. assert.NoError(t, err)
  147. assert.Equal(t, body, "XXX")
  148. // Release lock.
  149. body, err = testReleaseLock(s, "foo", "", "XXX")
  150. assert.NoError(t, err)
  151. assert.Equal(t, body, "")
  152. // Check that we released the lock.
  153. body, err = testGetLockValue(s, "foo")
  154. assert.NoError(t, err)
  155. assert.Equal(t, body, "")
  156. })
  157. }
  158. func testAcquireLock(s *server.Server, key string, value string, ttl int) (string, error) {
  159. resp, err := tests.PostForm(fmt.Sprintf("%s/mod/v2/lock/%s?value=%s&ttl=%d", s.URL(), key, value, ttl), nil)
  160. ret := tests.ReadBody(resp)
  161. return string(ret), err
  162. }
  163. func testGetLockIndex(s *server.Server, key string) (string, error) {
  164. resp, err := tests.Get(fmt.Sprintf("%s/mod/v2/lock/%s?field=index", s.URL(), key))
  165. ret := tests.ReadBody(resp)
  166. return string(ret), err
  167. }
  168. func testGetLockValue(s *server.Server, key string) (string, error) {
  169. resp, err := tests.Get(fmt.Sprintf("%s/mod/v2/lock/%s", s.URL(), key))
  170. ret := tests.ReadBody(resp)
  171. return string(ret), err
  172. }
  173. func testReleaseLock(s *server.Server, key string, index string, value string) (string, error) {
  174. resp, err := tests.DeleteForm(fmt.Sprintf("%s/mod/v2/lock/%s?index=%s&value=%s", s.URL(), key, index, value), nil)
  175. ret := tests.ReadBody(resp)
  176. return string(ret), err
  177. }
  178. func testRenewLock(s *server.Server, key string, index string, value string, ttl int) (string, error) {
  179. resp, err := tests.PutForm(fmt.Sprintf("%s/mod/v2/lock/%s?index=%s&value=%s&ttl=%d", s.URL(), key, index, value, ttl), nil)
  180. ret := tests.ReadBody(resp)
  181. return string(ret), err
  182. }