blob: 463405a3af018cdb694129566d642cd22e809e89 [file] [log] [blame]
Dan Willemsen9b587492017-07-10 22:13:00 -07001// Copyright 2017 Google Inc. 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
15package build
16
17import (
18 "bytes"
19 "context"
Patrice Arruda13848222019-04-22 17:12:02 -070020 "fmt"
21 "io/ioutil"
22 "os"
23 "path/filepath"
Dan Willemsen9b587492017-07-10 22:13:00 -070024 "reflect"
25 "strings"
26 "testing"
27
28 "android/soong/ui/logger"
29)
30
31func testContext() Context {
32 return Context{&ContextImpl{
Dan Willemsenb82471a2018-05-17 16:37:09 -070033 Context: context.Background(),
34 Logger: logger.New(&bytes.Buffer{}),
Colin Cross097ed2a2019-06-08 21:48:58 -070035 Writer: &bytes.Buffer{},
Dan Willemsen9b587492017-07-10 22:13:00 -070036 }}
37}
38
39func TestConfigParseArgsJK(t *testing.T) {
40 ctx := testContext()
41
42 testCases := []struct {
43 args []string
44
45 parallel int
46 keepGoing int
47 remaining []string
48 }{
49 {nil, -1, -1, nil},
50
51 {[]string{"-j"}, -1, -1, nil},
52 {[]string{"-j1"}, 1, -1, nil},
53 {[]string{"-j1234"}, 1234, -1, nil},
54
55 {[]string{"-j", "1"}, 1, -1, nil},
56 {[]string{"-j", "1234"}, 1234, -1, nil},
57 {[]string{"-j", "1234", "abc"}, 1234, -1, []string{"abc"}},
58 {[]string{"-j", "abc"}, -1, -1, []string{"abc"}},
59 {[]string{"-j", "1abc"}, -1, -1, []string{"1abc"}},
60
61 {[]string{"-k"}, -1, 0, nil},
62 {[]string{"-k0"}, -1, 0, nil},
63 {[]string{"-k1"}, -1, 1, nil},
64 {[]string{"-k1234"}, -1, 1234, nil},
65
66 {[]string{"-k", "0"}, -1, 0, nil},
67 {[]string{"-k", "1"}, -1, 1, nil},
68 {[]string{"-k", "1234"}, -1, 1234, nil},
69 {[]string{"-k", "1234", "abc"}, -1, 1234, []string{"abc"}},
70 {[]string{"-k", "abc"}, -1, 0, []string{"abc"}},
71 {[]string{"-k", "1abc"}, -1, 0, []string{"1abc"}},
72
73 // TODO: These are supported in Make, should we support them?
74 //{[]string{"-kj"}, -1, 0},
75 //{[]string{"-kj8"}, 8, 0},
76
77 // -jk is not valid in Make
78 }
79
80 for _, tc := range testCases {
81 t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
82 defer logger.Recover(func(err error) {
83 t.Fatal(err)
84 })
85
86 c := &configImpl{
87 parallel: -1,
88 keepGoing: -1,
89 }
90 c.parseArgs(ctx, tc.args)
91
92 if c.parallel != tc.parallel {
93 t.Errorf("for %q, parallel:\nwant: %d\n got: %d\n",
94 strings.Join(tc.args, " "),
95 tc.parallel, c.parallel)
96 }
97 if c.keepGoing != tc.keepGoing {
98 t.Errorf("for %q, keep going:\nwant: %d\n got: %d\n",
99 strings.Join(tc.args, " "),
100 tc.keepGoing, c.keepGoing)
101 }
102 if !reflect.DeepEqual(c.arguments, tc.remaining) {
103 t.Errorf("for %q, remaining arguments:\nwant: %q\n got: %q\n",
104 strings.Join(tc.args, " "),
105 tc.remaining, c.arguments)
106 }
107 })
108 }
109}
Dan Willemsen091525e2017-07-11 14:17:50 -0700110
111func TestConfigParseArgsVars(t *testing.T) {
112 ctx := testContext()
113
114 testCases := []struct {
115 env []string
116 args []string
117
118 expectedEnv []string
119 remaining []string
120 }{
121 {},
122 {
123 env: []string{"A=bc"},
124
125 expectedEnv: []string{"A=bc"},
126 },
127 {
128 args: []string{"abc"},
129
130 remaining: []string{"abc"},
131 },
132
133 {
134 args: []string{"A=bc"},
135
136 expectedEnv: []string{"A=bc"},
137 },
138 {
139 env: []string{"A=a"},
140 args: []string{"A=bc"},
141
142 expectedEnv: []string{"A=bc"},
143 },
144
145 {
146 env: []string{"A=a"},
147 args: []string{"A=", "=b"},
148
149 expectedEnv: []string{"A="},
150 remaining: []string{"=b"},
151 },
152 }
153
154 for _, tc := range testCases {
155 t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
156 defer logger.Recover(func(err error) {
157 t.Fatal(err)
158 })
159
160 e := Environment(tc.env)
161 c := &configImpl{
162 environ: &e,
163 }
164 c.parseArgs(ctx, tc.args)
165
166 if !reflect.DeepEqual([]string(*c.environ), tc.expectedEnv) {
167 t.Errorf("for env=%q args=%q, environment:\nwant: %q\n got: %q\n",
168 tc.env, tc.args,
169 tc.expectedEnv, []string(*c.environ))
170 }
171 if !reflect.DeepEqual(c.arguments, tc.remaining) {
172 t.Errorf("for env=%q args=%q, remaining arguments:\nwant: %q\n got: %q\n",
173 tc.env, tc.args,
174 tc.remaining, c.arguments)
175 }
176 })
177 }
178}
Patrice Arruda13848222019-04-22 17:12:02 -0700179
180func TestConfigCheckTopDir(t *testing.T) {
181 ctx := testContext()
182 buildRootDir := filepath.Dir(srcDirFileCheck)
183 expectedErrStr := fmt.Sprintf("Current working directory must be the source tree. %q not found.", srcDirFileCheck)
184
185 tests := []struct {
186 // ********* Setup *********
187 // Test description.
188 description string
189
190 // ********* Action *********
191 // If set to true, the build root file is created.
192 rootBuildFile bool
193
194 // The current path where Soong is being executed.
195 path string
196
197 // ********* Validation *********
198 // Expecting error and validate the error string against expectedErrStr.
199 wantErr bool
200 }{{
201 description: "current directory is the root source tree",
202 rootBuildFile: true,
203 path: ".",
204 wantErr: false,
205 }, {
206 description: "one level deep in the source tree",
207 rootBuildFile: true,
208 path: "1",
209 wantErr: true,
210 }, {
211 description: "very deep in the source tree",
212 rootBuildFile: true,
213 path: "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/7",
214 wantErr: true,
215 }, {
216 description: "outside of source tree",
217 rootBuildFile: false,
218 path: "1/2/3/4/5",
219 wantErr: true,
220 }}
221
222 for _, tt := range tests {
223 t.Run(tt.description, func(t *testing.T) {
224 defer logger.Recover(func(err error) {
225 if !tt.wantErr {
226 t.Fatalf("Got unexpected error: %v", err)
227 }
228 if expectedErrStr != err.Error() {
229 t.Fatalf("expected %s, got %s", expectedErrStr, err.Error())
230 }
231 })
232
233 // Create the root source tree.
234 rootDir, err := ioutil.TempDir("", "")
235 if err != nil {
236 t.Fatal(err)
237 }
238 defer os.RemoveAll(rootDir)
239
240 // Create the build root file. This is to test if topDir returns an error if the build root
241 // file does not exist.
242 if tt.rootBuildFile {
243 dir := filepath.Join(rootDir, buildRootDir)
244 if err := os.MkdirAll(dir, 0755); err != nil {
245 t.Errorf("failed to create %s directory: %v", dir, err)
246 }
247 f := filepath.Join(rootDir, srcDirFileCheck)
248 if err := ioutil.WriteFile(f, []byte{}, 0644); err != nil {
249 t.Errorf("failed to create file %s: %v", f, err)
250 }
251 }
252
253 // Next block of code is to set the current directory.
254 dir := rootDir
255 if tt.path != "" {
256 dir = filepath.Join(dir, tt.path)
257 if err := os.MkdirAll(dir, 0755); err != nil {
258 t.Errorf("failed to create %s directory: %v", dir, err)
259 }
260 }
261 curDir, err := os.Getwd()
262 if err != nil {
263 t.Fatalf("failed to get the current directory: %v", err)
264 }
265 defer func() { os.Chdir(curDir) }()
266
267 if err := os.Chdir(dir); err != nil {
268 t.Fatalf("failed to change directory to %s: %v", dir, err)
269 }
270
271 checkTopDir(ctx)
272 })
273 }
274}
275
276func TestConfigConvertToTarget(t *testing.T) {
277 tests := []struct {
278 // ********* Setup *********
279 // Test description.
280 description string
281
282 // ********* Action *********
283 // The current directory where Soong is being executed.
284 dir string
285
286 // The current prefix string to be pre-appended to the target.
287 prefix string
288
289 // ********* Validation *********
290 // The expected target to be invoked in ninja.
291 expectedTarget string
292 }{{
293 description: "one level directory in source tree",
294 dir: "test1",
295 prefix: "MODULES-IN-",
296 expectedTarget: "MODULES-IN-test1",
297 }, {
298 description: "multiple level directories in source tree",
299 dir: "test1/test2/test3/test4",
300 prefix: "GET-INSTALL-PATH-IN-",
301 expectedTarget: "GET-INSTALL-PATH-IN-test1-test2-test3-test4",
302 }}
303 for _, tt := range tests {
304 t.Run(tt.description, func(t *testing.T) {
305 target := convertToTarget(tt.dir, tt.prefix)
306 if target != tt.expectedTarget {
307 t.Errorf("expected %s, got %s for target", tt.expectedTarget, target)
308 }
309 })
310 }
311}
312
313func setTop(t *testing.T, dir string) func() {
314 curDir, err := os.Getwd()
315 if err != nil {
316 t.Fatalf("failed to get current directory: %v", err)
317 }
318 if err := os.Chdir(dir); err != nil {
319 t.Fatalf("failed to change directory to top dir %s: %v", dir, err)
320 }
321 return func() { os.Chdir(curDir) }
322}
323
324func createBuildFiles(t *testing.T, topDir string, buildFiles []string) {
325 for _, buildFile := range buildFiles {
326 buildFile = filepath.Join(topDir, buildFile)
327 if err := ioutil.WriteFile(buildFile, []byte{}, 0644); err != nil {
328 t.Errorf("failed to create file %s: %v", buildFile, err)
329 }
330 }
331}
332
333func createDirectories(t *testing.T, topDir string, dirs []string) {
334 for _, dir := range dirs {
335 dir = filepath.Join(topDir, dir)
336 if err := os.MkdirAll(dir, 0755); err != nil {
337 t.Errorf("failed to create %s directory: %v", dir, err)
338 }
339 }
340}
341
342func TestConfigGetTargets(t *testing.T) {
343 ctx := testContext()
344 tests := []struct {
345 // ********* Setup *********
346 // Test description.
347 description string
348
349 // Directories that exist in the source tree.
350 dirsInTrees []string
351
352 // Build files that exists in the source tree.
353 buildFiles []string
354
355 // ********* Action *********
356 // Directories passed in to soong_ui.
357 dirs []string
358
359 // Current directory that the user executed the build action command.
360 curDir string
361
362 // ********* Validation *********
363 // Expected targets from the function.
364 expectedTargets []string
365
366 // Expected build from the build system.
367 expectedBuildFiles []string
368
369 // Expecting error from running test case.
370 errStr string
371 }{{
372 description: "one target dir specified",
373 dirsInTrees: []string{"0/1/2/3"},
374 buildFiles: []string{"0/1/2/3/Android.bp"},
375 dirs: []string{"1/2/3"},
376 curDir: "0",
377 expectedTargets: []string{"MODULES-IN-0-1-2-3"},
378 expectedBuildFiles: []string{"0/1/2/3/Android.mk"},
379 }, {
380 description: "one target dir specified, build file does not exist",
381 dirsInTrees: []string{"0/1/2/3"},
382 buildFiles: []string{},
383 dirs: []string{"1/2/3"},
384 curDir: "0",
385 errStr: "Build file not found for 0/1/2/3 directory",
386 }, {
387 description: "one target dir specified, invalid targets specified",
388 dirsInTrees: []string{"0/1/2/3"},
389 buildFiles: []string{},
390 dirs: []string{"1/2/3:t1:t2"},
391 curDir: "0",
392 errStr: "1/2/3:t1:t2 not in proper directory:target1,target2,... format (\":\" was specified more than once)",
393 }, {
394 description: "one target dir specified, no targets specified but has colon",
395 dirsInTrees: []string{"0/1/2/3"},
396 buildFiles: []string{"0/1/2/3/Android.bp"},
397 dirs: []string{"1/2/3:"},
398 curDir: "0",
399 expectedTargets: []string{"MODULES-IN-0-1-2-3"},
400 expectedBuildFiles: []string{"0/1/2/3/Android.mk"},
401 }, {
402 description: "one target dir specified, two targets specified",
403 dirsInTrees: []string{"0/1/2/3"},
404 buildFiles: []string{"0/1/2/3/Android.bp"},
405 dirs: []string{"1/2/3:t1,t2"},
406 curDir: "0",
407 expectedTargets: []string{"t1", "t2"},
408 expectedBuildFiles: []string{"0/1/2/3/Android.mk"},
409 }, {
410 description: "one target dir specified, no targets and has a comma",
411 dirsInTrees: []string{"0/1/2/3"},
412 buildFiles: []string{"0/1/2/3/Android.bp"},
413 dirs: []string{"1/2/3:,"},
414 curDir: "0",
415 errStr: "0/1/2/3 not in proper directory:target1,target2,... format",
416 }, {
417 description: "one target dir specified, improper targets defined",
418 dirsInTrees: []string{"0/1/2/3"},
419 buildFiles: []string{"0/1/2/3/Android.bp"},
420 dirs: []string{"1/2/3:,t1"},
421 curDir: "0",
422 errStr: "0/1/2/3 not in proper directory:target1,target2,... format",
423 }, {
424 description: "one target dir specified, blank target",
425 dirsInTrees: []string{"0/1/2/3"},
426 buildFiles: []string{"0/1/2/3/Android.bp"},
427 dirs: []string{"1/2/3:t1,"},
428 curDir: "0",
429 errStr: "0/1/2/3 not in proper directory:target1,target2,... format",
430 }, {
431 description: "one target dir specified, many targets specified",
432 dirsInTrees: []string{"0/1/2/3"},
433 buildFiles: []string{"0/1/2/3/Android.bp"},
434 dirs: []string{"1/2/3:t1,t2,t3,t4,t5,t6,t7,t8,t9,t10"},
435 curDir: "0",
436 expectedTargets: []string{"t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10"},
437 expectedBuildFiles: []string{"0/1/2/3/Android.mk"},
438 }, {
439 description: "one target dir specified, one target specified, build file does not exist",
440 dirsInTrees: []string{"0/1/2/3"},
441 buildFiles: []string{},
442 dirs: []string{"1/2/3:t1"},
443 curDir: "0",
Patrice Arruda9450d0b2019-07-08 11:06:46 -0700444 errStr: "Couldn't locate a build file from 0/1/2/3 directory",
Patrice Arruda13848222019-04-22 17:12:02 -0700445 }, {
446 description: "one target dir specified, one target specified, build file not in target dir",
447 dirsInTrees: []string{"0/1/2/3"},
448 buildFiles: []string{"0/1/2/Android.mk"},
449 dirs: []string{"1/2/3:t1"},
450 curDir: "0",
451 errStr: "Couldn't locate a build file from 0/1/2/3 directory",
452 }, {
453 description: "one target dir specified, build file not in target dir",
454 dirsInTrees: []string{"0/1/2/3"},
455 buildFiles: []string{"0/1/2/Android.mk"},
456 dirs: []string{"1/2/3"},
457 curDir: "0",
458 expectedTargets: []string{"MODULES-IN-0-1-2"},
459 expectedBuildFiles: []string{"0/1/2/Android.mk"},
460 }, {
461 description: "multiple targets dir specified, targets specified",
462 dirsInTrees: []string{"0/1/2/3", "0/3/4"},
463 buildFiles: []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"},
464 dirs: []string{"1/2/3:t1,t2", "3/4:t3,t4,t5"},
465 curDir: "0",
466 expectedTargets: []string{"t1", "t2", "t3", "t4", "t5"},
467 expectedBuildFiles: []string{"0/1/2/3/Android.mk", "0/3/4/Android.mk"},
468 }, {
469 description: "multiple targets dir specified, one directory has targets specified",
470 dirsInTrees: []string{"0/1/2/3", "0/3/4"},
471 buildFiles: []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"},
472 dirs: []string{"1/2/3:t1,t2", "3/4"},
473 curDir: "0",
474 expectedTargets: []string{"t1", "t2", "MODULES-IN-0-3-4"},
475 expectedBuildFiles: []string{"0/1/2/3/Android.mk", "0/3/4/Android.mk"},
476 }, {
477 description: "two dirs specified, only one dir exist",
478 dirsInTrees: []string{"0/1/2/3"},
479 buildFiles: []string{"0/1/2/3/Android.mk"},
480 dirs: []string{"1/2/3:t1", "3/4"},
481 curDir: "0",
482 errStr: "couldn't find directory 0/3/4",
483 }, {
484 description: "multiple targets dirs specified at root source tree",
485 dirsInTrees: []string{"0/1/2/3", "0/3/4"},
486 buildFiles: []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"},
487 dirs: []string{"0/1/2/3:t1,t2", "0/3/4"},
488 curDir: ".",
489 expectedTargets: []string{"t1", "t2", "MODULES-IN-0-3-4"},
490 expectedBuildFiles: []string{"0/1/2/3/Android.mk", "0/3/4/Android.mk"},
491 }, {
492 description: "no directories specified",
493 dirsInTrees: []string{"0/1/2/3", "0/3/4"},
494 buildFiles: []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"},
495 dirs: []string{},
496 curDir: ".",
497 }}
498 for _, tt := range tests {
499 t.Run(tt.description, func(t *testing.T) {
500 defer logger.Recover(func(err error) {
501 if tt.errStr == "" {
502 t.Fatalf("Got unexpected error: %v", err)
503 }
504 if tt.errStr != err.Error() {
505 t.Errorf("expected %s, got %s", tt.errStr, err.Error())
506 }
507 })
508
509 // Create the root source tree.
510 topDir, err := ioutil.TempDir("", "")
511 if err != nil {
512 t.Fatalf("failed to create temp dir: %v", err)
513 }
514 defer os.RemoveAll(topDir)
515
516 createDirectories(t, topDir, tt.dirsInTrees)
517 createBuildFiles(t, topDir, tt.buildFiles)
518 r := setTop(t, topDir)
519 defer r()
520
521 targets, buildFiles := getTargetsFromDirs(ctx, tt.curDir, tt.dirs, "MODULES-IN-")
522 if !reflect.DeepEqual(targets, tt.expectedTargets) {
523 t.Errorf("expected %v, got %v for targets", tt.expectedTargets, targets)
524 }
525 if !reflect.DeepEqual(buildFiles, tt.expectedBuildFiles) {
526 t.Errorf("expected %v, got %v for build files", tt.expectedBuildFiles, buildFiles)
527 }
528
529 // If the execution reached here and there was an expected error code, the unit test case failed.
530 if tt.errStr != "" {
531 t.Errorf("expecting error %s", tt.errStr)
532 }
533 })
534 }
535}
536
537func TestConfigFindBuildFile(t *testing.T) {
538 ctx := testContext()
539
540 tests := []struct {
541 // ********* Setup *********
542 // Test description.
543 description string
544
545 // Array of build files to create in dir.
546 buildFiles []string
547
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700548 // Directories that exist in the source tree.
549 dirsInTrees []string
550
Patrice Arruda13848222019-04-22 17:12:02 -0700551 // ********* Action *********
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700552 // The base directory is where findBuildFile is invoked.
Patrice Arruda13848222019-04-22 17:12:02 -0700553 dir string
554
555 // ********* Validation *********
556 // Expected build file path to find.
557 expectedBuildFile string
558 }{{
559 description: "build file exists at leaf directory",
560 buildFiles: []string{"1/2/3/Android.bp"},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700561 dirsInTrees: []string{"1/2/3"},
Patrice Arruda13848222019-04-22 17:12:02 -0700562 dir: "1/2/3",
563 expectedBuildFile: "1/2/3/Android.mk",
564 }, {
565 description: "build file exists in all directory paths",
566 buildFiles: []string{"1/Android.mk", "1/2/Android.mk", "1/2/3/Android.mk"},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700567 dirsInTrees: []string{"1/2/3"},
Patrice Arruda13848222019-04-22 17:12:02 -0700568 dir: "1/2/3",
569 expectedBuildFile: "1/2/3/Android.mk",
570 }, {
571 description: "build file does not exist in all directory paths",
572 buildFiles: []string{},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700573 dirsInTrees: []string{"1/2/3"},
Patrice Arruda13848222019-04-22 17:12:02 -0700574 dir: "1/2/3",
575 expectedBuildFile: "",
576 }, {
577 description: "build file exists only at top directory",
578 buildFiles: []string{"Android.bp"},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700579 dirsInTrees: []string{"1/2/3"},
Patrice Arruda13848222019-04-22 17:12:02 -0700580 dir: "1/2/3",
581 expectedBuildFile: "",
582 }, {
583 description: "build file exist in a subdirectory",
584 buildFiles: []string{"1/2/Android.bp"},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700585 dirsInTrees: []string{"1/2/3"},
Patrice Arruda13848222019-04-22 17:12:02 -0700586 dir: "1/2/3",
587 expectedBuildFile: "1/2/Android.mk",
588 }, {
589 description: "build file exists in a subdirectory",
590 buildFiles: []string{"1/Android.mk"},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700591 dirsInTrees: []string{"1/2/3"},
Patrice Arruda13848222019-04-22 17:12:02 -0700592 dir: "1/2/3",
593 expectedBuildFile: "1/Android.mk",
594 }, {
595 description: "top directory",
596 buildFiles: []string{"Android.bp"},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700597 dirsInTrees: []string{},
Patrice Arruda13848222019-04-22 17:12:02 -0700598 dir: ".",
599 expectedBuildFile: "",
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700600 }, {
601 description: "build file exists in subdirectory",
602 buildFiles: []string{"1/2/3/Android.bp", "1/2/4/Android.bp"},
603 dirsInTrees: []string{"1/2/3", "1/2/4"},
604 dir: "1/2",
605 expectedBuildFile: "1/2/Android.mk",
606 }, {
607 description: "build file exists in parent subdirectory",
608 buildFiles: []string{"1/5/Android.bp"},
609 dirsInTrees: []string{"1/2/3", "1/2/4", "1/5"},
610 dir: "1/2",
611 expectedBuildFile: "1/Android.mk",
612 }, {
613 description: "build file exists in deep parent's subdirectory.",
614 buildFiles: []string{"1/5/6/Android.bp"},
615 dirsInTrees: []string{"1/2/3", "1/2/4", "1/5/6", "1/5/7"},
616 dir: "1/2",
617 expectedBuildFile: "1/Android.mk",
Patrice Arruda13848222019-04-22 17:12:02 -0700618 }}
619
620 for _, tt := range tests {
621 t.Run(tt.description, func(t *testing.T) {
622 defer logger.Recover(func(err error) {
623 t.Fatalf("Got unexpected error: %v", err)
624 })
625
626 topDir, err := ioutil.TempDir("", "")
627 if err != nil {
628 t.Fatalf("failed to create temp dir: %v", err)
629 }
630 defer os.RemoveAll(topDir)
631
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700632 createDirectories(t, topDir, tt.dirsInTrees)
Patrice Arruda13848222019-04-22 17:12:02 -0700633 createBuildFiles(t, topDir, tt.buildFiles)
634
635 curDir, err := os.Getwd()
636 if err != nil {
637 t.Fatalf("Could not get working directory: %v", err)
638 }
639 defer func() { os.Chdir(curDir) }()
640 if err := os.Chdir(topDir); err != nil {
641 t.Fatalf("Could not change top dir to %s: %v", topDir, err)
642 }
643
644 buildFile := findBuildFile(ctx, tt.dir)
645 if buildFile != tt.expectedBuildFile {
646 t.Errorf("expected %q, got %q for build file", tt.expectedBuildFile, buildFile)
647 }
648 })
649 }
650}
651
652func TestConfigSplitArgs(t *testing.T) {
653 tests := []struct {
654 // ********* Setup *********
655 // Test description.
656 description string
657
658 // ********* Action *********
659 // Arguments passed in to soong_ui.
660 args []string
661
662 // ********* Validation *********
663 // Expected newArgs list after extracting the directories.
664 expectedNewArgs []string
665
666 // Expected directories
667 expectedDirs []string
668 }{{
669 description: "flags but no directories specified",
670 args: []string{"showcommands", "-j", "-k"},
671 expectedNewArgs: []string{"showcommands", "-j", "-k"},
672 expectedDirs: []string{},
673 }, {
674 description: "flags and one directory specified",
675 args: []string{"snod", "-j", "dir:target1,target2"},
676 expectedNewArgs: []string{"snod", "-j"},
677 expectedDirs: []string{"dir:target1,target2"},
678 }, {
679 description: "flags and directories specified",
680 args: []string{"dist", "-k", "dir1", "dir2:target1,target2"},
681 expectedNewArgs: []string{"dist", "-k"},
682 expectedDirs: []string{"dir1", "dir2:target1,target2"},
683 }, {
684 description: "only directories specified",
685 args: []string{"dir1", "dir2", "dir3:target1,target2"},
686 expectedNewArgs: []string{},
687 expectedDirs: []string{"dir1", "dir2", "dir3:target1,target2"},
688 }}
689 for _, tt := range tests {
690 t.Run(tt.description, func(t *testing.T) {
691 args, dirs := splitArgs(tt.args)
692 if !reflect.DeepEqual(tt.expectedNewArgs, args) {
693 t.Errorf("expected %v, got %v for arguments", tt.expectedNewArgs, args)
694 }
695 if !reflect.DeepEqual(tt.expectedDirs, dirs) {
696 t.Errorf("expected %v, got %v for directories", tt.expectedDirs, dirs)
697 }
698 })
699 }
700}
701
702type envVar struct {
703 name string
704 value string
705}
706
707type buildActionTestCase struct {
708 // ********* Setup *********
709 // Test description.
710 description string
711
712 // Directories that exist in the source tree.
713 dirsInTrees []string
714
715 // Build files that exists in the source tree.
716 buildFiles []string
717
Patrice Arrudababa9a92019-07-03 10:47:34 -0700718 // Create root symlink that points to topDir.
719 rootSymlink bool
720
Patrice Arruda13848222019-04-22 17:12:02 -0700721 // ********* Action *********
722 // Arguments passed in to soong_ui.
723 args []string
724
725 // Directory where the build action was invoked.
726 curDir string
727
728 // WITH_TIDY_ONLY environment variable specified.
729 tidyOnly string
730
731 // ********* Validation *********
732 // Expected arguments to be in Config instance.
733 expectedArgs []string
734
735 // Expected environment variables to be set.
736 expectedEnvVars []envVar
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700737
738 // Expecting error from running test case.
739 expectedErrStr string
Patrice Arruda13848222019-04-22 17:12:02 -0700740}
741
742func testGetConfigArgs(t *testing.T, tt buildActionTestCase, action BuildAction, buildDependencies bool) {
743 ctx := testContext()
744
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700745 defer logger.Recover(func(err error) {
746 if tt.expectedErrStr == "" {
747 t.Fatalf("Got unexpected error: %v", err)
748 }
749 if tt.expectedErrStr != err.Error() {
750 t.Errorf("expected %s, got %s", tt.expectedErrStr, err.Error())
751 }
752 })
753
Patrice Arruda13848222019-04-22 17:12:02 -0700754 // Environment variables to set it to blank on every test case run.
755 resetEnvVars := []string{
756 "ONE_SHOT_MAKEFILE",
757 "WITH_TIDY_ONLY",
758 }
759
760 for _, name := range resetEnvVars {
761 if err := os.Unsetenv(name); err != nil {
762 t.Fatalf("failed to unset environment variable %s: %v", name, err)
763 }
764 }
765 if tt.tidyOnly != "" {
766 if err := os.Setenv("WITH_TIDY_ONLY", tt.tidyOnly); err != nil {
767 t.Errorf("failed to set WITH_TIDY_ONLY to %s: %v", tt.tidyOnly, err)
768 }
769 }
770
771 // Create the root source tree.
772 topDir, err := ioutil.TempDir("", "")
773 if err != nil {
774 t.Fatalf("failed to create temp dir: %v", err)
775 }
776 defer os.RemoveAll(topDir)
777
778 createDirectories(t, topDir, tt.dirsInTrees)
779 createBuildFiles(t, topDir, tt.buildFiles)
780
Patrice Arrudababa9a92019-07-03 10:47:34 -0700781 if tt.rootSymlink {
782 // Create a secondary root source tree which points to the true root source tree.
783 symlinkTopDir, err := ioutil.TempDir("", "")
784 if err != nil {
785 t.Fatalf("failed to create symlink temp dir: %v", err)
786 }
787 defer os.RemoveAll(symlinkTopDir)
788
789 symlinkTopDir = filepath.Join(symlinkTopDir, "root")
790 err = os.Symlink(topDir, symlinkTopDir)
791 if err != nil {
792 t.Fatalf("failed to create symlink: %v", err)
793 }
794 topDir = symlinkTopDir
795 }
796
Patrice Arruda13848222019-04-22 17:12:02 -0700797 r := setTop(t, topDir)
798 defer r()
799
800 // The next block is to create the root build file.
801 rootBuildFileDir := filepath.Dir(srcDirFileCheck)
802 if err := os.MkdirAll(rootBuildFileDir, 0755); err != nil {
803 t.Fatalf("Failed to create %s directory: %v", rootBuildFileDir, err)
804 }
805
806 if err := ioutil.WriteFile(srcDirFileCheck, []byte{}, 0644); err != nil {
807 t.Fatalf("failed to create %s file: %v", srcDirFileCheck, err)
808 }
809
810 args := getConfigArgs(action, tt.curDir, buildDependencies, ctx, tt.args)
811 if !reflect.DeepEqual(tt.expectedArgs, args) {
812 t.Fatalf("expected %v, got %v for config arguments", tt.expectedArgs, args)
813 }
814
815 for _, env := range tt.expectedEnvVars {
816 if val := os.Getenv(env.name); val != env.value {
817 t.Errorf("expecting %s, got %s for environment variable %s", env.value, val, env.name)
818 }
819 }
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700820
821 // If the execution reached here and there was an expected error code, the unit test case failed.
822 if tt.expectedErrStr != "" {
823 t.Errorf("expecting error %s", tt.expectedErrStr)
824 }
Patrice Arruda13848222019-04-22 17:12:02 -0700825}
826
Patrice Arruda39282062019-06-20 16:35:12 -0700827func TestGetConfigArgsBuildModules(t *testing.T) {
828 tests := []buildActionTestCase{{
829 description: "normal execution from the root source tree directory",
830 dirsInTrees: []string{"0/1/2", "0/2", "0/3"},
831 buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp", "0/3/Android.mk"},
832 args: []string{"-j", "fake_module", "fake_module2"},
833 curDir: ".",
834 tidyOnly: "",
835 expectedArgs: []string{"-j", "fake_module", "fake_module2"},
836 expectedEnvVars: []envVar{},
837 }, {
838 description: "normal execution in deep directory",
839 dirsInTrees: []string{"0/1/2", "0/2", "0/3", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6"},
840 buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/Android.mk"},
841 args: []string{"-j", "fake_module", "fake_module2", "-k"},
842 curDir: "1/2/3/4/5/6/7/8/9",
843 tidyOnly: "",
844 expectedArgs: []string{"-j", "fake_module", "fake_module2", "-k"},
845 expectedEnvVars: []envVar{},
846 }, {
847 description: "normal execution in deep directory, no targets",
848 dirsInTrees: []string{"0/1/2", "0/2", "0/3", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6"},
849 buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/Android.mk"},
850 args: []string{"-j", "-k"},
851 curDir: "1/2/3/4/5/6/7/8/9",
852 tidyOnly: "",
853 expectedArgs: []string{"-j", "-k"},
854 expectedEnvVars: []envVar{},
855 }, {
856 description: "normal execution in root source tree, no args",
857 dirsInTrees: []string{"0/1/2", "0/2", "0/3"},
858 buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp"},
859 args: []string{},
Patrice Arrudababa9a92019-07-03 10:47:34 -0700860 curDir: "0/2",
861 tidyOnly: "",
862 expectedArgs: []string{},
863 expectedEnvVars: []envVar{},
864 }, {
865 description: "normal execution in symlink root source tree, no args",
866 dirsInTrees: []string{"0/1/2", "0/2", "0/3"},
867 buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp"},
868 rootSymlink: true,
869 args: []string{},
870 curDir: "0/2",
Patrice Arruda39282062019-06-20 16:35:12 -0700871 tidyOnly: "",
872 expectedArgs: []string{},
873 expectedEnvVars: []envVar{},
874 }}
875 for _, tt := range tests {
876 t.Run("build action BUILD_MODULES with dependencies, "+tt.description, func(t *testing.T) {
877 testGetConfigArgs(t, tt, BUILD_MODULES, true)
878 })
879 }
880}
881
Patrice Arruda13848222019-04-22 17:12:02 -0700882// TODO: Remove this test case once mm shell build command has been deprecated.
883func TestGetConfigArgsBuildModulesInDirecotoryNoDeps(t *testing.T) {
884 tests := []buildActionTestCase{{
885 description: "normal execution in a directory",
886 dirsInTrees: []string{"0/1/2"},
887 buildFiles: []string{"0/1/2/Android.mk"},
888 args: []string{"-j", "-k", "showcommands", "fake-module"},
889 curDir: "0/1/2",
890 tidyOnly: "",
891 expectedArgs: []string{"-j", "-k", "showcommands", "fake-module", "MODULES-IN-0-1-2"},
892 expectedEnvVars: []envVar{
893 envVar{
894 name: "ONE_SHOT_MAKEFILE",
895 value: "0/1/2/Android.mk"}},
896 }, {
897 description: "makefile in parent directory",
898 dirsInTrees: []string{"0/1/2"},
899 buildFiles: []string{"0/1/Android.mk"},
900 args: []string{},
901 curDir: "0/1/2",
902 tidyOnly: "",
903 expectedArgs: []string{"MODULES-IN-0-1"},
904 expectedEnvVars: []envVar{
905 envVar{
906 name: "ONE_SHOT_MAKEFILE",
907 value: "0/1/Android.mk"}},
908 }, {
909 description: "build file not found",
910 dirsInTrees: []string{"0/1/2"},
911 buildFiles: []string{},
912 args: []string{},
913 curDir: "0/1/2",
914 tidyOnly: "",
915 expectedArgs: []string{"MODULES-IN-0-1-2"},
916 expectedEnvVars: []envVar{
917 envVar{
918 name: "ONE_SHOT_MAKEFILE",
919 value: "0/1/2/Android.mk"}},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -0700920 expectedErrStr: "Build file not found for 0/1/2 directory",
Patrice Arruda13848222019-04-22 17:12:02 -0700921 }, {
922 description: "build action executed at root directory",
923 dirsInTrees: []string{},
924 buildFiles: []string{},
925 args: []string{},
926 curDir: ".",
927 tidyOnly: "",
928 expectedArgs: []string{},
929 expectedEnvVars: []envVar{
930 envVar{
931 name: "ONE_SHOT_MAKEFILE",
932 value: ""}},
933 }, {
934 description: "GET-INSTALL-PATH specified,",
935 dirsInTrees: []string{"0/1/2"},
936 buildFiles: []string{"0/1/Android.mk"},
937 args: []string{"GET-INSTALL-PATH"},
938 curDir: "0/1/2",
939 tidyOnly: "",
940 expectedArgs: []string{"GET-INSTALL-PATH-IN-0-1"},
941 expectedEnvVars: []envVar{
942 envVar{
943 name: "ONE_SHOT_MAKEFILE",
944 value: "0/1/Android.mk"}},
945 }, {
946 description: "tidy only environment variable specified,",
947 dirsInTrees: []string{"0/1/2"},
948 buildFiles: []string{"0/1/Android.mk"},
949 args: []string{"GET-INSTALL-PATH"},
950 curDir: "0/1/2",
951 tidyOnly: "true",
952 expectedArgs: []string{"tidy_only"},
953 expectedEnvVars: []envVar{
954 envVar{
955 name: "ONE_SHOT_MAKEFILE",
956 value: "0/1/Android.mk"}},
957 }}
958 for _, tt := range tests {
959 t.Run("build action BUILD_MODULES_IN_DIR without their dependencies, "+tt.description, func(t *testing.T) {
960 testGetConfigArgs(t, tt, BUILD_MODULES_IN_A_DIRECTORY, false)
961 })
962 }
963}
964
965func TestGetConfigArgsBuildModulesInDirectory(t *testing.T) {
966 tests := []buildActionTestCase{{
967 description: "normal execution in a directory",
968 dirsInTrees: []string{"0/1/2"},
969 buildFiles: []string{"0/1/2/Android.mk"},
970 args: []string{"fake-module"},
971 curDir: "0/1/2",
972 tidyOnly: "",
973 expectedArgs: []string{"fake-module", "MODULES-IN-0-1-2"},
974 expectedEnvVars: []envVar{},
975 }, {
976 description: "build file in parent directory",
977 dirsInTrees: []string{"0/1/2"},
978 buildFiles: []string{"0/1/Android.mk"},
979 args: []string{},
980 curDir: "0/1/2",
981 tidyOnly: "",
982 expectedArgs: []string{"MODULES-IN-0-1"},
983 expectedEnvVars: []envVar{},
984 },
985 {
986 description: "build file in parent directory, multiple module names passed in",
987 dirsInTrees: []string{"0/1/2"},
988 buildFiles: []string{"0/1/Android.mk"},
989 args: []string{"fake-module1", "fake-module2", "fake-module3"},
990 curDir: "0/1/2",
991 tidyOnly: "",
992 expectedArgs: []string{"fake-module1", "fake-module2", "fake-module3", "MODULES-IN-0-1"},
993 expectedEnvVars: []envVar{},
994 }, {
995 description: "build file in 2nd level parent directory",
996 dirsInTrees: []string{"0/1/2"},
997 buildFiles: []string{"0/Android.bp"},
998 args: []string{},
999 curDir: "0/1/2",
1000 tidyOnly: "",
1001 expectedArgs: []string{"MODULES-IN-0"},
1002 expectedEnvVars: []envVar{},
1003 }, {
1004 description: "build action executed at root directory",
1005 dirsInTrees: []string{},
1006 buildFiles: []string{},
Patrice Arrudababa9a92019-07-03 10:47:34 -07001007 rootSymlink: false,
1008 args: []string{},
1009 curDir: ".",
1010 tidyOnly: "",
1011 expectedArgs: []string{},
1012 expectedEnvVars: []envVar{},
1013 }, {
1014 description: "build action executed at root directory in symlink",
1015 dirsInTrees: []string{},
1016 buildFiles: []string{},
1017 rootSymlink: true,
Patrice Arruda13848222019-04-22 17:12:02 -07001018 args: []string{},
1019 curDir: ".",
1020 tidyOnly: "",
1021 expectedArgs: []string{},
1022 expectedEnvVars: []envVar{},
1023 }, {
Patrice Arruda0dcf27f2019-07-08 17:03:33 -07001024 description: "build file not found",
Patrice Arruda13848222019-04-22 17:12:02 -07001025 dirsInTrees: []string{"0/1/2"},
1026 buildFiles: []string{},
1027 args: []string{},
1028 curDir: "0/1/2",
1029 tidyOnly: "",
1030 expectedArgs: []string{"MODULES-IN-0-1-2"},
1031 expectedEnvVars: []envVar{},
Patrice Arruda0dcf27f2019-07-08 17:03:33 -07001032 expectedErrStr: "Build file not found for 0/1/2 directory",
Patrice Arruda13848222019-04-22 17:12:02 -07001033 }, {
1034 description: "GET-INSTALL-PATH specified,",
1035 dirsInTrees: []string{"0/1/2"},
1036 buildFiles: []string{"0/1/Android.mk"},
1037 args: []string{"GET-INSTALL-PATH", "-j", "-k", "GET-INSTALL-PATH"},
1038 curDir: "0/1/2",
1039 tidyOnly: "",
1040 expectedArgs: []string{"-j", "-k", "GET-INSTALL-PATH-IN-0-1"},
1041 expectedEnvVars: []envVar{},
1042 }, {
1043 description: "tidy only environment variable specified,",
1044 dirsInTrees: []string{"0/1/2"},
1045 buildFiles: []string{"0/1/Android.mk"},
1046 args: []string{"GET-INSTALL-PATH"},
1047 curDir: "0/1/2",
1048 tidyOnly: "true",
1049 expectedArgs: []string{"tidy_only"},
1050 expectedEnvVars: []envVar{},
1051 }, {
1052 description: "normal execution in root directory with args",
1053 dirsInTrees: []string{},
1054 buildFiles: []string{},
1055 args: []string{"-j", "-k", "fake_module"},
1056 curDir: "",
1057 tidyOnly: "",
1058 expectedArgs: []string{"-j", "-k", "fake_module"},
1059 expectedEnvVars: []envVar{},
1060 }}
1061 for _, tt := range tests {
1062 t.Run("build action BUILD_MODULES_IN_DIR, "+tt.description, func(t *testing.T) {
1063 testGetConfigArgs(t, tt, BUILD_MODULES_IN_A_DIRECTORY, true)
1064 })
1065 }
1066}
1067
1068// TODO: Remove this test case once mmm shell build command has been deprecated.
1069func TestGetConfigArgsBuildModulesInDirectoriesNoDeps(t *testing.T) {
1070 tests := []buildActionTestCase{{
1071 description: "normal execution in a directory",
1072 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"},
1073 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"},
1074 args: []string{"3.1/:t1,t2", "3.2/:t3,t4", "3.3/:t5,t6"},
1075 curDir: "0/1/2",
1076 tidyOnly: "",
1077 expectedArgs: []string{"t1", "t2", "t3", "t4", "t5", "t6"},
1078 expectedEnvVars: []envVar{
1079 envVar{
1080 name: "ONE_SHOT_MAKEFILE",
1081 value: "0/1/2/3.1/Android.mk 0/1/2/3.2/Android.mk 0/1/2/3.3/Android.mk"}},
1082 }, {
1083 description: "GET-INSTALL-PATH specified",
1084 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"},
1085 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"},
1086 args: []string{"GET-INSTALL-PATH", "3.1/", "3.2/", "3.3/:t6"},
1087 curDir: "0/1/2",
1088 tidyOnly: "",
1089 expectedArgs: []string{"GET-INSTALL-PATH-IN-0-1-2-3.1", "GET-INSTALL-PATH-IN-0-1-2-3.2", "t6"},
1090 expectedEnvVars: []envVar{
1091 envVar{
1092 name: "ONE_SHOT_MAKEFILE",
1093 value: "0/1/2/3.1/Android.mk 0/1/2/3.2/Android.mk 0/1/2/3.3/Android.mk"}},
1094 }, {
1095 description: "tidy only environment variable specified",
1096 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"},
1097 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"},
1098 args: []string{"GET-INSTALL-PATH", "3.1/", "3.2/", "3.3/:t6"},
1099 curDir: "0/1/2",
1100 tidyOnly: "1",
1101 expectedArgs: []string{"tidy_only"},
1102 expectedEnvVars: []envVar{
1103 envVar{
1104 name: "ONE_SHOT_MAKEFILE",
1105 value: "0/1/2/3.1/Android.mk 0/1/2/3.2/Android.mk 0/1/2/3.3/Android.mk"}},
1106 }, {
1107 description: "normal execution from top dir directory",
1108 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"},
1109 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"},
1110 args: []string{"0/1/2/3.1", "0/1/2/3.2/:t3,t4", "0/1/2/3.3/:t5,t6"},
1111 curDir: ".",
1112 tidyOnly: "",
1113 expectedArgs: []string{"MODULES-IN-0-1-2-3.1", "t3", "t4", "t5", "t6"},
1114 expectedEnvVars: []envVar{
1115 envVar{
1116 name: "ONE_SHOT_MAKEFILE",
1117 value: "0/1/2/3.1/Android.mk 0/1/2/3.2/Android.mk 0/1/2/3.3/Android.mk"}},
1118 }}
1119 for _, tt := range tests {
1120 t.Run("build action BUILD_MODULES_IN_DIRS_NO_DEPS, "+tt.description, func(t *testing.T) {
1121 testGetConfigArgs(t, tt, BUILD_MODULES_IN_DIRECTORIES, false)
1122 })
1123 }
1124}
1125
1126func TestGetConfigArgsBuildModulesInDirectories(t *testing.T) {
1127 tests := []buildActionTestCase{{
1128 description: "normal execution in a directory",
1129 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"},
1130 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"},
1131 args: []string{"3.1/", "3.2/", "3.3/"},
1132 curDir: "0/1/2",
1133 tidyOnly: "",
1134 expectedArgs: []string{"MODULES-IN-0-1-2-3.1", "MODULES-IN-0-1-2-3.2", "MODULES-IN-0-1-2-3.3"},
1135 expectedEnvVars: []envVar{
1136 envVar{
1137 name: "ONE_SHOT_MAKEFILE",
1138 value: ""}},
1139 }, {
1140 description: "GET-INSTALL-PATH specified",
1141 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3"},
1142 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/Android.bp"},
1143 args: []string{"GET-INSTALL-PATH", "2/3.1/", "2/3.2", "3"},
1144 curDir: "0/1",
1145 tidyOnly: "",
1146 expectedArgs: []string{"GET-INSTALL-PATH-IN-0-1-2-3.1", "GET-INSTALL-PATH-IN-0-1-2-3.2", "GET-INSTALL-PATH-IN-0-1"},
1147 expectedEnvVars: []envVar{
1148 envVar{
1149 name: "ONE_SHOT_MAKEFILE",
1150 value: ""}},
1151 }, {
1152 description: "tidy only environment variable specified",
1153 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"},
1154 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"},
1155 args: []string{"GET-INSTALL-PATH", "3.1/", "3.2/", "3.3"},
1156 curDir: "0/1/2",
1157 tidyOnly: "1",
1158 expectedArgs: []string{"tidy_only"},
1159 expectedEnvVars: []envVar{
1160 envVar{
1161 name: "ONE_SHOT_MAKEFILE",
1162 value: ""}},
1163 }, {
1164 description: "normal execution from top dir directory",
1165 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"},
1166 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/3/Android.bp", "0/2/Android.bp"},
Patrice Arrudababa9a92019-07-03 10:47:34 -07001167 rootSymlink: false,
1168 args: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"},
1169 curDir: ".",
1170 tidyOnly: "",
1171 expectedArgs: []string{"MODULES-IN-0-1-2-3.1", "MODULES-IN-0-1-2-3.2", "MODULES-IN-0-1-3", "MODULES-IN-0-2"},
1172 expectedEnvVars: []envVar{
1173 envVar{
1174 name: "ONE_SHOT_MAKEFILE",
1175 value: ""}},
1176 }, {
1177 description: "normal execution from top dir directory in symlink",
1178 dirsInTrees: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"},
1179 buildFiles: []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/3/Android.bp", "0/2/Android.bp"},
1180 rootSymlink: true,
Patrice Arruda13848222019-04-22 17:12:02 -07001181 args: []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"},
1182 curDir: ".",
1183 tidyOnly: "",
1184 expectedArgs: []string{"MODULES-IN-0-1-2-3.1", "MODULES-IN-0-1-2-3.2", "MODULES-IN-0-1-3", "MODULES-IN-0-2"},
1185 expectedEnvVars: []envVar{
1186 envVar{
1187 name: "ONE_SHOT_MAKEFILE",
1188 value: ""}},
1189 }}
1190 for _, tt := range tests {
1191 t.Run("build action BUILD_MODULES_IN_DIRS, "+tt.description, func(t *testing.T) {
1192 testGetConfigArgs(t, tt, BUILD_MODULES_IN_DIRECTORIES, true)
1193 })
1194 }
1195}