rules_go: go_test: linker conflict when external test indirectly imports library under test

EDIT by jayconrod on 2020-07-21: Previous title was “Conflicting package heights due to external test”

The error messages for this issue now look like this:

 package conflict error: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/equality: package imports k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1
	  was compiled with: //staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library
	but was linked with: //staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_test
This sometimes happens when an external test (package ending with _test)
imports a package that imports the library being tested. This is not supported.

Using rules_go 0.16.5, I got the “conflicting package heights” error from a mix of internal and external tests, even though I believe that should be supported (ea0abdd2f467522ff1ae1f72c5a89982eb65d210). I’m not doing anything unusual in my BUILD or Go files, and almost everything was auto-generated by Gazelle. Upon fixing it, Gazelle prints warnings that I shouldn’t be separating the targets.

Error log:

INFO: Build options have changed, discarding analysis cache.
INFO: Analysed 85 targets (260 packages loaded, 8534 targets configured).
INFO: Found 85 targets...
ERROR: /Users/robfig/alpha/gocode/src/corp/it/apps/zendesk/BUILD.bazel:17:1: GoCompile gocode/src/corp/it/apps/zendesk/darwin_amd64_stripped/go_default_test%/corp/it/apps/zendesk_test.a failed (Exit 1) compile failed: error executing command
  (cd /private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/execroot/corp && \
  exec env - \
    APPLE_SDK_PLATFORM='' \
    APPLE_SDK_VERSION_OVERRIDE='' \
    CGO_ENABLED=1 \
    GOARCH=amd64 \
    GOOS=darwin \
    GOROOT=external/go_sdk \
    GOROOT_FINAL=GOROOT \
    PATH=external/local_config_cc:/bin:/usr/bin \
    XCODE_VERSION_OVERRIDE=9.4.1 \
  bazel-out/host/bin/external/io_bazel_rules_go/go/tools/builders/darwin_amd64_stripped/compile -sdk external/go_sdk -installsuffix darwin_amd64 -src gocode/src/corp/it/apps/zendesk/client.go -src gocode/src/corp/it/apps/zendesk/models.go -src gocode/src/corp/it/apps/zendesk/blackbox_test.go -src gocode/src/corp/it/apps/zendesk/client_test.go -src gocode/src/corp/it/apps/zendesk/models_test.go -arc 'corp/it/worker/config=corp/it/worker/config=bazel-out/darwin-fastbuild/bin/gocode/src/corp/it/worker/config/darwin_amd64_stripped/go_default_library%/corp/it/worker/config.a' -arc 'github.com/stretchr/testify/assert=github.com/stretchr/testify/assert=bazel-out/darwin-fastbuild/bin/external/com_github_stretchr_testify/assert/darwin_amd64_stripped/go_default_library%/github.com/stretchr/testify/assert.a' -arc 'corp/it/apps=corp/it/apps=bazel-out/darwin-fastbuild/bin/gocode/src/corp/it/apps/darwin_amd64_stripped/go_default_library%/corp/it/apps.a' -arc 'github.com/corp/glog=github.com/corp/glog=bazel-out/darwin-fastbuild/bin/external/com_github_corp_glog/darwin_amd64_stripped/go_default_library%/github.com/corp/glog.a' -arc 'corp/it/apps/zendesk=corp/it/apps/zendesk=bazel-out/darwin-fastbuild/bin/gocode/src/corp/it/apps/zendesk/darwin_amd64_stripped/go_default_test%/corp/it/apps/zendesk.a' -o bazel-out/darwin-fastbuild/bin/gocode/src/corp/it/apps/zendesk/darwin_amd64_stripped/go_default_test%/corp/it/apps/zendesk_test.a -package_list bazel-out/host/bin/external/go_sdk/packages.txt -testfilter only -- -trimpath . -p corp/it/apps/zendesk_test)

Use --sandbox_debug to see verbose messages from the sandbox: compile failed: error executing command
  ... [DUPE ERROR MESSAGE AS ABOVE] ...

Use --sandbox_debug to see verbose messages from the sandbox
GoCompile: error running compiler: exit status 2
/private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/sandbox/darwin-sandbox/399/execroot/corp/gocode/src/corp/it/apps/zendesk/blackbox_test.go:11:2: internal compiler error: conflicting package heights 18 and 16 for path "corp/it/apps/zendesk"

