11"""
2- Tests for the custom binary provider plugin.
2+ Tests for the bash binary provider plugin.
33
4- Tests the custom bash binary installer with safe commands.
4+ Tests the bash command installer with safe commands.
55"""
66
77import json
88import os
9+ import shutil
910import subprocess
1011import tempfile
1112from pathlib import Path
1213
1314import pytest
1415
1516
16- # Get the path to the custom provider hook
17+ # Get the path to the bash provider hook
1718PLUGIN_DIR = Path (__file__ ).parent .parent
18- INSTALL_HOOK = next (PLUGIN_DIR .glob ("on_BinaryRequest__*_custom.py" ), None )
19+ INSTALL_HOOK = next (PLUGIN_DIR .glob ("on_BinaryRequest__*_bash.py" ), None )
20+ BASH_ZX_INSTALL = (
21+ 'npm install --quiet --prefix "$INSTALL_ROOT/npm" zx '
22+ '&& ln -sf "$INSTALL_ROOT/npm/node_modules/.bin/zx" "$BIN_DIR/bash-zx"'
23+ )
1924
2025
21- class TestCustomProviderHook :
22- """Test the custom binary provider hook."""
26+ class TestBashProviderHook :
27+ """Test the bash binary provider hook."""
2328
2429 def setup_method (self , _method = None ):
2530 """Set up test environment."""
@@ -35,17 +40,17 @@ def test_hook_script_exists(self):
3540 """Hook script should exist."""
3641 assert INSTALL_HOOK and INSTALL_HOOK .exists (), f"Hook not found: { INSTALL_HOOK } "
3742
38- def test_hook_skips_when_custom_not_allowed (self ):
39- """Hook should skip when custom not in allowed binproviders."""
43+ def test_hook_skips_when_bash_not_allowed (self ):
44+ """Hook should skip when bash not in allowed binproviders."""
4045 env = os .environ .copy ()
4146 env ["SNAP_DIR" ] = self .temp_dir
42- overrides = json .dumps ({"custom " : {"install" : "echo hello" }})
47+ overrides = json .dumps ({"bash " : {"install" : "echo hello" }})
4348
4449 result = subprocess .run (
4550 [
4651 str (INSTALL_HOOK ),
4752 "--name=echo" ,
48- "--binproviders=pip,apt" , # custom not allowed
53+ "--binproviders=pip,apt" , # bash not allowed
4954 f"--overrides={ overrides } " ,
5055 ],
5156 capture_output = True ,
@@ -54,33 +59,34 @@ def test_hook_skips_when_custom_not_allowed(self):
5459 env = env ,
5560 )
5661
57- # Should exit cleanly (code 0) when custom not allowed
62+ # Should exit cleanly (code 0) when bash not allowed
5863 assert result .returncode == 0
59- assert "custom provider not allowed" in result .stderr
64+ assert "bash provider not allowed" in result .stderr
65+
66+ def test_hook_runs_bash_command_and_finds_binary (self ):
67+ """Hook should run a real bash install command and emit the installed binary."""
68+ if not shutil .which ("npm" ):
69+ pytest .skip ("npm is required for the real bash provider install test" )
6070
61- def test_hook_runs_custom_command_and_finds_binary (self ):
62- """Hook should run custom command and find the binary in PATH."""
6371 env = os .environ .copy ()
6472 env ["SNAP_DIR" ] = self .temp_dir
73+ env ["HOME" ] = self .temp_dir
6574 overrides = json .dumps (
66- {"custom " : {"install" : 'echo "custom install simulation"' }},
75+ {"bash " : {"install" : BASH_ZX_INSTALL }},
6776 )
6877
69- # Use a simple echo command that doesn't actually install anything
70- # Then check for 'echo' which is already in PATH
7178 result = subprocess .run (
7279 [
7380 str (INSTALL_HOOK ),
74- "--name=echo " ,
81+ "--name=bash-zx " ,
7582 f"--overrides={ overrides } " ,
7683 ],
7784 capture_output = True ,
7885 text = True ,
79- timeout = 30 ,
86+ timeout = 120 ,
8087 env = env ,
8188 )
8289
83- # Should succeed since echo is in PATH
8490 assert result .returncode == 0 , f"Hook failed: { result .stderr } "
8591
8692 # Parse JSONL output
@@ -89,20 +95,24 @@ def test_hook_runs_custom_command_and_finds_binary(self):
8995 if line .startswith ("{" ):
9096 try :
9197 record = json .loads (line )
92- if record .get ("type" ) == "Binary" and record .get ("name" ) == "echo" :
93- assert record ["binprovider" ] == "custom"
98+ if (
99+ record .get ("type" ) == "Binary"
100+ and record .get ("name" ) == "bash-zx"
101+ ):
102+ assert record ["binprovider" ] == "bash"
94103 assert record ["abspath" ]
104+ assert Path (record ["abspath" ]).exists ()
95105 return
96106 except json .JSONDecodeError :
97107 continue
98108
99109 pytest .fail ("No Binary JSONL record found in output" )
100110
101111 def test_hook_fails_for_missing_binary_after_command (self ):
102- """Hook should fail if binary not found after running custom command."""
112+ """Hook should fail if binary not found after running bash command."""
103113 env = os .environ .copy ()
104114 env ["SNAP_DIR" ] = self .temp_dir
105- overrides = json .dumps ({"custom " : {"install" : 'echo "failed install"' }})
115+ overrides = json .dumps ({"bash " : {"install" : 'echo "failed install"' }})
106116
107117 result = subprocess .run (
108118 [
@@ -118,13 +128,15 @@ def test_hook_fails_for_missing_binary_after_command(self):
118128
119129 # Should fail since binary not found after command
120130 assert result .returncode == 1
121- assert "not found" in result .stderr .lower ()
131+ assert "unable to load or install binary nonexistent_binary_xyz123" in (
132+ result .stderr .lower ()
133+ )
122134
123135 def test_hook_fails_for_failing_command (self ):
124- """Hook should fail if custom command returns non-zero exit code."""
136+ """Hook should fail if bash command returns non-zero exit code."""
125137 env = os .environ .copy ()
126138 env ["SNAP_DIR" ] = self .temp_dir
127- overrides = json .dumps ({"custom " : {"install" : "exit 1" }})
139+ overrides = json .dumps ({"bash " : {"install" : "exit 1" }})
128140
129141 result = subprocess .run (
130142 [
0 commit comments