github.com/braveheart12/insolar-09-08-19@v0.8.7/ledger/storage/dropstorage_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 storage_test
    18  
    19  import (
    20  	"context"
    21  	"sync"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  	"github.com/stretchr/testify/suite"
    28  
    29  	"github.com/insolar/insolar/component"
    30  	"github.com/insolar/insolar/core"
    31  	"github.com/insolar/insolar/instrumentation/inslogger"
    32  	"github.com/insolar/insolar/ledger/storage"
    33  	"github.com/insolar/insolar/ledger/storage/storagetest"
    34  	"github.com/insolar/insolar/log"
    35  	"github.com/insolar/insolar/platformpolicy"
    36  )
    37  
    38  type dropSuite struct {
    39  	suite.Suite
    40  
    41  	cm      *component.Manager
    42  	ctx     context.Context
    43  	cleaner func()
    44  	db      storage.DBContext
    45  
    46  	dropStorage storage.DropStorage
    47  }
    48  
    49  func NewDropSuite() *dropSuite {
    50  	return &dropSuite{
    51  		Suite: suite.Suite{},
    52  	}
    53  }
    54  
    55  // Init and run suite
    56  func TestDrop(t *testing.T) {
    57  	suite.Run(t, NewDropSuite())
    58  }
    59  
    60  func (s *dropSuite) BeforeTest(suiteName, testName string) {
    61  	s.cm = &component.Manager{}
    62  	s.ctx = inslogger.TestContext(s.T())
    63  
    64  	db, cleaner := storagetest.TmpDB(s.ctx, s.T())
    65  
    66  	s.db = db
    67  	s.cleaner = cleaner
    68  	s.dropStorage = storage.NewDropStorage(10)
    69  
    70  	s.cm.Inject(
    71  		platformpolicy.NewPlatformCryptographyScheme(),
    72  		s.db,
    73  		s.dropStorage,
    74  	)
    75  
    76  	err := s.cm.Init(s.ctx)
    77  	if err != nil {
    78  		s.T().Error("ComponentManager init failed", err)
    79  	}
    80  	err = s.cm.Start(s.ctx)
    81  	if err != nil {
    82  		s.T().Error("ComponentManager start failed", err)
    83  	}
    84  }
    85  
    86  func (s *dropSuite) AfterTest(suiteName, testName string) {
    87  	err := s.cm.Stop(s.ctx)
    88  	if err != nil {
    89  		s.T().Error("ComponentManager stop failed", err)
    90  	}
    91  	s.cleaner()
    92  }
    93  
    94  // testing storage CreateDrop lock logic
    95  //
    96  // 1) wait update transaction start, when start CreateDrop (should lock)
    97  // 2) transaction waits start of CreateDrop call and waits 'waittime' (200ms)
    98  // (could be unstable in really slow environments)
    99  // 3) wait CreateDrop and transaction finished
   100  // 4) compare finish time of CreateDrop and transaction
   101  // CreateDrop should happen after transaction (after 'waittime' timeout happens)
   102  func (s *dropSuite) TestStore_DropWaitWrites() {
   103  	// s.T().Parallel()
   104  
   105  	var txFin time.Time
   106  	var dropFin time.Time
   107  	waittime := time.Millisecond * 200
   108  
   109  	var wg sync.WaitGroup
   110  	wg.Add(2)
   111  	txstarted := make(chan bool)
   112  	dropwaits := make(chan bool)
   113  	var err error
   114  	go func() {
   115  		err = s.db.Update(s.ctx, func(tx *storage.TransactionManager) error {
   116  			log.Debug("start tx")
   117  			close(txstarted)
   118  			<-dropwaits
   119  			time.Sleep(waittime)
   120  			txFin = time.Now()
   121  			return nil
   122  		})
   123  		log.Debug("end tx")
   124  		wg.Done()
   125  	}()
   126  
   127  	go func() {
   128  		<-txstarted
   129  		log.Debug("start CreateDrop")
   130  		close(dropwaits)
   131  		_, _, dropSize, droperr := s.dropStorage.CreateDrop(s.ctx, core.TODOJetID, 0, []byte{})
   132  		if droperr != nil {
   133  			panic(droperr)
   134  		}
   135  		require.NotEqual(s.T(), 0, dropSize)
   136  		dropFin = time.Now()
   137  		log.Debug("end CreateDrop")
   138  		wg.Done()
   139  	}()
   140  	wg.Wait()
   141  
   142  	log.Debug("R: tx end t:", txFin)
   143  	log.Debug("R: drop   t:", dropFin)
   144  
   145  	require.NoError(s.T(), err)
   146  	assert.Conditionf(s.T(), func() bool {
   147  		return dropFin.After(txFin)
   148  	}, "drop should happens after transaction ending")
   149  }