Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add rapid pbt for trace parser #913

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b13c735
Add other steps to read/write test
p-offtermatt Apr 25, 2023
f5c9515
Improve error logging in trace handler test
p-offtermatt Apr 25, 2023
a6113ec
Push ActionType handling into Unmarshal/Marshal and out of own class
p-offtermatt Apr 26, 2023
aafcb05
Rename generic trace handler files to be clear they are for json
p-offtermatt Apr 26, 2023
1a650a6
Rename to marshalling to be more generic
p-offtermatt Apr 26, 2023
d3ea342
Add marshal/unmarshal for proposals
p-offtermatt Apr 26, 2023
5908bff
Export unexported field
p-offtermatt Apr 26, 2023
7144640
Add test for marshal/unmarshalling chain state
p-offtermatt Apr 26, 2023
163e39d
Fix pointer issues
p-offtermatt Apr 26, 2023
bd7dc45
Fix typo: action -> proposal
p-offtermatt Apr 26, 2023
ed4a647
Log proposal string in test
p-offtermatt Apr 27, 2023
7f03bc3
Use json.RawMessage instead of map[string]any
p-offtermatt Apr 27, 2023
e731ef1
For uniformity, also use RawMessage for step unmarshalling
p-offtermatt Apr 27, 2023
9aaec61
Add tests for extra proposal types
p-offtermatt Apr 27, 2023
87ed74a
Add more proposal types to test and unify names
p-offtermatt Apr 27, 2023
e2f34e9
Add handling for ParamsProposal
p-offtermatt Apr 27, 2023
26b6b45
Regenerate traces
p-offtermatt Apr 27, 2023
1fc70d7
Chore: Export forgotten field
p-offtermatt Apr 27, 2023
cf5f0d9
Use string, not int, to help marshal/unmarshal
p-offtermatt Apr 27, 2023
a1e873c
Add rapid to go.mod and .sum
p-offtermatt May 2, 2023
3588cfa
Add rapidpbt for chainState marshalling
p-offtermatt May 2, 2023
32bd59c
Rename file to make clear it only relates to chainState
p-offtermatt May 2, 2023
478d286
Add error return to TraceWriter and TraceParser
p-offtermatt May 2, 2023
16f90c1
gst
p-offtermatt May 3, 2023
653af8d
Add generators for actions and steps, utilize in test driver
p-offtermatt May 3, 2023
a9f22d4
Restrict range for time
p-offtermatt May 3, 2023
019c6a5
Add test for time marshal/unmarshal
p-offtermatt May 3, 2023
81a3a42
Make time have a lower bound, since negative numbers are not supporte…
p-offtermatt May 3, 2023
eb21af2
Improve label string for argument to time.Unix
p-offtermatt May 3, 2023
477aea3
Correct lower bound for time: 1900 years negative instead of 2000
p-offtermatt May 3, 2023
9d94c72
Convert timestamp to utc
p-offtermatt May 3, 2023
58cd068
Merge branch 'feat/upgrade-e2e-testing' into ph/881-testing-add-rapid…
p-offtermatt May 3, 2023
37e8be0
Format file
p-offtermatt May 3, 2023
0a6f16f
Ignore testdata folder
p-offtermatt May 3, 2023
f01a5af
Add go comment
p-offtermatt May 3, 2023
6bb177a
Add docstring to GetTraceGen
p-offtermatt May 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ require (
github.com/golang/glog v1.0.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/go-cmp v0.5.9
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/orderedcode v0.0.1 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
Expand All @@ -110,9 +110,9 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mitchellh/mapstructure v1.5.0
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/onsi/ginkgo v1.16.4 // indirect
github.com/onsi/gomega v1.20.0 // indirect
Expand Down Expand Up @@ -151,6 +151,8 @@ require (
nhooyr.io/websocket v1.8.6 // indirect
)

require pgregory.net/rapid v0.5.7

replace (
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.15-ics
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,9 @@ honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
pgregory.net/rapid v0.5.3 h1:163N50IHFqr1phZens4FQOdPgfJscR7a562mjQqeo4M=
pgregory.net/rapid v0.5.3/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
pgregory.net/rapid v0.5.7 h1:p7/XbOgyFY1I/3Q12UTXfos70VZTcgc3WeoyiEru5cs=
pgregory.net/rapid v0.5.7/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
testdata
348 changes: 348 additions & 0 deletions tests/e2e/action_rapid_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
package main

import (
"testing"
"time"

"github.com/stretchr/testify/require"
"pgregory.net/rapid"
)

func GetActionGen() *rapid.Generator[any] {
return rapid.OneOf(
GetSendTokensActionGen().AsAny(),
GetStartChainActionGen().AsAny(),
GetSubmitTextProposalActionGen().AsAny(),
GetSubmitConsumerAdditionProposalActionGen().AsAny(),
GetSubmitConsumerRemovalProposalActionGen().AsAny(),
GetSubmitParamChangeProposalActionGen().AsAny(),
GetSubmitEquivocationProposalActionGen().AsAny(),
GetVoteGovProposalActionGen().AsAny(),
GetStartConsumerChainActionGen().AsAny(),
GetAddChainToRelayerActionGen().AsAny(),
GetAddIbcConnectionActionGen().AsAny(),
GetAddIbcChannelActionGen().AsAny(),
GetStartHermesActionGen().AsAny(),
GetTransferChannelCompleteActionGen().AsAny(),
GetRelayPacketsActionGen().AsAny(),
GetRelayRewardPacketsToProviderActionGen().AsAny(),
GetDelegateTokensActionGen().AsAny(),
GetUnbondTokensActionGen().AsAny(),
GetRedelegateTokensActionGen().AsAny(),
GetDowntimeSlashActionGen().AsAny(),
GetUnjailValidatorActionGen().AsAny(),
GetRegisterRepresentativeActionGen().AsAny(),
GetDoublesignSlashActionGen().AsAny(),
GetAssignConsumerPubKeyActionGen().AsAny(),
GetSlashThrottleDequeueGen().AsAny(),
)
}

func GetSendTokensActionGen() *rapid.Generator[SendTokensAction] {
return rapid.Custom(func(t *rapid.T) SendTokensAction {
return SendTokensAction{
Amount: rapid.Uint().Draw(t, "Amount"),
Chain: GetChainIDGen().Draw(t, "Chain"),
From: GetValidatorIDGen().Draw(t, "From"),
To: GetValidatorIDGen().Draw(t, "To"),
}
})
}

func GetStartChainActionGen() *rapid.Generator[StartChainAction] {
return rapid.Custom(func(t *rapid.T) StartChainAction {
return StartChainAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Validators: GetStartChainValidatorsGen().Draw(t, "Validators"),
GenesisChanges: rapid.String().Draw(t, "GenesisChanges"),
SkipGentx: rapid.Bool().Draw(t, "SkipGentx"),
}
})
}

func GetStartChainValidatorsGen() *rapid.Generator[[]StartChainValidator] {
return rapid.Custom(func(t *rapid.T) []StartChainValidator {
return rapid.SliceOf(GetStartChainValidatorGen()).Draw(t, "StartChainValidators")
})
}

func GetStartChainValidatorGen() *rapid.Generator[StartChainValidator] {
return rapid.Custom(func(t *rapid.T) StartChainValidator {
return StartChainValidator{
Id: GetValidatorIDGen().Draw(t, "Id"),
Allocation: rapid.Uint().Draw(t, "Allocation"),
Stake: rapid.Uint().Draw(t, "Stake"),
}
})
}

func GetSubmitTextProposalActionGen() *rapid.Generator[submitTextProposalAction] {
return rapid.Custom(func(t *rapid.T) submitTextProposalAction {
return submitTextProposalAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
From: GetValidatorIDGen().Draw(t, "From"),
Deposit: rapid.Uint().Draw(t, "Deposit"),
PropType: rapid.String().Draw(t, "PropType"),
Title: rapid.String().Draw(t, "Title"),
Description: rapid.String().Draw(t, "Description"),
}
})
}

