• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package check
16
17import (
18	"fmt"
19	"os"
20	"path/filepath"
21	"runtime"
22	"sort"
23	"strings"
24
25	"github.com/bazelbuild/rules_go/go/tools/bazel"
26)
27
28type TestFile struct {
29	Workspace, ShortPath, Path string
30	Binary                     bool
31}
32
33var DefaultTestFiles = []TestFile{
34	{Workspace: "io_bazel_rules_go", Path: "tests/core/runfiles/local_file.txt"},
35	{Workspace: "io_bazel_rules_go", Path: "tests/core/runfiles/local_group.txt"},
36	{Workspace: "io_bazel_rules_go", Path: "tests/core/runfiles/local_bin", Binary: true},
37	{Workspace: "runfiles_remote_test", Path: "remote_file.txt"},
38	{Workspace: "runfiles_remote_test", Path: "remote_group.txt"},
39	{Workspace: "runfiles_remote_test", Path: "remote_bin", Binary: true},
40}
41
42func CheckRunfiles(files []TestFile) error {
43	// Check that the runfiles directory matches the current workspace.
44	// There is no runfiles directory on Windows.
45	if runtime.GOOS != "windows" {
46		dir, err := bazel.RunfilesPath()
47		if err != nil {
48			return err
49		}
50		root, base := filepath.Dir(dir), filepath.Base(dir)
51		if !strings.HasSuffix(root, ".runfiles") {
52			return fmt.Errorf("RunfilesPath: %q is not a .runfiles directory", dir)
53		}
54		workspace := os.Getenv("TEST_WORKSPACE")
55		if workspace != "" && workspace != base {
56			return fmt.Errorf("RunfilesPath: %q does not match test workspace %s", dir, workspace)
57		}
58		if srcDir := os.Getenv("TEST_SRCDIR"); srcDir != "" && filepath.Join(srcDir, workspace) != dir {
59			return fmt.Errorf("RunfilesPath: %q does not match TEST_SRCDIR %q", dir, srcDir)
60		}
61	}
62
63	// Check that files can be found with Runfile or FindBinary.
64	// Make sure the paths returned are absolute paths to actual files.
65	seen := make(map[string]string)
66	for _, f := range files {
67		var got string
68		var err error
69		if !f.Binary {
70			if got, err = bazel.Runfile(f.Path); err != nil {
71				return err
72			}
73			if !filepath.IsAbs(got) {
74				return fmt.Errorf("Runfile %s: got a relative path %q; want absolute", f.Path, got)
75			}
76			seen[f.Path] = got
77		} else {
78			var pkg, name string
79			if i := strings.LastIndex(f.Path, "/"); i < 0 {
80				name = f.Path
81			} else {
82				pkg = f.Path[:i]
83				name = f.Path[i+1:]
84			}
85			var ok bool
86			if got, ok = bazel.FindBinary(pkg, name); !ok {
87				return fmt.Errorf("FindBinary %s %s: could not find binary", pkg, name)
88			}
89			if !filepath.IsAbs(got) {
90				return fmt.Errorf("FindBinary %s %s: got a relative path %q; want absolute", pkg, name, got)
91			}
92		}
93
94		if _, err := os.Stat(got); err != nil {
95			return fmt.Errorf("%s: could not stat: %v", f.Path, err)
96		}
97	}
98
99	// Check that the files can be listed.
100	entries, err := bazel.ListRunfiles()
101	if err != nil {
102		return err
103	}
104	for _, e := range entries {
105		if want, ok := seen[e.ShortPath]; ok && want != e.Path {
106			return err
107		}
108		delete(seen, e.ShortPath)
109	}
110
111	if len(seen) > 0 {
112		unseen := make([]string, 0, len(seen))
113		for short := range seen {
114			unseen = append(unseen, short)
115		}
116		sort.Strings(unseen)
117		return fmt.Errorf("ListRunfiles did not include files:\n\t%s", strings.Join(unseen, "\n\t"))
118	}
119
120	return nil
121}
122