github.com/braveheart12/just@v0.8.7/ledger/artifactmanager/hotdatawaiter_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 artifactmanager
    18  
    19  import (
    20  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/insolar/insolar/core"
    25  	"github.com/insolar/insolar/instrumentation/inslogger"
    26  	"github.com/insolar/insolar/testutils"
    27  	"github.com/stretchr/testify/assert"
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  func TestNewHotDataWaiterConcrete(t *testing.T) {
    32  	t.Parallel()
    33  
    34  	// Act
    35  	hdw := NewHotDataWaiterConcrete()
    36  
    37  	// Assert
    38  	require.NotNil(t, hdw)
    39  	require.NotNil(t, hdw.waiters)
    40  }
    41  
    42  func TestHotDataWaiterConcrete_Get_CreateIfNil(t *testing.T) {
    43  	t.Parallel()
    44  
    45  	// Arrange
    46  	hdw := NewHotDataWaiterConcrete()
    47  	jetID := testutils.RandomID()
    48  
    49  	// Act
    50  	waiter := hdw.waiterForJet(jetID)
    51  
    52  	// Assert
    53  	require.NotNil(t, waiter)
    54  	require.Equal(t, waiter, hdw.waiters[jetID])
    55  	require.Equal(t, 1, len(hdw.waiters))
    56  }
    57  
    58  func TestHotDataWaiterConcrete_Wait_UnlockHotData(t *testing.T) {
    59  	t.Parallel()
    60  
    61  	// Arrange
    62  	syncChannel := make(chan struct{})
    63  	hdw := NewHotDataWaiterConcrete()
    64  	hdwLock := sync.Mutex{}
    65  	hdwGetter := func() HotDataWaiter {
    66  		hdwLock.Lock()
    67  		defer hdwLock.Unlock()
    68  
    69  		return hdw
    70  	}
    71  	jetID := testutils.RandomID()
    72  	_ = hdw.waiterForJet(jetID)
    73  
    74  	// Act
    75  	go func() {
    76  		err := hdwGetter().Wait(inslogger.TestContext(t), jetID)
    77  		require.Nil(t, err)
    78  		close(syncChannel)
    79  	}()
    80  
    81  	time.Sleep(10 * time.Millisecond)
    82  
    83  	// Closing waiter the first time, no error.
    84  	err := hdwGetter().Unlock(inslogger.TestContext(t), jetID)
    85  	require.NoError(t, err)
    86  
    87  	<-syncChannel
    88  
    89  	// Closing waiter the second time, error.
    90  	err = hdwGetter().Unlock(inslogger.TestContext(t), jetID)
    91  	assert.Error(t, err)
    92  }
    93  
    94  func TestHotDataWaiterConcrete_Wait_ThrowTimeout(t *testing.T) {
    95  	t.Parallel()
    96  
    97  	// Arrange
    98  	syncChannel := make(chan struct{})
    99  	hdw := NewHotDataWaiterConcrete()
   100  	hdwLock := sync.Mutex{}
   101  	hdwGetter := func() HotDataWaiter {
   102  		hdwLock.Lock()
   103  		defer hdwLock.Unlock()
   104  
   105  		return hdw
   106  	}
   107  	hdwLengthGetter := func() int {
   108  		hdwLock.Lock()
   109  		defer hdwLock.Unlock()
   110  
   111  		return len(hdw.waiters)
   112  	}
   113  	jetID := testutils.RandomID()
   114  	_ = hdw.waiterForJet(jetID)
   115  
   116  	// Act
   117  	go func() {
   118  		err := hdwGetter().Wait(inslogger.TestContext(t), jetID)
   119  		require.NotNil(t, err)
   120  		require.Equal(t, core.ErrHotDataTimeout, err)
   121  		close(syncChannel)
   122  	}()
   123  
   124  	time.Sleep(10 * time.Millisecond)
   125  
   126  	hdwGetter().ThrowTimeout(inslogger.TestContext(t))
   127  
   128  	<-syncChannel
   129  	require.Equal(t, 0, hdwLengthGetter())
   130  }
   131  
   132  func TestHotDataWaiterConcrete_Wait_ThrowTimeout_MultipleMembers(t *testing.T) {
   133  	t.Parallel()
   134  
   135  	// Arrange
   136  	syncChannel := make(chan struct{})
   137  	hdw := NewHotDataWaiterConcrete()
   138  	hdwLock := sync.Mutex{}
   139  	hdwGetter := func() HotDataWaiter {
   140  		hdwLock.Lock()
   141  		defer hdwLock.Unlock()
   142  
   143  		return hdw
   144  	}
   145  	hdwLengthGetter := func() int {
   146  		hdwLock.Lock()
   147  		defer hdwLock.Unlock()
   148  
   149  		return len(hdw.waiters)
   150  	}
   151  	jetID := testutils.RandomID()
   152  	secondJetID := testutils.RandomID()
   153  	_ = hdw.waiterForJet(jetID)
   154  
   155  	// Act
   156  	go func() {
   157  		err := hdwGetter().Wait(inslogger.TestContext(t), jetID)
   158  		require.NotNil(t, err)
   159  		require.Equal(t, core.ErrHotDataTimeout, err)
   160  		syncChannel <- struct{}{}
   161  	}()
   162  	go func() {
   163  		err := hdwGetter().Wait(inslogger.TestContext(t), secondJetID)
   164  		require.NotNil(t, err)
   165  		require.Equal(t, core.ErrHotDataTimeout, err)
   166  		syncChannel <- struct{}{}
   167  	}()
   168  
   169  	time.Sleep(10 * time.Millisecond)
   170  
   171  	hdwGetter().ThrowTimeout(inslogger.TestContext(t))
   172  
   173  	<-syncChannel
   174  	<-syncChannel
   175  
   176  	require.Equal(t, 0, hdwLengthGetter())
   177  }