github.com/lfch/etcd-io/tests/v3@v3.0.0-20221004140520-eac99acd3e9d/integration/v3lock_grpc_test.go (about)

     1  // Copyright 2017 The etcd Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package integration
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	pb "github.com/lfch/etcd-io/api/v3/etcdserverpb"
    23  	lockpb "github.com/lfch/etcd-io/server/v3/etcdserver/api/v3lock/v3lockpb"
    24  	"github.com/lfch/etcd-io/tests/v3/framework/integration"
    25  )
    26  
    27  // TestV3LockLockWaiter tests that a client will wait for a lock, then acquire it
    28  // once it is unlocked.
    29  func TestV3LockLockWaiter(t *testing.T) {
    30  	integration.BeforeTest(t)
    31  	clus := integration.NewCluster(t, &integration.ClusterConfig{Size: 1})
    32  	defer clus.Terminate(t)
    33  
    34  	lease1, err1 := integration.ToGRPC(clus.RandClient()).Lease.LeaseGrant(context.TODO(), &pb.LeaseGrantRequest{TTL: 30})
    35  	if err1 != nil {
    36  		t.Fatal(err1)
    37  	}
    38  	lease2, err2 := integration.ToGRPC(clus.RandClient()).Lease.LeaseGrant(context.TODO(), &pb.LeaseGrantRequest{TTL: 30})
    39  	if err2 != nil {
    40  		t.Fatal(err2)
    41  	}
    42  
    43  	lc := integration.ToGRPC(clus.Client(0)).Lock
    44  	l1, lerr1 := lc.Lock(context.TODO(), &lockpb.LockRequest{Name: []byte("foo"), Lease: lease1.ID})
    45  	if lerr1 != nil {
    46  		t.Fatal(lerr1)
    47  	}
    48  
    49  	lockc := make(chan struct{})
    50  	go func() {
    51  		l2, lerr2 := lc.Lock(context.TODO(), &lockpb.LockRequest{Name: []byte("foo"), Lease: lease2.ID})
    52  		if lerr2 != nil {
    53  			t.Error(lerr2)
    54  		}
    55  		if l1.Header.Revision >= l2.Header.Revision {
    56  			t.Errorf("expected l1 revision < l2 revision, got %d >= %d", l1.Header.Revision, l2.Header.Revision)
    57  		}
    58  		close(lockc)
    59  	}()
    60  
    61  	select {
    62  	case <-time.After(200 * time.Millisecond):
    63  	case <-lockc:
    64  		t.Fatalf("locked before unlock")
    65  	}
    66  
    67  	if _, uerr := lc.Unlock(context.TODO(), &lockpb.UnlockRequest{Key: l1.Key}); uerr != nil {
    68  		t.Fatal(uerr)
    69  	}
    70  
    71  	select {
    72  	case <-time.After(200 * time.Millisecond):
    73  		t.Fatalf("waiter did not lock after unlock")
    74  	case <-lockc:
    75  	}
    76  }