feat: add rsync info flags
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@ This document maps rsync's full feature set to FastSync's current implementation
|
|||||||
| `-q`, `--quiet` | Suppress non-error messages | ❌ Not Implemented | Removed because it had no effect |
|
| `-q`, `--quiet` | Suppress non-error messages | ❌ Not Implemented | Removed because it had no effect |
|
||||||
| `--help` | Show help | ✅ Implemented | Prints usage and exits; `-h` is not accepted |
|
| `--help` | Show help | ✅ Implemented | Prints usage and exits; `-h` is not accepted |
|
||||||
| `-V`, `--version` | Print version | ✅ Implemented | |
|
| `-V`, `--version` | Print version | ✅ Implemented | |
|
||||||
| `--info=FLAGS` | Fine-grained info verbosity | ❌ Not Implemented | Removed because it had no effect |
|
| `--info=FLAGS` | Fine-grained info verbosity | ✅ Implemented | Supports comma-separated rsync info names and `all`/`none` |
|
||||||
| `--debug=FLAGS` | Fine-grained debug verbosity | ❌ Not Implemented | Removed because it had no effect |
|
| `--debug=FLAGS` | Fine-grained debug verbosity | ❌ Not Implemented | Removed because it had no effect |
|
||||||
| `--stderr=MODE` | Change stderr output mode | ❌ Not Implemented | |
|
| `--stderr=MODE` | Change stderr output mode | ❌ Not Implemented | |
|
||||||
| `--no-motd` | Suppress daemon MOTD | ❌ Not Implemented | |
|
| `--no-motd` | Suppress daemon MOTD | ❌ Not Implemented | |
|
||||||
|
|||||||
+79
-10
@@ -88,6 +88,69 @@ static int set_nonneg_int_option(int* dest, const char* value, const char* optio
|
|||||||
|
|
||||||
static int read_patterns_from_file(const char* filepath, char*** patterns, int* count);
|
static int read_patterns_from_file(const char* filepath, char*** patterns, int* count);
|
||||||
|
|
||||||
|
static int parse_info_flags(const char* value, Config* config) {
|
||||||
|
if (!value || value[0] == '\0' || value[0] == ',' || value[strlen(value) - 1] == ',' ||
|
||||||
|
strstr(value, ",,")) {
|
||||||
|
log_message(LOG_LEVEL_ERROR, "--info requires at least one flag");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char* flags = str_dup(value);
|
||||||
|
if (!flags) {
|
||||||
|
log_message(LOG_LEVEL_ERROR, "memory allocation failed for --info");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t parsed = (uint32_t)config->info_level;
|
||||||
|
char* saveptr = NULL;
|
||||||
|
for (char* token = strtok_r(flags, ",", &saveptr); token != NULL;
|
||||||
|
token = strtok_r(NULL, ",", &saveptr)) {
|
||||||
|
uint32_t flag = 0;
|
||||||
|
if (strcmp(token, "all") == 0) {
|
||||||
|
parsed = LOG_INFO_ALL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(token, "none") == 0) {
|
||||||
|
parsed = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(token, "copy") == 0)
|
||||||
|
flag = LOG_INFO_COPY;
|
||||||
|
else if (strcmp(token, "del") == 0)
|
||||||
|
flag = LOG_INFO_DEL;
|
||||||
|
else if (strcmp(token, "flist") == 0)
|
||||||
|
flag = LOG_INFO_FLIST;
|
||||||
|
else if (strcmp(token, "misc") == 0)
|
||||||
|
flag = LOG_INFO_MISC;
|
||||||
|
else if (strcmp(token, "mount") == 0)
|
||||||
|
flag = LOG_INFO_MOUNT;
|
||||||
|
else if (strcmp(token, "name") == 0)
|
||||||
|
flag = LOG_INFO_NAME;
|
||||||
|
else if (strcmp(token, "nonreg") == 0)
|
||||||
|
flag = LOG_INFO_NONREG;
|
||||||
|
else if (strcmp(token, "progress") == 0)
|
||||||
|
flag = LOG_INFO_PROGRESS;
|
||||||
|
else if (strcmp(token, "skip") == 0)
|
||||||
|
flag = LOG_INFO_SKIP;
|
||||||
|
else if (strcmp(token, "stats") == 0)
|
||||||
|
flag = LOG_INFO_STATS;
|
||||||
|
else if (strcmp(token, "symsafe") == 0)
|
||||||
|
flag = LOG_INFO_SYMSAFE;
|
||||||
|
else if (strcmp(token, "backup") == 0)
|
||||||
|
flag = LOG_INFO_BACKUP;
|
||||||
|
else {
|
||||||
|
log_message(LOG_LEVEL_ERROR, "unknown --info flag: %s", token);
|
||||||
|
free(flags);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
parsed |= flag;
|
||||||
|
}
|
||||||
|
free(flags);
|
||||||
|
config->info_level = (int)parsed;
|
||||||
|
set_log_info_flags(parsed);
|
||||||
|
set_log_level(LOG_LEVEL_INFO);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a string as an unsigned long long. Returns 0 on success, -1 on error. */
|
/* Parse a string as an unsigned long long. Returns 0 on success, -1 on error. */
|
||||||
static int parse_ull_arg(const char* val, unsigned long long* out, const char* optname) {
|
static int parse_ull_arg(const char* val, unsigned long long* out, const char* optname) {
|
||||||
char* end;
|
char* end;
|
||||||
@@ -236,7 +299,7 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
config->use_compression = true;
|
config->use_compression = true;
|
||||||
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_info_message(LOG_INFO_MISC, "Enabled archive mode (-c -m -M)");
|
||||||
} else if (opt_is(argv[i], "-p", NULL) && i + 1 < argc) {
|
} else if (opt_is(argv[i], "-p", NULL) && i + 1 < argc) {
|
||||||
if (set_positive_int_option(&config->ssh_port, argv[++i], "-p") != 0)
|
if (set_positive_int_option(&config->ssh_port, argv[++i], "-p") != 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -270,7 +333,7 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
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 = true;
|
||||||
log_message(LOG_LEVEL_INFO, "Enabled Compression");
|
log_info_message(LOG_INFO_MISC, "Enabled Compression");
|
||||||
if (i + 1 < argc) {
|
if (i + 1 < argc) {
|
||||||
char* end_ptr;
|
char* end_ptr;
|
||||||
long level = strtol(argv[i + 1], &end_ptr, 10);
|
long level = strtol(argv[i + 1], &end_ptr, 10);
|
||||||
@@ -280,22 +343,22 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
config->compression_level = (int)level;
|
config->compression_level = (int)level;
|
||||||
log_message(LOG_LEVEL_INFO, "Set Compression level to %ld", level);
|
log_info_message(LOG_INFO_MISC, "Set Compression level to %ld", level);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (opt_is(argv[i], "-M", "--preserve")) {
|
} else if (opt_is(argv[i], "-M", "--preserve")) {
|
||||||
config->use_metadata = true;
|
config->use_metadata = true;
|
||||||
log_message(LOG_LEVEL_INFO, "Enabled metadata preservation");
|
log_info_message(LOG_INFO_MISC, "Enabled metadata preservation");
|
||||||
} else if (opt_is(argv[i], "-f", "--sendfile")) {
|
} else if (opt_is(argv[i], "-f", "--sendfile")) {
|
||||||
config->use_sendfile = true;
|
config->use_sendfile = true;
|
||||||
log_message(LOG_LEVEL_INFO, "Enabled sendfile");
|
log_info_message(LOG_INFO_MISC, "Enabled sendfile");
|
||||||
} else if (opt_is(argv[i], "-m", NULL)) {
|
} else if (opt_is(argv[i], "-m", NULL)) {
|
||||||
config->use_multithreading = true;
|
config->use_multithreading = true;
|
||||||
log_message(LOG_LEVEL_INFO, "Enabled Multithreading");
|
log_info_message(LOG_INFO_MISC, "Enabled Multithreading");
|
||||||
} else if (opt_is(argv[i], "-s", NULL)) {
|
} else if (opt_is(argv[i], "-s", NULL)) {
|
||||||
config->use_chunk_serialization = true;
|
config->use_chunk_serialization = true;
|
||||||
log_message(LOG_LEVEL_INFO, "Enabled Chunk Serialization");
|
log_info_message(LOG_INFO_MISC, "Enabled Chunk Serialization");
|
||||||
} else if (opt_is(argv[i], "--server-port", NULL) && i + 1 < argc) {
|
} else if (opt_is(argv[i], "--server-port", NULL) && i + 1 < argc) {
|
||||||
if (!parse_positive_int(argv[++i], &config->server_port)) {
|
if (!parse_positive_int(argv[++i], &config->server_port)) {
|
||||||
log_message(LOG_LEVEL_ERROR, "invalid --server-port value: %s", argv[i]);
|
log_message(LOG_LEVEL_ERROR, "invalid --server-port value: %s", argv[i]);
|
||||||
@@ -318,7 +381,7 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
io_set_bwlimit(kbps * 1024);
|
io_set_bwlimit(kbps * 1024);
|
||||||
log_message(LOG_LEVEL_INFO, "Set bandwidth limit to %llu KB/s", kbps);
|
log_info_message(LOG_INFO_MISC, "Set bandwidth limit to %llu KB/s", kbps);
|
||||||
} else if (opt_is(argv[i], "--chunk-size", NULL) && i + 1 < argc) {
|
} else if (opt_is(argv[i], "--chunk-size", NULL) && i + 1 < argc) {
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
if (parse_ull_arg(argv[++i], &val, "--chunk-size") != 0)
|
if (parse_ull_arg(argv[++i], &val, "--chunk-size") != 0)
|
||||||
@@ -351,6 +414,12 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
return -1;
|
return -1;
|
||||||
} else if (opt_is(argv[i], "-v", "--verbose")) {
|
} else if (opt_is(argv[i], "-v", "--verbose")) {
|
||||||
set_log_level(LOG_LEVEL_DEBUG);
|
set_log_level(LOG_LEVEL_DEBUG);
|
||||||
|
} else if (strncmp(argv[i], "--info=", 7) == 0) {
|
||||||
|
if (parse_info_flags(argv[i] + 7, config) != 0)
|
||||||
|
return -1;
|
||||||
|
} else if (opt_is(argv[i], "--info", NULL)) {
|
||||||
|
if (i + 1 >= argc || parse_info_flags(argv[++i], config) != 0)
|
||||||
|
return -1;
|
||||||
} 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;
|
||||||
@@ -483,11 +552,11 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
/* Enable implicit flags */
|
/* Enable implicit flags */
|
||||||
if (config->use_incremental && !config->use_metadata) {
|
if (config->use_incremental && !config->use_metadata) {
|
||||||
log_message(LOG_LEVEL_INFO, "Enabling metadata preservation for --incremental");
|
log_info_message(LOG_INFO_MISC, "Enabling metadata preservation for --incremental");
|
||||||
config->use_metadata = true;
|
config->use_metadata = true;
|
||||||
}
|
}
|
||||||
if (config->use_delta && !config->use_metadata) {
|
if (config->use_delta && !config->use_metadata) {
|
||||||
log_message(LOG_LEVEL_INFO, "Enabling metadata preservation for --delta");
|
log_info_message(LOG_INFO_MISC, "Enabling metadata preservation for --delta");
|
||||||
config->use_metadata = true;
|
config->use_metadata = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ static bool send_file_direct_sendfile(File* file, int fd, bool use_metadata) {
|
|||||||
static int send_single_file(Client* client, File* file, Config* config, bool use_incremental,
|
static int send_single_file(Client* client, File* file, Config* config, bool use_incremental,
|
||||||
bool use_sendfile) {
|
bool use_sendfile) {
|
||||||
int compression_level = config->use_compression ? config->compression_level : 0;
|
int compression_level = config->use_compression ? config->compression_level : 0;
|
||||||
|
log_info_message(LOG_INFO_COPY, "Transferring %s", file->path);
|
||||||
|
|
||||||
if (!use_incremental) {
|
if (!use_incremental) {
|
||||||
if (use_sendfile) {
|
if (use_sendfile) {
|
||||||
@@ -288,6 +289,7 @@ static int send_single_file(Client* client, File* file, Config* config, bool use
|
|||||||
DeltaSignature* sig = NULL;
|
DeltaSignature* sig = NULL;
|
||||||
int rc = incremental_check(client, file, config, &sig);
|
int rc = incremental_check(client, file, config, &sig);
|
||||||
if (rc == 1) {
|
if (rc == 1) {
|
||||||
|
log_info_message(LOG_INFO_SKIP, "Skipping unchanged %s", file->path);
|
||||||
delta_signature_destroy(sig);
|
delta_signature_destroy(sig);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -318,6 +320,7 @@ static int send_single_file(Client* client, File* file, Config* config, bool use
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (rc == 1) {
|
if (rc == 1) {
|
||||||
|
log_info_message(LOG_INFO_SKIP, "Skipping unchanged %s", file->path);
|
||||||
delta_signature_destroy(sig);
|
delta_signature_destroy(sig);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -680,6 +683,8 @@ int send_files(Config* config) {
|
|||||||
fprintf(stderr, "Stats: %d files, %.1f MB, %.1f MB/s\n", total_files, total_bytes / 1048576.0,
|
fprintf(stderr, "Stats: %d files, %.1f MB, %.1f MB/s\n", total_files, total_bytes / 1048576.0,
|
||||||
rate);
|
rate);
|
||||||
}
|
}
|
||||||
|
log_info_message(LOG_INFO_STATS, "Transfer summary: %d files, %.1f MB", total_files,
|
||||||
|
total_bytes / 1048576.0);
|
||||||
ret = ok ? 0 : 1;
|
ret = ok ? 0 : 1;
|
||||||
|
|
||||||
send_fail:
|
send_fail:
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ void print_usage(void) {
|
|||||||
printf(" -s Enable chunk serialization\n");
|
printf(" -s Enable chunk serialization\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(" -v, --verbose Enable debug logging\n");
|
printf(" -v, --verbose Enable debug logging\n");
|
||||||
|
printf(" --info=FLAGS Fine-grained info: copy,del,flist,misc,mount,name,nonreg,\n");
|
||||||
|
printf(" progress,skip,stats,symsafe,backup,all,none\n");
|
||||||
printf(" -M, --preserve Preserve file metadata\n");
|
printf(" -M, --preserve Preserve file metadata\n");
|
||||||
printf(" --chunk-size <n> Chunk size in bytes (default: %d)\n", DEFAULT_CHUNK_SIZE);
|
printf(" --chunk-size <n> Chunk size in bytes (default: %d)\n", DEFAULT_CHUNK_SIZE);
|
||||||
printf(" --source-dir <path> Source directory\n");
|
printf(" --source-dir <path> Source directory\n");
|
||||||
|
|||||||
@@ -7,12 +7,21 @@
|
|||||||
|
|
||||||
static const char* log_level_strings[] = {"DEBUG", "INFO", "WARN", "ERROR"};
|
static const char* log_level_strings[] = {"DEBUG", "INFO", "WARN", "ERROR"};
|
||||||
static LogLevel current_log_level = LOG_LEVEL_WARNING;
|
static LogLevel current_log_level = LOG_LEVEL_WARNING;
|
||||||
|
static uint32_t info_flags = 0;
|
||||||
static FILE* log_fp = NULL;
|
static FILE* log_fp = NULL;
|
||||||
|
|
||||||
void set_log_level(LogLevel level) {
|
void set_log_level(LogLevel level) {
|
||||||
current_log_level = level;
|
current_log_level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_log_info_flags(uint32_t flags) {
|
||||||
|
info_flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_log_info_flags(void) {
|
||||||
|
return info_flags;
|
||||||
|
}
|
||||||
|
|
||||||
void log_set_file(FILE* fp) {
|
void log_set_file(FILE* fp) {
|
||||||
log_fp = fp;
|
log_fp = fp;
|
||||||
}
|
}
|
||||||
@@ -53,6 +62,27 @@ void log_message(LogLevel log_level, const char* format, ...) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void log_info_message(LogInfoFlag flag, const char* format, ...) {
|
||||||
|
if ((info_flags & flag) == 0 && current_log_level > LOG_LEVEL_DEBUG)
|
||||||
|
return;
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm t;
|
||||||
|
if (!localtime_r(&now, &t))
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
write_message(stdout, LOG_LEVEL_INFO, t, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (log_fp) {
|
||||||
|
va_start(args, format);
|
||||||
|
write_message(log_fp, LOG_LEVEL_INFO, t, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void log_perror(const char* context) {
|
void log_perror(const char* context) {
|
||||||
log_message(LOG_LEVEL_ERROR, "%s: %s", context, strerror(errno));
|
log_message(LOG_LEVEL_ERROR, "%s: %s", context, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,32 @@
|
|||||||
#define LOG_H
|
#define LOG_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef enum { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR } LogLevel;
|
typedef enum { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR } LogLevel;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LOG_INFO_COPY = 1u << 0,
|
||||||
|
LOG_INFO_DEL = 1u << 1,
|
||||||
|
LOG_INFO_FLIST = 1u << 2,
|
||||||
|
LOG_INFO_MISC = 1u << 3,
|
||||||
|
LOG_INFO_MOUNT = 1u << 4,
|
||||||
|
LOG_INFO_NAME = 1u << 5,
|
||||||
|
LOG_INFO_NONREG = 1u << 6,
|
||||||
|
LOG_INFO_PROGRESS = 1u << 7,
|
||||||
|
LOG_INFO_SKIP = 1u << 8,
|
||||||
|
LOG_INFO_STATS = 1u << 9,
|
||||||
|
LOG_INFO_SYMSAFE = 1u << 10,
|
||||||
|
LOG_INFO_BACKUP = 1u << 11,
|
||||||
|
LOG_INFO_ALL = (1u << 12) - 1,
|
||||||
|
} LogInfoFlag;
|
||||||
|
|
||||||
void log_message(LogLevel log_level, const char* message, ...);
|
void log_message(LogLevel log_level, const char* message, ...);
|
||||||
void log_perror(const char* context);
|
void log_perror(const char* context);
|
||||||
void set_log_level(LogLevel level);
|
void set_log_level(LogLevel level);
|
||||||
|
void set_log_info_flags(uint32_t flags);
|
||||||
|
uint32_t get_log_info_flags(void);
|
||||||
|
void log_info_message(LogInfoFlag flag, const char* message, ...);
|
||||||
void log_set_file(FILE* fp);
|
void log_set_file(FILE* fp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -264,6 +264,27 @@ class TestProgress:
|
|||||||
assert "Done." in output, "--progress did not report completion"
|
assert "Done." in output, "--progress did not report completion"
|
||||||
|
|
||||||
|
|
||||||
|
class TestInfo:
|
||||||
|
def test_info_copy_reports_transfers(self, shared_server):
|
||||||
|
clean_dir(DEST_DIR)
|
||||||
|
result, _ = run_client(
|
||||||
|
SOURCE_DIR, DEST_DIR,
|
||||||
|
flags=["--info=copy"],
|
||||||
|
port=shared_server.port,
|
||||||
|
)
|
||||||
|
assert result.returncode == 0, f"Info sync failed: {(result.stderr or result.stdout)[:200]}"
|
||||||
|
output = result.stdout + result.stderr
|
||||||
|
assert "[INFO]" in output and "Transferring" in output
|
||||||
|
|
||||||
|
def test_info_rejects_unknown_flag(self):
|
||||||
|
result, _ = run_client(
|
||||||
|
SOURCE_DIR, DEST_DIR,
|
||||||
|
flags=["--info=unknown"],
|
||||||
|
)
|
||||||
|
assert result.returncode != 0
|
||||||
|
assert "unknown --info flag" in result.stderr
|
||||||
|
|
||||||
|
|
||||||
class TestBandwidthLimit:
|
class TestBandwidthLimit:
|
||||||
def test_bwlimit_runs(self, shared_server):
|
def test_bwlimit_runs(self, shared_server):
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
|
|||||||
+25
-1
@@ -1,6 +1,7 @@
|
|||||||
#include "test_client_cli.h"
|
#include "test_client_cli.h"
|
||||||
#include "client_validation.h"
|
#include "client_validation.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "log.h"
|
||||||
#include "test_utils.h"
|
#include "test_utils.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -277,7 +278,6 @@ static void test_parse_args_rejects_unimplemented_options() {
|
|||||||
"-i",
|
"-i",
|
||||||
"--itemize-changes",
|
"--itemize-changes",
|
||||||
"--out-format",
|
"--out-format",
|
||||||
"--info",
|
|
||||||
"--debug",
|
"--debug",
|
||||||
"--list-only",
|
"--list-only",
|
||||||
"-h",
|
"-h",
|
||||||
@@ -323,6 +323,28 @@ static void test_parse_args_rejects_unimplemented_options() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_parse_args_info_flags() {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char* argv[] = {"fastsync", "--info=copy,skip", "/src", "/dst"};
|
||||||
|
int positional_args[2];
|
||||||
|
int positional_count = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), 0);
|
||||||
|
EXPECT_EQ_INT(cfg->info_level, LOG_INFO_COPY | LOG_INFO_SKIP);
|
||||||
|
EXPECT_EQ_INT(get_log_info_flags(), LOG_INFO_COPY | LOG_INFO_SKIP);
|
||||||
|
config_delete(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_parse_args_rejects_invalid_info_flag() {
|
||||||
|
Config* cfg = config_create();
|
||||||
|
char* argv[] = {"fastsync", "--info=copy,unknown", "/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);
|
||||||
|
}
|
||||||
|
|
||||||
/* Test parse_args with --archive flag */
|
/* Test parse_args with --archive flag */
|
||||||
static void test_parse_args_archive() {
|
static void test_parse_args_archive() {
|
||||||
Config* cfg = config_create();
|
Config* cfg = config_create();
|
||||||
@@ -359,5 +381,7 @@ void test_client_cli() {
|
|||||||
test_parse_args_valid_compression_level();
|
test_parse_args_valid_compression_level();
|
||||||
test_parse_args_unknown_option();
|
test_parse_args_unknown_option();
|
||||||
test_parse_args_rejects_unimplemented_options();
|
test_parse_args_rejects_unimplemented_options();
|
||||||
|
test_parse_args_info_flags();
|
||||||
|
test_parse_args_rejects_invalid_info_flag();
|
||||||
test_parse_args_archive();
|
test_parse_args_archive();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user