| // Copyright 2018 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 ( |
| "reflect" |
| "testing" |
| |
| "android/soong/android" |
| ) |
| |
| func TestJarGenruleCombinerSingle(t *testing.T) { |
| t.Parallel() |
| t.Helper() |
| ctx := prepareForJavaTest.RunTestWithBp(t, ` |
| java_library { |
| name: "foo", |
| srcs: ["a.java"], |
| } |
| |
| java_genrule { |
| name: "gen", |
| tool_files: ["b.java"], |
| cmd: "$(location b.java) $(in) $(out)", |
| out: ["gen.jar"], |
| srcs: [":foo"], |
| } |
| |
| java_genrule_combiner { |
| name: "jarcomb", |
| static_libs: ["gen"], |
| headers: ["foo"], |
| } |
| |
| java_library { |
| name: "bar", |
| static_libs: ["jarcomb"], |
| srcs: ["c.java"], |
| } |
| |
| java_library { |
| name: "baz", |
| libs: ["jarcomb"], |
| srcs: ["c.java"], |
| } |
| `).TestContext |
| |
| fooMod := ctx.ModuleForTests(t, "foo", "android_common") |
| fooCombined := fooMod.Output("turbine-combined/foo.jar") |
| fooOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), fooMod.Module(), android.OutputFilesProvider) |
| fooHeaderJars := fooOutputFiles.TaggedOutputFiles[".hjar"] |
| |
| genMod := ctx.ModuleForTests(t, "gen", "android_common") |
| gen := genMod.Output("gen.jar") |
| |
| jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common") |
| jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider) |
| jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider) |
| |
| // Confirm that jarcomb simply forwards the jarcomb implementation and the foo headers. |
| if len(jarcombOutputFiles.DefaultOutputFiles) != 1 || |
| android.PathRelativeToTop(jarcombOutputFiles.DefaultOutputFiles[0]) != android.PathRelativeToTop(gen.Output) { |
| t.Errorf("jarcomb Implementation %v is not [%q]", |
| android.PathsRelativeToTop(jarcombOutputFiles.DefaultOutputFiles), android.PathRelativeToTop(gen.Output)) |
| } |
| jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"] |
| if !reflect.DeepEqual(jarcombHeaderJars, fooHeaderJars) { |
| t.Errorf("jarcomb Header jar %v is not %q", |
| jarcombHeaderJars, fooHeaderJars) |
| } |
| |
| // Confirm that JavaInfoProvider agrees. |
| if len(jarcombInfo.ImplementationJars) != 1 || |
| android.PathRelativeToTop(jarcombInfo.ImplementationJars[0]) != android.PathRelativeToTop(gen.Output) { |
| t.Errorf("jarcomb ImplementationJars %v is not [%q]", |
| android.PathsRelativeToTop(jarcombInfo.ImplementationJars), android.PathRelativeToTop(gen.Output)) |
| } |
| if len(jarcombInfo.HeaderJars) != 1 || |
| android.PathRelativeToTop(jarcombInfo.HeaderJars[0]) != android.PathRelativeToTop(fooCombined.Output) { |
| t.Errorf("jarcomb HeaderJars %v is not [%q]", |
| android.PathsRelativeToTop(jarcombInfo.HeaderJars), android.PathRelativeToTop(fooCombined.Output)) |
| } |
| |
| barMod := ctx.ModuleForTests(t, "bar", "android_common") |
| bar := barMod.Output("javac/bar.jar") |
| barCombined := barMod.Output("combined/bar.jar") |
| |
| // Confirm that bar uses the Implementation from gen and headerJars from foo. |
| if len(barCombined.Inputs) != 2 || |
| barCombined.Inputs[0].String() != bar.Output.String() || |
| barCombined.Inputs[1].String() != gen.Output.String() { |
| t.Errorf("bar combined jar inputs %v is not [%q, %q]", |
| barCombined.Inputs.Strings(), bar.Output.String(), gen.Output.String()) |
| } |
| |
| bazMod := ctx.ModuleForTests(t, "baz", "android_common") |
| baz := bazMod.Output("javac/baz.jar") |
| |
| string_in_list := func(s string, l []string) bool { |
| for _, v := range l { |
| if s == v { |
| return true |
| } |
| } |
| return false |
| } |
| |
| // Confirm that baz uses the headerJars from foo. |
| bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits) |
| for _, v := range android.PathsRelativeToTop(fooHeaderJars) { |
| if !string_in_list(v, bazImplicitsRel) { |
| t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v) |
| } |
| } |
| } |
| |
| func TestJarGenruleCombinerMulti(t *testing.T) { |
| t.Parallel() |
| t.Helper() |
| ctx := prepareForJavaTest.RunTestWithBp(t, ` |
| java_library { |
| name: "foo1", |
| srcs: ["foo1_a.java"], |
| } |
| |
| java_library { |
| name: "foo2", |
| srcs: ["foo2_a.java"], |
| } |
| |
| java_genrule { |
| name: "gen1", |
| tool_files: ["b.java"], |
| cmd: "$(location b.java) $(in) $(out)", |
| out: ["gen1.jar"], |
| srcs: [":foo1"], |
| } |
| |
| java_genrule { |
| name: "gen2", |
| tool_files: ["b.java"], |
| cmd: "$(location b.java) $(in) $(out)", |
| out: ["gen2.jar"], |
| srcs: [":foo2"], |
| } |
| |
| // Combine multiple java_genrule modules. |
| java_genrule_combiner { |
| name: "jarcomb", |
| static_libs: ["gen1", "gen2"], |
| headers: ["foo1", "foo2"], |
| } |
| |
| java_library { |
| name: "bar", |
| static_libs: ["jarcomb"], |
| srcs: ["c.java"], |
| } |
| |
| java_library { |
| name: "baz", |
| libs: ["jarcomb"], |
| srcs: ["c.java"], |
| } |
| `).TestContext |
| |
| gen1Mod := ctx.ModuleForTests(t, "gen1", "android_common") |
| gen1 := gen1Mod.Output("gen1.jar") |
| gen2Mod := ctx.ModuleForTests(t, "gen2", "android_common") |
| gen2 := gen2Mod.Output("gen2.jar") |
| |
| jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common") |
| jarcomb := jarcombMod.Output("combined/jarcomb.jar") |
| jarcombTurbine := jarcombMod.Output("turbine-combined/jarcomb.jar") |
| _ = jarcombTurbine |
| jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider) |
| _ = jarcombInfo |
| jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider) |
| jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"] |
| |
| if len(jarcomb.Inputs) != 2 || |
| jarcomb.Inputs[0].String() != gen1.Output.String() || |
| jarcomb.Inputs[1].String() != gen2.Output.String() { |
| t.Errorf("jarcomb inputs %v are not [%q, %q]", |
| jarcomb.Inputs.Strings(), gen1.Output.String(), gen2.Output.String()) |
| } |
| |
| if len(jarcombHeaderJars) != 1 || |
| android.PathRelativeToTop(jarcombHeaderJars[0]) != android.PathRelativeToTop(jarcombTurbine.Output) { |
| t.Errorf("jarcomb Header jars %v is not [%q]", |
| android.PathsRelativeToTop(jarcombHeaderJars), android.PathRelativeToTop(jarcombTurbine.Output)) |
| } |
| |
| barMod := ctx.ModuleForTests(t, "bar", "android_common") |
| bar := barMod.Output("javac/bar.jar") |
| barCombined := barMod.Output("combined/bar.jar") |
| |
| // Confirm that bar uses the Implementation and Headers from jarcomb. |
| if len(barCombined.Inputs) != 2 || |
| barCombined.Inputs[0].String() != bar.Output.String() || |
| barCombined.Inputs[1].String() != jarcomb.Output.String() { |
| t.Errorf("bar combined jar inputs %v is not [%q, %q]", |
| barCombined.Inputs.Strings(), bar.Output.String(), jarcomb.Output.String()) |
| } |
| |
| bazMod := ctx.ModuleForTests(t, "baz", "android_common") |
| baz := bazMod.Output("javac/baz.jar") |
| |
| string_in_list := func(s string, l []string) bool { |
| for _, v := range l { |
| if s == v { |
| return true |
| } |
| } |
| return false |
| } |
| |
| // Confirm that baz uses the headerJars from foo. |
| bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits) |
| for _, v := range android.PathsRelativeToTop(jarcombHeaderJars) { |
| if !string_in_list(v, bazImplicitsRel) { |
| t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v) |
| } |
| } |
| } |