// Copyright 2015 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package android import ( "testing" ) func TestSrcIsModule(t *testing.T) { type args struct { s string } tests := []struct { name string args args wantModule string }{ { name: "file", args: args{ s: "foo", }, wantModule: "", }, { name: "module", args: args{ s: ":foo", }, wantModule: "foo", }, { name: "tag", args: args{ s: ":foo{.bar}", }, wantModule: "foo{.bar}", }, { name: "extra colon", args: args{ s: ":foo:bar", }, wantModule: "foo:bar", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if gotModule := SrcIsModule(tt.args.s); gotModule != tt.wantModule { t.Errorf("SrcIsModule() = %v, want %v", gotModule, tt.wantModule) } }) } } func TestSrcIsModuleWithTag(t *testing.T) { type args struct { s string } tests := []struct { name string args args wantModule string wantTag string }{ { name: "file", args: args{ s: "foo", }, wantModule: "", wantTag: "", }, { name: "module", args: args{ s: ":foo", }, wantModule: "foo", wantTag: "", }, { name: "tag", args: args{ s: ":foo{.bar}", }, wantModule: "foo", wantTag: ".bar", }, { name: "empty tag", args: args{ s: ":foo{}", }, wantModule: "foo", wantTag: "", }, { name: "extra colon", args: args{ s: ":foo:bar", }, wantModule: "foo:bar", }, { name: "invalid tag", args: args{ s: ":foo{.bar", }, wantModule: "foo{.bar", }, { name: "invalid tag 2", args: args{ s: ":foo.bar}", }, wantModule: "foo.bar}", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotModule, gotTag := SrcIsModuleWithTag(tt.args.s) if gotModule != tt.wantModule { t.Errorf("SrcIsModuleWithTag() gotModule = %v, want %v", gotModule, tt.wantModule) } if gotTag != tt.wantTag { t.Errorf("SrcIsModuleWithTag() gotTag = %v, want %v", gotTag, tt.wantTag) } }) } } type depsModule struct { ModuleBase props struct { Deps []string } } func (m *depsModule) GenerateAndroidBuildActions(ctx ModuleContext) { } func (m *depsModule) DepsMutator(ctx BottomUpMutatorContext) { ctx.AddDependency(ctx.Module(), nil, m.props.Deps...) } func depsModuleFactory() Module { m := &depsModule{} m.AddProperties(&m.props) InitAndroidModule(m) return m } var prepareForModuleTests = FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("deps", depsModuleFactory) }) func TestErrorDependsOnDisabledModule(t *testing.T) { bp := ` deps { name: "foo", deps: ["bar"], } deps { name: "bar", enabled: false, } ` prepareForModuleTests. ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": depends on disabled module "bar"`)). RunTestWithBp(t, bp) } func TestValidateCorrectBuildParams(t *testing.T) { config := TestConfig(t.TempDir(), nil, "", nil) pathContext := PathContextForTesting(config) bparams := convertBuildParams(BuildParams{ // Test with Output Output: PathForOutput(pathContext, "undeclared_symlink"), SymlinkOutput: PathForOutput(pathContext, "undeclared_symlink"), }) err := validateBuildParams(bparams) if err != nil { t.Error(err) } bparams = convertBuildParams(BuildParams{ // Test with ImplicitOutput ImplicitOutput: PathForOutput(pathContext, "undeclared_symlink"), SymlinkOutput: PathForOutput(pathContext, "undeclared_symlink"), }) err = validateBuildParams(bparams) if err != nil { t.Error(err) } } func TestValidateIncorrectBuildParams(t *testing.T) { config := TestConfig(t.TempDir(), nil, "", nil) pathContext := PathContextForTesting(config) params := BuildParams{ Output: PathForOutput(pathContext, "regular_output"), Outputs: PathsForOutput(pathContext, []string{"out1", "out2"}), ImplicitOutput: PathForOutput(pathContext, "implicit_output"), ImplicitOutputs: PathsForOutput(pathContext, []string{"i_out1", "_out2"}), SymlinkOutput: PathForOutput(pathContext, "undeclared_symlink"), } bparams := convertBuildParams(params) err := validateBuildParams(bparams) if err != nil { FailIfNoMatchingErrors(t, "undeclared_symlink is not a declared output or implicit output", []error{err}) } else { t.Errorf("Expected build params to fail validation: %+v", bparams) } } func TestDistErrorChecking(t *testing.T) { bp := ` deps { name: "foo", dist: { dest: "../invalid-dest", dir: "../invalid-dir", suffix: "invalid/suffix", }, dists: [ { dest: "../invalid-dest0", dir: "../invalid-dir0", suffix: "invalid/suffix0", }, { dest: "../invalid-dest1", dir: "../invalid-dir1", suffix: "invalid/suffix1", }, ], } ` expectedErrs := []string{ "\\QAndroid.bp:5:13: module \"foo\": dist.dest: Path is outside directory: ../invalid-dest\\E", "\\QAndroid.bp:6:12: module \"foo\": dist.dir: Path is outside directory: ../invalid-dir\\E", "\\QAndroid.bp:7:15: module \"foo\": dist.suffix: Suffix may not contain a '/' character.\\E", "\\QAndroid.bp:11:15: module \"foo\": dists[0].dest: Path is outside directory: ../invalid-dest0\\E", "\\QAndroid.bp:12:14: module \"foo\": dists[0].dir: Path is outside directory: ../invalid-dir0\\E", "\\QAndroid.bp:13:17: module \"foo\": dists[0].suffix: Suffix may not contain a '/' character.\\E", "\\QAndroid.bp:16:15: module \"foo\": dists[1].dest: Path is outside directory: ../invalid-dest1\\E", "\\QAndroid.bp:17:14: module \"foo\": dists[1].dir: Path is outside directory: ../invalid-dir1\\E", "\\QAndroid.bp:18:17: module \"foo\": dists[1].suffix: Suffix may not contain a '/' character.\\E", } prepareForModuleTests. ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(expectedErrs)). RunTestWithBp(t, bp) }