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