test_offline_import_shell.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. """Exercise the POSIX entry point with a fake Python; no services or real venv."""
  2. import os
  3. from pathlib import Path
  4. import shutil
  5. import subprocess
  6. import tempfile
  7. import unittest
  8. def shell_path(path):
  9. value = Path(path).as_posix()
  10. if len(value) > 1 and value[1] == ':':
  11. return '/' + value[0].lower() + value[2:]
  12. return value
  13. class OfflineImportShellTests(unittest.TestCase):
  14. def setUp(self):
  15. self.shell = shutil.which('bash') or shutil.which('sh')
  16. if not self.shell and Path('C:/Program Files/Git/bin/bash.exe').is_file():
  17. self.shell = 'C:/Program Files/Git/bin/bash.exe'
  18. if not self.shell:
  19. self.skipTest('POSIX shell unavailable')
  20. self.tmp = tempfile.TemporaryDirectory()
  21. self.addCleanup(self.tmp.cleanup)
  22. self.root = Path(self.tmp.name)
  23. self.shell_cwd = subprocess.run([self.shell, '-c', 'pwd'], cwd=self.root,
  24. capture_output=True, text=True, check=True).stdout.strip()
  25. self.repo = self.root / 'repo with spaces'
  26. self.repo.mkdir()
  27. self.script = self.repo / 'deploy-offline.sh'
  28. self.script.write_bytes((Path(__file__).parents[2]/'deploy-offline.sh').read_bytes().replace(b'\r\n', b'\n'))
  29. self.capture = self.root/'arguments.txt'
  30. python = self.repo/'.venv/bin/python'
  31. python.parent.mkdir(parents=True)
  32. python.write_text('#!/bin/sh\nprintf "%s\\n" "$@" > "$CAPTURE"\n', encoding='utf-8', newline='\n')
  33. python.chmod(0o755)
  34. self.bin = self.root/'bin'
  35. self.bin.mkdir()
  36. uname = self.bin/'uname'
  37. uname.write_text('#!/bin/sh\nprintf "Linux\\n"\n', encoding='utf-8', newline='\n')
  38. uname.chmod(0o755)
  39. def run_shell(self, *args):
  40. env = dict(os.environ, CAPTURE=shell_path(self.capture))
  41. # An isolated PATH keeps this a syntax/argument test, including on Git Bash.
  42. return subprocess.run([self.shell, '-c', 'PATH="$1:/usr/bin:/bin"; export PATH; shift; exec /bin/sh "$@"',
  43. 'test', shell_path(self.bin), shell_path(self.script), *args], cwd=self.root,
  44. env=env, capture_output=True, text=True)
  45. def test_default_custom_relative_absolute_and_library(self):
  46. for args, tail in [
  47. ([], ['import-knowledge']),
  48. (['a path/new.zip'], ['import-knowledge', self.shell_cwd+'/a path/new.zip']),
  49. (['/transfer/new.zip', 'article'], ['import-knowledge','/transfer/new.zip','article'])]:
  50. with self.subTest(args=args):
  51. result = self.run_shell('import-knowledge', *args)
  52. self.assertEqual(result.returncode,0,result.stderr)
  53. self.assertEqual(self.capture.read_text().splitlines(),['scripts/deploy.py',*tail])
  54. def test_invalid_arguments_rejected_before_python(self):
  55. for args in [('x.zip','wrong'), ('',), ('x.zip','article','extra')]:
  56. with self.subTest(args=args):
  57. result = self.run_shell('import-knowledge', *args)
  58. self.assertEqual(result.returncode,2)
  59. self.assertFalse(self.capture.exists())