// 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_import", android.ModuleFactoryAdaptor(ImportFactory)) ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory)) ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators) ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators) 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_import { name: "bar", jars: ["a.jar"], } java_import { name: "baz", jars: ["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", "extracted0", "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() } }