xref: /aosp_15_r20/external/bazelbuild-rules_go/tests/runfiles/runfiles_test.go (revision 9bb1b549b6a84214c53be0924760be030e66b93a)
1*9bb1b549SSpandan Das// Copyright 2020, 2021, 2022 Google LLC
2*9bb1b549SSpandan Das//
3*9bb1b549SSpandan Das// Licensed under the Apache License, Version 2.0 (the "License");
4*9bb1b549SSpandan Das// you may not use this file except in compliance with the License.
5*9bb1b549SSpandan Das// You may obtain a copy of the License at
6*9bb1b549SSpandan Das//
7*9bb1b549SSpandan Das//     https://www.apache.org/licenses/LICENSE-2.0
8*9bb1b549SSpandan Das//
9*9bb1b549SSpandan Das// Unless required by applicable law or agreed to in writing, software
10*9bb1b549SSpandan Das// distributed under the License is distributed on an "AS IS" BASIS,
11*9bb1b549SSpandan Das// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9bb1b549SSpandan Das// See the License for the specific language governing permissions and
13*9bb1b549SSpandan Das// limitations under the License.
14*9bb1b549SSpandan Das
15*9bb1b549SSpandan Daspackage runfiles_test
16*9bb1b549SSpandan Das
17*9bb1b549SSpandan Dasimport (
18*9bb1b549SSpandan Das	"errors"
19*9bb1b549SSpandan Das	"os"
20*9bb1b549SSpandan Das	"os/exec"
21*9bb1b549SSpandan Das	"path/filepath"
22*9bb1b549SSpandan Das	"runtime"
23*9bb1b549SSpandan Das	"strings"
24*9bb1b549SSpandan Das	"testing"
25*9bb1b549SSpandan Das
26*9bb1b549SSpandan Das	"github.com/bazelbuild/rules_go/go/runfiles"
27*9bb1b549SSpandan Das)
28*9bb1b549SSpandan Das
29*9bb1b549SSpandan Dasfunc TestPath_FileLookup(t *testing.T) {
30*9bb1b549SSpandan Das	path, err := runfiles.Rlocation("io_bazel_rules_go/tests/runfiles/test.txt")
31*9bb1b549SSpandan Das	if err != nil {
32*9bb1b549SSpandan Das		t.Fatal(err)
33*9bb1b549SSpandan Das	}
34*9bb1b549SSpandan Das	b, err := os.ReadFile(path)
35*9bb1b549SSpandan Das	if err != nil {
36*9bb1b549SSpandan Das		t.Fatal(err)
37*9bb1b549SSpandan Das	}
38*9bb1b549SSpandan Das	got := strings.TrimSpace(string(b))
39*9bb1b549SSpandan Das	want := "hi!"
40*9bb1b549SSpandan Das	if got != want {
41*9bb1b549SSpandan Das		t.Errorf("got %q, want %q", got, want)
42*9bb1b549SSpandan Das	}
43*9bb1b549SSpandan Das}
44*9bb1b549SSpandan Das
45*9bb1b549SSpandan Dasfunc TestPath_SubprocessRunfilesLookup(t *testing.T) {
46*9bb1b549SSpandan Das	r, err := runfiles.New()
47*9bb1b549SSpandan Das	if err != nil {
48*9bb1b549SSpandan Das		panic(err)
49*9bb1b549SSpandan Das	}
50*9bb1b549SSpandan Das	// The binary “testprog” is itself built with Bazel, and needs
51*9bb1b549SSpandan Das	// runfiles.
52*9bb1b549SSpandan Das	testprogRpath := "io_bazel_rules_go/tests/runfiles/testprog/testprog_/testprog"
53*9bb1b549SSpandan Das	if runtime.GOOS == "windows" {
54*9bb1b549SSpandan Das		testprogRpath += ".exe"
55*9bb1b549SSpandan Das	}
56*9bb1b549SSpandan Das	prog, err := r.Rlocation(testprogRpath)
57*9bb1b549SSpandan Das	if err != nil {
58*9bb1b549SSpandan Das		panic(err)
59*9bb1b549SSpandan Das	}
60*9bb1b549SSpandan Das	cmd := exec.Command(prog)
61*9bb1b549SSpandan Das	// We add r.Env() after os.Environ() so that runfile environment
62*9bb1b549SSpandan Das	// variables override anything set in the process environment.
63*9bb1b549SSpandan Das	cmd.Env = append(os.Environ(), r.Env()...)
64*9bb1b549SSpandan Das	out, err := cmd.Output()
65*9bb1b549SSpandan Das	if err != nil {
66*9bb1b549SSpandan Das		t.Fatal(err)
67*9bb1b549SSpandan Das	}
68*9bb1b549SSpandan Das	got := strings.TrimSpace(string(out))
69*9bb1b549SSpandan Das	want := "hi!"
70*9bb1b549SSpandan Das	if got != want {
71*9bb1b549SSpandan Das		t.Errorf("got %q, want %q", got, want)
72*9bb1b549SSpandan Das	}
73*9bb1b549SSpandan Das}
74*9bb1b549SSpandan Das
75*9bb1b549SSpandan Dasfunc TestPath_errors(t *testing.T) {
76*9bb1b549SSpandan Das	r, err := runfiles.New()
77*9bb1b549SSpandan Das	if err != nil {
78*9bb1b549SSpandan Das		t.Fatal(err)
79*9bb1b549SSpandan Das	}
80*9bb1b549SSpandan Das	for _, s := range []string{"", "/..", "../", "a/../b", "a//b", "a/./b", `\a`} {
81*9bb1b549SSpandan Das		t.Run(s, func(t *testing.T) {
82*9bb1b549SSpandan Das			if got, err := r.Rlocation(s); err == nil {
83*9bb1b549SSpandan Das				t.Errorf("got %q, want error", got)
84*9bb1b549SSpandan Das			}
85*9bb1b549SSpandan Das		})
86*9bb1b549SSpandan Das	}
87*9bb1b549SSpandan Das	for _, s := range []string{"foo/..bar", "foo/.bar"} {
88*9bb1b549SSpandan Das		t.Run(s, func(t *testing.T) {
89*9bb1b549SSpandan Das			if _, err := r.Rlocation(s); err != nil && !os.IsNotExist(err.(runfiles.Error).Err) {
90*9bb1b549SSpandan Das				t.Errorf("got %q, want none or 'file not found' error", err)
91*9bb1b549SSpandan Das			}
92*9bb1b549SSpandan Das		})
93*9bb1b549SSpandan Das	}
94*9bb1b549SSpandan Das}
95*9bb1b549SSpandan Das
96*9bb1b549SSpandan Dasfunc TestRunfiles_zero(t *testing.T) {
97*9bb1b549SSpandan Das	var r runfiles.Runfiles
98*9bb1b549SSpandan Das	if got, err := r.Rlocation("a"); err == nil {
99*9bb1b549SSpandan Das		t.Errorf("Rlocation: got %q, want error", got)
100*9bb1b549SSpandan Das	}
101*9bb1b549SSpandan Das	if got := r.Env(); got != nil {
102*9bb1b549SSpandan Das		t.Errorf("Env: got %v, want nil", got)
103*9bb1b549SSpandan Das	}
104*9bb1b549SSpandan Das}
105*9bb1b549SSpandan Das
106*9bb1b549SSpandan Dasfunc TestRunfiles_empty(t *testing.T) {
107*9bb1b549SSpandan Das	dir := t.TempDir()
108*9bb1b549SSpandan Das	manifest := filepath.Join(dir, "manifest")
109*9bb1b549SSpandan Das	if err := os.WriteFile(manifest, []byte("__init__.py \n"), 0o600); err != nil {
110*9bb1b549SSpandan Das		t.Fatal(err)
111*9bb1b549SSpandan Das	}
112*9bb1b549SSpandan Das	r, err := runfiles.New(runfiles.ManifestFile(manifest))
113*9bb1b549SSpandan Das	if err != nil {
114*9bb1b549SSpandan Das		t.Fatal(err)
115*9bb1b549SSpandan Das	}
116*9bb1b549SSpandan Das	_, got := r.Rlocation("__init__.py")
117*9bb1b549SSpandan Das	want := runfiles.ErrEmpty
118*9bb1b549SSpandan Das	if !errors.Is(got, want) {
119*9bb1b549SSpandan Das		t.Errorf("Rlocation for empty file: got error %q, want something that wraps %q", got, want)
120*9bb1b549SSpandan Das	}
121*9bb1b549SSpandan Das}
122*9bb1b549SSpandan Das
123*9bb1b549SSpandan Dasfunc TestRunfiles_manifestWithDir(t *testing.T) {
124*9bb1b549SSpandan Das	dir := t.TempDir()
125*9bb1b549SSpandan Das	manifest := filepath.Join(dir, "manifest")
126*9bb1b549SSpandan Das	if err := os.WriteFile(manifest, []byte("foo/dir path/to/foo/dir\n"), 0o600); err != nil {
127*9bb1b549SSpandan Das		t.Fatal(err)
128*9bb1b549SSpandan Das	}
129*9bb1b549SSpandan Das	r, err := runfiles.New(runfiles.ManifestFile(manifest))
130*9bb1b549SSpandan Das	if err != nil {
131*9bb1b549SSpandan Das		t.Fatal(err)
132*9bb1b549SSpandan Das	}
133*9bb1b549SSpandan Das
134*9bb1b549SSpandan Das	for rlocation, want := range map[string]string{
135*9bb1b549SSpandan Das		"foo/dir":                    filepath.FromSlash("path/to/foo/dir"),
136*9bb1b549SSpandan Das		"foo/dir/file":               filepath.FromSlash("path/to/foo/dir/file"),
137*9bb1b549SSpandan Das		"foo/dir/deeply/nested/file": filepath.FromSlash("path/to/foo/dir/deeply/nested/file"),
138*9bb1b549SSpandan Das	} {
139*9bb1b549SSpandan Das		t.Run(rlocation, func(t *testing.T) {
140*9bb1b549SSpandan Das			got, err := r.Rlocation(rlocation)
141*9bb1b549SSpandan Das			if err != nil {
142*9bb1b549SSpandan Das				t.Fatalf("Rlocation failed: got unexpected error %q", err)
143*9bb1b549SSpandan Das			}
144*9bb1b549SSpandan Das			if got != want {
145*9bb1b549SSpandan Das				t.Errorf("Rlocation failed: got %q, want %q", got, want)
146*9bb1b549SSpandan Das			}
147*9bb1b549SSpandan Das		})
148*9bb1b549SSpandan Das	}
149*9bb1b549SSpandan Das}
150