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 37func Test(t *testing.T) { 38 type projectShare struct { 39 project string 40 conditions []string 41 } 42 tests := []struct { 43 condition string 44 name string 45 outDir string 46 roots []string 47 expectedOut []projectShare 48 }{ 49 { 50 condition: "firstparty", 51 name: "apex", 52 roots: []string{"highest.apex.meta_lic"}, 53 expectedOut: []projectShare{}, 54 }, 55 { 56 condition: "firstparty", 57 name: "container", 58 roots: []string{"container.zip.meta_lic"}, 59 expectedOut: []projectShare{}, 60 }, 61 { 62 condition: "firstparty", 63 name: "application", 64 roots: []string{"application.meta_lic"}, 65 expectedOut: []projectShare{}, 66 }, 67 { 68 condition: "firstparty", 69 name: "binary", 70 roots: []string{"bin/bin1.meta_lic"}, 71 expectedOut: []projectShare{}, 72 }, 73 { 74 condition: "firstparty", 75 name: "library", 76 roots: []string{"lib/libd.so.meta_lic"}, 77 expectedOut: []projectShare{}, 78 }, 79 { 80 condition: "notice", 81 name: "apex", 82 roots: []string{"highest.apex.meta_lic"}, 83 expectedOut: []projectShare{}, 84 }, 85 { 86 condition: "notice", 87 name: "container", 88 roots: []string{"container.zip.meta_lic"}, 89 expectedOut: []projectShare{}, 90 }, 91 { 92 condition: "notice", 93 name: "application", 94 roots: []string{"application.meta_lic"}, 95 expectedOut: []projectShare{}, 96 }, 97 { 98 condition: "notice", 99 name: "binary", 100 roots: []string{"bin/bin1.meta_lic"}, 101 expectedOut: []projectShare{}, 102 }, 103 { 104 condition: "notice", 105 name: "library", 106 roots: []string{"lib/libd.so.meta_lic"}, 107 expectedOut: []projectShare{}, 108 }, 109 { 110 condition: "reciprocal", 111 name: "apex", 112 roots: []string{"highest.apex.meta_lic"}, 113 expectedOut: []projectShare{ 114 { 115 project: "device/library", 116 conditions: []string{"reciprocal"}, 117 }, 118 { 119 project: "static/library", 120 conditions: []string{ 121 "reciprocal", 122 }, 123 }, 124 }, 125 }, 126 { 127 condition: "reciprocal", 128 name: "container", 129 roots: []string{"container.zip.meta_lic"}, 130 expectedOut: []projectShare{ 131 { 132 project: "device/library", 133 conditions: []string{"reciprocal"}, 134 }, 135 { 136 project: "static/library", 137 conditions: []string{ 138 "reciprocal", 139 }, 140 }, 141 }, 142 }, 143 { 144 condition: "reciprocal", 145 name: "application", 146 roots: []string{"application.meta_lic"}, 147 expectedOut: []projectShare{ 148 { 149 project: "device/library", 150 conditions: []string{"reciprocal"}, 151 }, 152 }, 153 }, 154 { 155 condition: "reciprocal", 156 name: "binary", 157 roots: []string{"bin/bin1.meta_lic"}, 158 expectedOut: []projectShare{ 159 { 160 project: "device/library", 161 conditions: []string{ 162 "reciprocal", 163 }, 164 }, 165 { 166 project: "static/library", 167 conditions: []string{ 168 "reciprocal", 169 }, 170 }, 171 }, 172 }, 173 { 174 condition: "reciprocal", 175 name: "library", 176 roots: []string{"lib/libd.so.meta_lic"}, 177 expectedOut: []projectShare{}, 178 }, 179 { 180 condition: "restricted", 181 name: "apex", 182 roots: []string{"highest.apex.meta_lic"}, 183 expectedOut: []projectShare{ 184 { 185 project: "base/library", 186 conditions: []string{"restricted"}, 187 }, 188 { 189 project: "device/library", 190 conditions: []string{"restricted_if_statically_linked"}, 191 }, 192 { 193 project: "dynamic/binary", 194 conditions: []string{"restricted"}, 195 }, 196 { 197 project: "static/binary", 198 conditions: []string{ 199 "restricted_if_statically_linked", 200 }, 201 }, 202 { 203 project: "static/library", 204 conditions: []string{ 205 "reciprocal", 206 "restricted_if_statically_linked", 207 }, 208 }, 209 }, 210 }, 211 { 212 condition: "restricted", 213 name: "container", 214 roots: []string{"container.zip.meta_lic"}, 215 expectedOut: []projectShare{ 216 { 217 project: "base/library", 218 conditions: []string{"restricted"}, 219 }, 220 { 221 project: "device/library", 222 conditions: []string{"restricted_if_statically_linked"}, 223 }, 224 { 225 project: "dynamic/binary", 226 conditions: []string{"restricted"}, 227 }, 228 { 229 project: "static/binary", 230 conditions: []string{ 231 "restricted_if_statically_linked", 232 }, 233 }, 234 { 235 project: "static/library", 236 conditions: []string{ 237 "reciprocal", 238 "restricted_if_statically_linked", 239 }, 240 }, 241 }, 242 }, 243 { 244 condition: "restricted", 245 name: "application", 246 roots: []string{"application.meta_lic"}, 247 expectedOut: []projectShare{ 248 { 249 project: "device/library", 250 conditions: []string{ 251 "restricted", 252 "restricted_if_statically_linked", 253 }, 254 }, 255 { 256 project: "distributable/application", 257 conditions: []string{ 258 "restricted", 259 "restricted_if_statically_linked", 260 }, 261 }, 262 }, 263 }, 264 { 265 condition: "restricted", 266 name: "binary", 267 roots: []string{"bin/bin1.meta_lic"}, 268 expectedOut: []projectShare{ 269 { 270 project: "device/library", 271 conditions: []string{ 272 "restricted_if_statically_linked", 273 }, 274 }, 275 { 276 project: "static/binary", 277 conditions: []string{ 278 "restricted_if_statically_linked", 279 }, 280 }, 281 { 282 project: "static/library", 283 conditions: []string{ 284 "reciprocal", 285 "restricted_if_statically_linked", 286 }, 287 }, 288 }, 289 }, 290 { 291 condition: "restricted", 292 name: "library", 293 roots: []string{"lib/libd.so.meta_lic"}, 294 expectedOut: []projectShare{}, 295 }, 296 { 297 condition: "proprietary", 298 name: "apex", 299 roots: []string{"highest.apex.meta_lic"}, 300 expectedOut: []projectShare{ 301 { 302 project: "base/library", 303 conditions: []string{"restricted"}, 304 }, 305 { 306 project: "dynamic/binary", 307 conditions: []string{"restricted"}, 308 }, 309 }, 310 }, 311 { 312 condition: "proprietary", 313 name: "container", 314 roots: []string{"container.zip.meta_lic"}, 315 expectedOut: []projectShare{ 316 { 317 project: "base/library", 318 conditions: []string{"restricted"}, 319 }, 320 { 321 project: "dynamic/binary", 322 conditions: []string{"restricted"}, 323 }, 324 }, 325 }, 326 { 327 condition: "proprietary", 328 name: "application", 329 roots: []string{"application.meta_lic"}, 330 expectedOut: []projectShare{ 331 { 332 project: "device/library", 333 conditions: []string{"restricted"}, 334 }, 335 { 336 project: "distributable/application", 337 conditions: []string{"restricted"}, 338 }, 339 }, 340 }, 341 { 342 condition: "proprietary", 343 name: "binary", 344 roots: []string{"bin/bin1.meta_lic"}, 345 expectedOut: []projectShare{}, 346 }, 347 { 348 condition: "proprietary", 349 name: "library", 350 roots: []string{"lib/libd.so.meta_lic"}, 351 expectedOut: []projectShare{}, 352 }, 353 { 354 condition: "regressgpl1", 355 name: "container", 356 roots: []string{"container.zip.meta_lic"}, 357 expectedOut: []projectShare{ 358 { 359 project: "bin/threelibraries", 360 conditions: []string{"restricted"}, 361 }, 362 }, 363 }, 364 { 365 condition: "regressgpl1", 366 name: "containerplus", 367 roots: []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"}, 368 expectedOut: []projectShare{ 369 { 370 project: "bin/threelibraries", 371 conditions: []string{"restricted"}, 372 }, 373 { 374 project: "lib/apache", 375 conditions: []string{"restricted"}, 376 }, 377 { 378 project: "lib/c++", 379 conditions: []string{"restricted"}, 380 }, 381 }, 382 }, 383 { 384 condition: "regressgpl2", 385 name: "container", 386 roots: []string{"container.zip.meta_lic"}, 387 expectedOut: []projectShare{ 388 { 389 project: "bin/threelibraries", 390 conditions: []string{"restricted"}, 391 }, 392 { 393 project: "lib/apache", 394 conditions: []string{"restricted"}, 395 }, 396 { 397 project: "lib/c++", 398 conditions: []string{"restricted"}, 399 }, 400 { 401 project: "lib/gpl", 402 conditions: []string{"restricted"}, 403 }, 404 }, 405 }, 406 { 407 condition: "regressgpl2", 408 name: "containerplus", 409 roots: []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"}, 410 expectedOut: []projectShare{ 411 { 412 project: "bin/threelibraries", 413 conditions: []string{"restricted"}, 414 }, 415 { 416 project: "lib/apache", 417 conditions: []string{"restricted"}, 418 }, 419 { 420 project: "lib/c++", 421 conditions: []string{"restricted"}, 422 }, 423 { 424 project: "lib/gpl", 425 conditions: []string{"restricted"}, 426 }, 427 }, 428 }, 429 } 430 for _, tt := range tests { 431 t.Run(tt.condition+" "+tt.name, func(t *testing.T) { 432 expectedOut := &bytes.Buffer{} 433 for _, p := range tt.expectedOut { 434 expectedOut.WriteString(p.project) 435 for _, lc := range p.conditions { 436 expectedOut.WriteString(",") 437 expectedOut.WriteString(lc) 438 } 439 expectedOut.WriteString("\n") 440 } 441 442 stdout := &bytes.Buffer{} 443 stderr := &bytes.Buffer{} 444 445 rootFiles := make([]string, 0, len(tt.roots)) 446 for _, r := range tt.roots { 447 rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r) 448 } 449 err := listShare(stdout, stderr, compliance.GetFS(tt.outDir), rootFiles...) 450 if err != nil { 451 t.Fatalf("listshare: error = %v, stderr = %v", err, stderr) 452 return 453 } 454 if stderr.Len() > 0 { 455 t.Errorf("listshare: gotStderr = %v, want none", stderr) 456 } 457 out := stdout.String() 458 expected := expectedOut.String() 459 if out != expected { 460 outList := strings.Split(out, "\n") 461 expectedList := strings.Split(expected, "\n") 462 startLine := 0 463 for len(outList) > startLine && len(expectedList) > startLine && outList[startLine] == expectedList[startLine] { 464 startLine++ 465 } 466 t.Errorf("listshare: gotStdout = %v, want %v, somewhere near line %d Stdout = %v, want %v", 467 out, expected, startLine+1, outList[startLine], expectedList[startLine]) 468 } 469 }) 470 } 471} 472