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 }