nspcc-dev / neo-go

Go Node and SDK for the Neo blockchain
MIT License
123 stars 79 forks source link

Contract coverage is not compatible with atomic covermode #3587

Open roman-khimov opened 2 months ago

roman-khimov commented 2 months ago

Current Behavior

go test -v -race ./path-to-contract -coverprofile=coverage.txt -covermode=atomic fails with

error: test wrote malformed coverage profile /tmp/go-build2520858745/b001/_cover_.out.

Expected Behavior

Same command working fine. In fact, any of -covermode or -race leads to this while a simple go test -v ./path-to-contract -coverprofile=coverage.txt works fine.

Possible Solution

Not yet known.

Your Environment

AnnaShaleva commented 1 month ago

any of -covermode or -race leads to this

The original problem is with covermode=atomic coverage mode, because -race overwrites coverage collection mode to atomic anyway.

while a simple go test -v ./path-to-contract -coverprofile=coverage.txt works fine.

It works fine because it uses set coverage mode by default.

So the issue is about proper atomic cover mode support. Here what I managed to find out: the described error is returned by go cover when it tries to merge the resulting coverage outputs from different tests. The source code that produces this error is: https://github.com/golang/go/blob/cbdb3545ad7d15204ef15daf124393aefb7b2c3d/src/cmd/go/internal/test/cover.go#L69

In particular, go cover tool can't find the expected covermode: atomic line in the start of specific coverage output file which results in this error. The error looks strange to me, because https://github.com/nspcc-dev/neo-go/pull/3616/commits/2dc588ea9578e54e5971c0730ae78313e5a804cf ensures this line is properly written to the output file. And hence, the only thing that might go wrong is the file location itself. I'd suggest to compile go cover tool with some custom logs, see what exactly causes this error (either an empty file or the line of the wrong form) and see what exactly go cover expects to get.

AnnaShaleva commented 1 month ago

And BTW, the reason is definitely not in the compiler; it's in the neotest coverage module itself.