1# Copyright 2015,2016 Nir Cohen 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 15import os 16import sys 17import ast 18import subprocess 19try: 20 from StringIO import StringIO # Python 2.x 21except ImportError: 22 from io import StringIO # Python 3.x 23 24import pytest 25 26 27BASE = os.path.abspath(os.path.dirname(__file__)) 28RESOURCES = os.path.join(BASE, 'resources') 29DISTROS_DIR = os.path.join(RESOURCES, 'distros') 30TESTDISTROS = os.path.join(RESOURCES, 'testdistros') 31SPECIAL = os.path.join(RESOURCES, 'special') 32DISTROS = [dist for dist in os.listdir(DISTROS_DIR) if dist != '__shared__'] 33 34 35IS_LINUX = sys.platform.startswith('linux') 36if IS_LINUX: 37 import distro 38 39 RELATIVE_UNIXCONFDIR = distro._UNIXCONFDIR[1:] 40 MODULE_DISTRO = distro._distro 41 42 43class TestNonLinuxPlatform: 44 """Obviously, this only tests Windows. Will add OS X tests on Travis 45 Later 46 """ 47 48 def test_cant_use_on_windows(self): 49 try: 50 import distro # NOQA 51 except ImportError as ex: 52 assert 'Unsupported platform' in str(ex) 53 54 55@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 56class TestCli: 57 58 def _parse(self, command): 59 sys.argv = command.split() 60 distro.main() 61 62 def _run(self, command): 63 stdout, _ = subprocess.Popen( 64 command, 65 stdout=subprocess.PIPE, 66 stderr=subprocess.PIPE).communicate() 67 # Need to decode or we get bytes in Python 3.x 68 return stdout.decode('utf-8') 69 70 def test_cli_for_coverage_yuch(self): 71 self._parse('distro') 72 self._parse('distro -j') 73 74 def test_cli(self): 75 command = [sys.executable, '-m', 'distro'] 76 desired_output = 'Name: ' + distro.name(pretty=True) 77 distro_version = distro.version(pretty=True) 78 distro_codename = distro.codename() 79 desired_output += '\n' + 'Version: ' + distro_version 80 desired_output += '\n' + 'Codename: ' + distro_codename 81 desired_output += '\n' 82 assert self._run(command) == desired_output 83 84 def test_cli_json(self): 85 command = [sys.executable, '-m', 'distro', '-j'] 86 assert ast.literal_eval(self._run(command)) == distro.info() 87 88 89@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 90class DistroTestCase(object): 91 """A base class for any testcase classes that test the distributions 92 represented in the `DISTROS` subtree. 93 """ 94 95 def setup_method(self, test_method): 96 # The environment stays the same across all testcases, so we 97 # save and restore the PATH env var in each test case that 98 # changes it: 99 self._saved_path = os.environ["PATH"] 100 self._saved_UNIXCONFDIR = distro._UNIXCONFDIR 101 102 def teardown_method(self, test_method): 103 os.environ["PATH"] = self._saved_path 104 distro._UNIXCONFDIR = self._saved_UNIXCONFDIR 105 106 def _setup_for_distro(self, distro_root): 107 distro_bin = os.path.join(distro_root, 'bin') 108 # We don't want to pick up a possibly present lsb_release in the 109 # distro that runs this test, so we use a PATH with only one entry: 110 os.environ["PATH"] = distro_bin 111 distro._UNIXCONFDIR = os.path.join(distro_root, RELATIVE_UNIXCONFDIR) 112 113 114@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 115class TestOSRelease: 116 117 def setup_method(self, test_method): 118 dist = test_method.__name__.split('_')[1] 119 os_release = os.path.join(DISTROS_DIR, dist, 'etc', 'os-release') 120 self.distro = distro.LinuxDistribution(False, os_release, 'non') 121 122 def _test_outcome(self, outcome): 123 assert self.distro.id() == outcome.get('id', '') 124 assert self.distro.name() == outcome.get('name', '') 125 assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') 126 assert self.distro.version() == outcome.get('version', '') 127 assert self.distro.version(pretty=True) == \ 128 outcome.get('pretty_version', '') 129 assert self.distro.version(best=True) == \ 130 outcome.get('best_version', '') 131 assert self.distro.like() == outcome.get('like', '') 132 assert self.distro.codename() == outcome.get('codename', '') 133 134 def test_arch_os_release(self): 135 desired_outcome = { 136 'id': 'arch', 137 'name': 'Arch Linux', 138 'pretty_name': 'Arch Linux', 139 } 140 self._test_outcome(desired_outcome) 141 142 def test_kali_os_release(self): 143 desired_outcome = { 144 'id': 'kali', 145 'name': 'Kali GNU/Linux', 146 'pretty_name': 'Kali GNU/Linux Rolling', 147 'version': '2017.1', 148 'pretty_version': '2017.1', 149 'best_version': '2017.1', 150 'like': 'debian' 151 } 152 self._test_outcome(desired_outcome) 153 154 def test_centos7_os_release(self): 155 desired_outcome = { 156 'id': 'centos', 157 'name': 'CentOS Linux', 158 'pretty_name': 'CentOS Linux 7 (Core)', 159 'version': '7', 160 'pretty_version': '7 (Core)', 161 'best_version': '7', 162 'like': 'rhel fedora', 163 'codename': 'Core' 164 } 165 self._test_outcome(desired_outcome) 166 167 def test_coreos_os_release(self): 168 desired_outcome = { 169 'id': 'coreos', 170 'name': 'CoreOS', 171 'pretty_name': 'CoreOS 899.15.0', 172 'version': '899.15.0', 173 'pretty_version': '899.15.0', 174 'best_version': '899.15.0' 175 } 176 self._test_outcome(desired_outcome) 177 178 def test_debian8_os_release(self): 179 desired_outcome = { 180 'id': 'debian', 181 'name': 'Debian GNU/Linux', 182 'pretty_name': 'Debian GNU/Linux 8 (jessie)', 183 'version': '8', 184 'pretty_version': '8 (jessie)', 185 'best_version': '8', 186 'codename': 'jessie' 187 } 188 self._test_outcome(desired_outcome) 189 190 def test_fedora19_os_release(self): 191 desired_outcome = { 192 'id': 'fedora', 193 'name': 'Fedora', 194 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', 195 'version': '19', 196 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', 197 'best_version': '19', 198 'codename': u'Schr\u00F6dinger\u2019s Cat' 199 } 200 self._test_outcome(desired_outcome) 201 202 def test_fedora23_os_release(self): 203 desired_outcome = { 204 'id': 'fedora', 205 'name': 'Fedora', 206 'pretty_name': 'Fedora 23 (Twenty Three)', 207 'version': '23', 208 'pretty_version': '23 (Twenty Three)', 209 'best_version': '23', 210 'codename': 'Twenty Three' 211 } 212 self._test_outcome(desired_outcome) 213 214 def test_fedora30_os_release(self): 215 # Fedora 21 and above no longer have code names but the metadata in os-release was only 216 # changed in a detectable way in Fedora 30+. The piece in parenthesis in the pretty_name 217 # field contains the VARIANT and differs depending on the variant which was installed. 218 desired_outcome = { 219 'id': 'fedora', 220 'name': 'Fedora', 221 'pretty_name': 'Fedora 30 (Thirty)', 222 'version': '30', 223 'pretty_version': '30', 224 'best_version': '30', 225 'codename': '' 226 } 227 self._test_outcome(desired_outcome) 228 229 def test_kvmibm1_os_release(self): 230 desired_outcome = { 231 'id': 'kvmibm', 232 'name': 'KVM for IBM z Systems', 233 'pretty_name': 'KVM for IBM z Systems 1.1.1 (Z)', 234 'version': '1.1.1', 235 'pretty_version': '1.1.1 (Z)', 236 'best_version': '1.1.1', 237 'like': 'rhel fedora', 238 'codename': 'Z' 239 } 240 self._test_outcome(desired_outcome) 241 242 def test_linuxmint17_os_release(self): 243 # Note: LinuxMint 17 actually *does* have Ubuntu 14.04 data in its 244 # os-release file. See discussion in GitHub issue #78. 245 desired_outcome = { 246 'id': 'ubuntu', 247 'name': 'Ubuntu', 248 'pretty_name': 'Ubuntu 14.04.3 LTS', 249 'version': '14.04', 250 'pretty_version': '14.04 (Trusty Tahr)', 251 'best_version': '14.04.3', 252 'like': 'debian', 253 'codename': 'Trusty Tahr' 254 } 255 self._test_outcome(desired_outcome) 256 257 def test_mageia5_os_release(self): 258 desired_outcome = { 259 'id': 'mageia', 260 'name': 'Mageia', 261 'pretty_name': 'Mageia 5', 262 'version': '5', 263 'pretty_version': '5', 264 'best_version': '5', 265 'like': 'mandriva fedora', 266 } 267 self._test_outcome(desired_outcome) 268 269 def test_manjaro1512_os_release(self): 270 self._test_outcome({ 271 'id': 'manjaro', 272 'name': 'Manjaro Linux', 273 'pretty_name': 'Manjaro Linux', 274 }) 275 276 def test_opensuse42_os_release(self): 277 desired_outcome = { 278 'id': 'opensuse', 279 'name': 'openSUSE Leap', 280 'pretty_name': 'openSUSE Leap 42.1 (x86_64)', 281 'version': '42.1', 282 'pretty_version': '42.1', 283 'best_version': '42.1', 284 'like': 'suse', 285 } 286 self._test_outcome(desired_outcome) 287 288 def test_raspbian7_os_release(self): 289 desired_outcome = { 290 'id': 'raspbian', 291 'name': 'Raspbian GNU/Linux', 292 'pretty_name': 'Raspbian GNU/Linux 7 (wheezy)', 293 'version': '7', 294 'pretty_version': '7 (wheezy)', 295 'best_version': '7', 296 'like': 'debian', 297 'codename': 'wheezy' 298 } 299 self._test_outcome(desired_outcome) 300 301 def test_raspbian8_os_release(self): 302 desired_outcome = { 303 'id': 'raspbian', 304 'name': 'Raspbian GNU/Linux', 305 'pretty_name': 'Raspbian GNU/Linux 8 (jessie)', 306 'version': '8', 307 'pretty_version': '8 (jessie)', 308 'best_version': '8', 309 'like': 'debian', 310 'codename': 'jessie' 311 } 312 self._test_outcome(desired_outcome) 313 314 def test_rhel7_os_release(self): 315 desired_outcome = { 316 'id': 'rhel', 317 'name': 'Red Hat Enterprise Linux Server', 318 'pretty_name': 'Red Hat Enterprise Linux Server 7.0 (Maipo)', 319 'version': '7.0', 320 'pretty_version': '7.0 (Maipo)', 321 'best_version': '7.0', 322 'like': 'fedora', 323 'codename': 'Maipo' 324 } 325 self._test_outcome(desired_outcome) 326 327 def test_slackware14_os_release(self): 328 desired_outcome = { 329 'id': 'slackware', 330 'name': 'Slackware', 331 'pretty_name': 'Slackware 14.1', 332 'version': '14.1', 333 'pretty_version': '14.1', 334 'best_version': '14.1' 335 } 336 self._test_outcome(desired_outcome) 337 338 def test_sles12_os_release(self): 339 desired_outcome = { 340 'id': 'sles', 341 'name': 'SLES', 342 'pretty_name': 'SUSE Linux Enterprise Server 12 SP1', 343 'version': '12.1', 344 'pretty_version': '12.1', 345 'best_version': '12.1' 346 } 347 self._test_outcome(desired_outcome) 348 349 def test_ubuntu14_os_release(self): 350 desired_outcome = { 351 'id': 'ubuntu', 352 'name': 'Ubuntu', 353 'pretty_name': 'Ubuntu 14.04.3 LTS', 354 'version': '14.04', 355 'pretty_version': '14.04 (Trusty Tahr)', 356 'best_version': '14.04.3', 357 'like': 'debian', 358 'codename': 'Trusty Tahr' 359 } 360 self._test_outcome(desired_outcome) 361 362 def test_ubuntu16_os_release(self): 363 desired_outcome = { 364 'id': 'ubuntu', 365 'name': 'Ubuntu', 366 'pretty_name': 'Ubuntu 16.04.1 LTS', 367 'version': '16.04', 368 'pretty_version': '16.04 (xenial)', 369 'best_version': '16.04.1', 370 'like': 'debian', 371 'codename': 'xenial' 372 } 373 self._test_outcome(desired_outcome) 374 375 def test_amazon2016_os_release(self): 376 desired_outcome = { 377 'id': 'amzn', 378 'name': 'Amazon Linux AMI', 379 'pretty_name': 'Amazon Linux AMI 2016.03', 380 'version': '2016.03', 381 'pretty_version': '2016.03', 382 'best_version': '2016.03', 383 'like': 'rhel fedora' 384 } 385 self._test_outcome(desired_outcome) 386 387 def test_scientific7_os_release(self): 388 desired_outcome = { 389 'id': 'rhel', 390 'name': 'Scientific Linux', 391 'pretty_name': 'Scientific Linux 7.2 (Nitrogen)', 392 'version': '7.2', 393 'pretty_version': '7.2 (Nitrogen)', 394 'best_version': '7.2', 395 'like': 'fedora', 396 'codename': 'Nitrogen' 397 } 398 self._test_outcome(desired_outcome) 399 400 def test_gentoo_os_release(self): 401 desired_outcome = { 402 'id': 'gentoo', 403 'name': 'Gentoo', 404 'pretty_name': 'Gentoo/Linux', 405 } 406 self._test_outcome(desired_outcome) 407 408 def test_openelec6_os_release(self): 409 desired_outcome = { 410 'id': 'openelec', 411 'name': 'OpenELEC', 412 'pretty_name': 'OpenELEC (official) - Version: 6.0.3', 413 'version': '6.0', 414 'pretty_version': '6.0', 415 'best_version': '6.0.3', 416 } 417 self._test_outcome(desired_outcome) 418 419 def test_cloudlinux7_os_release(self): 420 desired_outcome = { 421 'id': 'cloudlinux', 422 'codename': 'Yury Malyshev', 423 'name': 'CloudLinux', 424 'pretty_name': 'CloudLinux 7.3 (Yury Malyshev)', 425 'like': 'rhel fedora centos', 426 'version': '7.3', 427 'pretty_version': '7.3 (Yury Malyshev)', 428 'best_version': '7.3', 429 'major_version': '7', 430 'minor_version': '3' 431 } 432 self._test_outcome(desired_outcome) 433 434 435@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 436class TestLSBRelease(DistroTestCase): 437 438 def setup_method(self, test_method): 439 super(TestLSBRelease, self).setup_method(test_method) 440 dist = test_method.__name__.split('_')[1] 441 self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) 442 self.distro = distro.LinuxDistribution(True, 'non', 'non') 443 444 def _test_outcome(self, outcome): 445 assert self.distro.id() == outcome.get('id', '') 446 assert self.distro.name() == outcome.get('name', '') 447 assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') 448 assert self.distro.version() == outcome.get('version', '') 449 assert self.distro.version(pretty=True) == \ 450 outcome.get('pretty_version', '') 451 assert self.distro.version(best=True) == \ 452 outcome.get('best_version', '') 453 assert self.distro.like() == outcome.get('like', '') 454 assert self.distro.codename() == outcome.get('codename', '') 455 456 def test_linuxmint17_lsb_release(self): 457 desired_outcome = { 458 'id': 'linuxmint', 459 'name': 'LinuxMint', 460 'pretty_name': 'Linux Mint 17.3 Rosa', 461 'version': '17.3', 462 'pretty_version': '17.3 (rosa)', 463 'best_version': '17.3', 464 'codename': 'rosa' 465 } 466 self._test_outcome(desired_outcome) 467 468 def test_manjaro1512_lsb_release(self): 469 self._test_outcome({ 470 'id': 'manjarolinux', 471 'name': 'ManjaroLinux', 472 'pretty_name': 'Manjaro Linux', 473 'version': '15.12', 474 'pretty_version': '15.12 (Capella)', 475 'best_version': '15.12', 476 'codename': 'Capella' 477 }) 478 479 # @pytest.mark.xfail 480 # def test_openelec6_lsb_release(self): 481 # # TODO: This should be fixed as part of #109 when dealing 482 # # with distro inconsistencies 483 # desired_outcome = { 484 # 'id': 'openelec', 485 # 'name': 'OpenELEC', 486 # 'pretty_name': 'OpenELEC (official) - Version: 6.0.3', 487 # 'version': '6.0.3', 488 # 'pretty_version': '6.0.3', 489 # 'best_version': '6.0.3', 490 # } 491 # self._test_outcome(desired_outcome) 492 493 def test_openbsd62_uname(self): 494 self._test_outcome({ 495 'id': 'openbsd', 496 'name': 'OpenBSD', 497 'version': '6.2', 498 'pretty_name': 'OpenBSD 6.2', 499 'pretty_version': '6.2', 500 'best_version': '6.2' 501 }) 502 503 def test_netbsd711_uname(self): 504 self._test_outcome({ 505 'id': 'netbsd', 506 'name': 'NetBSD', 507 'version': '7.1.1', 508 'pretty_name': 'NetBSD 7.1.1', 509 'pretty_version': '7.1.1', 510 'best_version': '7.1.1' 511 }) 512 513 def test_freebsd111_uname(self): 514 self._test_outcome({ 515 'id': 'freebsd', 516 'name': 'FreeBSD', 517 'version': '11.1', 518 'pretty_name': 'FreeBSD 11.1', 519 'pretty_version': '11.1', 520 'best_version': '11.1' 521 }) 522 523 def test_ubuntu14normal_lsb_release(self): 524 self._setup_for_distro(os.path.join(TESTDISTROS, 'lsb', 525 'ubuntu14_normal')) 526 527 self.distro = distro.LinuxDistribution(True, 'non', 'non') 528 529 desired_outcome = { 530 'id': 'ubuntu', 531 'name': 'Ubuntu', 532 'pretty_name': 'Ubuntu 14.04.3 LTS', 533 'version': '14.04', 534 'pretty_version': '14.04 (trusty)', 535 'best_version': '14.04.3', 536 'codename': 'trusty' 537 } 538 self._test_outcome(desired_outcome) 539 540 def test_ubuntu14nomodules_lsb_release(self): 541 self._setup_for_distro(os.path.join(TESTDISTROS, 'lsb', 542 'ubuntu14_nomodules')) 543 544 self.distro = distro.LinuxDistribution(True, 'non', 'non') 545 546 desired_outcome = { 547 'id': 'ubuntu', 548 'name': 'Ubuntu', 549 'pretty_name': 'Ubuntu 14.04.3 LTS', 550 'version': '14.04', 551 'pretty_version': '14.04 (trusty)', 552 'best_version': '14.04.3', 553 'codename': 'trusty' 554 } 555 self._test_outcome(desired_outcome) 556 557 def test_trailingblanks_lsb_release(self): 558 self._setup_for_distro(os.path.join(TESTDISTROS, 'lsb', 559 'ubuntu14_trailingblanks')) 560 561 self.distro = distro.LinuxDistribution(True, 'non', 'non') 562 563 desired_outcome = { 564 'id': 'ubuntu', 565 'name': 'Ubuntu', 566 'pretty_name': 'Ubuntu 14.04.3 LTS', 567 'version': '14.04', 568 'pretty_version': '14.04 (trusty)', 569 'best_version': '14.04.3', 570 'codename': 'trusty' 571 } 572 self._test_outcome(desired_outcome) 573 574 @pytest.mark.parametrize('errnum', ('001', '002', '126', '130', '255')) 575 def test_lsb_release_error_level(self, errnum): 576 self._setup_for_distro(os.path.join( 577 TESTDISTROS, 'lsb', 'lsb_rc{0}'.format(errnum))) 578 with pytest.raises(subprocess.CalledProcessError) as excinfo: 579 distro.LinuxDistribution(True, 'non', 'non')._lsb_release_info 580 assert excinfo.value.returncode == int(errnum) 581 582 583@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 584class TestSpecialRelease(DistroTestCase): 585 def _test_outcome(self, outcome): 586 assert self.distro.id() == outcome.get('id', '') 587 assert self.distro.name() == outcome.get('name', '') 588 assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') 589 assert self.distro.version() == outcome.get('version', '') 590 assert self.distro.version(pretty=True) == \ 591 outcome.get('pretty_version', '') 592 assert self.distro.version(best=True) == \ 593 outcome.get('best_version', '') 594 assert self.distro.like() == outcome.get('like', '') 595 assert self.distro.codename() == outcome.get('codename', '') 596 assert self.distro.major_version() == outcome.get('major_version', '') 597 assert self.distro.minor_version() == outcome.get('minor_version', '') 598 assert self.distro.build_number() == outcome.get('build_number', '') 599 600 def test_empty_release(self): 601 distro_release = os.path.join(SPECIAL, 'empty-release') 602 self.distro = distro.LinuxDistribution(False, 'non', distro_release) 603 604 desired_outcome = { 605 'id': 'empty' 606 } 607 self._test_outcome(desired_outcome) 608 609 def test_unknowndistro_release(self): 610 self._setup_for_distro(os.path.join(TESTDISTROS, 'distro', 611 'unknowndistro')) 612 613 self.distro = distro.LinuxDistribution() 614 615 desired_outcome = { 616 'id': 'unknowndistro', 617 'name': 'Unknown Distro', 618 'pretty_name': 'Unknown Distro 1.0 (Unknown Codename)', 619 'version': '1.0', 620 'pretty_version': '1.0 (Unknown Codename)', 621 'best_version': '1.0', 622 'codename': 'Unknown Codename', 623 'major_version': '1', 624 'minor_version': '0' 625 } 626 self._test_outcome(desired_outcome) 627 628 def test_bad_uname(self): 629 self._setup_for_distro(os.path.join(TESTDISTROS, 'distro', 630 'baduname')) 631 self.distro = distro.LinuxDistribution() 632 633 assert self.distro.uname_attr('id') == '' 634 assert self.distro.uname_attr('name') == '' 635 assert self.distro.uname_attr('release') == '' 636 637 638@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 639class TestDistroRelease: 640 641 def _test_outcome(self, 642 outcome, 643 distro_name='', 644 version='', 645 release_file_id='', 646 release_file_suffix='release'): 647 release_file_id = release_file_id or distro_name 648 distro_release = os.path.join( 649 DISTROS_DIR, distro_name + version, 'etc', '{0}-{1}'.format( 650 release_file_id, release_file_suffix)) 651 self.distro = distro.LinuxDistribution(False, 'non', distro_release) 652 653 assert self.distro.id() == outcome.get('id', '') 654 assert self.distro.name() == outcome.get('name', '') 655 assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') 656 assert self.distro.version() == outcome.get('version', '') 657 assert self.distro.version(pretty=True) == \ 658 outcome.get('pretty_version', '') 659 assert self.distro.version(best=True) == \ 660 outcome.get('best_version', '') 661 assert self.distro.like() == outcome.get('like', '') 662 assert self.distro.codename() == outcome.get('codename', '') 663 assert self.distro.major_version() == outcome.get('major_version', '') 664 assert self.distro.minor_version() == outcome.get('minor_version', '') 665 assert self.distro.build_number() == outcome.get('build_number', '') 666 667 def test_arch_dist_release(self): 668 desired_outcome = { 669 'id': 'arch' 670 } 671 self._test_outcome(desired_outcome, 'arch') 672 673 def test_centos5_dist_release(self): 674 desired_outcome = { 675 'id': 'centos', 676 'name': 'CentOS', 677 'pretty_name': 'CentOS 5.11 (Final)', 678 'version': '5.11', 679 'pretty_version': '5.11 (Final)', 680 'best_version': '5.11', 681 'codename': 'Final', 682 'major_version': '5', 683 'minor_version': '11' 684 } 685 self._test_outcome(desired_outcome, 'centos', '5') 686 687 def test_centos7_dist_release(self): 688 desired_outcome = { 689 'id': 'centos', 690 'name': 'CentOS Linux', 691 'pretty_name': 'CentOS Linux 7.1.1503 (Core)', 692 'version': '7.1.1503', 693 'pretty_version': '7.1.1503 (Core)', 694 'best_version': '7.1.1503', 695 'codename': 'Core', 696 'major_version': '7', 697 'minor_version': '1', 698 'build_number': '1503' 699 } 700 self._test_outcome(desired_outcome, 'centos', '7') 701 702 def test_fedora19_dist_release(self): 703 desired_outcome = { 704 'id': 'fedora', 705 'name': 'Fedora', 706 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', 707 'version': '19', 708 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', 709 'best_version': '19', 710 'codename': u'Schr\u00F6dinger\u2019s Cat', 711 'major_version': '19' 712 } 713 self._test_outcome(desired_outcome, 'fedora', '19') 714 715 def test_fedora23_dist_release(self): 716 desired_outcome = { 717 'id': 'fedora', 718 'name': 'Fedora', 719 'pretty_name': 'Fedora 23 (Twenty Three)', 720 'version': '23', 721 'pretty_version': '23 (Twenty Three)', 722 'best_version': '23', 723 'codename': 'Twenty Three', 724 'major_version': '23' 725 } 726 self._test_outcome(desired_outcome, 'fedora', '23') 727 728 def test_fedora30_dist_release(self): 729 desired_outcome = { 730 'id': 'fedora', 731 'name': 'Fedora', 732 'pretty_name': 'Fedora 30 (Thirty)', 733 'version': '30', 734 'pretty_version': '30 (Thirty)', 735 'best_version': '30', 736 'codename': 'Thirty', 737 'major_version': '30' 738 } 739 self._test_outcome(desired_outcome, 'fedora', '30') 740 741 def test_gentoo_dist_release(self): 742 desired_outcome = { 743 'id': 'gentoo', 744 'name': 'Gentoo Base System', 745 'pretty_name': 'Gentoo Base System 2.2', 746 'version': '2.2', 747 'pretty_version': '2.2', 748 'best_version': '2.2', 749 'major_version': '2', 750 'minor_version': '2', 751 } 752 self._test_outcome(desired_outcome, 'gentoo') 753 754 def test_kvmibm1_dist_release(self): 755 desired_outcome = { 756 'id': 'base', 757 'name': 'KVM for IBM z Systems', 758 'pretty_name': 'KVM for IBM z Systems 1.1.1 (Z)', 759 'version': '1.1.1', 760 'pretty_version': '1.1.1 (Z)', 761 'best_version': '1.1.1', 762 'codename': 'Z', 763 'major_version': '1', 764 'minor_version': '1', 765 'build_number': '1' 766 } 767 self._test_outcome(desired_outcome, 'kvmibm', '1', 'base') 768 769 def test_mageia5_dist_release(self): 770 desired_outcome = { 771 'id': 'mageia', 772 'name': 'Mageia', 773 'pretty_name': 'Mageia 5 (Official)', 774 'version': '5', 775 'pretty_version': '5 (Official)', 776 'best_version': '5', 777 'codename': 'Official', 778 'major_version': '5' 779 } 780 self._test_outcome(desired_outcome, 'mageia', '5') 781 782 def test_manjaro1512_dist_release(self): 783 self._test_outcome({ 784 'id': 'manjaro', 785 'name': 'Manjaro Linux', 786 'pretty_name': 'Manjaro Linux', 787 'version': '', 788 'codename': '' 789 }, 'manjaro', '1512') 790 791 def test_opensuse42_dist_release(self): 792 desired_outcome = { 793 'id': 'suse', 794 'name': 'openSUSE', 795 'pretty_name': 'openSUSE 42.1 (x86_64)', 796 'version': '42.1', 797 'pretty_version': '42.1 (x86_64)', 798 'best_version': '42.1', 799 'codename': 'x86_64', 800 'major_version': '42', 801 'minor_version': '1' 802 } 803 self._test_outcome(desired_outcome, 'opensuse', '42', 'SuSE') 804 805 def test_oracle7_dist_release(self): 806 desired_outcome = { 807 'id': 'oracle', 808 'name': 'Oracle Linux Server', 809 'pretty_name': 'Oracle Linux Server 7.5', 810 'version': '7.5', 811 'pretty_version': '7.5', 812 'best_version': '7.5', 813 'major_version': '7', 814 'minor_version': '5' 815 } 816 self._test_outcome(desired_outcome, 'oracle', '7') 817 818 def test_rhel6_dist_release(self): 819 desired_outcome = { 820 'id': 'rhel', 821 'name': 'Red Hat Enterprise Linux Server', 822 'pretty_name': 'Red Hat Enterprise Linux Server 6.5 (Santiago)', 823 'version': '6.5', 824 'pretty_version': '6.5 (Santiago)', 825 'best_version': '6.5', 826 'codename': 'Santiago', 827 'major_version': '6', 828 'minor_version': '5' 829 } 830 self._test_outcome(desired_outcome, 'rhel', '6', 'redhat') 831 832 def test_rhel7_dist_release(self): 833 desired_outcome = { 834 'id': 'rhel', 835 'name': 'Red Hat Enterprise Linux Server', 836 'pretty_name': 'Red Hat Enterprise Linux Server 7.0 (Maipo)', 837 'version': '7.0', 838 'pretty_version': '7.0 (Maipo)', 839 'best_version': '7.0', 840 'codename': 'Maipo', 841 'major_version': '7', 842 'minor_version': '0' 843 } 844 self._test_outcome(desired_outcome, 'rhel', '7', 'redhat') 845 846 def test_slackware14_dist_release(self): 847 desired_outcome = { 848 'id': 'slackware', 849 'name': 'Slackware', 850 'pretty_name': 'Slackware 14.1', 851 'version': '14.1', 852 'pretty_version': '14.1', 853 'best_version': '14.1', 854 'major_version': '14', 855 'minor_version': '1' 856 } 857 self._test_outcome( 858 desired_outcome, 859 'slackware', 860 '14', 861 release_file_suffix='version') 862 863 def test_sles12_dist_release(self): 864 desired_outcome = { 865 'id': 'suse', 866 'name': 'SUSE Linux Enterprise Server', 867 'pretty_name': 'SUSE Linux Enterprise Server 12 (s390x)', 868 'version': '12', 869 'pretty_version': '12 (s390x)', 870 'best_version': '12', 871 'major_version': '12', 872 'codename': 's390x' 873 } 874 self._test_outcome(desired_outcome, 'sles', '12', 'SuSE') 875 876 def test_cloudlinux5_dist_release(self): 877 # Uses redhat-release only to get information. 878 # The id of 'rhel' can only be fixed with issue #109. 879 desired_outcome = { 880 'id': 'cloudlinux', 881 'codename': 'Vladislav Volkov', 882 'name': 'CloudLinux Server', 883 'pretty_name': 'CloudLinux Server 5.11 (Vladislav Volkov)', 884 'version': '5.11', 885 'pretty_version': '5.11 (Vladislav Volkov)', 886 'best_version': '5.11', 887 'major_version': '5', 888 'minor_version': '11' 889 } 890 self._test_outcome(desired_outcome, 'cloudlinux', '5', 'redhat') 891 892 def test_cloudlinux6_dist_release(self): 893 # Same as above, only has redhat-release. 894 desired_outcome = { 895 'id': 'cloudlinux', 896 'codename': 'Oleg Makarov', 897 'name': 'CloudLinux Server', 898 'pretty_name': 'CloudLinux Server 6.8 (Oleg Makarov)', 899 'version': '6.8', 900 'pretty_version': '6.8 (Oleg Makarov)', 901 'best_version': '6.8', 902 'major_version': '6', 903 'minor_version': '8' 904 } 905 self._test_outcome(desired_outcome, 'cloudlinux', '6', 'redhat') 906 907 def test_cloudlinux7_dist_release(self): 908 desired_outcome = { 909 'id': 'cloudlinux', 910 'codename': 'Yury Malyshev', 911 'name': 'CloudLinux', 912 'pretty_name': 'CloudLinux 7.3 (Yury Malyshev)', 913 'version': '7.3', 914 'pretty_version': '7.3 (Yury Malyshev)', 915 'best_version': '7.3', 916 'major_version': '7', 917 'minor_version': '3' 918 } 919 self._test_outcome(desired_outcome, 'cloudlinux', '7', 'redhat') 920 921 922@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 923class TestOverall(DistroTestCase): 924 """Test a LinuxDistribution object created with default arguments. 925 926 The direct accessor functions on that object are tested (e.g. `id()`); they 927 implement the precedence between the different sources of information. 928 929 In addition, because the distro release file is searched when not 930 specified, the information resulting from the distro release file is also 931 tested. The LSB and os-release sources are not tested again, because their 932 test is already done in TestLSBRelease and TestOSRelease, and their 933 algorithm does not depend on whether or not the file is specified. 934 935 TODO: This class should have testcases for all distros that are claimed 936 to be reliably maintained w.r.t. to their ID (see `id()`). Testcases for 937 the following distros are still missing: 938 * `amazon` - Amazon Linux 939 * `gentoo` - GenToo Linux 940 * `ibm_powerkvm` - IBM PowerKVM 941 * `parallels` - Parallels 942 * `pidora` - Pidora (Fedora remix for Raspberry Pi) 943 * `raspbian` - Raspbian 944 * `scientific` - Scientific Linux 945 * `xenserver` - XenServer 946 """ 947 948 def setup_method(self, test_method): 949 super(TestOverall, self).setup_method(test_method) 950 dist = test_method.__name__.split('_')[1] 951 self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) 952 self.distro = distro.LinuxDistribution() 953 954 def _test_outcome(self, outcome): 955 assert self.distro.id() == outcome.get('id', '') 956 assert self.distro.name() == outcome.get('name', '') 957 assert self.distro.name(pretty=True) == outcome.get('pretty_name', '') 958 assert self.distro.version() == outcome.get('version', '') 959 assert self.distro.version(pretty=True) == \ 960 outcome.get('pretty_version', '') 961 assert self.distro.version(best=True) == \ 962 outcome.get('best_version', '') 963 assert self.distro.like() == outcome.get('like', '') 964 assert self.distro.codename() == outcome.get('codename', '') 965 assert self.distro.major_version() == outcome.get('major_version', '') 966 assert self.distro.minor_version() == outcome.get('minor_version', '') 967 assert self.distro.build_number() == outcome.get('build_number', '') 968 969 def _test_non_existing_release_file(self): 970 # Test the info from the searched distro release file 971 # does not have one. 972 assert self.distro.distro_release_file == '' 973 assert len(self.distro.distro_release_info()) == 0 974 975 def _test_release_file_info(self, filename, outcome): 976 # Test the info from the searched distro release file 977 assert os.path.basename(self.distro.distro_release_file) == filename 978 distro_info = self.distro.distro_release_info() 979 for key, value in outcome.items(): 980 assert distro_info[key] == value 981 return distro_info 982 983 def test_arch_release(self): 984 desired_outcome = { 985 'id': 'arch', 986 'name': 'Arch Linux', 987 'pretty_name': 'Arch Linux', 988 } 989 self._test_outcome(desired_outcome) 990 991 # Test the info from the searched distro release file 992 # Does not have one; The empty /etc/arch-release file is not 993 # considered a valid distro release file: 994 self._test_non_existing_release_file() 995 996 def test_centos5_release(self): 997 desired_outcome = { 998 'id': 'centos', 999 'name': 'CentOS', 1000 'pretty_name': 'CentOS 5.11 (Final)', 1001 'version': '5.11', 1002 'pretty_version': '5.11 (Final)', 1003 'best_version': '5.11', 1004 'codename': 'Final', 1005 'major_version': '5', 1006 'minor_version': '11' 1007 } 1008 self._test_outcome(desired_outcome) 1009 1010 desired_info = { 1011 'id': 'centos', 1012 'name': 'CentOS', 1013 'version_id': '5.11', 1014 'codename': 'Final' 1015 } 1016 self._test_release_file_info('centos-release', desired_info) 1017 1018 def test_centos7_release(self): 1019 desired_outcome = { 1020 'id': 'centos', 1021 'name': 'CentOS Linux', 1022 'pretty_name': 'CentOS Linux 7 (Core)', 1023 'version': '7', 1024 'pretty_version': '7 (Core)', 1025 'best_version': '7.1.1503', 1026 'like': 'rhel fedora', 1027 'codename': 'Core', 1028 'major_version': '7' 1029 } 1030 self._test_outcome(desired_outcome) 1031 1032 desired_info = { 1033 'id': 'centos', 1034 'name': 'CentOS Linux', 1035 'version_id': '7.1.1503', 1036 'codename': 'Core' 1037 } 1038 self._test_release_file_info('centos-release', desired_info) 1039 1040 def test_coreos_release(self): 1041 desired_outcome = { 1042 'id': 'coreos', 1043 'name': 'CoreOS', 1044 'pretty_name': 'CoreOS 899.15.0', 1045 'version': '899.15.0', 1046 'pretty_version': '899.15.0', 1047 'best_version': '899.15.0', 1048 'major_version': '899', 1049 'minor_version': '15', 1050 'build_number': '0' 1051 } 1052 self._test_outcome(desired_outcome) 1053 self._test_non_existing_release_file() 1054 1055 def test_debian8_release(self): 1056 desired_outcome = { 1057 'id': 'debian', 1058 'name': 'Debian GNU/Linux', 1059 'pretty_name': 'Debian GNU/Linux 8 (jessie)', 1060 'version': '8', 1061 'pretty_version': '8 (jessie)', 1062 'best_version': '8.2', 1063 'codename': 'jessie', 1064 'major_version': '8' 1065 } 1066 self._test_outcome(desired_outcome) 1067 self._test_non_existing_release_file() 1068 1069 def test_exherbo_release(self): 1070 desired_outcome = { 1071 'id': 'exherbo', 1072 'name': 'Exherbo', 1073 'pretty_name': 'Exherbo Linux', 1074 } 1075 self._test_outcome(desired_outcome) 1076 1077 def test_fedora19_release(self): 1078 desired_outcome = { 1079 'id': 'fedora', 1080 'name': 'Fedora', 1081 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', 1082 'version': '19', 1083 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', 1084 'best_version': '19', 1085 'codename': u'Schr\u00F6dinger\u2019s Cat', 1086 'major_version': '19' 1087 } 1088 self._test_outcome(desired_outcome) 1089 1090 desired_info = { 1091 'id': 'fedora', 1092 'name': 'Fedora', 1093 'version_id': '19', 1094 'codename': u'Schr\u00F6dinger\u2019s Cat' 1095 } 1096 self._test_release_file_info('fedora-release', desired_info) 1097 1098 def test_fedora23_release(self): 1099 desired_outcome = { 1100 'id': 'fedora', 1101 'name': 'Fedora', 1102 'pretty_name': 'Fedora 23 (Twenty Three)', 1103 'version': '23', 1104 'pretty_version': '23 (Twenty Three)', 1105 'best_version': '23', 1106 'codename': 'Twenty Three', 1107 'major_version': '23' 1108 } 1109 self._test_outcome(desired_outcome) 1110 1111 desired_info = { 1112 'id': 'fedora', 1113 'name': 'Fedora', 1114 'version_id': '23', 1115 'codename': 'Twenty Three' 1116 } 1117 self._test_release_file_info('fedora-release', desired_info) 1118 1119 def test_fedora30_release(self): 1120 desired_outcome = { 1121 'id': 'fedora', 1122 'name': 'Fedora', 1123 'pretty_name': 'Fedora 30 (Thirty)', 1124 'version': '30', 1125 'pretty_version': '30', 1126 'best_version': '30', 1127 'codename': '', 1128 'major_version': '30' 1129 } 1130 self._test_outcome(desired_outcome) 1131 1132 desired_info = { 1133 'id': 'fedora', 1134 'name': 'Fedora', 1135 'version_id': '30', 1136 'codename': 'Thirty' 1137 } 1138 self._test_release_file_info('fedora-release', desired_info) 1139 1140 def test_kvmibm1_release(self): 1141 desired_outcome = { 1142 'id': 'kvmibm', 1143 'name': 'KVM for IBM z Systems', 1144 'pretty_name': 'KVM for IBM z Systems 1.1.1 (Z)', 1145 'version': '1.1.1', 1146 'pretty_version': '1.1.1 (Z)', 1147 'best_version': '1.1.1', 1148 'like': 'rhel fedora', 1149 'codename': 'Z', 1150 'major_version': '1', 1151 'minor_version': '1', 1152 'build_number': '1' 1153 } 1154 self._test_outcome(desired_outcome) 1155 1156 desired_info = { 1157 'id': 'base', 1158 'name': 'KVM for IBM z Systems', 1159 'version_id': '1.1.1', 1160 'codename': 'Z' 1161 } 1162 self._test_release_file_info('base-release', desired_info) 1163 1164 def test_linuxmint17_release(self): 1165 desired_outcome = { 1166 'id': 'ubuntu', 1167 'name': 'Ubuntu', 1168 'pretty_name': 'Ubuntu 14.04.3 LTS', 1169 'version': '14.04', 1170 'pretty_version': '14.04 (Trusty Tahr)', 1171 'best_version': '14.04.3', 1172 'like': 'debian', 1173 'codename': 'Trusty Tahr', 1174 'major_version': '14', 1175 'minor_version': '04' 1176 } 1177 self._test_outcome(desired_outcome) 1178 self._test_non_existing_release_file() 1179 1180 def test_mageia5_release(self): 1181 desired_outcome = { 1182 'id': 'mageia', 1183 'name': 'Mageia', 1184 'pretty_name': 'Mageia 5', 1185 'version': '5', 1186 'pretty_version': '5 (thornicroft)', 1187 'best_version': '5', 1188 'like': 'mandriva fedora', 1189 # TODO: Codename differs between distro release and lsb_release. 1190 'codename': 'thornicroft', 1191 'major_version': '5' 1192 } 1193 self._test_outcome(desired_outcome) 1194 1195 desired_info = { 1196 'id': 'mageia', 1197 'name': 'Mageia', 1198 'version_id': '5', 1199 'codename': 'Official' 1200 } 1201 self._test_release_file_info('mageia-release', desired_info) 1202 1203 def test_manjaro1512_release(self): 1204 self._test_outcome({ 1205 'id': 'manjaro', 1206 'name': 'Manjaro Linux', 1207 'pretty_name': 'Manjaro Linux', 1208 'version': '15.12', 1209 'pretty_version': '15.12 (Capella)', 1210 'best_version': '15.12', 1211 'major_version': '15', 1212 'minor_version': '12', 1213 'codename': 'Capella' 1214 }) 1215 1216 self._test_release_file_info( 1217 'manjaro-release', 1218 {'id': 'manjaro', 1219 'name': 'Manjaro Linux'}) 1220 1221 def test_opensuse42_release(self): 1222 desired_outcome = { 1223 'id': 'opensuse', 1224 'name': 'openSUSE Leap', 1225 'pretty_name': 'openSUSE Leap 42.1 (x86_64)', 1226 'version': '42.1', 1227 'pretty_version': '42.1 (x86_64)', 1228 'best_version': '42.1', 1229 'like': 'suse', 1230 'codename': 'x86_64', 1231 'major_version': '42', 1232 'minor_version': '1' 1233 } 1234 self._test_outcome(desired_outcome) 1235 1236 desired_info = { 1237 'id': 'SuSE', 1238 'name': 'openSUSE', 1239 'version_id': '42.1', 1240 'codename': 'x86_64' 1241 } 1242 self._test_release_file_info('SuSE-release', desired_info) 1243 1244 def test_oracle7_release(self): 1245 desired_outcome = { 1246 'id': 'oracle', 1247 'name': 'Oracle Linux Server', 1248 'pretty_name': 'Oracle Linux Server 7.5', 1249 'version': '7.5', 1250 'pretty_version': '7.5', 1251 'best_version': '7.5', 1252 'major_version': '7', 1253 'minor_version': '5' 1254 } 1255 self._test_outcome(desired_outcome) 1256 1257 desired_info = { 1258 'id': 'oracle', 1259 'name': 'Oracle Linux Server', 1260 'version_id': '7.5', 1261 } 1262 distro_info = self._test_release_file_info( 1263 'oracle-release', desired_info) 1264 assert 'codename' not in distro_info 1265 1266 def test_raspbian7_release(self): 1267 desired_outcome = { 1268 'id': 'raspbian', 1269 'name': 'Raspbian GNU/Linux', 1270 'pretty_name': 'Raspbian GNU/Linux 7 (wheezy)', 1271 'version': '7', 1272 'pretty_version': '7 (wheezy)', 1273 'best_version': '7', 1274 'like': 'debian', 1275 'codename': 'wheezy', 1276 'major_version': '7', 1277 } 1278 self._test_outcome(desired_outcome) 1279 self._test_non_existing_release_file() 1280 1281 def test_raspbian8_release(self): 1282 desired_outcome = { 1283 'id': 'raspbian', 1284 'name': 'Raspbian GNU/Linux', 1285 'pretty_name': 'Raspbian GNU/Linux 8 (jessie)', 1286 'version': '8', 1287 'pretty_version': '8 (jessie)', 1288 'best_version': '8', 1289 'like': 'debian', 1290 'codename': 'jessie', 1291 'major_version': '8', 1292 } 1293 self._test_outcome(desired_outcome) 1294 self._test_non_existing_release_file() 1295 1296 def test_rhel5_release(self): 1297 desired_outcome = { 1298 'id': 'rhel', 1299 'name': 'Red Hat Enterprise Linux Server', 1300 'pretty_name': 'Red Hat Enterprise Linux Server 5.11 (Tikanga)', 1301 'version': '5.11', 1302 'pretty_version': '5.11 (Tikanga)', 1303 'best_version': '5.11', 1304 'codename': 'Tikanga', 1305 'major_version': '5', 1306 'minor_version': '11' 1307 } 1308 self._test_outcome(desired_outcome) 1309 1310 desired_info = { 1311 'id': 'redhat', 1312 'name': 'Red Hat Enterprise Linux Server', 1313 'version_id': '5.11', 1314 'codename': 'Tikanga' 1315 } 1316 self._test_release_file_info('redhat-release', desired_info) 1317 1318 def test_rhel6_release(self): 1319 desired_outcome = { 1320 'id': 'rhel', 1321 'name': 'Red Hat Enterprise Linux Server', 1322 'pretty_name': 'Red Hat Enterprise Linux Server 6.5 (Santiago)', 1323 'version': '6.5', 1324 'pretty_version': '6.5 (Santiago)', 1325 'best_version': '6.5', 1326 'codename': 'Santiago', 1327 'major_version': '6', 1328 'minor_version': '5' 1329 } 1330 self._test_outcome(desired_outcome) 1331 1332 desired_info = { 1333 'id': 'redhat', 1334 'name': 'Red Hat Enterprise Linux Server', 1335 'version_id': '6.5', 1336 'codename': 'Santiago' 1337 } 1338 self._test_release_file_info('redhat-release', desired_info) 1339 1340 def test_rhel7_release(self): 1341 desired_outcome = { 1342 'id': 'rhel', 1343 'name': 'Red Hat Enterprise Linux Server', 1344 'pretty_name': 'Red Hat Enterprise Linux Server 7.0 (Maipo)', 1345 'version': '7.0', 1346 'pretty_version': '7.0 (Maipo)', 1347 'best_version': '7.0', 1348 'like': 'fedora', 1349 'codename': 'Maipo', 1350 'major_version': '7', 1351 'minor_version': '0' 1352 } 1353 self._test_outcome(desired_outcome) 1354 1355 desired_info = { 1356 'id': 'redhat', 1357 'name': 'Red Hat Enterprise Linux Server', 1358 'version_id': '7.0', 1359 'codename': 'Maipo' 1360 } 1361 self._test_release_file_info('redhat-release', desired_info) 1362 1363 def test_slackware14_release(self): 1364 desired_outcome = { 1365 'id': 'slackware', 1366 'name': 'Slackware', 1367 'pretty_name': 'Slackware 14.1', 1368 'version': '14.1', 1369 'pretty_version': '14.1', 1370 'best_version': '14.1', 1371 'major_version': '14', 1372 'minor_version': '1' 1373 } 1374 self._test_outcome(desired_outcome) 1375 1376 desired_info = { 1377 'id': 'slackware', 1378 'name': 'Slackware', 1379 'version_id': '14.1', 1380 } 1381 distro_info = self._test_release_file_info( 1382 'slackware-version', desired_info) 1383 assert 'codename' not in distro_info 1384 1385 def test_sles12_release(self): 1386 desired_outcome = { 1387 'id': 'sles', 1388 'name': 'SLES', 1389 'pretty_name': 'SUSE Linux Enterprise Server 12 SP1', 1390 'version': '12.1', 1391 'pretty_version': '12.1 (n/a)', 1392 'best_version': '12.1', 1393 'codename': 'n/a', 1394 'major_version': '12', 1395 'minor_version': '1' 1396 } 1397 self._test_outcome(desired_outcome) 1398 1399 desired_info = { 1400 'id': 'SuSE', 1401 'name': 'SUSE Linux Enterprise Server', 1402 'version_id': '12', 1403 'codename': 's390x' 1404 } 1405 self._test_release_file_info('SuSE-release', desired_info) 1406 1407 def test_ubuntu14_release(self): 1408 desired_outcome = { 1409 'id': 'ubuntu', 1410 'name': 'Ubuntu', 1411 'pretty_name': 'Ubuntu 14.04.3 LTS', 1412 'version': '14.04', 1413 'pretty_version': '14.04 (Trusty Tahr)', 1414 'best_version': '14.04.3', 1415 'like': 'debian', 1416 'codename': 'Trusty Tahr', 1417 'major_version': '14', 1418 'minor_version': '04' 1419 } 1420 self._test_outcome(desired_outcome) 1421 1422 # Test the info from the searched distro release file 1423 # Does not have one; /etc/debian_version is not considered a distro 1424 # release file: 1425 self._test_non_existing_release_file() 1426 1427 def test_ubuntu16_release(self): 1428 desired_outcome = { 1429 'id': 'ubuntu', 1430 'name': 'Ubuntu', 1431 'pretty_name': 'Ubuntu 16.04.1 LTS', 1432 'version': '16.04', 1433 'pretty_version': '16.04 (xenial)', 1434 'best_version': '16.04.1', 1435 'like': 'debian', 1436 'codename': 'xenial', 1437 'major_version': '16', 1438 'minor_version': '04' 1439 } 1440 self._test_outcome(desired_outcome) 1441 1442 # Test the info from the searched distro release file 1443 # Does not have one; /etc/debian_version is not considered a distro 1444 # release file: 1445 self._test_non_existing_release_file() 1446 1447 def test_amazon2016_release(self): 1448 desired_outcome = { 1449 'id': 'amzn', 1450 'name': 'Amazon Linux AMI', 1451 'pretty_name': 'Amazon Linux AMI 2016.03', 1452 'version': '2016.03', 1453 'pretty_version': '2016.03', 1454 'best_version': '2016.03', 1455 'like': 'rhel fedora', 1456 'major_version': '2016', 1457 'minor_version': '03' 1458 } 1459 self._test_outcome(desired_outcome) 1460 1461 def test_amazon2014_release(self): 1462 # Amazon Linux 2014 only contains a system-release file. 1463 # distro doesn't currently handle it. 1464 desired_outcome = {} 1465 self._test_outcome(desired_outcome) 1466 1467 def test_scientific6_release(self): 1468 desired_outcome = { 1469 'id': 'rhel', 1470 'name': 'Scientific Linux', 1471 'pretty_name': 'Scientific Linux 6.4 (Carbon)', 1472 'version': '6.4', 1473 'pretty_version': '6.4 (Carbon)', 1474 'best_version': '6.4', 1475 'codename': 'Carbon', 1476 'major_version': '6', 1477 'minor_version': '4', 1478 1479 } 1480 self._test_outcome(desired_outcome) 1481 1482 desired_info = { 1483 'id': 'redhat', 1484 'name': 'Scientific Linux', 1485 'version_id': '6.4', 1486 'codename': 'Carbon' 1487 } 1488 self._test_release_file_info('redhat-release', desired_info) 1489 1490 def test_scientific7_release(self): 1491 desired_outcome = { 1492 'id': 'rhel', 1493 'name': 'Scientific Linux', 1494 'pretty_name': 'Scientific Linux 7.2 (Nitrogen)', 1495 'version': '7.2', 1496 'pretty_version': '7.2 (Nitrogen)', 1497 'best_version': '7.2', 1498 'like': 'fedora', 1499 'codename': 'Nitrogen', 1500 'major_version': '7', 1501 'minor_version': '2', 1502 } 1503 self._test_outcome(desired_outcome) 1504 1505 desired_info = { 1506 'id': 'redhat', 1507 'name': 'Scientific Linux', 1508 'version_id': '7.2', 1509 'codename': 'Nitrogen' 1510 } 1511 self._test_release_file_info('redhat-release', desired_info) 1512 1513 def test_gentoo_release(self): 1514 desired_outcome = { 1515 'id': 'gentoo', 1516 'name': 'Gentoo', 1517 'pretty_name': 'Gentoo/Linux', 1518 'version': '2.2', 1519 'pretty_version': '2.2', 1520 'best_version': '2.2', 1521 'major_version': '2', 1522 'minor_version': '2', 1523 } 1524 self._test_outcome(desired_outcome) 1525 1526 desired_info = { 1527 'id': 'gentoo', 1528 'name': 'Gentoo Base System', 1529 'version_id': '2.2', 1530 } 1531 self._test_release_file_info('gentoo-release', desired_info) 1532 1533 def test_openelec6_release(self): 1534 desired_outcome = { 1535 'id': 'openelec', 1536 'name': 'OpenELEC', 1537 'pretty_name': 'OpenELEC (official) - Version: 6.0.3', 1538 'version': '6.0', 1539 'pretty_version': '6.0', 1540 'best_version': '6.0.3', 1541 'major_version': '6', 1542 'minor_version': '0', 1543 } 1544 self._test_outcome(desired_outcome) 1545 1546 def test_mandriva2011_release(self): 1547 desired_outcome = { 1548 'id': 'mandrivalinux', 1549 'name': 'MandrivaLinux', 1550 'pretty_name': 'Mandriva Linux 2011.0', 1551 'version': '2011.0', 1552 'pretty_version': '2011.0 (turtle)', 1553 'best_version': '2011.0', 1554 'major_version': '2011', 1555 'minor_version': '0', 1556 'codename': 'turtle' 1557 } 1558 self._test_outcome(desired_outcome) 1559 1560 desired_info = { 1561 'id': 'mandrake', 1562 'name': 'Mandriva Linux', 1563 'version_id': '2011.0', 1564 } 1565 self._test_release_file_info('mandrake-release', desired_info) 1566 1567 def test_cloudlinux5_release(self): 1568 # Uses redhat-release only to get information. 1569 # The id of 'rhel' can only be fixed with issue #109. 1570 desired_outcome = { 1571 'id': 'cloudlinux', 1572 'codename': 'Vladislav Volkov', 1573 'name': 'CloudLinux Server', 1574 'pretty_name': 'CloudLinux Server 5.11 (Vladislav Volkov)', 1575 'version': '5.11', 1576 'pretty_version': '5.11 (Vladislav Volkov)', 1577 'best_version': '5.11', 1578 'major_version': '5', 1579 'minor_version': '11' 1580 } 1581 self._test_outcome(desired_outcome) 1582 1583 def test_cloudlinux6_release(self): 1584 # Same as above, only has redhat-release. 1585 desired_outcome = { 1586 'id': 'cloudlinux', 1587 'codename': 'Oleg Makarov', 1588 'name': 'CloudLinux Server', 1589 'pretty_name': 'CloudLinux Server 6.8 (Oleg Makarov)', 1590 'version': '6.8', 1591 'pretty_version': '6.8 (Oleg Makarov)', 1592 'best_version': '6.8', 1593 'major_version': '6', 1594 'minor_version': '8' 1595 } 1596 self._test_outcome(desired_outcome) 1597 1598 def test_cloudlinux7_release(self): 1599 desired_outcome = { 1600 'id': 'cloudlinux', 1601 'codename': 'Yury Malyshev', 1602 'name': 'CloudLinux', 1603 'pretty_name': 'CloudLinux 7.3 (Yury Malyshev)', 1604 'like': 'rhel fedora centos', 1605 'version': '7.3', 1606 'pretty_version': '7.3 (Yury Malyshev)', 1607 'best_version': '7.3', 1608 'major_version': '7', 1609 'minor_version': '3' 1610 } 1611 self._test_outcome(desired_outcome) 1612 1613 1614def _bad_os_listdir(path='.'): 1615 """ This function is used by TestOverallWithEtcNotReadable to simulate 1616 a folder that cannot be called with os.listdir() but files are still 1617 readable. Forces distro to guess which *-release files are available. """ 1618 raise OSError() 1619 1620 1621@pytest.mark.skipIf(not IS_LINUX, reason='Irrelevant on non-linx') 1622class TestOverallWithEtcNotReadable(TestOverall): 1623 def setup_method(self, test_method): 1624 self._old_listdir = os.listdir 1625 os.listdir = _bad_os_listdir 1626 super(TestOverallWithEtcNotReadable, self).setup_method(test_method) 1627 1628 def teardown_method(self, test_method): 1629 super(TestOverallWithEtcNotReadable, self).teardown_method(test_method) 1630 if os.listdir is _bad_os_listdir: 1631 os.listdir = self._old_listdir 1632 1633 1634@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 1635class TestGetAttr(DistroTestCase): 1636 """Test the consistency between the results of 1637 `{source}_release_attr()` and `{source}_release_info()` for all 1638 distros in `DISTROS`. 1639 """ 1640 1641 def _test_attr(self, info_method, attr_method): 1642 for dist in DISTROS: 1643 self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) 1644 _distro = distro.LinuxDistribution() 1645 info = getattr(_distro, info_method)() 1646 for key in info.keys(): 1647 try: 1648 assert info[key] == getattr(_distro, attr_method)(key) 1649 except AssertionError: 1650 print("distro: {0}, key: {1}".format(dist, key)) 1651 1652 def test_os_release_attr(self): 1653 self._test_attr('os_release_info', 'os_release_attr') 1654 1655 def test_lsb_release_attr(self): 1656 self._test_attr('lsb_release_info', 'lsb_release_attr') 1657 1658 def test_distro_release_attr(self): 1659 self._test_attr('distro_release_info', 'distro_release_attr') 1660 1661 1662@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 1663class TestInfo(DistroTestCase): 1664 1665 def setup_method(self, test_method): 1666 super(TestInfo, self).setup_method(test_method) 1667 self.ubuntu14_os_release = os.path.join( 1668 DISTROS_DIR, 'ubuntu14', 'etc', 'os-release') 1669 1670 def test_info(self): 1671 _distro = distro.LinuxDistribution( 1672 False, self.ubuntu14_os_release, 'non') 1673 1674 desired_info = { 1675 'id': 'ubuntu', 1676 'version': '14.04', 1677 'like': 'debian', 1678 'version_parts': { 1679 'major': '14', 1680 'minor': '04', 1681 'build_number': '' 1682 }, 1683 'codename': 'Trusty Tahr' 1684 } 1685 1686 info = _distro.info() 1687 assert info == desired_info 1688 1689 desired_info_diff = { 1690 'version': '14.04 (Trusty Tahr)' 1691 } 1692 desired_info.update(desired_info_diff) 1693 info = _distro.info(pretty=True) 1694 assert info == desired_info 1695 1696 desired_info_diff = { 1697 'version': '14.04.3', 1698 'version_parts': { 1699 'major': '14', 1700 'minor': '04', 1701 'build_number': '3' 1702 } 1703 } 1704 desired_info.update(desired_info_diff) 1705 info = _distro.info(best=True) 1706 assert info == desired_info 1707 1708 desired_info_diff = { 1709 'version': '14.04.3 (Trusty Tahr)' 1710 } 1711 desired_info.update(desired_info_diff) 1712 info = _distro.info(pretty=True, best=True) 1713 assert info == desired_info 1714 1715 def test_none(self): 1716 1717 def _test_none(info): 1718 assert info['id'] == '' 1719 assert info['version'] == '' 1720 assert info['like'] == '' 1721 assert info['version_parts']['major'] == '' 1722 assert info['version_parts']['minor'] == '' 1723 assert info['version_parts']['build_number'] == '' 1724 assert info['codename'] == '' 1725 1726 _distro = distro.LinuxDistribution(False, 'non', 'non') 1727 1728 info = _distro.info() 1729 _test_none(info) 1730 1731 info = _distro.info(best=True) 1732 _test_none(info) 1733 1734 info = _distro.info(pretty=True) 1735 _test_none(info) 1736 1737 info = _distro.info(pretty=True, best=True) 1738 _test_none(info) 1739 1740 def test_linux_distribution(self): 1741 _distro = distro.LinuxDistribution(False, self.ubuntu14_os_release) 1742 i = _distro.linux_distribution() 1743 assert i == ('Ubuntu', '14.04', 'Trusty Tahr') 1744 1745 def test_linux_distribution_full_false(self): 1746 _distro = distro.LinuxDistribution(False, self.ubuntu14_os_release) 1747 i = _distro.linux_distribution(full_distribution_name=False) 1748 assert i == ('ubuntu', '14.04', 'Trusty Tahr') 1749 1750 def test_all(self): 1751 """Test info() by comparing its results with the results of specific 1752 consolidated accessor functions. 1753 """ 1754 def _test_all(info, best=False, pretty=False): 1755 assert info['id'] == _distro.id() 1756 assert info['version'] == _distro.version(pretty=pretty, best=best) 1757 assert info['version_parts']['major'] == \ 1758 _distro.major_version(best=best) 1759 assert info['version_parts']['minor'] == \ 1760 _distro.minor_version(best=best) 1761 assert info['version_parts']['build_number'] == \ 1762 _distro.build_number(best=best) 1763 assert info['like'] == _distro.like() 1764 assert info['codename'] == _distro.codename() 1765 assert len(info['version_parts']) == 3 1766 assert len(info) == 5 1767 1768 for dist in DISTROS: 1769 self._setup_for_distro(os.path.join(DISTROS_DIR, dist)) 1770 1771 _distro = distro.LinuxDistribution() 1772 1773 info = _distro.info() 1774 _test_all(info) 1775 1776 info = _distro.info(best=True) 1777 _test_all(info, best=True) 1778 1779 info = _distro.info(pretty=True) 1780 _test_all(info, pretty=True) 1781 1782 info = _distro.info(pretty=True, best=True) 1783 _test_all(info, pretty=True, best=True) 1784 1785 1786@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 1787class TestOSReleaseParsing: 1788 """Test the parsing of os-release files. 1789 """ 1790 1791 def setup_method(self, test_method): 1792 self.distro = distro.LinuxDistribution(False, None, None) 1793 self.distro.debug = True 1794 1795 def _get_props(self, input): 1796 return self.distro._parse_os_release_content(StringIO( 1797 input, 1798 )) 1799 1800 def _test_zero_length_props(self, input): 1801 props = self._get_props(input) 1802 assert len(props) == 0 1803 1804 def _test_empty_value(self, input): 1805 props = self._get_props(input) 1806 assert props.get('key', None) == '' 1807 1808 def _test_parsed_value(self, input): 1809 props = self._get_props(input) 1810 assert props.get('key', None) == 'value' 1811 1812 def test_kv_01_empty_file(self): 1813 self._test_zero_length_props('') 1814 1815 def test_kv_02_empty_line(self): 1816 self._test_zero_length_props('\n') 1817 1818 def test_kv_03_empty_line_with_crlf(self): 1819 self._test_zero_length_props('\r\n') 1820 1821 def test_kv_04_empty_line_with_just_cr(self): 1822 self._test_zero_length_props('\r') 1823 1824 def test_kv_05_comment(self): 1825 self._test_zero_length_props('# KEY=value\n') 1826 1827 def test_kv_06_empty_value(self): 1828 self._test_empty_value('KEY=\n') 1829 1830 def test_kv_07_empty_value_single_quoted(self): 1831 self._test_empty_value('KEY=\'\'\n') 1832 1833 def test_kv_08_empty_value_double_quoted(self): 1834 self._test_empty_value('KEY=""\n') 1835 1836 def test_kv_09_word(self): 1837 self._test_parsed_value('KEY=value\n') 1838 1839 def test_kv_10_word_no_newline(self): 1840 self._test_parsed_value('KEY=value') 1841 1842 def test_kv_11_word_with_crlf(self): 1843 self._test_parsed_value('KEY=value\r\n') 1844 1845 def test_kv_12_word_with_just_cr(self): 1846 self._test_parsed_value('KEY=value\r') 1847 1848 def test_kv_13_word_with_multi_blanks(self): 1849 self._test_empty_value('KEY= cmd \n') 1850 # Note: Without quotes, this assigns the empty string, and 'cmd' is 1851 # a separate token that is being ignored (it would be a command 1852 # in the shell). 1853 1854 def test_kv_14_unquoted_words(self): 1855 self._test_parsed_value('KEY=value cmd\n') 1856 1857 def test_kv_15_double_quoted_words(self): 1858 props = self._get_props('KEY="a simple value" cmd\n') 1859 assert props.get('key', None) == 'a simple value' 1860 1861 def test_kv_16_double_quoted_words_with_multi_blanks(self): 1862 props = self._get_props('KEY=" a simple value "\n') 1863 assert props.get('key', None) == ' a simple value ' 1864 1865 def test_kv_17_double_quoted_word_with_single_quote(self): 1866 props = self._get_props('KEY="it\'s value"\n') 1867 assert props.get('key', None) == 'it\'s value' 1868 1869 def test_kv_18_double_quoted_word_with_double_quote(self): 1870 props = self._get_props('KEY="a \\"bold\\" move"\n') 1871 assert props.get('key', None) == 'a "bold" move' 1872 1873 def test_kv_19_single_quoted_words(self): 1874 props = self._get_props('KEY=\'a simple value\'\n') 1875 assert props.get('key', None) == 'a simple value' 1876 1877 def test_kv_20_single_quoted_words_with_multi_blanks(self): 1878 props = self._get_props('KEY=\' a simple value \'\n') 1879 assert props.get('key', None) == ' a simple value ' 1880 1881 def test_kv_21_single_quoted_word_with_double_quote(self): 1882 props = self._get_props('KEY=\'a "bold" move\'\n') 1883 assert props.get('key', None) == 'a "bold" move' 1884 1885 def test_kv_22_quoted_unicode_wordchar(self): 1886 # "wordchar" means it is in the shlex.wordchars variable. 1887 props = self._get_props(u'KEY="wordchar: \u00CA (E accent grave)"\n') 1888 assert props.get('key', None) == u'wordchar: \u00CA (E accent grave)' 1889 1890 def test_kv_23_quoted_unicode_non_wordchar(self): 1891 # "non-wordchar" means it is not in the shlex.wordchars variable. 1892 props = self._get_props( 1893 u'KEY="non-wordchar: \u00A1 (inverted exclamation mark)"\n') 1894 assert (props.get('key', None) == 1895 u'non-wordchar: \u00A1 (inverted exclamation mark)') 1896 1897 def test_kv_24_double_quoted_entire_single_quoted_word(self): 1898 props = self._get_props('KEY="\'value\'"\n') 1899 assert props.get('key', None) == "'value'" 1900 1901 def test_kv_25_single_quoted_entire_double_quoted_word(self): 1902 props = self._get_props('KEY=\'"value"\'\n') 1903 assert props.get('key', None) == '"value"' 1904 1905 def test_kv_26_double_quoted_multiline(self): 1906 props = self.distro._parse_os_release_content(StringIO( 1907 'KEY="a multi\n' 1908 'line value"\n' 1909 )) 1910 assert props.get('key', None) == 'a multi\nline value' 1911 # TODO: Find out why the result is not 'a multi line value' 1912 1913 def test_kv_27_double_quoted_multiline_2(self): 1914 props = self._get_props('KEY=\' a simple value \'\n') 1915 props = self.distro._parse_os_release_content(StringIO( 1916 'KEY="a multi\n' 1917 'line=value"\n' 1918 )) 1919 assert props.get('key', None) == 'a multi\nline=value' 1920 # TODO: Find out why the result is not 'a multi line=value' 1921 1922 def test_kv_28_double_quoted_word_with_equal(self): 1923 props = self._get_props('KEY="var=value"\n') 1924 assert props.get('key', None) == 'var=value' 1925 1926 def test_kv_29_single_quoted_word_with_equal(self): 1927 props = self._get_props('KEY=\'var=value\'\n') 1928 assert props.get('key', None) == 'var=value' 1929 1930 def test_kx_01(self): 1931 props = self.distro._parse_os_release_content(StringIO( 1932 'KEY1=value1\n' 1933 'KEY2="value 2"\n' 1934 )) 1935 assert props.get('key1', None) == 'value1' 1936 assert props.get('key2', None) == 'value 2' 1937 1938 def test_kx_02(self): 1939 props = self.distro._parse_os_release_content(StringIO( 1940 '# KEY1=value1\n' 1941 'KEY2="value 2"\n' 1942 )) 1943 assert props.get('key1', None) is None 1944 assert props.get('key2', None) == 'value 2' 1945 1946 1947@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 1948class TestGlobal: 1949 """Test the global module-level functions, and default values of their 1950 arguments. 1951 """ 1952 1953 def setup_method(self, test_method): 1954 pass 1955 1956 def test_global(self): 1957 # Because the module-level functions use the module-global 1958 # LinuxDistribution instance, it would influence the tested 1959 # code too much if we mocked that in order to use the distro 1960 # specific release files. Instead, we let the functions use 1961 # the release files of the distro this test runs on, and 1962 # compare the result of the global functions with the result 1963 # of the methods on the global LinuxDistribution object. 1964 1965 def _test_consistency(function, kwargs=None): 1966 kwargs = kwargs or {} 1967 method_result = getattr(MODULE_DISTRO, function)(**kwargs) 1968 function_result = getattr(distro, function)(**kwargs) 1969 assert method_result == function_result 1970 1971 kwargs = {'full_distribution_name': True} 1972 _test_consistency('linux_distribution', kwargs) 1973 kwargs = {'full_distribution_name': False} 1974 _test_consistency('linux_distribution', kwargs) 1975 1976 kwargs = {'pretty': False} 1977 _test_consistency('name', kwargs) 1978 _test_consistency('version', kwargs) 1979 _test_consistency('info', kwargs) 1980 1981 kwargs = {'pretty': True} 1982 _test_consistency('name', kwargs) 1983 _test_consistency('version', kwargs) 1984 _test_consistency('info', kwargs) 1985 1986 kwargs = {'best': False} 1987 _test_consistency('version', kwargs) 1988 _test_consistency('version_parts', kwargs) 1989 _test_consistency('major_version', kwargs) 1990 _test_consistency('minor_version', kwargs) 1991 _test_consistency('build_number', kwargs) 1992 _test_consistency('info', kwargs) 1993 1994 kwargs = {'best': True} 1995 _test_consistency('version', kwargs) 1996 _test_consistency('version_parts', kwargs) 1997 _test_consistency('major_version', kwargs) 1998 _test_consistency('minor_version', kwargs) 1999 _test_consistency('build_number', kwargs) 2000 _test_consistency('info', kwargs) 2001 2002 _test_consistency('id') 2003 _test_consistency('like') 2004 _test_consistency('codename') 2005 _test_consistency('info') 2006 2007 _test_consistency('os_release_info') 2008 _test_consistency('lsb_release_info') 2009 _test_consistency('distro_release_info') 2010 _test_consistency('uname_info') 2011 2012 os_release_keys = [ 2013 'name', 2014 'version', 2015 'id', 2016 'id_like', 2017 'pretty_name', 2018 'version_id', 2019 'codename', 2020 ] 2021 for key in os_release_keys: 2022 _test_consistency('os_release_attr', {'attribute': key}) 2023 2024 lsb_release_keys = [ 2025 'distributor_id', 2026 'description', 2027 'release', 2028 'codename', 2029 ] 2030 for key in lsb_release_keys: 2031 _test_consistency('lsb_release_attr', {'attribute': key}) 2032 2033 distro_release_keys = [ 2034 'id', 2035 'name', 2036 'version_id', 2037 'codename', 2038 ] 2039 for key in distro_release_keys: 2040 _test_consistency('distro_release_attr', {'attribute': key}) 2041 2042 uname_keys = [ 2043 'id', 2044 'name', 2045 'release' 2046 ] 2047 for key in uname_keys: 2048 _test_consistency('uname_attr', {'attribute': key}) 2049 2050 2051@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') 2052class TestRepr: 2053 """Test the __repr__() method. 2054 """ 2055 2056 def test_repr(self): 2057 # We test that the class name and the names of all instance attributes 2058 # show up in the repr() string. 2059 repr_str = repr(distro._distro) 2060 assert "LinuxDistribution" in repr_str 2061 for attr in MODULE_DISTRO.__dict__.keys(): 2062 assert attr + '=' in repr_str 2063