func GetSubmitConsumerAdditionProposalActionGen() *rapid.Generator[submitConsumerAdditionProposalAction] {
return rapid.Custom(func(t *rapid.T) submitConsumerAdditionProposalAction {
return submitConsumerAdditionProposalAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
From: GetValidatorIDGen().Draw(t, "From"),
Deposit: rapid.Uint().Draw(t, "Deposit"),
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
SpawnTime: rapid.Uint().Draw(t, "SpawnTime"),
InitialHeight: GetHeightGen().Draw(t, "InitialHeight"),
}
})
}

func GetSubmitConsumerRemovalProposalActionGen() *rapid.Generator[submitConsumerRemovalProposalAction] {
return rapid.Custom(func(t *rapid.T) submitConsumerRemovalProposalAction {
return submitConsumerRemovalProposalAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
From: GetValidatorIDGen().Draw(t, "From"),
Deposit: rapid.Uint().Draw(t, "Deposit"),
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
StopTimeOffset: time.Duration(rapid.Int64().Draw(t, "StopTimeOffset")),
}
})
}

func GetSubmitParamChangeProposalActionGen() *rapid.Generator[submitParamChangeProposalAction] {
return rapid.Custom(func(t *rapid.T) submitParamChangeProposalAction {
return submitParamChangeProposalAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
From: GetValidatorIDGen().Draw(t, "From"),
Deposit: rapid.Uint().Draw(t, "Deposit"),
Subspace: rapid.String().Draw(t, "Subspace"),
Key: rapid.String().Draw(t, "Key"),
Value: rapid.String().Draw(t, "Value"), // TODO: make this more generic
}
})
}

