Merge remote-tracking branch 'origin/feat/rsync-compression-aliases' into dev
This commit is contained in:
@@ -343,6 +343,8 @@ features without changing the meaning of ordinary compatibility options.
|
|||||||
| `-m` | Enable the multithreaded scanner/loader/sender pipeline. |
|
| `-m` | Enable the multithreaded scanner/loader/sender pipeline. |
|
||||||
| `-c [level]`, `-z [level]` | Enable streaming zstd compression, levels 1-22. |
|
| `-c [level]`, `-z [level]` | Enable streaming zstd compression, levels 1-22. |
|
||||||
| `--compress-level <n>` | Set the zstd compression level. |
|
| `--compress-level <n>` | Set the zstd compression level. |
|
||||||
|
| `--zc <alg>` | Alias for `--compress-choice`. FastSync supports `zstd` and `none`. |
|
||||||
|
| `--zl <n>` | Alias for `--compress-level`. |
|
||||||
| `--chunk-size <bytes>` | Set the transfer chunk size. |
|
| `--chunk-size <bytes>` | Set the transfer chunk size. |
|
||||||
| `-s` | Enable FastSync chunk serialization. |
|
| `-s` | Enable FastSync chunk serialization. |
|
||||||
| `-f`, `--sendfile` | Use TCP `sendfile()` zero-copy transfer. Incompatible with compression and chunk serialization. |
|
| `-f`, `--sendfile` | Use TCP `sendfile()` zero-copy transfer. Incompatible with compression and chunk serialization. |
|
||||||
|
|||||||
+2
-2
@@ -172,8 +172,8 @@ This document maps rsync's full feature set to FastSync's current implementation
|
|||||||
| Flag | Rsync Description | FastSync Status | Notes |
|
| Flag | Rsync Description | FastSync Status | Notes |
|
||||||
|------|-------------------|-----------------|-------|
|
|------|-------------------|-----------------|-------|
|
||||||
| `-z`, `--compress` | Compress file data | 🔀 Alt Arg | Always uses zstd (rsync supports multiple algorithms) |
|
| `-z`, `--compress` | Compress file data | 🔀 Alt Arg | Always uses zstd (rsync supports multiple algorithms) |
|
||||||
| `--compress-choice=STR` | Choose compression algorithm | ❌ Not Implemented | Removed because it had no effect; FastSync always uses zstd |
|
| `--compress-choice=STR`, `--zc=STR` | Choose compression algorithm | ✅ Implemented | FastSync supports `zstd` and `none` |
|
||||||
| `--compress-level=NUM` | Set compression level | ✅ Implemented | 1-22, default 5 |
|
| `--compress-level=NUM`, `--zl=NUM` | Set compression level | ✅ Implemented | 1-22, default 5 |
|
||||||
| `--compress-threads=NUM` | Set compression threads | ❌ Not Implemented | |
|
| `--compress-threads=NUM` | Set compression threads | ❌ Not Implemented | |
|
||||||
| `--skip-compress=LIST` | Skip compress for suffixes | ❌ Not Implemented | Internal skip for hardcoded types; not user-configurable |
|
| `--skip-compress=LIST` | Skip compress for suffixes | ❌ Not Implemented | Internal skip for hardcoded types; not user-configurable |
|
||||||
|
|
||||||
|
|||||||
+64
-17
@@ -78,6 +78,18 @@ static int set_positive_int_option(int* dest, const char* value, const char* opt
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set and validate the compression algorithm selected by the client. */
|
||||||
|
static int set_compression_choice(Config* config, const char* value) {
|
||||||
|
if (strcmp(value, "zstd") != 0 && strcmp(value, "none") != 0) {
|
||||||
|
log_message(LOG_LEVEL_ERROR, "--compress-choice must be zstd or none");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (set_string_option(&config->compress_choice, value, "--compress-choice") != 0)
|
||||||
|
return -1;
|
||||||
|
config->use_compression = strcmp(value, "zstd") == 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a string as a non-negative integer into *dest. Returns true on success, false on error. */
|
/* Parse a string as a non-negative integer into *dest. Returns true on success, false on error. */
|
||||||
static int set_nonneg_int_option(int* dest, const char* value, const char* option_name) {
|
static int set_nonneg_int_option(int* dest, const char* value, const char* option_name) {
|
||||||
if (!parse_nonneg_int(value, dest)) {
|
if (!parse_nonneg_int(value, dest)) {
|
||||||
@@ -244,6 +256,8 @@ static const OptionEntry OPTION_TABLE[] = {
|
|||||||
{"--fastsync-server-path", NULL, OPT_STRING, offsetof(Config, fastsync_server_path)},
|
{"--fastsync-server-path", NULL, OPT_STRING, offsetof(Config, fastsync_server_path)},
|
||||||
{"--partial-dir", NULL, OPT_STRING, offsetof(Config, partial_dir)},
|
{"--partial-dir", NULL, OPT_STRING, offsetof(Config, partial_dir)},
|
||||||
{"--suffix", NULL, OPT_STRING, offsetof(Config, suffix)},
|
{"--suffix", NULL, OPT_STRING, offsetof(Config, suffix)},
|
||||||
|
{"--compress-choice", "--zc", OPT_STRING, offsetof(Config, compress_choice)},
|
||||||
|
{"--compress-level", "--zl", OPT_POS_INT, offsetof(Config, compression_level)},
|
||||||
|
|
||||||
{"--timeout", NULL, OPT_POS_INT, offsetof(Config, timeout)},
|
{"--timeout", NULL, OPT_POS_INT, offsetof(Config, timeout)},
|
||||||
{"--contimeout", NULL, OPT_POS_INT, offsetof(Config, contimeout)},
|
{"--contimeout", NULL, OPT_POS_INT, offsetof(Config, contimeout)},
|
||||||
@@ -264,6 +278,26 @@ static const OptionEntry* find_table_option(const char* arg) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const OptionEntry* find_table_option_with_equals(const char* arg, const char** value) {
|
||||||
|
const char* equals = strchr(arg, '=');
|
||||||
|
if (!equals || equals == arg)
|
||||||
|
return NULL;
|
||||||
|
size_t name_len = (size_t)(equals - arg);
|
||||||
|
for (size_t i = 0; i < sizeof(OPTION_TABLE) / sizeof(OPTION_TABLE[0]); i++) {
|
||||||
|
const OptionEntry* entry = &OPTION_TABLE[i];
|
||||||
|
if ((strlen(entry->name) == name_len && strncmp(arg, entry->name, name_len) == 0) ||
|
||||||
|
(entry->alias && strlen(entry->alias) == name_len &&
|
||||||
|
strncmp(arg, entry->alias, name_len) == 0)) {
|
||||||
|
if (strcmp(entry->name, "--compress-choice") == 0 ||
|
||||||
|
strcmp(entry->name, "--compress-level") == 0) {
|
||||||
|
*value = equals + 1;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int apply_table_option(Config* config, const OptionEntry* entry, const char* value) {
|
static int apply_table_option(Config* config, const OptionEntry* entry, const char* value) {
|
||||||
if (entry->kind == OPT_NOOP)
|
if (entry->kind == OPT_NOOP)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -313,21 +347,37 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const OptionEntry* entry = find_table_option(argv[i]);
|
const OptionEntry* entry = find_table_option(argv[i]);
|
||||||
|
const char* inline_value = NULL;
|
||||||
|
if (!entry)
|
||||||
|
entry = find_table_option_with_equals(argv[i], &inline_value);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
if (entry->kind != OPT_FLAG) {
|
if (entry->kind != OPT_FLAG) {
|
||||||
if (i + 1 >= argc) {
|
const char* value = inline_value;
|
||||||
|
if (!value && i + 1 < argc)
|
||||||
|
value = argv[++i];
|
||||||
|
if (!value) {
|
||||||
log_message(LOG_LEVEL_ERROR, "missing argument for %s", entry->name);
|
log_message(LOG_LEVEL_ERROR, "missing argument for %s", entry->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (apply_table_option(config, entry, argv[++i]) != 0)
|
if (strcmp(entry->name, "--compress-choice") == 0) {
|
||||||
return -1;
|
if (set_compression_choice(config, value) != 0)
|
||||||
if (entry->offset == offsetof(Config, chmod_spec)) {
|
return -1;
|
||||||
mode_t ignored;
|
} else {
|
||||||
if (!chmod_apply(0, config->chmod_spec, &ignored)) {
|
if (apply_table_option(config, entry, value) != 0)
|
||||||
log_message(LOG_LEVEL_ERROR, "--chmod has invalid permission changes");
|
return -1;
|
||||||
|
if (strcmp(entry->name, "--compress-level") == 0 &&
|
||||||
|
(config->compression_level < 1 || config->compression_level > 22)) {
|
||||||
|
log_message(LOG_LEVEL_ERROR, "--compress-level must be between 1 and 22");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
config->use_metadata = true;
|
if (entry->offset == offsetof(Config, chmod_spec)) {
|
||||||
|
mode_t ignored;
|
||||||
|
if (!chmod_apply(0, config->chmod_spec, &ignored)) {
|
||||||
|
log_message(LOG_LEVEL_ERROR, "--chmod has invalid permission changes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
config->use_metadata = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (apply_table_option(config, entry, NULL) != 0) {
|
} else if (apply_table_option(config, entry, NULL) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -356,7 +406,8 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
printf("fastsync version %s\n", PROTOCOL_VERSION);
|
printf("fastsync version %s\n", PROTOCOL_VERSION);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (opt_is(argv[i], "-a", "--archive")) {
|
} else if (opt_is(argv[i], "-a", "--archive")) {
|
||||||
config->use_compression = true;
|
config->use_compression =
|
||||||
|
!config->compress_choice || strcmp(config->compress_choice, "zstd") == 0;
|
||||||
config->use_multithreading = true;
|
config->use_multithreading = true;
|
||||||
config->use_metadata = true;
|
config->use_metadata = true;
|
||||||
log_message(LOG_LEVEL_INFO, "Enabled archive mode (-c -m -M)");
|
log_message(LOG_LEVEL_INFO, "Enabled archive mode (-c -m -M)");
|
||||||
@@ -392,7 +443,8 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
else
|
else
|
||||||
log_message(LOG_LEVEL_WARNING, "--delta-max value %llu too small, using default", val);
|
log_message(LOG_LEVEL_WARNING, "--delta-max value %llu too small, using default", val);
|
||||||
} else if (opt_is(argv[i], "-c", "-z")) {
|
} else if (opt_is(argv[i], "-c", "-z")) {
|
||||||
config->use_compression = true;
|
config->use_compression =
|
||||||
|
!config->compress_choice || strcmp(config->compress_choice, "zstd") == 0;
|
||||||
log_message(LOG_LEVEL_INFO, "Enabled Compression");
|
log_message(LOG_LEVEL_INFO, "Enabled Compression");
|
||||||
if (i + 1 < argc) {
|
if (i + 1 < argc) {
|
||||||
char* end_ptr;
|
char* end_ptr;
|
||||||
@@ -505,13 +557,6 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
} else if (opt_is(argv[i], "-T", NULL) && i + 1 < argc) {
|
} else if (opt_is(argv[i], "-T", NULL) && i + 1 < argc) {
|
||||||
if (set_positive_int_option(&config->timeout, argv[++i], "-T") != 0)
|
if (set_positive_int_option(&config->timeout, argv[++i], "-T") != 0)
|
||||||
return -1;
|
return -1;
|
||||||
} else if (opt_is(argv[i], "--compress-level", NULL) && i + 1 < argc) {
|
|
||||||
if (set_positive_int_option(&config->compression_level, argv[++i], "--compress-level") != 0)
|
|
||||||
return -1;
|
|
||||||
if (config->compression_level < 1 || config->compression_level > 22) {
|
|
||||||
log_message(LOG_LEVEL_ERROR, "--compress-level must be between 1 and 22");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else if (argv[i][0] == '-') {
|
} else if (argv[i][0] == '-') {
|
||||||
char* escaped = output_escape(argv[i], false);
|
char* escaped = output_escape(argv[i], false);
|
||||||
fprintf(stderr, "Unknown option: %s\n", escaped ? escaped : "<allocation failed>");
|
fprintf(stderr, "Unknown option: %s\n", escaped ? escaped : "<allocation failed>");
|
||||||
@@ -531,6 +576,8 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_log_level(config->quiet ? LOG_LEVEL_ERROR : (verbose ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING));
|
set_log_level(config->quiet ? LOG_LEVEL_ERROR : (verbose ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING));
|
||||||
|
if (config->compress_choice)
|
||||||
|
config->use_compression = strcmp(config->compress_choice, "zstd") == 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ void print_usage(void) {
|
|||||||
printf(" -s Enable chunk serialization\n");
|
printf(" -s Enable chunk serialization\n");
|
||||||
printf(" --secluded-args Accept rsync compatibility option (no effect)\n");
|
printf(" --secluded-args Accept rsync compatibility option (no effect)\n");
|
||||||
printf(" -f Enable sendfile (TCP only, not with -c or -s)\n");
|
printf(" -f Enable sendfile (TCP only, not with -c or -s)\n");
|
||||||
|
printf(" --compress-choice <alg> Compression algorithm (default: zstd)\n");
|
||||||
|
printf(" --zc <alg> Alias for --compress-choice\n");
|
||||||
printf(" -v, --verbose Enable debug logging\n");
|
printf(" -v, --verbose Enable debug logging\n");
|
||||||
printf(" -q, --quiet Suppress non-error output\n");
|
printf(" -q, --quiet Suppress non-error output\n");
|
||||||
printf(" --debug=FLAGS Fine-grained debug logging (use --debug=help for flags)\n");
|
printf(" --debug=FLAGS Fine-grained debug logging (use --debug=help for flags)\n");
|
||||||
@@ -86,6 +88,7 @@ void print_usage(void) {
|
|||||||
printf(" --inplace Update files in-place (no temp+rename)\n");
|
printf(" --inplace Update files in-place (no temp+rename)\n");
|
||||||
printf(" --fsync Fsync every written file before publication\n");
|
printf(" --fsync Fsync every written file before publication\n");
|
||||||
printf(" --compress-level <n> Compression level (default: 5)\n");
|
printf(" --compress-level <n> Compression level (default: 5)\n");
|
||||||
|
printf(" --zl <n> Alias for --compress-level\n");
|
||||||
printf(" --help Show this help\n");
|
printf(" --help Show this help\n");
|
||||||
printf(" -V, --version Show version\n");
|
printf(" -V, --version Show version\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,6 +206,28 @@ class TestChmod:
|
|||||||
assert (os.stat(os.path.join(received, "small.txt")).st_mode & 0o777) == 0o644
|
assert (os.stat(os.path.join(received, "small.txt")).st_mode & 0o777) == 0o644
|
||||||
|
|
||||||
|
|
||||||
|
class TestCompressionChoice:
|
||||||
|
def test_zstd_choice_compresses(self, shared_server):
|
||||||
|
clean_dir(DEST_DIR)
|
||||||
|
result, _ = run_client(SOURCE_DIR, DEST_DIR, flags=["--zc", "zstd"],
|
||||||
|
port=shared_server.port)
|
||||||
|
assert result.returncode == 0, f"zstd sync failed: {(result.stderr or result.stdout)[:200]}"
|
||||||
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
|
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
||||||
|
assert not missing, f"Missing: {missing}"
|
||||||
|
assert not mismatches, f"Mismatch: {mismatches}"
|
||||||
|
|
||||||
|
def test_none_choice_disables_compression(self, shared_server):
|
||||||
|
clean_dir(DEST_DIR)
|
||||||
|
result, _ = run_client(SOURCE_DIR, DEST_DIR, flags=["-z", "--compress-choice", "none"],
|
||||||
|
port=shared_server.port)
|
||||||
|
assert result.returncode == 0, f"none sync failed: {(result.stderr or result.stdout)[:200]}"
|
||||||
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
|
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
||||||
|
assert not missing, f"Missing: {missing}"
|
||||||
|
assert not mismatches, f"Mismatch: {mismatches}"
|
||||||
|
|
||||||
|
|
||||||
class TestExclude:
|
class TestExclude:
|
||||||
def test_exclude_single(self, shared_server):
|
def test_exclude_single(self, shared_server):
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
|
|||||||
+95
-1
@@ -5,6 +5,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "test_utils.h"
|
#include "test_utils.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -481,7 +482,7 @@ static void test_parse_args_rejects_unimplemented_options() {
|
|||||||
"--daemon",
|
"--daemon",
|
||||||
"--config",
|
"--config",
|
||||||
"--server",
|
"--server",
|
||||||
"--compress-choice"};
|
"--checksum-choice"};
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
for (size_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
||||||
Config* cfg = config_create();
|
Config* cfg = config_create();
|
||||||
@@ -688,6 +689,93 @@ static void test_parse_args_whole_file() {
|
|||||||
config_delete(cfg);
|
config_delete(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test rsync-compatible compression-choice and compression-level aliases. */
|
||||||
|
static void test_parse_args_compression_aliases() {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char* argv[] = {"fastsync", "--zc", "zstd", "--zl", "10", "/src", "/dst"};
|
||||||
|
int positional_args[2];
|
||||||
|
int positional_count = 0;
|
||||||
|
|
||||||
|
int ret = parse_args(cfg, 7, argv, positional_args, &positional_count);
|
||||||
|
EXPECT_EQ_INT(ret, 0);
|
||||||
|
EXPECT_EQ_STR(cfg->compress_choice, "zstd");
|
||||||
|
EXPECT_EQ_INT(cfg->compression_level, 10);
|
||||||
|
EXPECT_TRUE(cfg->use_compression);
|
||||||
|
EXPECT_EQ_INT(positional_count, 2);
|
||||||
|
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parse_args_compression_equals_and_none() {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char* argv[] = {"fastsync", "-z", "--zc=none", "--zl=7", "/src", "/dst"};
|
||||||
|
int positional_args[2];
|
||||||
|
int positional_count = 0;
|
||||||
|
|
||||||
|
int ret = parse_args(cfg, 6, argv, positional_args, &positional_count);
|
||||||
|
EXPECT_EQ_INT(ret, 0);
|
||||||
|
EXPECT_EQ_STR(cfg->compress_choice, "none");
|
||||||
|
EXPECT_EQ_INT(cfg->compression_level, 7);
|
||||||
|
EXPECT_FALSE(cfg->use_compression);
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parse_args_compression_canonical_equals() {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char* argv[] = {"fastsync", "--compress-choice=zstd", "--compress-level=7", "/src", "/dst"};
|
||||||
|
int positional_args[2];
|
||||||
|
int positional_count = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ_INT(parse_args(cfg, 5, argv, positional_args, &positional_count), 0);
|
||||||
|
EXPECT_EQ_STR(cfg->compress_choice, "zstd");
|
||||||
|
EXPECT_EQ_INT(cfg->compression_level, 7);
|
||||||
|
EXPECT_TRUE(cfg->use_compression);
|
||||||
|
EXPECT_EQ_INT(positional_count, 2);
|
||||||
|
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parse_args_compression_alias_equals() {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char* argv[] = {"fastsync", "--zc=zstd", "--zl=7", "/src", "/dst"};
|
||||||
|
int positional_args[2];
|
||||||
|
int positional_count = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ_INT(parse_args(cfg, 5, argv, positional_args, &positional_count), 0);
|
||||||
|
EXPECT_EQ_STR(cfg->compress_choice, "zstd");
|
||||||
|
EXPECT_EQ_INT(cfg->compression_level, 7);
|
||||||
|
EXPECT_TRUE(cfg->use_compression);
|
||||||
|
EXPECT_EQ_INT(positional_count, 2);
|
||||||
|
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parse_args_rejects_invalid_compression_level_equals() {
|
||||||
|
static const char* const values[] = {"0", "23", "invalid"};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char option[32];
|
||||||
|
snprintf(option, sizeof(option), "--compress-level=%s", values[i]);
|
||||||
|
char* argv[] = {"fastsync", option, "/src", "/dst"};
|
||||||
|
int positional_args[2];
|
||||||
|
int positional_count = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), -1);
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parse_args_rejects_invalid_compression_choice() {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char* argv[] = {"fastsync", "--compress-choice=bogus", "/src", "/dst"};
|
||||||
|
int positional_args[2];
|
||||||
|
int positional_count = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), -1);
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
void test_client_cli() {
|
void test_client_cli() {
|
||||||
test_validate_config_required_paths();
|
test_validate_config_required_paths();
|
||||||
test_validate_config_incompatible_options();
|
test_validate_config_incompatible_options();
|
||||||
@@ -734,4 +822,10 @@ void test_client_cli() {
|
|||||||
test_parse_args_secluded_args();
|
test_parse_args_secluded_args();
|
||||||
test_parse_args_short_s_remains_chunk_serialization();
|
test_parse_args_short_s_remains_chunk_serialization();
|
||||||
test_parse_args_whole_file();
|
test_parse_args_whole_file();
|
||||||
|
test_parse_args_compression_aliases();
|
||||||
|
test_parse_args_compression_equals_and_none();
|
||||||
|
test_parse_args_compression_canonical_equals();
|
||||||
|
test_parse_args_compression_alias_equals();
|
||||||
|
test_parse_args_rejects_invalid_compression_level_equals();
|
||||||
|
test_parse_args_rejects_invalid_compression_choice();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user