github.com/wolfd/bazel-gazelle@v0.14.0/cmd/gazelle/integration_test.go (about)

     1  /* Copyright 2017 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  */
    15  
    16  // This file contains integration tests for all of Gazelle. It's meant to test
    17  // common usage patterns and check for errors that are difficult to test in
    18  // unit tests.
    19  
    20  package main
    21  
    22  import (
    23  	"bytes"
    24  	"flag"
    25  	"io/ioutil"
    26  	"log"
    27  	"os"
    28  	"path/filepath"
    29  	"strings"
    30  	"testing"
    31  
    32  	"github.com/bazelbuild/bazel-gazelle/internal/config"
    33  	"github.com/bazelbuild/bazel-gazelle/internal/wspace"
    34  )
    35  
    36  type fileSpec struct {
    37  	path, content string
    38  }
    39  
    40  func createFiles(files []fileSpec) (string, error) {
    41  	dir, err := ioutil.TempDir(os.Getenv("TEST_TEMPDIR"), "integration_test")
    42  	if err != nil {
    43  		return "", err
    44  	}
    45  
    46  	for _, f := range files {
    47  		path := filepath.Join(dir, filepath.FromSlash(f.path))
    48  		if strings.HasSuffix(f.path, "/") {
    49  			if err := os.MkdirAll(path, 0700); err != nil {
    50  				os.RemoveAll(dir)
    51  				return "", err
    52  			}
    53  			continue
    54  		}
    55  		if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
    56  			os.RemoveAll(dir)
    57  			return "", err
    58  		}
    59  		if err := ioutil.WriteFile(path, []byte(f.content), 0600); err != nil {
    60  			os.RemoveAll(dir)
    61  			return "", err
    62  		}
    63  	}
    64  	return dir, nil
    65  }
    66  
    67  // skipIfWorkspaceVisible skips the test if the WORKSPACE file for the
    68  // repository is visible. This happens in newer Bazel versions when tests
    69  // are run without sandboxing, since temp directories may be inside the
    70  // exec root.
    71  func skipIfWorkspaceVisible(t *testing.T, dir string) {
    72  	if parent, err := wspace.Find(dir); err == nil {
    73  		t.Skipf("WORKSPACE visible in parent %q of tmp %q", parent, dir)
    74  	}
    75  }
    76  
    77  func checkFiles(t *testing.T, dir string, files []fileSpec) {
    78  	for _, f := range files {
    79  		path := filepath.Join(dir, f.path)
    80  		if strings.HasSuffix(f.path, "/") {
    81  			if st, err := os.Stat(path); err != nil {
    82  				t.Errorf("could not stat %s: %v", f.path, err)
    83  			} else if !st.IsDir() {
    84  				t.Errorf("not a directory: %s", f.path)
    85  			}
    86  		} else {
    87  			want := strings.TrimSpace(f.content)
    88  			gotBytes, err := ioutil.ReadFile(filepath.Join(dir, f.path))
    89  			if err != nil {
    90  				t.Errorf("could not read %s: %v", f.path, err)
    91  				continue
    92  			}
    93  			got := strings.TrimSpace(string(gotBytes))
    94  			if got != want {
    95  				t.Errorf("%s: got:\n%s\nwant:\n %s", f.path, gotBytes, f.content)
    96  			}
    97  		}
    98  	}
    99  }
   100  
   101  func runGazelle(wd string, args []string) error {
   102  	oldWd, err := os.Getwd()
   103  	if err != nil {
   104  		return err
   105  	}
   106  	if err := os.Chdir(wd); err != nil {
   107  		return err
   108  	}
   109  	defer os.Chdir(oldWd)
   110  
   111  	return run(args)
   112  }
   113  
   114  // TestHelp checks that help commands do not panic due to nil flag values.
   115  // Verifies #256.
   116  func TestHelp(t *testing.T) {
   117  	for _, args := range [][]string{
   118  		{"help"},
   119  		{"fix", "-h"},
   120  		{"update", "-h"},
   121  		{"update-repos", "-h"},
   122  	} {
   123  		t.Run(args[0], func(t *testing.T) {
   124  			if err := runGazelle(".", args); err == nil {
   125  				t.Errorf("%s: got success, want flag.ErrHelp", args[0])
   126  			} else if err != flag.ErrHelp {
   127  				t.Errorf("%s: got %v, want flag.ErrHelp", args[0], err)
   128  			}
   129  		})
   130  	}
   131  }
   132  
   133  func TestNoRepoRootOrWorkspace(t *testing.T) {
   134  	dir, err := createFiles(nil)
   135  	if err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	defer os.RemoveAll(dir)
   139  	skipIfWorkspaceVisible(t, dir)
   140  	want := "-repo_root not specified"
   141  	if err := runGazelle(dir, nil); err == nil {
   142  		t.Fatalf("got success; want %q", want)
   143  	} else if !strings.Contains(err.Error(), want) {
   144  		t.Fatalf("got %q; want %q", err, want)
   145  	}
   146  }
   147  
   148  func TestNoGoPrefixArgOrRule(t *testing.T) {
   149  	dir, err := createFiles([]fileSpec{
   150  		{path: "WORKSPACE", content: ""},
   151  		{path: "hello.go", content: "package hello"},
   152  	})
   153  	if err != nil {
   154  		t.Fatal(err)
   155  	}
   156  	buf := new(bytes.Buffer)
   157  	log.SetOutput(buf)
   158  	defer log.SetOutput(os.Stderr)
   159  	if err := runGazelle(dir, nil); err != nil {
   160  		t.Fatalf("got %#v; want success", err)
   161  	}
   162  	want := "go prefix is not set"
   163  	if !strings.Contains(buf.String(), want) {
   164  		t.Errorf("log does not contain %q\n--begin--\n%s--end--\n", want, buf.String())
   165  	}
   166  }
   167  
   168  // TestSelectLabelsSorted checks that string lists in srcs and deps are sorted
   169  // using buildifier order, even if they are inside select expressions.
   170  // This applies to both new and existing lists and should preserve comments.
   171  // buildifier does not do this yet bazelbuild/buildtools#122, so we do this
   172  // in addition to calling build.Rewrite.
   173  func TestSelectLabelsSorted(t *testing.T) {
   174  	dir, err := createFiles([]fileSpec{
   175  		{path: "WORKSPACE"},
   176  		{
   177  			path: "BUILD",
   178  			content: `
   179  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   180  
   181  go_library(
   182      name = "go_default_library",
   183      srcs = select({
   184          "@io_bazel_rules_go//go/platform:linux": [
   185              # foo comment
   186              "foo.go",  # side comment
   187              # bar comment
   188              "bar.go",
   189          ],
   190          "//conditions:default": [],
   191      }),
   192      importpath = "example.com/foo",
   193  )
   194  `,
   195  		},
   196  		{
   197  			path: "foo.go",
   198  			content: `
   199  // +build linux
   200  
   201  package foo
   202  
   203  import (
   204      _ "example.com/foo/outer"
   205      _ "example.com/foo/outer/inner"
   206      _ "github.com/jr_hacker/tools"
   207  )
   208  `,
   209  		},
   210  		{
   211  			path: "bar.go",
   212  			content: `// +build linux
   213  
   214  package foo
   215  `,
   216  		},
   217  		{path: "outer/outer.go", content: "package outer"},
   218  		{path: "outer/inner/inner.go", content: "package inner"},
   219  	})
   220  	want := `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   221  
   222  go_library(
   223      name = "go_default_library",
   224      srcs = [
   225          # bar comment
   226          "bar.go",
   227          # foo comment
   228          "foo.go",  # side comment
   229      ],
   230      importpath = "example.com/foo",
   231      visibility = ["//visibility:public"],
   232      deps = select({
   233          "@io_bazel_rules_go//go/platform:linux": [
   234              "//outer:go_default_library",
   235              "//outer/inner:go_default_library",
   236              "@com_github_jr_hacker_tools//:go_default_library",
   237          ],
   238          "//conditions:default": [],
   239      }),
   240  )
   241  `
   242  	if err != nil {
   243  		t.Fatal(err)
   244  	}
   245  
   246  	if err := runGazelle(dir, []string{"-go_prefix", "example.com/foo"}); err != nil {
   247  		t.Fatal(err)
   248  	}
   249  	if got, err := ioutil.ReadFile(filepath.Join(dir, "BUILD")); err != nil {
   250  		t.Fatal(err)
   251  	} else if string(got) != want {
   252  		t.Fatalf("got %s ; want %s", string(got), want)
   253  	}
   254  }
   255  
   256  func TestFixAndUpdateChanges(t *testing.T) {
   257  	files := []fileSpec{
   258  		{path: "WORKSPACE"},
   259  		{
   260  			path: "BUILD",
   261  			content: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix")
   262  load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_test")
   263  
   264  go_prefix("example.com/foo")
   265  
   266  go_library(
   267      name = "go_default_library",
   268      srcs = [
   269          "extra.go",
   270          "pure.go",
   271      ],
   272      library = ":cgo_default_library",
   273      visibility = ["//visibility:default"],
   274  )
   275  
   276  cgo_library(
   277      name = "cgo_default_library",
   278      srcs = ["cgo.go"],
   279  )
   280  `,
   281  		},
   282  		{
   283  			path:    "pure.go",
   284  			content: "package foo",
   285  		},
   286  		{
   287  			path: "cgo.go",
   288  			content: `package foo
   289  
   290  import "C"
   291  `,
   292  		},
   293  	}
   294  
   295  	cases := []struct {
   296  		cmd, want string
   297  	}{
   298  		{
   299  			cmd: "update",
   300  			want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library", "go_prefix")
   301  
   302  go_prefix("example.com/foo")
   303  
   304  go_library(
   305      name = "go_default_library",
   306      srcs = [
   307          "cgo.go",
   308          "pure.go",
   309      ],
   310      cgo = True,
   311      importpath = "example.com/foo",
   312      visibility = ["//visibility:default"],
   313  )
   314  
   315  cgo_library(
   316      name = "cgo_default_library",
   317      srcs = ["cgo.go"],
   318  )
   319  `,
   320  		}, {
   321  			cmd: "fix",
   322  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix")
   323  
   324  go_prefix("example.com/foo")
   325  
   326  go_library(
   327      name = "go_default_library",
   328      srcs = [
   329          "cgo.go",
   330          "pure.go",
   331      ],
   332      cgo = True,
   333      importpath = "example.com/foo",
   334      visibility = ["//visibility:default"],
   335  )
   336  `,
   337  		},
   338  	}
   339  
   340  	for _, c := range cases {
   341  		t.Run(c.cmd, func(t *testing.T) {
   342  			dir, err := createFiles(files)
   343  			if err != nil {
   344  				t.Fatal(err)
   345  			}
   346  
   347  			if err := runGazelle(dir, []string{c.cmd}); err != nil {
   348  				t.Fatal(err)
   349  			}
   350  			if got, err := ioutil.ReadFile(filepath.Join(dir, "BUILD")); err != nil {
   351  				t.Fatal(err)
   352  			} else if string(got) != c.want {
   353  				t.Fatalf("got %s ; want %s", string(got), c.want)
   354  			}
   355  		})
   356  	}
   357  }
   358  
   359  func TestFixUnlinkedCgoLibrary(t *testing.T) {
   360  	files := []fileSpec{
   361  		{path: "WORKSPACE"},
   362  		{
   363  			path: "BUILD",
   364  			content: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library")
   365  
   366  cgo_library(
   367      name = "cgo_default_library",
   368      srcs = ["cgo.go"],
   369  )
   370  
   371  go_library(
   372      name = "go_default_library",
   373      srcs = ["pure.go"],
   374      importpath = "example.com/foo",
   375      visibility = ["//visibility:public"],
   376  )
   377  `,
   378  		}, {
   379  			path:    "pure.go",
   380  			content: "package foo",
   381  		},
   382  	}
   383  
   384  	dir, err := createFiles(files)
   385  	if err != nil {
   386  		t.Fatal(err)
   387  	}
   388  
   389  	want := `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   390  
   391  go_library(
   392      name = "go_default_library",
   393      srcs = ["pure.go"],
   394      importpath = "example.com/foo",
   395      visibility = ["//visibility:public"],
   396  )
   397  `
   398  	if err := runGazelle(dir, []string{"fix", "-go_prefix", "example.com/foo"}); err != nil {
   399  		t.Fatal(err)
   400  	}
   401  	if got, err := ioutil.ReadFile(filepath.Join(dir, "BUILD")); err != nil {
   402  		t.Fatal(err)
   403  	} else if string(got) != want {
   404  		t.Fatalf("got %s ; want %s", string(got), want)
   405  	}
   406  }
   407  
   408  // TestMultipleDirectories checks that all directories in a repository are
   409  // indexed but only directories listed on the command line are updated.
   410  func TestMultipleDirectories(t *testing.T) {
   411  	files := []fileSpec{
   412  		{path: "WORKSPACE"},
   413  		{
   414  			path: "a/BUILD.bazel",
   415  			content: `# This file shouldn't be modified.
   416  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   417  
   418  go_library(
   419      name = "go_default_library",
   420      srcs = ["a.go"],
   421      importpath = "example.com/foo/x",
   422  )
   423  `,
   424  		}, {
   425  			path:    "a/a.go",
   426  			content: "package a",
   427  		}, {
   428  			path: "b/b.go",
   429  			content: `
   430  package b
   431  
   432  import _ "example.com/foo/x"
   433  `,
   434  		},
   435  	}
   436  	dir, err := createFiles(files)
   437  	if err != nil {
   438  		t.Fatal(err)
   439  	}
   440  	defer os.RemoveAll(dir)
   441  
   442  	args := []string{"-go_prefix", "example.com/foo", "b"}
   443  	if err := runGazelle(dir, args); err != nil {
   444  		t.Fatal(err)
   445  	}
   446  
   447  	checkFiles(t, dir, []fileSpec{
   448  		files[1], // should not change
   449  		{
   450  			path: "b/BUILD.bazel",
   451  			content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   452  
   453  go_library(
   454      name = "go_default_library",
   455      srcs = ["b.go"],
   456      importpath = "example.com/foo/b",
   457      visibility = ["//visibility:public"],
   458      deps = ["//a:go_default_library"],
   459  )
   460  `,
   461  		},
   462  	})
   463  }
   464  
   465  func TestErrorOutsideWorkspace(t *testing.T) {
   466  	files := []fileSpec{
   467  		{path: "a/"},
   468  		{path: "b/"},
   469  	}
   470  	dir, err := createFiles(files)
   471  	if err != nil {
   472  		t.Fatal(err)
   473  	}
   474  	defer os.RemoveAll(dir)
   475  	skipIfWorkspaceVisible(t, dir)
   476  
   477  	cases := []struct {
   478  		name, dir, want string
   479  		args            []string
   480  	}{
   481  		{
   482  			name: "outside workspace",
   483  			dir:  dir,
   484  			args: nil,
   485  			want: "WORKSPACE cannot be found",
   486  		}, {
   487  			name: "outside repo_root",
   488  			dir:  filepath.Join(dir, "a"),
   489  			args: []string{"-repo_root", filepath.Join(dir, "b")},
   490  			want: "not a subdirectory of repo root",
   491  		},
   492  	}
   493  	for _, c := range cases {
   494  		t.Run(c.name, func(t *testing.T) {
   495  			if err := runGazelle(c.dir, c.args); err == nil {
   496  				t.Fatalf("got success; want %q", c.want)
   497  			} else if !strings.Contains(err.Error(), c.want) {
   498  				t.Fatalf("got %q; want %q", err, c.want)
   499  			}
   500  		})
   501  	}
   502  }
   503  
   504  func TestBuildFileNameIgnoresBuild(t *testing.T) {
   505  	files := []fileSpec{
   506  		{path: "WORKSPACE"},
   507  		{path: "BUILD/"},
   508  		{
   509  			path:    "a/BUILD",
   510  			content: "!!! parse error",
   511  		}, {
   512  			path:    "a.go",
   513  			content: "package a",
   514  		},
   515  	}
   516  	dir, err := createFiles(files)
   517  	if err != nil {
   518  		t.Fatal(err)
   519  	}
   520  	defer os.Remove(dir)
   521  
   522  	args := []string{"-go_prefix", "example.com/foo", "-build_file_name", "BUILD.bazel"}
   523  	if err := runGazelle(dir, args); err != nil {
   524  		t.Fatal(err)
   525  	}
   526  	if _, err := os.Stat(filepath.Join(dir, "BUILD.bazel")); err != nil {
   527  		t.Errorf("BUILD.bazel not created: %v", err)
   528  	}
   529  }
   530  
   531  func TestExternalVendor(t *testing.T) {
   532  	files := []fileSpec{
   533  		{
   534  			path:    "WORKSPACE",
   535  			content: `workspace(name = "banana")`,
   536  		}, {
   537  			path: "a.go",
   538  			content: `package foo
   539  
   540  import _ "golang.org/x/bar"
   541  `,
   542  		}, {
   543  			path: "vendor/golang.org/x/bar/bar.go",
   544  			content: `package bar
   545  
   546  import _ "golang.org/x/baz"
   547  `,
   548  		}, {
   549  			path:    "vendor/golang.org/x/baz/baz.go",
   550  			content: "package baz",
   551  		},
   552  	}
   553  	dir, err := createFiles(files)
   554  	if err != nil {
   555  		t.Fatal(err)
   556  	}
   557  	defer os.RemoveAll(dir)
   558  
   559  	args := []string{"-go_prefix", "example.com/foo", "-external", "vendored"}
   560  	if err := runGazelle(dir, args); err != nil {
   561  		t.Fatal(err)
   562  	}
   563  
   564  	checkFiles(t, dir, []fileSpec{
   565  		{
   566  			path: config.DefaultValidBuildFileNames[0],
   567  			content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   568  
   569  go_library(
   570      name = "go_default_library",
   571      srcs = ["a.go"],
   572      importpath = "example.com/foo",
   573      visibility = ["//visibility:public"],
   574      deps = ["//vendor/golang.org/x/bar:go_default_library"],
   575  )
   576  `,
   577  		}, {
   578  			path: "vendor/golang.org/x/bar/" + config.DefaultValidBuildFileNames[0],
   579  			content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   580  
   581  go_library(
   582      name = "go_default_library",
   583      srcs = ["bar.go"],
   584      importmap = "example.com/foo/vendor/golang.org/x/bar",
   585      importpath = "golang.org/x/bar",
   586      visibility = ["//visibility:public"],
   587      deps = ["//vendor/golang.org/x/baz:go_default_library"],
   588  )
   589  `,
   590  		},
   591  	})
   592  }
   593  
   594  func TestMigrateProtoRules(t *testing.T) {
   595  	files := []fileSpec{
   596  		{path: "WORKSPACE"},
   597  		{
   598  			path: config.DefaultValidBuildFileNames[0],
   599  			content: `
   600  load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
   601  
   602  filegroup(
   603      name = "go_default_library_protos",
   604      srcs = ["foo.proto"],
   605      visibility = ["//visibility:public"],
   606  )
   607  
   608  go_proto_library(
   609      name = "go_default_library",
   610      srcs = [":go_default_library_protos"],
   611  )
   612  `,
   613  		}, {
   614  			path: "foo.proto",
   615  			content: `syntax = "proto3";
   616  
   617  option go_package = "example.com/repo";
   618  `,
   619  		}, {
   620  			path:    "foo.pb.go",
   621  			content: `package repo`,
   622  		},
   623  	}
   624  
   625  	for _, tc := range []struct {
   626  		args []string
   627  		want string
   628  	}{
   629  		{
   630  			args: []string{"update", "-go_prefix", "example.com/repo"},
   631  			want: `
   632  load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
   633  
   634  filegroup(
   635      name = "go_default_library_protos",
   636      srcs = ["foo.proto"],
   637      visibility = ["//visibility:public"],
   638  )
   639  
   640  go_proto_library(
   641      name = "go_default_library",
   642      srcs = [":go_default_library_protos"],
   643  )
   644  `,
   645  		}, {
   646  			args: []string{"fix", "-go_prefix", "example.com/repo"},
   647  			want: `
   648  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   649  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   650  
   651  proto_library(
   652      name = "repo_proto",
   653      srcs = ["foo.proto"],
   654      visibility = ["//visibility:public"],
   655  )
   656  
   657  go_proto_library(
   658      name = "repo_go_proto",
   659      importpath = "example.com/repo",
   660      proto = ":repo_proto",
   661      visibility = ["//visibility:public"],
   662  )
   663  
   664  go_library(
   665      name = "go_default_library",
   666      embed = [":repo_go_proto"],
   667      importpath = "example.com/repo",
   668      visibility = ["//visibility:public"],
   669  )
   670  `,
   671  		},
   672  	} {
   673  		t.Run(tc.args[0], func(t *testing.T) {
   674  			dir, err := createFiles(files)
   675  			if err != nil {
   676  				t.Fatal(err)
   677  			}
   678  			defer os.RemoveAll(dir)
   679  
   680  			if err := runGazelle(dir, tc.args); err != nil {
   681  				t.Fatal(err)
   682  			}
   683  
   684  			checkFiles(t, dir, []fileSpec{{
   685  				path:    config.DefaultValidBuildFileNames[0],
   686  				content: tc.want,
   687  			}})
   688  		})
   689  	}
   690  }
   691  
   692  func TestRemoveProtoDeletesRules(t *testing.T) {
   693  	files := []fileSpec{
   694  		{path: "WORKSPACE"},
   695  		{
   696  			path: config.DefaultValidBuildFileNames[0],
   697  			content: `
   698  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   699  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   700  
   701  filegroup(
   702      name = "go_default_library_protos",
   703      srcs = ["foo.proto"],
   704      visibility = ["//visibility:public"],
   705  )
   706  
   707  proto_library(
   708      name = "repo_proto",
   709      srcs = ["foo.proto"],
   710      visibility = ["//visibility:public"],
   711  )
   712  
   713  go_proto_library(
   714      name = "repo_go_proto",
   715      importpath = "example.com/repo",
   716      proto = ":repo_proto",
   717      visibility = ["//visibility:public"],
   718  )
   719  
   720  go_library(
   721      name = "go_default_library",
   722      srcs = ["extra.go"],
   723      embed = [":repo_go_proto"],
   724      importpath = "example.com/repo",
   725      visibility = ["//visibility:public"],
   726  )
   727  `,
   728  		}, {
   729  			path:    "extra.go",
   730  			content: `package repo`,
   731  		},
   732  	}
   733  	dir, err := createFiles(files)
   734  	if err != nil {
   735  		t.Fatal(err)
   736  	}
   737  	defer os.RemoveAll(dir)
   738  
   739  	args := []string{"fix", "-go_prefix", "example.com/repo"}
   740  	if err := runGazelle(dir, args); err != nil {
   741  		t.Fatal(err)
   742  	}
   743  
   744  	checkFiles(t, dir, []fileSpec{{
   745  		path: config.DefaultValidBuildFileNames[0],
   746  		content: `
   747  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   748  
   749  go_library(
   750      name = "go_default_library",
   751      srcs = ["extra.go"],
   752      importpath = "example.com/repo",
   753      visibility = ["//visibility:public"],
   754  )
   755  `,
   756  	}})
   757  }
   758  
   759  func TestAddServiceConvertsToGrpc(t *testing.T) {
   760  	files := []fileSpec{
   761  		{path: "WORKSPACE"},
   762  		{
   763  			path: config.DefaultValidBuildFileNames[0],
   764  			content: `
   765  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   766  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   767  
   768  proto_library(
   769      name = "repo_proto",
   770      srcs = ["foo.proto"],
   771      visibility = ["//visibility:public"],
   772  )
   773  
   774  go_proto_library(
   775      name = "repo_go_proto",
   776      importpath = "example.com/repo",
   777      proto = ":repo_proto",
   778      visibility = ["//visibility:public"],
   779  )
   780  
   781  go_library(
   782      name = "go_default_library",
   783      embed = [":repo_go_proto"],
   784      importpath = "example.com/repo",
   785      visibility = ["//visibility:public"],
   786  )
   787  `,
   788  		}, {
   789  			path: "foo.proto",
   790  			content: `syntax = "proto3";
   791  
   792  option go_package = "example.com/repo";
   793  
   794  service {}
   795  `,
   796  		},
   797  	}
   798  
   799  	dir, err := createFiles(files)
   800  	if err != nil {
   801  		t.Fatal(err)
   802  	}
   803  	defer os.RemoveAll(dir)
   804  
   805  	args := []string{"-go_prefix", "example.com/repo"}
   806  	if err := runGazelle(dir, args); err != nil {
   807  		t.Fatal(err)
   808  	}
   809  
   810  	checkFiles(t, dir, []fileSpec{{
   811  		path: config.DefaultValidBuildFileNames[0],
   812  		content: `
   813  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   814  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   815  
   816  proto_library(
   817      name = "repo_proto",
   818      srcs = ["foo.proto"],
   819      visibility = ["//visibility:public"],
   820  )
   821  
   822  go_proto_library(
   823      name = "repo_go_proto",
   824      compilers = ["@io_bazel_rules_go//proto:go_grpc"],
   825      importpath = "example.com/repo",
   826      proto = ":repo_proto",
   827      visibility = ["//visibility:public"],
   828  )
   829  
   830  go_library(
   831      name = "go_default_library",
   832      embed = [":repo_go_proto"],
   833      importpath = "example.com/repo",
   834      visibility = ["//visibility:public"],
   835  )
   836  `,
   837  	}})
   838  }
   839  
   840  func TestEmptyGoPrefix(t *testing.T) {
   841  	files := []fileSpec{
   842  		{path: "WORKSPACE"},
   843  		{
   844  			path:    "foo/foo.go",
   845  			content: "package foo",
   846  		}, {
   847  			path: "bar/bar.go",
   848  			content: `
   849  package bar
   850  
   851  import (
   852  	_ "fmt"
   853  	_ "foo"
   854  )
   855  `,
   856  		},
   857  	}
   858  
   859  	dir, err := createFiles(files)
   860  	if err != nil {
   861  		t.Fatal(err)
   862  	}
   863  	defer os.RemoveAll(dir)
   864  
   865  	args := []string{"-go_prefix", ""}
   866  	if err := runGazelle(dir, args); err != nil {
   867  		t.Fatal(err)
   868  	}
   869  
   870  	checkFiles(t, dir, []fileSpec{{
   871  		path: filepath.Join("bar", config.DefaultValidBuildFileNames[0]),
   872  		content: `
   873  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   874  
   875  go_library(
   876      name = "go_default_library",
   877      srcs = ["bar.go"],
   878      importpath = "bar",
   879      visibility = ["//visibility:public"],
   880      deps = ["//foo:go_default_library"],
   881  )
   882  `,
   883  	}})
   884  }
   885  
   886  // TestResolveKeptImportpath checks that Gazelle can resolve dependencies
   887  // against a library with a '# keep' comment on its importpath attribute
   888  // when the importpath doesn't match what Gazelle would infer.
   889  func TestResolveKeptImportpath(t *testing.T) {
   890  	files := []fileSpec{
   891  		{path: "WORKSPACE"},
   892  		{
   893  			path: "foo/foo.go",
   894  			content: `
   895  package foo
   896  
   897  import _ "example.com/alt/baz"
   898  `,
   899  		}, {
   900  			path: "bar/BUILD.bazel",
   901  			content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   902  
   903  go_library(
   904      name = "go_default_library",
   905      srcs = ["bar.go"],
   906      importpath = "example.com/alt/baz",  # keep
   907      visibility = ["//visibility:public"],
   908  )
   909  `,
   910  		}, {
   911  			path:    "bar/bar.go",
   912  			content: "package bar",
   913  		},
   914  	}
   915  
   916  	dir, err := createFiles(files)
   917  	if err != nil {
   918  		t.Fatal(err)
   919  	}
   920  	defer os.RemoveAll(dir)
   921  
   922  	args := []string{"-go_prefix", "example.com/repo"}
   923  	if err := runGazelle(dir, args); err != nil {
   924  		t.Fatal(err)
   925  	}
   926  
   927  	checkFiles(t, dir, []fileSpec{
   928  		{
   929  			path: "foo/BUILD.bazel",
   930  			content: `
   931  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   932  
   933  go_library(
   934      name = "go_default_library",
   935      srcs = ["foo.go"],
   936      importpath = "example.com/repo/foo",
   937      visibility = ["//visibility:public"],
   938      deps = ["//bar:go_default_library"],
   939  )
   940  `,
   941  		}, {
   942  			path: "bar/BUILD.bazel",
   943  			content: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   944  
   945  go_library(
   946      name = "go_default_library",
   947      srcs = ["bar.go"],
   948      importpath = "example.com/alt/baz",  # keep
   949      visibility = ["//visibility:public"],
   950  )
   951  `,
   952  		},
   953  	})
   954  }
   955  
   956  // TestResolveVendorSubdirectory checks that Gazelle can resolve libraries
   957  // in a vendor directory which is not at the repository root.
   958  func TestResolveVendorSubdirectory(t *testing.T) {
   959  	files := []fileSpec{
   960  		{path: "WORKSPACE"},
   961  		{
   962  			path:    "sub/vendor/example.com/foo/foo.go",
   963  			content: "package foo",
   964  		}, {
   965  			path: "sub/bar/bar.go",
   966  			content: `
   967  package bar
   968  
   969  import _ "example.com/foo"
   970  `,
   971  		},
   972  	}
   973  	dir, err := createFiles(files)
   974  	if err != nil {
   975  		t.Fatal(err)
   976  	}
   977  	defer os.RemoveAll(dir)
   978  
   979  	args := []string{"-go_prefix", "example.com/repo"}
   980  	if err := runGazelle(dir, args); err != nil {
   981  		t.Fatal(err)
   982  	}
   983  
   984  	checkFiles(t, dir, []fileSpec{
   985  		{
   986  			path: "sub/vendor/example.com/foo/BUILD.bazel",
   987  			content: `
   988  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   989  
   990  go_library(
   991      name = "go_default_library",
   992      srcs = ["foo.go"],
   993      importmap = "example.com/repo/sub/vendor/example.com/foo",
   994      importpath = "example.com/foo",
   995      visibility = ["//visibility:public"],
   996  )
   997  `,
   998  		}, {
   999  			path: "sub/bar/BUILD.bazel",
  1000  			content: `
  1001  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1002  
  1003  go_library(
  1004      name = "go_default_library",
  1005      srcs = ["bar.go"],
  1006      importpath = "example.com/repo/sub/bar",
  1007      visibility = ["//visibility:public"],
  1008      deps = ["//sub/vendor/example.com/foo:go_default_library"],
  1009  )
  1010  `,
  1011  		},
  1012  	})
  1013  }
  1014  
  1015  // TestDeleteProtoWithDeps checks that Gazelle will delete proto rules with
  1016  // dependencies after the proto sources are removed.
  1017  func TestDeleteProtoWithDeps(t *testing.T) {
  1018  	files := []fileSpec{
  1019  		{path: "WORKSPACE"},
  1020  		{
  1021  			path: "foo/BUILD.bazel",
  1022  			content: `
  1023  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
  1024  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1025  
  1026  go_library(
  1027      name = "go_default_library",
  1028      srcs = ["extra.go"],
  1029      embed = [":scratch_go_proto"],
  1030      importpath = "example.com/repo/foo",
  1031      visibility = ["//visibility:public"],
  1032  )
  1033  
  1034  proto_library(
  1035      name = "foo_proto",
  1036      srcs = ["foo.proto"],
  1037      visibility = ["//visibility:public"],
  1038      deps = ["//foo/bar:bar_proto"],
  1039  )
  1040  
  1041  go_proto_library(
  1042      name = "foo_go_proto",
  1043      importpath = "example.com/repo/foo",
  1044      proto = ":foo_proto",
  1045      visibility = ["//visibility:public"],
  1046      deps = ["//foo/bar:go_default_library"],
  1047  )
  1048  `,
  1049  		}, {
  1050  			path:    "foo/extra.go",
  1051  			content: "package foo",
  1052  		}, {
  1053  			path: "foo/bar/bar.proto",
  1054  			content: `
  1055  syntax = "proto3";
  1056  
  1057  option go_package = "example.com/repo/foo/bar";
  1058  
  1059  message Bar {};
  1060  `,
  1061  		},
  1062  	}
  1063  	dir, err := createFiles(files)
  1064  	if err != nil {
  1065  		t.Fatal(err)
  1066  	}
  1067  	defer os.RemoveAll(dir)
  1068  
  1069  	args := []string{"-go_prefix", "example.com/repo"}
  1070  	if err := runGazelle(dir, args); err != nil {
  1071  		t.Fatal(err)
  1072  	}
  1073  
  1074  	checkFiles(t, dir, []fileSpec{
  1075  		{
  1076  			path: "foo/BUILD.bazel",
  1077  			content: `
  1078  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1079  
  1080  go_library(
  1081      name = "go_default_library",
  1082      srcs = ["extra.go"],
  1083      importpath = "example.com/repo/foo",
  1084      visibility = ["//visibility:public"],
  1085  )
  1086  `,
  1087  		},
  1088  	})
  1089  }
  1090  
  1091  func TestCustomRepoNames(t *testing.T) {
  1092  	files := []fileSpec{
  1093  		{
  1094  			path: "WORKSPACE",
  1095  			content: `
  1096  go_repository(
  1097      name = "custom_repo",
  1098      importpath = "example.com/bar",
  1099      commit = "123456",
  1100  )
  1101  `,
  1102  		}, {
  1103  			path: "foo.go",
  1104  			content: `
  1105  package foo
  1106  
  1107  import _ "example.com/bar"
  1108  `,
  1109  		},
  1110  	}
  1111  	dir, err := createFiles(files)
  1112  	if err != nil {
  1113  		t.Fatal(err)
  1114  	}
  1115  	defer os.RemoveAll(dir)
  1116  
  1117  	args := []string{"-go_prefix", "example.com/foo"}
  1118  	if err := runGazelle(dir, args); err != nil {
  1119  		t.Fatal(err)
  1120  	}
  1121  
  1122  	checkFiles(t, dir, []fileSpec{
  1123  		{
  1124  			path: "BUILD.bazel",
  1125  			content: `
  1126  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1127  
  1128  go_library(
  1129      name = "go_default_library",
  1130      srcs = ["foo.go"],
  1131      importpath = "example.com/foo",
  1132      visibility = ["//visibility:public"],
  1133      deps = ["@custom_repo//:go_default_library"],
  1134  )
  1135  `,
  1136  		},
  1137  	})
  1138  }
  1139  
  1140  func TestImportReposFromDep(t *testing.T) {
  1141  	files := []fileSpec{
  1142  		{
  1143  			path: "WORKSPACE",
  1144  			content: `
  1145  http_archive(
  1146      name = "io_bazel_rules_go",
  1147      url = "https://github.com/bazelbuild/rules_go/releases/download/0.10.1/rules_go-0.10.1.tar.gz",
  1148      sha256 = "4b14d8dd31c6dbaf3ff871adcd03f28c3274e42abc855cb8fb4d01233c0154dc",
  1149  )
  1150  http_archive(
  1151      name = "bazel_gazelle",
  1152      url = "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.10.0/bazel-gazelle-0.10.0.tar.gz",
  1153      sha256 = "6228d9618ab9536892aa69082c063207c91e777e51bd3c5544c9c060cafe1bd8",
  1154  )
  1155  load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains", "go_repository")
  1156  go_rules_dependencies()
  1157  go_register_toolchains()
  1158  
  1159  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
  1160  gazelle_dependencies()
  1161  
  1162  go_repository(
  1163      name = "org_golang_x_net",
  1164      importpath = "golang.org/x/net",
  1165      tag = "1.2",
  1166  )
  1167  
  1168  # keep
  1169  go_repository(
  1170      name = "org_golang_x_sys",
  1171      importpath = "golang.org/x/sys",
  1172      remote = "https://github.com/golang/sys",
  1173  )
  1174  
  1175  http_archive(
  1176      name = "com_github_go_yaml_yaml",
  1177      urls = ["https://example.com/yaml.tar.gz"],
  1178      sha256 = "1234",
  1179  )
  1180  `,
  1181  		}, {
  1182  			path: "Gopkg.lock",
  1183  			content: `# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
  1184  
  1185  
  1186  [[projects]]
  1187    name = "github.com/pkg/errors"
  1188    packages = ["."]
  1189    revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
  1190    version = "v0.8.0"
  1191  
  1192  [[projects]]
  1193    branch = "master"
  1194    name = "golang.org/x/net"
  1195    packages = ["context"]
  1196    revision = "66aacef3dd8a676686c7ae3716979581e8b03c47"
  1197  
  1198  [[projects]]
  1199    branch = "master"
  1200    name = "golang.org/x/sys"
  1201    packages = ["unix"]
  1202    revision = "bb24a47a89eac6c1227fbcb2ae37a8b9ed323366"
  1203  
  1204  [[projects]]
  1205    branch = "v2"
  1206    name = "github.com/go-yaml/yaml"
  1207    packages = ["."]
  1208    revision = "cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b"
  1209  
  1210  [solve-meta]
  1211    analyzer-name = "dep"
  1212    analyzer-version = 1
  1213    inputs-digest = "05c1cd69be2c917c0cc4b32942830c2acfa044d8200fdc94716aae48a8083702"
  1214    solver-name = "gps-cdcl"
  1215    solver-version = 1
  1216  `,
  1217  		},
  1218  	}
  1219  	dir, err := createFiles(files)
  1220  	if err != nil {
  1221  		t.Fatal(err)
  1222  	}
  1223  	defer os.RemoveAll(dir)
  1224  
  1225  	args := []string{"update-repos", "-from_file", "Gopkg.lock"}
  1226  	if err := runGazelle(dir, args); err != nil {
  1227  		t.Fatal(err)
  1228  	}
  1229  
  1230  	checkFiles(t, dir, []fileSpec{
  1231  		{
  1232  			path: "WORKSPACE",
  1233  			content: `
  1234  http_archive(
  1235      name = "io_bazel_rules_go",
  1236      url = "https://github.com/bazelbuild/rules_go/releases/download/0.10.1/rules_go-0.10.1.tar.gz",
  1237      sha256 = "4b14d8dd31c6dbaf3ff871adcd03f28c3274e42abc855cb8fb4d01233c0154dc",
  1238  )
  1239  
  1240  http_archive(
  1241      name = "bazel_gazelle",
  1242      url = "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.10.0/bazel-gazelle-0.10.0.tar.gz",
  1243      sha256 = "6228d9618ab9536892aa69082c063207c91e777e51bd3c5544c9c060cafe1bd8",
  1244  )
  1245  
  1246  load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_dependencies")
  1247  
  1248  go_rules_dependencies()
  1249  
  1250  go_register_toolchains()
  1251  
  1252  load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
  1253  
  1254  gazelle_dependencies()
  1255  
  1256  go_repository(
  1257      name = "org_golang_x_net",
  1258      commit = "66aacef3dd8a676686c7ae3716979581e8b03c47",
  1259      importpath = "golang.org/x/net",
  1260  )
  1261  
  1262  # keep
  1263  go_repository(
  1264      name = "org_golang_x_sys",
  1265      importpath = "golang.org/x/sys",
  1266      remote = "https://github.com/golang/sys",
  1267  )
  1268  
  1269  http_archive(
  1270      name = "com_github_go_yaml_yaml",
  1271      urls = ["https://example.com/yaml.tar.gz"],
  1272      sha256 = "1234",
  1273  )
  1274  
  1275  go_repository(
  1276      name = "com_github_pkg_errors",
  1277      commit = "645ef00459ed84a119197bfb8d8205042c6df63d",
  1278      importpath = "github.com/pkg/errors",
  1279  )
  1280  `,
  1281  		}})
  1282  }
  1283  
  1284  func TestDeleteRulesInEmptyDir(t *testing.T) {
  1285  	files := []fileSpec{
  1286  		{path: "WORKSPACE"},
  1287  		{
  1288  			path: "BUILD.bazel",
  1289  			content: `
  1290  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_binary")
  1291  
  1292  go_library(
  1293      name = "go_default_library",
  1294      srcs = [
  1295          "bar.go",
  1296          "foo.go",
  1297      ],
  1298      importpath = "example.com/repo",
  1299      visibility = ["//visibility:private"],
  1300  )
  1301  
  1302  go_binary(
  1303      name = "cmd",
  1304      embed = [":go_default_library"],
  1305      visibility = ["//visibility:public"],
  1306  )
  1307  `,
  1308  		},
  1309  	}
  1310  	dir, err := createFiles(files)
  1311  	if err != nil {
  1312  		t.Fatal(err)
  1313  	}
  1314  	defer os.RemoveAll(dir)
  1315  
  1316  	args := []string{"-go_prefix=example.com/repo"}
  1317  	if err := runGazelle(dir, args); err != nil {
  1318  		t.Fatal(err)
  1319  	}
  1320  
  1321  	checkFiles(t, dir, []fileSpec{
  1322  		{
  1323  			path:    "BUILD.bazel",
  1324  			content: "",
  1325  		},
  1326  	})
  1327  }
  1328  
  1329  func TestFixWorkspaceWithoutGazelle(t *testing.T) {
  1330  	files := []fileSpec{
  1331  		{
  1332  			path: "WORKSPACE",
  1333  			content: `
  1334  load("@io_bazel_rules_go//go:def.bzl", "go_repository")
  1335  
  1336  go_repository(
  1337      name = "com_example_repo",
  1338      importpath = "example.com/repo",
  1339      tag = "1.2.3",
  1340  )
  1341  `,
  1342  		},
  1343  	}
  1344  	dir, err := createFiles(files)
  1345  	if err != nil {
  1346  		t.Fatal(err)
  1347  	}
  1348  	defer os.RemoveAll(dir)
  1349  
  1350  	if err := runGazelle(dir, []string{"fix", "-go_prefix="}); err == nil {
  1351  		t.Error("got success; want error")
  1352  	} else if want := "bazel_gazelle is not declared"; !strings.Contains(err.Error(), want) {
  1353  		t.Errorf("got error %v; want error containing %q", err, want)
  1354  	}
  1355  }
  1356  
  1357  // TestFixGazelle checks that loads of the gazelle macro from the old location
  1358  // in rules_go are replaced with the new location in @bazel_gazelle.
  1359  func TestFixGazelle(t *testing.T) {
  1360  	files := []fileSpec{
  1361  		{
  1362  			path: "WORKSPACE",
  1363  		}, {
  1364  			path: "BUILD.bazel",
  1365  			content: `
  1366  load("@io_bazel_rules_go//go:def.bzl", "gazelle", "go_library")
  1367  
  1368  gazelle(name = "gazelle")
  1369  
  1370  # keep
  1371  go_library(name = "go_default_library")
  1372  `,
  1373  		},
  1374  	}
  1375  	dir, err := createFiles(files)
  1376  	if err != nil {
  1377  		t.Fatal(err)
  1378  	}
  1379  	defer os.RemoveAll(dir)
  1380  
  1381  	if err := runGazelle(dir, nil); err != nil {
  1382  		t.Fatal(err)
  1383  	}
  1384  	checkFiles(t, dir, []fileSpec{
  1385  		{
  1386  			path: "BUILD.bazel",
  1387  			content: `
  1388  load("@bazel_gazelle//:def.bzl", "gazelle")
  1389  load("@io_bazel_rules_go//go:def.bzl", "go_library")
  1390  
  1391  gazelle(name = "gazelle")
  1392  
  1393  # keep
  1394  go_library(name = "go_default_library")
  1395  `,
  1396  		},
  1397  	})
  1398  }
  1399  
  1400  // TestKeepDeps checks rules with keep comments on the rule or on the deps
  1401  // attribute will not be modified during dependency resolution. Verifies #212.
  1402  func TestKeepDeps(t *testing.T) {
  1403  	files := []fileSpec{
  1404  		{
  1405  			path: "WORKSPACE",
  1406  		}, {
  1407  			path: "BUILD.bazel",
  1408  			content: `
  1409  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
  1410  
  1411  # gazelle:prefix example.com/repo
  1412  
  1413  # keep
  1414  go_library(
  1415      name = "go_default_library",
  1416      srcs = ["lib.go"],
  1417      importpath = "example.com/repo",
  1418      deps = [":dont_remove"],
  1419  )
  1420  
  1421  go_test(
  1422      name = "go_default_test",
  1423      # keep
  1424      srcs = ["lib_test.go"],
  1425      # keep
  1426      embed = [":go_default_library"],
  1427      # keep
  1428      deps = [":dont_remove"],
  1429  )
  1430  `,
  1431  		},
  1432  	}
  1433  	dir, err := createFiles(files)
  1434  	if err != nil {
  1435  		t.Fatal(err)
  1436  	}
  1437  	defer os.RemoveAll(dir)
  1438  
  1439  	if err := runGazelle(dir, nil); err != nil {
  1440  		t.Fatal(err)
  1441  	}
  1442  
  1443  	checkFiles(t, dir, files)
  1444  }
  1445  
  1446  func TestDontCreateBuildFileInEmptyDir(t *testing.T) {
  1447  	files := []fileSpec{
  1448  		{path: "WORKSPACE"},
  1449  		{path: "sub/"},
  1450  	}
  1451  	dir, err := createFiles(files)
  1452  	if err != nil {
  1453  		t.Fatal(err)
  1454  	}
  1455  	defer os.RemoveAll(dir)
  1456  	if err := runGazelle(dir, nil); err != nil {
  1457  		t.Error(err)
  1458  	}
  1459  	for _, f := range []string{"BUILD.bazel", "sub/BUILD.bazel"} {
  1460  		path := filepath.Join(dir, filepath.FromSlash(f))
  1461  		_, err := os.Stat(path)
  1462  		if err == nil {
  1463  			t.Errorf("%s: build file was created", f)
  1464  		}
  1465  	}
  1466  }
  1467  
  1468  // TODO(jayconrod): more tests
  1469  //   run in fix mode in testdata directories to create new files
  1470  //   run in diff mode in testdata directories to update existing files (no change)