github.phpd.cn/thought-machine/please@v12.2.0+incompatible/src/core/build_target_test.go (about)

     1  // Tests on specific functions in build_target.go
     2  package core
     3  
     4  import (
     5  	"fmt"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestCanSee(t *testing.T) {
    13  	state := NewDefaultBuildState()
    14  	target1 := makeTarget("//src/build/python:lib1", "")
    15  	target2 := makeTarget("//src/build/python:lib2", "PUBLIC")
    16  	target3 := makeTarget("//src/test/python:lib3", "//src/test/...")
    17  	target4 := makeTarget("//src/test/python/moar:lib4", "")
    18  
    19  	// target2 is public so anything can import it
    20  	assert.True(t, target3.CanSee(state, target2), "couldn't see public target")
    21  	assert.True(t, target4.CanSee(state, target2), "couldn't see public target")
    22  
    23  	// target1 is not public, other things can't import it
    24  	assert.False(t, target3.CanSee(state, target1), "could see private target")
    25  	assert.False(t, target4.CanSee(state, target1), "could see private target")
    26  
    27  	// target2 is in the same package as target1 so can implicitly see it
    28  	assert.True(t, target2.CanSee(state, target1), "couldn't see target in the same package")
    29  
    30  	// target3 is only visible to a subtree, things outside it can't see it
    31  	assert.False(t, target1.CanSee(state, target3), "could see target with restricted visibility")
    32  	assert.False(t, target2.CanSee(state, target3), "could see target with restricted visibility")
    33  
    34  	// Targets in that subtree can though.
    35  	assert.True(t, target4.CanSee(state, target3), "couldn't see target within its visibility spec")
    36  
    37  	// Sub-targets can see things visible to their parents.
    38  	target5 := makeTarget("//src/build/python:lib5", "//src/test/python:test5")
    39  	target6 := makeTarget("//src/test/python:_test5#pex", "")
    40  	assert.True(t, target6.CanSee(state, target5))
    41  	assert.False(t, target5.CanSee(state, target6))
    42  }
    43  
    44  func TestCanSeeExperimental(t *testing.T) {
    45  	config := DefaultConfiguration()
    46  	config.Parse.ExperimentalDir = []string{"experimental"}
    47  	state := NewBuildState(1, nil, 1, config)
    48  
    49  	target1 := makeTarget("//src/core:target1", "")
    50  	target2 := makeTarget("//experimental/user:target2", "PUBLIC")
    51  
    52  	// target2 can see target1 since it's in experimental, which suppress normal visibility constraints.
    53  	assert.True(t, target2.CanSee(state, target1))
    54  	// target1 can't see target2 because it's in experimental, even though it's public.
    55  	assert.False(t, target1.CanSee(state, target2))
    56  }
    57  
    58  func TestCheckDependencyVisibility(t *testing.T) {
    59  	target1 := makeTarget("//src/build/python:lib1", "")
    60  	target2 := makeTarget("//src/build/python:lib2", "PUBLIC", target1)
    61  	target3 := makeTarget("//src/test/python:lib3", "//src/test/...", target2)
    62  	target4 := makeTarget("//src/test/python/moar:lib4", "//src/test/...", target3)
    63  	target5 := makeTarget("//third_party/python:mock", "PUBLIC")
    64  	target5.TestOnly = true
    65  	target6 := makeTarget("//src/test/python:test_lib", "", target5)
    66  	target6.TestOnly = true
    67  	target7 := makeTarget("//src/test/python:test1", "", target5, target4)
    68  	target7.IsTest = true
    69  
    70  	state := NewDefaultBuildState()
    71  	state.Graph.AddTarget(target1)
    72  	state.Graph.AddTarget(target2)
    73  	state.Graph.AddTarget(target3)
    74  	state.Graph.AddTarget(target4)
    75  	state.Graph.AddTarget(target5)
    76  	state.Graph.AddTarget(target6)
    77  	state.Graph.AddTarget(target7)
    78  
    79  	// Deps should all be correct at this point
    80  	assert.NoError(t, target1.CheckDependencyVisibility(state))
    81  	assert.NoError(t, target2.CheckDependencyVisibility(state))
    82  	assert.NoError(t, target3.CheckDependencyVisibility(state))
    83  	assert.NoError(t, target4.CheckDependencyVisibility(state))
    84  	assert.NoError(t, target5.CheckDependencyVisibility(state))
    85  	assert.NoError(t, target6.CheckDependencyVisibility(state))
    86  	assert.NoError(t, target7.CheckDependencyVisibility(state))
    87  
    88  	// Now if we add a dep on this mock library, lib2 will fail because it's not a test.
    89  	target2.resolveDependency(target5.Label, target5)
    90  	assert.Error(t, target2.CheckDependencyVisibility(state))
    91  
    92  	// Similarly to above test, if we add a dep on something that can't be seen, we should
    93  	// get errors back from this function.
    94  	target3.resolveDependency(target1.Label, target1)
    95  	assert.Error(t, target3.CheckDependencyVisibility(state))
    96  }
    97  
    98  func TestAddOutput(t *testing.T) {
    99  	target := makeTarget("//src/test/python:lib1", "")
   100  	target.AddOutput("thingy.py")
   101  	target.AddOutput("thingy2.py")
   102  	target.AddOutput("thingy.py")
   103  	if len(target.Outputs()) != 2 {
   104  		t.Errorf("Incorrect output length; should be 2, was %d", len(target.Outputs()))
   105  	}
   106  }
   107  
   108  func TestAddOutputSorting(t *testing.T) {
   109  	target := makeTarget("//src/test/python:lib1", "")
   110  	target.AddOutput("1.py")
   111  	target.AddOutput("2.py")
   112  	target.AddOutput("1.py")
   113  	target.AddOutput("3.py")
   114  	target.AddOutput("1.pyx")
   115  	target.AddOutput("x.pyx")
   116  	expected := []string{
   117  		"1.py",
   118  		"1.pyx",
   119  		"2.py",
   120  		"3.py",
   121  		"x.pyx",
   122  	}
   123  	assert.Equal(t, expected, target.Outputs())
   124  }
   125  
   126  func TestAddSource(t *testing.T) {
   127  	target := makeTarget("//src/test/python:lib1", "")
   128  	target.AddSource(ParseBuildLabel("//src/test/python:lib2", ""))
   129  	target.AddSource(ParseBuildLabel("//src/test/python:lib3", ""))
   130  	target.AddSource(ParseBuildLabel("//src/test/python:lib2", ""))
   131  	assert.Equal(t, 2, len(target.Sources))
   132  	assert.Equal(t, 2, len(target.DeclaredDependencies()))
   133  }
   134  
   135  func TestSetContainerSettings(t *testing.T) {
   136  	target := makeTarget("//src/test/python:lib1", "")
   137  
   138  	target.SetContainerSetting("dockerimage", "tm/special_image:v2")
   139  	assert.Equal(t, "tm/special_image:v2", target.ContainerSettings.DockerImage)
   140  
   141  	target.SetContainerSetting("dockeruser", "")
   142  	assert.Equal(t, "", target.ContainerSettings.DockerUser)
   143  
   144  	target.SetContainerSetting("dockerrunargs", "-it")
   145  	assert.Equal(t, "-it", target.ContainerSettings.DockerRunArgs)
   146  }
   147  
   148  func TestOutputs(t *testing.T) {
   149  	target1 := makeTarget("//src/core:target1", "PUBLIC")
   150  	target1.AddOutput("file1.go")
   151  	target1.AddOutput("file2.go")
   152  	target2 := makeFilegroup("//src/test:target2", "PUBLIC", target1)
   153  	target2.AddSource(target1.Label)
   154  	addFilegroupSource(target2, "file3.go")
   155  	target3 := makeFilegroup("//src/test:target3", "PUBLIC", target2)
   156  	target3.AddSource(target2.Label)
   157  	addFilegroupSource(target3, "file4.go")
   158  
   159  	assert.Equal(t, []string{"file1.go", "file2.go"}, target1.Outputs())
   160  	assert.Equal(t, []string{"file1.go", "file2.go", "file3.go"}, target2.Outputs())
   161  	assert.Equal(t, []string{"file1.go", "file2.go", "file3.go", "file4.go"}, target3.Outputs())
   162  }
   163  
   164  func TestProvideFor(t *testing.T) {
   165  	// target1 is provided directly since they have a simple dependency
   166  	target1 := makeTarget("//src/core:target1", "PUBLIC")
   167  	target2 := makeTarget("//src/core:target2", "PUBLIC", target1)
   168  	assert.Equal(t, []BuildLabel{target1.Label}, target1.ProvideFor(target2))
   169  	// Now have target2 provide target1. target3 will get target1 instead.
   170  	target2.Provides = map[string]BuildLabel{"whatevs": target1.Label}
   171  	target3 := makeTarget("//src/core:target3", "PUBLIC", target2)
   172  	target3.Requires = append(target3.Requires, "whatevs")
   173  	assert.Equal(t, []BuildLabel{target1.Label}, target2.ProvideFor(target3))
   174  	// Now target4 has a data dependency on target2. It has the same requirement as target3 but
   175  	// it gets target2 instead of target1, because that's just how data deps work.
   176  	target4 := makeTarget("//src/core:target4", "PUBLIC", target2)
   177  	target4.Data = append(target4.Data, target2.Label)
   178  	target4.Requires = append(target4.Requires, "whatevs")
   179  	assert.Equal(t, []BuildLabel{target2.Label}, target2.ProvideFor(target4))
   180  }
   181  
   182  func TestAddProvide(t *testing.T) {
   183  	target1 := makeTarget("//src/core:target1", "PUBLIC")
   184  	target2 := makeTarget("//src/core:target2", "PUBLIC", target1)
   185  	target3 := makeTarget("//src/core:target3", "PUBLIC", target2)
   186  	target2.AddDependency(target1.Label)
   187  	target2.AddProvide("go", ParseBuildLabel(":target1", "src/core"))
   188  	target3.Requires = append(target3.Requires, "go")
   189  	assert.Equal(t, []BuildLabel{target1.Label}, target2.ProvideFor(target3))
   190  }
   191  
   192  func TestAddDatum(t *testing.T) {
   193  	target1 := makeTarget("//src/core:target1", "PUBLIC")
   194  	target2 := makeTarget("//src/core:target2", "PUBLIC")
   195  	target1.AddDatum(target2.Label)
   196  	assert.Equal(t, target1.Data, []BuildInput{target2.Label})
   197  	assert.True(t, target1.dependencies[0].data)
   198  	// Now we add it as a dependency too, which unsets the data label
   199  	target1.AddMaybeExportedDependency(target2.Label, false, false)
   200  	assert.False(t, target1.dependencies[0].data)
   201  }
   202  
   203  func TestCheckDuplicateOutputs(t *testing.T) {
   204  	target1 := makeFilegroup("//src/core:target1", "PUBLIC")
   205  	target3 := makeFilegroup("//src/core:target3", "PUBLIC")
   206  	target2 := makeFilegroup("//src/core:target2", "PUBLIC", target1, target3)
   207  	addFilegroupSource(target1, "thingy.txt")
   208  	addFilegroupSource(target3, "thingy.txt")
   209  	assert.NoError(t, target1.CheckDuplicateOutputs())
   210  	target2.AddSource(target1.Label)
   211  	target2.AddSource(target1.Label)
   212  	// Not an error yet because AddOutput deduplicates trivially identical outputs.
   213  	assert.NoError(t, target2.CheckDuplicateOutputs())
   214  	// Will fail now we add the same output to another target.
   215  	target2.AddSource(target3.Label)
   216  	assert.Error(t, target2.CheckDuplicateOutputs())
   217  }
   218  
   219  func TestLabels(t *testing.T) {
   220  	target := makeTarget("//src/core:target1", "PUBLIC")
   221  	assert.False(t, target.HasLabel("py"))
   222  	assert.False(t, target.HasAnyLabel([]string{"py", "go"}))
   223  	target.AddLabel("py")
   224  	assert.True(t, target.HasLabel("py"))
   225  	assert.True(t, target.HasAnyLabel([]string{"py", "go"}))
   226  	target.AddLabel("py")
   227  	target.AddLabel("go")
   228  	assert.Equal(t, 2, len(target.Labels))
   229  	// "test" label is implicit on tests.
   230  	assert.False(t, target.HasLabel("test"))
   231  	target.IsTest = true
   232  	assert.True(t, target.HasLabel("test"))
   233  }
   234  
   235  func TestGetCommandConfig(t *testing.T) {
   236  	target := makeTarget("//src/core:target1", "PUBLIC")
   237  	target.Command = "test1"
   238  	assert.Equal(t, "test1", target.GetCommandConfig(""))
   239  	target.Command = ""
   240  	target.AddCommand("opt", "test3")
   241  	target.AddCommand("dbg", "test4")
   242  	assert.Equal(t, "test3", target.GetCommandConfig("opt"))
   243  	assert.Equal(t, "test4", target.GetCommandConfig("dbg"))
   244  }
   245  
   246  func TestGetCommand(t *testing.T) {
   247  	state := NewDefaultBuildState()
   248  	state.Config.Build.Config = "dbg"
   249  	state.Config.Build.FallbackConfig = "opt"
   250  	target := makeTarget("//src/core:target1", "PUBLIC")
   251  	target.Command = "test1"
   252  	assert.Equal(t, "test1", target.GetCommand(state))
   253  	assert.Panics(t, func() { target.AddCommand("opt", "test2") },
   254  		"Should panic when adding a config command to a target with a command already")
   255  	target.Command = ""
   256  	target.AddCommand("opt", "test3")
   257  	target.AddCommand("dbg", "test4")
   258  	assert.Equal(t, "test4", target.GetCommand(state), "Current config is dbg")
   259  	state.Config.Build.Config = "opt"
   260  	assert.Equal(t, "test3", target.GetCommand(state), "Current config is opt")
   261  	state.Config.Build.Config = "fast"
   262  	assert.Equal(t, "test3", target.GetCommand(state), "Default config is opt, should fall back to that")
   263  }
   264  
   265  func TestGetTestCommand(t *testing.T) {
   266  	state := NewDefaultBuildState()
   267  	state.Config.Build.Config = "dbg"
   268  	state.Config.Build.FallbackConfig = "opt"
   269  	target := makeTarget("//src/core:target1", "PUBLIC")
   270  	target.TestCommand = "test1"
   271  	assert.Equal(t, "test1", target.GetTestCommand(state))
   272  	assert.Panics(t, func() { target.AddTestCommand("opt", "test2") },
   273  		"Should panic when adding a config command to a target with a command already")
   274  	target.TestCommand = ""
   275  	target.AddTestCommand("opt", "test3")
   276  	target.AddTestCommand("dbg", "test4")
   277  	assert.Equal(t, "test4", target.GetTestCommand(state), "Current config is dbg")
   278  	state.Config.Build.Config = "opt"
   279  	assert.Equal(t, "test3", target.GetTestCommand(state), "Current config is opt")
   280  	state.Config.Build.Config = "fast"
   281  	assert.Equal(t, "test3", target.GetTestCommand(state), "Default config is opt, should fall back to that")
   282  }
   283  
   284  func TestHasSource(t *testing.T) {
   285  	target := makeTarget("//src/core:target1", "")
   286  	target.Sources = append(target.Sources, FileLabel{File: "file1.go"})
   287  	target.AddNamedSource("wevs", FileLabel{File: "file2.go"})
   288  	assert.True(t, target.HasSource("file1.go"))
   289  	assert.True(t, target.HasSource("file2.go"))
   290  	assert.False(t, target.HasSource("file3.go"))
   291  }
   292  
   293  func TestToolPath(t *testing.T) {
   294  	target := makeTarget("//src/core:target1", "")
   295  	target.AddOutput("file1.go")
   296  	target.AddOutput("file2.go")
   297  	wd, _ := os.Getwd()
   298  	root := wd + "/plz-out/gen/src/core"
   299  	assert.Equal(t, fmt.Sprintf("%s/file1.go %s/file2.go", root, root), target.toolPath())
   300  }
   301  
   302  func TestDependencies(t *testing.T) {
   303  	target1 := makeTarget("//src/core:target1", "")
   304  	target2 := makeTarget("//src/core:target2", "", target1)
   305  	target3 := makeTarget("//src/core:target3", "", target1, target2)
   306  	assert.Equal(t, []BuildLabel{}, target1.DeclaredDependencies())
   307  	assert.Equal(t, []*BuildTarget{}, target1.Dependencies())
   308  	assert.Equal(t, []BuildLabel{target1.Label}, target2.DeclaredDependencies())
   309  	assert.Equal(t, []*BuildTarget{target1}, target2.Dependencies())
   310  	assert.Equal(t, []BuildLabel{target1.Label, target2.Label}, target3.DeclaredDependencies())
   311  	assert.Equal(t, []*BuildTarget{target1, target2}, target3.Dependencies())
   312  }
   313  
   314  func TestBuildDependencies(t *testing.T) {
   315  	target1 := makeTarget("//src/core:target1", "")
   316  	target2 := makeTarget("//src/core:target2", "", target1)
   317  	target3 := makeTarget("//src/core:target3", "", target2)
   318  	target3.AddDatum(target1.Label)
   319  	assert.Equal(t, []*BuildTarget{}, target1.BuildDependencies())
   320  	assert.Equal(t, []*BuildTarget{target1}, target2.BuildDependencies())
   321  	assert.Equal(t, []*BuildTarget{target2}, target3.BuildDependencies())
   322  }
   323  
   324  func TestDeclaredDependenciesStrict(t *testing.T) {
   325  	target1 := makeTarget("//src/core:target1", "")
   326  	target2 := makeTarget("//src/core:target2", "", target1)
   327  	target3 := makeTarget("//src/core:target3", "", target2)
   328  	target3.AddMaybeExportedDependency(target1.Label, true, false)
   329  	assert.Equal(t, []BuildLabel{}, target1.DeclaredDependenciesStrict())
   330  	assert.Equal(t, []BuildLabel{target1.Label}, target2.DeclaredDependenciesStrict())
   331  	assert.Equal(t, []BuildLabel{target2.Label}, target3.DeclaredDependenciesStrict())
   332  }
   333  
   334  func TestAddDependency(t *testing.T) {
   335  	target1 := makeTarget("//src/core:target1", "")
   336  	target2 := makeTarget("//src/core:target2", "")
   337  	assert.Equal(t, []BuildLabel{}, target2.DeclaredDependencies())
   338  	assert.Equal(t, []BuildLabel{}, target2.ExportedDependencies())
   339  	target2.AddDependency(target1.Label)
   340  	assert.Equal(t, []BuildLabel{target1.Label}, target2.DeclaredDependencies())
   341  	assert.Equal(t, []BuildLabel{}, target2.ExportedDependencies())
   342  	target2.AddMaybeExportedDependency(target1.Label, true, false)
   343  	assert.Equal(t, []BuildLabel{target1.Label}, target2.DeclaredDependencies())
   344  	assert.Equal(t, []BuildLabel{target1.Label}, target2.ExportedDependencies())
   345  	assert.Equal(t, []*BuildTarget{}, target2.Dependencies())
   346  	target2.resolveDependency(target1.Label, target1)
   347  	assert.Equal(t, []*BuildTarget{target1}, target2.Dependencies())
   348  }
   349  
   350  func TestAddDependencySource(t *testing.T) {
   351  	target1 := makeTarget("//src/core:target1", "")
   352  	target2 := makeTarget("//src/core:target2", "")
   353  	target2.AddMaybeExportedDependency(target1.Label, true, true)
   354  	assert.True(t, target2.IsSourceOnlyDep(target1.Label))
   355  	// N.B. It's important that calling this again cancels the source flag.
   356  	target2.AddMaybeExportedDependency(target1.Label, true, false)
   357  	assert.False(t, target2.IsSourceOnlyDep(target1.Label))
   358  }
   359  
   360  func TestDependencyFor(t *testing.T) {
   361  	target1 := makeTarget("//src/core:target1", "")
   362  	target2 := makeTarget("//src/core:target2", "", target1)
   363  	assert.Equal(t, []*BuildTarget{target1}, target2.DependenciesFor(target1.Label))
   364  	assert.Equal(t, []*BuildTarget(nil), target2.DependenciesFor(target2.Label))
   365  	assert.Equal(t, 1, len(target2.dependencies))
   366  }
   367  
   368  func TestParent(t *testing.T) {
   369  	// "grandchild" is of course a misnomer since we only really have a concept of
   370  	// one level of parent-child relationship.
   371  	grandchild := makeTarget("//src/core:__target1#child#grandchild", "")
   372  	child := makeTarget("//src/core:_target1#child", "", grandchild)
   373  	parent := makeTarget("//src/core:target1", "", child)
   374  	graph := NewGraph()
   375  	graph.AddTarget(grandchild)
   376  	graph.AddTarget(child)
   377  	graph.AddTarget(parent)
   378  
   379  	assert.Equal(t, parent.Label, grandchild.Label.Parent())
   380  	assert.Equal(t, parent.Label, child.Label.Parent())
   381  	assert.Equal(t, parent.Label, parent.Label.Parent())
   382  	assert.Equal(t, parent, grandchild.Parent(graph))
   383  	assert.Equal(t, parent, child.Parent(graph))
   384  	assert.Equal(t, (*BuildTarget)(nil), parent.Parent(graph))
   385  }
   386  
   387  func TestHasParent(t *testing.T) {
   388  	grandchild := makeTarget("//src/core:__target1#child#grandchild", "")
   389  	child := makeTarget("//src/core:_target1#child", "", grandchild)
   390  	parent := makeTarget("//src/core:target1", "", child)
   391  	assert.True(t, grandchild.HasParent())
   392  	assert.True(t, child.HasParent())
   393  	assert.False(t, parent.HasParent())
   394  }
   395  
   396  func TestOutMode(t *testing.T) {
   397  	// Check that output modes match the binary flag correctly.
   398  	// This feels a little fatuous but it's hard to have any less specific assertions on it.
   399  	target := makeTarget("//src/core:target1", "")
   400  	assert.Equal(t, os.FileMode(0444), target.OutMode())
   401  	target.IsBinary = true
   402  	assert.Equal(t, os.FileMode(0555), target.OutMode())
   403  }
   404  
   405  func TestOutputOrdering(t *testing.T) {
   406  	// Check that outputs come out ordered, this is important for hash stability; previously
   407  	// we preserved the original order, but tools like buildifier may reorder them assuming
   408  	// that the order of arguments is not important.
   409  	target1 := makeTarget("//src/core:target1", "")
   410  	target1.AddOutput("file1.txt")
   411  	target1.AddOutput("file2.txt")
   412  	target2 := makeTarget("//src/core:target2", "")
   413  	target2.AddOutput("file2.txt")
   414  	target2.AddOutput("file1.txt")
   415  	assert.Equal(t, target1.DeclaredOutputs(), target2.DeclaredOutputs())
   416  	assert.Equal(t, target1.Outputs(), target2.Outputs())
   417  }
   418  
   419  func TestNamedOutputs(t *testing.T) {
   420  	target := makeTarget("//src/core:target1", "")
   421  	target.AddOutput("a.txt")
   422  	target.AddOutput("z.txt")
   423  	target.AddNamedOutput("srcs", "src1.c")
   424  	target.AddNamedOutput("srcs", "src2.c")
   425  	target.AddNamedOutput("hdrs", "hdr1.h")
   426  	target.AddNamedOutput("hdrs", "hdr2.h")
   427  	target.AddNamedOutput("hdrs", "hdr2.h") // deliberate duplicate
   428  	assert.Equal(t, []string{"a.txt", "hdr1.h", "hdr2.h", "src1.c", "src2.c", "z.txt"}, target.Outputs())
   429  	assert.Equal(t, []string{"a.txt", "z.txt"}, target.DeclaredOutputs())
   430  	assert.Equal(t, map[string][]string{"srcs": {"src1.c", "src2.c"}, "hdrs": {"hdr1.h", "hdr2.h"}}, target.DeclaredNamedOutputs())
   431  	assert.Equal(t, []string{"hdr1.h", "hdr2.h"}, target.NamedOutputs("hdrs"))
   432  	assert.Equal(t, []string{"src1.c", "src2.c"}, target.NamedOutputs("srcs"))
   433  	assert.Equal(t, 0, len(target.NamedOutputs("go_srcs")))
   434  	assert.Equal(t, []string{"hdrs", "srcs"}, target.DeclaredOutputNames())
   435  }
   436  
   437  func TestAllLocalSources(t *testing.T) {
   438  	target := makeTarget("//src/core:target1", "")
   439  	target.AddSource(FileLabel{File: "target1.go", Package: "src/core"})
   440  	target.AddSource(BuildLabel{Name: "target2", PackageName: "src/core"})
   441  	target.AddSource(SystemFileLabel{Path: "/usr/bin/bash"})
   442  	assert.Equal(t, []string{"src/core/target1.go"}, target.AllLocalSources())
   443  }
   444  
   445  func TestCheckSecrets(t *testing.T) {
   446  	target := makeTarget("//src/core:target1", "")
   447  	assert.NoError(t, target.CheckSecrets())
   448  	target.Secrets = append(target.Secrets, "/bin/sh")
   449  	assert.NoError(t, target.CheckSecrets())
   450  	// Checking for files in the home directory is awkward because nothing is really
   451  	// guaranteed to exist. We just check the directory itself for now.
   452  	target.Secrets = append(target.Secrets, "~/")
   453  	assert.NoError(t, target.CheckSecrets())
   454  	target.Secrets = append(target.Secrets, "/doesnt_exist")
   455  	assert.Error(t, target.CheckSecrets())
   456  }
   457  
   458  func TestAddTool(t *testing.T) {
   459  	target1 := makeTarget("//src/core:target1", "")
   460  	target2 := makeTarget("//src/core:target2", "")
   461  	target1.AddTool(target2.Label)
   462  	assert.Equal(t, []BuildInput{target2.Label}, target1.Tools)
   463  	assert.True(t, target1.HasDependency(target2.Label))
   464  }
   465  
   466  func TestAddNamedTool(t *testing.T) {
   467  	target1 := makeTarget("//src/core:target1", "")
   468  	target2 := makeTarget("//src/core:target2", "")
   469  	target1.AddNamedTool("test", target2.Label)
   470  	assert.Equal(t, 0, len(target1.Tools))
   471  	assert.Equal(t, []BuildInput{target2.Label}, target1.NamedTools("test"))
   472  	assert.True(t, target1.HasDependency(target2.Label))
   473  }
   474  
   475  func TestAllTools(t *testing.T) {
   476  	target1 := makeTarget("//src/core:target1", "")
   477  	target2 := makeTarget("//src/core:target2", "")
   478  	target3 := makeTarget("//src/core:target3", "")
   479  	target4 := makeTarget("//src/core:target4", "")
   480  	target1.AddTool(target2.Label)
   481  	target1.AddNamedTool("test1", target4.Label)
   482  	target1.AddNamedTool("test2", target3.Label)
   483  	assert.Equal(t, []BuildInput{target2.Label, target4.Label, target3.Label}, target1.AllTools())
   484  }
   485  
   486  func TestContainerSettingsToMap(t *testing.T) {
   487  	s := TargetContainerSettings{
   488  		DockerImage: "alpine:3.5",
   489  		DockerUser:  "test",
   490  	}
   491  	expected := map[string]string{
   492  		"docker_image": "alpine:3.5",
   493  		"docker_user":  "test",
   494  	}
   495  	assert.Equal(t, expected, s.ToMap())
   496  }
   497  
   498  func TestShouldIncludeSimple(t *testing.T) {
   499  	target := makeTargetWithLabels("//src/core:target1", "a", "b", "c")
   500  	excludes := []string{}
   501  	includes := []string{"a"}
   502  	assert.True(t, target.ShouldInclude(includes, excludes))
   503  
   504  	includes = []string{"b"}
   505  	assert.True(t, target.ShouldInclude(includes, excludes))
   506  
   507  	includes = []string{"c"}
   508  	assert.True(t, target.ShouldInclude(includes, excludes))
   509  }
   510  
   511  func TestShouldIncludeNonMatchingInclude(t *testing.T) {
   512  	target := makeTargetWithLabels("//src/core:target1", "a", "b", "c")
   513  	excludes := []string{}
   514  	includes := []string{"d"}
   515  	assert.False(t, target.ShouldInclude(includes, excludes))
   516  }
   517  
   518  func TestShouldIncludeWithExclude(t *testing.T) {
   519  	target := makeTargetWithLabels("//src/core:target1", "a", "b", "c")
   520  	includes := []string{}
   521  	excludes := []string{"a"}
   522  	assert.False(t, target.ShouldInclude(includes, excludes))
   523  
   524  	excludes = []string{"b"}
   525  	assert.False(t, target.ShouldInclude(includes, excludes))
   526  
   527  	excludes = []string{"c"}
   528  	assert.False(t, target.ShouldInclude(includes, excludes))
   529  }
   530  
   531  func TestShouldIncludeWithIncludeAndExclude(t *testing.T) {
   532  	target := makeTargetWithLabels("//src/core:target1", "a", "b", "c")
   533  	includes := []string{"a"}
   534  	excludes := []string{"b"}
   535  	assert.False(t, target.ShouldInclude(includes, excludes))
   536  }
   537  
   538  func TestShouldIncludeWithCompoundInclude(t *testing.T) {
   539  	target := makeTargetWithLabels("//src/core:target1", "a", "b", "c")
   540  	includes := []string{"a,b"}
   541  	excludes := []string{}
   542  	assert.True(t, target.ShouldInclude(includes, excludes))
   543  
   544  	includes = []string{"a,d", "a"}
   545  	assert.True(t, target.ShouldInclude(includes, excludes))
   546  
   547  	includes = []string{"a,d"}
   548  	assert.False(t, target.ShouldInclude(includes, excludes))
   549  }
   550  
   551  func TestShouldIncludeWithCompoundExclude(t *testing.T) {
   552  	target := makeTargetWithLabels("//src/core:target1", "a", "b", "c")
   553  	includes := []string{}
   554  	excludes := []string{"a,d"}
   555  	assert.True(t, target.ShouldInclude(includes, excludes))
   556  
   557  	excludes = []string{"a,b", "d"}
   558  	assert.False(t, target.ShouldInclude(includes, excludes))
   559  }
   560  
   561  func TestShouldIncludeWithCompoundIncludeAndExclude(t *testing.T) {
   562  	target := makeTargetWithLabels("//src/core:target1", "a", "b", "c")
   563  	includes := []string{"a,b"}
   564  	excludes := []string{"a,d"}
   565  	assert.True(t, target.ShouldInclude(includes, excludes))
   566  
   567  	includes = []string{"a,b"}
   568  	excludes = []string{"a,c"}
   569  	assert.False(t, target.ShouldInclude(includes, excludes))
   570  }
   571  
   572  func TestShouldIncludeManual(t *testing.T) {
   573  	target := makeTargetWithLabels("//src/core:target1", "a", "manual")
   574  	// Doesn't include because "manual" overrides it
   575  	assert.False(t, target.ShouldInclude([]string{"a"}, nil))
   576  
   577  	target = makeTargetWithLabels("//src/core:target1", "a", "manual:test_armhf")
   578  	// Does include because it's a different architecture
   579  	assert.True(t, target.ShouldInclude([]string{"a"}, nil))
   580  
   581  	target = makeTargetWithLabels("//src/core:target1", "a", "manual:"+OsArch)
   582  	// Doesn't include because it's manual for this architecture.
   583  	assert.False(t, target.ShouldInclude([]string{"a"}, nil))
   584  }
   585  
   586  func makeTarget(label, visibility string, deps ...*BuildTarget) *BuildTarget {
   587  	target := NewBuildTarget(ParseBuildLabel(label, ""))
   588  	if visibility == "PUBLIC" {
   589  		target.Visibility = append(target.Visibility, BuildLabel{PackageName: "", Name: "..."})
   590  	} else if visibility != "" {
   591  		target.Visibility = append(target.Visibility, ParseBuildLabel(visibility, ""))
   592  	}
   593  	for _, dep := range deps {
   594  		target.AddDependency(dep.Label)
   595  		target.resolveDependency(dep.Label, dep)
   596  	}
   597  	return target
   598  }
   599  
   600  func makeTargetWithLabels(name string, labels ...string) *BuildTarget {
   601  	target := makeTarget(name, "")
   602  	for _, label := range labels {
   603  		target.AddLabel(label)
   604  	}
   605  	return target
   606  }
   607  
   608  func makeFilegroup(label, visibility string, deps ...*BuildTarget) *BuildTarget {
   609  	target := makeTarget(label, visibility, deps...)
   610  	target.IsFilegroup = true
   611  	return target
   612  }
   613  
   614  func addFilegroupSource(target *BuildTarget, source string) {
   615  	target.AddSource(FileLabel{Package: target.Label.PackageName, File: source})
   616  }