Custom GO unit test coverage rule

407 views
Skip to first unread message

gfee...@gmail.com

unread,
Aug 15, 2019, 1:38:16 PM8/15/19
to bazel-discuss
Hi all,

I have written a custom rule. The purpose is to provide a mechanism to run unit testing on a Go target with 100% coverage. The rule checks the coverage percentage, and if it is < 100, it throws error. The rule uses the shell to run these commands basically:

"go test -cover" ..
"go tool cover" ...

Why did I approach it this way? Well as far as I can tell, there is no way in Bazel/Go rules to run 'bazel coverage' command and specify that I want the test to fail if coverage percentage < 100. This is an important criteria for me. So I had to write this custom one.

The rule works, however the only way I was able to get it to work with Go was to leverage the 'go_path' rule and specify these on the data attribute of the rule. The rule then takes these go_paths and builds the GOPATH environment variable so that the go commands will function properly. 

If I didn't use 'go_path' and tried to build GOPATH variable using deps attribute, it would never work because Go would always look for the code underneath a 'src' directory, and bazel does not place the Go library dependencies in this structure in the sandbox. So I HAD to use the go_path approach.

As I said this method was working ... but now today it has broken.

I have started to use github.com/aws/aws-sdk-go as an external dependency.

I defined it as a 'go_repository' and gazelle builds out the build files correctly.. I also created the necessary go_path rules for it (4 total) that my Go package is importing.

import ( 
     .........
)

But when my custom rule runs, I get these error messages:

third_party/golang/com_github_aws_aws_sdk_go/aws_session_path2/src/github.com/aws/aws-sdk-go/aws/session/shared_config.go:8:2: use of internal package github.com/aws/aws-sdk-go/internal/ini not allowed
third_party/golang/com_github_aws_aws_sdk_go/aws_session_path2/src/github.com/aws/aws-sdk-go/aws/request/offset_reader.go:7:2: use of internal package github.com/aws/aws-sdk-go/internal/sdkio not allowed
third_party/golang/com_github_aws_aws_sdk_go/aws_session_path2/src/github.com/aws/aws-sdk-go/aws/session/credentials.go:14:2: use of internal package github.com/aws/aws-sdk-go/internal/shareddefaults not allowed

I can clearly see in the sandbox, this go_path rule named 'aws_session_path2' is pulling in the dependent parts of the Go package, so these dependencies (under internal/ini, internal/sdkio, internal/shareddefaults) are indeed in the sandbox under a common root path which is: "<sandbox>/third_party/golang/com_github_aws_aws_sdk_go/aws_session_path2/"

but Go is somehow considering the 'internal' components to be 'outside' of it's root path.

I'm definitely stuck and seek advice on how I can resolve this situation. I fiddled with GOPATH with no luck at all..

thank you!


gfee...@gmail.com

unread,
Jan 3, 2020, 11:38:55 AM1/3/20
to bazel-discuss
I did find a workaround for this back in August, I just never posted the information. Well here it is, very late.

I found that if I included all the aws dependencies together in a separate go_path rule, like this:

go_path(
    name = "all_aws_go_path",
    deps = [
        "@com_github_aws_aws_sdk_go//aws:go_default_library",
        "@com_github_aws_aws_sdk_go//aws/awserr:go_default_library",
        "@com_github_aws_aws_sdk_go//aws/session:go_default_library",
        "@com_github_aws_aws_sdk_go//service/dynamodb:go_default_library",
        "@com_github_aws_aws_sdk_go//service/dynamodb/dynamodbattribute:go_default_library",
        "@com_github_aws_aws_sdk_go//service/dynamodb/dynamodbiface:go_default_library",
    ],
)

then my custom rule could refer to it and the error messages about 'use of internal package not allowed' would not come up.

go_coverage_test(
    name = "my_coverage_go_test",
    size = "small",
    srcs = glob(["*_test.go"]),
    data = [
        ":all_aws_go_path",
        etc, etc
    ],
    etc, etc
)
Reply all
Reply to author
Forward
0 new messages