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  }