1// Copyright (C) 2022 The Android Open Source Project 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 15package local 16 17import ( 18 "bytes" 19 "context" 20 "reflect" 21 "testing" 22 23 "tools/treble/build/report/app" 24) 25 26type ninjaTest struct { 27 command *TestCmd 28 input *TestCmd 29 query *TestCmd 30 path *TestCmd 31 paths *TestCmd 32 deps *TestCmd 33 build *TestCmd 34} 35 36func (n *ninjaTest) Command(ctx context.Context, target string) (*bytes.Buffer, error) { 37 return bytes.NewBufferString(n.command.text), n.command.err 38} 39func (n *ninjaTest) Input(ctx context.Context, target string) (*bytes.Buffer, error) { 40 return bytes.NewBufferString(n.input.text), n.input.err 41} 42func (n *ninjaTest) Query(ctx context.Context, target string) (*bytes.Buffer, error) { 43 return bytes.NewBufferString(n.query.text), n.query.err 44} 45func (n *ninjaTest) Path(ctx context.Context, target string, dependency string) (*bytes.Buffer, error) { 46 return bytes.NewBufferString(n.path.text), n.path.err 47} 48func (n *ninjaTest) Paths(ctx context.Context, target string, dependency string) (*bytes.Buffer, error) { 49 return bytes.NewBufferString(n.paths.text), n.paths.err 50} 51func (n *ninjaTest) Deps(ctx context.Context) (*bytes.Buffer, error) { 52 return bytes.NewBufferString(n.deps.text), n.deps.err 53} 54func (n *ninjaTest) Build(ctx context.Context, target string) (*bytes.Buffer, error) { 55 return bytes.NewBufferString(n.build.text), n.build.err 56} 57 58func Test_ninja(t *testing.T) { 59 type commandTest struct { 60 cmd *TestCmd 61 res *app.BuildCommand 62 } 63 type queryTest struct { 64 cmd *TestCmd 65 res *app.BuildQuery 66 } 67 type inputTest struct { 68 cmd *TestCmd 69 res *app.BuildInput 70 } 71 type pathTest struct { 72 cmd *TestCmd 73 res *app.BuildPath 74 } 75 type pathsTest struct { 76 cmd *TestCmd 77 res []*app.BuildPath 78 } 79 type depsTest struct { 80 cmd *TestCmd 81 res *app.BuildDeps 82 } 83 type buildTest struct { 84 cmd *TestCmd 85 res *app.BuildCmdResult 86 } 87 tests := []struct { 88 target string 89 dependency string 90 command commandTest 91 query queryTest 92 input inputTest 93 path pathTest 94 paths pathsTest 95 deps depsTest 96 build buildTest 97 }{ 98 { 99 target: "test", 100 dependency: "dependency", 101 command: commandTest{ 102 cmd: &TestCmd{text: " cmd1\ncmd2\n cmd3\n", err: nil}, 103 res: &app.BuildCommand{Target: "test", Cmds: []string{"cmd1", "cmd2", "cmd3"}}}, 104 query: queryTest{ 105 cmd: &TestCmd{text: "input:\ninfile\noutputs:\noutfile\n", err: nil}, 106 res: &app.BuildQuery{Target: "test", Inputs: []string{"infile"}, Outputs: []string{"outfile"}}}, 107 input: inputTest{ 108 cmd: &TestCmd{text: "file1\nfile2\nfile3\nfile4\nfile5\n", err: nil}, 109 res: &app.BuildInput{Target: "test", Files: []string{"file1", "file2", "file3", "file4", "file5"}}, 110 }, 111 path: pathTest{ 112 cmd: &TestCmd{text: "test\nmid1\nmid2\nmid3\ndependency\n", err: nil}, 113 res: &app.BuildPath{Target: "test", Dependency: "dependency", 114 Paths: []string{"test", "mid1", "mid2", "mid3", "dependency"}}, 115 }, 116 paths: pathsTest{ 117 cmd: &TestCmd{text: "test mid1 mid2 mid3 dependency\ntest mid4 dependency\n", err: nil}, 118 res: []*app.BuildPath{ 119 &app.BuildPath{Target: "test", Dependency: "dependency", Paths: []string{"test", "mid1", "mid2", "mid3", "dependency"}}, 120 &app.BuildPath{Target: "test", Dependency: "dependency", Paths: []string{"test", "mid4", "dependency"}}, 121 }, 122 }, 123 deps: depsTest{ 124 cmd: &TestCmd{text: "some/build/library.so: #deps1\n dependentFile1.S\n dependentFile2.S\nsome/build/library2.so: #deps1\n dependentFile1.S\n dependentFile3.S\n"}, 125 res: &app.BuildDeps{Targets: map[string][]string{ 126 "some/build/library.so": []string{"dependentFile1.S", "dependentFile2.S"}, 127 "some/build/library2.so": []string{"dependentFile1.S", "dependentFile3.S"}, 128 }, 129 }, 130 }, 131 build: buildTest{ 132 cmd: &TestCmd{text: "", err: nil}, 133 res: &app.BuildCmdResult{Name: "test", Output: []string{}, Success: true}}, 134 }, 135 } 136 for _, test := range tests { 137 138 exec := &ninjaTest{ 139 command: test.command.cmd, 140 query: test.query.cmd, 141 input: test.input.cmd, 142 path: test.path.cmd, 143 paths: test.paths.cmd, 144 deps: test.deps.cmd, 145 build: test.build.cmd, 146 } 147 n := &ninjaCli{n: exec} 148 149 if test.command.cmd != nil { 150 if res, err := n.Command(nil, test.target); err != nil { 151 t.Errorf("Command error %s", err) 152 } else { 153 if !reflect.DeepEqual(*res, *test.command.res) { 154 t.Errorf("Command result %v; want %v", *res, *test.command.res) 155 } 156 } 157 } 158 if test.query.cmd != nil { 159 if res, err := n.Query(nil, test.target); err != nil { 160 t.Errorf("Query error %s", err) 161 } else { 162 if !reflect.DeepEqual(*res, *test.query.res) { 163 t.Errorf("Query result %v; want %v", *res, *test.query.res) 164 } 165 } 166 167 } 168 if test.input.cmd != nil { 169 if res, err := n.Input(nil, test.target); err != nil { 170 t.Errorf("Input error %s", err) 171 } else { 172 if !reflect.DeepEqual(*res, *test.input.res) { 173 t.Errorf("Input result %v; want %v", *res, *test.input.res) 174 } 175 } 176 177 } 178 if test.path.cmd != nil { 179 if res, err := n.Path(nil, test.target, test.dependency); err != nil { 180 t.Errorf("Path error %s", err) 181 } else { 182 if !reflect.DeepEqual(*res, *test.path.res) { 183 t.Errorf("Path result %v; want %v", *res, *test.path.res) 184 } 185 } 186 187 } 188 if test.paths.cmd != nil { 189 if res, err := n.Paths(nil, test.target, test.dependency); err != nil { 190 t.Errorf("Paths error %s", err) 191 } else { 192 if !reflect.DeepEqual(res, test.paths.res) { 193 t.Errorf("Paths result %v; want %v", res, test.paths.res) 194 } 195 } 196 197 } 198 if test.deps.cmd != nil { 199 if res, err := n.Deps(nil); err != nil { 200 t.Errorf("Deps error %s", err) 201 } else { 202 if !reflect.DeepEqual(res, test.deps.res) { 203 t.Errorf("Deps result %v; want %v", res, test.deps.res) 204 } 205 } 206 207 } 208 if test.build.cmd != nil { 209 res := n.Build(nil, test.target) 210 if !reflect.DeepEqual(*res, *test.build.res) { 211 t.Errorf("Build result %+v; want %+v", *res, *test.build.res) 212 } 213 214 } 215 } 216} 217