import shutil import pytest from gpustack.utils.command import ( is_command_available, find_parameter, find_bool_parameter, get_versioned_command, extend_args_no_exist, format_backend_parameters, ) def test_is_command_available_true(monkeypatch): # Simulate that shutil.which finds the command monkeypatch.setattr(shutil, 'which', lambda name: f'/usr/bin/{name}') assert is_command_available('foo') is True def test_is_command_available_false(monkeypatch): # Simulate that shutil.which does not find the command monkeypatch.setattr(shutil, 'which', lambda name: None) assert is_command_available('bar') is False @pytest.mark.parametrize( 'parameters,param_names,expected', [ (None, ['foo'], None), ([], ['foo'], None), (['--foo=bar'], ['foo'], 'bar'), (['-f=baz'], ['f'], 'baz'), (['--foo=bar=baz'], ['foo'], 'bar=baz'), (['--foo', 'value'], ['foo'], 'value'), (['-f', 'val'], ['f'], 'val'), # multiple names: should match first key in parameters (['--x=5'], ['y', 'x'], '5'), # missing value after flag (['--foo'], ['foo'], None), # key not present (['--bar=1', '--baz', '2'], ['foo'], None), # Leading whitespace with = format (most common case) ([' --max-model-len=8192'], ['max-model-len'], '8192'), ([' --foo=bar'], ['foo'], 'bar'), ([' --foo bar'], ['foo'], 'bar'), # Trailing whitespace before = (['--foo =bar'], ['foo'], 'bar'), # Both leading and trailing whitespace ([' --foo =bar'], ['foo'], 'bar'), # Multiple spaces around = (['--foo = bar'], ['foo'], ' bar'), (['--foo =" bar"'], ['foo'], '" bar"'), ( [ '--hf-overrides \'{"rope_scaling": {"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}}\'' ], ['hf-overrides'], '{"rope_scaling": {"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}}', ), ( [ '--hf-overrides={"rope_scaling": {"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}}' ], ['hf-overrides'], '{"rope_scaling": {"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}}', ), ], ) def test_find_parameter(parameters, param_names, expected): assert find_parameter(parameters, param_names) == expected @pytest.mark.parametrize( 'parameters,param_names,expected', [ # flag present (['--foo'], ['foo'], True), (['-f'], ['f'], True), (['--enable-feature'], ['enable-feature'], True), # key=value should not count as boolean flag (['--foo=bar'], ['foo'], False), # flag not present (['--bar'], ['foo'], False), ([], ['foo'], False), # Leading whitespace ([' --foo'], ['foo'], True), ([' --enable-feature'], ['enable-feature'], True), # Trailing whitespace (['--foo '], ['foo'], True), # Both leading and trailing whitespace ([' --foo '], ['foo'], True), ], ) def test_find_bool_parameter(parameters, param_names, expected): assert find_bool_parameter(parameters, param_names) is expected @pytest.mark.parametrize( 'command_name,version,expected', [ ('mycmd.exe', '1.0', 'mycmd_1.0.exe'), ('tool', '2.3.4', 'tool_2.3.4'), ('app.bin', 'v2', 'app.bin_v2'), ('', 'v', '_v'), ], ) def test_get_versioned_command(command_name, version, expected): assert get_versioned_command(command_name, version) == expected @pytest.mark.parametrize( 'initial_args,new_args,expected', [ # Branch 1: Add tuple (key, value) when key doesn't exist ([], [('--host', '127.0.0.1')], ['--host', '127.0.0.1']), # Branch 2: Skip tuple when key already exists (exact match) (['--host', '0.0.0.0'], [('--host', '127.0.0.1')], ['--host', '0.0.0.0']), # Branch 3: Skip tuple when key exists with = format (['--host=0.0.0.0'], [('--host', '127.0.0.1')], ['--host=0.0.0.0']), # Branch 4: Add single flag when it doesn't exist ([], ['--enable-metrics'], ['--enable-metrics']), # Branch 5: Skip single flag when it already exists (['--enable-metrics'], ['--enable-metrics'], ['--enable-metrics']), # Mixed: Add multiple arguments ( ['--port', '8080'], [('--host', '127.0.0.1'), '--enable-metrics', ('--workers', '4')], [ '--port', '8080', '--host', '127.0.0.1', '--enable-metrics', '--workers', '4', ], ), # Edge case: No new args to add (['--existing', 'value'], [], ['--existing', 'value']), ], ) def test_extend_args_no_exist(initial_args, new_args, expected): extend_args_no_exist(initial_args, *new_args) assert initial_args == expected @pytest.mark.parametrize( 'parameters,expected', [ ( [ '--max-model-len', '8192', '--disable-access-log-for-endpoints', '/metrics', ], ['--max-model-len=8192', '--disable-access-log-for-endpoints=/metrics'], ), ( ['--enable-prefix-caching', '--max-seq-len=32768'], ['--enable-prefix-caching', '--max-seq-len=32768'], ), ( ['--max-prefill-tokens', '-1', '--no-metrics'], ['--max-prefill-tokens=-1', '--no-metrics'], ), (None, []), ], ) def test_format_backend_parameters(parameters, expected): assert format_backend_parameters(parameters) == expected