github.com/braveheart12/just@v0.8.7/messagebus/messagebus_test.go (about)

     1  /*
     2   *    Copyright 2019 Insolar Technologies
     3   *
     4   *    Licensed under the Apache License, Version 2.0 (the "License");
     5   *    you may not use this file except in compliance with the License.
     6   *    You may obtain a copy of the License at
     7   *
     8   *        http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   *    Unless required by applicable law or agreed to in writing, software
    11   *    distributed under the License is distributed on an "AS IS" BASIS,
    12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *    See the License for the specific language governing permissions and
    14   *    limitations under the License.
    15   */
    16  
    17  package messagebus
    18  
    19  import (
    20  	"context"
    21  	"sync/atomic"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/stretchr/testify/require"
    26  
    27  	"github.com/insolar/insolar/component"
    28  	"github.com/insolar/insolar/configuration"
    29  	"github.com/insolar/insolar/core"
    30  	"github.com/insolar/insolar/core/message"
    31  	"github.com/insolar/insolar/testutils"
    32  	"github.com/insolar/insolar/testutils/network"
    33  )
    34  
    35  var testType = core.MessageType(123)
    36  
    37  type replyMock int
    38  
    39  func (replyMock) Type() core.ReplyType {
    40  	return core.ReplyType(124)
    41  }
    42  
    43  var testReply replyMock = 124
    44  
    45  func testHandler(_ context.Context, _ core.Parcel) (core.Reply, error) {
    46  	return testReply, nil
    47  }
    48  
    49  func prepare(t *testing.T, ctx context.Context, currentPulse int, msgPulse int) (*MessageBus, *testutils.PulseStorageMock, core.Parcel) {
    50  	mb, err := NewMessageBus(configuration.Configuration{})
    51  	require.NoError(t, err)
    52  
    53  	net := network.GetTestNetwork()
    54  	jc := testutils.NewJetCoordinatorMock(t)
    55  	nn := network.NewNodeNetworkMock(t)
    56  	nn.GetOriginFunc = func() (r core.Node) {
    57  		n := network.NewNodeMock(t)
    58  		n.IDMock.Return(core.RecordRef{})
    59  		return n
    60  	}
    61  
    62  	pcs := testutils.NewPlatformCryptographyScheme()
    63  	cs := testutils.NewCryptographyServiceMock(t)
    64  	dtf := testutils.NewDelegationTokenFactoryMock(t)
    65  	pf := NewParcelFactory()
    66  	ps := testutils.NewPulseStorageMock(t)
    67  
    68  	(&component.Manager{}).Inject(net, jc, nn, pcs, cs, dtf, pf, ps, mb)
    69  
    70  	ps.CurrentFunc = func(ctx context.Context) (*core.Pulse, error) {
    71  		return &core.Pulse{
    72  			PulseNumber:     core.PulseNumber(currentPulse),
    73  			NextPulseNumber: core.PulseNumber(currentPulse + 1),
    74  		}, nil
    75  	}
    76  
    77  	err = mb.Register(testType, testHandler)
    78  	require.NoError(t, err)
    79  
    80  	parcel := testutils.NewParcelMock(t)
    81  
    82  	parcel.PulseFunc = func() core.PulseNumber {
    83  		return core.PulseNumber(msgPulse)
    84  	}
    85  	parcel.TypeFunc = func() core.MessageType {
    86  		return testType
    87  	}
    88  	parcel.GetSenderFunc = func() (r core.RecordRef) {
    89  		return testutils.RandomRef()
    90  	}
    91  	parcel.MessageMock.Return(&message.GetObject{})
    92  
    93  	mb.Unlock(ctx)
    94  
    95  	return mb, ps, parcel
    96  }
    97  
    98  func TestMessageBus_doDeliver_PrevPulse(t *testing.T) {
    99  	ctx := context.Background()
   100  	mb, _, parcel := prepare(t, ctx, 100, 99)
   101  
   102  	result, err := mb.doDeliver(ctx, parcel)
   103  	require.Error(t, err)
   104  	require.Nil(t, result)
   105  }
   106  
   107  func TestMessageBus_doDeliver_SamePulse(t *testing.T) {
   108  	ctx := context.Background()
   109  	mb, _, parcel := prepare(t, ctx, 100, 100)
   110  
   111  	result, err := mb.doDeliver(ctx, parcel)
   112  	require.NoError(t, err)
   113  	require.Equal(t, testReply, result)
   114  }
   115  
   116  func TestMessageBus_doDeliver_NextPulse(t *testing.T) {
   117  	ctx := context.Background()
   118  	mb, ps, parcel := prepare(t, ctx, 100, 101)
   119  
   120  	pulseUpdated := false
   121  
   122  	var triggerUnlock int32
   123  	newPulse := &core.Pulse{
   124  		PulseNumber:     101,
   125  		NextPulseNumber: 102,
   126  	}
   127  	fn := ps.CurrentFunc
   128  	ps.CurrentFunc = func(ctx context.Context) (*core.Pulse, error) {
   129  		if atomic.LoadInt32(&triggerUnlock) > 0 {
   130  			return newPulse, nil
   131  		}
   132  		return fn(ctx)
   133  	}
   134  	go func() {
   135  		// should unlock
   136  		time.Sleep(time.Second)
   137  		atomic.AddInt32(&triggerUnlock, 1)
   138  
   139  		pulseUpdated = true
   140  		err := mb.OnPulse(ctx, *newPulse)
   141  		require.NoError(t, err)
   142  	}()
   143  	// blocks until newPulse returns
   144  	result, err := mb.doDeliver(ctx, parcel)
   145  	require.NoError(t, err)
   146  	require.Equal(t, testReply, result)
   147  	require.True(t, pulseUpdated)
   148  }
   149  
   150  func TestMessageBus_doDeliver_TwoAheadPulses(t *testing.T) {
   151  	ctx := context.Background()
   152  	mb, ps, parcel := prepare(t, ctx, 100, 102)
   153  
   154  	pulse := &core.Pulse{
   155  		PulseNumber:     100,
   156  		NextPulseNumber: 101,
   157  	}
   158  	ps.CurrentFunc = func(ctx context.Context) (*core.Pulse, error) {
   159  		return pulse, nil
   160  	}
   161  	go func() {
   162  		for i := 1; i <= 2; i++ {
   163  			pulse = &core.Pulse{
   164  				PulseNumber:     core.PulseNumber(100 + i),
   165  				NextPulseNumber: core.PulseNumber(100 + i + 1),
   166  			}
   167  			err := mb.OnPulse(ctx, *pulse)
   168  			require.NoError(t, err)
   169  		}
   170  	}()
   171  
   172  	_, err := mb.doDeliver(ctx, parcel)
   173  	require.NoError(t, err)
   174  	require.Equal(t, core.PulseNumber(102), pulse.PulseNumber)
   175  }