Skip to content

Commit

Permalink
Create test exhibiting issue bazel-contrib#2224
Browse files Browse the repository at this point in the history
Demonstrate that stamps are not compiled into objects when referred to
through genrules.
  • Loading branch information
achew22 committed Dec 4, 2019
1 parent a667c18 commit bbbb900
Show file tree
Hide file tree
Showing 6 changed files with 309 additions and 0 deletions.
24 changes: 24 additions & 0 deletions go/tools/bazel_testing/bazel_testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,30 @@ func RunBazel(args ...string) error {
return err
}

// BazelInfo collects the workspace attributes and returns them.
//
// If the command starts but exits with a non-zero status, a *StderrExitError
// will be returned which wraps the original *exec.ExitError.
func BazelInfo() (map[string]string, error) {
out, err := BazelOutput("info")
return parseInfo(out), err
}

func parseInfo(in []byte) map[string]string {
ret := map[string]string{}

lines := bytes.Split(in, []byte("\n"))
for _, line := range lines {
if len(line) == 0 {
continue
}
res := bytes.SplitN(line, []byte(": "), 2)
ret[string(res[0])] = string(res[1])
}

return ret
}

// BazelOutput invokes a bazel command with a list of arguments and returns
// the content of stdout.
//
Expand Down
9 changes: 9 additions & 0 deletions go/tools/bazel_testing/bazel_testing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package bazel_testing

import (
"testing"
)

func TestParseInfo(t *testing.T) {

}
6 changes: 6 additions & 0 deletions tests/core/stamp/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 = "genrule_go_binary_test",
srcs = ["genrule_go_binary_test.go"],
)
10 changes: 10 additions & 0 deletions tests/core/stamp/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. _#2224: https://github.com/bazelbuild/rules_go/issues/2224

Stamp functionality
===================

genrule_go_binary
-----------------

Checks that ``go_binary`` targets depended upon by genrules are stamped.
This is just a regression test for (`#2224`_).
132 changes: 132 additions & 0 deletions tests/core/stamp/fileset_stamp_go_binary_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// 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 fileset_stamp_go_binary_test

