github.com/braveheart12/just@v0.8.7/ledger/heavyserver/heavysync_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 heavyserver
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/insolar/insolar/component"
    24  	"github.com/insolar/insolar/core"
    25  	"github.com/insolar/insolar/instrumentation/inslogger"
    26  	"github.com/insolar/insolar/ledger/storage"
    27  	"github.com/insolar/insolar/ledger/storage/jet"
    28  	"github.com/insolar/insolar/ledger/storage/storagetest"
    29  	"github.com/insolar/insolar/platformpolicy"
    30  	"github.com/insolar/insolar/testutils"
    31  	"github.com/stretchr/testify/require"
    32  	"github.com/stretchr/testify/suite"
    33  )
    34  
    35  type heavysyncSuite struct {
    36  	suite.Suite
    37  
    38  	cm      *component.Manager
    39  	ctx     context.Context
    40  	cleaner func()
    41  	db      storage.DBContext
    42  
    43  	pulseTracker   storage.PulseTracker
    44  	replicaStorage storage.ReplicaStorage
    45  
    46  	sync *Sync
    47  }
    48  
    49  func NewHeavysyncSuite() *heavysyncSuite {
    50  	return &heavysyncSuite{
    51  		Suite: suite.Suite{},
    52  	}
    53  }
    54  
    55  // Init and run suite
    56  func TestHeavysync(t *testing.T) {
    57  	suite.Run(t, NewHeavysyncSuite())
    58  }
    59  
    60  func (s *heavysyncSuite) 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.pulseTracker = storage.NewPulseTracker()
    69  	s.replicaStorage = storage.NewReplicaStorage()
    70  
    71  	s.cm.Inject(
    72  		platformpolicy.NewPlatformCryptographyScheme(),
    73  		s.db,
    74  		s.pulseTracker,
    75  		s.replicaStorage,
    76  	)
    77  
    78  	err := s.cm.Init(s.ctx)
    79  	if err != nil {
    80  		s.T().Error("ComponentManager init failed", err)
    81  	}
    82  	err = s.cm.Start(s.ctx)
    83  	if err != nil {
    84  		s.T().Error("ComponentManager start failed", err)
    85  	}
    86  }
    87  
    88  func (s *heavysyncSuite) AfterTest(suiteName, testName string) {
    89  	err := s.cm.Stop(s.ctx)
    90  	if err != nil {
    91  		s.T().Error("ComponentManager stop failed", err)
    92  	}
    93  	s.cleaner()
    94  }
    95  
    96  func (s *heavysyncSuite) TestHeavy_SyncBasic() {
    97  	var err error
    98  	var pnum core.PulseNumber
    99  	kvalues := []core.KV{
   100  		{K: []byte("100"), V: []byte("500")},
   101  	}
   102  
   103  	// TODO: call every case in subtest
   104  	jetID := testutils.RandomJet()
   105  
   106  	sync := NewSync(s.db)
   107  	sync.ReplicaStorage = s.replicaStorage
   108  	err = sync.Start(s.ctx, jetID, pnum)
   109  	require.Error(s.T(), err, "start with zero pulse")
   110  
   111  	err = sync.Store(s.ctx, jetID, pnum, kvalues)
   112  	require.Error(s.T(), err, "store values on non started sync")
   113  
   114  	err = sync.Stop(s.ctx, jetID, pnum)
   115  	require.Error(s.T(), err, "stop on non started sync")
   116  
   117  	pnum = 5
   118  	err = sync.Start(s.ctx, jetID, pnum)
   119  	require.Error(s.T(), err, "last synced pulse is less when 'first pulse number'")
   120  
   121  	pnum = core.FirstPulseNumber
   122  	err = sync.Start(s.ctx, jetID, pnum)
   123  	require.Error(s.T(), err, "start from first pulse on empty storage")
   124  
   125  	pnum = core.FirstPulseNumber + 1
   126  	err = sync.Start(s.ctx, jetID, pnum)
   127  	require.NoError(s.T(), err, "start sync on empty heavy jet with non first pulse number")
   128  
   129  	err = sync.Start(s.ctx, jetID, pnum)
   130  	require.Error(s.T(), err, "double start")
   131  
   132  	pnumNext := pnum + 1
   133  	err = sync.Start(s.ctx, jetID, pnumNext)
   134  	require.Error(s.T(), err, "start next pulse sync when previous not end")
   135  
   136  	// stop previous
   137  	err = sync.Stop(s.ctx, jetID, pnum)
   138  	require.NoError(s.T(), err)
   139  
   140  	// start sparse next
   141  	pnumNextPlus := pnumNext + 1
   142  	err = sync.Start(s.ctx, jetID, pnumNextPlus)
   143  	require.NoError(s.T(), err, "sparse sync is ok")
   144  	err = sync.Stop(s.ctx, jetID, pnumNextPlus)
   145  	require.NoError(s.T(), err)
   146  
   147  	// prepare pulse helper
   148  	preparepulse := func(pn core.PulseNumber) {
   149  		pulse := core.Pulse{PulseNumber: pn}
   150  		err = s.pulseTracker.AddPulse(s.ctx, pulse)
   151  		require.NoError(s.T(), err)
   152  	}
   153  	pnum = pnumNextPlus + 1
   154  	pnumNext = pnum + 1
   155  	preparepulse(pnum)
   156  	preparepulse(pnumNext) // should set correct next for previous pulse
   157  
   158  	err = sync.Start(s.ctx, jetID, pnumNext)
   159  	require.NoError(s.T(), err, "start next pulse")
   160  
   161  	err = sync.Store(s.ctx, jetID, pnumNextPlus, kvalues)
   162  	require.Error(s.T(), err, "store from other pulse at the same jet")
   163  
   164  	err = sync.Stop(s.ctx, jetID, pnumNextPlus)
   165  	require.Error(s.T(), err, "stop from other pulse at the same jet")
   166  
   167  	err = sync.Store(s.ctx, jetID, pnumNext, kvalues)
   168  	require.NoError(s.T(), err, "store on current range")
   169  	err = sync.Store(s.ctx, jetID, pnumNext, kvalues)
   170  	require.NoError(s.T(), err, "store the same on current range")
   171  	err = sync.Stop(s.ctx, jetID, pnumNext)
   172  	require.NoError(s.T(), err, "stop current range")
   173  
   174  	preparepulse(pnumNextPlus) // should set corret next for previous pulse
   175  	sync = NewSync(s.db)
   176  	sync.ReplicaStorage = s.replicaStorage
   177  	err = sync.Start(s.ctx, jetID, pnumNextPlus)
   178  	require.NoError(s.T(), err, "start next+1 range on new sync instance (checkpoint check)")
   179  	err = sync.Store(s.ctx, jetID, pnumNextPlus, kvalues)
   180  	require.NoError(s.T(), err, "store next+1 pulse")
   181  	err = sync.Stop(s.ctx, jetID, pnumNextPlus)
   182  	require.NoError(s.T(), err, "stop next+1 range on new sync instance")
   183  }
   184  
   185  func (s *heavysyncSuite) TestHeavy_SyncByJet() {
   186  	var err error
   187  	var pnum core.PulseNumber
   188  	kvalues1 := []core.KV{
   189  		{K: []byte("1_11"), V: []byte("1_12")},
   190  	}
   191  	kvalues2 := []core.KV{
   192  		{K: []byte("2_21"), V: []byte("2_22")},
   193  	}
   194  
   195  	// TODO: call every case in subtest
   196  	jetID1 := testutils.RandomJet()
   197  	jetID2 := jetID1
   198  	// flip first bit of last byte jetID2 for different prefixes
   199  	lastidx := len(jetID1) - 1
   200  	jetID2[lastidx] ^= 0xFF
   201  
   202  	sync := NewSync(s.db)
   203  	sync.ReplicaStorage = s.replicaStorage
   204  
   205  	pnum = core.FirstPulseNumber + 1
   206  	pnumNext := pnum + 1
   207  	preparepulse(s, pnum)
   208  	preparepulse(s, pnumNext) // should set correct next for previous pulse
   209  
   210  	err = sync.Start(s.ctx, jetID1, core.FirstPulseNumber)
   211  	require.Error(s.T(), err)
   212  
   213  	err = sync.Start(s.ctx, jetID1, pnum)
   214  	require.NoError(s.T(), err, "start from first+1 pulse on empty storage, jet1")
   215  
   216  	err = sync.Start(s.ctx, jetID2, pnum)
   217  	require.NoError(s.T(), err, "start from first+1 pulse on empty storage, jet2")
   218  
   219  	err = sync.Store(s.ctx, jetID2, pnum, kvalues2)
   220  	require.NoError(s.T(), err, "store jet2 pulse")
   221  
   222  	err = sync.Store(s.ctx, jetID1, pnum, kvalues1)
   223  	require.NoError(s.T(), err, "store jet1 pulse")
   224  
   225  	// stop previous
   226  	err = sync.Stop(s.ctx, jetID1, pnum)
   227  	err = sync.Stop(s.ctx, jetID2, pnum)
   228  	require.NoError(s.T(), err)
   229  }
   230  
   231  func (s *heavysyncSuite) TestHeavy_SyncLockOnPrefix() {
   232  	var err error
   233  	var pnum core.PulseNumber
   234  
   235  	// different jets with same prefix
   236  	jetID1 := *jet.NewID(1, []byte{})
   237  	jetID2 := *jet.NewID(2, []byte{})
   238  
   239  	sync := NewSync(s.db)
   240  	sync.ReplicaStorage = s.replicaStorage
   241  
   242  	pnum = core.FirstPulseNumber + 2
   243  	// should set correct next for previous pulse
   244  	preparepulse(s, pnum-1)
   245  	preparepulse(s, pnum)
   246  
   247  	err = sync.Start(s.ctx, jetID1, pnum)
   248  	require.NoError(s.T(), err, "all should be ok")
   249  
   250  	err = sync.Start(s.ctx, jetID2, pnum)
   251  	require.Error(s.T(), err, "should not start on same prefix")
   252  
   253  	// stop previous sync (only prefix matters)
   254  	err = sync.Stop(s.ctx, jetID2, pnum)
   255  	require.NoError(s.T(), err)
   256  
   257  	err = sync.Start(s.ctx, jetID2, pnum+1)
   258  	require.NoError(s.T(), err, "should start after released lock")
   259  }
   260  
   261  func preparepulse(s *heavysyncSuite, pn core.PulseNumber) {
   262  	pulse := core.Pulse{PulseNumber: pn}
   263  	err := s.pulseTracker.AddPulse(s.ctx, pulse)
   264  	require.NoError(s.T(), err)
   265  }