1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""
Shared pytest configuration and utilities for netencode integration tests.
"""
import os
import sys
import subprocess
import pytest
from typing import Optional, List, Union

# Add lib-python to Python path for importing netencode module
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib-python'))


def get_tool_path(tool_name: str) -> str:
    """Get the full path to a netencode tool from environment variables or PATH."""
    # First try environment variables (for nix-build derivation)
    env_var = tool_name.upper().replace('-', '_')
    path = os.environ.get(env_var)
    if path and os.path.exists(path):
        return path
    
    # Fallback: try to find in PATH (for shell.nix)
    try:
        return subprocess.check_output(['which', tool_name], text=True).strip()
    except subprocess.CalledProcessError:
        pytest.skip(f"Tool {tool_name} not found in environment or PATH")


def run_tool(tool_name: str, *args: str, stdin: Optional[Union[str, bytes]] = None, 
             expect_success: bool = True) -> subprocess.CompletedProcess:
    """
    Run a netencode tool with the given arguments and stdin.
    
    Args:
        tool_name: Name of the tool (e.g., 'netencode-record-get', 'json-to-netencode')
        *args: Command line arguments to pass to the tool
        stdin: String or bytes to pass as stdin to the tool
        expect_success: If True, raise exception on non-zero exit code
        
    Returns:
        CompletedProcess object with stdout, stderr, returncode
    """
    tool_path = get_tool_path(tool_name)
    
    # Convert stdin to bytes if needed
    if isinstance(stdin, str):
        stdin_bytes = stdin.encode('utf-8')
    elif isinstance(stdin, bytes):
        stdin_bytes = stdin
    else:
        stdin_bytes = None
    
    result = subprocess.run(
        [tool_path] + list(args),
        input=stdin_bytes,
        capture_output=True
    )
    
    if expect_success and result.returncode != 0:
        pytest.fail(
            f"{tool_name} failed with exit code {result.returncode}\n"
            f"stdout: {result.stdout.decode('utf-8', errors='replace')}\n"
            f"stderr: {result.stderr.decode('utf-8', errors='replace')}\n"
            f"stdin: {stdin}"
        )
    
    return result