| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 1 | // 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 |  | 
|  | 15 | package build | 
|  | 16 |  | 
|  | 17 | import ( | 
|  | 18 | "bytes" | 
|  | 19 | "context" | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 20 | "fmt" | 
|  | 21 | "io/ioutil" | 
|  | 22 | "os" | 
|  | 23 | "path/filepath" | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 24 | "reflect" | 
|  | 25 | "strings" | 
|  | 26 | "testing" | 
|  | 27 |  | 
|  | 28 | "android/soong/ui/logger" | 
| Patrice Arruda | 219eef3 | 2020-06-01 17:29:30 +0000 | [diff] [blame] | 29 | "android/soong/ui/status" | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 30 | ) | 
|  | 31 |  | 
|  | 32 | func testContext() Context { | 
|  | 33 | return Context{&ContextImpl{ | 
| Dan Willemsen | b82471a | 2018-05-17 16:37:09 -0700 | [diff] [blame] | 34 | Context: context.Background(), | 
|  | 35 | Logger:  logger.New(&bytes.Buffer{}), | 
| Colin Cross | 097ed2a | 2019-06-08 21:48:58 -0700 | [diff] [blame] | 36 | Writer:  &bytes.Buffer{}, | 
| Patrice Arruda | 219eef3 | 2020-06-01 17:29:30 +0000 | [diff] [blame] | 37 | Status:  &status.Status{}, | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 38 | }} | 
|  | 39 | } | 
|  | 40 |  | 
|  | 41 | func TestConfigParseArgsJK(t *testing.T) { | 
|  | 42 | ctx := testContext() | 
|  | 43 |  | 
|  | 44 | testCases := []struct { | 
|  | 45 | args []string | 
|  | 46 |  | 
|  | 47 | parallel  int | 
|  | 48 | keepGoing int | 
|  | 49 | remaining []string | 
|  | 50 | }{ | 
|  | 51 | {nil, -1, -1, nil}, | 
|  | 52 |  | 
|  | 53 | {[]string{"-j"}, -1, -1, nil}, | 
|  | 54 | {[]string{"-j1"}, 1, -1, nil}, | 
|  | 55 | {[]string{"-j1234"}, 1234, -1, nil}, | 
|  | 56 |  | 
|  | 57 | {[]string{"-j", "1"}, 1, -1, nil}, | 
|  | 58 | {[]string{"-j", "1234"}, 1234, -1, nil}, | 
|  | 59 | {[]string{"-j", "1234", "abc"}, 1234, -1, []string{"abc"}}, | 
|  | 60 | {[]string{"-j", "abc"}, -1, -1, []string{"abc"}}, | 
|  | 61 | {[]string{"-j", "1abc"}, -1, -1, []string{"1abc"}}, | 
|  | 62 |  | 
|  | 63 | {[]string{"-k"}, -1, 0, nil}, | 
|  | 64 | {[]string{"-k0"}, -1, 0, nil}, | 
|  | 65 | {[]string{"-k1"}, -1, 1, nil}, | 
|  | 66 | {[]string{"-k1234"}, -1, 1234, nil}, | 
|  | 67 |  | 
|  | 68 | {[]string{"-k", "0"}, -1, 0, nil}, | 
|  | 69 | {[]string{"-k", "1"}, -1, 1, nil}, | 
|  | 70 | {[]string{"-k", "1234"}, -1, 1234, nil}, | 
|  | 71 | {[]string{"-k", "1234", "abc"}, -1, 1234, []string{"abc"}}, | 
|  | 72 | {[]string{"-k", "abc"}, -1, 0, []string{"abc"}}, | 
|  | 73 | {[]string{"-k", "1abc"}, -1, 0, []string{"1abc"}}, | 
|  | 74 |  | 
|  | 75 | // TODO: These are supported in Make, should we support them? | 
|  | 76 | //{[]string{"-kj"}, -1, 0}, | 
|  | 77 | //{[]string{"-kj8"}, 8, 0}, | 
|  | 78 |  | 
|  | 79 | // -jk is not valid in Make | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | for _, tc := range testCases { | 
|  | 83 | t.Run(strings.Join(tc.args, " "), func(t *testing.T) { | 
|  | 84 | defer logger.Recover(func(err error) { | 
|  | 85 | t.Fatal(err) | 
|  | 86 | }) | 
|  | 87 |  | 
|  | 88 | c := &configImpl{ | 
|  | 89 | parallel:  -1, | 
|  | 90 | keepGoing: -1, | 
|  | 91 | } | 
|  | 92 | c.parseArgs(ctx, tc.args) | 
|  | 93 |  | 
|  | 94 | if c.parallel != tc.parallel { | 
|  | 95 | t.Errorf("for %q, parallel:\nwant: %d\n got: %d\n", | 
|  | 96 | strings.Join(tc.args, " "), | 
|  | 97 | tc.parallel, c.parallel) | 
|  | 98 | } | 
|  | 99 | if c.keepGoing != tc.keepGoing { | 
|  | 100 | t.Errorf("for %q, keep going:\nwant: %d\n got: %d\n", | 
|  | 101 | strings.Join(tc.args, " "), | 
|  | 102 | tc.keepGoing, c.keepGoing) | 
|  | 103 | } | 
|  | 104 | if !reflect.DeepEqual(c.arguments, tc.remaining) { | 
|  | 105 | t.Errorf("for %q, remaining arguments:\nwant: %q\n got: %q\n", | 
|  | 106 | strings.Join(tc.args, " "), | 
|  | 107 | tc.remaining, c.arguments) | 
|  | 108 | } | 
|  | 109 | }) | 
|  | 110 | } | 
|  | 111 | } | 
| Dan Willemsen | 091525e | 2017-07-11 14:17:50 -0700 | [diff] [blame] | 112 |  | 
|  | 113 | func TestConfigParseArgsVars(t *testing.T) { | 
|  | 114 | ctx := testContext() | 
|  | 115 |  | 
|  | 116 | testCases := []struct { | 
|  | 117 | env  []string | 
|  | 118 | args []string | 
|  | 119 |  | 
|  | 120 | expectedEnv []string | 
|  | 121 | remaining   []string | 
|  | 122 | }{ | 
|  | 123 | {}, | 
|  | 124 | { | 
|  | 125 | env: []string{"A=bc"}, | 
|  | 126 |  | 
|  | 127 | expectedEnv: []string{"A=bc"}, | 
|  | 128 | }, | 
|  | 129 | { | 
|  | 130 | args: []string{"abc"}, | 
|  | 131 |  | 
|  | 132 | remaining: []string{"abc"}, | 
|  | 133 | }, | 
|  | 134 |  | 
|  | 135 | { | 
|  | 136 | args: []string{"A=bc"}, | 
|  | 137 |  | 
|  | 138 | expectedEnv: []string{"A=bc"}, | 
|  | 139 | }, | 
|  | 140 | { | 
|  | 141 | env:  []string{"A=a"}, | 
|  | 142 | args: []string{"A=bc"}, | 
|  | 143 |  | 
|  | 144 | expectedEnv: []string{"A=bc"}, | 
|  | 145 | }, | 
|  | 146 |  | 
|  | 147 | { | 
|  | 148 | env:  []string{"A=a"}, | 
|  | 149 | args: []string{"A=", "=b"}, | 
|  | 150 |  | 
|  | 151 | expectedEnv: []string{"A="}, | 
|  | 152 | remaining:   []string{"=b"}, | 
|  | 153 | }, | 
|  | 154 | } | 
|  | 155 |  | 
|  | 156 | for _, tc := range testCases { | 
|  | 157 | t.Run(strings.Join(tc.args, " "), func(t *testing.T) { | 
|  | 158 | defer logger.Recover(func(err error) { | 
|  | 159 | t.Fatal(err) | 
|  | 160 | }) | 
|  | 161 |  | 
|  | 162 | e := Environment(tc.env) | 
|  | 163 | c := &configImpl{ | 
|  | 164 | environ: &e, | 
|  | 165 | } | 
|  | 166 | c.parseArgs(ctx, tc.args) | 
|  | 167 |  | 
|  | 168 | if !reflect.DeepEqual([]string(*c.environ), tc.expectedEnv) { | 
|  | 169 | t.Errorf("for env=%q args=%q, environment:\nwant: %q\n got: %q\n", | 
|  | 170 | tc.env, tc.args, | 
|  | 171 | tc.expectedEnv, []string(*c.environ)) | 
|  | 172 | } | 
|  | 173 | if !reflect.DeepEqual(c.arguments, tc.remaining) { | 
|  | 174 | t.Errorf("for env=%q args=%q, remaining arguments:\nwant: %q\n got: %q\n", | 
|  | 175 | tc.env, tc.args, | 
|  | 176 | tc.remaining, c.arguments) | 
|  | 177 | } | 
|  | 178 | }) | 
|  | 179 | } | 
|  | 180 | } | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 181 |  | 
|  | 182 | func TestConfigCheckTopDir(t *testing.T) { | 
|  | 183 | ctx := testContext() | 
|  | 184 | buildRootDir := filepath.Dir(srcDirFileCheck) | 
|  | 185 | expectedErrStr := fmt.Sprintf("Current working directory must be the source tree. %q not found.", srcDirFileCheck) | 
|  | 186 |  | 
|  | 187 | tests := []struct { | 
|  | 188 | // ********* Setup ********* | 
|  | 189 | // Test description. | 
|  | 190 | description string | 
|  | 191 |  | 
|  | 192 | // ********* Action ********* | 
|  | 193 | // If set to true, the build root file is created. | 
|  | 194 | rootBuildFile bool | 
|  | 195 |  | 
|  | 196 | // The current path where Soong is being executed. | 
|  | 197 | path string | 
|  | 198 |  | 
|  | 199 | // ********* Validation ********* | 
|  | 200 | // Expecting error and validate the error string against expectedErrStr. | 
|  | 201 | wantErr bool | 
|  | 202 | }{{ | 
|  | 203 | description:   "current directory is the root source tree", | 
|  | 204 | rootBuildFile: true, | 
|  | 205 | path:          ".", | 
|  | 206 | wantErr:       false, | 
|  | 207 | }, { | 
|  | 208 | description:   "one level deep in the source tree", | 
|  | 209 | rootBuildFile: true, | 
|  | 210 | path:          "1", | 
|  | 211 | wantErr:       true, | 
|  | 212 | }, { | 
|  | 213 | description:   "very deep in the source tree", | 
|  | 214 | rootBuildFile: true, | 
|  | 215 | 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", | 
|  | 216 | wantErr:       true, | 
|  | 217 | }, { | 
|  | 218 | description:   "outside of source tree", | 
|  | 219 | rootBuildFile: false, | 
|  | 220 | path:          "1/2/3/4/5", | 
|  | 221 | wantErr:       true, | 
|  | 222 | }} | 
|  | 223 |  | 
|  | 224 | for _, tt := range tests { | 
|  | 225 | t.Run(tt.description, func(t *testing.T) { | 
|  | 226 | defer logger.Recover(func(err error) { | 
|  | 227 | if !tt.wantErr { | 
|  | 228 | t.Fatalf("Got unexpected error: %v", err) | 
|  | 229 | } | 
|  | 230 | if expectedErrStr != err.Error() { | 
|  | 231 | t.Fatalf("expected %s, got %s", expectedErrStr, err.Error()) | 
|  | 232 | } | 
|  | 233 | }) | 
|  | 234 |  | 
|  | 235 | // Create the root source tree. | 
|  | 236 | rootDir, err := ioutil.TempDir("", "") | 
|  | 237 | if err != nil { | 
|  | 238 | t.Fatal(err) | 
|  | 239 | } | 
|  | 240 | defer os.RemoveAll(rootDir) | 
|  | 241 |  | 
|  | 242 | // Create the build root file. This is to test if topDir returns an error if the build root | 
|  | 243 | // file does not exist. | 
|  | 244 | if tt.rootBuildFile { | 
|  | 245 | dir := filepath.Join(rootDir, buildRootDir) | 
|  | 246 | if err := os.MkdirAll(dir, 0755); err != nil { | 
|  | 247 | t.Errorf("failed to create %s directory: %v", dir, err) | 
|  | 248 | } | 
|  | 249 | f := filepath.Join(rootDir, srcDirFileCheck) | 
|  | 250 | if err := ioutil.WriteFile(f, []byte{}, 0644); err != nil { | 
|  | 251 | t.Errorf("failed to create file %s: %v", f, err) | 
|  | 252 | } | 
|  | 253 | } | 
|  | 254 |  | 
|  | 255 | // Next block of code is to set the current directory. | 
|  | 256 | dir := rootDir | 
|  | 257 | if tt.path != "" { | 
|  | 258 | dir = filepath.Join(dir, tt.path) | 
|  | 259 | if err := os.MkdirAll(dir, 0755); err != nil { | 
|  | 260 | t.Errorf("failed to create %s directory: %v", dir, err) | 
|  | 261 | } | 
|  | 262 | } | 
|  | 263 | curDir, err := os.Getwd() | 
|  | 264 | if err != nil { | 
|  | 265 | t.Fatalf("failed to get the current directory: %v", err) | 
|  | 266 | } | 
|  | 267 | defer func() { os.Chdir(curDir) }() | 
|  | 268 |  | 
|  | 269 | if err := os.Chdir(dir); err != nil { | 
|  | 270 | t.Fatalf("failed to change directory to %s: %v", dir, err) | 
|  | 271 | } | 
|  | 272 |  | 
|  | 273 | checkTopDir(ctx) | 
|  | 274 | }) | 
|  | 275 | } | 
|  | 276 | } | 
|  | 277 |  | 
|  | 278 | func TestConfigConvertToTarget(t *testing.T) { | 
|  | 279 | tests := []struct { | 
|  | 280 | // ********* Setup ********* | 
|  | 281 | // Test description. | 
|  | 282 | description string | 
|  | 283 |  | 
|  | 284 | // ********* Action ********* | 
|  | 285 | // The current directory where Soong is being executed. | 
|  | 286 | dir string | 
|  | 287 |  | 
|  | 288 | // The current prefix string to be pre-appended to the target. | 
|  | 289 | prefix string | 
|  | 290 |  | 
|  | 291 | // ********* Validation ********* | 
|  | 292 | // The expected target to be invoked in ninja. | 
|  | 293 | expectedTarget string | 
|  | 294 | }{{ | 
|  | 295 | description:    "one level directory in source tree", | 
|  | 296 | dir:            "test1", | 
|  | 297 | prefix:         "MODULES-IN-", | 
|  | 298 | expectedTarget: "MODULES-IN-test1", | 
|  | 299 | }, { | 
|  | 300 | description:    "multiple level directories in source tree", | 
|  | 301 | dir:            "test1/test2/test3/test4", | 
|  | 302 | prefix:         "GET-INSTALL-PATH-IN-", | 
|  | 303 | expectedTarget: "GET-INSTALL-PATH-IN-test1-test2-test3-test4", | 
|  | 304 | }} | 
|  | 305 | for _, tt := range tests { | 
|  | 306 | t.Run(tt.description, func(t *testing.T) { | 
|  | 307 | target := convertToTarget(tt.dir, tt.prefix) | 
|  | 308 | if target != tt.expectedTarget { | 
|  | 309 | t.Errorf("expected %s, got %s for target", tt.expectedTarget, target) | 
|  | 310 | } | 
|  | 311 | }) | 
|  | 312 | } | 
|  | 313 | } | 
|  | 314 |  | 
|  | 315 | func setTop(t *testing.T, dir string) func() { | 
|  | 316 | curDir, err := os.Getwd() | 
|  | 317 | if err != nil { | 
|  | 318 | t.Fatalf("failed to get current directory: %v", err) | 
|  | 319 | } | 
|  | 320 | if err := os.Chdir(dir); err != nil { | 
|  | 321 | t.Fatalf("failed to change directory to top dir %s: %v", dir, err) | 
|  | 322 | } | 
|  | 323 | return func() { os.Chdir(curDir) } | 
|  | 324 | } | 
|  | 325 |  | 
|  | 326 | func createBuildFiles(t *testing.T, topDir string, buildFiles []string) { | 
|  | 327 | for _, buildFile := range buildFiles { | 
|  | 328 | buildFile = filepath.Join(topDir, buildFile) | 
|  | 329 | if err := ioutil.WriteFile(buildFile, []byte{}, 0644); err != nil { | 
|  | 330 | t.Errorf("failed to create file %s: %v", buildFile, err) | 
|  | 331 | } | 
|  | 332 | } | 
|  | 333 | } | 
|  | 334 |  | 
|  | 335 | func createDirectories(t *testing.T, topDir string, dirs []string) { | 
|  | 336 | for _, dir := range dirs { | 
|  | 337 | dir = filepath.Join(topDir, dir) | 
|  | 338 | if err := os.MkdirAll(dir, 0755); err != nil { | 
|  | 339 | t.Errorf("failed to create %s directory: %v", dir, err) | 
|  | 340 | } | 
|  | 341 | } | 
|  | 342 | } | 
|  | 343 |  | 
|  | 344 | func TestConfigGetTargets(t *testing.T) { | 
|  | 345 | ctx := testContext() | 
|  | 346 | tests := []struct { | 
|  | 347 | // ********* Setup ********* | 
|  | 348 | // Test description. | 
|  | 349 | description string | 
|  | 350 |  | 
|  | 351 | // Directories that exist in the source tree. | 
|  | 352 | dirsInTrees []string | 
|  | 353 |  | 
|  | 354 | // Build files that exists in the source tree. | 
|  | 355 | buildFiles []string | 
|  | 356 |  | 
|  | 357 | // ********* Action ********* | 
|  | 358 | // Directories passed in to soong_ui. | 
|  | 359 | dirs []string | 
|  | 360 |  | 
|  | 361 | // Current directory that the user executed the build action command. | 
|  | 362 | curDir string | 
|  | 363 |  | 
|  | 364 | // ********* Validation ********* | 
|  | 365 | // Expected targets from the function. | 
|  | 366 | expectedTargets []string | 
|  | 367 |  | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 368 | // Expecting error from running test case. | 
|  | 369 | errStr string | 
|  | 370 | }{{ | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 371 | description:     "one target dir specified", | 
|  | 372 | dirsInTrees:     []string{"0/1/2/3"}, | 
|  | 373 | buildFiles:      []string{"0/1/2/3/Android.bp"}, | 
|  | 374 | dirs:            []string{"1/2/3"}, | 
|  | 375 | curDir:          "0", | 
|  | 376 | expectedTargets: []string{"MODULES-IN-0-1-2-3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 377 | }, { | 
|  | 378 | description: "one target dir specified, build file does not exist", | 
|  | 379 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 380 | buildFiles:  []string{}, | 
|  | 381 | dirs:        []string{"1/2/3"}, | 
|  | 382 | curDir:      "0", | 
|  | 383 | errStr:      "Build file not found for 0/1/2/3 directory", | 
|  | 384 | }, { | 
|  | 385 | description: "one target dir specified, invalid targets specified", | 
|  | 386 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 387 | buildFiles:  []string{}, | 
|  | 388 | dirs:        []string{"1/2/3:t1:t2"}, | 
|  | 389 | curDir:      "0", | 
|  | 390 | errStr:      "1/2/3:t1:t2 not in proper directory:target1,target2,... format (\":\" was specified more than once)", | 
|  | 391 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 392 | description:     "one target dir specified, no targets specified but has colon", | 
|  | 393 | dirsInTrees:     []string{"0/1/2/3"}, | 
|  | 394 | buildFiles:      []string{"0/1/2/3/Android.bp"}, | 
|  | 395 | dirs:            []string{"1/2/3:"}, | 
|  | 396 | curDir:          "0", | 
|  | 397 | expectedTargets: []string{"MODULES-IN-0-1-2-3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 398 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 399 | description:     "one target dir specified, two targets specified", | 
|  | 400 | dirsInTrees:     []string{"0/1/2/3"}, | 
|  | 401 | buildFiles:      []string{"0/1/2/3/Android.bp"}, | 
|  | 402 | dirs:            []string{"1/2/3:t1,t2"}, | 
|  | 403 | curDir:          "0", | 
|  | 404 | expectedTargets: []string{"t1", "t2"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 405 | }, { | 
|  | 406 | description: "one target dir specified, no targets and has a comma", | 
|  | 407 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 408 | buildFiles:  []string{"0/1/2/3/Android.bp"}, | 
|  | 409 | dirs:        []string{"1/2/3:,"}, | 
|  | 410 | curDir:      "0", | 
|  | 411 | errStr:      "0/1/2/3 not in proper directory:target1,target2,... format", | 
|  | 412 | }, { | 
|  | 413 | description: "one target dir specified, improper targets defined", | 
|  | 414 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 415 | buildFiles:  []string{"0/1/2/3/Android.bp"}, | 
|  | 416 | dirs:        []string{"1/2/3:,t1"}, | 
|  | 417 | curDir:      "0", | 
|  | 418 | errStr:      "0/1/2/3 not in proper directory:target1,target2,... format", | 
|  | 419 | }, { | 
|  | 420 | description: "one target dir specified, blank target", | 
|  | 421 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 422 | buildFiles:  []string{"0/1/2/3/Android.bp"}, | 
|  | 423 | dirs:        []string{"1/2/3:t1,"}, | 
|  | 424 | curDir:      "0", | 
|  | 425 | errStr:      "0/1/2/3 not in proper directory:target1,target2,... format", | 
|  | 426 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 427 | description:     "one target dir specified, many targets specified", | 
|  | 428 | dirsInTrees:     []string{"0/1/2/3"}, | 
|  | 429 | buildFiles:      []string{"0/1/2/3/Android.bp"}, | 
|  | 430 | dirs:            []string{"1/2/3:t1,t2,t3,t4,t5,t6,t7,t8,t9,t10"}, | 
|  | 431 | curDir:          "0", | 
|  | 432 | expectedTargets: []string{"t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 433 | }, { | 
|  | 434 | description: "one target dir specified, one target specified, build file does not exist", | 
|  | 435 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 436 | buildFiles:  []string{}, | 
|  | 437 | dirs:        []string{"1/2/3:t1"}, | 
|  | 438 | curDir:      "0", | 
| Patrice Arruda | 9450d0b | 2019-07-08 11:06:46 -0700 | [diff] [blame] | 439 | errStr:      "Couldn't locate a build file from 0/1/2/3 directory", | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 440 | }, { | 
|  | 441 | description: "one target dir specified, one target specified, build file not in target dir", | 
|  | 442 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 443 | buildFiles:  []string{"0/1/2/Android.mk"}, | 
|  | 444 | dirs:        []string{"1/2/3:t1"}, | 
|  | 445 | curDir:      "0", | 
|  | 446 | errStr:      "Couldn't locate a build file from 0/1/2/3 directory", | 
|  | 447 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 448 | description:     "one target dir specified, build file not in target dir", | 
|  | 449 | dirsInTrees:     []string{"0/1/2/3"}, | 
|  | 450 | buildFiles:      []string{"0/1/2/Android.mk"}, | 
|  | 451 | dirs:            []string{"1/2/3"}, | 
|  | 452 | curDir:          "0", | 
|  | 453 | expectedTargets: []string{"MODULES-IN-0-1-2"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 454 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 455 | description:     "multiple targets dir specified, targets specified", | 
|  | 456 | dirsInTrees:     []string{"0/1/2/3", "0/3/4"}, | 
|  | 457 | buildFiles:      []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"}, | 
|  | 458 | dirs:            []string{"1/2/3:t1,t2", "3/4:t3,t4,t5"}, | 
|  | 459 | curDir:          "0", | 
|  | 460 | expectedTargets: []string{"t1", "t2", "t3", "t4", "t5"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 461 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 462 | description:     "multiple targets dir specified, one directory has targets specified", | 
|  | 463 | dirsInTrees:     []string{"0/1/2/3", "0/3/4"}, | 
|  | 464 | buildFiles:      []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"}, | 
|  | 465 | dirs:            []string{"1/2/3:t1,t2", "3/4"}, | 
|  | 466 | curDir:          "0", | 
|  | 467 | expectedTargets: []string{"t1", "t2", "MODULES-IN-0-3-4"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 468 | }, { | 
|  | 469 | description: "two dirs specified, only one dir exist", | 
|  | 470 | dirsInTrees: []string{"0/1/2/3"}, | 
|  | 471 | buildFiles:  []string{"0/1/2/3/Android.mk"}, | 
|  | 472 | dirs:        []string{"1/2/3:t1", "3/4"}, | 
|  | 473 | curDir:      "0", | 
|  | 474 | errStr:      "couldn't find directory 0/3/4", | 
|  | 475 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 476 | description:     "multiple targets dirs specified at root source tree", | 
|  | 477 | dirsInTrees:     []string{"0/1/2/3", "0/3/4"}, | 
|  | 478 | buildFiles:      []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"}, | 
|  | 479 | dirs:            []string{"0/1/2/3:t1,t2", "0/3/4"}, | 
|  | 480 | curDir:          ".", | 
|  | 481 | expectedTargets: []string{"t1", "t2", "MODULES-IN-0-3-4"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 482 | }, { | 
|  | 483 | description: "no directories specified", | 
|  | 484 | dirsInTrees: []string{"0/1/2/3", "0/3/4"}, | 
|  | 485 | buildFiles:  []string{"0/1/2/3/Android.bp", "0/3/4/Android.mk"}, | 
|  | 486 | dirs:        []string{}, | 
|  | 487 | curDir:      ".", | 
|  | 488 | }} | 
|  | 489 | for _, tt := range tests { | 
|  | 490 | t.Run(tt.description, func(t *testing.T) { | 
|  | 491 | defer logger.Recover(func(err error) { | 
|  | 492 | if tt.errStr == "" { | 
|  | 493 | t.Fatalf("Got unexpected error: %v", err) | 
|  | 494 | } | 
|  | 495 | if tt.errStr != err.Error() { | 
|  | 496 | t.Errorf("expected %s, got %s", tt.errStr, err.Error()) | 
|  | 497 | } | 
|  | 498 | }) | 
|  | 499 |  | 
|  | 500 | // Create the root source tree. | 
|  | 501 | topDir, err := ioutil.TempDir("", "") | 
|  | 502 | if err != nil { | 
|  | 503 | t.Fatalf("failed to create temp dir: %v", err) | 
|  | 504 | } | 
|  | 505 | defer os.RemoveAll(topDir) | 
|  | 506 |  | 
|  | 507 | createDirectories(t, topDir, tt.dirsInTrees) | 
|  | 508 | createBuildFiles(t, topDir, tt.buildFiles) | 
|  | 509 | r := setTop(t, topDir) | 
|  | 510 | defer r() | 
|  | 511 |  | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 512 | targets := getTargetsFromDirs(ctx, tt.curDir, tt.dirs, "MODULES-IN-") | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 513 | if !reflect.DeepEqual(targets, tt.expectedTargets) { | 
|  | 514 | t.Errorf("expected %v, got %v for targets", tt.expectedTargets, targets) | 
|  | 515 | } | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 516 |  | 
|  | 517 | // If the execution reached here and there was an expected error code, the unit test case failed. | 
|  | 518 | if tt.errStr != "" { | 
|  | 519 | t.Errorf("expecting error %s", tt.errStr) | 
|  | 520 | } | 
|  | 521 | }) | 
|  | 522 | } | 
|  | 523 | } | 
|  | 524 |  | 
|  | 525 | func TestConfigFindBuildFile(t *testing.T) { | 
|  | 526 | ctx := testContext() | 
|  | 527 |  | 
|  | 528 | tests := []struct { | 
|  | 529 | // ********* Setup ********* | 
|  | 530 | // Test description. | 
|  | 531 | description string | 
|  | 532 |  | 
|  | 533 | // Array of build files to create in dir. | 
|  | 534 | buildFiles []string | 
|  | 535 |  | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 536 | // Directories that exist in the source tree. | 
|  | 537 | dirsInTrees []string | 
|  | 538 |  | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 539 | // ********* Action ********* | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 540 | // The base directory is where findBuildFile is invoked. | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 541 | dir string | 
|  | 542 |  | 
|  | 543 | // ********* Validation ********* | 
|  | 544 | // Expected build file path to find. | 
|  | 545 | expectedBuildFile string | 
|  | 546 | }{{ | 
|  | 547 | description:       "build file exists at leaf directory", | 
|  | 548 | buildFiles:        []string{"1/2/3/Android.bp"}, | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 549 | dirsInTrees:       []string{"1/2/3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 550 | dir:               "1/2/3", | 
|  | 551 | expectedBuildFile: "1/2/3/Android.mk", | 
|  | 552 | }, { | 
|  | 553 | description:       "build file exists in all directory paths", | 
|  | 554 | buildFiles:        []string{"1/Android.mk", "1/2/Android.mk", "1/2/3/Android.mk"}, | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 555 | dirsInTrees:       []string{"1/2/3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 556 | dir:               "1/2/3", | 
|  | 557 | expectedBuildFile: "1/2/3/Android.mk", | 
|  | 558 | }, { | 
|  | 559 | description:       "build file does not exist in all directory paths", | 
|  | 560 | buildFiles:        []string{}, | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 561 | dirsInTrees:       []string{"1/2/3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 562 | dir:               "1/2/3", | 
|  | 563 | expectedBuildFile: "", | 
|  | 564 | }, { | 
|  | 565 | description:       "build file exists only at top directory", | 
|  | 566 | buildFiles:        []string{"Android.bp"}, | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 567 | dirsInTrees:       []string{"1/2/3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 568 | dir:               "1/2/3", | 
|  | 569 | expectedBuildFile: "", | 
|  | 570 | }, { | 
|  | 571 | description:       "build file exist in a subdirectory", | 
|  | 572 | buildFiles:        []string{"1/2/Android.bp"}, | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 573 | dirsInTrees:       []string{"1/2/3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 574 | dir:               "1/2/3", | 
|  | 575 | expectedBuildFile: "1/2/Android.mk", | 
|  | 576 | }, { | 
|  | 577 | description:       "build file exists in a subdirectory", | 
|  | 578 | buildFiles:        []string{"1/Android.mk"}, | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 579 | dirsInTrees:       []string{"1/2/3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 580 | dir:               "1/2/3", | 
|  | 581 | expectedBuildFile: "1/Android.mk", | 
|  | 582 | }, { | 
|  | 583 | description:       "top directory", | 
|  | 584 | buildFiles:        []string{"Android.bp"}, | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 585 | dirsInTrees:       []string{}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 586 | dir:               ".", | 
|  | 587 | expectedBuildFile: "", | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 588 | }, { | 
|  | 589 | description:       "build file exists in subdirectory", | 
|  | 590 | buildFiles:        []string{"1/2/3/Android.bp", "1/2/4/Android.bp"}, | 
|  | 591 | dirsInTrees:       []string{"1/2/3", "1/2/4"}, | 
|  | 592 | dir:               "1/2", | 
|  | 593 | expectedBuildFile: "1/2/Android.mk", | 
|  | 594 | }, { | 
|  | 595 | description:       "build file exists in parent subdirectory", | 
|  | 596 | buildFiles:        []string{"1/5/Android.bp"}, | 
|  | 597 | dirsInTrees:       []string{"1/2/3", "1/2/4", "1/5"}, | 
|  | 598 | dir:               "1/2", | 
|  | 599 | expectedBuildFile: "1/Android.mk", | 
|  | 600 | }, { | 
|  | 601 | description:       "build file exists in deep parent's subdirectory.", | 
|  | 602 | buildFiles:        []string{"1/5/6/Android.bp"}, | 
|  | 603 | dirsInTrees:       []string{"1/2/3", "1/2/4", "1/5/6", "1/5/7"}, | 
|  | 604 | dir:               "1/2", | 
|  | 605 | expectedBuildFile: "1/Android.mk", | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 606 | }} | 
|  | 607 |  | 
|  | 608 | for _, tt := range tests { | 
|  | 609 | t.Run(tt.description, func(t *testing.T) { | 
|  | 610 | defer logger.Recover(func(err error) { | 
|  | 611 | t.Fatalf("Got unexpected error: %v", err) | 
|  | 612 | }) | 
|  | 613 |  | 
|  | 614 | topDir, err := ioutil.TempDir("", "") | 
|  | 615 | if err != nil { | 
|  | 616 | t.Fatalf("failed to create temp dir: %v", err) | 
|  | 617 | } | 
|  | 618 | defer os.RemoveAll(topDir) | 
|  | 619 |  | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 620 | createDirectories(t, topDir, tt.dirsInTrees) | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 621 | createBuildFiles(t, topDir, tt.buildFiles) | 
|  | 622 |  | 
|  | 623 | curDir, err := os.Getwd() | 
|  | 624 | if err != nil { | 
|  | 625 | t.Fatalf("Could not get working directory: %v", err) | 
|  | 626 | } | 
|  | 627 | defer func() { os.Chdir(curDir) }() | 
|  | 628 | if err := os.Chdir(topDir); err != nil { | 
|  | 629 | t.Fatalf("Could not change top dir to %s: %v", topDir, err) | 
|  | 630 | } | 
|  | 631 |  | 
|  | 632 | buildFile := findBuildFile(ctx, tt.dir) | 
|  | 633 | if buildFile != tt.expectedBuildFile { | 
|  | 634 | t.Errorf("expected %q, got %q for build file", tt.expectedBuildFile, buildFile) | 
|  | 635 | } | 
|  | 636 | }) | 
|  | 637 | } | 
|  | 638 | } | 
|  | 639 |  | 
|  | 640 | func TestConfigSplitArgs(t *testing.T) { | 
|  | 641 | tests := []struct { | 
|  | 642 | // ********* Setup ********* | 
|  | 643 | // Test description. | 
|  | 644 | description string | 
|  | 645 |  | 
|  | 646 | // ********* Action ********* | 
|  | 647 | // Arguments passed in to soong_ui. | 
|  | 648 | args []string | 
|  | 649 |  | 
|  | 650 | // ********* Validation ********* | 
|  | 651 | // Expected newArgs list after extracting the directories. | 
|  | 652 | expectedNewArgs []string | 
|  | 653 |  | 
|  | 654 | // Expected directories | 
|  | 655 | expectedDirs []string | 
|  | 656 | }{{ | 
|  | 657 | description:     "flags but no directories specified", | 
|  | 658 | args:            []string{"showcommands", "-j", "-k"}, | 
|  | 659 | expectedNewArgs: []string{"showcommands", "-j", "-k"}, | 
|  | 660 | expectedDirs:    []string{}, | 
|  | 661 | }, { | 
|  | 662 | description:     "flags and one directory specified", | 
|  | 663 | args:            []string{"snod", "-j", "dir:target1,target2"}, | 
|  | 664 | expectedNewArgs: []string{"snod", "-j"}, | 
|  | 665 | expectedDirs:    []string{"dir:target1,target2"}, | 
|  | 666 | }, { | 
|  | 667 | description:     "flags and directories specified", | 
|  | 668 | args:            []string{"dist", "-k", "dir1", "dir2:target1,target2"}, | 
|  | 669 | expectedNewArgs: []string{"dist", "-k"}, | 
|  | 670 | expectedDirs:    []string{"dir1", "dir2:target1,target2"}, | 
|  | 671 | }, { | 
|  | 672 | description:     "only directories specified", | 
|  | 673 | args:            []string{"dir1", "dir2", "dir3:target1,target2"}, | 
|  | 674 | expectedNewArgs: []string{}, | 
|  | 675 | expectedDirs:    []string{"dir1", "dir2", "dir3:target1,target2"}, | 
|  | 676 | }} | 
|  | 677 | for _, tt := range tests { | 
|  | 678 | t.Run(tt.description, func(t *testing.T) { | 
|  | 679 | args, dirs := splitArgs(tt.args) | 
|  | 680 | if !reflect.DeepEqual(tt.expectedNewArgs, args) { | 
|  | 681 | t.Errorf("expected %v, got %v for arguments", tt.expectedNewArgs, args) | 
|  | 682 | } | 
|  | 683 | if !reflect.DeepEqual(tt.expectedDirs, dirs) { | 
|  | 684 | t.Errorf("expected %v, got %v for directories", tt.expectedDirs, dirs) | 
|  | 685 | } | 
|  | 686 | }) | 
|  | 687 | } | 
|  | 688 | } | 
|  | 689 |  | 
|  | 690 | type envVar struct { | 
|  | 691 | name  string | 
|  | 692 | value string | 
|  | 693 | } | 
|  | 694 |  | 
|  | 695 | type buildActionTestCase struct { | 
|  | 696 | // ********* Setup ********* | 
|  | 697 | // Test description. | 
|  | 698 | description string | 
|  | 699 |  | 
|  | 700 | // Directories that exist in the source tree. | 
|  | 701 | dirsInTrees []string | 
|  | 702 |  | 
|  | 703 | // Build files that exists in the source tree. | 
|  | 704 | buildFiles []string | 
|  | 705 |  | 
| Patrice Arruda | baba9a9 | 2019-07-03 10:47:34 -0700 | [diff] [blame] | 706 | // Create root symlink that points to topDir. | 
|  | 707 | rootSymlink bool | 
|  | 708 |  | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 709 | // ********* Action ********* | 
|  | 710 | // Arguments passed in to soong_ui. | 
|  | 711 | args []string | 
|  | 712 |  | 
|  | 713 | // Directory where the build action was invoked. | 
|  | 714 | curDir string | 
|  | 715 |  | 
|  | 716 | // WITH_TIDY_ONLY environment variable specified. | 
|  | 717 | tidyOnly string | 
|  | 718 |  | 
|  | 719 | // ********* Validation ********* | 
|  | 720 | // Expected arguments to be in Config instance. | 
|  | 721 | expectedArgs []string | 
|  | 722 |  | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 723 | // Expecting error from running test case. | 
|  | 724 | expectedErrStr string | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 725 | } | 
|  | 726 |  | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 727 | func testGetConfigArgs(t *testing.T, tt buildActionTestCase, action BuildAction) { | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 728 | ctx := testContext() | 
|  | 729 |  | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 730 | defer logger.Recover(func(err error) { | 
|  | 731 | if tt.expectedErrStr == "" { | 
|  | 732 | t.Fatalf("Got unexpected error: %v", err) | 
|  | 733 | } | 
|  | 734 | if tt.expectedErrStr != err.Error() { | 
|  | 735 | t.Errorf("expected %s, got %s", tt.expectedErrStr, err.Error()) | 
|  | 736 | } | 
|  | 737 | }) | 
|  | 738 |  | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 739 | // Environment variables to set it to blank on every test case run. | 
|  | 740 | resetEnvVars := []string{ | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 741 | "WITH_TIDY_ONLY", | 
|  | 742 | } | 
|  | 743 |  | 
|  | 744 | for _, name := range resetEnvVars { | 
|  | 745 | if err := os.Unsetenv(name); err != nil { | 
|  | 746 | t.Fatalf("failed to unset environment variable %s: %v", name, err) | 
|  | 747 | } | 
|  | 748 | } | 
|  | 749 | if tt.tidyOnly != "" { | 
|  | 750 | if err := os.Setenv("WITH_TIDY_ONLY", tt.tidyOnly); err != nil { | 
|  | 751 | t.Errorf("failed to set WITH_TIDY_ONLY to %s: %v", tt.tidyOnly, err) | 
|  | 752 | } | 
|  | 753 | } | 
|  | 754 |  | 
|  | 755 | // Create the root source tree. | 
|  | 756 | topDir, err := ioutil.TempDir("", "") | 
|  | 757 | if err != nil { | 
|  | 758 | t.Fatalf("failed to create temp dir: %v", err) | 
|  | 759 | } | 
|  | 760 | defer os.RemoveAll(topDir) | 
|  | 761 |  | 
|  | 762 | createDirectories(t, topDir, tt.dirsInTrees) | 
|  | 763 | createBuildFiles(t, topDir, tt.buildFiles) | 
|  | 764 |  | 
| Patrice Arruda | baba9a9 | 2019-07-03 10:47:34 -0700 | [diff] [blame] | 765 | if tt.rootSymlink { | 
|  | 766 | // Create a secondary root source tree which points to the true root source tree. | 
|  | 767 | symlinkTopDir, err := ioutil.TempDir("", "") | 
|  | 768 | if err != nil { | 
|  | 769 | t.Fatalf("failed to create symlink temp dir: %v", err) | 
|  | 770 | } | 
|  | 771 | defer os.RemoveAll(symlinkTopDir) | 
|  | 772 |  | 
|  | 773 | symlinkTopDir = filepath.Join(symlinkTopDir, "root") | 
|  | 774 | err = os.Symlink(topDir, symlinkTopDir) | 
|  | 775 | if err != nil { | 
|  | 776 | t.Fatalf("failed to create symlink: %v", err) | 
|  | 777 | } | 
|  | 778 | topDir = symlinkTopDir | 
|  | 779 | } | 
|  | 780 |  | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 781 | r := setTop(t, topDir) | 
|  | 782 | defer r() | 
|  | 783 |  | 
|  | 784 | // The next block is to create the root build file. | 
|  | 785 | rootBuildFileDir := filepath.Dir(srcDirFileCheck) | 
|  | 786 | if err := os.MkdirAll(rootBuildFileDir, 0755); err != nil { | 
|  | 787 | t.Fatalf("Failed to create %s directory: %v", rootBuildFileDir, err) | 
|  | 788 | } | 
|  | 789 |  | 
|  | 790 | if err := ioutil.WriteFile(srcDirFileCheck, []byte{}, 0644); err != nil { | 
|  | 791 | t.Fatalf("failed to create %s file: %v", srcDirFileCheck, err) | 
|  | 792 | } | 
|  | 793 |  | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 794 | args := getConfigArgs(action, tt.curDir, ctx, tt.args) | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 795 | if !reflect.DeepEqual(tt.expectedArgs, args) { | 
|  | 796 | t.Fatalf("expected %v, got %v for config arguments", tt.expectedArgs, args) | 
|  | 797 | } | 
|  | 798 |  | 
| Patrice Arruda | 0dcf27f | 2019-07-08 17:03:33 -0700 | [diff] [blame] | 799 | // If the execution reached here and there was an expected error code, the unit test case failed. | 
|  | 800 | if tt.expectedErrStr != "" { | 
|  | 801 | t.Errorf("expecting error %s", tt.expectedErrStr) | 
|  | 802 | } | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 803 | } | 
|  | 804 |  | 
| Patrice Arruda | 3928206 | 2019-06-20 16:35:12 -0700 | [diff] [blame] | 805 | func TestGetConfigArgsBuildModules(t *testing.T) { | 
|  | 806 | tests := []buildActionTestCase{{ | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 807 | description:  "normal execution from the root source tree directory", | 
|  | 808 | dirsInTrees:  []string{"0/1/2", "0/2", "0/3"}, | 
|  | 809 | buildFiles:   []string{"0/1/2/Android.mk", "0/2/Android.bp", "0/3/Android.mk"}, | 
|  | 810 | args:         []string{"-j", "fake_module", "fake_module2"}, | 
|  | 811 | curDir:       ".", | 
|  | 812 | tidyOnly:     "", | 
|  | 813 | expectedArgs: []string{"-j", "fake_module", "fake_module2"}, | 
| Patrice Arruda | 3928206 | 2019-06-20 16:35:12 -0700 | [diff] [blame] | 814 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 815 | description:  "normal execution in deep directory", | 
|  | 816 | dirsInTrees:  []string{"0/1/2", "0/2", "0/3", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6"}, | 
|  | 817 | 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"}, | 
|  | 818 | args:         []string{"-j", "fake_module", "fake_module2", "-k"}, | 
|  | 819 | curDir:       "1/2/3/4/5/6/7/8/9", | 
|  | 820 | tidyOnly:     "", | 
|  | 821 | expectedArgs: []string{"-j", "fake_module", "fake_module2", "-k"}, | 
| Patrice Arruda | 3928206 | 2019-06-20 16:35:12 -0700 | [diff] [blame] | 822 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 823 | description:  "normal execution in deep directory, no targets", | 
|  | 824 | dirsInTrees:  []string{"0/1/2", "0/2", "0/3", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6"}, | 
|  | 825 | 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"}, | 
|  | 826 | args:         []string{"-j", "-k"}, | 
|  | 827 | curDir:       "1/2/3/4/5/6/7/8/9", | 
|  | 828 | tidyOnly:     "", | 
|  | 829 | expectedArgs: []string{"-j", "-k"}, | 
| Patrice Arruda | 3928206 | 2019-06-20 16:35:12 -0700 | [diff] [blame] | 830 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 831 | description:  "normal execution in root source tree, no args", | 
|  | 832 | dirsInTrees:  []string{"0/1/2", "0/2", "0/3"}, | 
|  | 833 | buildFiles:   []string{"0/1/2/Android.mk", "0/2/Android.bp"}, | 
|  | 834 | args:         []string{}, | 
|  | 835 | curDir:       "0/2", | 
|  | 836 | tidyOnly:     "", | 
|  | 837 | expectedArgs: []string{}, | 
| Patrice Arruda | baba9a9 | 2019-07-03 10:47:34 -0700 | [diff] [blame] | 838 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 839 | description:  "normal execution in symlink root source tree, no args", | 
|  | 840 | dirsInTrees:  []string{"0/1/2", "0/2", "0/3"}, | 
|  | 841 | buildFiles:   []string{"0/1/2/Android.mk", "0/2/Android.bp"}, | 
|  | 842 | rootSymlink:  true, | 
|  | 843 | args:         []string{}, | 
|  | 844 | curDir:       "0/2", | 
|  | 845 | tidyOnly:     "", | 
|  | 846 | expectedArgs: []string{}, | 
| Patrice Arruda | 3928206 | 2019-06-20 16:35:12 -0700 | [diff] [blame] | 847 | }} | 
|  | 848 | for _, tt := range tests { | 
|  | 849 | t.Run("build action BUILD_MODULES with dependencies, "+tt.description, func(t *testing.T) { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 850 | testGetConfigArgs(t, tt, BUILD_MODULES) | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 851 | }) | 
|  | 852 | } | 
|  | 853 | } | 
|  | 854 |  | 
|  | 855 | func TestGetConfigArgsBuildModulesInDirectory(t *testing.T) { | 
|  | 856 | tests := []buildActionTestCase{{ | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 857 | description:  "normal execution in a directory", | 
|  | 858 | dirsInTrees:  []string{"0/1/2"}, | 
|  | 859 | buildFiles:   []string{"0/1/2/Android.mk"}, | 
|  | 860 | args:         []string{"fake-module"}, | 
|  | 861 | curDir:       "0/1/2", | 
|  | 862 | tidyOnly:     "", | 
|  | 863 | expectedArgs: []string{"fake-module", "MODULES-IN-0-1-2"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 864 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 865 | description:  "build file in parent directory", | 
|  | 866 | dirsInTrees:  []string{"0/1/2"}, | 
|  | 867 | buildFiles:   []string{"0/1/Android.mk"}, | 
|  | 868 | args:         []string{}, | 
|  | 869 | curDir:       "0/1/2", | 
|  | 870 | tidyOnly:     "", | 
|  | 871 | expectedArgs: []string{"MODULES-IN-0-1"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 872 | }, | 
|  | 873 | { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 874 | description:  "build file in parent directory, multiple module names passed in", | 
|  | 875 | dirsInTrees:  []string{"0/1/2"}, | 
|  | 876 | buildFiles:   []string{"0/1/Android.mk"}, | 
|  | 877 | args:         []string{"fake-module1", "fake-module2", "fake-module3"}, | 
|  | 878 | curDir:       "0/1/2", | 
|  | 879 | tidyOnly:     "", | 
|  | 880 | expectedArgs: []string{"fake-module1", "fake-module2", "fake-module3", "MODULES-IN-0-1"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 881 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 882 | description:  "build file in 2nd level parent directory", | 
|  | 883 | dirsInTrees:  []string{"0/1/2"}, | 
|  | 884 | buildFiles:   []string{"0/Android.bp"}, | 
|  | 885 | args:         []string{}, | 
|  | 886 | curDir:       "0/1/2", | 
|  | 887 | tidyOnly:     "", | 
|  | 888 | expectedArgs: []string{"MODULES-IN-0"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 889 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 890 | description:  "build action executed at root directory", | 
|  | 891 | dirsInTrees:  []string{}, | 
|  | 892 | buildFiles:   []string{}, | 
|  | 893 | rootSymlink:  false, | 
|  | 894 | args:         []string{}, | 
|  | 895 | curDir:       ".", | 
|  | 896 | tidyOnly:     "", | 
|  | 897 | expectedArgs: []string{}, | 
| Patrice Arruda | baba9a9 | 2019-07-03 10:47:34 -0700 | [diff] [blame] | 898 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 899 | description:  "build action executed at root directory in symlink", | 
|  | 900 | dirsInTrees:  []string{}, | 
|  | 901 | buildFiles:   []string{}, | 
|  | 902 | rootSymlink:  true, | 
|  | 903 | args:         []string{}, | 
|  | 904 | curDir:       ".", | 
|  | 905 | tidyOnly:     "", | 
|  | 906 | expectedArgs: []string{}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 907 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 908 | description:    "build file not found", | 
|  | 909 | dirsInTrees:    []string{"0/1/2"}, | 
|  | 910 | buildFiles:     []string{}, | 
|  | 911 | args:           []string{}, | 
|  | 912 | curDir:         "0/1/2", | 
|  | 913 | tidyOnly:       "", | 
|  | 914 | expectedArgs:   []string{"MODULES-IN-0-1-2"}, | 
|  | 915 | expectedErrStr: "Build file not found for 0/1/2 directory", | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 916 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 917 | description:  "GET-INSTALL-PATH specified,", | 
|  | 918 | dirsInTrees:  []string{"0/1/2"}, | 
|  | 919 | buildFiles:   []string{"0/1/Android.mk"}, | 
|  | 920 | args:         []string{"GET-INSTALL-PATH", "-j", "-k", "GET-INSTALL-PATH"}, | 
|  | 921 | curDir:       "0/1/2", | 
|  | 922 | tidyOnly:     "", | 
|  | 923 | expectedArgs: []string{"-j", "-k", "GET-INSTALL-PATH-IN-0-1"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 924 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 925 | description:  "tidy only environment variable specified,", | 
|  | 926 | dirsInTrees:  []string{"0/1/2"}, | 
|  | 927 | buildFiles:   []string{"0/1/Android.mk"}, | 
|  | 928 | args:         []string{"GET-INSTALL-PATH"}, | 
|  | 929 | curDir:       "0/1/2", | 
|  | 930 | tidyOnly:     "true", | 
|  | 931 | expectedArgs: []string{"tidy_only"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 932 | }, { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 933 | description:  "normal execution in root directory with args", | 
|  | 934 | dirsInTrees:  []string{}, | 
|  | 935 | buildFiles:   []string{}, | 
|  | 936 | args:         []string{"-j", "-k", "fake_module"}, | 
|  | 937 | curDir:       "", | 
|  | 938 | tidyOnly:     "", | 
|  | 939 | expectedArgs: []string{"-j", "-k", "fake_module"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 940 | }} | 
|  | 941 | for _, tt := range tests { | 
|  | 942 | t.Run("build action BUILD_MODULES_IN_DIR, "+tt.description, func(t *testing.T) { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 943 | testGetConfigArgs(t, tt, BUILD_MODULES_IN_A_DIRECTORY) | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 944 | }) | 
|  | 945 | } | 
|  | 946 | } | 
|  | 947 |  | 
|  | 948 | func TestGetConfigArgsBuildModulesInDirectories(t *testing.T) { | 
|  | 949 | tests := []buildActionTestCase{{ | 
|  | 950 | description:  "normal execution in a directory", | 
|  | 951 | dirsInTrees:  []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"}, | 
|  | 952 | buildFiles:   []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"}, | 
|  | 953 | args:         []string{"3.1/", "3.2/", "3.3/"}, | 
|  | 954 | curDir:       "0/1/2", | 
|  | 955 | tidyOnly:     "", | 
|  | 956 | expectedArgs: []string{"MODULES-IN-0-1-2-3.1", "MODULES-IN-0-1-2-3.2", "MODULES-IN-0-1-2-3.3"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 957 | }, { | 
|  | 958 | description:  "GET-INSTALL-PATH specified", | 
|  | 959 | dirsInTrees:  []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3"}, | 
|  | 960 | buildFiles:   []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/Android.bp"}, | 
|  | 961 | args:         []string{"GET-INSTALL-PATH", "2/3.1/", "2/3.2", "3"}, | 
|  | 962 | curDir:       "0/1", | 
|  | 963 | tidyOnly:     "", | 
|  | 964 | 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"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 965 | }, { | 
|  | 966 | description:  "tidy only environment variable specified", | 
|  | 967 | dirsInTrees:  []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/2/3.3"}, | 
|  | 968 | buildFiles:   []string{"0/1/2/3.1/Android.bp", "0/1/2/3.2/Android.bp", "0/1/2/3.3/Android.bp"}, | 
|  | 969 | args:         []string{"GET-INSTALL-PATH", "3.1/", "3.2/", "3.3"}, | 
|  | 970 | curDir:       "0/1/2", | 
|  | 971 | tidyOnly:     "1", | 
|  | 972 | expectedArgs: []string{"tidy_only"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 973 | }, { | 
|  | 974 | description:  "normal execution from top dir directory", | 
|  | 975 | dirsInTrees:  []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"}, | 
|  | 976 | 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 Arruda | baba9a9 | 2019-07-03 10:47:34 -0700 | [diff] [blame] | 977 | rootSymlink:  false, | 
|  | 978 | args:         []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"}, | 
|  | 979 | curDir:       ".", | 
|  | 980 | tidyOnly:     "", | 
|  | 981 | 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"}, | 
| Patrice Arruda | baba9a9 | 2019-07-03 10:47:34 -0700 | [diff] [blame] | 982 | }, { | 
|  | 983 | description:  "normal execution from top dir directory in symlink", | 
|  | 984 | dirsInTrees:  []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"}, | 
|  | 985 | 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"}, | 
|  | 986 | rootSymlink:  true, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 987 | args:         []string{"0/1/2/3.1", "0/1/2/3.2", "0/1/3", "0/2"}, | 
|  | 988 | curDir:       ".", | 
|  | 989 | tidyOnly:     "", | 
|  | 990 | 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"}, | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 991 | }} | 
|  | 992 | for _, tt := range tests { | 
|  | 993 | t.Run("build action BUILD_MODULES_IN_DIRS, "+tt.description, func(t *testing.T) { | 
| Dan Willemsen | ce41e94 | 2019-07-29 23:39:30 -0700 | [diff] [blame] | 994 | testGetConfigArgs(t, tt, BUILD_MODULES_IN_DIRECTORIES) | 
| Patrice Arruda | 1384822 | 2019-04-22 17:12:02 -0700 | [diff] [blame] | 995 | }) | 
|  | 996 | } | 
|  | 997 | } |