Skip to content

Commit e4ae9d5

Browse files
committed
test: add rapid pbt for trace parser (#913)
* Add other steps to read/write test * Improve error logging in trace handler test * Push ActionType handling into Unmarshal/Marshal and out of own class * Rename generic trace handler files to be clear they are for json * Rename to marshalling to be more generic * Add marshal/unmarshal for proposals * Export unexported field * Add test for marshal/unmarshalling chain state * Fix pointer issues * Fix typo: action -> proposal * Log proposal string in test * Use json.RawMessage instead of map[string]any * For uniformity, also use RawMessage for step unmarshalling * Add tests for extra proposal types * Add more proposal types to test and unify names * Add handling for ParamsProposal * Regenerate traces * Chore: Export forgotten field * Use string, not int, to help marshal/unmarshal * Add rapid to go.mod and .sum * Add rapidpbt for chainState marshalling * Rename file to make clear it only relates to chainState * Add error return to TraceWriter and TraceParser * gst * Add generators for actions and steps, utilize in test driver * Restrict range for time * Add test for time marshal/unmarshal * Make time have a lower bound, since negative numbers are not supported by RFC3339 * Improve label string for argument to time.Unix * Correct lower bound for time: 1900 years negative instead of 2000 * Convert timestamp to utc * Format file * Ignore testdata folder * Add go comment * Add docstring to GetTraceGen
1 parent 4bab3dd commit e4ae9d5

File tree

9 files changed

+699
-17
lines changed

9 files changed

+699
-17
lines changed

go.mod

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ require (
8989
github.com/golang/snappy v0.0.4 // indirect
9090
github.com/google/btree v1.1.2 // indirect
9191
github.com/google/go-cmp v0.5.9
92+
github.com/google/gofuzz v1.2.0 // indirect
9293
github.com/google/orderedcode v0.0.1 // indirect
9394
github.com/google/uuid v1.3.0 // indirect
9495
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
@@ -126,6 +127,14 @@ require (
126127
github.com/mitchellh/go-homedir v1.1.0 // indirect
127128
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
128129
github.com/mitchellh/mapstructure v1.5.0
130+
github.com/linxGnu/grocksdb v1.7.10 // indirect
131+
github.com/magiconair/properties v1.8.6 // indirect
132+
github.com/mattn/go-colorable v0.1.13 // indirect
133+
github.com/mattn/go-isatty v0.0.16 // indirect
134+
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
135+
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
136+
github.com/minio/highwayhash v1.0.2 // indirect
137+
github.com/mitchellh/mapstructure v1.5.0 // indirect
129138
github.com/mtibben/percent v0.2.1 // indirect
130139
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
131140
github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect
@@ -168,6 +177,14 @@ require (
168177
require (
169178
github.com/spf13/viper v1.16.0
170179
google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529
180+
)
181+
require pgregory.net/rapid v0.5.7
182+
183+
replace (
184+
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.45.15-ics
185+
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
186+
github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.27
187+
google.golang.org/grpc => google.golang.org/grpc v1.33.2
171188
)
172189

173190
require (

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,10 @@ nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
18791879
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
18801880
pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA=
18811881
pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
1882+
pgregory.net/rapid v0.5.3 h1:163N50IHFqr1phZens4FQOdPgfJscR7a562mjQqeo4M=
1883+
pgregory.net/rapid v0.5.3/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
1884+
pgregory.net/rapid v0.5.7 h1:p7/XbOgyFY1I/3Q12UTXfos70VZTcgc3WeoyiEru5cs=
1885+
pgregory.net/rapid v0.5.7/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
18821886
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
18831887
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
18841888
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=

tests/e2e/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
testdata

tests/e2e/action_rapid_test.go

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/stretchr/testify/require"
8+
"pgregory.net/rapid"
9+
)
10+
11+
func GetActionGen() *rapid.Generator[any] {
12+
return rapid.OneOf(
13+
GetSendTokensActionGen().AsAny(),
14+
GetStartChainActionGen().AsAny(),
15+
GetSubmitTextProposalActionGen().AsAny(),
16+
GetSubmitConsumerAdditionProposalActionGen().AsAny(),
17+
GetSubmitConsumerRemovalProposalActionGen().AsAny(),
18+
GetSubmitParamChangeProposalActionGen().AsAny(),
19+
GetSubmitEquivocationProposalActionGen().AsAny(),
20+
GetVoteGovProposalActionGen().AsAny(),
21+
GetStartConsumerChainActionGen().AsAny(),
22+
GetAddChainToRelayerActionGen().AsAny(),
23+
GetAddIbcConnectionActionGen().AsAny(),
24+
GetAddIbcChannelActionGen().AsAny(),
25+
GetStartHermesActionGen().AsAny(),
26+
GetTransferChannelCompleteActionGen().AsAny(),
27+
GetRelayPacketsActionGen().AsAny(),
28+
GetRelayRewardPacketsToProviderActionGen().AsAny(),
29+
GetDelegateTokensActionGen().AsAny(),
30+
GetUnbondTokensActionGen().AsAny(),
31+
GetRedelegateTokensActionGen().AsAny(),
32+
GetDowntimeSlashActionGen().AsAny(),
33+
GetUnjailValidatorActionGen().AsAny(),
34+
GetRegisterRepresentativeActionGen().AsAny(),
35+
GetDoublesignSlashActionGen().AsAny(),
36+
GetAssignConsumerPubKeyActionGen().AsAny(),
37+
GetSlashThrottleDequeueGen().AsAny(),
38+
)
39+
}
40+
41+
func GetSendTokensActionGen() *rapid.Generator[SendTokensAction] {
42+
return rapid.Custom(func(t *rapid.T) SendTokensAction {
43+
return SendTokensAction{
44+
Amount: rapid.Uint().Draw(t, "Amount"),
45+
Chain: GetChainIDGen().Draw(t, "Chain"),
46+
From: GetValidatorIDGen().Draw(t, "From"),
47+
To: GetValidatorIDGen().Draw(t, "To"),
48+
}
49+
})
50+
}
51+
52+
func GetStartChainActionGen() *rapid.Generator[StartChainAction] {
53+
return rapid.Custom(func(t *rapid.T) StartChainAction {
54+
return StartChainAction{
55+
Chain: GetChainIDGen().Draw(t, "Chain"),
56+
Validators: GetStartChainValidatorsGen().Draw(t, "Validators"),
57+
GenesisChanges: rapid.String().Draw(t, "GenesisChanges"),
58+
SkipGentx: rapid.Bool().Draw(t, "SkipGentx"),
59+
}
60+
})
61+
}
62+
63+
func GetStartChainValidatorsGen() *rapid.Generator[[]StartChainValidator] {
64+
return rapid.Custom(func(t *rapid.T) []StartChainValidator {
65+
return rapid.SliceOf(GetStartChainValidatorGen()).Draw(t, "StartChainValidators")
66+
})
67+
}
68+
69+
func GetStartChainValidatorGen() *rapid.Generator[StartChainValidator] {
70+
return rapid.Custom(func(t *rapid.T) StartChainValidator {
71+
return StartChainValidator{
72+
Id: GetValidatorIDGen().Draw(t, "Id"),
73+
Allocation: rapid.Uint().Draw(t, "Allocation"),
74+
Stake: rapid.Uint().Draw(t, "Stake"),
75+
}
76+
})
77+
}
78+
79+
func GetSubmitTextProposalActionGen() *rapid.Generator[submitTextProposalAction] {
80+
return rapid.Custom(func(t *rapid.T) submitTextProposalAction {
81+
return submitTextProposalAction{
82+
Chain: GetChainIDGen().Draw(t, "Chain"),
83+
From: GetValidatorIDGen().Draw(t, "From"),
84+
Deposit: rapid.Uint().Draw(t, "Deposit"),
85+
PropType: rapid.String().Draw(t, "PropType"),
86+
Title: rapid.String().Draw(t, "Title"),
87+
Description: rapid.String().Draw(t, "Description"),
88+
}
89+
})
90+
}
91+
92+
func GetSubmitConsumerAdditionProposalActionGen() *rapid.Generator[submitConsumerAdditionProposalAction] {
93+
return rapid.Custom(func(t *rapid.T) submitConsumerAdditionProposalAction {
94+
return submitConsumerAdditionProposalAction{
95+
Chain: GetChainIDGen().Draw(t, "Chain"),
96+
From: GetValidatorIDGen().Draw(t, "From"),
97+
Deposit: rapid.Uint().Draw(t, "Deposit"),
98+
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
99+
SpawnTime: rapid.Uint().Draw(t, "SpawnTime"),
100+
InitialHeight: GetHeightGen().Draw(t, "InitialHeight"),
101+
}
102+
})
103+
}
104+
105+
func GetSubmitConsumerRemovalProposalActionGen() *rapid.Generator[submitConsumerRemovalProposalAction] {
106+
return rapid.Custom(func(t *rapid.T) submitConsumerRemovalProposalAction {
107+
return submitConsumerRemovalProposalAction{
108+
Chain: GetChainIDGen().Draw(t, "Chain"),
109+
From: GetValidatorIDGen().Draw(t, "From"),
110+
Deposit: rapid.Uint().Draw(t, "Deposit"),
111+
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
112+
StopTimeOffset: time.Duration(rapid.Int64().Draw(t, "StopTimeOffset")),
113+
}
114+
})
115+
}
116+
117+
func GetSubmitParamChangeProposalActionGen() *rapid.Generator[submitParamChangeProposalAction] {
118+
return rapid.Custom(func(t *rapid.T) submitParamChangeProposalAction {
119+
return submitParamChangeProposalAction{
120+
Chain: GetChainIDGen().Draw(t, "Chain"),
121+
From: GetValidatorIDGen().Draw(t, "From"),
122+
Deposit: rapid.Uint().Draw(t, "Deposit"),
123+
Subspace: rapid.String().Draw(t, "Subspace"),
124+
Key: rapid.String().Draw(t, "Key"),
125+
Value: rapid.String().Draw(t, "Value"), // TODO: make this more generic
126+
}
127+
})
128+
}
129+
130+
func GetSubmitEquivocationProposalActionGen() *rapid.Generator[submitEquivocationProposalAction] {
131+
return rapid.Custom(func(t *rapid.T) submitEquivocationProposalAction {
132+
return submitEquivocationProposalAction{
133+
Chain: GetChainIDGen().Draw(t, "Chain"),
134+
From: GetValidatorIDGen().Draw(t, "From"),
135+
Deposit: rapid.Uint().Draw(t, "Deposit"),
136+
Height: rapid.Int64().Draw(t, "Height"),
137+
Time: GetTimeGen().Draw(t, "Time"),
138+
Power: rapid.Int64().Draw(t, "Power"),
139+
}
140+
})
141+
}
142+
143+
func TestMarshalAndUnmarshalTime(t *testing.T) {
144+
rapid.Check(t, func(t *rapid.T) {
145+
time1 := GetTimeGen().Draw(t, "time")
146+
data, err := time1.MarshalJSON()
147+
require.NoError(t, err)
148+
var time2 time.Time
149+
err = time2.UnmarshalJSON(data)
150+
require.NoError(t, err)
151+
require.True(t, time1.Equal(time2))
152+
})
153+
}
154+
155+
func GetTimeGen() *rapid.Generator[time.Time] {
156+
return rapid.Custom(func(t *rapid.T) time.Time {
157+
return time.Unix(rapid.Int64Range(-5.9959e+10, 1.5779e+11).Draw(t, "unix time"), 0).UTC()
158+
})
159+
}
160+
161+
func GetVoteGovProposalActionGen() *rapid.Generator[voteGovProposalAction] {
162+
return rapid.Custom(func(t *rapid.T) voteGovProposalAction {
163+
return voteGovProposalAction{
164+
Chain: GetChainIDGen().Draw(t, "Chain"),
165+
From: rapid.SliceOf(GetValidatorIDGen()).Draw(t, "From"),
166+
Vote: rapid.SliceOf(rapid.String()).Draw(t, "Vote"),
167+
PropNumber: rapid.Uint().Draw(t, "PropNumber"),
168+
}
169+
})
170+
}
171+
172+
func GetStartConsumerChainActionGen() *rapid.Generator[startConsumerChainAction] {
173+
return rapid.Custom(func(t *rapid.T) startConsumerChainAction {
174+
return startConsumerChainAction{
175+
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
176+
ProviderChain: GetChainIDGen().Draw(t, "ProviderChain"),
177+
Validators: GetStartChainValidatorsGen().Draw(t, "Validators"),
178+
GenesisChanges: rapid.String().Draw(t, "GenesisChanges"),
179+
}
180+
})
181+
}
182+
183+
func GetAddChainToRelayerActionGen() *rapid.Generator[addChainToRelayerAction] {
184+
return rapid.Custom(func(t *rapid.T) addChainToRelayerAction {
185+
return addChainToRelayerAction{
186+
Chain: GetChainIDGen().Draw(t, "Chain"),
187+
Validator: GetValidatorIDGen().Draw(t, "Validator"),
188+
}
189+
})
190+
}
191+
192+
func GetAddIbcConnectionActionGen() *rapid.Generator[addIbcConnectionAction] {
193+
return rapid.Custom(func(t *rapid.T) addIbcConnectionAction {
194+
return addIbcConnectionAction{
195+
ChainA: GetChainIDGen().Draw(t, "ChainA"),
196+
ChainB: GetChainIDGen().Draw(t, "ChainB"),
197+
ClientA: rapid.Uint().Draw(t, "ClientA"),
198+
ClientB: rapid.Uint().Draw(t, "ClientB"),
199+
}
200+
})
201+
}
202+
203+
func GetAddIbcChannelActionGen() *rapid.Generator[addIbcChannelAction] {
204+
return rapid.Custom(func(t *rapid.T) addIbcChannelAction {
205+
return addIbcChannelAction{
206+
ChainA: GetChainIDGen().Draw(t, "ChainA"),
207+
ChainB: GetChainIDGen().Draw(t, "ChainB"),
208+
ConnectionA: rapid.Uint().Draw(t, "ConnectionA"),
209+
PortA: rapid.String().Draw(t, "PortA"),
210+
PortB: rapid.String().Draw(t, "PortB"),
211+
Order: rapid.String().Draw(t, "Order"),
212+
}
213+
})
214+
}
215+
216+
func GetStartHermesActionGen() *rapid.Generator[startHermesAction] {
217+
return rapid.Just(startHermesAction{})
218+
}
219+
220+
func GetTransferChannelCompleteActionGen() *rapid.Generator[transferChannelCompleteAction] {
221+
return rapid.Custom(func(t *rapid.T) transferChannelCompleteAction {
222+
return transferChannelCompleteAction{
223+
ChainA: GetChainIDGen().Draw(t, "ChainA"),
224+
ChainB: GetChainIDGen().Draw(t, "ChainB"),
225+
ConnectionA: rapid.Uint().Draw(t, "ConnectionA"),
226+
PortA: rapid.String().Draw(t, "PortA"),
227+
PortB: rapid.String().Draw(t, "PortB"),
228+
Order: rapid.String().Draw(t, "Order"),
229+
ChannelA: rapid.Uint().Draw(t, "ChannelA"),
230+
ChannelB: rapid.Uint().Draw(t, "ChannelB"),
231+
}
232+
})
233+
}
234+
235+
func GetRelayPacketsActionGen() *rapid.Generator[relayPacketsAction] {
236+
return rapid.Custom(func(t *rapid.T) relayPacketsAction {
237+
return relayPacketsAction{
238+
Chain: GetChainIDGen().Draw(t, "Chain"),
239+
Port: rapid.String().Draw(t, "Port"),
240+
Channel: rapid.Uint().Draw(t, "Channel"),
241+
}
242+
})
243+
}
244+
245+
func GetRelayRewardPacketsToProviderActionGen() *rapid.Generator[relayRewardPacketsToProviderAction] {
246+
return rapid.Custom(func(t *rapid.T) relayRewardPacketsToProviderAction {
247+
return relayRewardPacketsToProviderAction{
248+
ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"),
249+
ProviderChain: GetChainIDGen().Draw(t, "ProviderChain"),
250+
Port: rapid.String().Draw(t, "Port"),
251+
Channel: rapid.Uint().Draw(t, "Channel"),
252+
}
253+
})
254+
}
255+
256+
func GetDelegateTokensActionGen() *rapid.Generator[delegateTokensAction] {
257+
return rapid.Custom(func(t *rapid.T) delegateTokensAction {
258+
return delegateTokensAction{
259+
Chain: GetChainIDGen().Draw(t, "Chain"),
260+
Amount: rapid.Uint().Draw(t, "Amount"),
261+
From: GetValidatorIDGen().Draw(t, "From"),
262+
To: GetValidatorIDGen().Draw(t, "To"),
263+
}
264+
})
265+
}
266+
267+
func GetUnbondTokensActionGen() *rapid.Generator[unbondTokensAction] {
268+
return rapid.Custom(func(t *rapid.T) unbondTokensAction {
269+
return unbondTokensAction{
270+
Chain: GetChainIDGen().Draw(t, "Chain"),
271+
Amount: rapid.Uint().Draw(t, "Amount"),
272+
Sender: GetValidatorIDGen().Draw(t, "Sender"),
273+
UnbondFrom: GetValidatorIDGen().Draw(t, "UnbondFrom"),
274+
}
275+
})
276+
}
277+
278+
func GetRedelegateTokensActionGen() *rapid.Generator[redelegateTokensAction] {
279+
return rapid.Custom(func(t *rapid.T) redelegateTokensAction {
280+
return redelegateTokensAction{
281+
Chain: GetChainIDGen().Draw(t, "Chain"),
282+
Amount: rapid.Uint().Draw(t, "Amount"),
283+
Src: GetValidatorIDGen().Draw(t, "Src"),
284+
Dst: GetValidatorIDGen().Draw(t, "Dst"),
285+
TxSender: GetValidatorIDGen().Draw(t, "TxSender"),
286+
}
287+
})
288+
}
289+
290+
func GetDowntimeSlashActionGen() *rapid.Generator[downtimeSlashAction] {
291+
return rapid.Custom(func(t *rapid.T) downtimeSlashAction {
292+
return downtimeSlashAction{
293+
Chain: GetChainIDGen().Draw(t, "Chain"),
294+
Validator: GetValidatorIDGen().Draw(t, "Validator"),
295+
}
296+
})
297+
}
298+
299+
func GetUnjailValidatorActionGen() *rapid.Generator[unjailValidatorAction] {
300+
return rapid.Custom(func(t *rapid.T) unjailValidatorAction {
301+
return unjailValidatorAction{
302+
Validator: GetValidatorIDGen().Draw(t, "Validator"),
303+
Provider: GetChainIDGen().Draw(t, "Provider"),
304+
}
305+
})
306+
}
307+
308+
func GetRegisterRepresentativeActionGen() *rapid.Generator[registerRepresentativeAction] {
309+
return rapid.Custom(func(t *rapid.T) registerRepresentativeAction {
310+
return registerRepresentativeAction{
311+
Chain: GetChainIDGen().Draw(t, "Chain"),
312+
Representatives: rapid.SliceOf(GetValidatorIDGen()).Draw(t, "Representatives"),
313+
Stakes: rapid.SliceOf(rapid.Uint()).Draw(t, "Stakes"),
314+
}
315+
})
316+
}
317+
318+
func GetDoublesignSlashActionGen() *rapid.Generator[doublesignSlashAction] {
319+
return rapid.Custom(func(t *rapid.T) doublesignSlashAction {
320+
return doublesignSlashAction{
321+
Chain: GetChainIDGen().Draw(t, "Chain"),
322+
Validator: GetValidatorIDGen().Draw(t, "Validator"),
323+
}
324+
})
325+
}
326+
327+
func GetAssignConsumerPubKeyActionGen() *rapid.Generator[assignConsumerPubKeyAction] {
328+
return rapid.Custom(func(t *rapid.T) assignConsumerPubKeyAction {
329+
return assignConsumerPubKeyAction{
330+
Chain: GetChainIDGen().Draw(t, "Chain"),
331+
Validator: GetValidatorIDGen().Draw(t, "Validator"),
332+
ConsumerPubkey: rapid.String().Draw(t, "ConsumerPubkey"),
333+
ReconfigureNode: rapid.Bool().Draw(t, "ReconfigureNode"),
334+
ExpectError: rapid.Bool().Draw(t, "ExpectError"),
335+
}
336+
})
337+
}
338+
339+
func GetSlashThrottleDequeueGen() *rapid.Generator[slashThrottleDequeue] {
340+
return rapid.Custom(func(t *rapid.T) slashThrottleDequeue {
341+
return slashThrottleDequeue{
342+
Chain: GetChainIDGen().Draw(t, "Chain"),
343+
CurrentQueueSize: rapid.Int().Draw(t, "CurrentQueueSize"),
344+
NextQueueSize: rapid.Int().Draw(t, "NextQueueSize"),
345+
Timeout: time.Duration(rapid.Int().Draw(t, "Timeout")) * time.Millisecond,
346+
}
347+
})
348+
}

0 commit comments

Comments
 (0)