1# Copyright (c) 2014 Ahmed H. Ismail 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# http://www.apache.org/licenses/LICENSE-2.0 6# Unless required by applicable law or agreed to in writing, software 7# distributed under the License is distributed on an "AS IS" BASIS, 8# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9# See the License for the specific language governing permissions and 10# limitations under the License. 11 12from __future__ import absolute_import 13from __future__ import print_function 14from __future__ import unicode_literals 15 16import os 17import shutil 18import tempfile 19from unittest import TestCase 20 21from spdx.checksum import Algorithm 22from spdx.config import LICENSE_MAP, EXCEPTION_MAP 23from spdx.creationinfo import Tool 24from spdx.document import Document, ExternalDocumentRef 25from spdx.document import License 26from spdx.file import File 27from spdx.package import Package 28from spdx.utils import NoAssert 29from spdx.version import Version 30 31from tests import utils_test 32 33 34class TestVersion(TestCase): 35 maxDiff = None 36 37 def test_creation(self): 38 v = Version(major=2, minor=1) 39 assert v.major == 2 40 assert v.minor == 1 41 42 def test_comparison(self): 43 v1 = Version(major=1, minor=2) 44 v2 = Version(major=2, minor=1) 45 assert v1 != v2 46 assert v1 < v2 47 assert v1 <= v2 48 assert v2 > v1 49 assert v2 >= v1 50 v3 = Version(major=1, minor=2) 51 assert v3 == v1 52 assert not v1 < v3 53 assert v1 <= v3 54 55 56class TestDocument(TestCase): 57 maxDiff = None 58 59 def test_creation(self): 60 document = Document( 61 version=Version(major=2, minor=1), 62 data_license=License(full_name='Academic Free License v1.1', 63 identifier='AFL-1.1') 64 ) 65 document.add_ext_document_reference( 66 ExternalDocumentRef('DocumentRef-spdx-tool-2.1', 67 'https://spdx.org/spdxdocs/spdx-tools-v2.1-3F2504E0-4F89-41D3-9A0C-0305E82C3301', 68 Algorithm('SHA1', 'SOME-SHA1')) 69 ) 70 assert document.comment is None 71 assert document.version == Version(2, 1) 72 assert document.data_license.identifier == 'AFL-1.1' 73 assert document.ext_document_references[-1].external_document_id == 'DocumentRef-spdx-tool-2.1' 74 assert document.ext_document_references[-1].spdx_document_uri == 'https://spdx.org/spdxdocs/spdx-tools-v2.1-3F2504E0-4F89-41D3-9A0C-0305E82C3301' 75 assert document.ext_document_references[-1].check_sum.identifier == 'SHA1' 76 assert document.ext_document_references[-1].check_sum.value == 'SOME-SHA1' 77 78 def test_document_validate_failures_returns_informative_messages(self): 79 doc = Document(Version(2, 1), License.from_identifier('CC0-1.0'), 80 'Sample_Document-V2.1', spdx_id='SPDXRef-DOCUMENT', 81 namespace='https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301') 82 pack = doc.package = Package('some/path', NoAssert()) 83 file1 = File('./some/path/tofile') 84 file1.name = './some/path/tofile' 85 file1.spdx_id = 'SPDXRef-File' 86 file1.chk_sum = Algorithm('SHA1', 'SOME-SHA1') 87 lic1 = License.from_identifier('LGPL-2.1-only') 88 file1.add_lics(lic1) 89 pack.add_lics_from_file(lic1) 90 messages = [] 91 messages = doc.validate(messages) 92 expected = [ 93 'No creators defined, must have at least one.', 94 'Creation info missing created date.', 95 'Package checksum must be instance of spdx.checksum.Algorithm', 96 'Package download_location can not be None.', 97 'Package verif_code can not be None.', 98 'Package cr_text can not be None.', 99 'Package must have at least one file.', 100 'Package concluded license must be instance of spdx.utils.SPDXNone ' 101 'or spdx.utils.NoAssert or spdx.document.License', 102 'Package declared license must be instance of spdx.utils.SPDXNone ' 103 'or spdx.utils.NoAssert or spdx.document.License' 104 ] 105 assert expected == messages 106 107 def test_document_is_valid_when_using_or_later_licenses(self): 108 doc = Document(Version(2, 1), License.from_identifier('CC0-1.0'), 109 'Sample_Document-V2.1', spdx_id='SPDXRef-DOCUMENT', 110 namespace='https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301') 111 doc.creation_info.add_creator(Tool('ScanCode')) 112 doc.creation_info.set_created_now() 113 114 package = doc.package = Package(name='some/path', download_location=NoAssert()) 115 package.spdx_id = 'SPDXRef-Package' 116 package.cr_text = 'Some copyrught' 117 package.verif_code = 'SOME code' 118 package.license_declared = NoAssert() 119 package.conc_lics = NoAssert() 120 121 file1 = File('./some/path/tofile') 122 file1.name = './some/path/tofile' 123 file1.spdx_id = 'SPDXRef-File' 124 file1.chk_sum = Algorithm('SHA1', 'SOME-SHA1') 125 file1.conc_lics = NoAssert() 126 file1.copyright = NoAssert() 127 128 lic1 = License.from_identifier('LGPL-2.1-or-later') 129 file1.add_lics(lic1) 130 131 package.add_lics_from_file(lic1) 132 package.add_file(file1) 133 messages = [] 134 is_valid = doc.validate(messages) 135 assert is_valid 136 assert not messages 137 138 139class TestWriters(TestCase): 140 maxDiff = None 141 142 def _get_lgpl_doc(self, or_later=False): 143 doc = Document(Version(2, 1), License.from_identifier('CC0-1.0'), 144 'Sample_Document-V2.1', spdx_id='SPDXRef-DOCUMENT', 145 namespace='https://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301') 146 doc.creation_info.add_creator(Tool('ScanCode')) 147 doc.creation_info.set_created_now() 148 149 package = doc.package = Package(name='some/path', download_location=NoAssert()) 150 package.spdx_id = 'SPDXRef-Package' 151 package.cr_text = 'Some copyrught' 152 package.verif_code = 'SOME code' 153 package.check_sum = Algorithm('SHA1', 'SOME-SHA1') 154 package.license_declared = NoAssert() 155 package.conc_lics = NoAssert() 156 157 file1 = File('./some/path/tofile') 158 file1.name = './some/path/tofile' 159 file1.spdx_id = 'SPDXRef-File' 160 file1.chk_sum = Algorithm('SHA1', 'SOME-SHA1') 161 file1.conc_lics = NoAssert() 162 file1.copyright = NoAssert() 163 164 lic1 = License.from_identifier('LGPL-2.1-only') 165 if or_later: 166 lic1 = License.from_identifier('LGPL-2.1-or-later') 167 168 file1.add_lics(lic1) 169 170 package.add_lics_from_file(lic1) 171 package.add_file(file1) 172 return doc 173 174 def test_write_document_rdf_with_validate(self): 175 from spdx.writers.rdf import write_document 176 doc = self._get_lgpl_doc() 177 temp_dir = '' 178 try: 179 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 180 result_file = os.path.join(temp_dir, 'spdx-simple.rdf') 181 with open(result_file, 'wb') as output: 182 write_document(doc, output, validate=True) 183 184 expected_file = utils_test.get_test_loc( 185 'doc_write/rdf-simple.json', 186 test_data_dir=utils_test.test_data_dir) 187 188 utils_test.check_rdf_scan(expected_file, result_file, regen=False) 189 finally: 190 if temp_dir and os.path.exists(temp_dir): 191 shutil.rmtree(temp_dir) 192 193 def test_write_document_rdf_with_or_later_with_validate(self): 194 from spdx.writers.rdf import write_document 195 doc = self._get_lgpl_doc(or_later=True) 196 197 temp_dir = '' 198 try: 199 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 200 result_file = os.path.join(temp_dir, 'spdx-simple-plus.rdf') 201 202 # test proper! 203 with open(result_file, 'wb') as output: 204 write_document(doc, output, validate=True) 205 206 expected_file = utils_test.get_test_loc( 207 'doc_write/rdf-simple-plus.json', 208 test_data_dir=utils_test.test_data_dir) 209 210 utils_test.check_rdf_scan(expected_file, result_file, regen=False) 211 finally: 212 if temp_dir and os.path.exists(temp_dir): 213 shutil.rmtree(temp_dir) 214 215 def test_write_document_tv_with_validate(self): 216 from spdx.writers.tagvalue import write_document 217 doc = self._get_lgpl_doc() 218 219 temp_dir = '' 220 try: 221 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 222 result_file = os.path.join(temp_dir, 'spdx-simple.tv') 223 with open(result_file, 'w') as output: 224 write_document(doc, output, validate=True) 225 226 expected_file = utils_test.get_test_loc( 227 'doc_write/tv-simple.tv', 228 test_data_dir=utils_test.test_data_dir) 229 230 utils_test.check_tv_scan(expected_file, result_file, regen=False) 231 finally: 232 if temp_dir and os.path.exists(temp_dir): 233 shutil.rmtree(temp_dir) 234 235 def test_write_document_tv_with_or_later_with_validate(self): 236 from spdx.writers.tagvalue import write_document 237 238 doc = self._get_lgpl_doc(or_later=True) 239 240 temp_dir = '' 241 try: 242 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 243 result_file = os.path.join(temp_dir, 'spdx-simple-plus.tv') 244 245 # test proper! 246 with open(result_file, 'w') as output: 247 write_document(doc, output, validate=True) 248 249 expected_file = utils_test.get_test_loc( 250 'doc_write/tv-simple-plus.tv', 251 test_data_dir=utils_test.test_data_dir) 252 253 utils_test.check_tv_scan(expected_file, result_file, regen=False) 254 finally: 255 if temp_dir and os.path.exists(temp_dir): 256 shutil.rmtree(temp_dir) 257 258 def test_write_document_json_with_validate(self): 259 from spdx.writers.json import write_document 260 doc = self._get_lgpl_doc() 261 262 temp_dir = '' 263 try: 264 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 265 result_file = os.path.join(temp_dir, 'spdx-simple.json') 266 with open(result_file, 'w') as output: 267 write_document(doc, output, validate=True) 268 269 expected_file = utils_test.get_test_loc( 270 'doc_write/json-simple.json', 271 test_data_dir=utils_test.test_data_dir) 272 273 utils_test.check_json_scan(expected_file, result_file, regen=False) 274 finally: 275 if temp_dir and os.path.exists(temp_dir): 276 shutil.rmtree(temp_dir) 277 278 def test_write_document_json_with_or_later_with_validate(self): 279 from spdx.writers.json import write_document 280 doc = self._get_lgpl_doc(or_later=True) 281 282 temp_dir = '' 283 try: 284 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 285 result_file = os.path.join(temp_dir, 'spdx-simple-plus.json') 286 with open(result_file, 'w') as output: 287 write_document(doc, output, validate=True) 288 289 expected_file = utils_test.get_test_loc( 290 'doc_write/json-simple-plus.json', 291 test_data_dir=utils_test.test_data_dir) 292 293 utils_test.check_json_scan(expected_file, result_file, regen=False) 294 finally: 295 if temp_dir and os.path.exists(temp_dir): 296 shutil.rmtree(temp_dir) 297 298 def test_write_document_yaml_with_validate(self): 299 from spdx.writers.yaml import write_document 300 doc = self._get_lgpl_doc() 301 302 temp_dir = '' 303 try: 304 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 305 result_file = os.path.join(temp_dir, 'spdx-simple.yaml') 306 with open(result_file, 'w') as output: 307 write_document(doc, output, validate=True) 308 309 expected_file = utils_test.get_test_loc( 310 'doc_write/yaml-simple.yaml', 311 test_data_dir=utils_test.test_data_dir) 312 313 utils_test.check_yaml_scan(expected_file, result_file, regen=False) 314 finally: 315 if temp_dir and os.path.exists(temp_dir): 316 shutil.rmtree(temp_dir) 317 318 def test_write_document_yaml_with_or_later_with_validate(self): 319 from spdx.writers.yaml import write_document 320 doc = self._get_lgpl_doc(or_later=True) 321 322 temp_dir = '' 323 try: 324 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 325 result_file = os.path.join(temp_dir, 'spdx-simple-plus.yaml') 326 with open(result_file, 'w') as output: 327 write_document(doc, output, validate=True) 328 329 expected_file = utils_test.get_test_loc( 330 'doc_write/yaml-simple-plus.yaml', 331 test_data_dir=utils_test.test_data_dir) 332 333 utils_test.check_yaml_scan(expected_file, result_file, regen=False) 334 finally: 335 if temp_dir and os.path.exists(temp_dir): 336 shutil.rmtree(temp_dir) 337 338 def test_write_document_xml_with_validate(self): 339 from spdx.writers.xml import write_document 340 doc = self._get_lgpl_doc() 341 342 temp_dir = '' 343 try: 344 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 345 result_file = os.path.join(temp_dir, 'spdx-simple.xml') 346 with open(result_file, 'w') as output: 347 write_document(doc, output, validate=True) 348 349 expected_file = utils_test.get_test_loc( 350 'doc_write/xml-simple.xml', 351 test_data_dir=utils_test.test_data_dir) 352 353 utils_test.check_xml_scan(expected_file, result_file, regen=False) 354 finally: 355 if temp_dir and os.path.exists(temp_dir): 356 shutil.rmtree(temp_dir) 357 358 def test_write_document_xml_with_or_later_with_validate(self): 359 from spdx.writers.xml import write_document 360 doc = self._get_lgpl_doc(or_later=True) 361 362 temp_dir = '' 363 try: 364 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 365 result_file = os.path.join(temp_dir, 'spdx-simple-plus.xml') 366 with open(result_file, 'w') as output: 367 write_document(doc, output, validate=True) 368 369 expected_file = utils_test.get_test_loc( 370 'doc_write/xml-simple-plus.xml', 371 test_data_dir=utils_test.test_data_dir) 372 373 utils_test.check_xml_scan(expected_file, result_file, regen=False) 374 finally: 375 if temp_dir and os.path.exists(temp_dir): 376 shutil.rmtree(temp_dir) 377 378 def _get_mini_doc(self,): 379 doc = Document(Version(2, 1), License.from_identifier('CC0-1.0')) 380 doc.creation_info.add_creator(Tool('ScanCode')) 381 doc.creation_info.set_created_now() 382 383 package = doc.package = Package(download_location=NoAssert()) 384 package.license_declared = NoAssert() 385 package.conc_lics = NoAssert() 386 return doc 387 388 def test_write_document_tv_mini(self): 389 from spdx.writers.tagvalue import write_document 390 doc = self._get_mini_doc() 391 392 temp_dir = '' 393 try: 394 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 395 result_file = os.path.join(temp_dir, 'spdx-simple.tv') 396 with open(result_file, 'w') as output: 397 write_document(doc, output, validate=False) 398 expected_file = utils_test.get_test_loc('doc_write/tv-mini.tv') 399 utils_test.check_tv_scan(expected_file, result_file, regen=False) 400 finally: 401 if temp_dir and os.path.exists(temp_dir): 402 shutil.rmtree(temp_dir) 403 404 def test_write_document_rdf_mini(self): 405 from spdx.writers.rdf import write_document 406 doc = self._get_mini_doc() 407 temp_dir = '' 408 try: 409 temp_dir = tempfile.mkdtemp(prefix='test_spdx') 410 result_file = os.path.join(temp_dir, 'spdx-simple.rdf') 411 with open(result_file, 'wb') as output: 412 write_document(doc, output, validate=False) 413 expected_file = utils_test.get_test_loc('doc_write/rdf-mini.json') 414 utils_test.check_rdf_scan(expected_file, result_file, regen=False) 415 finally: 416 if temp_dir and os.path.exists(temp_dir): 417 shutil.rmtree(temp_dir) 418 419 420class TestLicense(TestCase): 421 maxDiff = None 422 423 def test_url(self): 424 lic = License(full_name='Apache License 1.0', identifier='Apache-1.0') 425 assert lic.url == 'http://spdx.org/licenses/Apache-1.0' 426 427 def test_license_list(self): 428 assert LICENSE_MAP['Aladdin Free Public License'] == 'Aladdin' 429 assert LICENSE_MAP['Aladdin'] == 'Aladdin Free Public License' 430 assert LICENSE_MAP['MIT License'] == 'MIT' 431 assert LICENSE_MAP['MIT'] == 'MIT License' 432 assert LICENSE_MAP['BSD 4-Clause "Original" or "Old" License'] == 'BSD-4-Clause' 433 assert LICENSE_MAP['BSD-4-Clause'] == 'BSD 4-Clause "Original" or "Old" License' 434 435 def test_from_full_name(self): 436 mit = License.from_full_name('MIT License') 437 assert mit.identifier == 'MIT' 438 assert mit.url == 'http://spdx.org/licenses/MIT' 439 440 def test_from_identifier(self): 441 mit = License.from_identifier('MIT') 442 assert mit.full_name == 'MIT License' 443 assert mit.url == 'http://spdx.org/licenses/MIT' 444 445 446class TestException(TestCase): 447 448 def test_exception_list(self): 449 assert EXCEPTION_MAP['Linux Syscall Note'] == 'Linux-syscall-note' 450 assert EXCEPTION_MAP['Linux-syscall-note'] == 'Linux Syscall Note' 451 assert EXCEPTION_MAP['GCC Runtime Library exception 3.1'] == 'GCC-exception-3.1' 452 assert EXCEPTION_MAP['GCC-exception-3.1'] == 'GCC Runtime Library exception 3.1' 453