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_allows_dynamic_linking"}, 191 }, 192 { 193 project: "dynamic/binary", 194 conditions: []string{"restricted"}, 195 }, 196 { 197 project: "highest/apex", 198 conditions: []string{ 199 "restricted", 200 "restricted_allows_dynamic_linking", 201 }, 202 }, 203 { 204 project: "static/binary", 205 conditions: []string{ 206 "restricted_allows_dynamic_linking", 207 }, 208 }, 209 { 210 project: "static/library", 211 conditions: []string{ 212 "reciprocal", 213 "restricted_allows_dynamic_linking", 214 }, 215 }, 216 }, 217 }, 218 { 219 condition: "restricted", 220 name: "container", 221 roots: []string{"container.zip.meta_lic"}, 222 expectedOut: []projectShare{ 223 { 224 project: "base/library", 225 conditions: []string{"restricted"}, 226 }, 227 { 228 project: "container/zip", 229 conditions: []string{ 230 "restricted", 231 "restricted_allows_dynamic_linking", 232 }, 233 }, 234 { 235 project: "device/library", 236 conditions: []string{"restricted_allows_dynamic_linking"}, 237 }, 238 { 239 project: "dynamic/binary", 240 conditions: []string{"restricted"}, 241 }, 242 { 243 project: "static/binary", 244 conditions: []string{ 245 "restricted_allows_dynamic_linking", 246 }, 247 }, 248 { 249 project: "static/library", 250 conditions: []string{ 251 "reciprocal", 252 "restricted_allows_dynamic_linking", 253 }, 254 }, 255 }, 256 }, 257 { 258 condition: "restricted", 259 name: "application", 260 roots: []string{"application.meta_lic"}, 261 expectedOut: []projectShare{ 262 { 263 project: "device/library", 264 conditions: []string{ 265 "restricted", 266 "restricted_allows_dynamic_linking", 267 }, 268 }, 269 { 270 project: "distributable/application", 271 conditions: []string{ 272 "restricted", 273 "restricted_allows_dynamic_linking", 274 }, 275 }, 276 }, 277 }, 278 { 279 condition: "restricted", 280 name: "binary", 281 roots: []string{"bin/bin1.meta_lic"}, 282 expectedOut: []projectShare{ 283 { 284 project: "device/library", 285 conditions: []string{ 286 "restricted_allows_dynamic_linking", 287 }, 288 }, 289 { 290 project: "static/binary", 291 conditions: []string{ 292 "restricted_allows_dynamic_linking", 293 }, 294 }, 295 { 296 project: "static/library", 297 conditions: []string{ 298 "reciprocal", 299 "restricted_allows_dynamic_linking", 300 }, 301 }, 302 }, 303 }, 304 { 305 condition: "restricted", 306 name: "library", 307 roots: []string{"lib/libd.so.meta_lic"}, 308 expectedOut: []projectShare{}, 309 }, 310 { 311 condition: "proprietary", 312 name: "apex", 313 roots: []string{"highest.apex.meta_lic"}, 314 expectedOut: []projectShare{ 315 { 316 project: "base/library", 317 conditions: []string{"restricted"}, 318 }, 319 { 320 project: "dynamic/binary", 321 conditions: []string{"restricted"}, 322 }, 323 { 324 project: "highest/apex", 325 conditions: []string{"restricted"}, 326 }, 327 }, 328 }, 329 { 330 condition: "proprietary", 331 name: "container", 332 roots: []string{"container.zip.meta_lic"}, 333 expectedOut: []projectShare{ 334 { 335 project: "base/library", 336 conditions: []string{"restricted"}, 337 }, 338 { 339 project: "container/zip", 340 conditions: []string{"restricted"}, 341 }, 342 { 343 project: "dynamic/binary", 344 conditions: []string{"restricted"}, 345 }, 346 }, 347 }, 348 { 349 condition: "proprietary", 350 name: "application", 351 roots: []string{"application.meta_lic"}, 352 expectedOut: []projectShare{ 353 { 354 project: "device/library", 355 conditions: []string{"restricted"}, 356 }, 357 { 358 project: "distributable/application", 359 conditions: []string{"restricted"}, 360 }, 361 }, 362 }, 363 { 364 condition: "proprietary", 365 name: "binary", 366 roots: []string{"bin/bin1.meta_lic"}, 367 expectedOut: []projectShare{}, 368 }, 369 { 370 condition: "proprietary", 371 name: "library", 372 roots: []string{"lib/libd.so.meta_lic"}, 373 expectedOut: []projectShare{}, 374 }, 375 { 376 condition: "regressgpl1", 377 name: "container", 378 roots: []string{"container.zip.meta_lic"}, 379 expectedOut: []projectShare{ 380 { 381 project: "bin/threelibraries", 382 conditions: []string{"restricted"}, 383 }, 384 { 385 project: "container/zip", 386 conditions: []string{"restricted"}, 387 }, 388 }, 389 }, 390 { 391 condition: "regressgpl1", 392 name: "containerplus", 393 roots: []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"}, 394 expectedOut: []projectShare{ 395 { 396 project: "bin/threelibraries", 397 conditions: []string{"restricted"}, 398 }, 399 { 400 project: "container/zip", 401 conditions: []string{"restricted"}, 402 }, 403 { 404 project: "lib/apache", 405 conditions: []string{"restricted"}, 406 }, 407 { 408 project: "lib/c++", 409 conditions: []string{"restricted"}, 410 }, 411 }, 412 }, 413 { 414 condition: "regressgpl2", 415 name: "container", 416 roots: []string{"container.zip.meta_lic"}, 417 expectedOut: []projectShare{ 418 { 419 project: "bin/threelibraries", 420 conditions: []string{"restricted"}, 421 }, 422 { 423 project: "container/zip", 424 conditions: []string{"restricted"}, 425 }, 426 { 427 project: "lib/apache", 428 conditions: []string{"restricted"}, 429 }, 430 { 431 project: "lib/c++", 432 conditions: []string{"restricted"}, 433 }, 434 { 435 project: "lib/gpl", 436 conditions: []string{"restricted"}, 437 }, 438 }, 439 }, 440 { 441 condition: "regressgpl2", 442 name: "containerplus", 443 roots: []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"}, 444 expectedOut: []projectShare{ 445 { 446 project: "bin/threelibraries", 447 conditions: []string{"restricted"}, 448 }, 449 { 450 project: "container/zip", 451 conditions: []string{"restricted"}, 452 }, 453 { 454 project: "lib/apache", 455 conditions: []string{"restricted"}, 456 }, 457 { 458 project: "lib/c++", 459 conditions: []string{"restricted"}, 460 }, 461 { 462 project: "lib/gpl", 463 conditions: []string{"restricted"}, 464 }, 465 }, 466 }, 467 } 468 for _, tt := range tests { 469 t.Run(tt.condition+" "+tt.name, func(t *testing.T) { 470 expectedOut := &bytes.Buffer{} 471 for _, p := range tt.expectedOut { 472 expectedOut.WriteString(p.project) 473 for _, lc := range p.conditions { 474 expectedOut.WriteString(",") 475 expectedOut.WriteString(lc) 476 } 477 expectedOut.WriteString("\n") 478 } 479 480 stdout := &bytes.Buffer{} 481 stderr := &bytes.Buffer{} 482 483 rootFiles := make([]string, 0, len(tt.roots)) 484 for _, r := range tt.roots { 485 rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r) 486 } 487 err := listShare(stdout, stderr, compliance.GetFS(tt.outDir), rootFiles...) 488 if err != nil { 489 t.Fatalf("listshare: error = %v, stderr = %v", err, stderr) 490 return 491 } 492 if stderr.Len() > 0 { 493 t.Errorf("listshare: gotStderr = %v, want none", stderr) 494 } 495 out := stdout.String() 496 expected := expectedOut.String() 497 if out != expected { 498 outList := strings.Split(out, "\n") 499 expectedList := strings.Split(expected, "\n") 500 startLine := 0 501 for len(outList) > startLine && len(expectedList) > startLine && outList[startLine] == expectedList[startLine] { 502 startLine++ 503 } 504 t.Errorf("listshare: gotStdout = %v, want %v, somewhere near line %d Stdout = %v, want %v", 505 out, expected, startLine+1, outList[startLine], expectedList[startLine]) 506 } 507 }) 508 } 509} 510