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

Implement initial LCOV reporter (no function names support) #11883

Merged
merged 21 commits into from
Jun 22, 2024

Conversation

exoego
Copy link
Contributor

@exoego exoego commented Jun 15, 2024

What does this PR do?

Closes #4015

This adds new config to bunfig which allows users to use lcov coverage reporter and also disable console reporter.

  • Documentation or TypeScript types (it's okay to leave the rest blank in this case)
  • Code changes

AFAIK, function names in LCOV is optional, and tools like CodeCov accept LCOV file without function names.
So I think LCOV without function names is still valuable to users.

How did you verify your code works?

I run the locally-built bun-debug over https://github.com/honojs/hono and obtained LCOV file like below:

...
TN:
SF:src/adapter/bun/index.ts
FNF:1
FNH:1
DA:6,45
DA:7,51
DA:8,49
DA:9,40
LF:10
LH:4
end_of_record
...

Then I uploaded the generated LCOV to CodeCov and confirmed files are succesfully processed by CodeCov:
image
image

Sorry, I couldn't figure out how to write test for this.
Happy to add test if guidance provided 🙇

  • I included a test for the new code, or an existing test covers it
  • I wrote TypeScript/JavaScript tests and they pass locally (bun-debug test test-file-name.test)
  • I updated Aliases in module_loader.zig to include the new module

@exoego exoego marked this pull request as ready for review June 15, 2024 05:18
@exoego exoego changed the title Implement LCOV reporter without function names supports Implement initial LCOV reporter (no function names support) Jun 15, 2024
@Electroid Electroid requested a review from Jarred-Sumner June 17, 2024 20:20
Copy link
Contributor

github-actions bot commented Jun 17, 2024

@Jarred-Sumner, your commit has failing tests :(

💻 1 failing tests Darwin x64 baseline

  • test/regression/issue/09041.test.ts 1 failing

🐧💪 1 failing tests Linux AARCH64

  • test/js/deno/crypto/webcrypto.test.ts 1 failing

🪟💻 1 failing tests Windows x64 baseline

  • test/cli/install/registry/bun-install-registry.test.ts 1 failing

🪟💻 2 failing tests Windows x64

  • test/integration/next-pages/test/dev-server.test.ts 1 failing
  • test/js/bun/io/bun-write.test.js 1 failing

View logs

@exoego
Copy link
Contributor Author

exoego commented Jun 21, 2024

I am happy to finish this PR if I get advised what is missing.

Copy link
Member

@paperclover paperclover left a comment

Choose a reason for hiding this comment

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

overall this looks good. some notes attached.

in addition

  • kind of sad that lines with comments are marked as not hit. though i dont think that is an issue in your implementation, but the coverage stuff overall.
  • should we get --coverage-reporter= command line arguments?
  • for tests, I think it would be reasonable to snapshot test the samples. look for usages of tempDirWithFiles to setup directory trees to test.

src/cli/test_command.zig Outdated Show resolved Hide resolved

while (iter.next()) |entry| {
const value: bun.sourcemap.ByteRangeMapping = entry.*;
byte_ranges.appendAssumeCapacity(value);
Copy link
Member

Choose a reason for hiding this comment

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

cant this just be written as appendAssumeCapacity(value.*)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it doesn't compile on my end:

src/cli/test_command.zig:292:51: error: cannot dereference non-pointer type 'src.sourcemap.CodeCoverage.ByteRangeMapping'
            byte_ranges.appendAssumeCapacity(value.*);
                                             ~~~~~^~
src/sourcemap/CodeCoverage.zig:307:30: note: struct declared here
pub const ByteRangeMapping = struct {
                             ^~~~~~
referenced by:
    exec: src/cli/test_command.zig:920:37

Copy link
Member

Choose a reason for hiding this comment

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

oh wait sorry, i meant entry.*

the point being these two lines can be one line (i dont think the type annotation is of much value)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, it worked 54d12d3
(Sorry, I am a super newbie to Ziglang)

src/cli/test_command.zig Outdated Show resolved Hide resolved
src/bunfig.zig Outdated Show resolved Hide resolved
src/bunfig.zig Outdated Show resolved Hide resolved
@exoego
Copy link
Contributor Author

exoego commented Jun 21, 2024

@paperdave Thanks for your review. I think all comments are addressed

@paperclover
Copy link
Member

@exoego see the two bullet points in the main 'requested changes' comment. to repeat:

  • this at least needs tests to verify it works on all platforms, and to make sure it doesnt just stop working one day.
  • consider (but not mandatory) adding a CLI flag like --coverage-reporter

but otherwise we're good

@exoego
Copy link
Contributor Author

exoego commented Jun 21, 2024

Added CLI parameters in 68d99da

Added snapshot test 75476db
But bun test --update-snapshots does not even create coverage/ directory...
I miss some steps to test bun changes?

EDIT:
I was succesfully able to run npm run test and commit snapshot .

Copy link
Member

@paperclover paperclover left a comment

Choose a reason for hiding this comment

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

im going to add a commit that renames --coverage-reports-dir to just --coverage-dir but yeah this is good.

it could use more tests, but i want to get this in for todays release.

Copy link
Member

@paperclover paperclover left a comment

Choose a reason for hiding this comment

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

wait, nevermind, coverage.test.ts is failing

@exoego
Copy link
Contributor Author

exoego commented Jun 22, 2024

Hmm, do you have an advice to fix coverage.test.ts?

…make it one pass, use more Windows-friendly APIs for creating the directory
while (iter.next()) |line| {
// DA: line number, hit count
// FIXME: Remove the magic number that is used to convert the hit count to the correct value
try writer.print("DA:{d},{d}\n", .{ line + 1, report.lines_hits.ptr[line] - 2863311530 });
Copy link
Collaborator

Choose a reason for hiding this comment

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

@exoego the reason this magic number made it seemingly work: undefined memory. In safety-checked builds of Zig (debug, ReleaseSafe), 0xa is the default-initialized value for memory.

This magic number was turning 0xa into 0. In a release build, this is undefined behavior and will produce a result which will either crash the program, infinite loop, or something unexpected. This is why it did not work in CI.

line_hits = try LinesHits.initCapacity(allocator, line_count);
line_hits.len = line_count;
const line_hits_slice = line_hits.slice();
@memset(line_hits_slice, 0);
Copy link
Collaborator

Choose a reason for hiding this comment

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

@exoego note how we now zero-initialize the line_hits array to ensure that we can access values which have never been written to without worrying about undefined behavior.

@@ -415,7 +477,7 @@ pub const ByteRangeMapping = struct {
executable_lines.set(line);
if (has_executed) {
lines_which_have_executed.set(line);
lines_hits.ptr[line] += 1;
line_hits_slice[line] += 1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

@exoego writing to a many-item pointer ([*]MyType) directly is very much a footgun. You want to use a slice (ptr[0..len]), which has bounds checks.

@Jarred-Sumner Jarred-Sumner merged commit 4830e2d into oven-sh:main Jun 22, 2024
49 of 53 checks passed
@exoego exoego deleted the lcov branch June 22, 2024 09:08
@exoego
Copy link
Contributor Author

exoego commented Jun 22, 2024

Thanks!!

zackradisic pushed a commit that referenced this pull request Jun 24, 2024
dylan-conway pushed a commit that referenced this pull request Jun 26, 2024
Comment on lines +382 to +383
const tmpname = std.fmt.bufPrintZ(&shortname_buf, ".lcov.info.{s}.tmp", .{bun.fmt.fmtSliceHexLower(&base64_bytes)}) catch unreachable;
const path = bun.path.joinAbsStringBufZ(relative_dir, &lcov_name_buf, &.{ opts.reports_directory, tmpname }, .auto);

Choose a reason for hiding this comment

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

Running multiple times is leaving the folder with multiple tml files, is this expected?
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement an lcov coverage reporter for bun test
4 participants