mirror of
https://github.com/containers/ramalama.git
synced 2026-02-05 06:46:39 +01:00
264 lines
9.7 KiB
Bash
264 lines
9.7 KiB
Bash
#!/usr/bin/env bats
|
|
#
|
|
# Tests based on 'ramalama help'
|
|
#
|
|
# Find all commands listed by 'ramalama --help'. Run each one, make sure it
|
|
# provides its own --help output.
|
|
# Any usage message that ends in '[options]' is interpreted as a command
|
|
# that takes no further arguments; we confirm by running with 'invalid-arg'
|
|
# and confirming that it exits with error status and message.
|
|
#
|
|
load helpers
|
|
|
|
function check_help() {
|
|
local count=0
|
|
local found
|
|
|
|
echo $(_ramalama_commands "$@")
|
|
for cmd in $(_ramalama_commands "$@"); do
|
|
# Human-readable ramalama command string, with multiple spaces collapsed
|
|
command_string="ramalama $* $cmd"
|
|
command_string=${command_string// / } # 'ramalama x' -> 'ramalama x'
|
|
|
|
dprint "$command_string --help"
|
|
run_ramalama "$@" $cmd --help
|
|
local full_help="$output"
|
|
|
|
# The line immediately after 'usage:' gives us a 1-line synopsis
|
|
usage=$(echo "$full_help" | grep -A4 '^usage:')
|
|
assert "$usage" != "" "ramalama $cmd: no usage message found"
|
|
|
|
# Strip off the leading command string; we no longer need it
|
|
usage=$(sed -e "s/^ $command_string \?//" <<<"$usage")
|
|
|
|
# If usage ends in '[command]', recurse into subcommands
|
|
if expr "$usage" : '\[command\]' >/dev/null; then
|
|
found[subcommands]=1
|
|
# (except for 'ramalama help', which is a special case)
|
|
if [[ $cmd != "help" ]]; then
|
|
check_help "$@" $cmd
|
|
fi
|
|
continue
|
|
fi
|
|
|
|
# Cross-check: if usage includes '[options]', there must be a
|
|
# longer 'options:' section in the full --help output; vice-versa,
|
|
# if 'options:' is in full output, usage line must have '[options]'.
|
|
if ! expr "$full_help" : ".*options:" >/dev/null; then
|
|
die "$command_string: usage includes '[options]' but has no 'Options:' subsection"
|
|
fi
|
|
# If usage lists no arguments (strings in ALL CAPS), confirm
|
|
# by running with 'invalid-arg' and expecting failure.
|
|
if ! expr "$usage" : '.*[A-Z]' >/dev/null; then
|
|
if [ "$cmd" != "help" ] && [ "$cmd" != "daemon" ] && [ "$cmd" != "benchmarks" ]; then
|
|
dprint "$command_string invalid-arg"
|
|
run_ramalama '?' "$@" $cmd invalid-arg
|
|
is "$status" 2 \
|
|
"'$usage' indicates that the command takes no arguments. I invoked it with 'invalid-arg' and expected an error status"
|
|
is "$output" ".*ramalama: error: unrecognized arguments: invalid-arg" \
|
|
"'$usage' indicates that the command takes no arguments. I invoked it with 'invalid-arg' and expected the following error message"
|
|
fi
|
|
found[takes_no_args]=1
|
|
fi
|
|
|
|
# If usage has required arguments, try running without them.
|
|
if expr "$usage" : '[A-Z]' >/dev/null; then
|
|
# The </dev/null protects us from 'ramalama login' which will
|
|
# try to read username/password from stdin.
|
|
dprint "$command_string (without required args)"
|
|
run_ramalama '?' "$@" $cmd </dev/null
|
|
is "$status" 2 \
|
|
"'$usage' indicates at least one required arg. I invoked it with no args and expected an error exit code"
|
|
is "$output" "Error:.* \(require\|must\|provide\|need\|choose\|accepts\)" \
|
|
"'$usage' indicates at least one required arg. I invoked it with no args and expected one of these error messages"
|
|
|
|
found[required_args]=1
|
|
fi
|
|
|
|
count=$(expr $count + 1)
|
|
done
|
|
|
|
# Any command that takes subcommands, prints its help and errors if called
|
|
# without one.
|
|
dprint "ramalama $*"
|
|
run_ramalama "$@"
|
|
|
|
# Assume that 'NoSuchCommand' is not a command
|
|
dprint "ramalama $* NoSuchCommand"
|
|
run_ramalama '?' "$@" NoSuchCommand
|
|
is "$status" 2 "'ramalama $* NoSuchCommand' - exit status"
|
|
is "$output" ".*ramalama: error: argument subcommand: invalid choice: .*'NoSuchCommand'" \
|
|
"'ramalama $* NoSuchCommand' - expected error message"
|
|
}
|
|
|
|
|
|
@test "ramalama help - basic tests" {
|
|
|
|
# Called with no args -- start with 'ramalama --help'. check_help() will
|
|
# recurse for any subcommands.
|
|
check_help
|
|
|
|
# Test for regression of #7273 (spurious "--remote" help on output)
|
|
for helpopt in help --help -h; do
|
|
run_ramalama $helpopt
|
|
is "${lines[0]}" "usage: ramalama [-h] [--debug] [--dryrun] [--engine {podman,docker}]" \
|
|
"ramalama $helpopt: first line of output"
|
|
done
|
|
|
|
}
|
|
|
|
@test "ramalama verify default image" {
|
|
|
|
unset RAMALAMA_IMAGE RAMALAMA_IMAGES RAMALAMA_DEFAULT_IMAGE
|
|
run_ramalama run --help
|
|
is "$output" ".*image IMAGE.*OCI container image to run with the specified AI model" "Verify default image"
|
|
is "$output" ".*default: quay.io/ramalama/.*" "Verify default image"
|
|
|
|
image=m_$(safename)
|
|
RAMALAMA_IMAGE=${image} run_ramalama run --help
|
|
is "$output" ".*default: ${image}" "Verify default image from environment"
|
|
|
|
conf=$RAMALAMA_TMPDIR/ramalama.conf
|
|
cat >$conf <<EOF
|
|
[ramalama]
|
|
image="$image"
|
|
EOF
|
|
|
|
RAMALAMA_CONFIG=${conf} run_ramalama bench --help
|
|
is "$output" ".*default: ${image}" "Verify default image from ramalama.conf"
|
|
|
|
image1=m_$(safename)
|
|
RAMALAMA_IMAGE=${image1} RAMALAMA_CONFIG=${conf} run_ramalama serve --help
|
|
is "$output" ".*default: ${image1}" "Verify default image from environment over ramalama.conf"
|
|
}
|
|
|
|
@test "ramalama verify default engine" {
|
|
# Cannot run on docker as that also sets RAMALAMA_CONTAINER_ENGINE
|
|
skip_if_docker
|
|
engine=e_$(safename)
|
|
RAMALAMA_CONTAINER_ENGINE=${engine} run_ramalama --help
|
|
is "$output" ".*default: ${engine}" "Verify default engine from environment variable"
|
|
|
|
conf=$RAMALAMA_TMPDIR/ramalama.conf
|
|
cat >$conf <<EOF
|
|
[ramalama]
|
|
engine="$engine"
|
|
EOF
|
|
|
|
RAMALAMA_CONFIG=${conf} run_ramalama --help
|
|
is "$output" ".*default: ${engine}" "Verify default engine from ramalama.conf"
|
|
|
|
engine1=e_$(safename)
|
|
RAMALAMA_CONTAINER_ENGINE=${engine1} RAMALAMA_CONFIG=${conf} run_ramalama --help
|
|
is "$output" ".*default: ${engine1}" "Verify default engine from environment variable override ramamalama.conf"
|
|
|
|
engine2=e_$(safename)
|
|
RAMALAMA_CONTAINER_ENGINE=${engine1} RAMALAMA_CONFIG=${conf} run_ramalama 2 --engine ${engine2} --help
|
|
is "$output" ".*ramalama: error: argument --engine: invalid choice: '${engine}' (choose from .*)" "Verify --engine rules them all"
|
|
}
|
|
|
|
@test "ramalama verify default runtime" {
|
|
run_ramalama --help
|
|
is "$output" ".*default: llama.cpp" "Verify default runtime from environment variable"
|
|
|
|
conf=$RAMALAMA_TMPDIR/ramalama.conf
|
|
cat >$conf <<EOF
|
|
[ramalama]
|
|
runtime="mlx"
|
|
EOF
|
|
|
|
RAMALAMA_CONFIG=${conf} run_ramalama --help
|
|
is "$output" ".*default: mlx" "Verify default runtime from ramalama.conf"
|
|
}
|
|
|
|
@test "ramalama verify default store" {
|
|
store=/e_$(safename)
|
|
run_ramalama --help
|
|
if is_rootless; then
|
|
is "$output" ".*default: ${HOME}/.local/share/ramalama" "Verify default store"
|
|
else
|
|
is "$output" ".*default: /var/lib/ramalama" "Verify default store"
|
|
fi
|
|
|
|
conf=$RAMALAMA_TMPDIR/ramalama.conf
|
|
cat >$conf <<EOF
|
|
[ramalama]
|
|
store="$store"
|
|
EOF
|
|
|
|
RAMALAMA_CONFIG=${conf} run_ramalama --help
|
|
is "$output" ".*default: ${store}" "Verify default store from ramalama.conf"
|
|
|
|
store1=/e_$(safename)
|
|
RAMALAMA_CONFIG=${conf} run_ramalama --store=${store1} --help
|
|
is "$output" ".*default: ${store1}" "Verify default store from ramalama.conf"
|
|
}
|
|
|
|
@test "ramalama verify default container" {
|
|
skip_if_nocontainer
|
|
|
|
run_ramalama --help
|
|
is "$output" ".*The RAMALAMA_IN_CONTAINER environment variable modifies default behaviour. (default: False)" "Verify default container"
|
|
|
|
RAMALAMA_IN_CONTAINER=false run_ramalama --help
|
|
is "$output" ".*The RAMALAMA_IN_CONTAINER environment variable modifies default behaviour. (default: True)" "Verify default container with environment"
|
|
|
|
conf=$RAMALAMA_TMPDIR/ramalama.conf
|
|
cat >$conf <<EOF
|
|
[ramalama]
|
|
container=false
|
|
EOF
|
|
|
|
RAMALAMA_CONFIG=${conf} run_ramalama --help
|
|
is "$output" ".*The RAMALAMA_IN_CONTAINER environment variable modifies default behaviour. (default: True)" "Verify default container override in ramalama.conf"
|
|
}
|
|
|
|
@test "ramalama verify transport" {
|
|
transport=e_$(safename)
|
|
RAMALAMA_TRANSPORT=${transport} run_ramalama 22 pull foobar
|
|
is "$output" "Error: transport \"${transport}\" not supported. Must be oci, huggingface, modelscope, or ollama." "Verify bogus transport throws error"
|
|
|
|
}
|
|
|
|
@test "ramalama verify default port" {
|
|
|
|
run_ramalama serve --help
|
|
is "$output" ".*port for AI Model server to listen on.*8080" "Verify default port"
|
|
|
|
conf=$RAMALAMA_TMPDIR/ramalama.conf
|
|
cat >$conf <<EOF
|
|
[ramalama]
|
|
port="1776"
|
|
EOF
|
|
|
|
RAMALAMA_CONFIG=${conf} run_ramalama serve --help
|
|
is "$output" ".*port for AI Model server to listen on.*1776" "Verify default port"
|
|
}
|
|
|
|
@test "ramalama verify one argument to rm" {
|
|
|
|
run_ramalama 22 rm
|
|
is "$output" "Error: one MODEL or --all must be specified" "Verify at least one argument"
|
|
}
|
|
|
|
@test "ramalama verify default api_key" {
|
|
API_KEY=e_$(safename)
|
|
conf=$RAMALAMA_TMPDIR/ramalama.conf
|
|
cat >$conf <<EOF
|
|
[ramalama]
|
|
api_key="${API_KEY}"
|
|
EOF
|
|
|
|
|
|
RAMALAMA_CONFIG=${conf} run_ramalama chat --help
|
|
is "$output" ".*default:.*${API_KEY}" "Verify default api_key from ramalama.conf"
|
|
|
|
RAMALAMA_API_KEY=${API_KEY} RAMALAMA_CONFIG=/dev/null run_ramalama chat --help
|
|
is "$output" ".*default:.*${API_KEY}" "Verify default api_key from environment is set"
|
|
|
|
RAMALAMA_API_KEY=${API_KEY} RAMALAMA_CONFIG=${conf} run_ramalama chat --help
|
|
is "$output" ".*default:.*${API_KEY}" "Verify default api_key from environment is set"
|
|
}
|
|
|
|
# vim: filetype=sh
|