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