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  }