github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/retryrpc/upcall_test.go (about) 1 // Copyright (c) 2015-2021, NVIDIA CORPORATION. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package retryrpc 5 6 import ( 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/swiftstack/ProxyFS/retryrpc/rpctest" 13 ) 14 15 // Test Upcall() functionality 16 func TestUpCall(t *testing.T) { 17 testUpCall(t) 18 } 19 20 type MyClient struct { 21 sync.Mutex 22 cond *sync.Cond // Signal that received Interrupt() callback 23 sawCallback bool // True if Interrupt() was called 24 } 25 26 func (cb *MyClient) Interrupt(payload []byte) { 27 cb.Lock() 28 cb.sawCallback = true 29 cb.cond.Broadcast() 30 cb.Unlock() 31 return 32 } 33 34 // Test getting an upcallbasic Server creation and deletion 35 func testUpCall(t *testing.T) { 36 var myUniqueClientID string = "my upcall client 1" 37 38 assert := assert.New(t) 39 zero := 0 40 assert.Equal(0, zero) 41 42 // Create new rpctest server - needed for calling 43 // RPCs 44 myJrpcfs := rpctest.NewServer() 45 46 rrSvr, ipaddr, port := getNewServer(10*time.Second, false) 47 assert.NotNil(rrSvr) 48 49 // Register the Server - sets up the methods supported by the 50 // server 51 err := rrSvr.Register(myJrpcfs) 52 assert.Nil(err) 53 54 // Start listening for requests on the ipaddr/port 55 startErr := rrSvr.Start() 56 assert.Nil(startErr, "startErr is not nil") 57 58 // Tell server to start accepting and processing requests 59 rrSvr.Run() 60 61 // Now - setup a client to send requests to the server 62 cb := &MyClient{} 63 cb.cond = sync.NewCond(&cb.Mutex) 64 65 clientConfig := &ClientConfig{MyUniqueID: myUniqueClientID, IPAddr: ipaddr, Port: port, 66 RootCAx509CertificatePEM: rrSvr.Creds.RootCAx509CertificatePEM, Callbacks: cb, 67 DeadlineIO: 5 * time.Second} 68 rrClnt, newErr := NewClient(clientConfig) 69 assert.NotNil(rrClnt) 70 assert.Nil(newErr) 71 72 // Send an RPC which should return success 73 pingRequest := &rpctest.PingReq{Message: "Ping Me!"} 74 pingReply := &rpctest.PingReply{} 75 sendErr := rrClnt.Send("RpcPing", pingRequest, pingReply) 76 assert.Nil(sendErr) 77 assert.Equal("pong 8 bytes", pingReply.Message) 78 assert.Equal(1, rrSvr.CompletedCnt()) 79 80 // Send an upcall() from the server to the client and 81 // verify that client method is called. 82 var msg1 []byte = []byte("server msg back to client") 83 rrSvr.SendCallback(myUniqueClientID, msg1) 84 85 // Wait until Interrupt() was called 86 cb.Lock() 87 for cb.sawCallback != true { 88 cb.cond.Wait() 89 } 90 cb.Unlock() 91 92 // Dump stats 93 /* DEBUG ONLY - 94 fmt.Printf("pfsagent dump stats: %s\n", bucketstats.SprintStats(bucketstats.StatFormatParsable1, "proxyfs.retryrpc", rrClnt.GetStatsGroupName())) 95 */ 96 97 // Stop the client before exiting 98 rrClnt.Close() 99 100 // Stop the server before exiting 101 rrSvr.Close() 102 }