d146e1bb7c
CI / lint (pull_request) Failing after 3s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
272 lines
8.3 KiB
C
272 lines
8.3 KiB
C
#include "test_client_cli.h"
|
|
#include "config.h"
|
|
#include "test_utils.h"
|
|
#include "utils.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
/* Declaration of parse_args from client_cli.c */
|
|
int parse_args(Config* config, int argc, char* argv[], int* positional_args, int* positional_count);
|
|
|
|
/* Test main() with --help flag (early return path, no server connection needed) */
|
|
static void test_cli_help() {
|
|
/* We can't easily call main() because it calls send_files which needs a server.
|
|
* Instead, test the argument parsing logic by testing that config_create works
|
|
* with the same parameters client_cli uses, and that config_delete cleans up
|
|
* properly when send_directory and receive_root_directory are NULL. */
|
|
|
|
/* This matches what client_cli does at startup */
|
|
Config* cfg = config_create();
|
|
EXPECT_NOT_NULL(cfg);
|
|
EXPECT_NULL(cfg->send_directory);
|
|
EXPECT_NULL(cfg->receive_root_directory);
|
|
EXPECT_FALSE(cfg->save_to_disk);
|
|
EXPECT_EQ_INT(cfg->compression_level, 5);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test that --archive sets compression, multithreading, and metadata */
|
|
static void test_cli_archive_flags() {
|
|
Config* cfg = config_create();
|
|
EXPECT_NOT_NULL(cfg);
|
|
|
|
/* Simulate --archive flag */
|
|
cfg->use_compression = true;
|
|
cfg->use_multithreading = true;
|
|
cfg->use_metadata = true;
|
|
|
|
EXPECT_TRUE(cfg->use_compression);
|
|
EXPECT_TRUE(cfg->use_multithreading);
|
|
EXPECT_TRUE(cfg->use_metadata);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test that --dry-run sets dry_run flag */
|
|
static void test_cli_dry_run() {
|
|
Config* cfg = config_create();
|
|
|
|
cfg->dry_run = true;
|
|
EXPECT_TRUE(cfg->dry_run);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test that --delete sets use_delete */
|
|
static void test_cli_delete_flag() {
|
|
Config* cfg = config_create();
|
|
|
|
cfg->use_delete = true;
|
|
EXPECT_TRUE(cfg->use_delete);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test exclude pattern handling */
|
|
static void test_cli_exclude_patterns() {
|
|
Config* cfg = config_create();
|
|
EXPECT_NOT_NULL(cfg);
|
|
|
|
/* Simulate --exclude "*.log" --exclude "tmp/" */
|
|
cfg->exclude_patterns = malloc(2 * sizeof(char*));
|
|
EXPECT_NOT_NULL(cfg->exclude_patterns);
|
|
cfg->exclude_patterns[0] = str_dup("*.log");
|
|
cfg->exclude_patterns[1] = str_dup("tmp/");
|
|
cfg->exclude_count = 2;
|
|
|
|
EXPECT_EQ_STR(cfg->exclude_patterns[0], "*.log");
|
|
EXPECT_EQ_STR(cfg->exclude_patterns[1], "tmp/");
|
|
EXPECT_EQ_INT(cfg->exclude_count, 2);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args with --help returns 1 (clean exit) */
|
|
static void test_parse_args_help() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "--help"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 2, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, 1);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args with -V/--version returns 1 */
|
|
static void test_parse_args_version() {
|
|
Config* cfg = config_create();
|
|
char* argv_short[] = {"fastsync", "-V"};
|
|
char* argv_long[] = {"fastsync", "--version"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 2, argv_short, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, 1);
|
|
|
|
ret = parse_args(cfg, 2, argv_long, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, 1);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args with valid port */
|
|
static void test_parse_args_valid_port() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "-p", "2222", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 5, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, 0);
|
|
EXPECT_EQ_INT(cfg->ssh_port, 2222);
|
|
EXPECT_EQ_INT(positional_count, 2);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args rejects port > 65535 */
|
|
static void test_parse_args_invalid_port() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "-p", "99999", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 5, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, -1);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args rejects non-numeric port */
|
|
static void test_parse_args_non_numeric_port() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "-p", "abc", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 5, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, -1);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args rejects server port > 65535 */
|
|
static void test_parse_args_invalid_server_port() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "--server-port", "70000", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 5, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, -1);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args rejects invalid compression level */
|
|
static void test_parse_args_invalid_compression_level() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "-c", "25", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 5, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, -1);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args accepts valid compression level */
|
|
static void test_parse_args_valid_compression_level() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "-c", "10", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 5, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, 0);
|
|
EXPECT_EQ_INT(cfg->compression_level, 10);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Test parse_args unknown option returns error */
|
|
static void test_parse_args_unknown_option() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "--nonexistent", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 4, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, -1);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
/* Parsed-but-unimplemented options must fail instead of being silently accepted. */
|
|
static void test_parse_args_rejects_unimplemented_options() {
|
|
static const char* const options[] = {
|
|
"-q", "--quiet", "--silent", "--queue-size",
|
|
"-H", "--hard-links", "-A", "--acls",
|
|
"-X", "--xattrs", "-D", "--devices",
|
|
"-i", "--itemize-changes", "--out-format", "--info",
|
|
"--debug", "--list-only", "-h", "--human-readable",
|
|
"-u", "--update", "--append", "--append-verify",
|
|
"--delete-excluded", "--delete-after", "--max-delete", "--filter",
|
|
"--files-from", "--cvs-exclude", "--prune-empty-dirs", "-R",
|
|
"--relative", "-e", "--rsh", "--rsync-path",
|
|
"--temp-dir", "--compare-dest", "--copy-dest", "--link-dest",
|
|
"--delete-before", "--address", "--bind-address", "--ipv6",
|
|
"--ipv4", "--daemon", "--config", "--server",
|
|
"--checksum", "--compress-choice"};
|
|
|
|
for (size_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", (char*)options[i], "dummy", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
EXPECT_EQ_INT(parse_args(cfg, 5, argv, positional_args, &positional_count), -1);
|
|
config_delete(cfg);
|
|
}
|
|
}
|
|
|
|
/* Test parse_args with --archive flag */
|
|
static void test_parse_args_archive() {
|
|
Config* cfg = config_create();
|
|
char* argv[] = {"fastsync", "--archive", "/src", "/dst"};
|
|
int positional_args[2];
|
|
int positional_count = 0;
|
|
|
|
int ret = parse_args(cfg, 4, argv, positional_args, &positional_count);
|
|
EXPECT_EQ_INT(ret, 0);
|
|
EXPECT_TRUE(cfg->use_compression);
|
|
EXPECT_TRUE(cfg->use_multithreading);
|
|
EXPECT_TRUE(cfg->use_metadata);
|
|
|
|
config_delete(cfg);
|
|
}
|
|
|
|
void test_client_cli() {
|
|
test_cli_help();
|
|
test_cli_archive_flags();
|
|
test_cli_dry_run();
|
|
test_cli_delete_flag();
|
|
test_cli_exclude_patterns();
|
|
test_parse_args_help();
|
|
test_parse_args_version();
|
|
test_parse_args_valid_port();
|
|
test_parse_args_invalid_port();
|
|
test_parse_args_non_numeric_port();
|
|
test_parse_args_invalid_server_port();
|
|
test_parse_args_invalid_compression_level();
|
|
test_parse_args_valid_compression_level();
|
|
test_parse_args_unknown_option();
|
|
test_parse_args_rejects_unimplemented_options();
|
|
test_parse_args_archive();
|
|
}
|