github.com/braveheart12/insolar-09-08-19@v0.8.7/ledger/exporter/exporter_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 exporter 18 19 import ( 20 "context" 21 "encoding/json" 22 "strconv" 23 "testing" 24 25 "github.com/insolar/insolar/component" 26 "github.com/insolar/insolar/configuration" 27 "github.com/insolar/insolar/core" 28 "github.com/insolar/insolar/core/message" 29 "github.com/insolar/insolar/instrumentation/inslogger" 30 "github.com/insolar/insolar/ledger/storage" 31 "github.com/insolar/insolar/ledger/storage/record" 32 "github.com/insolar/insolar/ledger/storage/storagetest" 33 "github.com/insolar/insolar/platformpolicy" 34 base58 "github.com/jbenet/go-base58" 35 "github.com/stretchr/testify/assert" 36 "github.com/stretchr/testify/require" 37 "github.com/stretchr/testify/suite" 38 "github.com/ugorji/go/codec" 39 ) 40 41 type exporterSuite struct { 42 suite.Suite 43 44 cm *component.Manager 45 ctx context.Context 46 cleaner func() 47 48 pulseTracker storage.PulseTracker 49 objectStorage storage.ObjectStorage 50 jetStorage storage.JetStorage 51 pulseStorage *storage.PulseStorage 52 53 exporter *Exporter 54 jetID core.RecordID 55 } 56 57 func NewExporterSuite() *exporterSuite { 58 return &exporterSuite{ 59 Suite: suite.Suite{}, 60 } 61 } 62 63 // Init and run suite 64 func TestExporter(t *testing.T) { 65 suite.Run(t, NewExporterSuite()) 66 } 67 68 func (s *exporterSuite) BeforeTest(suiteName, testName string) { 69 s.cm = &component.Manager{} 70 s.ctx = inslogger.TestContext(s.T()) 71 s.jetID = core.TODOJetID 72 73 db, cleaner := storagetest.TmpDB(s.ctx, s.T()) 74 s.cleaner = cleaner 75 s.pulseTracker = storage.NewPulseTracker() 76 s.objectStorage = storage.NewObjectStorage() 77 s.jetStorage = storage.NewJetStorage() 78 s.pulseStorage = storage.NewPulseStorage() 79 s.exporter = NewExporter(configuration.Exporter{ExportLag: 0}) 80 81 s.cm.Inject( 82 platformpolicy.NewPlatformCryptographyScheme(), 83 db, 84 s.pulseTracker, 85 s.objectStorage, 86 s.jetStorage, 87 s.pulseStorage, 88 s.exporter, 89 ) 90 91 err := s.cm.Init(s.ctx) 92 if err != nil { 93 s.T().Error("ComponentManager init failed", err) 94 } 95 err = s.cm.Start(s.ctx) 96 if err != nil { 97 s.T().Error("ComponentManager start failed", err) 98 } 99 } 100 101 func (s *exporterSuite) AfterTest(suiteName, testName string) { 102 err := s.cm.Stop(s.ctx) 103 if err != nil { 104 s.T().Error("ComponentManager stop failed", err) 105 } 106 s.cleaner() 107 } 108 109 func (s *exporterSuite) TestExporter_Export() { 110 for i := 1; i <= 3; i++ { 111 err := s.pulseTracker.AddPulse( 112 s.ctx, 113 core.Pulse{ 114 PulseNumber: core.FirstPulseNumber + 10*core.PulseNumber(i), 115 PrevPulseNumber: core.FirstPulseNumber + 10*core.PulseNumber(i-1), 116 PulseTimestamp: 10 * int64(i+1), 117 }, 118 ) 119 require.NoError(s.T(), err) 120 } 121 122 type testData struct { 123 Field string 124 Data struct { 125 Field string 126 } 127 } 128 mem := make([]byte, 0) 129 blobData := testData{Field: "objectValue"} 130 blobData.Data.Field = "anotherValue" 131 codec.NewEncoderBytes(&mem, &codec.CborHandle{}).MustEncode(blobData) 132 blobID, err := s.objectStorage.SetBlob(s.ctx, s.jetID, core.FirstPulseNumber+10, mem) 133 require.NoError(s.T(), err) 134 _, err = s.objectStorage.SetRecord(s.ctx, s.jetID, core.FirstPulseNumber+10, &record.GenesisRecord{}) 135 require.NoError(s.T(), err) 136 objectID, err := s.objectStorage.SetRecord(s.ctx, s.jetID, core.FirstPulseNumber+10, &record.ObjectActivateRecord{ 137 ObjectStateRecord: record.ObjectStateRecord{ 138 Memory: blobID, 139 }, 140 IsDelegate: true, 141 }) 142 msg := &message.CallConstructor{} 143 var parcel core.Parcel = &message.Parcel{Msg: msg} 144 145 msgHash := platformpolicy.NewPlatformCryptographyScheme().IntegrityHasher().Hash(message.ToBytes(msg)) 146 requestID, err := s.objectStorage.SetRecord(s.ctx, s.jetID, core.FirstPulseNumber+10, &record.RequestRecord{ 147 MessageHash: msgHash, 148 Parcel: message.ParcelToBytes(parcel), 149 }) 150 require.NoError(s.T(), err) 151 152 result, err := s.exporter.Export(s.ctx, 0, 15) 153 require.NoError(s.T(), err) 154 assert.Equal(s.T(), 2, len(result.Data)) 155 assert.Equal(s.T(), 2, result.Size) 156 assert.Nil(s.T(), result.NextFrom) 157 158 result, err = s.exporter.Export(s.ctx, 0, 2) 159 require.NoError(s.T(), err) 160 assert.Equal(s.T(), 2, len(result.Data)) 161 assert.Equal(s.T(), 2, result.Size) 162 assert.Equal(s.T(), core.FirstPulseNumber+20, int(*result.NextFrom)) 163 _, err = json.Marshal(result) 164 assert.NoError(s.T(), err) 165 166 pulse := result.Data[strconv.FormatUint(uint64(core.FirstPulseNumber), 10)].([]*pulseData)[0].Pulse 167 assert.Equal(s.T(), core.FirstPulseNumber, int(pulse.PulseNumber)) 168 assert.Equal(s.T(), int64(0), pulse.PulseTimestamp) 169 pulse = result.Data[strconv.FormatUint(uint64(core.FirstPulseNumber+10), 10)].([]*pulseData)[0].Pulse 170 assert.Equal(s.T(), core.FirstPulseNumber+10, int(pulse.PulseNumber)) 171 assert.Equal(s.T(), int64(20), pulse.PulseTimestamp) 172 173 records := result.Data[strconv.FormatUint(uint64(core.FirstPulseNumber+10), 10)].([]*pulseData)[0].Records 174 object, ok := records[base58.Encode(objectID[:])] 175 if assert.True(s.T(), ok, "object not found by ID") { 176 assert.Equal(s.T(), "TypeActivate", object.Type) 177 assert.Equal(s.T(), true, object.Data.(*record.ObjectActivateRecord).IsDelegate) 178 assert.Equal(s.T(), "objectValue", object.Payload["Memory"].(payload)["Field"]) 179 } 180 181 request, ok := records[base58.Encode(requestID[:])] 182 if assert.True(s.T(), ok, "request not found by ID") { 183 assert.Equal(s.T(), "TypeCallRequest", request.Type) 184 assert.Equal(s.T(), msgHash, request.Data.(*record.RequestRecord).MessageHash) 185 assert.Equal(s.T(), core.TypeCallConstructor.String(), request.Payload["Type"]) 186 } 187 188 _, err = s.exporter.Export(s.ctx, 100000, 2) 189 require.Error(s.T(), err, "From-pulse should be smaller (or equal) current-pulse") 190 191 _, err = s.exporter.Export(s.ctx, 60000, 2) 192 require.NoError(s.T(), err, "From-pulse should be smaller (or equal) current-pulse") 193 } 194 195 func (s *exporterSuite) TestExporter_ExportGetBlobFailed() { 196 for i := 1; i <= 3; i++ { 197 err := s.pulseTracker.AddPulse( 198 s.ctx, 199 core.Pulse{ 200 PulseNumber: core.FirstPulseNumber + 10*core.PulseNumber(i), 201 PrevPulseNumber: core.FirstPulseNumber + 10*core.PulseNumber(i-1), 202 PulseTimestamp: 10 * int64(i+1), 203 }, 204 ) 205 require.NoError(s.T(), err) 206 } 207 208 _, err := s.objectStorage.SetRecord(s.ctx, s.jetID, core.FirstPulseNumber+10, &record.ObjectActivateRecord{ 209 ObjectStateRecord: record.ObjectStateRecord{ 210 Memory: &core.RecordID{}, 211 }, 212 IsDelegate: true, 213 }) 214 require.NoError(s.T(), err) 215 216 result, err := s.exporter.Export(s.ctx, core.FirstPulseNumber+10, 10) 217 assert.Equal(s.T(), 1, len(result.Data)) 218 assert.Equal(s.T(), 1, result.Size) 219 }