| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- """
- Tests for the pip binary provider plugin.
- Tests cover:
- 1. Hook script execution
- 2. pip package detection
- 3. Virtual environment handling
- 4. JSONL output format
- """
- import json
- import os
- import subprocess
- import sys
- import tempfile
- from pathlib import Path
- from unittest.mock import patch, MagicMock
- import pytest
- from django.test import TestCase
- # Get the path to the pip provider hook
- PLUGIN_DIR = Path(__file__).parent.parent
- INSTALL_HOOK = next(PLUGIN_DIR.glob('on_Binary__*_pip_install.py'), None)
- class TestPipProviderHook(TestCase):
- """Test the pip binary provider installation hook."""
- def setUp(self):
- """Set up test environment."""
- self.temp_dir = tempfile.mkdtemp()
- self.output_dir = Path(self.temp_dir) / 'output'
- self.output_dir.mkdir()
- self.lib_dir = Path(self.temp_dir) / 'lib' / 'x86_64-linux'
- self.lib_dir.mkdir(parents=True, exist_ok=True)
- self.lib_dir = Path(self.temp_dir) / 'lib' / 'x86_64-linux'
- self.lib_dir.mkdir(parents=True, exist_ok=True)
- def tearDown(self):
- """Clean up."""
- import shutil
- shutil.rmtree(self.temp_dir, ignore_errors=True)
- def test_hook_script_exists(self):
- """Hook script should exist."""
- self.assertTrue(INSTALL_HOOK and INSTALL_HOOK.exists(), f"Hook not found: {INSTALL_HOOK}")
- def test_hook_help(self):
- """Hook should accept --help without error."""
- result = subprocess.run(
- [sys.executable, str(INSTALL_HOOK), '--help'],
- capture_output=True,
- text=True,
- timeout=30
- )
- # May succeed or fail depending on implementation
- # At minimum should not crash with Python error
- self.assertNotIn('Traceback', result.stderr)
- def test_hook_finds_pip(self):
- """Hook should find pip binary."""
- env = os.environ.copy()
- env['DATA_DIR'] = self.temp_dir
- env['LIB_DIR'] = str(self.lib_dir)
- result = subprocess.run(
- [
- sys.executable, str(INSTALL_HOOK),
- '--name=pip',
- '--binproviders=pip',
- '--binary-id=test-uuid',
- '--machine-id=test-machine',
- ],
- capture_output=True,
- text=True,
- cwd=str(self.output_dir),
- env=env,
- timeout=60
- )
- # Check for JSONL output
- jsonl_found = False
- for line in result.stdout.split('\n'):
- line = line.strip()
- if line.startswith('{'):
- try:
- record = json.loads(line)
- if record.get('type') == 'Binary' and record.get('name') == 'pip':
- jsonl_found = True
- # Verify structure
- self.assertIn('abspath', record)
- self.assertIn('version', record)
- break
- except json.JSONDecodeError:
- continue
- # Should not crash
- self.assertNotIn('Traceback', result.stderr)
- # Should find pip via pip provider
- self.assertTrue(jsonl_found, "Expected to find pip binary in JSONL output")
- def test_hook_unknown_package(self):
- """Hook should handle unknown packages gracefully."""
- env = os.environ.copy()
- env['DATA_DIR'] = self.temp_dir
- env['LIB_DIR'] = str(self.lib_dir)
- result = subprocess.run(
- [
- sys.executable, str(INSTALL_HOOK),
- '--name=nonexistent_package_xyz123',
- '--binproviders=pip',
- '--binary-id=test-uuid',
- '--machine-id=test-machine',
- ],
- capture_output=True,
- text=True,
- cwd=str(self.output_dir),
- env=env,
- timeout=60
- )
- # Should not crash
- self.assertNotIn('Traceback', result.stderr)
- # May have non-zero exit code for missing package
- class TestPipProviderIntegration(TestCase):
- """Integration tests for pip provider with real packages."""
- def setUp(self):
- """Set up test environment."""
- self.temp_dir = tempfile.mkdtemp()
- self.output_dir = Path(self.temp_dir) / 'output'
- self.output_dir.mkdir()
- def tearDown(self):
- """Clean up."""
- import shutil
- shutil.rmtree(self.temp_dir, ignore_errors=True)
- def test_hook_finds_pip_installed_binary(self):
- """Hook should find binaries installed via pip."""
- pip_check = subprocess.run(
- [sys.executable, '-m', 'pip', '--version'],
- capture_output=True,
- text=True,
- )
- assert pip_check.returncode == 0, "pip not available"
- env = os.environ.copy()
- env['DATA_DIR'] = self.temp_dir
- # Try to find 'pip' itself which should be available
- result = subprocess.run(
- [
- sys.executable, str(INSTALL_HOOK),
- '--name=pip',
- '--binproviders=pip,env',
- '--binary-id=test-uuid',
- '--machine-id=test-machine',
- ],
- capture_output=True,
- text=True,
- cwd=str(self.output_dir),
- env=env,
- timeout=60
- )
- # Look for success in output
- for line in result.stdout.split('\n'):
- line = line.strip()
- if line.startswith('{'):
- try:
- record = json.loads(line)
- if record.get('type') == 'Binary' and 'pip' in record.get('name', ''):
- # Found pip binary
- self.assertTrue(record.get('abspath'))
- return
- except json.JSONDecodeError:
- continue
- # If we get here without finding pip, that's acceptable
- # as long as the hook didn't crash
- self.assertNotIn('Traceback', result.stderr)
- if __name__ == '__main__':
- pytest.main([__file__, '-v'])
|