xref: /aosp_15_r20/external/bazel-skylib/gazelle/bzl/gazelle_test.go (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1*bcb5dc79SHONG Yifanpackage bzl
2*bcb5dc79SHONG Yifan
3*bcb5dc79SHONG Yifan/* Copyright 2020 The Bazel Authors. All rights reserved.
4*bcb5dc79SHONG Yifan
5*bcb5dc79SHONG YifanLicensed under the Apache License, Version 2.0 (the "License");
6*bcb5dc79SHONG Yifanyou may not use this file except in compliance with the License.
7*bcb5dc79SHONG YifanYou may obtain a copy of the License at
8*bcb5dc79SHONG Yifan
9*bcb5dc79SHONG Yifan   http://www.apache.org/licenses/LICENSE-2.0
10*bcb5dc79SHONG Yifan
11*bcb5dc79SHONG YifanUnless required by applicable law or agreed to in writing, software
12*bcb5dc79SHONG Yifandistributed under the License is distributed on an "AS IS" BASIS,
13*bcb5dc79SHONG YifanWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*bcb5dc79SHONG YifanSee the License for the specific language governing permissions and
15*bcb5dc79SHONG Yifanlimitations under the License.
16*bcb5dc79SHONG Yifan*/
17*bcb5dc79SHONG Yifan
18*bcb5dc79SHONG Yifanimport (
19*bcb5dc79SHONG Yifan	"io/ioutil"
20*bcb5dc79SHONG Yifan	"os"
21*bcb5dc79SHONG Yifan	"os/exec"
22*bcb5dc79SHONG Yifan	"path/filepath"
23*bcb5dc79SHONG Yifan	"strings"
24*bcb5dc79SHONG Yifan	"testing"
25*bcb5dc79SHONG Yifan
26*bcb5dc79SHONG Yifan	"github.com/bazelbuild/bazel-gazelle/testtools"
27*bcb5dc79SHONG Yifan	"github.com/bazelbuild/rules_go/go/tools/bazel"
28*bcb5dc79SHONG Yifan)
29*bcb5dc79SHONG Yifan
30*bcb5dc79SHONG Yifanvar gazellePath = findGazelle()
31*bcb5dc79SHONG Yifan
32*bcb5dc79SHONG Yifanconst testDataPath = "bzl/testdata/"
33*bcb5dc79SHONG Yifan
34*bcb5dc79SHONG Yifan// TestGazelleBinary runs a gazelle binary with starlib installed on each
35*bcb5dc79SHONG Yifan// directory in `testdata/*`. Please see `testdata/README.md` for more
36*bcb5dc79SHONG Yifan// information on each test.
37*bcb5dc79SHONG Yifanfunc TestGazelleBinary(t *testing.T) {
38*bcb5dc79SHONG Yifan	tests := map[string][]bazel.RunfileEntry{}
39*bcb5dc79SHONG Yifan
40*bcb5dc79SHONG Yifan	files, err := bazel.ListRunfiles()
41*bcb5dc79SHONG Yifan	if err != nil {
42*bcb5dc79SHONG Yifan		t.Fatalf("bazel.ListRunfiles() error: %v", err)
43*bcb5dc79SHONG Yifan	}
44*bcb5dc79SHONG Yifan	for _, f := range files {
45*bcb5dc79SHONG Yifan		if strings.HasPrefix(f.ShortPath, testDataPath) {
46*bcb5dc79SHONG Yifan			relativePath := strings.TrimPrefix(f.ShortPath, testDataPath)
47*bcb5dc79SHONG Yifan			parts := strings.SplitN(relativePath, "/", 2)
48*bcb5dc79SHONG Yifan			if len(parts) < 2 {
49*bcb5dc79SHONG Yifan				// This file is not a part of a testcase since it must be in a dir that
50*bcb5dc79SHONG Yifan				// is the test case and then have a path inside of that.
51*bcb5dc79SHONG Yifan				continue
52*bcb5dc79SHONG Yifan			}
53*bcb5dc79SHONG Yifan
54*bcb5dc79SHONG Yifan			tests[parts[0]] = append(tests[parts[0]], f)
55*bcb5dc79SHONG Yifan		}
56*bcb5dc79SHONG Yifan	}
57*bcb5dc79SHONG Yifan	if len(tests) == 0 {
58*bcb5dc79SHONG Yifan		t.Fatal("no tests found")
59*bcb5dc79SHONG Yifan	}
60*bcb5dc79SHONG Yifan
61*bcb5dc79SHONG Yifan	for testName, files := range tests {
62*bcb5dc79SHONG Yifan		testPath(t, testName, files)
63*bcb5dc79SHONG Yifan	}
64*bcb5dc79SHONG Yifan}
65*bcb5dc79SHONG Yifan
66*bcb5dc79SHONG Yifanfunc testPath(t *testing.T, name string, files []bazel.RunfileEntry) {
67*bcb5dc79SHONG Yifan	t.Run(name, func(t *testing.T) {
68*bcb5dc79SHONG Yifan		var inputs []testtools.FileSpec
69*bcb5dc79SHONG Yifan		var goldens []testtools.FileSpec
70*bcb5dc79SHONG Yifan
71*bcb5dc79SHONG Yifan		for _, f := range files {
72*bcb5dc79SHONG Yifan			path := f.Path
73*bcb5dc79SHONG Yifan			trim := testDataPath + name + "/"
74*bcb5dc79SHONG Yifan			shortPath := strings.TrimPrefix(f.ShortPath, trim)
75*bcb5dc79SHONG Yifan			info, err := os.Stat(path)
76*bcb5dc79SHONG Yifan			if err != nil {
77*bcb5dc79SHONG Yifan				t.Fatalf("os.Stat(%q) error: %v", path, err)
78*bcb5dc79SHONG Yifan			}
79*bcb5dc79SHONG Yifan
80*bcb5dc79SHONG Yifan			// Skip dirs.
81*bcb5dc79SHONG Yifan			if info.IsDir() {
82*bcb5dc79SHONG Yifan				continue
83*bcb5dc79SHONG Yifan			}
84*bcb5dc79SHONG Yifan
85*bcb5dc79SHONG Yifan			content, err := ioutil.ReadFile(path)
86*bcb5dc79SHONG Yifan			if err != nil {
87*bcb5dc79SHONG Yifan				t.Errorf("ioutil.ReadFile(%q) error: %v", path, err)
88*bcb5dc79SHONG Yifan			}
89*bcb5dc79SHONG Yifan
90*bcb5dc79SHONG Yifan			// Now trim the common prefix off.
91*bcb5dc79SHONG Yifan			if strings.HasSuffix(shortPath, ".in") {
92*bcb5dc79SHONG Yifan				inputs = append(inputs, testtools.FileSpec{
93*bcb5dc79SHONG Yifan					Path:    strings.TrimSuffix(shortPath, ".in"),
94*bcb5dc79SHONG Yifan					Content: string(content),
95*bcb5dc79SHONG Yifan				})
96*bcb5dc79SHONG Yifan			} else if strings.HasSuffix(shortPath, ".out") {
97*bcb5dc79SHONG Yifan				goldens = append(goldens, testtools.FileSpec{
98*bcb5dc79SHONG Yifan					Path:    strings.TrimSuffix(shortPath, ".out"),
99*bcb5dc79SHONG Yifan					Content: string(content),
100*bcb5dc79SHONG Yifan				})
101*bcb5dc79SHONG Yifan			} else {
102*bcb5dc79SHONG Yifan				inputs = append(inputs, testtools.FileSpec{
103*bcb5dc79SHONG Yifan					Path:    shortPath,
104*bcb5dc79SHONG Yifan					Content: string(content),
105*bcb5dc79SHONG Yifan				})
106*bcb5dc79SHONG Yifan				goldens = append(goldens, testtools.FileSpec{
107*bcb5dc79SHONG Yifan					Path:    shortPath,
108*bcb5dc79SHONG Yifan					Content: string(content),
109*bcb5dc79SHONG Yifan				})
110*bcb5dc79SHONG Yifan			}
111*bcb5dc79SHONG Yifan		}
112*bcb5dc79SHONG Yifan
113*bcb5dc79SHONG Yifan		dir, cleanup := testtools.CreateFiles(t, inputs)
114*bcb5dc79SHONG Yifan		defer cleanup()
115*bcb5dc79SHONG Yifan
116*bcb5dc79SHONG Yifan		cmd := exec.Command(gazellePath, "-build_file_name=BUILD")
117*bcb5dc79SHONG Yifan		cmd.Stdout = os.Stdout
118*bcb5dc79SHONG Yifan		cmd.Stderr = os.Stderr
119*bcb5dc79SHONG Yifan		cmd.Dir = dir
120*bcb5dc79SHONG Yifan		if err := cmd.Run(); err != nil {
121*bcb5dc79SHONG Yifan			t.Fatal(err)
122*bcb5dc79SHONG Yifan		}
123*bcb5dc79SHONG Yifan
124*bcb5dc79SHONG Yifan		testtools.CheckFiles(t, dir, goldens)
125*bcb5dc79SHONG Yifan		if t.Failed() {
126*bcb5dc79SHONG Yifan			filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
127*bcb5dc79SHONG Yifan				if err != nil {
128*bcb5dc79SHONG Yifan					return err
129*bcb5dc79SHONG Yifan				}
130*bcb5dc79SHONG Yifan				t.Logf("%q exists", path)
131*bcb5dc79SHONG Yifan				return nil
132*bcb5dc79SHONG Yifan			})
133*bcb5dc79SHONG Yifan		}
134*bcb5dc79SHONG Yifan	})
135*bcb5dc79SHONG Yifan}
136*bcb5dc79SHONG Yifan
137*bcb5dc79SHONG Yifanfunc findGazelle() string {
138*bcb5dc79SHONG Yifan	gazellePath, ok := bazel.FindBinary("bzl", "gazelle-skylib")
139*bcb5dc79SHONG Yifan	if !ok {
140*bcb5dc79SHONG Yifan		panic("could not find gazelle binary")
141*bcb5dc79SHONG Yifan	}
142*bcb5dc79SHONG Yifan	return gazellePath
143*bcb5dc79SHONG Yifan}
144