blob: 8858a573c45810085493e60ba0186868f3f77715 [file] [log] [blame]
// 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 check
import (
"fmt"
"os"
"path/filepath"
"runtime"
"sort"
"strings"
"github.com/bazelbuild/rules_go/go/tools/bazel"
)
type TestFile struct {
Workspace, ShortPath, Path string
Binary bool
}
var DefaultTestFiles = []TestFile{
{Workspace: "io_bazel_rules_go", Path: "tests/core/runfiles/local_file.txt"},
{Workspace: "io_bazel_rules_go", Path: "tests/core/runfiles/local_group.txt"},
{Workspace: "io_bazel_rules_go", Path: "tests/core/runfiles/local_bin", Binary: true},
{Workspace: "runfiles_remote_test", Path: "remote_file.txt"},
{Workspace: "runfiles_remote_test", Path: "remote_group.txt"},
{Workspace: "runfiles_remote_test", Path: "remote_bin", Binary: true},
}
func CheckRunfiles(files []TestFile) error {
// Check that the runfiles directory matches the current workspace.
// There is no runfiles directory on Windows.
if runtime.GOOS != "windows" {
dir, err := bazel.RunfilesPath()
if err != nil {
return err
}
root, base := filepath.Dir(dir), filepath.Base(dir)
if !strings.HasSuffix(root, ".runfiles") {
return fmt.Errorf("RunfilesPath: %q is not a .runfiles directory", dir)
}
workspace := os.Getenv("TEST_WORKSPACE")
if workspace != "" && workspace != base {
return fmt.Errorf("RunfilesPath: %q does not match test workspace %s", dir, workspace)
}
if srcDir := os.Getenv("TEST_SRCDIR"); srcDir != "" && filepath.Join(srcDir, workspace) != dir {
return fmt.Errorf("RunfilesPath: %q does not match TEST_SRCDIR %q", dir, srcDir)
}
}
// Check that files can be found with Runfile or FindBinary.
// Make sure the paths returned are absolute paths to actual files.
seen := make(map[string]string)
for _, f := range files {
var got string
var err error
if !f.Binary {
if got, err = bazel.Runfile(f.Path); err != nil {
return err
}
if !filepath.IsAbs(got) {
return fmt.Errorf("Runfile %s: got a relative path %q; want absolute", f.Path, got)
}
seen[f.Path] = got
} else {
var pkg, name string
if i := strings.LastIndex(f.Path, "/"); i < 0 {
name = f.Path
} else {
pkg = f.Path[:i]
name = f.Path[i+1:]
}
var ok bool
if got, ok = bazel.FindBinary(pkg, name); !ok {
return fmt.Errorf("FindBinary %s %s: could not find binary", pkg, name)
}
if !filepath.IsAbs(got) {
return fmt.Errorf("FindBinary %s %s: got a relative path %q; want absolute", pkg, name, got)
}
}
if _, err := os.Stat(got); err != nil {
return fmt.Errorf("%s: could not stat: %v", f.Path, err)
}
}
// Check that the files can be listed.
entries, err := bazel.ListRunfiles()
if err != nil {
return err
}
for _, e := range entries {
if want, ok := seen[e.ShortPath]; ok && want != e.Path {
return err
}
delete(seen, e.ShortPath)
}
if len(seen) > 0 {
unseen := make([]string, 0, len(seen))
for short := range seen {
unseen = append(unseen, short)
}
sort.Strings(unseen)
return fmt.Errorf("ListRunfiles did not include files:\n\t%s", strings.Join(unseen, "\n\t"))
}
return nil
}