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 trace input via JSON #1265

Closed
wants to merge 45 commits into from

Conversation

p-offtermatt
Copy link
Contributor

@p-offtermatt p-offtermatt commented Sep 6, 2023

Description

Closes: #1240

Changes are as follows:

  • Main e2e test entry file: For the test main.go, change the behavior flags are processed:

    • --tc now has the form --tc teststeps::testrunner
    • new flag --test-file filename::testrunner
    • These changes are made so that the steps and the runner are separated. This is more future proof, and for test-file, specifying the test runner separately is necessary.
  • Trace format:


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • Included the correct type prefix in the PR title
  • Targeted the correct branch (see PR Targeting)
  • Provided a link to the relevant issue or specification
  • Reviewed "Files changed" and left comments if necessary
  • Confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • Confirmed the correct type prefix in the PR title
  • Confirmed all author checklist items have been addressed
  • Confirmed that this PR does not change production code

@github-actions github-actions bot added the C:Testing Assigned automatically by the PR labeler label Sep 6, 2023
p-offtermatt and others added 28 commits September 6, 2023 13:31
* 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 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
@github-actions github-actions bot added C:Build Assigned automatically by the PR labeler C:CI Assigned automatically by the PR labeler labels Sep 15, 2023
)

var selectedTestfiles TestSet

var stepChoices = map[string]StepChoice{
Copy link
Contributor Author

@p-offtermatt p-offtermatt Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I separated step choices from test runs.

Why: When we input files, we need to give the test runs separately anyways. This makes that behaviour universal. Also seems more future proof, e.g. for running the same steps with different test runs/contexts

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To a semi outsider like myself, the abstractions here are not super intuitive.

"steps" seems like a set of steps to make in running a test.

"test runs" seems synonymous to "steps"

@@ -66,15 +66,15 @@ var slashThrottleSteps = concatSteps(
stepsStopChain("consu", 2),
)

var democracySteps = concatSteps(
var democracyRewardsSteps = concatSteps(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming was confusing before: democracySteps were the input for democracy-reward, and rewardDenomConsumerSteps were the input for democracy. This makes the mapping of test cases to step names more consistent.

@@ -56,3 +56,17 @@ jobs:
go-version: "1.20"
- name: E2E tests
run: make test-e2e-short-cometmock
Trace-Tests:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test that reads traces to the CI to check that trace-reading does not break. Could be expanded in the future

@@ -0,0 +1 @@
testdata
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore temporary folder that rapid puts test failures in

@p-offtermatt p-offtermatt marked this pull request as ready for review September 15, 2023 09:59
@p-offtermatt p-offtermatt requested a review from a team as a code owner September 15, 2023 09:59
@shaspitz
Copy link
Contributor

I'm about to review, first impression of reading the description: this work all seems awesome. There's a lot of changes added in one PR tho. Is it possible to split out these individual components?

  • CLI changes: adding flags, changing parameter format, etc.
  • Pure refactors like making fields public
  • Meat of changes, JSON as test trace input

Totally understand if it's not worth the effort to split everything out at this point, just throwing out the idea

Copy link
Contributor

@shaspitz shaspitz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really cool stuff! My comments are mostly in regard to e2e test abstraction rather than functionality directly related to the PR title. Might be worth splitting things out if not too challenging

@@ -36,7 +36,7 @@ jobs:
with:
go-version: "1.20" # The Go version to download (if necessary) and use.
- name: E2E changeover test
run: go run ./tests/e2e/... --tc changeover
run: go run ./tests/e2e/... --tc changeover::changeover
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From description

for test-file, specifying the test runner separately is necessary

It seems to me like specifying testrunner is mostly relevant to the --test-file flag. Is it neccessary to also require that callers specify the testrunner when using --tc?

Asking because the cli for e2e tests is becoming quite verbose to run a simple test from the manual (golang defined) test cases

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we should document the required format for each flag in a readme if that's not already done

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we should document the required format for each flag in a readme if that's not already done

You can see it by running --help, do you think that is good enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From description

for test-file, specifying the test runner separately is necessary

It seems to me like specifying testrunner is mostly relevant to the --test-file flag. Is it neccessary to also require that callers specify the testrunner when using --tc?

Asking because the cli for e2e tests is becoming quite verbose to run a simple test from the manual (golang defined) test cases

Okay, I can see that. I'm between making it optional and removing it for the test cases, and I think for now I will remove it for --tc. Can be added back later if we need it.

@@ -0,0 +1,485 @@
package main

import (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I understanding correctly that this file serves to fuzz test the ser/deser of json specified e2e actions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly


// This needs to be adjusted manually when new actions are added and should
// include generators for all actions that are mentioned in main.go/runStep.
func GetActionGen() *rapid.Generator[any] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will prob need more context to properly review this file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently splitting this out, then we can e.g. go over that part, or I'll write more explanation

tests/e2e/actions.go Outdated Show resolved Hide resolved
"github.com/davecgh/go-spew/spew"
)

func TestProposalUnmarshal(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason these tests don't use rapid like action_rapid_test.go does?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I wanted to expliticly give a json string as an input, since this is hard to do with Rapid - we can get a json input by marshalling the rapid-generated objects, but this implies trusting that the marshal function does things correctly. this is able to test unmarshal and marshal in a slightly more isolated manner

case "main.submitConsumerAdditionProposalAction":
var a submitConsumerAdditionProposalAction
err := json.Unmarshal(rawAction, &a)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have

if err != nil {
	return nil, err
}

live outside the switch statement so as to not repeat code. Maybe just create a var err error above the switch that can be set

Copy link
Contributor Author

@p-offtermatt p-offtermatt Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, f5b0355

case "main.ConsumerAdditionProposal":
prop := ConsumerAdditionProposal{}
err := json.Unmarshal(inputMap, &prop)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above with local err variable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

)

var selectedTestfiles TestSet

var stepChoices = map[string]StepChoice{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To a semi outsider like myself, the abstractions here are not super intuitive.

"steps" seems like a set of steps to make in running a test.

"test runs" seems synonymous to "steps"

func getTestCases(selection TestSet) (tests []testRunWithSteps) {
type testRunWithSteps struct {
testRun TestRun
steps []Step
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to above, it seems like "steps" should be a field of TestRun, as in a test run is a high level abstraction with config + actual steps to be executed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have renamed TestRun to TestConfig, since that is much more fitting to reality.

Good call, easy to get blind to these weird, historical naming choices. I've refactored this.

The abstractions are now:
A TestRun is made of
steps []Step
testConfig TestConfig

lmk if you still find it confusing

testRuns []string
}

type TestRunChoice struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestRun already has a name field right? Is this new type neccessary?

@p-offtermatt
Copy link
Contributor Author

p-offtermatt commented Sep 19, 2023

Thanks for the review, very useful stuff! I'll give splitting this as much as possible a try and apply your comments.

@p-offtermatt
Copy link
Contributor Author

Closing in favor of a feature branch https://github.com/cosmos/interchain-security/tree/feat/trace-format

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C:Build Assigned automatically by the PR labeler C:CI Assigned automatically by the PR labeler C:Testing Assigned automatically by the PR labeler
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Modify the e2e framework to take traces as an input
2 participants