github.com/braveheart12/insolar-09-08-19@v0.8.7/ledger/jetcoordinator/jetcoordinator_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 jetcoordinator 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/insolar/insolar" 24 "github.com/insolar/insolar/component" 25 "github.com/insolar/insolar/core" 26 "github.com/insolar/insolar/instrumentation/inslogger" 27 "github.com/insolar/insolar/ledger/storage" 28 "github.com/insolar/insolar/ledger/storage/jet" 29 "github.com/insolar/insolar/ledger/storage/nodes" 30 "github.com/insolar/insolar/ledger/storage/storagetest" 31 "github.com/insolar/insolar/platformpolicy" 32 "github.com/insolar/insolar/pulsar/entropygenerator" 33 "github.com/insolar/insolar/testutils" 34 "github.com/insolar/insolar/testutils/network" 35 "github.com/pkg/errors" 36 "github.com/stretchr/testify/assert" 37 "github.com/stretchr/testify/require" 38 "github.com/stretchr/testify/suite" 39 ) 40 41 type jetCoordinatorSuite struct { 42 suite.Suite 43 44 cm *component.Manager 45 ctx context.Context 46 cleaner func() 47 48 pulseStorage *storage.PulseStorage 49 pulseTracker storage.PulseTracker 50 jetStorage storage.JetStorage 51 nodeStorage *nodes.AccessorMock 52 coordinator *JetCoordinator 53 } 54 55 func NewJetCoordinatorSuite() *jetCoordinatorSuite { 56 return &jetCoordinatorSuite{ 57 Suite: suite.Suite{}, 58 } 59 } 60 61 func TestCoordinator(t *testing.T) { 62 suite.Run(t, NewJetCoordinatorSuite()) 63 } 64 65 func (s *jetCoordinatorSuite) BeforeTest(suiteName, testName string) { 66 s.cm = &component.Manager{} 67 s.ctx = inslogger.TestContext(s.T()) 68 69 db, cleaner := storagetest.TmpDB(s.ctx, s.T()) 70 71 s.cleaner = cleaner 72 s.pulseTracker = storage.NewPulseTracker() 73 s.pulseStorage = storage.NewPulseStorage() 74 s.jetStorage = storage.NewJetStorage() 75 s.nodeStorage = nodes.NewAccessorMock(s.T()) 76 s.coordinator = NewJetCoordinator(5) 77 s.coordinator.NodeNet = network.NewNodeNetworkMock(s.T()) 78 79 s.cm.Inject( 80 testutils.NewPlatformCryptographyScheme(), 81 db, 82 s.pulseTracker, 83 s.pulseStorage, 84 s.jetStorage, 85 s.nodeStorage, 86 s.coordinator, 87 ) 88 89 err := s.cm.Init(s.ctx) 90 if err != nil { 91 s.T().Error("ComponentManager init failed", err) 92 } 93 err = s.cm.Start(s.ctx) 94 if err != nil { 95 s.T().Error("ComponentManager start failed", err) 96 } 97 } 98 99 func (s *jetCoordinatorSuite) AfterTest(suiteName, testName string) { 100 err := s.cm.Stop(s.ctx) 101 if err != nil { 102 s.T().Error("ComponentManager stop failed", err) 103 } 104 s.cleaner() 105 } 106 107 func (s *jetCoordinatorSuite) TestJetCoordinator_QueryRole() { 108 err := s.pulseTracker.AddPulse(s.ctx, core.Pulse{PulseNumber: 0, Entropy: core.Entropy{1, 2, 3}}) 109 require.NoError(s.T(), err) 110 var nds []insolar.Node 111 var nodeRefs []core.RecordRef 112 for i := 0; i < 100; i++ { 113 ref := *core.NewRecordRef(core.DomainID, *core.NewRecordID(0, []byte{byte(i)})) 114 nds = append(nds, insolar.Node{ID: ref, Role: core.StaticRoleLightMaterial}) 115 nodeRefs = append(nodeRefs, ref) 116 } 117 require.NoError(s.T(), err) 118 119 s.nodeStorage.InRoleMock.Return(nds, nil) 120 121 objID := core.NewRecordID(0, []byte{1, 42, 123}) 122 s.jetStorage.UpdateJetTree(s.ctx, 0, true, *jet.NewID(50, []byte{1, 42, 123})) 123 124 selected, err := s.coordinator.QueryRole(s.ctx, core.DynamicRoleLightValidator, *objID, 0) 125 require.NoError(s.T(), err) 126 assert.Equal(s.T(), 3, len(selected)) 127 128 // Indexes are hard-coded from previously calculated values. 129 assert.Equal(s.T(), []core.RecordRef{nodeRefs[16], nodeRefs[21], nodeRefs[78]}, selected) 130 } 131 132 func TestJetCoordinator_Me(t *testing.T) { 133 t.Parallel() 134 // Arrange 135 expectedID := testutils.RandomRef() 136 nodeNet := network.NewNodeNetworkMock(t) 137 node := network.NewNodeMock(t) 138 nodeNet.GetOriginMock.Return(node) 139 node.IDMock.Return(expectedID) 140 jc := NewJetCoordinator(1) 141 jc.NodeNet = nodeNet 142 143 // Act 144 resultID := jc.Me() 145 146 // Assert 147 require.Equal(t, expectedID, resultID) 148 } 149 150 func TestNewJetCoordinator(t *testing.T) { 151 t.Parallel() 152 // Act 153 calc := NewJetCoordinator(12) 154 155 // Assert 156 require.NotNil(t, calc) 157 require.Equal(t, 12, calc.lightChainLimit) 158 } 159 160 func TestJetCoordinator_IsBeyondLimit_ProblemsWithTracker(t *testing.T) { 161 t.Parallel() 162 // Arrange 163 ctx := inslogger.TestContext(t) 164 pulseTrackerMock := storage.NewPulseTrackerMock(t) 165 pulseTrackerMock.GetPulseMock.Return(nil, errors.New("it's expected")) 166 calc := NewJetCoordinator(12) 167 calc.PulseTracker = pulseTrackerMock 168 169 // Act 170 res, err := calc.IsBeyondLimit(ctx, core.FirstPulseNumber, 0) 171 172 // Assert 173 require.NotNil(t, err) 174 require.Equal(t, false, res) 175 } 176 177 func TestJetCoordinator_IsBeyondLimit_ProblemsWithTracker_SecondCall(t *testing.T) { 178 t.Parallel() 179 // Arrange 180 ctx := inslogger.TestContext(t) 181 pulseTrackerMock := storage.NewPulseTrackerMock(t) 182 pulseTrackerMock.GetPulseFunc = func(p context.Context, p1 core.PulseNumber) (r *storage.Pulse, r1 error) { 183 if p1 == core.FirstPulseNumber { 184 return &storage.Pulse{}, nil 185 } 186 187 return nil, errors.New("it's expected") 188 } 189 calc := NewJetCoordinator(12) 190 calc.PulseTracker = pulseTrackerMock 191 192 // Act 193 res, err := calc.IsBeyondLimit(ctx, core.FirstPulseNumber, 0) 194 195 // Assert 196 require.NotNil(t, err) 197 require.Equal(t, false, res) 198 } 199 200 func TestJetCoordinator_IsBeyondLimit_OutsideOfLightChainLimit(t *testing.T) { 201 t.Parallel() 202 // Arrange 203 ctx := inslogger.TestContext(t) 204 pulseTrackerMock := storage.NewPulseTrackerMock(t) 205 pulseTrackerMock.GetPulseFunc = func(p context.Context, p1 core.PulseNumber) (r *storage.Pulse, r1 error) { 206 if p1 == core.FirstPulseNumber { 207 return &storage.Pulse{SerialNumber: 50}, nil 208 } 209 210 return &storage.Pulse{SerialNumber: 24}, nil 211 } 212 calc := NewJetCoordinator(25) 213 calc.PulseTracker = pulseTrackerMock 214 215 // Act 216 res, err := calc.IsBeyondLimit(ctx, core.FirstPulseNumber, 0) 217 218 // Assert 219 require.Nil(t, err) 220 require.Equal(t, true, res) 221 } 222 223 func TestJetCoordinator_IsBeyondLimit_InsideOfLightChainLimit(t *testing.T) { 224 t.Parallel() 225 // Arrange 226 ctx := inslogger.TestContext(t) 227 pulseTrackerMock := storage.NewPulseTrackerMock(t) 228 pulseTrackerMock.GetPulseFunc = func(p context.Context, p1 core.PulseNumber) (r *storage.Pulse, r1 error) { 229 if p1 == core.FirstPulseNumber { 230 return &storage.Pulse{SerialNumber: 50}, nil 231 } 232 233 return &storage.Pulse{SerialNumber: 34}, nil 234 } 235 calc := NewJetCoordinator(25) 236 calc.PulseTracker = pulseTrackerMock 237 238 // Act 239 res, err := calc.IsBeyondLimit(ctx, core.FirstPulseNumber, 0) 240 241 // Assert 242 require.Nil(t, err) 243 require.Equal(t, false, res) 244 } 245 246 func TestJetCoordinator_NodeForJet_CheckLimitFailed(t *testing.T) { 247 t.Parallel() 248 // Arrange 249 ctx := inslogger.TestContext(t) 250 pulseTrackerMock := storage.NewPulseTrackerMock(t) 251 pulseTrackerMock.GetPulseMock.Return(nil, errors.New("it's expected")) 252 calc := NewJetCoordinator(12) 253 calc.PulseTracker = pulseTrackerMock 254 255 // Act 256 res, err := calc.NodeForJet(ctx, testutils.RandomJet(), core.FirstPulseNumber, 0) 257 258 // Assert 259 require.NotNil(t, err) 260 require.Nil(t, res) 261 } 262 263 func TestJetCoordinator_NodeForJet_GoToHeavy(t *testing.T) { 264 t.Parallel() 265 // Arrange 266 ctx := inslogger.TestContext(t) 267 pulseTrackerMock := storage.NewPulseTrackerMock(t) 268 pulseTrackerMock.GetPulseFunc = func(p context.Context, p1 core.PulseNumber) (r *storage.Pulse, r1 error) { 269 if p1 == core.FirstPulseNumber { 270 return &storage.Pulse{SerialNumber: 50}, nil 271 } 272 273 return &storage.Pulse{SerialNumber: 24}, nil 274 } 275 expectedID := core.NewRecordRef(testutils.RandomID(), testutils.RandomID()) 276 activeNodesStorageMock := nodes.NewAccessorMock(t) 277 activeNodesStorageMock.InRoleFunc = func(p core.PulseNumber, p1 core.StaticRole) (r []insolar.Node, r1 error) { 278 require.Equal(t, core.FirstPulseNumber, int(p)) 279 require.Equal(t, core.StaticRoleHeavyMaterial, p1) 280 281 return []insolar.Node{{ID: *expectedID}}, nil 282 } 283 284 pulseStorageMock := testutils.NewPulseStorageMock(t) 285 pulseStorageMock.CurrentFunc = func(p context.Context) (r *core.Pulse, r1 error) { 286 generator := entropygenerator.StandardEntropyGenerator{} 287 return &core.Pulse{PulseNumber: core.FirstPulseNumber, Entropy: generator.GenerateEntropy()}, nil 288 } 289 290 calc := NewJetCoordinator(25) 291 calc.PulseTracker = pulseTrackerMock 292 calc.Nodes = activeNodesStorageMock 293 calc.PulseStorage = pulseStorageMock 294 calc.PlatformCryptographyScheme = platformpolicy.NewPlatformCryptographyScheme() 295 296 // Act 297 resNode, err := calc.NodeForJet(ctx, testutils.RandomJet(), core.FirstPulseNumber, 0) 298 299 // Assert 300 require.Nil(t, err) 301 require.Equal(t, expectedID, resNode) 302 } 303 304 func TestJetCoordinator_NodeForJet_GoToLight(t *testing.T) { 305 t.Parallel() 306 // Arrange 307 ctx := inslogger.TestContext(t) 308 pulseTrackerMock := storage.NewPulseTrackerMock(t) 309 pulseTrackerMock.GetPulseFunc = func(p context.Context, p1 core.PulseNumber) (r *storage.Pulse, r1 error) { 310 if p1 == core.FirstPulseNumber { 311 return &storage.Pulse{SerialNumber: 50}, nil 312 } 313 314 return &storage.Pulse{SerialNumber: 49}, nil 315 } 316 expectedID := core.NewRecordRef(testutils.RandomID(), testutils.RandomID()) 317 activeNodesStorageMock := nodes.NewAccessorMock(t) 318 activeNodesStorageMock.InRoleFunc = func(p core.PulseNumber, p1 core.StaticRole) (r []insolar.Node, r1 error) { 319 require.Equal(t, 0, int(p)) 320 require.Equal(t, core.StaticRoleLightMaterial, p1) 321 322 return []insolar.Node{{ID: *expectedID}}, nil 323 } 324 325 pulseStorageMock := testutils.NewPulseStorageMock(t) 326 pulseStorageMock.CurrentFunc = func(p context.Context) (r *core.Pulse, r1 error) { 327 generator := entropygenerator.StandardEntropyGenerator{} 328 return &core.Pulse{PulseNumber: core.FirstPulseNumber, Entropy: generator.GenerateEntropy()}, nil 329 } 330 331 calc := NewJetCoordinator(25) 332 calc.PulseTracker = pulseTrackerMock 333 calc.Nodes = activeNodesStorageMock 334 calc.PulseStorage = pulseStorageMock 335 calc.PlatformCryptographyScheme = platformpolicy.NewPlatformCryptographyScheme() 336 337 // Act 338 resNode, err := calc.NodeForJet(ctx, testutils.RandomJet(), core.FirstPulseNumber, 0) 339 340 // Assert 341 require.Nil(t, err) 342 require.Equal(t, expectedID, resNode) 343 }