From 0274018acd872ee795c7d370391e17652aac42a1 Mon Sep 17 00:00:00 2001 From: Son Luong Ngoc Date: Mon, 27 Jun 2022 11:09:23 +0200 Subject: [PATCH] tests: nogo over generated code 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. --- tests/core/nogo/generate/BUILD.bazel | 6 ++ tests/core/nogo/generate/README.rst | 12 +++ tests/core/nogo/generate/empty_test.go | 116 +++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 tests/core/nogo/generate/BUILD.bazel create mode 100644 tests/core/nogo/generate/README.rst create mode 100644 tests/core/nogo/generate/empty_test.go diff --git a/tests/core/nogo/generate/BUILD.bazel b/tests/core/nogo/generate/BUILD.bazel new file mode 100644 index 0000000000..52567b61b0 --- /dev/null +++ b/tests/core/nogo/generate/BUILD.bazel @@ -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"], +) diff --git a/tests/core/nogo/generate/README.rst b/tests/core/nogo/generate/README.rst new file mode 100644 index 0000000000..0d0cac0360 --- /dev/null +++ b/tests/core/nogo/generate/README.rst @@ -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. + diff --git a/tests/core/nogo/generate/empty_test.go b/tests/core/nogo/generate/empty_test.go new file mode 100644 index 0000000000..bdfa913836 --- /dev/null +++ b/tests/core/nogo/generate/empty_test.go @@ -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) +}