| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 1 | // Copyright 2019 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 android | 
|  | 16 |  | 
|  | 17 | import ( | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 18 | "crypto/sha256" | 
|  | 19 | "encoding/hex" | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 20 | "fmt" | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 21 | "path/filepath" | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 22 | "regexp" | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 23 | "strings" | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 24 | "testing" | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 25 |  | 
|  | 26 | "github.com/google/blueprint" | 
|  | 27 |  | 
|  | 28 | "android/soong/shared" | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 29 | ) | 
|  | 30 |  | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 31 | var ( | 
|  | 32 | pctx_ruleBuilderTest           = NewPackageContext("android/soong/rule_builder") | 
|  | 33 | pctx_ruleBuilderTestSubContext = NewPackageContext("android/soong/rule_builder/config") | 
|  | 34 | ) | 
|  | 35 |  | 
|  | 36 | func init() { | 
|  | 37 | pctx_ruleBuilderTest.Import("android/soong/rule_builder/config") | 
|  | 38 | pctx_ruleBuilderTest.StaticVariable("cmdFlags", "${config.ConfigFlags}") | 
|  | 39 | pctx_ruleBuilderTestSubContext.StaticVariable("ConfigFlags", "--some-clang-flag") | 
|  | 40 | } | 
|  | 41 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 42 | func builderContext() BuilderContext { | 
|  | 43 | return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{ | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 44 | "ld":      nil, | 
|  | 45 | "a.o":     nil, | 
|  | 46 | "b.o":     nil, | 
|  | 47 | "cp":      nil, | 
|  | 48 | "a":       nil, | 
|  | 49 | "b":       nil, | 
|  | 50 | "ls":      nil, | 
|  | 51 | "turbine": nil, | 
|  | 52 | "java":    nil, | 
|  | 53 | "javac":   nil, | 
|  | 54 | })) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 55 | } | 
|  | 56 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 57 | func ExampleRuleBuilder() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 58 | ctx := builderContext() | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 59 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 60 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 61 |  | 
|  | 62 | rule.Command(). | 
|  | 63 | Tool(PathForSource(ctx, "ld")). | 
|  | 64 | Inputs(PathsForTesting("a.o", "b.o")). | 
|  | 65 | FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 66 | rule.Command().Text("echo success") | 
|  | 67 |  | 
|  | 68 | // To add the command to the build graph: | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 69 | // rule.Build("link", "link") | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 70 |  | 
|  | 71 | fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && ")) | 
|  | 72 | fmt.Printf("tools: %q\n", rule.Tools()) | 
|  | 73 | fmt.Printf("inputs: %q\n", rule.Inputs()) | 
|  | 74 | fmt.Printf("outputs: %q\n", rule.Outputs()) | 
|  | 75 |  | 
|  | 76 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 77 | // commands: "ld a.o b.o -o out/soong/linked && echo success" | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 78 | // tools: ["ld"] | 
|  | 79 | // inputs: ["a.o" "b.o"] | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 80 | // outputs: ["out/soong/linked"] | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 81 | } | 
|  | 82 |  | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 83 | func ExampleRuleBuilder_Temporary() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 84 | ctx := builderContext() | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 85 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 86 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 87 |  | 
|  | 88 | rule.Command(). | 
|  | 89 | Tool(PathForSource(ctx, "cp")). | 
|  | 90 | Input(PathForSource(ctx, "a")). | 
|  | 91 | Output(PathForOutput(ctx, "b")) | 
|  | 92 | rule.Command(). | 
|  | 93 | Tool(PathForSource(ctx, "cp")). | 
|  | 94 | Input(PathForOutput(ctx, "b")). | 
|  | 95 | Output(PathForOutput(ctx, "c")) | 
|  | 96 | rule.Temporary(PathForOutput(ctx, "b")) | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 97 |  | 
|  | 98 | fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && ")) | 
|  | 99 | fmt.Printf("tools: %q\n", rule.Tools()) | 
|  | 100 | fmt.Printf("inputs: %q\n", rule.Inputs()) | 
|  | 101 | fmt.Printf("outputs: %q\n", rule.Outputs()) | 
|  | 102 |  | 
|  | 103 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 104 | // commands: "cp a out/soong/b && cp out/soong/b out/soong/c" | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 105 | // tools: ["cp"] | 
|  | 106 | // inputs: ["a"] | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 107 | // outputs: ["out/soong/c"] | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 108 | } | 
|  | 109 |  | 
|  | 110 | func ExampleRuleBuilder_DeleteTemporaryFiles() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 111 | ctx := builderContext() | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 112 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 113 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 114 |  | 
|  | 115 | rule.Command(). | 
|  | 116 | Tool(PathForSource(ctx, "cp")). | 
|  | 117 | Input(PathForSource(ctx, "a")). | 
|  | 118 | Output(PathForOutput(ctx, "b")) | 
|  | 119 | rule.Command(). | 
|  | 120 | Tool(PathForSource(ctx, "cp")). | 
|  | 121 | Input(PathForOutput(ctx, "b")). | 
|  | 122 | Output(PathForOutput(ctx, "c")) | 
|  | 123 | rule.Temporary(PathForOutput(ctx, "b")) | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 124 | rule.DeleteTemporaryFiles() | 
|  | 125 |  | 
|  | 126 | fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && ")) | 
|  | 127 | fmt.Printf("tools: %q\n", rule.Tools()) | 
|  | 128 | fmt.Printf("inputs: %q\n", rule.Inputs()) | 
|  | 129 | fmt.Printf("outputs: %q\n", rule.Outputs()) | 
|  | 130 |  | 
|  | 131 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 132 | // commands: "cp a out/soong/b && cp out/soong/b out/soong/c && rm -f out/soong/b" | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 133 | // tools: ["cp"] | 
|  | 134 | // inputs: ["a"] | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 135 | // outputs: ["out/soong/c"] | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 136 | } | 
|  | 137 |  | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 138 | func ExampleRuleBuilder_Installs() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 139 | ctx := builderContext() | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 140 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 141 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 142 |  | 
|  | 143 | out := PathForOutput(ctx, "linked") | 
|  | 144 |  | 
|  | 145 | rule.Command(). | 
|  | 146 | Tool(PathForSource(ctx, "ld")). | 
|  | 147 | Inputs(PathsForTesting("a.o", "b.o")). | 
|  | 148 | FlagWithOutput("-o ", out) | 
|  | 149 | rule.Install(out, "/bin/linked") | 
|  | 150 | rule.Install(out, "/sbin/linked") | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 151 |  | 
|  | 152 | fmt.Printf("rule.Installs().String() = %q\n", rule.Installs().String()) | 
|  | 153 |  | 
|  | 154 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 155 | // rule.Installs().String() = "out/soong/linked:/bin/linked out/soong/linked:/sbin/linked" | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 156 | } | 
|  | 157 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 158 | func ExampleRuleBuilderCommand() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 159 | ctx := builderContext() | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 160 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 161 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 162 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 163 | // chained | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 164 | rule.Command(). | 
|  | 165 | Tool(PathForSource(ctx, "ld")). | 
|  | 166 | Inputs(PathsForTesting("a.o", "b.o")). | 
|  | 167 | FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 168 |  | 
|  | 169 | // unchained | 
|  | 170 | cmd := rule.Command() | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 171 | cmd.Tool(PathForSource(ctx, "ld")) | 
|  | 172 | cmd.Inputs(PathsForTesting("a.o", "b.o")) | 
|  | 173 | cmd.FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 174 |  | 
|  | 175 | // mixed: | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 176 | cmd = rule.Command().Tool(PathForSource(ctx, "ld")) | 
|  | 177 | cmd.Inputs(PathsForTesting("a.o", "b.o")) | 
|  | 178 | cmd.FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 179 | } | 
|  | 180 |  | 
|  | 181 | func ExampleRuleBuilderCommand_Flag() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 182 | ctx := builderContext() | 
|  | 183 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 184 | Tool(PathForSource(ctx, "ls")).Flag("-l")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 185 | // Output: | 
|  | 186 | // ls -l | 
|  | 187 | } | 
|  | 188 |  | 
| Colin Cross | 92b7d58 | 2019-03-29 15:32:51 -0700 | [diff] [blame] | 189 | func ExampleRuleBuilderCommand_Flags() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 190 | ctx := builderContext() | 
|  | 191 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 92b7d58 | 2019-03-29 15:32:51 -0700 | [diff] [blame] | 192 | Tool(PathForSource(ctx, "ls")).Flags([]string{"-l", "-a"})) | 
|  | 193 | // Output: | 
|  | 194 | // ls -l -a | 
|  | 195 | } | 
|  | 196 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 197 | func ExampleRuleBuilderCommand_FlagWithArg() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 198 | ctx := builderContext() | 
|  | 199 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 200 | Tool(PathForSource(ctx, "ls")). | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 201 | FlagWithArg("--sort=", "time")) | 
|  | 202 | // Output: | 
|  | 203 | // ls --sort=time | 
|  | 204 | } | 
|  | 205 |  | 
| Colin Cross | c7ed004 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 206 | func ExampleRuleBuilderCommand_FlagForEachArg() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 207 | ctx := builderContext() | 
|  | 208 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 209 | Tool(PathForSource(ctx, "ls")). | 
| Colin Cross | c7ed004 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 210 | FlagForEachArg("--sort=", []string{"time", "size"})) | 
|  | 211 | // Output: | 
|  | 212 | // ls --sort=time --sort=size | 
|  | 213 | } | 
|  | 214 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 215 | func ExampleRuleBuilderCommand_FlagForEachInput() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 216 | ctx := builderContext() | 
|  | 217 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 218 | Tool(PathForSource(ctx, "turbine")). | 
|  | 219 | FlagForEachInput("--classpath ", PathsForTesting("a.jar", "b.jar"))) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 220 | // Output: | 
|  | 221 | // turbine --classpath a.jar --classpath b.jar | 
|  | 222 | } | 
|  | 223 |  | 
|  | 224 | func ExampleRuleBuilderCommand_FlagWithInputList() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 225 | ctx := builderContext() | 
|  | 226 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 227 | Tool(PathForSource(ctx, "java")). | 
|  | 228 | FlagWithInputList("-classpath=", PathsForTesting("a.jar", "b.jar"), ":")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 229 | // Output: | 
|  | 230 | // java -classpath=a.jar:b.jar | 
|  | 231 | } | 
|  | 232 |  | 
|  | 233 | func ExampleRuleBuilderCommand_FlagWithInput() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 234 | ctx := builderContext() | 
|  | 235 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 236 | Tool(PathForSource(ctx, "java")). | 
|  | 237 | FlagWithInput("-classpath=", PathForSource(ctx, "a"))) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 238 | // Output: | 
|  | 239 | // java -classpath=a | 
|  | 240 | } | 
|  | 241 |  | 
|  | 242 | func ExampleRuleBuilderCommand_FlagWithList() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 243 | ctx := builderContext() | 
|  | 244 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 245 | Tool(PathForSource(ctx, "ls")). | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 246 | FlagWithList("--sort=", []string{"time", "size"}, ",")) | 
|  | 247 | // Output: | 
|  | 248 | // ls --sort=time,size | 
|  | 249 | } | 
|  | 250 |  | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 251 | func ExampleRuleBuilderCommand_FlagWithRspFileInputList() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 252 | ctx := builderContext() | 
|  | 253 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 254 | Tool(PathForSource(ctx, "javac")). | 
| Colin Cross | 70c4741 | 2021-03-12 17:48:14 -0800 | [diff] [blame] | 255 | FlagWithRspFileInputList("@", PathForOutput(ctx, "foo.rsp"), PathsForTesting("a.java", "b.java")). | 
|  | 256 | String()) | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 257 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 258 | // javac @out/soong/foo.rsp | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 259 | } | 
|  | 260 |  | 
|  | 261 | func ExampleRuleBuilderCommand_String() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 262 | ctx := builderContext() | 
|  | 263 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 264 | Text("FOO=foo"). | 
|  | 265 | Text("echo $FOO"). | 
|  | 266 | String()) | 
|  | 267 | // Output: | 
|  | 268 | // FOO=foo echo $FOO | 
|  | 269 | } | 
|  | 270 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 271 | func TestRuleBuilder(t *testing.T) { | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 272 | fs := map[string][]byte{ | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 273 | "dep_fixer":  nil, | 
|  | 274 | "input":      nil, | 
|  | 275 | "Implicit":   nil, | 
|  | 276 | "Input":      nil, | 
|  | 277 | "OrderOnly":  nil, | 
|  | 278 | "OrderOnlys": nil, | 
|  | 279 | "Tool":       nil, | 
|  | 280 | "input2":     nil, | 
|  | 281 | "tool2":      nil, | 
|  | 282 | "input3":     nil, | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 283 | } | 
|  | 284 |  | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 285 | pathCtx := PathContextForTesting(TestConfig("out_local", nil, "", fs)) | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 286 | ctx := builderContextForTests{ | 
|  | 287 | PathContext: pathCtx, | 
|  | 288 | } | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 289 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 290 | addCommands := func(rule *RuleBuilder) { | 
|  | 291 | cmd := rule.Command(). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 292 | DepFile(PathForOutput(ctx, "module/DepFile")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 293 | Flag("Flag"). | 
|  | 294 | FlagWithArg("FlagWithArg=", "arg"). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 295 | FlagWithDepFile("FlagWithDepFile=", PathForOutput(ctx, "module/depfile")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 296 | FlagWithInput("FlagWithInput=", PathForSource(ctx, "input")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 297 | FlagWithOutput("FlagWithOutput=", PathForOutput(ctx, "module/output")). | 
|  | 298 | FlagWithRspFileInputList("FlagWithRspFileInputList=", PathForOutput(ctx, "rsp"), | 
|  | 299 | Paths{ | 
|  | 300 | PathForSource(ctx, "RspInput"), | 
|  | 301 | PathForOutput(ctx, "other/RspOutput2"), | 
|  | 302 | }). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 303 | Implicit(PathForSource(ctx, "Implicit")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 304 | ImplicitDepFile(PathForOutput(ctx, "module/ImplicitDepFile")). | 
|  | 305 | ImplicitOutput(PathForOutput(ctx, "module/ImplicitOutput")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 306 | Input(PathForSource(ctx, "Input")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 307 | Output(PathForOutput(ctx, "module/Output")). | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 308 | OrderOnly(PathForSource(ctx, "OrderOnly")). | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 309 | Validation(PathForSource(ctx, "Validation")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 310 | Text("Text"). | 
|  | 311 | Tool(PathForSource(ctx, "Tool")) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 312 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 313 | rule.Command(). | 
|  | 314 | Text("command2"). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 315 | DepFile(PathForOutput(ctx, "module/depfile2")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 316 | Input(PathForSource(ctx, "input2")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 317 | Output(PathForOutput(ctx, "module/output2")). | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 318 | OrderOnlys(PathsForSource(ctx, []string{"OrderOnlys"})). | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 319 | Validations(PathsForSource(ctx, []string{"Validations"})). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 320 | Tool(PathForSource(ctx, "tool2")) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 321 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 322 | // Test updates to the first command after the second command has been started | 
|  | 323 | cmd.Text("after command2") | 
|  | 324 | // Test updating a command when the previous update did not replace the cmd variable | 
|  | 325 | cmd.Text("old cmd") | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 326 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 327 | // Test a command that uses the output of a previous command as an input | 
|  | 328 | rule.Command(). | 
|  | 329 | Text("command3"). | 
|  | 330 | Input(PathForSource(ctx, "input3")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 331 | Input(PathForOutput(ctx, "module/output2")). | 
|  | 332 | Output(PathForOutput(ctx, "module/output3")). | 
|  | 333 | Text(cmd.PathForInput(PathForSource(ctx, "input3"))). | 
|  | 334 | Text(cmd.PathForOutput(PathForOutput(ctx, "module/output2"))) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 335 | } | 
| Colin Cross | 1d2cf04 | 2019-03-29 15:33:06 -0700 | [diff] [blame] | 336 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 337 | wantInputs := PathsForSource(ctx, []string{"Implicit", "Input", "input", "input2", "input3"}) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 338 | wantRspFileInputs := Paths{PathForSource(ctx, "RspInput"), | 
|  | 339 | PathForOutput(ctx, "other/RspOutput2")} | 
|  | 340 | wantOutputs := PathsForOutput(ctx, []string{ | 
| Cole Faust | 9a346f6 | 2024-01-18 20:12:02 +0000 | [diff] [blame] | 341 | "module/ImplicitOutput", "module/Output", "module/output", "module/output2", | 
|  | 342 | "module/output3"}) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 343 | wantDepFiles := PathsForOutput(ctx, []string{ | 
|  | 344 | "module/DepFile", "module/depfile", "module/ImplicitDepFile", "module/depfile2"}) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 345 | wantTools := PathsForSource(ctx, []string{"Tool", "tool2"}) | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 346 | wantOrderOnlys := PathsForSource(ctx, []string{"OrderOnly", "OrderOnlys"}) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 347 | wantValidations := PathsForSource(ctx, []string{"Validation", "Validations"}) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 348 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 349 | t.Run("normal", func(t *testing.T) { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 350 | rule := NewRuleBuilder(pctx, ctx) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 351 | addCommands(rule) | 
| Colin Cross | 1d2cf04 | 2019-03-29 15:33:06 -0700 | [diff] [blame] | 352 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 353 | wantCommands := []string{ | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 354 | "out_local/soong/module/DepFile Flag FlagWithArg=arg FlagWithDepFile=out_local/soong/module/depfile " + | 
|  | 355 | "FlagWithInput=input FlagWithOutput=out_local/soong/module/output FlagWithRspFileInputList=out_local/soong/rsp " + | 
| Cole Faust | 9a346f6 | 2024-01-18 20:12:02 +0000 | [diff] [blame] | 356 | "Input out_local/soong/module/Output Text Tool after command2 old cmd", | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 357 | "command2 out_local/soong/module/depfile2 input2 out_local/soong/module/output2 tool2", | 
|  | 358 | "command3 input3 out_local/soong/module/output2 out_local/soong/module/output3 input3 out_local/soong/module/output2", | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 359 | } | 
| Colin Cross | 1d2cf04 | 2019-03-29 15:33:06 -0700 | [diff] [blame] | 360 |  | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 361 | wantDepMergerCommand := "out_local/soong/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer " + | 
|  | 362 | "out_local/soong/module/DepFile out_local/soong/module/depfile out_local/soong/module/ImplicitDepFile out_local/soong/module/depfile2" | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 363 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 364 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 365 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 366 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 367 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 368 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 369 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 370 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 371 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 372 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 373 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 374 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 375 | }) | 
|  | 376 |  | 
|  | 377 | t.Run("sbox", func(t *testing.T) { | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 378 | rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"), | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 379 | PathForOutput(ctx, "sbox.textproto")) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 380 | addCommands(rule) | 
|  | 381 |  | 
|  | 382 | wantCommands := []string{ | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 383 | "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " + | 
|  | 384 | "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " + | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 385 | "FlagWithRspFileInputList=out_local/soong/rsp Input __SBOX_SANDBOX_DIR__/out/Output " + | 
| Cole Faust | 9a346f6 | 2024-01-18 20:12:02 +0000 | [diff] [blame] | 386 | "Text Tool after command2 old cmd", | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 387 | "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 tool2", | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 388 | "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2", | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 389 | } | 
|  | 390 |  | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 391 | wantDepMergerCommand := "out_local/soong/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 392 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 393 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 394 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 395 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 396 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 397 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
|  | 398 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 399 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 400 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 401 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 402 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 403 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 404 | }) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 405 |  | 
|  | 406 | t.Run("sbox tools", func(t *testing.T) { | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 407 | rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"), | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 408 | PathForOutput(ctx, "sbox.textproto")).SandboxTools() | 
|  | 409 | addCommands(rule) | 
|  | 410 |  | 
|  | 411 | wantCommands := []string{ | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 412 | "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " + | 
|  | 413 | "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " + | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 414 | "FlagWithRspFileInputList=out_local/soong/rsp Input __SBOX_SANDBOX_DIR__/out/Output " + | 
| Cole Faust | 9a346f6 | 2024-01-18 20:12:02 +0000 | [diff] [blame] | 415 | "Text __SBOX_SANDBOX_DIR__/tools/src/Tool after command2 old cmd", | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 416 | "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/tools/src/tool2", | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 417 | "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2", | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 418 | } | 
|  | 419 |  | 
|  | 420 | wantDepMergerCommand := "__SBOX_SANDBOX_DIR__/tools/out/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" | 
|  | 421 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 422 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 423 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 424 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 425 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 426 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
|  | 427 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 428 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 429 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 430 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 431 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 432 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 433 | }) | 
| Colin Cross | 045bfd9 | 2021-03-24 16:38:03 -0700 | [diff] [blame] | 434 |  | 
|  | 435 | t.Run("sbox inputs", func(t *testing.T) { | 
|  | 436 | rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"), | 
|  | 437 | PathForOutput(ctx, "sbox.textproto")).SandboxInputs() | 
|  | 438 | addCommands(rule) | 
|  | 439 |  | 
|  | 440 | wantCommands := []string{ | 
|  | 441 | "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " + | 
|  | 442 | "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " + | 
| Cole Faust | e8561c6 | 2023-11-30 17:26:37 -0800 | [diff] [blame] | 443 | "FlagWithRspFileInputList=__SBOX_SANDBOX_DIR__/out/soong/rsp Input __SBOX_SANDBOX_DIR__/out/Output " + | 
| Cole Faust | 9a346f6 | 2024-01-18 20:12:02 +0000 | [diff] [blame] | 444 | "Text __SBOX_SANDBOX_DIR__/tools/src/Tool after command2 old cmd", | 
| Colin Cross | 045bfd9 | 2021-03-24 16:38:03 -0700 | [diff] [blame] | 445 | "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/tools/src/tool2", | 
|  | 446 | "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2", | 
|  | 447 | } | 
|  | 448 |  | 
|  | 449 | wantDepMergerCommand := "__SBOX_SANDBOX_DIR__/tools/out/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" | 
|  | 450 |  | 
|  | 451 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
|  | 452 |  | 
|  | 453 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
|  | 454 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
|  | 455 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
| Colin Cross | 045bfd9 | 2021-03-24 16:38:03 -0700 | [diff] [blame] | 456 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 457 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 458 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 459 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Colin Cross | 045bfd9 | 2021-03-24 16:38:03 -0700 | [diff] [blame] | 460 |  | 
|  | 461 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
|  | 462 | }) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 463 | } | 
|  | 464 |  | 
|  | 465 | func testRuleBuilderFactory() Module { | 
|  | 466 | module := &testRuleBuilderModule{} | 
|  | 467 | module.AddProperties(&module.properties) | 
|  | 468 | InitAndroidModule(module) | 
|  | 469 | return module | 
|  | 470 | } | 
|  | 471 |  | 
|  | 472 | type testRuleBuilderModule struct { | 
|  | 473 | ModuleBase | 
|  | 474 | properties struct { | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 475 | Srcs  []string | 
|  | 476 | Flags []string | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 477 |  | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 478 | Restat              bool | 
|  | 479 | Sbox                bool | 
|  | 480 | Sbox_inputs         bool | 
|  | 481 | Unescape_ninja_vars bool | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 482 | } | 
|  | 483 | } | 
|  | 484 |  | 
|  | 485 | func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) { | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 486 | in := PathsForSource(ctx, t.properties.Srcs) | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 487 | implicit := PathForSource(ctx, "implicit") | 
|  | 488 | orderOnly := PathForSource(ctx, "orderonly") | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 489 | validation := PathForSource(ctx, "validation") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 490 | out := PathForModuleOut(ctx, "gen", ctx.ModuleName()) | 
|  | 491 | outDep := PathForModuleOut(ctx, "gen", ctx.ModuleName()+".d") | 
|  | 492 | outDir := PathForModuleOut(ctx, "gen") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 493 | rspFile := PathForModuleOut(ctx, "rsp") | 
|  | 494 | rspFile2 := PathForModuleOut(ctx, "rsp2") | 
|  | 495 | rspFileContents := PathsForSource(ctx, []string{"rsp_in"}) | 
|  | 496 | rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 497 | manifestPath := PathForModuleOut(ctx, "sbox.textproto") | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 498 |  | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 499 | testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, t.properties.Flags, | 
|  | 500 | out, outDep, outDir, | 
|  | 501 | manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, t.properties.Unescape_ninja_vars, | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 502 | rspFile, rspFileContents, rspFile2, rspFileContents2) | 
| Colin Cross | 786cd6d | 2019-02-01 16:41:11 -0800 | [diff] [blame] | 503 | } | 
|  | 504 |  | 
|  | 505 | type testRuleBuilderSingleton struct{} | 
|  | 506 |  | 
|  | 507 | func testRuleBuilderSingletonFactory() Singleton { | 
|  | 508 | return &testRuleBuilderSingleton{} | 
|  | 509 | } | 
|  | 510 |  | 
|  | 511 | func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) { | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 512 | in := PathsForSource(ctx, []string{"in"}) | 
|  | 513 | implicit := PathForSource(ctx, "implicit") | 
|  | 514 | orderOnly := PathForSource(ctx, "orderonly") | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 515 | validation := PathForSource(ctx, "validation") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 516 | out := PathForOutput(ctx, "singleton/gen/baz") | 
|  | 517 | outDep := PathForOutput(ctx, "singleton/gen/baz.d") | 
|  | 518 | outDir := PathForOutput(ctx, "singleton/gen") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 519 | rspFile := PathForOutput(ctx, "singleton/rsp") | 
|  | 520 | rspFile2 := PathForOutput(ctx, "singleton/rsp2") | 
|  | 521 | rspFileContents := PathsForSource(ctx, []string{"rsp_in"}) | 
|  | 522 | rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 523 | manifestPath := PathForOutput(ctx, "singleton/sbox.textproto") | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 524 |  | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 525 | testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, nil, out, outDep, outDir, | 
|  | 526 | manifestPath, true, false, false, false, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 527 | rspFile, rspFileContents, rspFile2, rspFileContents2) | 
| Colin Cross | 786cd6d | 2019-02-01 16:41:11 -0800 | [diff] [blame] | 528 | } | 
|  | 529 |  | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 530 | func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path, | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 531 | flags []string, | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 532 | out, outDep, outDir, manifestPath WritablePath, | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 533 | restat, sbox, sboxInputs, unescapeNinjaVars bool, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 534 | rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) { | 
|  | 535 |  | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 536 | rule := NewRuleBuilder(pctx_ruleBuilderTest, ctx) | 
| Colin Cross | 786cd6d | 2019-02-01 16:41:11 -0800 | [diff] [blame] | 537 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 538 | if sbox { | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 539 | rule.Sbox(outDir, manifestPath) | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 540 | if sboxInputs { | 
|  | 541 | rule.SandboxInputs() | 
|  | 542 | } | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 543 | } | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 544 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 545 | rule.Command(). | 
|  | 546 | Tool(PathForSource(ctx, "cp")). | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 547 | Flags(flags). | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 548 | Inputs(in). | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 549 | Implicit(implicit). | 
|  | 550 | OrderOnly(orderOnly). | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 551 | Validation(validation). | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 552 | Output(out). | 
|  | 553 | ImplicitDepFile(outDep). | 
|  | 554 | FlagWithRspFileInputList("@", rspFile, rspFileContents). | 
|  | 555 | FlagWithRspFileInputList("@", rspFile2, rspFileContents2) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 556 |  | 
|  | 557 | if restat { | 
|  | 558 | rule.Restat() | 
|  | 559 | } | 
| Colin Cross | baa676f | 2019-02-25 14:56:01 -0800 | [diff] [blame] | 560 |  | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 561 | if unescapeNinjaVars { | 
|  | 562 | rule.BuildWithUnescapedNinjaVars("rule", "desc") | 
|  | 563 | } else { | 
|  | 564 | rule.Build("rule", "desc") | 
|  | 565 | } | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 566 | } | 
|  | 567 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 568 | var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) { | 
|  | 569 | ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory) | 
|  | 570 | ctx.RegisterSingletonType("rule_builder_test", testRuleBuilderSingletonFactory) | 
|  | 571 | }) | 
|  | 572 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 573 | func TestRuleBuilder_Build(t *testing.T) { | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 574 | fs := MockFS{ | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 575 | "in": nil, | 
|  | 576 | "cp": nil, | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 577 | } | 
|  | 578 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 579 | bp := ` | 
|  | 580 | rule_builder_test { | 
|  | 581 | name: "foo", | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 582 | srcs: ["in"], | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 583 | restat: true, | 
|  | 584 | } | 
|  | 585 | rule_builder_test { | 
|  | 586 | name: "foo_sbox", | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 587 | srcs: ["in"], | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 588 | sbox: true, | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 589 | } | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 590 | rule_builder_test { | 
|  | 591 | name: "foo_sbox_inputs", | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 592 | srcs: ["in"], | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 593 | sbox: true, | 
|  | 594 | sbox_inputs: true, | 
|  | 595 | } | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 596 | ` | 
|  | 597 |  | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 598 | result := GroupFixturePreparers( | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 599 | prepareForRuleBuilderTest, | 
|  | 600 | FixtureWithRootAndroidBp(bp), | 
|  | 601 | fs.AddToFixture(), | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 602 | ).RunTest(t) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 603 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 604 | check := func(t *testing.T, params TestingBuildParams, rspFile2Params TestingBuildParams, | 
|  | 605 | wantCommand, wantOutput, wantDepfile, wantRspFile, wantRspFile2 string, | 
|  | 606 | wantRestat bool, extraImplicits, extraCmdDeps []string) { | 
|  | 607 |  | 
| Dan Willemsen | c89b6f1 | 2019-08-29 14:47:40 -0700 | [diff] [blame] | 608 | t.Helper() | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 609 | command := params.RuleParams.Command | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 610 | re := regexp.MustCompile(" # hash of input list: [a-z0-9]*$") | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 611 | command = re.ReplaceAllLiteralString(command, "") | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 612 |  | 
|  | 613 | AssertStringEquals(t, "RuleParams.Command", wantCommand, command) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 614 |  | 
|  | 615 | wantDeps := append([]string{"cp"}, extraCmdDeps...) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 616 | AssertArrayString(t, "RuleParams.CommandDeps", wantDeps, params.RuleParams.CommandDeps) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 617 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 618 | AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 619 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 620 | wantInputs := []string{"rsp_in"} | 
|  | 621 | AssertArrayString(t, "Inputs", wantInputs, params.Inputs.Strings()) | 
|  | 622 |  | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 623 | wantImplicits := append([]string{"implicit", "in"}, extraImplicits...) | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 624 | // The second rsp file and the files listed in it should be in implicits | 
|  | 625 | wantImplicits = append(wantImplicits, "rsp_in2", wantRspFile2) | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 626 | AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 627 |  | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 628 | wantOrderOnlys := []string{"orderonly"} | 
|  | 629 | AssertPathsRelativeToTopEquals(t, "OrderOnly", wantOrderOnlys, params.OrderOnly) | 
|  | 630 |  | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 631 | wantValidations := []string{"validation"} | 
|  | 632 | AssertPathsRelativeToTopEquals(t, "Validations", wantValidations, params.Validations) | 
|  | 633 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 634 | wantRspFileContent := "$in" | 
|  | 635 | AssertStringEquals(t, "RspfileContent", wantRspFileContent, params.RuleParams.RspfileContent) | 
|  | 636 |  | 
|  | 637 | AssertStringEquals(t, "Rspfile", wantRspFile, params.RuleParams.Rspfile) | 
|  | 638 |  | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 639 | AssertPathRelativeToTopEquals(t, "Output", wantOutput, params.Output) | 
| Colin Cross | baa676f | 2019-02-25 14:56:01 -0800 | [diff] [blame] | 640 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 641 | if len(params.ImplicitOutputs) != 0 { | 
|  | 642 | t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings()) | 
|  | 643 | } | 
|  | 644 |  | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 645 | AssertPathRelativeToTopEquals(t, "Depfile", wantDepfile, params.Depfile) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 646 |  | 
|  | 647 | if params.Deps != blueprint.DepsGCC { | 
|  | 648 | t.Errorf("want Deps = %q, got %q", blueprint.DepsGCC, params.Deps) | 
| Colin Cross | baa676f | 2019-02-25 14:56:01 -0800 | [diff] [blame] | 649 | } | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 650 |  | 
| Colin Cross | f61d03d | 2023-11-02 16:56:39 -0700 | [diff] [blame] | 651 | rspFile2Content := ContentFromFileRuleForTests(t, result.TestContext, rspFile2Params) | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 652 | AssertStringEquals(t, "rspFile2 content", "rsp_in2\n", rspFile2Content) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 653 | } | 
|  | 654 |  | 
| Colin Cross | 4c83e5c | 2019-02-25 14:54:28 -0800 | [diff] [blame] | 655 | t.Run("module", func(t *testing.T) { | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 656 | outFile := "out/soong/.intermediates/foo/gen/foo" | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 657 | rspFile := "out/soong/.intermediates/foo/rsp" | 
|  | 658 | rspFile2 := "out/soong/.intermediates/foo/rsp2" | 
|  | 659 | module := result.ModuleForTests("foo", "") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 660 | check(t, module.Rule("rule"), module.Output(rspFile2), | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 661 | "cp in "+outFile+" @"+rspFile+" @"+rspFile2, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 662 | outFile, outFile+".d", rspFile, rspFile2, true, nil, nil) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 663 | }) | 
|  | 664 | t.Run("sbox", func(t *testing.T) { | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 665 | outDir := "out/soong/.intermediates/foo_sbox" | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 666 | sboxOutDir := filepath.Join(outDir, "gen") | 
|  | 667 | outFile := filepath.Join(sboxOutDir, "foo_sbox") | 
|  | 668 | depFile := filepath.Join(sboxOutDir, "foo_sbox.d") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 669 | rspFile := filepath.Join(outDir, "rsp") | 
|  | 670 | rspFile2 := filepath.Join(outDir, "rsp2") | 
|  | 671 | manifest := filepath.Join(outDir, "sbox.textproto") | 
|  | 672 | sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox") | 
|  | 673 | sandboxPath := shared.TempDirForOutDir("out/soong") | 
|  | 674 |  | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 675 | cmd := sbox + ` --sandbox-path ` + sandboxPath + ` --output-dir ` + sboxOutDir + ` --manifest ` + manifest | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 676 | module := result.ModuleForTests("foo_sbox", "") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 677 | check(t, module.Output("gen/foo_sbox"), module.Output(rspFile2), | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 678 | cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox}) | 
|  | 679 | }) | 
|  | 680 | t.Run("sbox_inputs", func(t *testing.T) { | 
|  | 681 | outDir := "out/soong/.intermediates/foo_sbox_inputs" | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 682 | sboxOutDir := filepath.Join(outDir, "gen") | 
|  | 683 | outFile := filepath.Join(sboxOutDir, "foo_sbox_inputs") | 
|  | 684 | depFile := filepath.Join(sboxOutDir, "foo_sbox_inputs.d") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 685 | rspFile := filepath.Join(outDir, "rsp") | 
|  | 686 | rspFile2 := filepath.Join(outDir, "rsp2") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 687 | manifest := filepath.Join(outDir, "sbox.textproto") | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 688 | sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox") | 
|  | 689 | sandboxPath := shared.TempDirForOutDir("out/soong") | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 690 |  | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 691 | cmd := sbox + ` --sandbox-path ` + sandboxPath + ` --output-dir ` + sboxOutDir + ` --manifest ` + manifest | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 692 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 693 | module := result.ModuleForTests("foo_sbox_inputs", "") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 694 | check(t, module.Output("gen/foo_sbox_inputs"), module.Output(rspFile2), | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 695 | cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox}) | 
| Colin Cross | 4c83e5c | 2019-02-25 14:54:28 -0800 | [diff] [blame] | 696 | }) | 
|  | 697 | t.Run("singleton", func(t *testing.T) { | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 698 | outFile := filepath.Join("out/soong/singleton/gen/baz") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 699 | rspFile := filepath.Join("out/soong/singleton/rsp") | 
|  | 700 | rspFile2 := filepath.Join("out/soong/singleton/rsp2") | 
|  | 701 | singleton := result.SingletonForTests("rule_builder_test") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 702 | check(t, singleton.Rule("rule"), singleton.Output(rspFile2), | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 703 | "cp in "+outFile+" @"+rspFile+" @"+rspFile2, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 704 | outFile, outFile+".d", rspFile, rspFile2, true, nil, nil) | 
| Colin Cross | 4c83e5c | 2019-02-25 14:54:28 -0800 | [diff] [blame] | 705 | }) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 706 | } | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 707 |  | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 708 | func TestRuleBuilderHashInputs(t *testing.T) { | 
|  | 709 | // The basic idea here is to verify that the command (in the case of a | 
|  | 710 | // non-sbox rule) or the sbox textproto manifest contain a hash of the | 
|  | 711 | // inputs. | 
|  | 712 |  | 
|  | 713 | // By including a hash of the inputs, we cause the rule to re-run if | 
|  | 714 | // the list of inputs changes because the command line or a dependency | 
|  | 715 | // changes. | 
|  | 716 |  | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 717 | hashOf := func(s string) string { | 
|  | 718 | sum := sha256.Sum256([]byte(s)) | 
|  | 719 | return hex.EncodeToString(sum[:]) | 
|  | 720 | } | 
|  | 721 |  | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 722 | bp := ` | 
|  | 723 | rule_builder_test { | 
|  | 724 | name: "hash0", | 
|  | 725 | srcs: ["in1.txt", "in2.txt"], | 
|  | 726 | } | 
|  | 727 | rule_builder_test { | 
|  | 728 | name: "hash0_sbox", | 
|  | 729 | srcs: ["in1.txt", "in2.txt"], | 
|  | 730 | sbox: true, | 
|  | 731 | } | 
|  | 732 | rule_builder_test { | 
|  | 733 | name: "hash1", | 
|  | 734 | srcs: ["in1.txt", "in2.txt", "in3.txt"], | 
|  | 735 | } | 
|  | 736 | rule_builder_test { | 
|  | 737 | name: "hash1_sbox", | 
|  | 738 | srcs: ["in1.txt", "in2.txt", "in3.txt"], | 
|  | 739 | sbox: true, | 
|  | 740 | } | 
|  | 741 | ` | 
|  | 742 | testcases := []struct { | 
|  | 743 | name         string | 
|  | 744 | expectedHash string | 
|  | 745 | }{ | 
|  | 746 | { | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 747 | name:         "hash0", | 
|  | 748 | expectedHash: hashOf("implicit\nin1.txt\nin2.txt"), | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 749 | }, | 
|  | 750 | { | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 751 | name:         "hash1", | 
|  | 752 | expectedHash: hashOf("implicit\nin1.txt\nin2.txt\nin3.txt"), | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 753 | }, | 
|  | 754 | } | 
|  | 755 |  | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 756 | result := GroupFixturePreparers( | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 757 | prepareForRuleBuilderTest, | 
|  | 758 | FixtureWithRootAndroidBp(bp), | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 759 | ).RunTest(t) | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 760 |  | 
|  | 761 | for _, test := range testcases { | 
|  | 762 | t.Run(test.name, func(t *testing.T) { | 
|  | 763 | t.Run("sbox", func(t *testing.T) { | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 764 | gen := result.ModuleForTests(test.name+"_sbox", "") | 
| Colin Cross | f61d03d | 2023-11-02 16:56:39 -0700 | [diff] [blame] | 765 | manifest := RuleBuilderSboxProtoForTests(t, result.TestContext, gen.Output("sbox.textproto")) | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 766 | hash := manifest.Commands[0].GetInputHash() | 
|  | 767 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 768 | AssertStringEquals(t, "hash", test.expectedHash, hash) | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 769 | }) | 
|  | 770 | t.Run("", func(t *testing.T) { | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 771 | gen := result.ModuleForTests(test.name+"", "") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 772 | command := gen.Output("gen/" + test.name).RuleParams.Command | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 773 | if g, w := command, " # hash of input list: "+test.expectedHash; !strings.HasSuffix(g, w) { | 
|  | 774 | t.Errorf("Expected command line to end with %q, got %q", w, g) | 
|  | 775 | } | 
|  | 776 | }) | 
|  | 777 | }) | 
|  | 778 | } | 
|  | 779 | } | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 780 |  | 
|  | 781 | func TestRuleBuilderWithNinjaVarEscaping(t *testing.T) { | 
|  | 782 | bp := ` | 
|  | 783 | rule_builder_test { | 
| Colin Cross | 31a6745 | 2023-11-02 16:57:08 -0700 | [diff] [blame] | 784 | name: "foo_sbox_escaped", | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 785 | flags: ["${cmdFlags}"], | 
|  | 786 | sbox: true, | 
|  | 787 | sbox_inputs: true, | 
|  | 788 | } | 
|  | 789 | rule_builder_test { | 
| Colin Cross | 31a6745 | 2023-11-02 16:57:08 -0700 | [diff] [blame] | 790 | name: "foo_sbox_unescaped", | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 791 | flags: ["${cmdFlags}"], | 
|  | 792 | sbox: true, | 
|  | 793 | sbox_inputs: true, | 
|  | 794 | unescape_ninja_vars: true, | 
|  | 795 | } | 
|  | 796 | ` | 
|  | 797 | result := GroupFixturePreparers( | 
|  | 798 | prepareForRuleBuilderTest, | 
|  | 799 | FixtureWithRootAndroidBp(bp), | 
|  | 800 | ).RunTest(t) | 
|  | 801 |  | 
| Colin Cross | 31a6745 | 2023-11-02 16:57:08 -0700 | [diff] [blame] | 802 | escapedNinjaMod := result.ModuleForTests("foo_sbox_escaped", "").Output("sbox.textproto") | 
|  | 803 | AssertStringEquals(t, "expected rule", "android/soong/android.rawFileCopy", escapedNinjaMod.Rule.String()) | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 804 | AssertStringDoesContain( | 
|  | 805 | t, | 
|  | 806 | "", | 
| Colin Cross | 31a6745 | 2023-11-02 16:57:08 -0700 | [diff] [blame] | 807 | ContentFromFileRuleForTests(t, result.TestContext, escapedNinjaMod), | 
|  | 808 | "${cmdFlags}", | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 809 | ) | 
|  | 810 |  | 
| Colin Cross | 31a6745 | 2023-11-02 16:57:08 -0700 | [diff] [blame] | 811 | unescapedNinjaMod := result.ModuleForTests("foo_sbox_unescaped", "").Rule("unescapedWriteFile") | 
| Sam Delmerico | 285b66a | 2023-09-25 12:13:17 +0000 | [diff] [blame] | 812 | AssertStringDoesContain( | 
|  | 813 | t, | 
|  | 814 | "", | 
|  | 815 | unescapedNinjaMod.BuildParams.Args["content"], | 
|  | 816 | "${cmdFlags}", | 
|  | 817 | ) | 
|  | 818 | AssertStringDoesNotContain( | 
|  | 819 | t, | 
|  | 820 | "", | 
|  | 821 | unescapedNinjaMod.BuildParams.Args["content"], | 
|  | 822 | "$${cmdFlags}", | 
|  | 823 | ) | 
|  | 824 | } |