import (
"bytes"
"io/ioutil"
"os"
"os/exec"
"strings"
"testing"

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

const (
genruleOut = "genrule_out"
successMsg = "success"
stampNotAppliedMsg = "Stamp == stampNotApplied"
stampNotEvaluatedMsg = "Stamp == setButUnevaluated"
)

func TestMain(m *testing.M) {
bazel_testing.TestMain(m, bazel_testing.Args{
Main: `
-- .bazelrc --
build:stamp --stamp
build:stamp --workspace_status_command="sh status.sh"
# Note that run and test both inherrit bazelrc options from build
-- status.sh --
echo "STABLE_STAMPED_VARIABLE ` + successMsg + `"
-- BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
go_binary(
name = "stamp",
srcs = ["stamp.go"],
out = "stamp",
x_defs = {
"main.stamp": "{STABLE_STAMPED_VARIABLE}",
},
)
filegroup(
name = "filegroup",
srcs = [":stamp"],
)
-- stamp.go --
package main
import "fmt"
const setButUnevaluated = "{STABLE_STAMPED_VARIABLE}"
const stampNotApplied = "STAMP_NOT_APPLIED"
var stamp string = stampNotApplied
func main() {
fmt.Print(stamp)
}
`,
})
}

func Test(t *testing.T) {
// Running the go binary without stamping should cause the stampNotAppliedMsg error.
if err := bazel_testing.RunBazel(
"build",
"//:filegroup",
); err == nil {
// This is good
} else if bErr, ok := err.(*bazel_testing.StderrExitError); !ok {
t.Fatalf("got %v; want StderrExitError", err)
} else if code := bErr.Err.ExitCode(); code != 2 {
t.Fatalf("got code %d; want code 2 (test failure)\n%v", code, bErr.Error())
} else if !strings.Contains(bErr.Error(), stampNotEvaluatedMsg) {
t.Fatalf("got %q; should contain %q", bErr.Error(), stampNotEvaluatedMsg)
}

cmd := exec.Command("find", "./bazel-bin/")
cmd.Stdout = os.Stdout
cmd.Run()

// Run the binary that was included in the filegroup to see if the output contains "success"
bin, ok := bazel.FindBinary("filegroup", "stamp")
if !ok {
t.Fatal("bazel.FindBinary(\"filegroup\", \"stamp\") = false")
}
t.Log(bin)

// Build the genrule that has the stamped binary transitively.
if err := bazel_testing.RunBazel(
"build",
"--config=stamp",
"//:genrule",
); err != nil {
t.Fatal(err)
}

var genruleFilePath string
if info, err := bazel_testing.BazelInfo(); err != nil {
t.Fatal(err)
} else {
genruleFilePath = info["output_path"]
}

files, err := ioutil.ReadDir(genruleFilePath)
if err != nil {
t.Fatal(err)
}

for _, file := range files {
t.Logf("File: %s", file.Name())
}

if output, err := ioutil.ReadFile(genruleFilePath + "/" + genruleOut); err != nil {
t.Fatal(err)
} else if !bytes.Equal(output, []byte(successMsg)) {
t.Fatalf("got %q; want %q", output, successMsg)
}
}
128 changes: 128 additions & 0 deletions tests/core/stamp/genrule_go_binary_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// 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 genrule_go_binary_test

import (
"bytes"
"io/ioutil"
"strings"
"testing"

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

const (
genruleOut = "genrule_out"
successMsg = "success"
stampNotAppliedMsg = "Stamp == stampNotApplied"
stampNotEvaluatedMsg = "Stamp == setButUnevaluated"
)

func TestMain(m *testing.M) {
bazel_testing.TestMain(m, bazel_testing.Args{
Main: `
-- .bazelrc --
build:stamp --stamp
build:stamp --workspace_status_command="sh status.sh"
# Note that run and test both inherrit bazelrc options from build
-- status.sh --
echo "STABLE_STAMPED_VARIABLE ` + successMsg + `"
-- BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
go_binary(
name = "stamp",
srcs = ["stamp.go"],
out = "stamp",
x_defs = {
"main.stamp": "{STABLE_STAMPED_VARIABLE}",
},
)
genrule(
name = "genrule",
cmd = "$(location :stamp) > $@",
tools = [":stamp"],
outs = ["` + genruleOut + `"],
)
-- stamp.go --
package main
import "fmt"
const setButUnevaluated = "{STABLE_STAMPED_VARIABLE}"
const stampNotApplied = "STAMP_NOT_APPLIED"
var stamp string = stampNotApplied
func main() {
if stamp == stampNotApplied {
panic("` + stampNotAppliedMsg + `")
}
// TODO(issue/2224): Uncomment this line to demonstrate stamping issues.
//if stamp == setButUnevaluated {
// panic("` + stampNotEvaluatedMsg + `")
//}
//fmt.Print(stamp)
fmt.Print("` + successMsg + `")
}
`,
})
}

func Test(t *testing.T) {
// Running the go binary without stamping should cause the stampNotAppliedMsg error.
if err := bazel_testing.RunBazel(
"run",
"//:stamp",
); err == nil {
//t.Fatal("got success; want failure")
} else if bErr, ok := err.(*bazel_testing.StderrExitError); !ok {
t.Fatalf("got %v; want StderrExitError", err)
} else if code := bErr.Err.ExitCode(); code != 2 {
t.Fatalf("got code %d; want code 2 (test failure)\n%v", code, bErr.Error())
} else if !strings.Contains(bErr.Error(), stampNotEvaluatedMsg) {
t.Fatalf("got %q; should contain %q", bErr.Error(), stampNotEvaluatedMsg)
}

// Running the go binary with stamping should work just fine.
if err := bazel_testing.RunBazel(
"run",
"--config=stamp",
"//:stamp",
); err != nil {
t.Fatal(err)
}

// Build the genrule that has the stamped binary transitively.
if err := bazel_testing.RunBazel(
"build",
"--config=stamp",
"//:genrule",
); err != nil {
t.Fatal(err)
}

var genruleFilePath string
if info, err := bazel_testing.BazelInfo(); err != nil {
t.Fatal(err)
} else {
genruleFilePath = info["bazel-bin"]
}

if output, err := ioutil.ReadFile(genruleFilePath + "/" + genruleOut); err != nil {
t.Fatal(err)
} else if !bytes.Equal(output, []byte(successMsg)) {
t.Fatalf("got %q; want %q", output, successMsg)
}
}

0 comments on commit bbbb900

Please sign in to comment.