Write state diff to CSV #2
@ -1,13 +0,0 @@
|
||||
package builder_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestBuilder(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Builder Suite")
|
||||
}
|
@ -1,36 +1,18 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Contains a batch of utility type declarations used by the tests. As the node
|
||||
// operates on unique types, a lot of them are needed to check various features.
|
||||
|
||||
package builder_test
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
b "github.com/ethereum/go-ethereum/statediff/builder"
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/gomega"
|
||||
"testing"
|
||||
"math/big"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
b "github.com/ethereum/go-ethereum/statediff/builder"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"bytes"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -116,204 +98,205 @@ func testChainGen(i int, block *core.BlockGen) {
|
||||
}
|
||||
}
|
||||
|
||||
var _ = ginkgo.Describe("", func() {
|
||||
var (
|
||||
block0Hash, block1Hash, block2Hash, block3Hash common.Hash
|
||||
block0, block1, block2, block3 *types.Block
|
||||
builder b.Builder
|
||||
miningReward = int64(3000000000000000000)
|
||||
burnAddress = common.HexToAddress("0x0")
|
||||
diff *b.StateDiff
|
||||
err error
|
||||
)
|
||||
|
||||
func TestBuilder(t *testing.T) {
|
||||
_, blocks := makeChain(3, 0, genesis)
|
||||
block0Hash = common.HexToHash("0xd1721cfd0b29c36fd7a68f25c128e86413fb666a6e1d68e89b875bd299262661")
|
||||
block1Hash = common.HexToHash("0x47c398dd688eaa4dd11b006888156783fe32df83d59b197c0fcd303408103d39")
|
||||
block2Hash = common.HexToHash("0x351b2f531838683ba457e8ca4d3a844cc48147dceafbcb589dc6e3227856ee75")
|
||||
block3Hash = common.HexToHash("0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73")
|
||||
|
||||
block0 = blocks[block0Hash]
|
||||
block1 = blocks[block1Hash]
|
||||
block2 = blocks[block2Hash]
|
||||
block3 = blocks[block3Hash]
|
||||
builder = b.NewBuilder(testdb)
|
||||
|
||||
testEmptyDiff(t)
|
||||
testBlock1(t)
|
||||
testBlock2(t)
|
||||
testBlock3(t)
|
||||
}
|
||||
|
||||
var errorString = "Actual and expected do not match"
|
||||
|
||||
func testEmptyDiff(t *testing.T) {
|
||||
expectedDiff := b.StateDiff{
|
||||
BlockNumber: block0.Number().Int64(),
|
||||
BlockHash: block0Hash,
|
||||
CreatedAccounts: emptyAccountDiffEventualMap,
|
||||
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||
UpdatedAccounts: emptyAccountDiffIncrementalMap,
|
||||
}
|
||||
|
||||
diff, err := builder.BuildStateDiff(block0.Root(), block0.Root(), block0.Number().Int64(), block0Hash)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !equals(diff, &expectedDiff) {
|
||||
t.Errorf("Actual and expected do not match:\nActual: %+v\nExpected: %+v", diff, expectedDiff)
|
||||
}
|
||||
}
|
||||
|
||||
func testBlock1(t *testing.T) {
|
||||
//10000 transferred from testBankAddress to account1Addr
|
||||
var balanceChange = int64(10000)
|
||||
|
||||
diff, err = builder.BuildStateDiff(block0.Root(), block1.Root(), block1.Number().Int64(), block1Hash)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
//it includes the block number and hash
|
||||
if !equals(diff.BlockNumber, block1.Number().Int64()) { t.Errorf(errorString) }
|
||||
if !equals(diff.BlockHash, block1Hash) { t.Errorf(errorString)}
|
||||
|
||||
//it returns an empty collection for deleted accounts
|
||||
if !equals(diff.DeletedAccounts, emptyAccountDiffEventualMap) { t.Errorf(errorString)}
|
||||
|
||||
//it returns balance diffs for updated accounts
|
||||
expectedBankBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(testBankFunds.Int64() - balanceChange),
|
||||
OldValue: testBankFunds,
|
||||
}
|
||||
|
||||
if !equals(len(diff.UpdatedAccounts), 1) { t.Errorf(errorString) }
|
||||
if !equals(diff.UpdatedAccounts[testBankAddress].Balance, expectedBankBalanceDiff) { t.Errorf(errorString) }
|
||||
|
||||
//it returns balance diffs for new accounts
|
||||
expectedAccount1BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(balanceChange),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
expectedBurnAddrBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(miningReward),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
if !equals(len(diff.CreatedAccounts), 2) {}
|
||||
if !equals(diff.CreatedAccounts[account1Addr].Balance, expectedAccount1BalanceDiff) { t.Errorf(errorString) }
|
||||
if !equals(diff.CreatedAccounts[burnAddress].Balance, expectedBurnAddrBalanceDiff) { t.Errorf(errorString) }
|
||||
}
|
||||
|
||||
func testBlock2(t *testing.T) {
|
||||
//1000 transferred from testBankAddress to account1Addr
|
||||
//1000 transferred from account1Addr to account2Addr
|
||||
var (
|
||||
block0Hash, block1Hash, block2Hash, block3Hash common.Hash
|
||||
block0, block1, block2, block3 *types.Block
|
||||
builder b.Builder
|
||||
miningReward = int64(3000000000000000000)
|
||||
burnAddress = common.HexToAddress("0x0")
|
||||
diff *b.StateDiff
|
||||
err error
|
||||
balanceChange = int64(1000)
|
||||
block1BankBalance = int64(99990000)
|
||||
block1Account1Balance = int64(10000)
|
||||
)
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
_, blocks := makeChain(3, 0, genesis)
|
||||
block0Hash = common.HexToHash("0xd1721cfd0b29c36fd7a68f25c128e86413fb666a6e1d68e89b875bd299262661")
|
||||
block1Hash = common.HexToHash("0x47c398dd688eaa4dd11b006888156783fe32df83d59b197c0fcd303408103d39")
|
||||
block2Hash = common.HexToHash("0x351b2f531838683ba457e8ca4d3a844cc48147dceafbcb589dc6e3227856ee75")
|
||||
block3Hash = common.HexToHash("0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73")
|
||||
diff, err = builder.BuildStateDiff(block1.Root(), block2.Root(), block2.Number().Int64(), block2Hash)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
//it includes the block number and hash
|
||||
if !equals(diff.BlockNumber, block2.Number().Int64()) { t.Errorf(errorString)}
|
||||
if !equals(diff.BlockHash, block2Hash) {}
|
||||
|
||||
block0 = blocks[block0Hash]
|
||||
block1 = blocks[block1Hash]
|
||||
block2 = blocks[block2Hash]
|
||||
block3 = blocks[block3Hash]
|
||||
builder = b.NewBuilder(testdb)
|
||||
})
|
||||
//it returns an empty collection for deleted accounts
|
||||
if !equals(diff.DeletedAccounts, emptyAccountDiffEventualMap) { t.Errorf(errorString) }
|
||||
|
||||
ginkgo.It("returns empty account diff collections when the state root hasn't changed", func() {
|
||||
expectedDiff := b.StateDiff{
|
||||
BlockNumber: block0.Number().Int64(),
|
||||
BlockHash: block0Hash,
|
||||
CreatedAccounts: emptyAccountDiffEventualMap,
|
||||
DeletedAccounts: emptyAccountDiffEventualMap,
|
||||
UpdatedAccounts: emptyAccountDiffIncrementalMap,
|
||||
//it returns balance diffs for updated accounts
|
||||
expectedBankBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(block1BankBalance - balanceChange),
|
||||
OldValue: big.NewInt(block1BankBalance),
|
||||
}
|
||||
|
||||
expectedAccount1BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(block1Account1Balance - balanceChange + balanceChange),
|
||||
OldValue: big.NewInt(block1Account1Balance),
|
||||
}
|
||||
|
||||
expectedBurnBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(miningReward + miningReward),
|
||||
OldValue: big.NewInt(miningReward),
|
||||
}
|
||||
|
||||
if !equals(len(diff.UpdatedAccounts), 3) { t.Errorf(errorString) }
|
||||
if !equals(diff.UpdatedAccounts[testBankAddress].Balance, expectedBankBalanceDiff) { t.Errorf(errorString) }
|
||||
if !equals(diff.UpdatedAccounts[account1Addr].Balance, expectedAccount1BalanceDiff) { t.Errorf(errorString) }
|
||||
if !equals(diff.UpdatedAccounts[burnAddress].Balance, expectedBurnBalanceDiff) { t.Errorf(errorString) }
|
||||
|
||||
//it returns balance diffs for new accounts
|
||||
expectedAccount2BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(balanceChange),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
expectedContractBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(0),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
if !equals(len(diff.CreatedAccounts), 2) { t.Errorf(errorString) }
|
||||
if !equals(diff.CreatedAccounts[account2Addr].Balance, expectedAccount2BalanceDiff) { t.Errorf(errorString) }
|
||||
if !equals(diff.CreatedAccounts[contractAddr].Balance, expectedContractBalanceDiff) { t.Errorf(errorString) }
|
||||
}
|
||||
|
||||
func testBlock3(t *testing.T) {
|
||||
diff, err = builder.BuildStateDiff(block2.Root(), block3.Root(), block3.Number().Int64(), block3Hash)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
//it includes the block number and hash
|
||||
if !equals(diff.BlockNumber, block3.Number().Int64()) { t.Errorf(errorString) }
|
||||
if !equals(diff.BlockHash, block3Hash) { t.Errorf(errorString) }
|
||||
|
||||
//it returns an empty collection for deleted accounts
|
||||
if !equals(diff.DeletedAccounts, emptyAccountDiffEventualMap) { t.Errorf(errorString) }
|
||||
|
||||
//it returns an empty collection for created accounts
|
||||
if !equals(diff.CreatedAccounts, emptyAccountDiffEventualMap) { t.Errorf(errorString) }
|
||||
|
||||
//it returns balance, storage and nonce diffs for updated accounts
|
||||
block2Account2Balance := int64(1000)
|
||||
expectedAcct2BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(block2Account2Balance + miningReward),
|
||||
OldValue: big.NewInt(block2Account2Balance),
|
||||
}
|
||||
|
||||
diff, err := builder.BuildStateDiff(block0.Root(), block0.Root(), block0.Number().Int64(), block0Hash)
|
||||
expectedContractStorageDiff := make(map[string]b.DiffString)
|
||||
newVal := "0x03"
|
||||
oldVal := "0x0"
|
||||
path := "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"
|
||||
expectedContractStorageDiff[path] = b.DiffString{
|
||||
NewValue: &newVal,
|
||||
OldValue: &oldVal,
|
||||
}
|
||||
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
gomega.Expect(diff).To(gomega.Equal(&expectedDiff))
|
||||
})
|
||||
oldNonce := uint64(2)
|
||||
newNonce := uint64(3)
|
||||
expectedBankNonceDiff := b.DiffUint64{
|
||||
NewValue: &newNonce,
|
||||
OldValue: &oldNonce,
|
||||
}
|
||||
|
||||
ginkgo.Context("Block 1", func() {
|
||||
//10000 transferred from testBankAddress to account1Addr
|
||||
var balanceChange = int64(10000)
|
||||
if !equals(len(diff.UpdatedAccounts), 3) { t.Errorf(errorString) }
|
||||
if !equals(diff.UpdatedAccounts[account2Addr].Balance, expectedAcct2BalanceDiff) { t.Errorf(errorString) }
|
||||
if !equals(diff.UpdatedAccounts[contractAddr].Storage, expectedContractStorageDiff) { t.Errorf(errorString) }
|
||||
if !equals(diff.UpdatedAccounts[testBankAddress].Nonce, expectedBankNonceDiff) { t.Errorf(errorString) }
|
||||
}
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
diff, err = builder.BuildStateDiff(block0.Root(), block1.Root(), block1.Number().Int64(), block1Hash)
|
||||
func equals(actual, expected interface{}) (success bool) {
|
||||
if actualByteSlice, ok := actual.([]byte); ok {
|
||||
if expectedByteSlice, ok := expected.([]byte); ok {
|
||||
return bytes.Equal(actualByteSlice, expectedByteSlice)
|
||||
}
|
||||
}
|
||||
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
ginkgo.It("includes the block number and hash", func() {
|
||||
gomega.Expect(diff.BlockNumber).To(gomega.Equal(block1.Number().Int64()))
|
||||
gomega.Expect(diff.BlockHash).To(gomega.Equal(block1Hash))
|
||||
})
|
||||
|
||||
ginkgo.It("returns an empty collection for deleted accounts", func() {
|
||||
gomega.Expect(diff.DeletedAccounts).To(gomega.Equal(emptyAccountDiffEventualMap))
|
||||
})
|
||||
|
||||
ginkgo.It("returns balance diffs for updated accounts", func() {
|
||||
expectedBankBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(testBankFunds.Int64() - balanceChange),
|
||||
OldValue: testBankFunds,
|
||||
}
|
||||
|
||||
gomega.Expect(len(diff.UpdatedAccounts)).To(gomega.Equal(1))
|
||||
gomega.Expect(diff.UpdatedAccounts[testBankAddress].Balance).To(gomega.Equal(expectedBankBalanceDiff))
|
||||
})
|
||||
|
||||
ginkgo.It("returns balance diffs for new accounts", func() {
|
||||
expectedAccount1BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(balanceChange),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
expectedBurnAddrBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(miningReward),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
gomega.Expect(len(diff.CreatedAccounts)).To(gomega.Equal(2))
|
||||
gomega.Expect(diff.CreatedAccounts[account1Addr].Balance).To(gomega.Equal(expectedAccount1BalanceDiff))
|
||||
gomega.Expect(diff.CreatedAccounts[burnAddress].Balance).To(gomega.Equal(expectedBurnAddrBalanceDiff))
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.Context("Block 2", func() {
|
||||
//1000 transferred from testBankAddress to account1Addr
|
||||
//1000 transferred from account1Addr to account2Addr
|
||||
var (
|
||||
balanceChange = int64(1000)
|
||||
block1BankBalance = int64(99990000)
|
||||
block1Account1Balance = int64(10000)
|
||||
)
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
diff, err = builder.BuildStateDiff(block1.Root(), block2.Root(), block2.Number().Int64(), block2Hash)
|
||||
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
ginkgo.It("includes the block number and hash", func() {
|
||||
gomega.Expect(diff.BlockNumber).To(gomega.Equal(block2.Number().Int64()))
|
||||
gomega.Expect(diff.BlockHash).To(gomega.Equal(block2Hash))
|
||||
})
|
||||
|
||||
ginkgo.It("returns an empty collection for deleted accounts", func() {
|
||||
gomega.Expect(diff.DeletedAccounts).To(gomega.Equal(emptyAccountDiffEventualMap))
|
||||
})
|
||||
|
||||
ginkgo.It("returns balance diffs for updated accounts", func() {
|
||||
expectedBankBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(block1BankBalance - balanceChange),
|
||||
OldValue: big.NewInt(block1BankBalance),
|
||||
}
|
||||
|
||||
expectedAccount1BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(block1Account1Balance - balanceChange + balanceChange),
|
||||
OldValue: big.NewInt(block1Account1Balance),
|
||||
}
|
||||
|
||||
expectedBurnBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(miningReward + miningReward),
|
||||
OldValue: big.NewInt(miningReward),
|
||||
}
|
||||
|
||||
gomega.Expect(len(diff.UpdatedAccounts)).To(gomega.Equal(3))
|
||||
gomega.Expect(diff.UpdatedAccounts[testBankAddress].Balance).To(gomega.Equal(expectedBankBalanceDiff))
|
||||
gomega.Expect(diff.UpdatedAccounts[account1Addr].Balance).To(gomega.Equal(expectedAccount1BalanceDiff))
|
||||
gomega.Expect(diff.UpdatedAccounts[burnAddress].Balance).To(gomega.Equal(expectedBurnBalanceDiff))
|
||||
})
|
||||
|
||||
ginkgo.It("returns balance diffs for new accounts", func() {
|
||||
expectedAccount2BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(balanceChange),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
expectedContractBalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(0),
|
||||
OldValue: nil,
|
||||
}
|
||||
|
||||
gomega.Expect(len(diff.CreatedAccounts)).To(gomega.Equal(2))
|
||||
gomega.Expect(diff.CreatedAccounts[account2Addr].Balance).To(gomega.Equal(expectedAccount2BalanceDiff))
|
||||
gomega.Expect(diff.CreatedAccounts[contractAddr].Balance).To(gomega.Equal(expectedContractBalanceDiff))
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.Context("Block 3", func() {
|
||||
//the contract's storage is changed
|
||||
//and the block is mined by account 2
|
||||
ginkgo.BeforeEach(func() {
|
||||
diff, err = builder.BuildStateDiff(block2.Root(), block3.Root(), block3.Number().Int64(), block3Hash)
|
||||
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
ginkgo.It("includes the block number and hash", func() {
|
||||
gomega.Expect(diff.BlockNumber).To(gomega.Equal(block3.Number().Int64()))
|
||||
gomega.Expect(diff.BlockHash).To(gomega.Equal(block3Hash))
|
||||
})
|
||||
|
||||
ginkgo.It("returns an empty collection for deleted accounts", func() {
|
||||
gomega.Expect(diff.DeletedAccounts).To(gomega.Equal(emptyAccountDiffEventualMap))
|
||||
})
|
||||
|
||||
ginkgo.It("returns an empty collection for created accounts", func() {
|
||||
gomega.Expect(diff.CreatedAccounts).To(gomega.Equal(emptyAccountDiffEventualMap))
|
||||
})
|
||||
|
||||
ginkgo.It("returns balance, storage and nonce diffs for updated accounts", func() {
|
||||
block2Account2Balance := int64(1000)
|
||||
expectedAcct2BalanceDiff := b.DiffBigInt{
|
||||
NewValue: big.NewInt(block2Account2Balance + miningReward),
|
||||
OldValue: big.NewInt(block2Account2Balance),
|
||||
}
|
||||
|
||||
expectedContractStorageDiff := make(map[string]b.DiffString)
|
||||
newVal := "0x03"
|
||||
oldVal := "0x0"
|
||||
path := "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"
|
||||
expectedContractStorageDiff[path] = b.DiffString{
|
||||
NewValue: &newVal,
|
||||
OldValue: &oldVal,
|
||||
}
|
||||
|
||||
oldNonce := uint64(2)
|
||||
newNonce := uint64(3)
|
||||
expectedBankNonceDiff := b.DiffUint64{
|
||||
NewValue: &newNonce,
|
||||
OldValue: &oldNonce,
|
||||
}
|
||||
|
||||
gomega.Expect(len(diff.UpdatedAccounts)).To(gomega.Equal(3))
|
||||
gomega.Expect(diff.UpdatedAccounts[account2Addr].Balance).To(gomega.Equal(expectedAcct2BalanceDiff))
|
||||
gomega.Expect(diff.UpdatedAccounts[contractAddr].Storage).To(gomega.Equal(expectedContractStorageDiff))
|
||||
gomega.Expect(diff.UpdatedAccounts[testBankAddress].Nonce).To(gomega.Equal(expectedBankNonceDiff))
|
||||
})
|
||||
})
|
||||
})
|
||||
return reflect.DeepEqual(actual, expected)
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package extractor_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestExtractor(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Extractor Suite")
|
||||
}
|
@ -1,101 +1,108 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Contains a batch of utility type declarations used by the tests. As the node
|
||||
// operates on unique types, a lot of them are needed to check various features.
|
||||
|
||||
package extractor_test
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
b "github.com/ethereum/go-ethereum/statediff/builder"
|
||||
e "github.com/ethereum/go-ethereum/statediff/extractor"
|
||||
"testing"
|
||||
"github.com/ethereum/go-ethereum/statediff/testhelpers"
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/gomega"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
b "github.com/ethereum/go-ethereum/statediff/builder"
|
||||
e "github.com/ethereum/go-ethereum/statediff/extractor"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"bytes"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var _ = ginkgo.Describe("Extractor", func() {
|
||||
var publisher testhelpers.MockPublisher
|
||||
var builder testhelpers.MockBuilder
|
||||
var currentBlockNumber *big.Int
|
||||
var parentBlock, currentBlock *types.Block
|
||||
var expectedStateDiff b.StateDiff
|
||||
var extractor e.Extractor
|
||||
var err error
|
||||
var publisher testhelpers.MockPublisher
|
||||
var builder testhelpers.MockBuilder
|
||||
var currentBlockNumber *big.Int
|
||||
var parentBlock, currentBlock *types.Block
|
||||
var expectedStateDiff b.StateDiff
|
||||
var extractor e.Extractor
|
||||
var err error
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
publisher = testhelpers.MockPublisher{}
|
||||
builder = testhelpers.MockBuilder{}
|
||||
extractor, err = e.NewExtractor(&builder, &publisher)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
func TestExtractor(t *testing.T) {
|
||||
publisher = testhelpers.MockPublisher{}
|
||||
builder = testhelpers.MockBuilder{}
|
||||
extractor, err = e.NewExtractor(&builder, &publisher)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
blockNumber := rand.Int63()
|
||||
parentBlockNumber := big.NewInt(blockNumber - int64(1))
|
||||
currentBlockNumber = big.NewInt(blockNumber)
|
||||
parentBlock = types.NewBlock(&types.Header{Number: parentBlockNumber}, nil, nil, nil)
|
||||
currentBlock = types.NewBlock(&types.Header{Number: currentBlockNumber}, nil, nil, nil)
|
||||
blockNumber := rand.Int63()
|
||||
parentBlockNumber := big.NewInt(blockNumber - int64(1))
|
||||
currentBlockNumber = big.NewInt(blockNumber)
|
||||
parentBlock = types.NewBlock(&types.Header{Number: parentBlockNumber}, nil, nil, nil)
|
||||
currentBlock = types.NewBlock(&types.Header{Number: currentBlockNumber}, nil, nil, nil)
|
||||
|
||||
expectedStateDiff = b.StateDiff{
|
||||
BlockNumber: blockNumber,
|
||||
BlockHash: currentBlock.Hash(),
|
||||
CreatedAccounts: nil,
|
||||
DeletedAccounts: nil,
|
||||
UpdatedAccounts: nil,
|
||||
expectedStateDiff = b.StateDiff{
|
||||
BlockNumber: blockNumber,
|
||||
BlockHash: currentBlock.Hash(),
|
||||
CreatedAccounts: nil,
|
||||
DeletedAccounts: nil,
|
||||
UpdatedAccounts: nil,
|
||||
}
|
||||
|
||||
testBuildStateDiffStruct(t)
|
||||
testBuildStateDiffErrorHandling(t)
|
||||
testPublishingStateDiff(t)
|
||||
testPublisherErrorHandling(t)
|
||||
}
|
||||
|
||||
func testBuildStateDiffStruct(t *testing.T) {
|
||||
builder.SetStateDiffToBuild(&expectedStateDiff)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !equals(builder.OldStateRoot, parentBlock.Root()) { t.Error()}
|
||||
if !equals(builder.NewStateRoot, currentBlock.Root()) { t.Error()}
|
||||
if !equals(builder.BlockNumber,currentBlockNumber.Int64()) { t.Error()}
|
||||
if !equals(builder.BlockHash, currentBlock.Hash()) { t.Error()}
|
||||
}
|
||||
|
||||
func testBuildStateDiffErrorHandling(t *testing.T) {
|
||||
builder.SetBuilderError(testhelpers.MockError)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
if err == nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !equals(err, testhelpers.MockError) { t.Error() }
|
||||
builder.SetBuilderError(nil)
|
||||
}
|
||||
|
||||
func testPublishingStateDiff(t *testing.T) {
|
||||
builder.SetStateDiffToBuild(&expectedStateDiff)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !equals(publisher.StateDiff, &expectedStateDiff) { t.Error() }
|
||||
}
|
||||
|
||||
func testPublisherErrorHandling(t *testing.T) {
|
||||
publisher.SetPublisherError(testhelpers.MockError)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, but it didn't occur.")
|
||||
}
|
||||
if !equals(err, testhelpers.MockError) { t.Error() }
|
||||
|
||||
publisher.SetPublisherError(nil)
|
||||
}
|
||||
|
||||
func equals(actual, expected interface{}) (success bool) {
|
||||
if actualByteSlice, ok := actual.([]byte); ok {
|
||||
if expectedByteSlice, ok := expected.([]byte); ok {
|
||||
return bytes.Equal(actualByteSlice, expectedByteSlice)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ginkgo.It("builds a state diff struct", func() {
|
||||
builder.SetStateDiffToBuild(&expectedStateDiff)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
gomega.Expect(builder.OldStateRoot).To(gomega.Equal(parentBlock.Root()))
|
||||
gomega.Expect(builder.NewStateRoot).To(gomega.Equal(currentBlock.Root()))
|
||||
gomega.Expect(builder.BlockNumber).To(gomega.Equal(currentBlockNumber.Int64()))
|
||||
gomega.Expect(builder.BlockHash).To(gomega.Equal(currentBlock.Hash()))
|
||||
})
|
||||
|
||||
ginkgo.It("returns an error if building the state diff fails", func() {
|
||||
builder.SetBuilderError(testhelpers.MockError)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
|
||||
gomega.Expect(err).To(gomega.HaveOccurred())
|
||||
gomega.Expect(err).To(gomega.MatchError(testhelpers.MockError))
|
||||
})
|
||||
|
||||
ginkgo.It("publishes the state diff struct", func() {
|
||||
builder.SetStateDiffToBuild(&expectedStateDiff)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
gomega.Expect(publisher.StateDiff).To(gomega.Equal(&expectedStateDiff))
|
||||
})
|
||||
|
||||
ginkgo.It("returns an error if publishing the diff fails", func() {
|
||||
publisher.SetPublisherError(testhelpers.MockError)
|
||||
|
||||
_, err = extractor.ExtractStateDiff(*parentBlock, *currentBlock)
|
||||
|
||||
gomega.Expect(err).To(gomega.HaveOccurred())
|
||||
gomega.Expect(err).To(gomega.MatchError(testhelpers.MockError))
|
||||
})
|
||||
})
|
||||
return reflect.DeepEqual(actual, expected)
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package publisher_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestPublisher(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Publisher Suite")
|
||||
}
|
@ -1,169 +1,237 @@
|
||||
package publisher_test
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"github.com/ethereum/go-ethereum/statediff"
|
||||
"github.com/ethereum/go-ethereum/statediff/builder"
|
||||
p "github.com/ethereum/go-ethereum/statediff/publisher"
|
||||
"github.com/ethereum/go-ethereum/statediff/testhelpers"
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/gomega"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"github.com/ethereum/go-ethereum/statediff/testhelpers"
|
||||
p "github.com/ethereum/go-ethereum/statediff/publisher"
|
||||
"io/ioutil"
|
||||
"github.com/ethereum/go-ethereum/statediff"
|
||||
"encoding/csv"
|
||||
"path/filepath"
|
||||
"bytes"
|
||||
"reflect"
|
||||
"github.com/ethereum/go-ethereum/statediff/builder"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var _ = ginkgo.Describe("Publisher", func() {
|
||||
var (
|
||||
tempDir = os.TempDir()
|
||||
testFilePrefix = "test-statediff"
|
||||
publisher p.Publisher
|
||||
dir string
|
||||
err error
|
||||
)
|
||||
var (
|
||||
tempDir = os.TempDir()
|
||||
testFilePrefix = "test-statediff"
|
||||
publisher p.Publisher
|
||||
dir string
|
||||
err error
|
||||
)
|
||||
|
||||
var expectedCreatedAccountRow = []string{
|
||||
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||
testhelpers.BlockHash,
|
||||
"created",
|
||||
"created account code",
|
||||
testhelpers.CodeHash,
|
||||
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.StoragePath,
|
||||
var expectedCreatedAccountRow = []string{
|
||||
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||
testhelpers.BlockHash,
|
||||
"created",
|
||||
"created account code",
|
||||
testhelpers.CodeHash,
|
||||
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.StoragePath,
|
||||
}
|
||||
|
||||
var expectedUpdatedAccountRow = []string{
|
||||
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||
testhelpers.BlockHash,
|
||||
"updated",
|
||||
"",
|
||||
testhelpers.CodeHash,
|
||||
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.StoragePath,
|
||||
}
|
||||
|
||||
var expectedDeletedAccountRow = []string{
|
||||
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||
testhelpers.BlockHash,
|
||||
"deleted",
|
||||
"deleted account code",
|
||||
testhelpers.CodeHash,
|
||||
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.StoragePath,
|
||||
}
|
||||
|
||||
|
||||
|
||||
func TestPublisher(t *testing.T) {
|
||||
dir, err = ioutil.TempDir(tempDir, testFilePrefix)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
config := statediff.Config{
|
||||
Path: dir,
|
||||
Mode: statediff.CSV,
|
||||
}
|
||||
publisher, err = p.NewPublisher(config)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
var expectedUpdatedAccountRow = []string{
|
||||
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||
testhelpers.BlockHash,
|
||||
"updated",
|
||||
"",
|
||||
testhelpers.CodeHash,
|
||||
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.StoragePath,
|
||||
type Test func(t *testing.T)
|
||||
|
||||
var tests = []Test{testColumnHeaders,
|
||||
testAccountDiffs,
|
||||
testWhenNoDiff,
|
||||
testDefaultPublisher,
|
||||
testDefaultDirectory,
|
||||
}
|
||||
|
||||
var expectedDeletedAccountRow = []string{
|
||||
strconv.FormatInt(testhelpers.BlockNumber, 10),
|
||||
testhelpers.BlockHash,
|
||||
"deleted",
|
||||
"deleted account code",
|
||||
testhelpers.CodeHash,
|
||||
strconv.FormatUint(testhelpers.OldNonceValue, 10),
|
||||
strconv.FormatUint(testhelpers.NewNonceValue, 10),
|
||||
strconv.FormatInt(testhelpers.OldBalanceValue, 10),
|
||||
strconv.FormatInt(testhelpers.NewBalanceValue, 10),
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.ContractRoot,
|
||||
testhelpers.StoragePath,
|
||||
for _, test := range tests {
|
||||
test(t)
|
||||
removeFilesFromDir(dir, t)
|
||||
}
|
||||
}
|
||||
|
||||
func removeFilesFromDir(dir string, t *testing.T) {
|
||||
files, err := filepath.Glob(filepath.Join(dir, "*"))
|
||||
if err != nil {
|
||||
t.Error()
|
||||
}
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
dir, err = ioutil.TempDir(tempDir, testFilePrefix)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
config := statediff.Config{
|
||||
Path: dir,
|
||||
Mode: statediff.CSV,
|
||||
for _, file := range files {
|
||||
err = os.RemoveAll(file)
|
||||
if err !=nil {
|
||||
t.Error()
|
||||
}
|
||||
publisher, err = p.NewPublisher(config)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
ginkgo.AfterEach(func() {
|
||||
os.RemoveAll(dir)
|
||||
})
|
||||
func testColumnHeaders(t *testing.T) {
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
ginkgo.It("persists the column headers to a CSV file", func() {
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
file, err := getTestDiffFile(dir)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
file, err := getTestDiffFile(dir)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(lines) <= 1 { t.Error() }
|
||||
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
gomega.Expect(len(lines) > 1).To(gomega.BeTrue())
|
||||
gomega.Expect(lines[0]).To(gomega.Equal(p.Headers))
|
||||
})
|
||||
if !equals(lines[0], p.Headers) { t.Error() }
|
||||
}
|
||||
|
||||
ginkgo.It("persists the created, upated and deleted account diffs to a CSV file", func() {
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
func testAccountDiffs(t *testing.T) {
|
||||
// it persists the created, updated and deleted account diffs to a CSV file
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
file, err := getTestDiffFile(dir)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
file, err := getTestDiffFile(dir)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
gomega.Expect(len(lines) > 3).To(gomega.BeTrue())
|
||||
gomega.Expect(lines[1]).To(gomega.Equal(expectedCreatedAccountRow))
|
||||
gomega.Expect(lines[2]).To(gomega.Equal(expectedUpdatedAccountRow))
|
||||
gomega.Expect(lines[3]).To(gomega.Equal(expectedDeletedAccountRow))
|
||||
})
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(lines) <= 3 { t.Error() }
|
||||
if !equals(lines[1], expectedCreatedAccountRow) { t.Error() }
|
||||
if !equals(lines[2], expectedUpdatedAccountRow) { t.Error()}
|
||||
if !equals(lines[3], expectedDeletedAccountRow) { t.Error()}
|
||||
}
|
||||
|
||||
ginkgo.It("creates an empty CSV when there is no diff", func() {
|
||||
emptyDiff := builder.StateDiff{}
|
||||
_, err = publisher.PublishStateDiff(&emptyDiff)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
func testWhenNoDiff(t *testing.T) {
|
||||
//it creates an empty CSV when there is no diff", func() {
|
||||
emptyDiff := builder.StateDiff{}
|
||||
_, err = publisher.PublishStateDiff(&emptyDiff)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
file, err := getTestDiffFile(dir)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
file, err := getTestDiffFile(dir)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
gomega.Expect(len(lines)).To(gomega.Equal(1))
|
||||
})
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !equals(len(lines), 1) { t.Error() }
|
||||
}
|
||||
|
||||
ginkgo.It("defaults to publishing state diffs to a CSV file when no mode is configured", func() {
|
||||
config := statediff.Config{Path: dir}
|
||||
publisher, err = p.NewPublisher(config)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
func testDefaultPublisher(t *testing.T) {
|
||||
//it defaults to publishing state diffs to a CSV file when no mode is configured
|
||||
config := statediff.Config{Path: dir}
|
||||
publisher, err = p.NewPublisher(config)
|
||||
if err != nil { t.Error(err) }
|
||||
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
if err != nil { t.Error(err) }
|
||||
|
||||
file, err := getTestDiffFile(dir)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
file, err := getTestDiffFile(dir)
|
||||
if err != nil { t.Error(err) }
|
||||
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
gomega.Expect(len(lines)).To(gomega.Equal(4))
|
||||
gomega.Expect(lines[0]).To(gomega.Equal(p.Headers))
|
||||
})
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
if err != nil { t.Error(err) }
|
||||
if !equals(len(lines), 4) { t.Error()}
|
||||
if !equals(lines[0],p.Headers) { t.Error()}
|
||||
}
|
||||
|
||||
ginkgo.It("defaults to publishing CSV files in the current directory when no path is configured", func() {
|
||||
config := statediff.Config{}
|
||||
publisher, err = p.NewPublisher(config)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
func testDefaultDirectory(t *testing.T) {
|
||||
//it defaults to publishing CSV files in the current directory when no path is configured
|
||||
config := statediff.Config{}
|
||||
publisher, err = p.NewPublisher(config)
|
||||
if err != nil { t.Error(err) }
|
||||
|
||||
err := os.Chdir(dir)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
err := os.Chdir(dir)
|
||||
if err != nil { t.Error(err) }
|
||||
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
_, err = publisher.PublishStateDiff(&testhelpers.TestStateDiff)
|
||||
if err != nil { t.Error(err) }
|
||||
|
||||
file, err := getTestDiffFile(dir)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
file, err := getTestDiffFile(dir)
|
||||
if err != nil { t.Error(err) }
|
||||
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
gomega.Expect(len(lines)).To(gomega.Equal(4))
|
||||
gomega.Expect(lines[0]).To(gomega.Equal(p.Headers))
|
||||
})
|
||||
})
|
||||
lines, err := csv.NewReader(file).ReadAll()
|
||||
if err != nil { t.Error(err) }
|
||||
if !equals(len(lines), 4) { t.Error() }
|
||||
if !equals(lines[0], p.Headers) { t.Error() }
|
||||
}
|
||||
|
||||
func getTestDiffFile(dir string) (*os.File, error) {
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
gomega.Expect(len(files) > 0).To(gomega.BeTrue())
|
||||
if err != nil { return nil, err }
|
||||
if len(files) == 0 { return nil, errors.New("There are 0 files.") }
|
||||
|
||||
fileName := files[0].Name()
|
||||
filePath := filepath.Join(dir, fileName)
|
||||
|
||||
return os.Open(filePath)
|
||||
}
|
||||
|
||||
func equals(actual, expected interface{}) (success bool) {
|
||||
if actualByteSlice, ok := actual.([]byte); ok {
|
||||
if expectedByteSlice, ok := expected.([]byte); ok {
|
||||
return bytes.Equal(actualByteSlice, expectedByteSlice)
|
||||
}
|
||||
}
|
||||
|
||||
return reflect.DeepEqual(actual, expected)
|
||||
}
|
||||
|
@ -11,3 +11,6 @@ func TestStatediff(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Statediff Suite")
|
||||
}
|
||||
|
||||
//convert this over to use built in golang library
|
||||
//only save the new value, and have a pointer to the old value - not sure how this pointer will work for the CSV version
|
||||
|
Loading…
Reference in New Issue
Block a user