github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/lock/etcdlock/mutex_test.go (about) 1 package etcdlock 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/projecteru2/core/store/etcdv3/embedded" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestMutex(t *testing.T) { 14 embedd := embedded.NewCluster(t, "/test") 15 cli := embedd.RandClient() 16 17 _, err := New(cli, "", time.Second*1) 18 assert.Error(t, err) 19 mutex, err := New(cli, "test", time.Second*1) 20 assert.NoError(t, err) 21 22 ctx := context.Background() 23 ctx, err = mutex.Lock(ctx) 24 assert.Nil(t, ctx.Err()) 25 assert.NoError(t, err) 26 err = mutex.Unlock(ctx) 27 assert.NoError(t, err) 28 assert.NoError(t, ctx.Err()) 29 30 // round 2: another lock attempt timeout 31 32 m2, err := New(cli, "test", time.Second) 33 assert.NoError(t, err) 34 _, err = m2.Lock(context.Background()) 35 m3, err := New(cli, "test", 100*time.Millisecond) 36 assert.NoError(t, err) 37 _, err = m3.Lock(context.Background()) 38 assert.EqualError(t, err, "context deadline exceeded") 39 m2.Unlock(context.Background()) 40 m3.Unlock(context.Background()) 41 42 // round 3: ctx canceled after lock secured 43 m4, err := New(cli, "test", time.Second) 44 assert.NoError(t, err) 45 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 46 defer cancel() 47 rCtx, err := m4.Lock(ctx) 48 <-rCtx.Done() 49 assert.EqualError(t, rCtx.Err(), "context deadline exceeded") 50 m4.Unlock(context.Background()) 51 52 // round 4: passive release 53 54 m5, err := New(cli, "test", time.Second) 55 assert.NoError(t, err) 56 _, err = m5.Lock(context.Background()) 57 assert.NoError(t, err) 58 // then after embedded ETCD close, m5 will be unlocked from passive branch 59 } 60 61 func TestTryLock(t *testing.T) { 62 embedd := embedded.NewCluster(t, "/test") 63 cli := embedd.RandClient() 64 65 m1, err := New(cli, "test", time.Second*1) 66 assert.NoError(t, err) 67 m2, err := New(cli, "test", time.Second*1) 68 assert.NoError(t, err) 69 70 ctx1, err := m1.Lock(context.Background()) 71 assert.Nil(t, ctx1.Err()) 72 assert.NoError(t, err) 73 74 ctx2, err := m2.TryLock(context.Background()) 75 assert.Nil(t, ctx2) 76 assert.Error(t, err) 77 78 assert.NoError(t, m1.Unlock(context.Background())) 79 assert.NoError(t, m2.Unlock(context.Background())) 80 81 // round 2: lock conflict 82 83 m3, err := New(cli, "test", time.Second) 84 assert.NoError(t, err) 85 m4, err := New(cli, "test", time.Second) 86 assert.NoError(t, err) 87 88 rCtx, err := m3.TryLock(context.Background()) 89 assert.NoError(t, err) 90 _, err = m4.TryLock(context.Background()) 91 assert.EqualError(t, err, "mutex: Locked by another session") 92 m4.Unlock(context.Background()) 93 m3.Unlock(context.Background()) 94 assert.NoError(t, rCtx.Err()) 95 96 // round 3: ctx canceled after lock secured 97 m5, err := New(cli, "test", time.Second) 98 assert.NoError(t, err) 99 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 100 defer cancel() 101 rCtx, err = m5.TryLock(ctx) 102 <-rCtx.Done() 103 assert.EqualError(t, rCtx.Err(), "context deadline exceeded") 104 m5.Unlock(context.Background()) 105 106 // round 4: passive release 107 108 m6, err := New(cli, "test", time.Second) 109 assert.NoError(t, err) 110 _, err = m6.TryLock(context.Background()) 111 assert.NoError(t, err) 112 // then after embedded ETCD close, m5 will be unlocked from passive branch 113 }