1// Copyright 2021 Google LLC 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 main 16 17import ( 18 "bytes" 19 "fmt" 20 "os" 21 "strings" 22 "testing" 23 24 "android/soong/tools/compliance" 25) 26 27func TestMain(m *testing.M) { 28 // Change into the parent directory before running the tests 29 // so they can find the testdata directory. 30 if err := os.Chdir(".."); err != nil { 31 fmt.Printf("failed to change to testdata directory: %s\n", err) 32 os.Exit(1) 33 } 34 os.Exit(m.Run()) 35} 36 37type outcome struct { 38 target string 39 privacyCondition string 40 shareCondition string 41} 42 43func (o *outcome) String() string { 44 return fmt.Sprintf("%s %s and must share from %s", o.target, o.privacyCondition, o.shareCondition) 45} 46 47type outcomeList []*outcome 48 49func (ol outcomeList) String() string { 50 result := "" 51 for _, o := range ol { 52 result = result + o.String() + "\n" 53 } 54 return result 55} 56 57func Test(t *testing.T) { 58 tests := []struct { 59 condition string 60 name string 61 outDir string 62 roots []string 63 expectedStdout string 64 expectedOutcomes outcomeList 65 }{ 66 { 67 condition: "firstparty", 68 name: "apex", 69 roots: []string{"highest.apex.meta_lic"}, 70 expectedStdout: "PASS", 71 }, 72 { 73 condition: "firstparty", 74 name: "container", 75 roots: []string{"container.zip.meta_lic"}, 76 expectedStdout: "PASS", 77 }, 78 { 79 condition: "firstparty", 80 name: "application", 81 roots: []string{"application.meta_lic"}, 82 expectedStdout: "PASS", 83 }, 84 { 85 condition: "firstparty", 86 name: "binary", 87 roots: []string{"bin/bin2.meta_lic"}, 88 expectedStdout: "PASS", 89 }, 90 { 91 condition: "firstparty", 92 name: "library", 93 roots: []string{"lib/libd.so.meta_lic"}, 94 expectedStdout: "PASS", 95 }, 96 { 97 condition: "notice", 98 name: "apex", 99 roots: []string{"highest.apex.meta_lic"}, 100 expectedStdout: "PASS", 101 }, 102 { 103 condition: "notice", 104 name: "container", 105 roots: []string{"container.zip.meta_lic"}, 106 expectedStdout: "PASS", 107 }, 108 { 109 condition: "notice", 110 name: "application", 111 roots: []string{"application.meta_lic"}, 112 expectedStdout: "PASS", 113 }, 114 { 115 condition: "notice", 116 name: "binary", 117 roots: []string{"bin/bin2.meta_lic"}, 118 expectedStdout: "PASS", 119 }, 120 { 121 condition: "notice", 122 name: "library", 123 roots: []string{"lib/libd.so.meta_lic"}, 124 expectedStdout: "PASS", 125 }, 126 { 127 condition: "reciprocal", 128 name: "apex", 129 roots: []string{"highest.apex.meta_lic"}, 130 expectedStdout: "PASS", 131 }, 132 { 133 condition: "reciprocal", 134 name: "container", 135 roots: []string{"container.zip.meta_lic"}, 136 expectedStdout: "PASS", 137 }, 138 { 139 condition: "reciprocal", 140 name: "application", 141 roots: []string{"application.meta_lic"}, 142 expectedStdout: "PASS", 143 }, 144 { 145 condition: "reciprocal", 146 name: "binary", 147 roots: []string{"bin/bin2.meta_lic"}, 148 expectedStdout: "PASS", 149 }, 150 { 151 condition: "reciprocal", 152 name: "library", 153 roots: []string{"lib/libd.so.meta_lic"}, 154 expectedStdout: "PASS", 155 }, 156 { 157 condition: "restricted", 158 name: "apex", 159 roots: []string{"highest.apex.meta_lic"}, 160 expectedStdout: "PASS", 161 }, 162 { 163 condition: "restricted", 164 name: "container", 165 roots: []string{"container.zip.meta_lic"}, 166 expectedStdout: "PASS", 167 }, 168 { 169 condition: "restricted", 170 name: "application", 171 roots: []string{"application.meta_lic"}, 172 expectedStdout: "PASS", 173 }, 174 { 175 condition: "restricted", 176 name: "binary", 177 roots: []string{"bin/bin2.meta_lic"}, 178 expectedStdout: "PASS", 179 }, 180 { 181 condition: "restricted", 182 name: "library", 183 roots: []string{"lib/libd.so.meta_lic"}, 184 expectedStdout: "PASS", 185 }, 186 { 187 condition: "proprietary", 188 name: "apex", 189 roots: []string{"highest.apex.meta_lic"}, 190 expectedStdout: "FAIL", 191 expectedOutcomes: outcomeList{ 192 &outcome{ 193 target: "testdata/proprietary/bin/bin2.meta_lic", 194 privacyCondition: "proprietary", 195 shareCondition: "restricted", 196 }, 197 }, 198 }, 199 { 200 condition: "proprietary", 201 name: "container", 202 roots: []string{"container.zip.meta_lic"}, 203 expectedStdout: "FAIL", 204 expectedOutcomes: outcomeList{ 205 &outcome{ 206 target: "testdata/proprietary/bin/bin2.meta_lic", 207 privacyCondition: "proprietary", 208 shareCondition: "restricted", 209 }, 210 }, 211 }, 212 { 213 condition: "proprietary", 214 name: "application", 215 roots: []string{"application.meta_lic"}, 216 expectedStdout: "FAIL", 217 expectedOutcomes: outcomeList{ 218 &outcome{ 219 target: "testdata/proprietary/lib/liba.so.meta_lic", 220 privacyCondition: "proprietary", 221 shareCondition: "restricted", 222 }, 223 }, 224 }, 225 { 226 condition: "proprietary", 227 name: "binary", 228 roots: []string{"bin/bin2.meta_lic", "lib/libb.so.meta_lic"}, 229 expectedStdout: "FAIL", 230 expectedOutcomes: outcomeList{ 231 &outcome{ 232 target: "testdata/proprietary/bin/bin2.meta_lic", 233 privacyCondition: "proprietary", 234 shareCondition: "restricted", 235 }, 236 }, 237 }, 238 { 239 condition: "proprietary", 240 name: "library", 241 roots: []string{"lib/libd.so.meta_lic"}, 242 expectedStdout: "PASS", 243 }, 244 } 245 for _, tt := range tests { 246 t.Run(tt.condition+" "+tt.name, func(t *testing.T) { 247 stdout := &bytes.Buffer{} 248 stderr := &bytes.Buffer{} 249 250 rootFiles := make([]string, 0, len(tt.roots)) 251 for _, r := range tt.roots { 252 rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r) 253 } 254 err := checkShare(stdout, stderr, compliance.GetFS(tt.outDir), rootFiles...) 255 if err != nil && err != failConflicts { 256 t.Fatalf("checkshare: error = %v, stderr = %v", err, stderr) 257 return 258 } 259 var actualStdout string 260 for _, s := range strings.Split(stdout.String(), "\n") { 261 ts := strings.TrimLeft(s, " \t") 262 if len(ts) < 1 { 263 continue 264 } 265 if len(actualStdout) > 0 { 266 t.Errorf("checkshare: unexpected multiple output lines %q, want %q", actualStdout+"\n"+ts, tt.expectedStdout) 267 } 268 actualStdout = ts 269 } 270 if actualStdout != tt.expectedStdout { 271 t.Errorf("checkshare: unexpected stdout %q, want %q", actualStdout, tt.expectedStdout) 272 } 273 errList := strings.Split(stderr.String(), "\n") 274 actualOutcomes := make(outcomeList, 0, len(errList)) 275 for _, cstring := range errList { 276 ts := strings.TrimLeft(cstring, " \t") 277 if len(ts) < 1 { 278 continue 279 } 280 cFields := strings.Split(ts, " ") 281 actualOutcomes = append(actualOutcomes, &outcome{ 282 target: cFields[0], 283 privacyCondition: cFields[1], 284 shareCondition: cFields[6], 285 }) 286 } 287 if len(actualOutcomes) != len(tt.expectedOutcomes) { 288 t.Errorf("checkshare: unexpected got %d outcomes %s, want %d outcomes %s", 289 len(actualOutcomes), actualOutcomes, len(tt.expectedOutcomes), tt.expectedOutcomes) 290 return 291 } 292 for i := range actualOutcomes { 293 if actualOutcomes[i].String() != tt.expectedOutcomes[i].String() { 294 t.Errorf("checkshare: unexpected outcome #%d, got %q, want %q", 295 i+1, actualOutcomes[i], tt.expectedOutcomes[i]) 296 } 297 } 298 }) 299 } 300} 301