func GetSubmitEquivocationProposalActionGen() *rapid.Generator[submitEquivocationProposalAction] {
return rapid.Custom(func(t *rapid.T) submitEquivocationProposalAction {
return submitEquivocationProposalAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
From: GetValidatorIDGen().Draw(t, "From"),
Deposit: rapid.Uint().Draw(t, "Deposit"),
Height: rapid.Int64().Draw(t, "Height"),
Time: GetTimeGen().Draw(t, "Time"),
Power: rapid.Int64().Draw(t, "Power"),
}
})
}

func TestMarshalAndUnmarshalTime(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
time1 := GetTimeGen().Draw(t, "time")
data, err := time1.MarshalJSON()
require.NoError(t, err)
var time2 time.Time
err = time2.UnmarshalJSON(data)
require.NoError(t, err)
require.True(t, time1.Equal(time2))
})
}

func GetTimeGen() *rapid.Generator[time.Time] {
return rapid.Custom(func(t *rapid.T) time.Time {
return time.Unix(rapid.Int64Range(-5.9959e+10, 1.5779e+11).Draw(t, "unix time"), 0).UTC()
})
}

func GetVoteGovProposalActionGen() *rapid.Generator[voteGovProposalAction] {
return rapid.Custom(func(t *rapid.T) voteGovProposalAction {
return voteGovProposalAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
From: rapid.SliceOf(GetValidatorIDGen()).Draw(t, "From"),
Vote: rapid.SliceOf(rapid.String()).Draw(t, "Vote"),
PropNumber: rapid.Uint().Draw(t, "PropNumber"),
}
})
}

func GetStartConsumerChainActionGen() *rapid.Generator[startConsumerChainAction] {
return rapid.Custom(func(t *rapid.T) startConsumerChainAction {
return startConsumerChainAction{
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
ProviderChain: GetChainIDGen().Draw(t, "ProviderChain"),
Validators: GetStartChainValidatorsGen().Draw(t, "Validators"),
GenesisChanges: rapid.String().Draw(t, "GenesisChanges"),
}
})
}

func GetAddChainToRelayerActionGen() *rapid.Generator[addChainToRelayerAction] {
return rapid.Custom(func(t *rapid.T) addChainToRelayerAction {
return addChainToRelayerAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Validator: GetValidatorIDGen().Draw(t, "Validator"),
}
})
}

func GetAddIbcConnectionActionGen() *rapid.Generator[addIbcConnectionAction] {
return rapid.Custom(func(t *rapid.T) addIbcConnectionAction {
return addIbcConnectionAction{
ChainA: GetChainIDGen().Draw(t, "ChainA"),
ChainB: GetChainIDGen().Draw(t, "ChainB"),
ClientA: rapid.Uint().Draw(t, "ClientA"),
ClientB: rapid.Uint().Draw(t, "ClientB"),
}
})
}

func GetAddIbcChannelActionGen() *rapid.Generator[addIbcChannelAction] {
return rapid.Custom(func(t *rapid.T) addIbcChannelAction {
return addIbcChannelAction{
ChainA: GetChainIDGen().Draw(t, "ChainA"),
ChainB: GetChainIDGen().Draw(t, "ChainB"),
ConnectionA: rapid.Uint().Draw(t, "ConnectionA"),
PortA: rapid.String().Draw(t, "PortA"),
PortB: rapid.String().Draw(t, "PortB"),
Order: rapid.String().Draw(t, "Order"),
}
})
}

func GetStartHermesActionGen() *rapid.Generator[startHermesAction] {
return rapid.Just(startHermesAction{})
}

func GetTransferChannelCompleteActionGen() *rapid.Generator[transferChannelCompleteAction] {
return rapid.Custom(func(t *rapid.T) transferChannelCompleteAction {
return transferChannelCompleteAction{
ChainA: GetChainIDGen().Draw(t, "ChainA"),
ChainB: GetChainIDGen().Draw(t, "ChainB"),
ConnectionA: rapid.Uint().Draw(t, "ConnectionA"),
PortA: rapid.String().Draw(t, "PortA"),
PortB: rapid.String().Draw(t, "PortB"),
Order: rapid.String().Draw(t, "Order"),
ChannelA: rapid.Uint().Draw(t, "ChannelA"),
ChannelB: rapid.Uint().Draw(t, "ChannelB"),
}
})
}

func GetRelayPacketsActionGen() *rapid.Generator[relayPacketsAction] {
return rapid.Custom(func(t *rapid.T) relayPacketsAction {
return relayPacketsAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Port: rapid.String().Draw(t, "Port"),
Channel: rapid.Uint().Draw(t, "Channel"),
}
})
}

