github.com/matrixorigin/matrixone@v1.2.0/pkg/common/morpc/future_test.go (about)

     1  // Copyright 2021 - 2022 Matrix Origin
     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 morpc
    16  
    17  import (
    18  	"context"
    19  	"runtime/debug"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  func TestNewFutureWillPanic(t *testing.T) {
    28  	defer func() {
    29  		if err := recover(); err == nil {
    30  			assert.Fail(t, "must panic")
    31  		}
    32  	}()
    33  	f := newFuture(nil)
    34  	f.init(RPCMessage{Ctx: context.Background()})
    35  }
    36  
    37  func TestCloseChanAfterGC(t *testing.T) {
    38  	f := newFuture(nil)
    39  	c := f.c
    40  	c <- &testMessage{}
    41  	f = nil
    42  	debug.FreeOSMemory()
    43  	for {
    44  		select {
    45  		case _, ok := <-c:
    46  			if !ok {
    47  				return
    48  			}
    49  		case <-time.After(time.Second * 5):
    50  			assert.Fail(t, "failed")
    51  		}
    52  	}
    53  }
    54  
    55  func TestNewFuture(t *testing.T) {
    56  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    57  	defer cancel()
    58  
    59  	f := newFuture(nil)
    60  	f.init(newTestRPCMessage(ctx, 1))
    61  	defer f.Close()
    62  
    63  	assert.NotNil(t, f)
    64  	assert.False(t, f.mu.closed, false)
    65  	assert.NotNil(t, f.c)
    66  	assert.Equal(t, 0, len(f.c))
    67  	assert.Equal(t, uint64(1), f.getSendMessageID())
    68  	assert.Equal(t, ctx, f.send.Ctx)
    69  }
    70  
    71  func TestReleaseFuture(t *testing.T) {
    72  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    73  	defer cancel()
    74  
    75  	req := newTestMessage(1)
    76  	f := newFuture(func(f *Future) { f.reset() })
    77  	f.init(newTestRPCMessage(ctx, 1))
    78  	f.c <- req
    79  	f.Close()
    80  	assert.True(t, f.mu.closed)
    81  	assert.Equal(t, 0, len(f.c))
    82  	assert.Equal(t, RPCMessage{}, f.send)
    83  	assert.Nil(t, f.send.Ctx)
    84  }
    85  
    86  func TestGet(t *testing.T) {
    87  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    88  	defer cancel()
    89  
    90  	req := newTestMessage(1)
    91  	f := newFuture(func(f *Future) { f.reset() })
    92  	f.ref()
    93  	f.init(newTestRPCMessage(ctx, 1))
    94  	defer f.Close()
    95  
    96  	f.messageSent(nil)
    97  	f.done(req, nil)
    98  	resp, err := f.Get()
    99  	assert.Nil(t, err)
   100  	assert.Equal(t, req, resp)
   101  }
   102  
   103  func TestGetWithTimeout(t *testing.T) {
   104  	ctx, cancel := context.WithTimeout(context.Background(), 1)
   105  	defer cancel()
   106  
   107  	f := newFuture(func(f *Future) { f.reset() })
   108  	f.ref()
   109  	f.init(newTestRPCMessage(ctx, 1))
   110  	defer f.Close()
   111  
   112  	f.messageSent(nil)
   113  	resp, err := f.Get()
   114  	assert.NotNil(t, err)
   115  	assert.Nil(t, resp)
   116  	assert.Equal(t, ctx.Err(), err)
   117  }
   118  
   119  func TestGetWithError(t *testing.T) {
   120  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   121  	defer cancel()
   122  
   123  	f := newFuture(func(f *Future) { f.reset() })
   124  	f.ref()
   125  	f.init(newTestRPCMessage(ctx, 1))
   126  	defer f.Close()
   127  
   128  	errResp := moerr.NewBackendClosed(context.TODO())
   129  	f.error(1, errResp, nil)
   130  
   131  	f.messageSent(nil)
   132  	resp, err := f.Get()
   133  	assert.Error(t, err)
   134  	assert.Nil(t, resp)
   135  	assert.Equal(t, errResp, err)
   136  }
   137  
   138  func TestGetWithInvalidResponse(t *testing.T) {
   139  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   140  	defer cancel()
   141  
   142  	f := newFuture(func(f *Future) { f.reset() })
   143  	f.init(newTestRPCMessage(ctx, 1))
   144  	defer f.Close()
   145  
   146  	f.done(newTestMessage(2), nil)
   147  	assert.Equal(t, 0, len(f.c))
   148  }
   149  
   150  func TestTimeout(t *testing.T) {
   151  	ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
   152  	f := newFuture(func(f *Future) { f.reset() })
   153  	f.init(newTestRPCMessage(ctx, 1))
   154  	defer f.Close()
   155  
   156  	assert.False(t, f.timeout())
   157  	cancel()
   158  	assert.True(t, f.timeout())
   159  }
   160  
   161  func newTestRPCMessage(ctx context.Context, id uint64) RPCMessage {
   162  	return RPCMessage{Ctx: ctx, Message: newTestMessage(id)}
   163  }