test_main.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import io
  2. import json
  3. from pathlib import Path
  4. import pytest
  5. import re
  6. import responses
  7. from shutil import copytree
  8. from subprocess import run, PIPE
  9. import sys
  10. from testpath import MockCommand, assert_isfile, assert_isdir
  11. from zipfile import ZipFile
  12. from nsist import main
  13. from nsist.util import CACHE_ENV_VAR
  14. from .utils import test_dir, only_on_windows
  15. example_dir = Path(test_dir, 'console_example')
  16. @pytest.fixture()
  17. def console_eg_copy(tmp_path):
  18. dst = tmp_path / 'example'
  19. copytree(str(example_dir), str(dst))
  20. return dst
  21. def respond_python_zip(req):
  22. buf = io.BytesIO()
  23. with ZipFile(buf, 'w') as zf:
  24. zf.writestr('python.exe', b'')
  25. return 200, {}, buf.getvalue()
  26. @responses.activate
  27. def test_console_example(tmp_path, console_eg_copy, monkeypatch):
  28. responses.add_callback('GET', re.compile(r'https://www.python.org/ftp/.*'),
  29. callback=respond_python_zip, content_type='application/zip',
  30. )
  31. monkeypatch.chdir(console_eg_copy)
  32. monkeypatch.setenv(CACHE_ENV_VAR, str(tmp_path / 'cache'))
  33. with MockCommand('makensis') as makensis:
  34. ec = main(['installer.cfg'])
  35. assert ec == 0
  36. assert makensis.get_calls()[0]['argv'][1].endswith('installer.nsi')
  37. build_dir = console_eg_copy / 'build' / 'nsis'
  38. assert_isdir(build_dir)
  39. assert_isfile(build_dir / 'Python' / 'python.exe')
  40. assert_isfile(build_dir / 'pkgs' / 'sample_printer' / '__init__.py')
  41. assert_isfile(build_dir / 'Sample_printer.launch.py')
  42. # To exclude tests requiring network on an unplugged machine, use: pytest -m "not network"
  43. @only_on_windows
  44. @pytest.mark.network
  45. def test_installer(console_eg_copy, tmp_path):
  46. # Create installer
  47. run(
  48. [sys.executable, '-m', 'nsist', 'installer.cfg'],
  49. cwd=str(console_eg_copy),
  50. check=True,
  51. )
  52. installer = console_eg_copy / 'build' / 'nsis' / 'Sample_printer_1.0.exe'
  53. inst_dir = tmp_path / 'inst'
  54. # Run installer
  55. run([str(installer), '/S', '/INSTDIR={}'.format(inst_dir)], check=True)
  56. import os
  57. print(os.listdir(str(inst_dir)))
  58. inst_python = inst_dir / 'Python' / 'python.exe'
  59. inst_launch_script = inst_dir / 'Sample_printer.launch.py'
  60. inst_exe_wrapper = inst_dir / 'bin' / 'pynsist-test-print.exe'
  61. assert_isfile(inst_python)
  62. assert_isfile(inst_launch_script)
  63. assert_isfile(inst_exe_wrapper)
  64. assert_isfile(inst_dir / 'pkgs' / 'sample_printer' / '__init__.py')
  65. # Run installed program
  66. res = run([str(inst_python), str(inst_launch_script)],
  67. check=True, stdout=PIPE)
  68. json_res = json.loads(res.stdout.decode('utf-8', 'replace'))
  69. print(res.stdout.decode('utf-8', 'replace'))
  70. assert json_res['py_executable'] == str(inst_python)
  71. assert json_res['py_version'].startswith('3.8.3') # Set in installer.cfg
  72. assert json_res['data_file_path'].endswith('data.txt')
  73. assert json_res['data_file_content'] == 'newt'
  74. # Run through command-line wrapper
  75. res2 = run([str(inst_exe_wrapper)], check=True, stdout=PIPE)
  76. print("Command line wrapper -----------------------------------------")
  77. print(res2.stdout.decode('utf-8', 'replace'))
  78. json_res2 = json.loads(res2.stdout.decode('utf-8', 'replace'))
  79. assert json_res2 == json_res
  80. # Check command-line wrapper is on PATH
  81. assert str(inst_exe_wrapper.parent) in get_registry_path()
  82. def get_registry_path():
  83. """Read the PATH environment variable from the Windows registry"""
  84. import winreg
  85. res = []
  86. # System-wide part of PATH
  87. with winreg.CreateKey(
  88. winreg.HKEY_LOCAL_MACHINE,
  89. r"System\CurrentControlSet\Control\Session Manager\Environment"
  90. ) as key:
  91. try:
  92. path = winreg.QueryValueEx(key, "PATH")[0]
  93. except WindowsError:
  94. # No value called PATH
  95. pass
  96. else:
  97. res.extend(path.split(';'))
  98. # User part of PATH
  99. with winreg.CreateKey(winreg.HKEY_CURRENT_USER, r"Environment") as key:
  100. try:
  101. path = winreg.QueryValueEx(key, "PATH")[0]
  102. except WindowsError:
  103. # No value called PATH
  104. pass
  105. else:
  106. res.extend(path.split(';'))
  107. return res