Please file a bug report including a short program that triggers the error.
https://golang.org/issue/new

WORKSPACE

http_archive(
    name = "io_bazel_rules_go",
    url = "https://github.com/bazelbuild/rules_go/releases/download/0.16.5/rules_go-0.16.5.tar.gz",
    sha256 = "7be7dc01f1e0afdba6c8eb2b43d2fa01c743be1b9273ab1eaf6c233df078d705",
)

BUILD file

# //gocode/src/corp/it/apps/okta/BUILD.bazel
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
    name = "go_default_library",
    srcs = [
        "client.go",
        "common.go",
        "const.go",
        "models.go",
    ],
    importpath = "corp/it/apps/okta",
    visibility = ["//visibility:public"],
    deps = [
        "//gocode/src/corp/it/apps:go_default_library",
        "@com_github_corp_errgo//:go_default_library",
        "@com_github_corp_glog//:go_default_library",
    ],
)

go_test(
    name = "go_default_test",
    srcs = [
        "blackbox_test.go",
        "client_test.go",
        "models_test.go",
    ],
    embed = [":go_default_library"],
    deps = [
        "//gocode/src/corp/it/apps:go_default_library",
        "//gocode/src/corp/it/worker/config:go_default_library",
        "@com_github_stretchr_testify//assert:go_default_library",
        "@com_github_corp_errgo//:go_default_library",
    ],
)

Go file (package + imports)

// blackbox_test.go
package okta_test

import (
	"os"
	"testing"
	"corp/it/apps"
	"corp/it/apps/okta"
	"corp/it/worker/config"
)

// tests

Splitting up the BUILD file in the typical way fixes the problem:

go_test(
    name = "go_default_test",
    srcs = [
        "client_test.go",
        "models_test.go",
    ],
    embed = [":go_default_library"],
    deps = [
        "//gocode/src/corp/it/apps:go_default_library",
        "//gocode/src/corp/it/worker/config:go_default_library",
        "@com_github_stretchr_testify//assert:go_default_library",
        "@com_github_corp_errgo//:go_default_library",
    ],
)

go_test(
    name = "go_default_xtest",
    srcs = ["blackbox_test.go"],
    deps = [
        ":go_default_library",
        "//gocode/src/corp/it/apps:go_default_library",
        "//gocode/src/corp/it/worker/config:go_default_library",
        "@com_github_stretchr_testify//assert:go_default_library",
        "@com_github_corp_errgo//:go_default_library",
    ],
)

but results in this warning on subsequent gazelle runs

gazelle: /Users/robfig/alpha/gocode/src/corp/it/apps/okta/BUILD.bazel: go_default_xtest is no longer necessary. Run 'gazelle fix' to squash with go_default_test.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 37 (31 by maintainers)

Commits related to this issue

Most upvoted comments

Hopefully #2579 should fix this issue. Please try it out and comment if you find that anything is still broken.

If it works, I’ll backport it and tag a point release this week.

I am still having an issue with this with go version 1.20, bazel version 6.4.0, io_bazel_rules_go version 0.42.0 and bazel_gazelle version 0.33.0:

link: package conflict error: cloud.google.com/go/iam/apiv1/iampb: package imports google.golang.org/genproto/googleapis/api/annotations
	  was compiled with: @org_golang_google_genproto_googleapis_api//annotations:annotations
	but was linked with: @org_golang_google_genproto//googleapis/api/annotations:annotations
See https://github.com/bazelbuild/rules_go/issues/1877.

Are there any fixes I can make on my side?

I spent most of today working on a permanent fix for this. I think I have something promising; will polish it and submit it tomorrow if it passes all the tests. It doesn’t require an aspect, but it adds a lot of complicated analysis code to go_test. It requires storing a lot more information in GoArchiveData, but I’m going to keep those fields private so this change can be backported.

This is very common in our codebase. I think the big issue we face is that even with purely external tests, gazelle produces a go_test rule that embeds the package and triggers this warning. Perhaps gazelle can be updated to separate the internal and external tests into different targets?

@jayconrod : I tried 464eb9c71c682d1a8367944ec768f25f989a9916 on the current master version of Baseplate.go and it no longer show the warnings when we run bazel test //...:all. When on v0.23.5 it shows 3 warnings.