func GetRelayRewardPacketsToProviderActionGen() *rapid.Generator[relayRewardPacketsToProviderAction] {
return rapid.Custom(func(t *rapid.T) relayRewardPacketsToProviderAction {
return relayRewardPacketsToProviderAction{
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
ProviderChain: GetChainIDGen().Draw(t, "ProviderChain"),
Port: rapid.String().Draw(t, "Port"),
Channel: rapid.Uint().Draw(t, "Channel"),
}
})
}

func GetDelegateTokensActionGen() *rapid.Generator[delegateTokensAction] {
return rapid.Custom(func(t *rapid.T) delegateTokensAction {
return delegateTokensAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Amount: rapid.Uint().Draw(t, "Amount"),
From: GetValidatorIDGen().Draw(t, "From"),
To: GetValidatorIDGen().Draw(t, "To"),
}
})
}

func GetUnbondTokensActionGen() *rapid.Generator[unbondTokensAction] {
return rapid.Custom(func(t *rapid.T) unbondTokensAction {
return unbondTokensAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Amount: rapid.Uint().Draw(t, "Amount"),
Sender: GetValidatorIDGen().Draw(t, "Sender"),
UnbondFrom: GetValidatorIDGen().Draw(t, "UnbondFrom"),
}
})
}

func GetRedelegateTokensActionGen() *rapid.Generator[redelegateTokensAction] {
return rapid.Custom(func(t *rapid.T) redelegateTokensAction {
return redelegateTokensAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Amount: rapid.Uint().Draw(t, "Amount"),
Src: GetValidatorIDGen().Draw(t, "Src"),
Dst: GetValidatorIDGen().Draw(t, "Dst"),
TxSender: GetValidatorIDGen().Draw(t, "TxSender"),
}
})
}

func GetDowntimeSlashActionGen() *rapid.Generator[downtimeSlashAction] {
return rapid.Custom(func(t *rapid.T) downtimeSlashAction {
return downtimeSlashAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Validator: GetValidatorIDGen().Draw(t, "Validator"),
}
})
}

func GetUnjailValidatorActionGen() *rapid.Generator[unjailValidatorAction] {
return rapid.Custom(func(t *rapid.T) unjailValidatorAction {
return unjailValidatorAction{
Validator: GetValidatorIDGen().Draw(t, "Validator"),
Provider: GetChainIDGen().Draw(t, "Provider"),
}
})
}

func GetRegisterRepresentativeActionGen() *rapid.Generator[registerRepresentativeAction] {
return rapid.Custom(func(t *rapid.T) registerRepresentativeAction {
return registerRepresentativeAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Representatives: rapid.SliceOf(GetValidatorIDGen()).Draw(t, "Representatives"),
Stakes: rapid.SliceOf(rapid.Uint()).Draw(t, "Stakes"),
}
})
}

func GetDoublesignSlashActionGen() *rapid.Generator[doublesignSlashAction] {
return rapid.Custom(func(t *rapid.T) doublesignSlashAction {
return doublesignSlashAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Validator: GetValidatorIDGen().Draw(t, "Validator"),
}
})
}

func GetAssignConsumerPubKeyActionGen() *rapid.Generator[assignConsumerPubKeyAction] {
return rapid.Custom(func(t *rapid.T) assignConsumerPubKeyAction {
return assignConsumerPubKeyAction{
Chain: GetChainIDGen().Draw(t, "Chain"),
Validator: GetValidatorIDGen().Draw(t, "Validator"),
ConsumerPubkey: rapid.String().Draw(t, "ConsumerPubkey"),
ReconfigureNode: rapid.Bool().Draw(t, "ReconfigureNode"),
ExpectError: rapid.Bool().Draw(t, "ExpectError"),
}
})
}

func GetSlashThrottleDequeueGen() *rapid.Generator[slashThrottleDequeue] {
return rapid.Custom(func(t *rapid.T) slashThrottleDequeue {
return slashThrottleDequeue{
Chain: GetChainIDGen().Draw(t, "Chain"),
CurrentQueueSize: rapid.Int().Draw(t, "CurrentQueueSize"),
NextQueueSize: rapid.Int().Draw(t, "NextQueueSize"),
Timeout: time.Duration(rapid.Int().Draw(t, "Timeout")) * time.Millisecond,
}
})
}
2 changes: 1 addition & 1 deletion tests/e2e/json_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

// TraceParser provides an interface for parsers that read sequences of Steps from files.
type TraceParser interface {
ReadTraceFromFile(filepath string) []Step
ReadTraceFromFile(filepath string) ([]Step, error)
}

// JSONParser is a simple parser that reads steps by unmarshalling from a file.
Expand Down
Loading