1// Copyright 2017 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 15package cc 16 17import ( 18 "fmt" 19 "io/ioutil" 20 "os" 21 "path/filepath" 22 "testing" 23 24 "android/soong/android" 25 "android/soong/genrule" 26 27 "github.com/google/blueprint" 28) 29 30type dataFile struct { 31 path string 32 file string 33} 34 35var testDataTests = []struct { 36 name string 37 modules string 38 data []dataFile 39}{ 40 { 41 name: "data files", 42 modules: ` 43 test { 44 name: "foo", 45 data: [ 46 "baz", 47 "bar/baz", 48 ], 49 }`, 50 data: []dataFile{ 51 {"dir", "baz"}, 52 {"dir", "bar/baz"}, 53 }, 54 }, 55 { 56 name: "filegroup", 57 modules: ` 58 filegroup { 59 name: "fg", 60 srcs: [ 61 "baz", 62 "bar/baz", 63 ], 64 } 65 66 test { 67 name: "foo", 68 data: [":fg"], 69 }`, 70 data: []dataFile{ 71 {"dir", "baz"}, 72 {"dir", "bar/baz"}, 73 }, 74 }, 75 { 76 name: "relative filegroup", 77 modules: ` 78 filegroup { 79 name: "fg", 80 srcs: [ 81 "bar/baz", 82 ], 83 path: "bar", 84 } 85 86 test { 87 name: "foo", 88 data: [":fg"], 89 }`, 90 data: []dataFile{ 91 {"dir/bar", "baz"}, 92 }, 93 }, 94 { 95 name: "relative filegroup trailing slash", 96 modules: ` 97 filegroup { 98 name: "fg", 99 srcs: [ 100 "bar/baz", 101 ], 102 path: "bar/", 103 } 104 105 test { 106 name: "foo", 107 data: [":fg"], 108 }`, 109 data: []dataFile{ 110 {"dir/bar", "baz"}, 111 }, 112 }, 113} 114 115func TestDataTests(t *testing.T) { 116 buildDir, err := ioutil.TempDir("", "soong_test_test") 117 if err != nil { 118 t.Fatal(err) 119 } 120 defer os.RemoveAll(buildDir) 121 122 config := android.TestConfig(buildDir) 123 124 for _, test := range testDataTests { 125 t.Run(test.name, func(t *testing.T) { 126 ctx := blueprint.NewContext() 127 android.RegisterTestMutators(ctx) 128 ctx.MockFileSystem(map[string][]byte{ 129 "Blueprints": []byte(`subdirs = ["dir"]`), 130 "dir/Blueprints": []byte(test.modules), 131 "dir/baz": nil, 132 "dir/bar/baz": nil, 133 }) 134 ctx.RegisterModuleType("filegroup", genrule.FileGroupFactory) 135 ctx.RegisterModuleType("test", newTest) 136 137 _, errs := ctx.ParseBlueprintsFiles("Blueprints") 138 fail(t, errs) 139 _, errs = ctx.PrepareBuildActions(config) 140 fail(t, errs) 141 142 foo := findModule(ctx, "foo") 143 if foo == nil { 144 t.Fatalf("failed to find module foo") 145 } 146 147 got := foo.(*testDataTest).data 148 if len(got) != len(test.data) { 149 t.Errorf("expected %d data files, got %d", 150 len(test.data), len(got)) 151 } 152 153 for i := range got { 154 if i >= len(test.data) { 155 break 156 } 157 158 path := filepath.Join(test.data[i].path, test.data[i].file) 159 if test.data[i].file != got[i].Rel() || 160 path != got[i].String() { 161 fmt.Errorf("expected %s:%s got %s:%s", 162 path, test.data[i].file, 163 got[i].String(), got[i].Rel()) 164 } 165 } 166 }) 167 } 168} 169 170type testDataTest struct { 171 android.ModuleBase 172 data android.Paths 173 Properties struct { 174 Data []string 175 } 176} 177 178func newTest() (blueprint.Module, []interface{}) { 179 m := &testDataTest{} 180 return android.InitAndroidModule(m, &m.Properties) 181} 182 183func (test *testDataTest) DepsMutator(ctx android.BottomUpMutatorContext) { 184 android.ExtractSourcesDeps(ctx, test.Properties.Data) 185} 186 187func (test *testDataTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 188 test.data = ctx.ExpandSources(test.Properties.Data, nil) 189} 190 191func findModule(ctx *blueprint.Context, name string) blueprint.Module { 192 var ret blueprint.Module 193 ctx.VisitAllModules(func(m blueprint.Module) { 194 if ctx.ModuleName(m) == name { 195 ret = m 196 } 197 }) 198 return ret 199} 200 201func fail(t *testing.T, errs []error) { 202 if len(errs) > 0 { 203 for _, err := range errs { 204 t.Error(err) 205 } 206 t.FailNow() 207 } 208} 209