check_build.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/usr/bin/env python
  2. # License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
  3. import os
  4. import stat
  5. import subprocess
  6. import sys
  7. import unittest
  8. from functools import partial
  9. from . import BaseTest
  10. class TestBuild(BaseTest):
  11. def test_exe(self) -> None:
  12. from kitty.constants import kitten_exe, kitty_exe, str_version
  13. exe = kitty_exe()
  14. self.assertTrue(os.access(exe, os.X_OK))
  15. self.assertTrue(os.path.isfile(exe))
  16. self.assertIn('kitty', os.path.basename(exe))
  17. exe = kitten_exe()
  18. self.assertTrue(os.access(exe, os.X_OK))
  19. self.assertTrue(os.path.isfile(exe))
  20. self.assertIn(str_version, subprocess.check_output([exe, '--version']).decode())
  21. def test_loading_extensions(self) -> None:
  22. import kitty.fast_data_types as fdt
  23. from kittens.transfer import rsync
  24. del fdt, rsync
  25. def test_loading_shaders(self) -> None:
  26. from kitty.shaders import Program
  27. for name in 'cell border bgimage tint graphics'.split():
  28. Program(name)
  29. def test_glfw_modules(self) -> None:
  30. from kitty.constants import glfw_path, is_macos
  31. linux_backends = ['x11']
  32. if not self.is_ci:
  33. linux_backends.append('wayland')
  34. modules = ['cocoa'] if is_macos else linux_backends
  35. for name in modules:
  36. path = glfw_path(name)
  37. self.assertTrue(os.path.isfile(path), f'{path} is not a file')
  38. self.assertTrue(os.access(path, os.X_OK), f'{path} is not executable')
  39. def test_all_kitten_names(self) -> None:
  40. from kittens.runner import all_kitten_names
  41. names = all_kitten_names()
  42. self.assertIn('diff', names)
  43. self.assertIn('hints', names)
  44. self.assertGreater(len(names), 8)
  45. def test_filesystem_locations(self) -> None:
  46. from kitty.constants import fonts_dir, local_docs, logo_png_file, shell_integration_dir, terminfo_dir
  47. zsh = os.path.join(shell_integration_dir, 'zsh')
  48. self.assertTrue(os.path.isdir(terminfo_dir), f'Terminfo dir: {terminfo_dir}')
  49. self.assertTrue(os.path.exists(logo_png_file), f'Logo file: {logo_png_file}')
  50. self.assertTrue(os.path.exists(zsh), f'Shell integration: {zsh}')
  51. nsfm = os.path.join(fonts_dir, 'SymbolsNerdFontMono-Regular.ttf')
  52. self.assertTrue(os.path.exists(nsfm), f'Logo file: {nsfm}')
  53. def is_executable(x):
  54. mode = os.stat(x).st_mode
  55. q = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
  56. return mode & q == q
  57. for x in ('kitty', 'kitten'):
  58. x = os.path.join(shell_integration_dir, 'ssh', x)
  59. self.assertTrue(is_executable(x), f'{x} is not executable')
  60. if getattr(sys, 'frozen', False):
  61. self.assertTrue(os.path.isdir(local_docs()), f'Local docs: {local_docs()}')
  62. def test_ca_certificates(self):
  63. import ssl
  64. if not getattr(sys, 'frozen', False):
  65. self.skipTest('CA certificates are only tested on frozen builds')
  66. c = ssl.create_default_context()
  67. self.assertGreater(c.cert_store_stats()['x509_ca'], 2)
  68. def test_docs_url(self):
  69. from kitty.constants import website_url
  70. from kitty.utils import docs_url
  71. def run_tests(p, base, suffix='.html'):
  72. def t(x, e):
  73. self.ae(p(x), base + e)
  74. t('', 'index.html' if suffix == '.html' else '')
  75. t('conf', f'conf{suffix}')
  76. t('kittens/ssh#frag', f'kittens/ssh{suffix}#frag')
  77. t('#ref=confloc', f'conf{suffix}#confloc')
  78. t('#ref=conf-kitty-fonts', f'conf{suffix}#conf-kitty-fonts')
  79. t('#ref=conf-kitten-ssh-xxx', f'kittens/ssh{suffix}#conf-kitten-ssh-xxx')
  80. t('#ref=at_close_tab', f'remote-control{suffix}#at-close-tab')
  81. t('#ref=at-close-tab', f'remote-control{suffix}#at-close-tab')
  82. t('#ref=action-copy', f'actions{suffix}#copy')
  83. t('#ref=doc-/marks', f'marks{suffix}')
  84. run_tests(partial(docs_url, local_docs_root='/docs'), 'file:///docs/')
  85. w = website_url()
  86. run_tests(partial(docs_url, local_docs_root=None), w, '/')
  87. self.ae(docs_url('#ref=issues-123'), 'https://github.com/kovidgoyal/kitty/issues/123')
  88. def test_launcher_ensures_stdio(self):
  89. import subprocess
  90. from kitty.constants import kitty_exe
  91. exe = kitty_exe()
  92. cp = subprocess.run([exe, '+runpy', f'''\
  93. import os, sys
  94. if sys.stdin:
  95. os.close(sys.stdin.fileno())
  96. if sys.stdout:
  97. os.close(sys.stdout.fileno())
  98. if sys.stderr:
  99. os.close(sys.stderr.fileno())
  100. os.execlp({exe!r}, 'kitty', '+runpy', 'import sys; raise SystemExit(1 if sys.stdout is None or sys.stdin is None or sys.stderr is None else 0)')
  101. '''])
  102. self.assertEqual(cp.returncode, 0)
  103. def main() -> None:
  104. tests = unittest.defaultTestLoader.loadTestsFromTestCase(TestBuild)
  105. r = unittest.TextTestRunner(verbosity=4)
  106. result = r.run(tests)
  107. if result.errors or result.failures:
  108. raise SystemExit(1)