poky/meta/lib/oeqa/selftest/cases/oelib/license.py
Peter Kjellerstedt 16f1a14f83 license.py: Correct selection of licenses in is_included()
When faced with multiple sets of licenses combined with | (OR), it was
possible for oe.license.is_included() to choose a set of licenses with
a blacklisted license and then report failure, even if choosing
another set of licenses would have resulted in a successful
result. This happened when the chosen set still contained more
whitelisted licenses than the other set.

This change makes sure a set with any blacklisted license is always
considered with a lower weight than a set with only whitelisted
licenses.

Example: Faced with the license string "GPL-3.0 & GPL-2.0 & LGPL-2.1 |
Proprietary" and with "GPL-3.0" being blacklisted, the old code would
report a failure since "GPL-3.0 & GPL-2.0 & LGPL-2.1" still contains
more whitelisted licenses than "Proprietary" does.

This change also adds a unit test for oe.license.is_included().

(From OE-Core rev: 312b4d6175e189852c0787ca2fe99b99ce92d1bd)

Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2017-10-07 23:20:39 +01:00

100 lines
3.3 KiB
Python

from unittest.case import TestCase
import oe.license
class SeenVisitor(oe.license.LicenseVisitor):
def __init__(self):
self.seen = []
oe.license.LicenseVisitor.__init__(self)
def visit_Str(self, node):
self.seen.append(node.s)
class TestSingleLicense(TestCase):
licenses = [
"GPLv2",
"LGPL-2.0",
"Artistic",
"MIT",
"GPLv3+",
"FOO_BAR",
]
invalid_licenses = ["GPL/BSD"]
@staticmethod
def parse(licensestr):
visitor = SeenVisitor()
visitor.visit_string(licensestr)
return visitor.seen
def test_single_licenses(self):
for license in self.licenses:
licenses = self.parse(license)
self.assertListEqual(licenses, [license])
def test_invalid_licenses(self):
for license in self.invalid_licenses:
with self.assertRaises(oe.license.InvalidLicense) as cm:
self.parse(license)
self.assertEqual(cm.exception.license, license)
class TestSimpleCombinations(TestCase):
tests = {
"FOO&BAR": ["FOO", "BAR"],
"BAZ & MOO": ["BAZ", "MOO"],
"ALPHA|BETA": ["ALPHA"],
"BAZ&MOO|FOO": ["FOO"],
"FOO&BAR|BAZ": ["FOO", "BAR"],
}
preferred = ["ALPHA", "FOO", "BAR"]
def test_tests(self):
def choose(a, b):
if all(lic in self.preferred for lic in b):
return b
else:
return a
for license, expected in self.tests.items():
licenses = oe.license.flattened_licenses(license, choose)
self.assertListEqual(licenses, expected)
class TestComplexCombinations(TestSimpleCombinations):
tests = {
"FOO & (BAR | BAZ)&MOO": ["FOO", "BAR", "MOO"],
"(ALPHA|(BETA&THETA)|OMEGA)&DELTA": ["OMEGA", "DELTA"],
"((ALPHA|BETA)&FOO)|BAZ": ["BETA", "FOO"],
"(GPL-2.0|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0", "BSD-4-clause", "MIT"],
}
preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0"]
class TestIsIncluded(TestCase):
tests = {
("FOO | BAR", None, None):
[True, ["FOO"]],
("FOO | BAR", None, "FOO"):
[True, ["BAR"]],
("FOO | BAR", "BAR", None):
[True, ["BAR"]],
("FOO | BAR & FOOBAR", "*BAR", None):
[True, ["BAR", "FOOBAR"]],
("FOO | BAR & FOOBAR", None, "FOO*"):
[False, ["FOOBAR"]],
("(FOO | BAR) & FOOBAR | BARFOO", None, "FOO"):
[True, ["BAR", "FOOBAR"]],
("(FOO | BAR) & FOOBAR | BAZ & MOO & BARFOO", None, "FOO"):
[True, ["BAZ", "MOO", "BARFOO"]],
("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, None):
[True, ["GPL-3.0", "GPL-2.0", "LGPL-2.1"]],
("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0"):
[True, ["Proprietary"]],
("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0 Proprietary"):
[False, ["GPL-3.0"]]
}
def test_tests(self):
for args, expected in self.tests.items():
is_included, licenses = oe.license.is_included(
args[0], (args[1] or '').split(), (args[2] or '').split())
self.assertEqual(is_included, expected[0])
self.assertListEqual(licenses, expected[1])