-
Notifications
You must be signed in to change notification settings - Fork 7
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
Continuation of removing crossing hellos in channel handshake #68
Changes from 7 commits
527a11a
af6bcec
40771a6
c2eecab
4f7e88a
9856d24
a75219d
dbb9b0e
c890576
86d61ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"go/ast" | ||
"go/parser" | ||
"go/token" | ||
"io/fs" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
const ( | ||
testNamePrefix = "Test" | ||
testFileNameSuffix = "_test.go" | ||
e2eTestDirectory = "e2e" | ||
) | ||
|
||
// GithubActionTestMatrix represents | ||
type GithubActionTestMatrix struct { | ||
Include []TestSuitePair `json:"include"` | ||
} | ||
|
||
type TestSuitePair struct { | ||
Test string `json:"test"` | ||
Suite string `json:"suite"` | ||
} | ||
|
||
func main() { | ||
githubActionMatrix, err := getGithubActionMatrixForTests(e2eTestDirectory) | ||
if err != nil { | ||
fmt.Printf("error generating github action json: %s", err) | ||
os.Exit(1) | ||
} | ||
|
||
ghBytes, err := json.Marshal(githubActionMatrix) | ||
if err != nil { | ||
fmt.Printf("error marshalling github action json: %s", err) | ||
os.Exit(1) | ||
} | ||
fmt.Println(string(ghBytes)) | ||
} | ||
|
||
// getGithubActionMatrixForTests returns a json string representing the contents that should go in the matrix | ||
// field in a github action workflow. This string can be used with `fromJSON(str)` to dynamically build | ||
// the workflow matrix to include all E2E tests under the e2eRootDirectory directory. | ||
func getGithubActionMatrixForTests(e2eRootDirectory string) (GithubActionTestMatrix, error) { | ||
testSuiteMapping := map[string][]string{} | ||
fset := token.NewFileSet() | ||
err := filepath.Walk(e2eRootDirectory, func(path string, info fs.FileInfo, err error) error { | ||
// only look at test files | ||
if !strings.HasSuffix(path, testFileNameSuffix) { | ||
return nil | ||
} | ||
|
||
f, err := parser.ParseFile(fset, path, nil, 0) | ||
if err != nil { | ||
return fmt.Errorf("failed parsing file: %s", err) | ||
} | ||
|
||
suiteNameForFile, testCases, err := extractSuiteAndTestNames(f) | ||
if err != nil { | ||
return fmt.Errorf("failed extracting test suite name and test cases: %s", err) | ||
} | ||
|
||
testSuiteMapping[suiteNameForFile] = testCases | ||
|
||
return nil | ||
}) | ||
|
||
if err != nil { | ||
return GithubActionTestMatrix{}, err | ||
} | ||
|
||
gh := GithubActionTestMatrix{ | ||
Include: []TestSuitePair{}, | ||
} | ||
|
||
for testSuiteName, testCases := range testSuiteMapping { | ||
for _, testCaseName := range testCases { | ||
gh.Include = append(gh.Include, TestSuitePair{ | ||
Test: testCaseName, | ||
Suite: testSuiteName, | ||
}) | ||
} | ||
} | ||
|
||
return gh, nil | ||
} | ||
|
||
// extractSuiteAndTestNames extracts the name of the test suite function as well | ||
// as all tests associated with it in the same file. | ||
func extractSuiteAndTestNames(file *ast.File) (string, []string, error) { | ||
var suiteNameForFile string | ||
var testCases []string | ||
|
||
for _, d := range file.Decls { | ||
if f, ok := d.(*ast.FuncDecl); ok { | ||
functionName := f.Name.Name | ||
if isTestSuiteMethod(f) { | ||
if suiteNameForFile != "" { | ||
return "", nil, fmt.Errorf("found a second test function: %s when %s was already found", f.Name.Name, suiteNameForFile) | ||
} | ||
suiteNameForFile = functionName | ||
continue | ||
} | ||
if isTestFunction(f) { | ||
testCases = append(testCases, functionName) | ||
} | ||
} | ||
} | ||
if suiteNameForFile == "" { | ||
return "", nil, fmt.Errorf("file %s had no test suite test case", file.Name.Name) | ||
} | ||
return suiteNameForFile, testCases, nil | ||
} | ||
|
||
// isTestSuiteMethod returns true if the function is a test suite function. | ||
// e.g. func TestFeeMiddlewareTestSuite(t *testing.T) { ... } | ||
func isTestSuiteMethod(f *ast.FuncDecl) bool { | ||
return strings.HasPrefix(f.Name.Name, testNamePrefix) && len(f.Type.Params.List) == 1 | ||
} | ||
|
||
// isTestFunction returns true if the function name starts with "Test" and has no parameters. | ||
// as test suite functions do not accept a *testing.T. | ||
func isTestFunction(f *ast.FuncDecl) bool { | ||
return strings.HasPrefix(f.Name.Name, testNamePrefix) && len(f.Type.Params.List) == 0 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"path" | ||
"sort" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const ( | ||
nonTestFile = "not_test_file.go" | ||
goTestFileNameOne = "first_go_file_test.go" | ||
goTestFileNameTwo = "second_go_file_test.go" | ||
) | ||
|
||
func TestGetGithubActionMatrixForTests(t *testing.T) { | ||
t.Run("empty dir does not fail", func(t *testing.T) { | ||
testingDir := t.TempDir() | ||
_, err := getGithubActionMatrixForTests(testingDir) | ||
assert.NoError(t, err) | ||
}) | ||
|
||
t.Run("only test functions are picked up", func(t *testing.T) { | ||
testingDir := t.TempDir() | ||
createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) | ||
|
||
gh, err := getGithubActionMatrixForTests(testingDir) | ||
assert.NoError(t, err) | ||
|
||
expected := GithubActionTestMatrix{ | ||
Include: []TestSuitePair{ | ||
{ | ||
Suite: "TestFeeMiddlewareTestSuite", | ||
Test: "TestA", | ||
}, | ||
{ | ||
Suite: "TestFeeMiddlewareTestSuite", | ||
Test: "TestB", | ||
}, | ||
}, | ||
} | ||
assertGithubActionTestMatricesEqual(t, expected, gh) | ||
}) | ||
|
||
t.Run("all files are picked up", func(t *testing.T) { | ||
testingDir := t.TempDir() | ||
createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) | ||
createFileWithTestSuiteAndTests(t, "TransferTestSuite", "TestC", "TestD", testingDir, goTestFileNameTwo) | ||
|
||
gh, err := getGithubActionMatrixForTests(testingDir) | ||
assert.NoError(t, err) | ||
|
||
expected := GithubActionTestMatrix{ | ||
Include: []TestSuitePair{ | ||
{ | ||
Suite: "TestTransferTestSuite", | ||
Test: "TestC", | ||
}, | ||
{ | ||
Suite: "TestFeeMiddlewareTestSuite", | ||
Test: "TestA", | ||
}, | ||
{ | ||
Suite: "TestFeeMiddlewareTestSuite", | ||
Test: "TestB", | ||
}, | ||
{ | ||
Suite: "TestTransferTestSuite", | ||
Test: "TestD", | ||
}, | ||
}, | ||
} | ||
|
||
assertGithubActionTestMatricesEqual(t, expected, gh) | ||
}) | ||
|
||
t.Run("non test files are not picked up", func(t *testing.T) { | ||
testingDir := t.TempDir() | ||
createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, nonTestFile) | ||
|
||
gh, err := getGithubActionMatrixForTests(testingDir) | ||
assert.NoError(t, err) | ||
assert.Empty(t, gh.Include) | ||
}) | ||
|
||
t.Run("fails when there are multiple suite runs", func(t *testing.T) { | ||
testingDir := t.TempDir() | ||
createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, nonTestFile) | ||
|
||
fileWithTwoSuites := `package foo | ||
func SuiteOne(t *testing.T) { | ||
suite.Run(t, new(FeeMiddlewareTestSuite)) | ||
} | ||
|
||
func SuiteTwo(t *testing.T) { | ||
suite.Run(t, new(FeeMiddlewareTestSuite)) | ||
} | ||
|
||
type FeeMiddlewareTestSuite struct {} | ||
` | ||
|
||
err := os.WriteFile(path.Join(testingDir, goTestFileNameOne), []byte(fileWithTwoSuites), os.FileMode(777)) | ||
assert.NoError(t, err) | ||
|
||
_, err = getGithubActionMatrixForTests(testingDir) | ||
assert.Error(t, err) | ||
}) | ||
} | ||
|
||
func assertGithubActionTestMatricesEqual(t *testing.T, expected, actual GithubActionTestMatrix) { | ||
// sort by both suite and test as the order of the end result does not matter as | ||
// all tests will be run. | ||
sort.SliceStable(expected.Include, func(i, j int) bool { | ||
memberI := expected.Include[i] | ||
memberJ := expected.Include[j] | ||
if memberI.Suite == memberJ.Suite { | ||
return memberI.Test < memberJ.Test | ||
} | ||
return memberI.Suite < memberJ.Suite | ||
}) | ||
|
||
sort.SliceStable(actual.Include, func(i, j int) bool { | ||
memberI := actual.Include[i] | ||
memberJ := actual.Include[j] | ||
if memberI.Suite == memberJ.Suite { | ||
return memberI.Test < memberJ.Test | ||
} | ||
return memberI.Suite < memberJ.Suite | ||
}) | ||
assert.Equal(t, expected.Include, actual.Include) | ||
} | ||
|
||
func goTestFileContents(suiteName, fnName1, fnName2 string) string { | ||
|
||
replacedSuiteName := strings.ReplaceAll(`package foo | ||
|
||
func TestSuiteName(t *testing.T) { | ||
suite.Run(t, new(SuiteName)) | ||
} | ||
|
||
type SuiteName struct {} | ||
|
||
func (s *SuiteName) fnName1() {} | ||
func (s *SuiteName) fnName2() {} | ||
|
||
func (s *SuiteName) suiteHelper() {} | ||
|
||
func helper() {} | ||
`, "SuiteName", suiteName) | ||
|
||
replacedFn1Name := strings.ReplaceAll(replacedSuiteName, "fnName1", fnName1) | ||
return strings.ReplaceAll(replacedFn1Name, "fnName2", fnName2) | ||
} | ||
|
||
func createFileWithTestSuiteAndTests(t *testing.T, suiteName, fn1Name, fn2Name, dir, filename string) { | ||
goFileContents := goTestFileContents(suiteName, fn1Name, fn2Name) | ||
err := os.WriteFile(path.Join(dir, filename), []byte(goFileContents), os.FileMode(777)) | ||
assert.NoError(t, err) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,7 +62,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ | |
* (modules/core/04-channel) [\#1232](https://github.com/cosmos/ibc-go/pull/1232) Updating params on `NewPacketId` and moving to bottom of file. | ||
* (app/29-fee) [\#1305](https://github.com/cosmos/ibc-go/pull/1305) Change version string for fee module to `ics29-1` | ||
* (app/29-fee) [\#1341](https://github.com/cosmos/ibc-go/pull/1341) Check if the fee module is locked and if the fee module is enabled before refunding all fees | ||
* (modules/core/04-channel) [\#1317](https://github.com/cosmos/ibc-go/pull/1317) Remove crossing hellos from ChanOpenTry | ||
* (modules/core/04-channel) [\#1317](https://github.com/cosmos/ibc-go/pull/1317) Remove corssing hellos from channel handshakes. The `PreviousChannelId` in `MsgChannelOpenTry` has been deprecated. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is an API breaking change, would it make more sense to add this to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good! |
||
* (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. | ||
* (testing/simapp) [\#1397](https://github.com/cosmos/ibc-go/pull/1397) Adding mock module to maccperms and adding check to ensure mock module is not a blocked account address. | ||
* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# ADR 006: 02-client refactor | ||
|
||
## Changelog | ||
* 18 May 2022: Initial Draft | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. | ||
|
||
## Decision | ||
|
||
> This section explains all of the details of the proposed solution, including implementation details. | ||
It should also describe affects / corollary items that may need to be changed as a part of this. | ||
If the proposed change will be large, please also indicate a way to do the change to maximize ease of review. | ||
(e.g. the optimal split of things to do between separate PR's) | ||
|
||
## Consequences | ||
|
||
> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. | ||
|
||
### Positive | ||
|
||
### Negative | ||
|
||
### Neutral | ||
|
||
## References | ||
|
||
The primary discussion which motivated these changes was documented in issue [#284](https://github.com/cosmos/ibc-go/issues/284). | ||
|
||
Issues: | ||
* {reference link} | ||
|
||
PRs: | ||
* {ref} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.