| // Copyright 2017 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 java |
| |
| import ( |
| "android/soong/android" |
| "fmt" |
| "io/ioutil" |
| "os" |
| "path/filepath" |
| "strings" |
| "testing" |
| ) |
| |
| var buildDir string |
| |
| func setUp() { |
| var err error |
| buildDir, err = ioutil.TempDir("", "soong_java_test") |
| if err != nil { |
| panic(err) |
| } |
| } |
| |
| func tearDown() { |
| os.RemoveAll(buildDir) |
| } |
| |
| func TestMain(m *testing.M) { |
| run := func() int { |
| setUp() |
| defer tearDown() |
| |
| return m.Run() |
| } |
| |
| os.Exit(run()) |
| } |
| |
| func testJava(t *testing.T, bp string) *android.TestContext { |
| config := android.TestConfig(buildDir) |
| |
| ctx := android.NewTestContext() |
| ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory)) |
| ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory)) |
| ctx.RegisterModuleType("java_prebuilt_library", android.ModuleFactoryAdaptor(PrebuiltFactory)) |
| ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory)) |
| ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) |
| ctx.Register() |
| |
| extraModules := []string{"core-libart", "frameworks", "sdk_v14"} |
| |
| for _, extra := range extraModules { |
| bp += fmt.Sprintf(` |
| java_library { |
| name: "%s", |
| no_standard_libraries: true, |
| } |
| `, extra) |
| } |
| |
| ctx.MockFileSystem(map[string][]byte{ |
| "Android.bp": []byte(bp), |
| "a.java": nil, |
| "b.java": nil, |
| "c.java": nil, |
| "a.jar": nil, |
| "b.jar": nil, |
| }) |
| |
| _, errs := ctx.ParseBlueprintsFiles("Android.bp") |
| fail(t, errs) |
| _, errs = ctx.PrepareBuildActions(config) |
| fail(t, errs) |
| |
| return ctx |
| } |
| |
| func TestSimple(t *testing.T) { |
| ctx := testJava(t, ` |
| java_library { |
| name: "foo", |
| srcs: ["a.java"], |
| libs: ["bar"], |
| static_libs: ["baz"], |
| } |
| |
| java_library { |
| name: "bar", |
| srcs: ["b.java"], |
| } |
| |
| java_library { |
| name: "baz", |
| srcs: ["c.java"], |
| } |
| `) |
| |
| javac := ctx.ModuleForTests("foo", "").Rule("javac") |
| jar := ctx.ModuleForTests("foo", "").Rule("jar") |
| |
| if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { |
| t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) |
| } |
| |
| bar := filepath.Join(buildDir, ".intermediates", "bar", "classes-full-debug.jar") |
| if !strings.Contains(javac.Args["classpath"], bar) { |
| t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar) |
| } |
| |
| baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.list") |
| if !strings.Contains(jar.Args["jarArgs"], baz) { |
| t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz) |
| } |
| } |
| |
| func TestSdk(t *testing.T) { |
| ctx := testJava(t, ` |
| java_library { |
| name: "foo1", |
| srcs: ["a.java"], |
| } |
| |
| java_library { |
| name: "foo2", |
| srcs: ["a.java"], |
| sdk_version: "", |
| } |
| |
| java_library { |
| name: "foo3", |
| srcs: ["a.java"], |
| sdk_version: "14", |
| } |
| |
| java_library { |
| name: "foo4", |
| srcs: ["a.java"], |
| sdk_version: "current", |
| } |
| |
| java_library { |
| name: "foo5", |
| srcs: ["a.java"], |
| sdk_version: "system_current", |
| } |
| |
| java_library { |
| name: "foo6", |
| srcs: ["a.java"], |
| sdk_version: "test_current", |
| } |
| `) |
| |
| type depType int |
| const ( |
| staticLib = iota |
| classpathLib |
| bootclasspathLib |
| ) |
| |
| check := func(module, dep string, depType depType) { |
| if dep != "" { |
| dep = filepath.Join(buildDir, ".intermediates", dep, "classes-full-debug.jar") |
| } |
| |
| javac := ctx.ModuleForTests(module, "").Rule("javac") |
| |
| if depType == bootclasspathLib { |
| got := strings.TrimPrefix(javac.Args["bootClasspath"], "-bootclasspath ") |
| if got != dep { |
| t.Errorf("module %q bootclasspath %q != %q", module, got, dep) |
| } |
| } else if depType == classpathLib { |
| got := strings.TrimPrefix(javac.Args["classpath"], "-classpath ") |
| if got != dep { |
| t.Errorf("module %q classpath %q != %q", module, got, dep) |
| } |
| } |
| |
| if len(javac.Implicits) != 1 || javac.Implicits[0].String() != dep { |
| t.Errorf("module %q implicits != [%q]", dep) |
| } |
| } |
| |
| check("foo1", "core-libart", bootclasspathLib) |
| } |
| |
| func TestPrebuilts(t *testing.T) { |
| ctx := testJava(t, ` |
| java_library { |
| name: "foo", |
| srcs: ["a.java"], |
| libs: ["bar"], |
| static_libs: ["baz"], |
| } |
| |
| java_prebuilt_library { |
| name: "bar", |
| srcs: ["a.jar"], |
| } |
| |
| java_prebuilt_library { |
| name: "baz", |
| srcs: ["b.jar"], |
| } |
| `) |
| |
| javac := ctx.ModuleForTests("foo", "").Rule("javac") |
| jar := ctx.ModuleForTests("foo", "").Rule("jar") |
| |
| bar := "a.jar" |
| if !strings.Contains(javac.Args["classpath"], bar) { |
| t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar) |
| } |
| |
| baz := filepath.Join(buildDir, ".intermediates", "baz", "extracted", "classes.list") |
| if !strings.Contains(jar.Args["jarArgs"], baz) { |
| t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz) |
| } |
| } |
| |
| func TestDefaults(t *testing.T) { |
| ctx := testJava(t, ` |
| java_defaults { |
| name: "defaults", |
| srcs: ["a.java"], |
| libs: ["bar"], |
| static_libs: ["baz"], |
| } |
| |
| java_library { |
| name: "foo", |
| defaults: ["defaults"], |
| } |
| |
| java_library { |
| name: "bar", |
| srcs: ["b.java"], |
| } |
| |
| java_library { |
| name: "baz", |
| srcs: ["c.java"], |
| } |
| `) |
| |
| javac := ctx.ModuleForTests("foo", "").Rule("javac") |
| jar := ctx.ModuleForTests("foo", "").Rule("jar") |
| |
| if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { |
| t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) |
| } |
| |
| bar := filepath.Join(buildDir, ".intermediates", "bar", "classes-full-debug.jar") |
| if !strings.Contains(javac.Args["classpath"], bar) { |
| t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar) |
| } |
| |
| baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.list") |
| if !strings.Contains(jar.Args["jarArgs"], baz) { |
| t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz) |
| } |
| } |
| |
| func fail(t *testing.T, errs []error) { |
| if len(errs) > 0 { |
| for _, err := range errs { |
| t.Error(err) |
| } |
| t.FailNow() |
| } |
| } |