-
Notifications
You must be signed in to change notification settings - Fork 3
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
feat: binary coverage #45
Conversation
Retrieve coverage from instrumented `manifestd`
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #45 +/- ##
===========================================
+ Coverage 44.06% 59.20% +15.13%
===========================================
Files 34 34
Lines 2115 2140 +25
===========================================
+ Hits 932 1267 +335
+ Misses 1139 808 -331
- Partials 44 65 +21 ☔ View full report in Codecov by Sentry. |
// Same as ChainNode.HomeDir() but we need it before the chain is created | ||
// The node volume is always mounted at /var/cosmos-chain/[chain-name] | ||
// This is a hackish way to get the coverage files from the ephemeral containers |
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.
This is the "hackish" part. I'm curious to know if there's a better way.
// createAuthzJSON generates a JSON file for an authorization message. | ||
// This is a copy of interchaintest/chain/cosmos/module_authz.go#createAuthzJSON with the addition of the chain environment variables to the Exec call | ||
func createAuthzJSON(ctx context.Context, chain *cosmos.CosmosChain, filePath string, genMsgCmd []string) error { | ||
if !strings.Contains(strings.Join(genMsgCmd, " "), "--generate-only") { | ||
genMsgCmd = append(genMsgCmd, "--generate-only") | ||
} | ||
|
||
res, resErr, err := chain.GetNode().Exec(ctx, genMsgCmd, chain.Config().Env) | ||
if resErr != nil { | ||
return fmt.Errorf("failed to generate msg: %s", resErr) | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return chain.GetNode().WriteFile(ctx, res, filePath) | ||
} | ||
|
||
// ExecTx executes a transaction, waits for 2 blocks if successful, then returns the tx hash. | ||
// This is a copy of interchaintest/chain/cosmos/chain_node.go#ExecTx with the addition of the chain environment variables to the Exec call | ||
func ExecTx(ctx context.Context, chain *cosmos.CosmosChain, keyName string, command ...string) (string, error) { | ||
stdout, _, err := chain.GetNode().Exec(ctx, chain.GetNode().TxCommand(keyName, command...), chain.Config().Env) | ||
if err != nil { | ||
return "", err | ||
} | ||
output := cosmos.CosmosTx{} | ||
err = json.Unmarshal([]byte(stdout), &output) | ||
if err != nil { | ||
return "", err | ||
} | ||
if output.Code != 0 { | ||
return output.TxHash, fmt.Errorf("transaction failed with code %d: %s", output.Code, output.RawLog) | ||
} | ||
if err := testutil.WaitForBlocks(ctx, 2, chain.GetNode()); err != nil { | ||
return "", err | ||
} | ||
return output.TxHash, nil |
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.
I had to duplicate those from interchaintest
to add environment variable context so that GOCOVERDIR
behaves properly. The helper functions from interchaintest
don't support adding environment variable context.
// Workaround AuthzExec which doesn't propagate the environment variables to the Exec call | ||
fileName := "authz.json" | ||
err = createAuthzJSON(ctx, chain, fileName, nestedCmd) | ||
require.NoError(t, err) | ||
|
||
_, err = ExecTx(ctx, chain, grantee.KeyName(), []string{"authz", "exec", path.Join(chain.GetNode().HomeDir(), fileName)}...) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), poa.ErrStakingActionNotAllowed.Error()) | ||
require.ErrorContains(t, err, poa.ErrStakingActionNotAllowed.Error()) |
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.
Not using the workaround results in the test failing because GOCOVERDIR
is not properly set.
@@ -83,3 +99,38 @@ func AppEncoding() *sdktestutil.TestEncodingConfig { | |||
|
|||
return &enc | |||
} | |||
|
|||
func CopyCoverageFromContainer(ctx context.Context, t *testing.T, client *client.Client, containerId string, internalGoCoverDir string) { |
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.
The dockerutil
module is not exposed in interchaintest
v8.2.0. This workaround works just fine.
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.
this is fixed in main of ictest, just not a proper release yet
- name: Run coverage | ||
run: make coverage | ||
- name: Upload coverage to Codecov | ||
uses: codecov/codecov-action@v4-beta | ||
uses: codecov/codecov-action@v4.3.0 |
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.
We need that version now or else coverage from fork PR won't get uploaded.
Retrieve coverage from instrumented
manifestd
binary.This PR supports measuring the coverage of an instrumented
manifestd
binary.The
manifestd
binary is used ininterchaintest
to perform various operations. This PR enables retrieving themanifestd
coverage information from ephemeral containers.The way of doing so is hackish for lack of a better word. I'm curious to know if there's a better way...
Also,
interchaintest
helpers function, e.g.,AuthzExec
,TokenFactoryMintDenom
, etc, don't allow passing environment variables. I had to work around it.I should probably decouple the
interchaintest
from the coverage feature at some point...