Test validateBasic methods
This commit is contained in:
@@ -101,7 +101,7 @@ func TestFailFastImport(t *testing.T) {
|
||||
}},
|
||||
Contracts: nil,
|
||||
}},
|
||||
"happy path: code info and contract do match": {
|
||||
"happy path: code id in info and contract do match": {
|
||||
src: types.GenesisState{
|
||||
Codes: []types.Code{{
|
||||
CodeInfo: wasmTypes.CodeInfo{
|
||||
@@ -112,13 +112,8 @@ func TestFailFastImport(t *testing.T) {
|
||||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: addrFromUint64(1<<32 + 1),
|
||||
ContractInfo: wasmTypes.ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
},
|
||||
ContractAddress: contractAddress(1, 1),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -135,21 +130,11 @@ func TestFailFastImport(t *testing.T) {
|
||||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: addrFromUint64(1<<32 + 1),
|
||||
ContractInfo: wasmTypes.ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
},
|
||||
ContractAddress: contractAddress(1, 1),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }),
|
||||
}, {
|
||||
ContractAddress: addrFromUint64(2<<32 + 1),
|
||||
ContractInfo: wasmTypes.ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
},
|
||||
ContractAddress: contractAddress(2, 1),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -160,17 +145,12 @@ func TestFailFastImport(t *testing.T) {
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: contractAddress(1, 1),
|
||||
ContractInfo: wasmTypes.ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
},
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"prevent duplicate contracts": {
|
||||
"prevent duplicate contract address": {
|
||||
src: types.GenesisState{
|
||||
Codes: []types.Code{{
|
||||
CodeInfo: wasmTypes.CodeInfo{
|
||||
@@ -182,25 +162,15 @@ func TestFailFastImport(t *testing.T) {
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: contractAddress(1, 1),
|
||||
ContractInfo: wasmTypes.ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
},
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }),
|
||||
}, {
|
||||
ContractAddress: contractAddress(1, 1),
|
||||
ContractInfo: wasmTypes.ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
},
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"prevent duplicate contract model": {
|
||||
"prevent duplicate contract model keys": {
|
||||
src: types.GenesisState{
|
||||
Codes: []types.Code{{
|
||||
CodeInfo: wasmTypes.CodeInfo{
|
||||
@@ -211,13 +181,8 @@ func TestFailFastImport(t *testing.T) {
|
||||
}},
|
||||
Contracts: []types.Contract{
|
||||
{
|
||||
ContractAddress: addrFromUint64(1<<32 + 1),
|
||||
ContractInfo: wasmTypes.ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
},
|
||||
ContractAddress: contractAddress(1, 1),
|
||||
ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }),
|
||||
ContractState: []types.Model{
|
||||
{
|
||||
Key: []byte{0x1},
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/libs/rand"
|
||||
)
|
||||
|
||||
func TestValidateGenesisState(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
srcMutator func(state GenesisState)
|
||||
srcMutator func(*GenesisState)
|
||||
expError bool
|
||||
}{
|
||||
"all good": {
|
||||
srcMutator: func(s GenesisState) {},
|
||||
srcMutator: func(s *GenesisState) {},
|
||||
},
|
||||
"codeinfo invalid": {
|
||||
srcMutator: func(s GenesisState) {
|
||||
srcMutator: func(s *GenesisState) {
|
||||
s.Codes[0].CodeInfo.CodeHash = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"contract invalid": {
|
||||
srcMutator: func(s GenesisState) {
|
||||
srcMutator: func(s *GenesisState) {
|
||||
s.Contracts[0].ContractAddress = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"sequence invalid": {
|
||||
srcMutator: func(s GenesisState) {
|
||||
srcMutator: func(s *GenesisState) {
|
||||
s.Sequences[0].IDKey = nil
|
||||
},
|
||||
expError: true,
|
||||
@@ -37,7 +36,7 @@ func TestValidateGenesisState(t *testing.T) {
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
state := genesisFixture(spec.srcMutator)
|
||||
state := GenesisFixture(spec.srcMutator)
|
||||
got := state.ValidateBasic()
|
||||
if spec.expError {
|
||||
require.Error(t, got)
|
||||
@@ -46,62 +45,86 @@ func TestValidateGenesisState(t *testing.T) {
|
||||
require.NoError(t, got)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func genesisFixture(mutators ...func(state GenesisState)) GenesisState {
|
||||
const (
|
||||
numCodes = 2
|
||||
numContracts = 2
|
||||
numSequences = 2
|
||||
)
|
||||
|
||||
fixture := GenesisState{
|
||||
Codes: make([]Code, numCodes),
|
||||
Contracts: make([]Contract, numContracts),
|
||||
Sequences: make([]Sequence, numSequences),
|
||||
}
|
||||
for i := 0; i < numCodes; i++ {
|
||||
fixture.Codes[i] = codeFixture()
|
||||
}
|
||||
for i := 0; i < numContracts; i++ {
|
||||
fixture.Contracts[i] = contractFixture()
|
||||
}
|
||||
for i := 0; i < numSequences; i++ {
|
||||
fixture.Sequences[i] = Sequence{
|
||||
IDKey: rand.Bytes(5),
|
||||
Value: uint64(i),
|
||||
}
|
||||
}
|
||||
for _, m := range mutators {
|
||||
m(fixture)
|
||||
}
|
||||
return fixture
|
||||
}
|
||||
|
||||
func codeFixture() Code {
|
||||
wasmCode := rand.Bytes(100)
|
||||
codeHash := sha256.Sum256(wasmCode)
|
||||
anyAddress := make([]byte, 20)
|
||||
|
||||
return Code{
|
||||
CodeInfo: CodeInfo{
|
||||
CodeHash: codeHash[:],
|
||||
Creator: anyAddress,
|
||||
func TestCodeValidateBasic(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
srcMutator func(*Code)
|
||||
expError bool
|
||||
}{
|
||||
"all good": {srcMutator: func(_ *Code) {}},
|
||||
"codeinfo invalid": {
|
||||
srcMutator: func(c *Code) {
|
||||
c.CodeInfo.CodeHash = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
CodesBytes: wasmCode,
|
||||
}
|
||||
}
|
||||
|
||||
func contractFixture() Contract {
|
||||
anyAddress := make([]byte, 20)
|
||||
return Contract{
|
||||
ContractAddress: anyAddress,
|
||||
ContractInfo: ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
"codeBytes empty": {
|
||||
srcMutator: func(c *Code) {
|
||||
c.CodesBytes = []byte{}
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"codeBytes nil": {
|
||||
srcMutator: func(c *Code) {
|
||||
c.CodesBytes = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"codeBytes greater limit": {
|
||||
srcMutator: func(c *Code) {
|
||||
c.CodesBytes = bytes.Repeat([]byte{0x1}, MaxWasmSize+1)
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
state := CodeFixture(spec.srcMutator)
|
||||
got := state.ValidateBasic()
|
||||
if spec.expError {
|
||||
require.Error(t, got)
|
||||
return
|
||||
}
|
||||
require.NoError(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestContractValidateBasic(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
srcMutator func(*Contract)
|
||||
expError bool
|
||||
}{
|
||||
"all good": {srcMutator: func(_ *Contract) {}},
|
||||
"contract address invalid": {
|
||||
srcMutator: func(c *Contract) {
|
||||
c.ContractAddress = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"contract info invalid": {
|
||||
srcMutator: func(c *Contract) {
|
||||
c.ContractInfo.Creator = nil
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
"contract state invalid": {
|
||||
srcMutator: func(c *Contract) {
|
||||
c.ContractState = append(c.ContractState, Model{})
|
||||
},
|
||||
expError: true,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
state := ContractFixture(spec.srcMutator)
|
||||
got := state.ValidateBasic()
|
||||
if spec.expError {
|
||||
require.Error(t, got)
|
||||
return
|
||||
}
|
||||
require.NoError(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
102
x/wasm/internal/types/test_fixtures.go
Normal file
102
x/wasm/internal/types/test_fixtures.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/rand"
|
||||
)
|
||||
|
||||
func GenesisFixture(mutators ...func(*GenesisState)) GenesisState {
|
||||
const (
|
||||
numCodes = 2
|
||||
numContracts = 2
|
||||
numSequences = 2
|
||||
)
|
||||
|
||||
fixture := GenesisState{
|
||||
Codes: make([]Code, numCodes),
|
||||
Contracts: make([]Contract, numContracts),
|
||||
Sequences: make([]Sequence, numSequences),
|
||||
}
|
||||
for i := 0; i < numCodes; i++ {
|
||||
fixture.Codes[i] = CodeFixture()
|
||||
}
|
||||
for i := 0; i < numContracts; i++ {
|
||||
fixture.Contracts[i] = ContractFixture()
|
||||
}
|
||||
for i := 0; i < numSequences; i++ {
|
||||
fixture.Sequences[i] = Sequence{
|
||||
IDKey: rand.Bytes(5),
|
||||
Value: uint64(i),
|
||||
}
|
||||
}
|
||||
for _, m := range mutators {
|
||||
m(&fixture)
|
||||
}
|
||||
return fixture
|
||||
}
|
||||
|
||||
func CodeFixture(mutators ...func(*Code)) Code {
|
||||
wasmCode := rand.Bytes(100)
|
||||
codeHash := sha256.Sum256(wasmCode)
|
||||
anyAddress := make([]byte, 20)
|
||||
|
||||
fixture := Code{
|
||||
CodeInfo: CodeInfo{
|
||||
CodeHash: codeHash[:],
|
||||
Creator: anyAddress,
|
||||
},
|
||||
CodesBytes: wasmCode,
|
||||
}
|
||||
|
||||
for _, m := range mutators {
|
||||
m(&fixture)
|
||||
}
|
||||
return fixture
|
||||
}
|
||||
|
||||
func CodeInfoFixture(mutators ...func(*CodeInfo)) CodeInfo {
|
||||
wasmCode := bytes.Repeat([]byte{0x1}, 10)
|
||||
codeHash := sha256.Sum256(wasmCode)
|
||||
anyAddress := make([]byte, 20)
|
||||
fixture := CodeInfo{
|
||||
CodeHash: codeHash[:],
|
||||
Creator: anyAddress,
|
||||
Source: "https://example.com",
|
||||
Builder: "my/builder:tag",
|
||||
}
|
||||
for _, m := range mutators {
|
||||
m(&fixture)
|
||||
}
|
||||
return fixture
|
||||
}
|
||||
|
||||
func ContractFixture(mutators ...func(*Contract)) Contract {
|
||||
anyAddress := make([]byte, 20)
|
||||
fixture := Contract{
|
||||
ContractAddress: anyAddress,
|
||||
ContractInfo: ContractInfoFixture(),
|
||||
ContractState: []Model{{Key: []byte("anyKey"), Value: []byte("anyValue")}},
|
||||
}
|
||||
|
||||
for _, m := range mutators {
|
||||
m(&fixture)
|
||||
}
|
||||
return fixture
|
||||
}
|
||||
|
||||
func ContractInfoFixture(mutators ...func(*ContractInfo)) ContractInfo {
|
||||
anyAddress := make([]byte, 20)
|
||||
fixture := ContractInfo{
|
||||
CodeID: 1,
|
||||
Creator: anyAddress,
|
||||
Label: "any",
|
||||
Created: &AbsoluteTxPosition{BlockHeight: 1, TxIndex: 1},
|
||||
}
|
||||
|
||||
for _, m := range mutators {
|
||||
m(&fixture)
|
||||
}
|
||||
return fixture
|
||||
}
|
||||
@@ -97,6 +97,9 @@ func (c *ContractInfo) ValidateBasic() error {
|
||||
if err := validateLabel(c.Label); err != nil {
|
||||
return sdkerrors.Wrap(err, "label")
|
||||
}
|
||||
if c.Created == nil {
|
||||
return sdkerrors.Wrap(ErrEmpty, "created")
|
||||
}
|
||||
if err := c.Created.ValidateBasic(); err != nil {
|
||||
return sdkerrors.Wrap(err, "created")
|
||||
}
|
||||
|
||||
133
x/wasm/internal/types/types_test.go
Normal file
133
x/wasm/internal/types/types_test.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestContractInfoValidateBasic(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
srcMutator func(*ContractInfo)
|
||||
expError bool
|
||||
}{
|
||||
"all good": {srcMutator: func(_ *ContractInfo) {}},
|
||||
"code id empty": {
|
||||
srcMutator: func(c *ContractInfo) { c.CodeID = 0 },
|
||||
expError: true,
|
||||
},
|
||||
"creator empty": {
|
||||
srcMutator: func(c *ContractInfo) { c.Creator = nil },
|
||||
expError: true,
|
||||
},
|
||||
"creator not an address": {
|
||||
srcMutator: func(c *ContractInfo) { c.Creator = make([]byte, sdk.AddrLen-1) },
|
||||
expError: true,
|
||||
},
|
||||
"admin empty": {
|
||||
srcMutator: func(c *ContractInfo) { c.Admin = nil },
|
||||
expError: false,
|
||||
},
|
||||
"admin not an address": {
|
||||
srcMutator: func(c *ContractInfo) { c.Admin = make([]byte, sdk.AddrLen-1) },
|
||||
expError: true,
|
||||
},
|
||||
"label empty": {
|
||||
srcMutator: func(c *ContractInfo) { c.Label = "" },
|
||||
expError: true,
|
||||
},
|
||||
"label exceeds limit": {
|
||||
srcMutator: func(c *ContractInfo) { c.Label = strings.Repeat("a", MaxLabelSize+1) },
|
||||
expError: true,
|
||||
},
|
||||
"init msg empty": {
|
||||
srcMutator: func(c *ContractInfo) { c.InitMsg = nil },
|
||||
},
|
||||
"created nil": {
|
||||
srcMutator: func(c *ContractInfo) { c.Created = nil },
|
||||
expError: true,
|
||||
},
|
||||
"created invalid": {
|
||||
srcMutator: func(c *ContractInfo) { c.Created = &AbsoluteTxPosition{BlockHeight: -1} },
|
||||
expError: true,
|
||||
},
|
||||
"last updated nil": {
|
||||
srcMutator: func(c *ContractInfo) { c.LastUpdated = nil },
|
||||
},
|
||||
"previous code id empty": {
|
||||
srcMutator: func(c *ContractInfo) { c.PreviousCodeID = 0 },
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
state := ContractInfoFixture(spec.srcMutator)
|
||||
got := state.ValidateBasic()
|
||||
if spec.expError {
|
||||
require.Error(t, got)
|
||||
return
|
||||
}
|
||||
require.NoError(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeInfoValidateBasic(t *testing.T) {
|
||||
specs := map[string]struct {
|
||||
srcMutator func(*CodeInfo)
|
||||
expError bool
|
||||
}{
|
||||
"all good": {srcMutator: func(_ *CodeInfo) {}},
|
||||
"code hash empty": {
|
||||
srcMutator: func(c *CodeInfo) { c.CodeHash = []byte{} },
|
||||
expError: true,
|
||||
},
|
||||
"code hash nil": {
|
||||
srcMutator: func(c *CodeInfo) { c.CodeHash = nil },
|
||||
expError: true,
|
||||
},
|
||||
"creator empty": {
|
||||
srcMutator: func(c *CodeInfo) { c.Creator = nil },
|
||||
expError: true,
|
||||
},
|
||||
"creator not an address": {
|
||||
srcMutator: func(c *CodeInfo) { c.Creator = make([]byte, sdk.AddrLen-1) },
|
||||
expError: true,
|
||||
},
|
||||
"source empty": {
|
||||
srcMutator: func(c *CodeInfo) { c.Source = "" },
|
||||
},
|
||||
"source not an url": {
|
||||
srcMutator: func(c *CodeInfo) { c.Source = "invalid" },
|
||||
expError: true,
|
||||
},
|
||||
"source not an absolute url": {
|
||||
srcMutator: func(c *CodeInfo) { c.Source = "../bar.txt" },
|
||||
expError: true,
|
||||
},
|
||||
"source not https schema url": {
|
||||
srcMutator: func(c *CodeInfo) { c.Source = "http://example.com" },
|
||||
expError: true,
|
||||
},
|
||||
"builder tag exceeds limit": {
|
||||
srcMutator: func(c *CodeInfo) { c.Builder = strings.Repeat("a", MaxBuildTagSize+1) },
|
||||
expError: true,
|
||||
},
|
||||
"builder tag does not match pattern": {
|
||||
srcMutator: func(c *CodeInfo) { c.Builder = "invalid" },
|
||||
expError: true,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
state := CodeInfoFixture(spec.srcMutator)
|
||||
got := state.ValidateBasic()
|
||||
if spec.expError {
|
||||
require.Error(t, got)
|
||||
return
|
||||
}
|
||||
require.NoError(t, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user