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