LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 1 | // Copyright 2018 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 java |
| 16 | |
| 17 | import ( |
| 18 | "reflect" |
| 19 | "testing" |
| 20 | |
| 21 | "android/soong/android" |
| 22 | ) |
| 23 | |
| 24 | func TestJarGenruleCombinerSingle(t *testing.T) { |
| 25 | t.Parallel() |
| 26 | t.Helper() |
| 27 | ctx := prepareForJavaTest.RunTestWithBp(t, ` |
| 28 | java_library { |
| 29 | name: "foo", |
| 30 | srcs: ["a.java"], |
| 31 | } |
| 32 | |
| 33 | java_genrule { |
| 34 | name: "gen", |
| 35 | tool_files: ["b.java"], |
| 36 | cmd: "$(location b.java) $(in) $(out)", |
| 37 | out: ["gen.jar"], |
| 38 | srcs: [":foo"], |
| 39 | } |
| 40 | |
| 41 | java_genrule_combiner { |
| 42 | name: "jarcomb", |
| 43 | static_libs: ["gen"], |
| 44 | headers: ["foo"], |
| 45 | } |
| 46 | |
| 47 | java_library { |
| 48 | name: "bar", |
| 49 | static_libs: ["jarcomb"], |
| 50 | srcs: ["c.java"], |
| 51 | } |
| 52 | |
| 53 | java_library { |
| 54 | name: "baz", |
| 55 | libs: ["jarcomb"], |
| 56 | srcs: ["c.java"], |
| 57 | } |
| 58 | `).TestContext |
| 59 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 60 | fooMod := ctx.ModuleForTests(t, "foo", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 61 | fooCombined := fooMod.Output("turbine-combined/foo.jar") |
| 62 | fooOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), fooMod.Module(), android.OutputFilesProvider) |
| 63 | fooHeaderJars := fooOutputFiles.TaggedOutputFiles[".hjar"] |
| 64 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 65 | genMod := ctx.ModuleForTests(t, "gen", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 66 | gen := genMod.Output("gen.jar") |
| 67 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 68 | jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 69 | jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider) |
| 70 | jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider) |
| 71 | |
| 72 | // Confirm that jarcomb simply forwards the jarcomb implementation and the foo headers. |
| 73 | if len(jarcombOutputFiles.DefaultOutputFiles) != 1 || |
| 74 | android.PathRelativeToTop(jarcombOutputFiles.DefaultOutputFiles[0]) != android.PathRelativeToTop(gen.Output) { |
| 75 | t.Errorf("jarcomb Implementation %v is not [%q]", |
| 76 | android.PathsRelativeToTop(jarcombOutputFiles.DefaultOutputFiles), android.PathRelativeToTop(gen.Output)) |
| 77 | } |
| 78 | jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"] |
| 79 | if !reflect.DeepEqual(jarcombHeaderJars, fooHeaderJars) { |
| 80 | t.Errorf("jarcomb Header jar %v is not %q", |
| 81 | jarcombHeaderJars, fooHeaderJars) |
| 82 | } |
| 83 | |
| 84 | // Confirm that JavaInfoProvider agrees. |
| 85 | if len(jarcombInfo.ImplementationJars) != 1 || |
| 86 | android.PathRelativeToTop(jarcombInfo.ImplementationJars[0]) != android.PathRelativeToTop(gen.Output) { |
| 87 | t.Errorf("jarcomb ImplementationJars %v is not [%q]", |
| 88 | android.PathsRelativeToTop(jarcombInfo.ImplementationJars), android.PathRelativeToTop(gen.Output)) |
| 89 | } |
| 90 | if len(jarcombInfo.HeaderJars) != 1 || |
| 91 | android.PathRelativeToTop(jarcombInfo.HeaderJars[0]) != android.PathRelativeToTop(fooCombined.Output) { |
| 92 | t.Errorf("jarcomb HeaderJars %v is not [%q]", |
| 93 | android.PathsRelativeToTop(jarcombInfo.HeaderJars), android.PathRelativeToTop(fooCombined.Output)) |
| 94 | } |
| 95 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 96 | barMod := ctx.ModuleForTests(t, "bar", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 97 | bar := barMod.Output("javac/bar.jar") |
| 98 | barCombined := barMod.Output("combined/bar.jar") |
| 99 | |
| 100 | // Confirm that bar uses the Implementation from gen and headerJars from foo. |
| 101 | if len(barCombined.Inputs) != 2 || |
| 102 | barCombined.Inputs[0].String() != bar.Output.String() || |
| 103 | barCombined.Inputs[1].String() != gen.Output.String() { |
| 104 | t.Errorf("bar combined jar inputs %v is not [%q, %q]", |
| 105 | barCombined.Inputs.Strings(), bar.Output.String(), gen.Output.String()) |
| 106 | } |
| 107 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 108 | bazMod := ctx.ModuleForTests(t, "baz", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 109 | baz := bazMod.Output("javac/baz.jar") |
| 110 | |
| 111 | string_in_list := func(s string, l []string) bool { |
| 112 | for _, v := range l { |
| 113 | if s == v { |
| 114 | return true |
| 115 | } |
| 116 | } |
| 117 | return false |
| 118 | } |
| 119 | |
| 120 | // Confirm that baz uses the headerJars from foo. |
| 121 | bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits) |
| 122 | for _, v := range android.PathsRelativeToTop(fooHeaderJars) { |
| 123 | if !string_in_list(v, bazImplicitsRel) { |
| 124 | t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v) |
| 125 | } |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | func TestJarGenruleCombinerMulti(t *testing.T) { |
| 130 | t.Parallel() |
| 131 | t.Helper() |
| 132 | ctx := prepareForJavaTest.RunTestWithBp(t, ` |
| 133 | java_library { |
| 134 | name: "foo1", |
| 135 | srcs: ["foo1_a.java"], |
| 136 | } |
| 137 | |
| 138 | java_library { |
| 139 | name: "foo2", |
| 140 | srcs: ["foo2_a.java"], |
| 141 | } |
| 142 | |
| 143 | java_genrule { |
| 144 | name: "gen1", |
| 145 | tool_files: ["b.java"], |
| 146 | cmd: "$(location b.java) $(in) $(out)", |
| 147 | out: ["gen1.jar"], |
| 148 | srcs: [":foo1"], |
| 149 | } |
| 150 | |
| 151 | java_genrule { |
| 152 | name: "gen2", |
| 153 | tool_files: ["b.java"], |
| 154 | cmd: "$(location b.java) $(in) $(out)", |
| 155 | out: ["gen2.jar"], |
| 156 | srcs: [":foo2"], |
| 157 | } |
| 158 | |
| 159 | // Combine multiple java_genrule modules. |
| 160 | java_genrule_combiner { |
| 161 | name: "jarcomb", |
| 162 | static_libs: ["gen1", "gen2"], |
| 163 | headers: ["foo1", "foo2"], |
| 164 | } |
| 165 | |
| 166 | java_library { |
| 167 | name: "bar", |
| 168 | static_libs: ["jarcomb"], |
| 169 | srcs: ["c.java"], |
| 170 | } |
| 171 | |
| 172 | java_library { |
| 173 | name: "baz", |
| 174 | libs: ["jarcomb"], |
| 175 | srcs: ["c.java"], |
| 176 | } |
| 177 | `).TestContext |
| 178 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 179 | gen1Mod := ctx.ModuleForTests(t, "gen1", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 180 | gen1 := gen1Mod.Output("gen1.jar") |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 181 | gen2Mod := ctx.ModuleForTests(t, "gen2", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 182 | gen2 := gen2Mod.Output("gen2.jar") |
| 183 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 184 | jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 185 | jarcomb := jarcombMod.Output("combined/jarcomb.jar") |
| 186 | jarcombTurbine := jarcombMod.Output("turbine-combined/jarcomb.jar") |
| 187 | _ = jarcombTurbine |
| 188 | jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider) |
| 189 | _ = jarcombInfo |
| 190 | jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider) |
| 191 | jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"] |
| 192 | |
| 193 | if len(jarcomb.Inputs) != 2 || |
| 194 | jarcomb.Inputs[0].String() != gen1.Output.String() || |
| 195 | jarcomb.Inputs[1].String() != gen2.Output.String() { |
| 196 | t.Errorf("jarcomb inputs %v are not [%q, %q]", |
| 197 | jarcomb.Inputs.Strings(), gen1.Output.String(), gen2.Output.String()) |
| 198 | } |
| 199 | |
| 200 | if len(jarcombHeaderJars) != 1 || |
| 201 | android.PathRelativeToTop(jarcombHeaderJars[0]) != android.PathRelativeToTop(jarcombTurbine.Output) { |
| 202 | t.Errorf("jarcomb Header jars %v is not [%q]", |
| 203 | android.PathsRelativeToTop(jarcombHeaderJars), android.PathRelativeToTop(jarcombTurbine.Output)) |
| 204 | } |
| 205 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 206 | barMod := ctx.ModuleForTests(t, "bar", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 207 | bar := barMod.Output("javac/bar.jar") |
| 208 | barCombined := barMod.Output("combined/bar.jar") |
| 209 | |
| 210 | // Confirm that bar uses the Implementation and Headers from jarcomb. |
| 211 | if len(barCombined.Inputs) != 2 || |
| 212 | barCombined.Inputs[0].String() != bar.Output.String() || |
| 213 | barCombined.Inputs[1].String() != jarcomb.Output.String() { |
| 214 | t.Errorf("bar combined jar inputs %v is not [%q, %q]", |
| 215 | barCombined.Inputs.Strings(), bar.Output.String(), jarcomb.Output.String()) |
| 216 | } |
| 217 | |
Colin Cross | 90607e9 | 2025-02-11 14:58:07 -0800 | [diff] [blame] | 218 | bazMod := ctx.ModuleForTests(t, "baz", "android_common") |
LaMont Jones | 8546f0c | 2025-01-30 13:51:14 -0800 | [diff] [blame] | 219 | baz := bazMod.Output("javac/baz.jar") |
| 220 | |
| 221 | string_in_list := func(s string, l []string) bool { |
| 222 | for _, v := range l { |
| 223 | if s == v { |
| 224 | return true |
| 225 | } |
| 226 | } |
| 227 | return false |
| 228 | } |
| 229 | |
| 230 | // Confirm that baz uses the headerJars from foo. |
| 231 | bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits) |
| 232 | for _, v := range android.PathsRelativeToTop(jarcombHeaderJars) { |
| 233 | if !string_in_list(v, bazImplicitsRel) { |
| 234 | t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v) |
| 235 | } |
| 236 | } |
| 237 | } |