diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-02-12 20:57:17 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-02-12 20:57:17 +0100 |
| commit | b333b06772c89d96aacb5490d6a219fba7c09cc6 (patch) | |
| tree | 211df60083a5946baa2ed61d33d8121b7e251b06 /llama.cpp/tests/test-arg-parser.cpp | |
| download | llmnpc-b333b06772c89d96aacb5490d6a219fba7c09cc6.tar.gz | |
Engage!
Diffstat (limited to 'llama.cpp/tests/test-arg-parser.cpp')
| -rw-r--r-- | llama.cpp/tests/test-arg-parser.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/llama.cpp/tests/test-arg-parser.cpp b/llama.cpp/tests/test-arg-parser.cpp new file mode 100644 index 0000000..67f8ca6 --- /dev/null +++ b/llama.cpp/tests/test-arg-parser.cpp @@ -0,0 +1,208 @@ +#include "arg.h" +#include "common.h" +#include "download.h" + +#include <string> +#include <vector> +#include <sstream> +#include <unordered_set> + +#undef NDEBUG +#include <cassert> + +int main(void) { + common_params params; + + printf("test-arg-parser: make sure there is no duplicated arguments in any examples\n\n"); + for (int ex = 0; ex < LLAMA_EXAMPLE_COUNT; ex++) { + try { + auto ctx_arg = common_params_parser_init(params, (enum llama_example)ex); + common_params_add_preset_options(ctx_arg.options); + std::unordered_set<std::string> seen_args; + std::unordered_set<std::string> seen_env_vars; + for (const auto & opt : ctx_arg.options) { + // check for args duplications + for (const auto & arg : opt.get_args()) { + if (seen_args.find(arg) == seen_args.end()) { + seen_args.insert(arg); + } else { + fprintf(stderr, "test-arg-parser: found different handlers for the same argument: %s", arg.c_str()); + exit(1); + } + } + // check for env var duplications + for (const auto & env : opt.get_env()) { + if (seen_env_vars.find(env) == seen_env_vars.end()) { + seen_env_vars.insert(env); + } else { + fprintf(stderr, "test-arg-parser: found different handlers for the same env var: %s", env.c_str()); + exit(1); + } + } + + // ensure shorter argument precedes longer argument + if (opt.args.size() > 1) { + const std::string first(opt.args.front()); + const std::string last(opt.args.back()); + + if (first.length() > last.length()) { + fprintf(stderr, "test-arg-parser: shorter argument should come before longer one: %s, %s\n", + first.c_str(), last.c_str()); + assert(false); + } + } + + // same check for negated arguments + if (opt.args_neg.size() > 1) { + const std::string first(opt.args_neg.front()); + const std::string last(opt.args_neg.back()); + + if (first.length() > last.length()) { + fprintf(stderr, "test-arg-parser: shorter negated argument should come before longer one: %s, %s\n", + first.c_str(), last.c_str()); + assert(false); + } + } + } + } catch (std::exception & e) { + printf("%s\n", e.what()); + assert(false); + } + } + + auto list_str_to_char = [](std::vector<std::string> & argv) -> std::vector<char *> { + std::vector<char *> res; + for (auto & arg : argv) { + res.push_back(const_cast<char *>(arg.data())); + } + return res; + }; + + std::vector<std::string> argv; + + printf("test-arg-parser: test invalid usage\n\n"); + + // missing value + argv = {"binary_name", "-m"}; + assert(false == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + + // wrong value (int) + argv = {"binary_name", "-ngl", "hello"}; + assert(false == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + + // wrong value (enum) + argv = {"binary_name", "-sm", "hello"}; + assert(false == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + + // non-existence arg in specific example (--draft cannot be used outside llama-speculative) + argv = {"binary_name", "--draft", "123"}; + assert(false == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_EMBEDDING)); + + // negated arg + argv = {"binary_name", "--no-mmap"}; + assert(false == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + + + printf("test-arg-parser: test valid usage\n\n"); + + argv = {"binary_name", "-m", "model_file.gguf"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.model.path == "model_file.gguf"); + + argv = {"binary_name", "-t", "1234"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.cpuparams.n_threads == 1234); + + argv = {"binary_name", "--verbose"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.verbosity > 1); + + argv = {"binary_name", "-m", "abc.gguf", "--predict", "6789", "--batch-size", "9090"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.model.path == "abc.gguf"); + assert(params.n_predict == 6789); + assert(params.n_batch == 9090); + + // --draft cannot be used outside llama-speculative + argv = {"binary_name", "--draft", "123"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_SPECULATIVE)); + assert(params.speculative.n_max == 123); + + // multi-value args (CSV) + argv = {"binary_name", "--lora", "file1.gguf,\"file2,2.gguf\",\"file3\"\"3\"\".gguf\",file4\".gguf"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.lora_adapters.size() == 4); + assert(params.lora_adapters[0].path == "file1.gguf"); + assert(params.lora_adapters[1].path == "file2,2.gguf"); + assert(params.lora_adapters[2].path == "file3\"3\".gguf"); + assert(params.lora_adapters[3].path == "file4\".gguf"); + +// skip this part on windows, because setenv is not supported +#ifdef _WIN32 + printf("test-arg-parser: skip on windows build\n"); +#else + printf("test-arg-parser: test environment variables (valid + invalid usages)\n\n"); + + setenv("LLAMA_ARG_THREADS", "blah", true); + argv = {"binary_name"}; + assert(false == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + + setenv("LLAMA_ARG_MODEL", "blah.gguf", true); + setenv("LLAMA_ARG_THREADS", "1010", true); + argv = {"binary_name"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.model.path == "blah.gguf"); + assert(params.cpuparams.n_threads == 1010); + + printf("test-arg-parser: test negated environment variables\n\n"); + + setenv("LLAMA_ARG_MMAP", "0", true); + setenv("LLAMA_ARG_NO_PERF", "1", true); // legacy format + argv = {"binary_name"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.use_mmap == false); + assert(params.no_perf == true); + + printf("test-arg-parser: test environment variables being overwritten\n\n"); + + setenv("LLAMA_ARG_MODEL", "blah.gguf", true); + setenv("LLAMA_ARG_THREADS", "1010", true); + argv = {"binary_name", "-m", "overwritten.gguf"}; + assert(true == common_params_parse(argv.size(), list_str_to_char(argv).data(), params, LLAMA_EXAMPLE_COMMON)); + assert(params.model.path == "overwritten.gguf"); + assert(params.cpuparams.n_threads == 1010); +#endif // _WIN32 + + printf("test-arg-parser: test download functions\n\n"); + const char * GOOD_URL = "http://ggml.ai/"; + const char * BAD_URL = "http://ggml.ai/404"; + + { + printf("test-arg-parser: test good URL\n\n"); + auto res = common_remote_get_content(GOOD_URL, {}); + assert(res.first == 200); + assert(res.second.size() > 0); + std::string str(res.second.data(), res.second.size()); + assert(str.find("llama.cpp") != std::string::npos); + } + + { + printf("test-arg-parser: test bad URL\n\n"); + auto res = common_remote_get_content(BAD_URL, {}); + assert(res.first == 404); + } + + { + printf("test-arg-parser: test max size error\n"); + common_remote_params params; + params.max_size = 1; + try { + common_remote_get_content(GOOD_URL, params); + assert(false && "it should throw an error"); + } catch (std::exception & e) { + printf(" expected error: %s\n\n", e.what()); + } + } + + printf("test-arg-parser: all tests OK\n\n"); +} |
