github.com/bazelbuild/rules_go@v0.47.2-0.20240515105122-e7ddb9ea474e/go/tools/bazel/bazel_test.go (about)

     1  // Copyright 2017 Google Inc.
     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  package bazel
    15  
    16  import (
    17  	"errors"
    18  	"fmt"
    19  	"io/ioutil"
    20  	"os"
    21  	"strings"
    22  	"testing"
    23  )
    24  
    25  // makeAndEnterTempdir creates a temporary directory and chdirs into it.
    26  func makeAndEnterTempdir() (func(), error) {
    27  	oldCwd, err := os.Getwd()
    28  	if err != nil {
    29  		return nil, fmt.Errorf("cannot get path to current directory: %v", err)
    30  	}
    31  
    32  	tempDir, err := ioutil.TempDir("", "test")
    33  	if err != nil {
    34  		return nil, fmt.Errorf("failed to create temporary directory: %v", err)
    35  	}
    36  
    37  	err = os.Chdir(tempDir)
    38  	if err != nil {
    39  		os.RemoveAll(tempDir)
    40  		return nil, fmt.Errorf("cannot enter temporary directory %s: %v", tempDir, err)
    41  	}
    42  
    43  	cleanup := func() {
    44  		defer os.RemoveAll(tempDir)
    45  		defer os.Chdir(oldCwd)
    46  	}
    47  	return cleanup, nil
    48  }
    49  
    50  // createPaths creates a collection of paths for testing purposes.  Paths can end with a /, in
    51  // which case a directory is created; or they can end with a *, in which case an executable file
    52  // is created.  (This matches the nomenclature of "ls -F".)
    53  func createPaths(paths []string) error {
    54  	for _, path := range paths {
    55  		if strings.HasSuffix(path, "/") {
    56  			if err := os.MkdirAll(path, 0755); err != nil {
    57  				return fmt.Errorf("failed to create directory %s: %v", path, err)
    58  			}
    59  		} else {
    60  			mode := os.FileMode(0644)
    61  			if strings.HasSuffix(path, "*") {
    62  				path = path[0 : len(path)-1]
    63  				mode |= 0111
    64  			}
    65  			if err := ioutil.WriteFile(path, []byte{}, mode); err != nil {
    66  				return fmt.Errorf("failed to create file %s with mode %v: %v", path, mode, err)
    67  			}
    68  		}
    69  	}
    70  	return nil
    71  }
    72  
    73  func TestRunfile(t *testing.T) {
    74  	file := "go/tools/bazel/empty.txt"
    75  	runfile, err := Runfile(file)
    76  	if err != nil {
    77  		t.Errorf("When reading file %s got error %s", file, err)
    78  	}
    79  
    80  	// Check that the file actually exist
    81  	if _, err := os.Stat(runfile); err != nil {
    82  		t.Errorf("File found by runfile doesn't exist")
    83  	}
    84  }
    85  
    86  func TestRunfilesPath(t *testing.T) {
    87  	path, err := RunfilesPath()
    88  	if err != nil {
    89  		t.Errorf("Error finding runfiles path: %s", err)
    90  	}
    91  
    92  	if path == "" {
    93  		t.Errorf("Runfiles path is empty: %s", path)
    94  	}
    95  }
    96  
    97  func TestNewTmpDir(t *testing.T) {
    98  	// prefix := "new/temp/dir"
    99  	prefix := "demodir"
   100  	tmpdir, err := NewTmpDir(prefix)
   101  	if err != nil {
   102  		t.Errorf("When creating temp dir %s got error %s", prefix, err)
   103  	}
   104  
   105  	// Check that the tempdir actually exist
   106  	if _, err := os.Stat(tmpdir); err != nil {
   107  		t.Errorf("New tempdir (%s) not created. Got error %s", tmpdir, err)
   108  	}
   109  }
   110  
   111  func TestTestTmpDir(t *testing.T) {
   112  	if TestTmpDir() == "" {
   113  		t.Errorf("TestTmpDir (TEST_TMPDIR) was left empty")
   114  	}
   115  }
   116  
   117  func TestTestWorkspace(t *testing.T) {
   118  	workspace, err := TestWorkspace()
   119  
   120  	if workspace == "" {
   121  		t.Errorf("Workspace is left empty")
   122  	}
   123  
   124  	if err != nil {
   125  		t.Errorf("Unable to get workspace with error %s", err)
   126  	}
   127  }
   128  
   129  func TestPythonManifest(t *testing.T) {
   130  	cleanup, err := makeAndEnterTempdir()
   131  	if err != nil {
   132  		t.Fatal(err)
   133  	}
   134  	defer cleanup()
   135  
   136  	err = ioutil.WriteFile("MANIFEST",
   137  		// all on one line to make sure the whitespace stays exactly as in the source file
   138  		[]byte("__init__.py \n__main__/external/__init__.py \n__main__/external/rules_python/__init__.py \n__main__/external/rules_python/python/__init__.py \n__main__/external/rules_python/python/runfiles/__init__.py \n__main__/external/rules_python/python/runfiles/runfiles.py C:/users/sam/_bazel_sam/pj4cl7d4/external/rules_python/python/runfiles/runfiles.py\n__main__/go_cat_/go_cat.exe C:/users/sam/_bazel_sam/pj4cl7d4/execroot/__main__/bazel-out/x64_windows-opt-exec-2B5CBBC6/bin/go_cat_/go_cat.exe\n__main__/important.txt C:/users/sam/dev/rules_go_runfiles_repro/important.txt\n__main__/parent.exe C:/users/sam/_bazel_sam/pj4cl7d4/execroot/__main__/bazel-out/x64_windows-opt-exec-2B5CBBC6/bin/parent.exe\n__main__/parent.py C:/users/sam/dev/rules_go_runfiles_repro/parent.py\n__main__/parent.zip C:/users/sam/_bazel_sam/pj4cl7d4/execroot/__main__/bazel-out/x64_windows-opt-exec-2B5CBBC6/bin/parent.zip\nrules_python/__init__.py \nrules_python/python/__init__.py \nrules_python/python/runfiles/__init__.py \nrules_python/python/runfiles/runfiles.py C:/users/sam/_bazel_sam/pj4cl7d4/external/rules_python/python/runfiles/runfiles.py"),
   139  		os.FileMode(0644),
   140  	)
   141  	if err != nil {
   142  		t.Fatalf("Failed to write sample manifest: %v", err)
   143  	}
   144  
   145  	originalEnvVar := os.Getenv(RUNFILES_MANIFEST_FILE)
   146  	defer func() {
   147  		if err = os.Setenv(RUNFILES_MANIFEST_FILE, originalEnvVar); err != nil {
   148  			t.Fatalf("Failed to reset environment: %v", err)
   149  		}
   150  	}()
   151  
   152  	if err = os.Setenv(RUNFILES_MANIFEST_FILE, "MANIFEST"); err != nil {
   153  		t.Fatalf("Failed to set manifest file environement variable: %v", err)
   154  	}
   155  
   156  	initRunfiles()
   157  
   158  	if runfiles.err != nil {
   159  		t.Errorf("failed to init runfiles: %v", runfiles.err)
   160  	}
   161  
   162  	entry, ok := runfiles.index.GetIgnoringWorkspace("important.txt")
   163  	if !ok {
   164  		t.Errorf("failed to locate runfile %s in index", "important.txt")
   165  	}
   166  
   167  	if entry.Workspace != "__main__" {
   168  		t.Errorf("incorrect workspace for runfile. Expected: %s, actual %s", "__main__", entry.Workspace)
   169  	}
   170  }
   171  
   172  func TestSpliceDelimitedOSArgs(t *testing.T) {
   173  	testData := map[string]struct {
   174  		initial []string
   175  		want    []string
   176  		final   []string
   177  		wantErr error
   178  	}{
   179  		"no args": {
   180  			[]string{},
   181  			[]string{},
   182  			[]string{},
   183  			nil,
   184  		},
   185  		"empty splice": {
   186  			[]string{"-begin_files", "-end_files"},
   187  			[]string{},
   188  			[]string{},
   189  			nil,
   190  		},
   191  		"removes inner args": {
   192  			[]string{"-begin_files", "a", "-end_files"},
   193  			[]string{"a"},
   194  			[]string{},
   195  			nil,
   196  		},
   197  		"preserves outer args": {
   198  			[]string{"a", "-begin_files", "b", "c", "-end_files", "d"},
   199  			[]string{"b", "c"},
   200  			[]string{"a", "d"},
   201  			nil,
   202  		},
   203  		"complains about missing end delimiter": {
   204  			[]string{"-begin_files"},
   205  			[]string{},
   206  			[]string{},
   207  			errors.New("error: -begin_files, -end_files not set together or in order"),
   208  		},
   209  		"complains about missing begin delimiter": {
   210  			[]string{"-end_files"},
   211  			[]string{},
   212  			[]string{},
   213  			errors.New("error: -begin_files, -end_files not set together or in order"),
   214  		},
   215  		"complains about out-of-order delimiter": {
   216  			[]string{"-end_files", "-begin_files"},
   217  			[]string{},
   218  			[]string{},
   219  			errors.New("error: -begin_files, -end_files not set together or in order"),
   220  		},
   221  		"-- at middle": {
   222  			[]string{"-begin_files", "a", "b", "--", "-end_files"},
   223  			[]string{},
   224  			[]string{},
   225  			errors.New("error: -begin_files, -end_files not set together or in order"),
   226  		},
   227  		"-- at beginning": {
   228  			[]string{"--", "-begin_files", "a", "-end_files"},
   229  			[]string{},
   230  			[]string{"--", "-begin_files", "a", "-end_files"},
   231  			nil,
   232  		},
   233  	}
   234  	for name, tc := range testData {
   235  		t.Run(name, func(t *testing.T) {
   236  			os.Args = tc.initial
   237  			got, err := SpliceDelimitedOSArgs("-begin_files", "-end_files")
   238  			if err != nil {
   239  				if tc.wantErr == nil {
   240  					t.Fatalf("unexpected err: %v", err)
   241  				}
   242  				if tc.wantErr.Error() != err.Error() {
   243  					t.Fatalf("err: want %v, got %v", tc.wantErr, err)
   244  				}
   245  				return
   246  			}
   247  			if len(tc.want) != len(got) {
   248  				t.Fatalf("len(want: %d, got %d", len(tc.want), len(got))
   249  			}
   250  			for i, actual := range got {
   251  				expected := tc.want[i]
   252  				if expected != actual {
   253  					t.Errorf("%d: want %v, got %v", i, expected, actual)
   254  				}
   255  			}
   256  			if len(tc.final) != len(os.Args) {
   257  				t.Fatalf("len(want: %d, os.Args %d", len(tc.final), len(os.Args))
   258  			}
   259  			for i, actual := range os.Args {
   260  				expected := tc.final[i]
   261  				if expected != actual {
   262  					t.Errorf("%d: want %v, os.Args %v", i, expected, actual)
   263  				}
   264  			}
   265  		})
   266  	}
   267  }