Skip to content

Commit

Permalink
tests: nogo over generated code
Browse files Browse the repository at this point in the history
This add a test that demonstrate the current behavior of nogo today:
code which was generated under rules_go during internal/external test
package compilation is subjected to static analysis.

This behavior is not ideal as end users have very little control over
the way rules_go generated these code and would not be able to fix them
to please the analyzer.

In a future patch, we will introduce a mechanism to alleviate this pain
and flip the expectation in this test.
  • Loading branch information
sluongng committed Jun 27, 2022
1 parent bebe25e commit 0274018
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
6 changes: 6 additions & 0 deletions tests/core/nogo/generate/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
load("@io_bazel_rules_go//go/tools/bazel_testing:def.bzl", "go_bazel_test")

go_bazel_test(
name = "empty_test",
srcs = ["empty_test.go"],
)
12 changes: 12 additions & 0 deletions tests/core/nogo/generate/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
nogo test with generated code
=======================

.. _nogo: /go/nogo.rst

Tests to ensure `nogo`_ interaction with generated code.

empty_test
-------------
Checks that `nogo`_ is running over the `_empty.go` file that was
generated as part of GoCompilePkg.

116 changes: 116 additions & 0 deletions tests/core/nogo/generate/empty_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2019 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package empty_test

import (
"errors"
"os/exec"
"strings"
"testing"

"github.com/bazelbuild/rules_go/go/tools/bazel_testing"
)

func TestMain(m *testing.M) {
bazel_testing.TestMain(m, bazel_testing.Args{
Main: `
-- BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test", "nogo")
go_test(
name = "simple_test",
size = "small",
srcs = ["simple_test.go"],
)
nogo(
name = "nogo",
deps = ["//noempty"],
visibility = ["//visibility:public"],
)
-- simple_test.go --
package simple
import (
"testing"
)
func TestFoo(t *testing.T) {
}
-- noempty/BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "noempty",
srcs = ["analyzer.go"],
importpath = "noempty",
visibility = ["//visibility:public"],
deps = [
"@org_golang_x_tools//go/analysis",
],
)
-- noempty/analyzer.go --
package noempty
import (
"fmt"
"path/filepath"
"strings"
"golang.org/x/tools/go/analysis"
)
var Analyzer = &analysis.Analyzer{
Name: "noempty",
Doc: "noempty ensure that source code was not a generated file created by rules_go test rewrite",
Run: run,
}
func run(pass *analysis.Pass) (interface{}, error) {
for _, f := range pass.Files {
pos := pass.Fset.PositionFor(f.Pos(), false)
if strings.HasSuffix(pos.Filename, filepath.Join(".", "_empty.go")) {
pass.Report(analysis.Diagnostic{
Pos: 0,
Message: fmt.Sprintf("Detected generated source code from rules_go: %s", pos.Filename),
})
}
}
return nil, nil
}
`,
Nogo: `@//:nogo`,
})
}

func TestNogoGenEmptyCode(t *testing.T) {
out, err := bazel_testing.BazelOutput("build", "-k", "//:simple_test")
if err == nil {
t.Fatal("test should fail")
}

var eErr *exec.ExitError
if errors.As(err, &eErr) &&
strings.Contains(string(eErr.Stderr), "Detected generated source code from rules_go") &&
strings.Contains(string(eErr.Stderr), "(noempty)") {
// Expected failure
return
}

println(string(out))
t.Fatal(err)
}

0 comments on commit 0274018

Please sign in to comment.