github.com/macb/etcd@v0.3.1-0.20140227003422-a60481c6b1a0/mod/lock/v2/tests/mod_lock_test.go (about) 1 package lock 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/coreos/etcd/server" 9 "github.com/coreos/etcd/tests" 10 "github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert" 11 ) 12 13 // Ensure that a lock can be acquired and released. 14 func TestModLockAcquireAndRelease(t *testing.T) { 15 tests.RunServer(func(s *server.Server) { 16 // Acquire lock. 17 body, status, err := testAcquireLock(s, "foo", "", 10) 18 assert.NoError(t, err) 19 assert.Equal(t, status, 200) 20 assert.Equal(t, body, "2") 21 22 // Check that we have the lock. 23 body, status, err = testGetLockIndex(s, "foo") 24 assert.NoError(t, err) 25 assert.Equal(t, status, 200) 26 assert.Equal(t, body, "2") 27 28 // Release lock. 29 body, status, err = testReleaseLock(s, "foo", "2", "") 30 assert.NoError(t, err) 31 assert.Equal(t, status, 200) 32 assert.Equal(t, body, "") 33 34 // Check that we have the lock. 35 body, status, err = testGetLockIndex(s, "foo") 36 assert.NoError(t, err) 37 assert.Equal(t, status, 200) 38 assert.Equal(t, body, "") 39 }) 40 } 41 42 // Ensure that a lock can be acquired and another process is blocked until released. 43 func TestModLockBlockUntilAcquire(t *testing.T) { 44 tests.RunServer(func(s *server.Server) { 45 c := make(chan bool) 46 47 // Acquire lock #1. 48 go func() { 49 body, status, err := testAcquireLock(s, "foo", "", 10) 50 assert.NoError(t, err) 51 assert.Equal(t, status, 200) 52 assert.Equal(t, body, "2") 53 c <- true 54 }() 55 <-c 56 57 // Acquire lock #2. 58 waiting := true 59 go func() { 60 c <- true 61 body, status, err := testAcquireLock(s, "foo", "", 10) 62 assert.NoError(t, err) 63 assert.Equal(t, status, 200) 64 assert.Equal(t, body, "4") 65 waiting = false 66 }() 67 <-c 68 69 time.Sleep(1 * time.Second) 70 71 // Check that we have the lock #1. 72 body, status, err := testGetLockIndex(s, "foo") 73 assert.NoError(t, err) 74 assert.Equal(t, status, 200) 75 assert.Equal(t, body, "2") 76 77 // Check that we are still waiting for lock #2. 78 assert.Equal(t, waiting, true) 79 80 // Release lock #1. 81 _, status, err = testReleaseLock(s, "foo", "2", "") 82 assert.NoError(t, err) 83 assert.Equal(t, status, 200) 84 85 // Check that we have lock #2. 86 body, status, err = testGetLockIndex(s, "foo") 87 assert.NoError(t, err) 88 assert.Equal(t, status, 200) 89 assert.Equal(t, body, "4") 90 91 // Release lock #2. 92 _, status, err = testReleaseLock(s, "foo", "4", "") 93 assert.NoError(t, err) 94 assert.Equal(t, status, 200) 95 96 // Check that we have no lock. 97 body, status, err = testGetLockIndex(s, "foo") 98 assert.NoError(t, err) 99 assert.Equal(t, status, 200) 100 assert.Equal(t, body, "") 101 }) 102 } 103 104 // Ensure that a lock will be released after the TTL. 105 func TestModLockExpireAndRelease(t *testing.T) { 106 tests.RunServer(func(s *server.Server) { 107 c := make(chan bool) 108 109 // Acquire lock #1. 110 go func() { 111 body, status, err := testAcquireLock(s, "foo", "", 2) 112 assert.NoError(t, err) 113 assert.Equal(t, status, 200) 114 assert.Equal(t, body, "2") 115 c <- true 116 }() 117 <-c 118 119 // Acquire lock #2. 120 go func() { 121 c <- true 122 body, status, err := testAcquireLock(s, "foo", "", 10) 123 assert.NoError(t, err) 124 assert.Equal(t, status, 200) 125 assert.Equal(t, body, "4") 126 }() 127 <-c 128 129 time.Sleep(1 * time.Second) 130 131 // Check that we have the lock #1. 132 body, status, err := testGetLockIndex(s, "foo") 133 assert.NoError(t, err) 134 assert.Equal(t, status, 200) 135 assert.Equal(t, body, "2") 136 137 // Wait for lock #1 TTL. 138 time.Sleep(2 * time.Second) 139 140 // Check that we have lock #2. 141 body, status, err = testGetLockIndex(s, "foo") 142 assert.NoError(t, err) 143 assert.Equal(t, status, 200) 144 assert.Equal(t, body, "4") 145 }) 146 } 147 148 // Ensure that a lock can be renewed. 149 func TestModLockRenew(t *testing.T) { 150 tests.RunServer(func(s *server.Server) { 151 // Acquire lock. 152 body, status, err := testAcquireLock(s, "foo", "", 3) 153 assert.NoError(t, err) 154 assert.Equal(t, status, 200) 155 assert.Equal(t, body, "2") 156 157 time.Sleep(2 * time.Second) 158 159 // Check that we have the lock. 160 body, status, err = testGetLockIndex(s, "foo") 161 assert.NoError(t, err) 162 assert.Equal(t, status, 200) 163 assert.Equal(t, body, "2") 164 165 // Renew lock. 166 body, status, err = testRenewLock(s, "foo", "2", "", 3) 167 assert.NoError(t, err) 168 assert.Equal(t, status, 200) 169 assert.Equal(t, body, "") 170 171 time.Sleep(2 * time.Second) 172 173 // Check that we still have the lock. 174 body, status, err = testGetLockIndex(s, "foo") 175 assert.NoError(t, err) 176 assert.Equal(t, status, 200) 177 assert.Equal(t, body, "2") 178 179 time.Sleep(2 * time.Second) 180 181 // Check that lock was released. 182 body, status, err = testGetLockIndex(s, "foo") 183 assert.NoError(t, err) 184 assert.Equal(t, status, 200) 185 assert.Equal(t, body, "") 186 }) 187 } 188 189 // Ensure that a lock can be acquired with a value and released by value. 190 func TestModLockAcquireAndReleaseByValue(t *testing.T) { 191 tests.RunServer(func(s *server.Server) { 192 // Acquire lock. 193 body, status, err := testAcquireLock(s, "foo", "XXX", 10) 194 assert.NoError(t, err) 195 assert.Equal(t, status, 200) 196 assert.Equal(t, body, "2") 197 198 // Check that we have the lock. 199 body, status, err = testGetLockValue(s, "foo") 200 assert.NoError(t, err) 201 assert.Equal(t, status, 200) 202 assert.Equal(t, body, "XXX") 203 204 // Release lock. 205 body, status, err = testReleaseLock(s, "foo", "", "XXX") 206 assert.NoError(t, err) 207 assert.Equal(t, status, 200) 208 assert.Equal(t, body, "") 209 210 // Check that we released the lock. 211 body, status, err = testGetLockValue(s, "foo") 212 assert.NoError(t, err) 213 assert.Equal(t, status, 200) 214 assert.Equal(t, body, "") 215 }) 216 } 217 218 func testAcquireLock(s *server.Server, key string, value string, ttl int) (string, int, error) { 219 resp, err := tests.PostForm(fmt.Sprintf("%s/mod/v2/lock/%s?value=%s&ttl=%d", s.URL(), key, value, ttl), nil) 220 ret := tests.ReadBody(resp) 221 return string(ret), resp.StatusCode, err 222 } 223 224 func testGetLockIndex(s *server.Server, key string) (string, int, error) { 225 resp, err := tests.Get(fmt.Sprintf("%s/mod/v2/lock/%s?field=index", s.URL(), key)) 226 ret := tests.ReadBody(resp) 227 return string(ret), resp.StatusCode, err 228 } 229 230 func testGetLockValue(s *server.Server, key string) (string, int, error) { 231 resp, err := tests.Get(fmt.Sprintf("%s/mod/v2/lock/%s", s.URL(), key)) 232 ret := tests.ReadBody(resp) 233 return string(ret), resp.StatusCode, err 234 } 235 236 func testReleaseLock(s *server.Server, key string, index string, value string) (string, int, error) { 237 resp, err := tests.DeleteForm(fmt.Sprintf("%s/mod/v2/lock/%s?index=%s&value=%s", s.URL(), key, index, value), nil) 238 ret := tests.ReadBody(resp) 239 return string(ret), resp.StatusCode, err 240 } 241 242 func testRenewLock(s *server.Server, key string, index string, value string, ttl int) (string, int, error) { 243 resp, err := tests.PutForm(fmt.Sprintf("%s/mod/v2/lock/%s?index=%s&value=%s&ttl=%d", s.URL(), key, index, value, ttl), nil) 244 ret := tests.ReadBody(resp) 245 return string(ret), resp.StatusCode, err 246 }