mirror of
https://github.com/facebook/zstd.git
synced 2025-09-16 09:36:32 +02:00
Merge pull request #3394 from terrelln/issue-3010
[cli-tests] Test file stat read/write
This commit is contained in:
165
programs/util.c
165
programs/util.c
@@ -66,6 +66,27 @@ extern "C" {
|
|||||||
#define UTIL_DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
#define UTIL_DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
||||||
#define UTIL_DISPLAYLEVEL(l, ...) { if (g_utilDisplayLevel>=l) { UTIL_DISPLAY(__VA_ARGS__); } }
|
#define UTIL_DISPLAYLEVEL(l, ...) { if (g_utilDisplayLevel>=l) { UTIL_DISPLAY(__VA_ARGS__); } }
|
||||||
|
|
||||||
|
static int g_traceDepth = 0;
|
||||||
|
int g_traceFileStat = 0;
|
||||||
|
|
||||||
|
#define UTIL_TRACE_CALL(...) \
|
||||||
|
{ \
|
||||||
|
if (g_traceFileStat) { \
|
||||||
|
UTIL_DISPLAY("Trace:FileStat: %*s> ", g_traceDepth, ""); \
|
||||||
|
UTIL_DISPLAY(__VA_ARGS__); \
|
||||||
|
UTIL_DISPLAY("\n"); \
|
||||||
|
++g_traceDepth; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UTIL_TRACE_RET(ret) \
|
||||||
|
{ \
|
||||||
|
if (g_traceFileStat) { \
|
||||||
|
--g_traceDepth; \
|
||||||
|
UTIL_DISPLAY("Trace:FileStat: %*s< %d\n", g_traceDepth, "", (ret)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
/* A modified version of realloc().
|
/* A modified version of realloc().
|
||||||
* If UTIL_realloc() fails the original block is freed.
|
* If UTIL_realloc() fails the original block is freed.
|
||||||
*/
|
*/
|
||||||
@@ -121,21 +142,34 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg,
|
|||||||
* Functions
|
* Functions
|
||||||
***************************************/
|
***************************************/
|
||||||
|
|
||||||
|
void UTIL_traceFileStat(void)
|
||||||
|
{
|
||||||
|
g_traceFileStat = 1;
|
||||||
|
}
|
||||||
|
|
||||||
int UTIL_stat(const char* filename, stat_t* statbuf)
|
int UTIL_stat(const char* filename, stat_t* statbuf)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
UTIL_TRACE_CALL("UTIL_stat(%s)", filename);
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
return !_stat64(filename, statbuf);
|
ret = !_stat64(filename, statbuf);
|
||||||
#elif defined(__MINGW32__) && defined (__MSVCRT__)
|
#elif defined(__MINGW32__) && defined (__MSVCRT__)
|
||||||
return !_stati64(filename, statbuf);
|
ret = !_stati64(filename, statbuf);
|
||||||
#else
|
#else
|
||||||
return !stat(filename, statbuf);
|
ret = !stat(filename, statbuf);
|
||||||
#endif
|
#endif
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UTIL_isRegularFile(const char* infilename)
|
int UTIL_isRegularFile(const char* infilename)
|
||||||
{
|
{
|
||||||
stat_t statbuf;
|
stat_t statbuf;
|
||||||
return UTIL_stat(infilename, &statbuf) && UTIL_isRegularFileStat(&statbuf);
|
int ret;
|
||||||
|
UTIL_TRACE_CALL("UTIL_isRegularFile(%s)", infilename);
|
||||||
|
ret = UTIL_stat(infilename, &statbuf) && UTIL_isRegularFileStat(&statbuf);
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UTIL_isRegularFileStat(const stat_t* statbuf)
|
int UTIL_isRegularFileStat(const stat_t* statbuf)
|
||||||
@@ -151,44 +185,66 @@ int UTIL_isRegularFileStat(const stat_t* statbuf)
|
|||||||
int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions)
|
int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions)
|
||||||
{
|
{
|
||||||
stat_t localStatBuf;
|
stat_t localStatBuf;
|
||||||
|
UTIL_TRACE_CALL("UTIL_chmod(%s, %u)", filename, (unsigned)permissions);
|
||||||
if (statbuf == NULL) {
|
if (statbuf == NULL) {
|
||||||
if (!UTIL_stat(filename, &localStatBuf)) return 0;
|
if (!UTIL_stat(filename, &localStatBuf)) {
|
||||||
|
UTIL_TRACE_RET(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
statbuf = &localStatBuf;
|
statbuf = &localStatBuf;
|
||||||
}
|
}
|
||||||
if (!UTIL_isRegularFileStat(statbuf)) return 0; /* pretend success, but don't change anything */
|
if (!UTIL_isRegularFileStat(statbuf)) {
|
||||||
return chmod(filename, permissions);
|
UTIL_TRACE_RET(0);
|
||||||
|
return 0; /* pretend success, but don't change anything */
|
||||||
|
}
|
||||||
|
UTIL_TRACE_CALL("chmod");
|
||||||
|
{
|
||||||
|
int const ret = chmod(filename, permissions);
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set access and modification times */
|
/* set access and modification times */
|
||||||
int UTIL_utime(const char* filename, const stat_t *statbuf)
|
int UTIL_utime(const char* filename, const stat_t *statbuf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
UTIL_TRACE_CALL("UTIL_utime(%s)", filename);
|
||||||
/* We check that st_mtime is a macro here in order to give us confidence
|
/* We check that st_mtime is a macro here in order to give us confidence
|
||||||
* that struct stat has a struct timespec st_mtim member. We need this
|
* that struct stat has a struct timespec st_mtim member. We need this
|
||||||
* check because there are some platforms that claim to be POSIX 2008
|
* check because there are some platforms that claim to be POSIX 2008
|
||||||
* compliant but which do not have st_mtim... */
|
* compliant but which do not have st_mtim... */
|
||||||
#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime)
|
#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime)
|
||||||
/* (atime, mtime) */
|
{
|
||||||
struct timespec timebuf[2] = { {0, UTIME_NOW} };
|
/* (atime, mtime) */
|
||||||
timebuf[1] = statbuf->st_mtim;
|
struct timespec timebuf[2] = { {0, UTIME_NOW} };
|
||||||
ret = utimensat(AT_FDCWD, filename, timebuf, 0);
|
timebuf[1] = statbuf->st_mtim;
|
||||||
|
ret = utimensat(AT_FDCWD, filename, timebuf, 0);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
struct utimbuf timebuf;
|
{
|
||||||
timebuf.actime = time(NULL);
|
struct utimbuf timebuf;
|
||||||
timebuf.modtime = statbuf->st_mtime;
|
timebuf.actime = time(NULL);
|
||||||
ret = utime(filename, &timebuf);
|
timebuf.modtime = statbuf->st_mtime;
|
||||||
|
ret = utime(filename, &timebuf);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
|
int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
stat_t curStatBuf;
|
stat_t curStatBuf;
|
||||||
if (!UTIL_stat(filename, &curStatBuf) || !UTIL_isRegularFileStat(&curStatBuf))
|
UTIL_TRACE_CALL("UTIL_setFileStat(%s)", filename);
|
||||||
|
|
||||||
|
if (!UTIL_stat(filename, &curStatBuf) || !UTIL_isRegularFileStat(&curStatBuf)) {
|
||||||
|
UTIL_TRACE_RET(-1);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* set access and modification times */
|
/* set access and modification times */
|
||||||
res += UTIL_utime(filename, statbuf);
|
res += UTIL_utime(filename, statbuf);
|
||||||
@@ -200,13 +256,18 @@ int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
|
|||||||
res += UTIL_chmod(filename, &curStatBuf, statbuf->st_mode & 07777); /* Copy file permissions */
|
res += UTIL_chmod(filename, &curStatBuf, statbuf->st_mode & 07777); /* Copy file permissions */
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
UTIL_TRACE_RET(-res);
|
||||||
return -res; /* number of errors is returned */
|
return -res; /* number of errors is returned */
|
||||||
}
|
}
|
||||||
|
|
||||||
int UTIL_isDirectory(const char* infilename)
|
int UTIL_isDirectory(const char* infilename)
|
||||||
{
|
{
|
||||||
stat_t statbuf;
|
stat_t statbuf;
|
||||||
return UTIL_stat(infilename, &statbuf) && UTIL_isDirectoryStat(&statbuf);
|
int ret;
|
||||||
|
UTIL_TRACE_CALL("UTIL_isDirectory(%s)", infilename);
|
||||||
|
ret = UTIL_stat(infilename, &statbuf) && UTIL_isDirectoryStat(&statbuf);
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UTIL_isDirectoryStat(const stat_t* statbuf)
|
int UTIL_isDirectoryStat(const stat_t* statbuf)
|
||||||
@@ -224,33 +285,44 @@ int UTIL_compareStr(const void *p1, const void *p2) {
|
|||||||
|
|
||||||
int UTIL_isSameFile(const char* fName1, const char* fName2)
|
int UTIL_isSameFile(const char* fName1, const char* fName2)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
assert(fName1 != NULL); assert(fName2 != NULL);
|
assert(fName1 != NULL); assert(fName2 != NULL);
|
||||||
|
UTIL_TRACE_CALL("UTIL_isSameFile(%s, %s)", fName1, fName2);
|
||||||
#if defined(_MSC_VER) || defined(_WIN32)
|
#if defined(_MSC_VER) || defined(_WIN32)
|
||||||
/* note : Visual does not support file identification by inode.
|
/* note : Visual does not support file identification by inode.
|
||||||
* inode does not work on Windows, even with a posix layer, like msys2.
|
* inode does not work on Windows, even with a posix layer, like msys2.
|
||||||
* The following work-around is limited to detecting exact name repetition only,
|
* The following work-around is limited to detecting exact name repetition only,
|
||||||
* aka `filename` is considered different from `subdir/../filename` */
|
* aka `filename` is considered different from `subdir/../filename` */
|
||||||
return !strcmp(fName1, fName2);
|
ret = !strcmp(fName1, fName2);
|
||||||
#else
|
#else
|
||||||
{ stat_t file1Stat;
|
{ stat_t file1Stat;
|
||||||
stat_t file2Stat;
|
stat_t file2Stat;
|
||||||
return UTIL_stat(fName1, &file1Stat)
|
ret = UTIL_stat(fName1, &file1Stat)
|
||||||
&& UTIL_stat(fName2, &file2Stat)
|
&& UTIL_stat(fName2, &file2Stat)
|
||||||
&& (file1Stat.st_dev == file2Stat.st_dev)
|
&& (file1Stat.st_dev == file2Stat.st_dev)
|
||||||
&& (file1Stat.st_ino == file2Stat.st_ino);
|
&& (file1Stat.st_ino == file2Stat.st_ino);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UTIL_isFIFO : distinguish named pipes */
|
/* UTIL_isFIFO : distinguish named pipes */
|
||||||
int UTIL_isFIFO(const char* infilename)
|
int UTIL_isFIFO(const char* infilename)
|
||||||
{
|
{
|
||||||
|
UTIL_TRACE_CALL("UTIL_isFIFO(%s)", infilename);
|
||||||
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */
|
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */
|
||||||
#if PLATFORM_POSIX_VERSION >= 200112L
|
#if PLATFORM_POSIX_VERSION >= 200112L
|
||||||
stat_t statbuf;
|
{
|
||||||
if (UTIL_stat(infilename, &statbuf) && UTIL_isFIFOStat(&statbuf)) return 1;
|
stat_t statbuf;
|
||||||
|
if (UTIL_stat(infilename, &statbuf) && UTIL_isFIFOStat(&statbuf)) {
|
||||||
|
UTIL_TRACE_RET(1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
(void)infilename;
|
(void)infilename;
|
||||||
|
UTIL_TRACE_RET(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,13 +350,20 @@ int UTIL_isBlockDevStat(const stat_t* statbuf)
|
|||||||
|
|
||||||
int UTIL_isLink(const char* infilename)
|
int UTIL_isLink(const char* infilename)
|
||||||
{
|
{
|
||||||
|
UTIL_TRACE_CALL("UTIL_isLink(%s)", infilename);
|
||||||
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */
|
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */
|
||||||
#if PLATFORM_POSIX_VERSION >= 200112L
|
#if PLATFORM_POSIX_VERSION >= 200112L
|
||||||
stat_t statbuf;
|
{
|
||||||
int const r = lstat(infilename, &statbuf);
|
stat_t statbuf;
|
||||||
if (!r && S_ISLNK(statbuf.st_mode)) return 1;
|
int const r = lstat(infilename, &statbuf);
|
||||||
|
if (!r && S_ISLNK(statbuf.st_mode)) {
|
||||||
|
UTIL_TRACE_RET(1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
(void)infilename;
|
(void)infilename;
|
||||||
|
UTIL_TRACE_RET(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,13 +373,18 @@ static int g_fakeStdoutIsConsole = 0;
|
|||||||
|
|
||||||
int UTIL_isConsole(FILE* file)
|
int UTIL_isConsole(FILE* file)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
UTIL_TRACE_CALL("UTIL_isConsole(%d)", fileno(file));
|
||||||
if (file == stdin && g_fakeStdinIsConsole)
|
if (file == stdin && g_fakeStdinIsConsole)
|
||||||
return 1;
|
ret = 1;
|
||||||
if (file == stderr && g_fakeStderrIsConsole)
|
else if (file == stderr && g_fakeStderrIsConsole)
|
||||||
return 1;
|
ret = 1;
|
||||||
if (file == stdout && g_fakeStdoutIsConsole)
|
else if (file == stdout && g_fakeStdoutIsConsole)
|
||||||
return 1;
|
ret = 1;
|
||||||
return IS_CONSOLE(file);
|
else
|
||||||
|
ret = IS_CONSOLE(file);
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_fakeStdinIsConsole(void)
|
void UTIL_fakeStdinIsConsole(void)
|
||||||
@@ -319,8 +403,16 @@ void UTIL_fakeStderrIsConsole(void)
|
|||||||
U64 UTIL_getFileSize(const char* infilename)
|
U64 UTIL_getFileSize(const char* infilename)
|
||||||
{
|
{
|
||||||
stat_t statbuf;
|
stat_t statbuf;
|
||||||
if (!UTIL_stat(infilename, &statbuf)) return UTIL_FILESIZE_UNKNOWN;
|
UTIL_TRACE_CALL("UTIL_getFileSize(%s)", infilename);
|
||||||
return UTIL_getFileSizeStat(&statbuf);
|
if (!UTIL_stat(infilename, &statbuf)) {
|
||||||
|
UTIL_TRACE_RET(-1);
|
||||||
|
return UTIL_FILESIZE_UNKNOWN;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
U64 const size = UTIL_getFileSizeStat(&statbuf);
|
||||||
|
UTIL_TRACE_RET((int)size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
U64 UTIL_getFileSizeStat(const stat_t* statbuf)
|
U64 UTIL_getFileSizeStat(const stat_t* statbuf)
|
||||||
@@ -397,11 +489,16 @@ U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles)
|
|||||||
{
|
{
|
||||||
U64 total = 0;
|
U64 total = 0;
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
UTIL_TRACE_CALL("UTIL_getTotalFileSize(%u)", nbFiles);
|
||||||
for (n=0; n<nbFiles; n++) {
|
for (n=0; n<nbFiles; n++) {
|
||||||
U64 const size = UTIL_getFileSize(fileNamesTable[n]);
|
U64 const size = UTIL_getFileSize(fileNamesTable[n]);
|
||||||
if (size == UTIL_FILESIZE_UNKNOWN) return UTIL_FILESIZE_UNKNOWN;
|
if (size == UTIL_FILESIZE_UNKNOWN) {
|
||||||
|
UTIL_TRACE_RET(-1);
|
||||||
|
return UTIL_FILESIZE_UNKNOWN;
|
||||||
|
}
|
||||||
total += size;
|
total += size;
|
||||||
}
|
}
|
||||||
|
UTIL_TRACE_RET((int)total);
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -189,6 +189,11 @@ void UTIL_fakeStdinIsConsole(void);
|
|||||||
void UTIL_fakeStdoutIsConsole(void);
|
void UTIL_fakeStdoutIsConsole(void);
|
||||||
void UTIL_fakeStderrIsConsole(void);
|
void UTIL_fakeStderrIsConsole(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit traces for functions that read, or modify file metadata.
|
||||||
|
*/
|
||||||
|
void UTIL_traceFileStat(void);
|
||||||
|
|
||||||
#define UTIL_FILESIZE_UNKNOWN ((U64)(-1))
|
#define UTIL_FILESIZE_UNKNOWN ((U64)(-1))
|
||||||
U64 UTIL_getFileSize(const char* infilename);
|
U64 UTIL_getFileSize(const char* infilename);
|
||||||
U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles);
|
U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles);
|
||||||
|
@@ -1004,6 +1004,7 @@ int main(int argCount, const char* argv[])
|
|||||||
if (!strcmp(argument, "--fake-stdin-is-console")) { UTIL_fakeStdinIsConsole(); continue; }
|
if (!strcmp(argument, "--fake-stdin-is-console")) { UTIL_fakeStdinIsConsole(); continue; }
|
||||||
if (!strcmp(argument, "--fake-stdout-is-console")) { UTIL_fakeStdoutIsConsole(); continue; }
|
if (!strcmp(argument, "--fake-stdout-is-console")) { UTIL_fakeStdoutIsConsole(); continue; }
|
||||||
if (!strcmp(argument, "--fake-stderr-is-console")) { UTIL_fakeStderrIsConsole(); continue; }
|
if (!strcmp(argument, "--fake-stderr-is-console")) { UTIL_fakeStderrIsConsole(); continue; }
|
||||||
|
if (!strcmp(argument, "--trace-file-stat")) { UTIL_traceFileStat(); continue; }
|
||||||
|
|
||||||
/* long commands with arguments */
|
/* long commands with arguments */
|
||||||
#ifndef ZSTD_NODICT
|
#ifndef ZSTD_NODICT
|
||||||
|
@@ -45,6 +45,16 @@ Examples:
|
|||||||
./run.py --preserve --verbose basic/help.sh
|
./run.py --preserve --verbose basic/help.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Updating exact output
|
||||||
|
|
||||||
|
If a test is failing because a `.stderr.exact` or `.stdout.exact` no longer matches, you can re-run the tests with `--set-exact-output` and the correct output will be written.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
./run.py --set-exact-output
|
||||||
|
./run.py basic/help.sh --set-exact-output
|
||||||
|
```
|
||||||
|
|
||||||
## Writing a test
|
## Writing a test
|
||||||
|
|
||||||
Test cases are arbitrary executables, and can be written in any language, but are generally shell scripts.
|
Test cases are arbitrary executables, and can be written in any language, but are generally shell scripts.
|
||||||
|
8
tests/cli-tests/file-stat/compress-file-to-file.sh
Executable file
8
tests/cli-tests/file-stat/compress-file-to-file.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen > file
|
||||||
|
|
||||||
|
zstd file -q --trace-file-stat -o file.zst
|
||||||
|
zstd -tq file.zst
|
@@ -0,0 +1,36 @@
|
|||||||
|
Trace:FileStat: > UTIL_isLink(file)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(2)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 65537
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_isSameFile(file, file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 65537
|
||||||
|
Trace:FileStat: > UTIL_utime(file.zst)
|
||||||
|
Trace:FileStat: < 0
|
8
tests/cli-tests/file-stat/compress-file-to-stdout.sh
Executable file
8
tests/cli-tests/file-stat/compress-file-to-stdout.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen > file
|
||||||
|
|
||||||
|
zstd file -cq --trace-file-stat > file.zst
|
||||||
|
zstd -tq file.zst
|
@@ -0,0 +1,22 @@
|
|||||||
|
Trace:FileStat: > UTIL_isLink(file)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(1)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 65537
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdout*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 65537
|
8
tests/cli-tests/file-stat/compress-stdin-to-file.sh
Executable file
8
tests/cli-tests/file-stat/compress-stdin-to-file.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen > file
|
||||||
|
|
||||||
|
zstd < file -q --trace-file-stat -o file.zst
|
||||||
|
zstd -tq file.zst
|
@@ -0,0 +1,28 @@
|
|||||||
|
Trace:FileStat: > UTIL_isConsole(0)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(2)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < -1
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isSameFile(/*stdin*\, file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < -1
|
8
tests/cli-tests/file-stat/compress-stdin-to-stdout.sh
Executable file
8
tests/cli-tests/file-stat/compress-stdin-to-stdout.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen > file
|
||||||
|
|
||||||
|
zstd < file -cq --trace-file-stat > file.zst
|
||||||
|
zstd -tq file.zst
|
@@ -0,0 +1,20 @@
|
|||||||
|
Trace:FileStat: > UTIL_isConsole(0)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(1)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < -1
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdout*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < -1
|
7
tests/cli-tests/file-stat/decompress-file-to-file.sh
Executable file
7
tests/cli-tests/file-stat/decompress-file-to-file.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen | zstd -q > file.zst
|
||||||
|
|
||||||
|
zstd -dq --trace-file-stat file.zst
|
@@ -0,0 +1,30 @@
|
|||||||
|
Trace:FileStat: > UTIL_isLink(file.zst)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(1)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(2)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_isSameFile(file.zst, file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_utime(file)
|
||||||
|
Trace:FileStat: < 0
|
7
tests/cli-tests/file-stat/decompress-file-to-stdout.sh
Executable file
7
tests/cli-tests/file-stat/decompress-file-to-stdout.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen | zstd -q > file.zst
|
||||||
|
|
||||||
|
zstd -dcq --trace-file-stat file.zst > file
|
@@ -0,0 +1,14 @@
|
|||||||
|
Trace:FileStat: > UTIL_isLink(file.zst)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(1)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(file.zst)
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_stat(file.zst)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdout*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
7
tests/cli-tests/file-stat/decompress-stdin-to-file.sh
Executable file
7
tests/cli-tests/file-stat/decompress-stdin-to-file.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen | zstd -q > file.zst
|
||||||
|
|
||||||
|
zstd -dcq --trace-file-stat < file.zst -o file
|
@@ -0,0 +1,20 @@
|
|||||||
|
Trace:FileStat: > UTIL_isConsole(0)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(2)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isSameFile(/*stdin*\, file)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(file)
|
||||||
|
Trace:FileStat: > UTIL_stat(file)
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
7
tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh
Executable file
7
tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
datagen | zstd -q > file.zst
|
||||||
|
|
||||||
|
zstd -dcq --trace-file-stat < file.zst > file
|
@@ -0,0 +1,12 @@
|
|||||||
|
Trace:FileStat: > UTIL_isConsole(0)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isConsole(1)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdin*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
|
||||||
|
Trace:FileStat: > UTIL_stat(/*stdout*\)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: < 0
|
@@ -209,6 +209,7 @@ class Options:
|
|||||||
preserve: bool,
|
preserve: bool,
|
||||||
scratch_dir: str,
|
scratch_dir: str,
|
||||||
test_dir: str,
|
test_dir: str,
|
||||||
|
set_exact_output: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.env = env
|
self.env = env
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
@@ -216,6 +217,7 @@ class Options:
|
|||||||
self.preserve = preserve
|
self.preserve = preserve
|
||||||
self.scratch_dir = scratch_dir
|
self.scratch_dir = scratch_dir
|
||||||
self.test_dir = test_dir
|
self.test_dir = test_dir
|
||||||
|
self.set_exact_output = set_exact_output
|
||||||
|
|
||||||
|
|
||||||
class TestCase:
|
class TestCase:
|
||||||
@@ -335,7 +337,7 @@ class TestCase:
|
|||||||
self._test_stdin.close()
|
self._test_stdin.close()
|
||||||
self._test_stdin = None
|
self._test_stdin = None
|
||||||
|
|
||||||
def _check_output_exact(self, out_name: str, expected: bytes) -> None:
|
def _check_output_exact(self, out_name: str, expected: bytes, exact_name: str) -> None:
|
||||||
"""
|
"""
|
||||||
Check the output named :out_name: for an exact match against the :expected: content.
|
Check the output named :out_name: for an exact match against the :expected: content.
|
||||||
Saves the success and message.
|
Saves the success and message.
|
||||||
@@ -349,6 +351,10 @@ class TestCase:
|
|||||||
self._success[check_name] = False
|
self._success[check_name] = False
|
||||||
self._message[check_name] = f"{out_name} does not match!\n> diff expected actual\n{diff(expected, actual)}"
|
self._message[check_name] = f"{out_name} does not match!\n> diff expected actual\n{diff(expected, actual)}"
|
||||||
|
|
||||||
|
if self._opts.set_exact_output:
|
||||||
|
with open(exact_name, "wb") as f:
|
||||||
|
f.write(actual)
|
||||||
|
|
||||||
def _check_output_glob(self, out_name: str, expected: bytes) -> None:
|
def _check_output_glob(self, out_name: str, expected: bytes) -> None:
|
||||||
"""
|
"""
|
||||||
Check the output named :out_name: for a glob match against the :expected: glob.
|
Check the output named :out_name: for a glob match against the :expected: glob.
|
||||||
@@ -386,7 +392,7 @@ class TestCase:
|
|||||||
ignore_name = f"{self._test_file}.{out_name}.ignore"
|
ignore_name = f"{self._test_file}.{out_name}.ignore"
|
||||||
|
|
||||||
if os.path.exists(exact_name):
|
if os.path.exists(exact_name):
|
||||||
return self._check_output_exact(out_name, read_file(exact_name))
|
return self._check_output_exact(out_name, read_file(exact_name), exact_name)
|
||||||
elif os.path.exists(glob_name):
|
elif os.path.exists(glob_name):
|
||||||
return self._check_output_glob(out_name, read_file(glob_name))
|
return self._check_output_glob(out_name, read_file(glob_name))
|
||||||
elif os.path.exists(ignore_name):
|
elif os.path.exists(ignore_name):
|
||||||
@@ -394,7 +400,7 @@ class TestCase:
|
|||||||
self._success[check_name] = True
|
self._success[check_name] = True
|
||||||
self._message[check_name] = f"{out_name} ignored!"
|
self._message[check_name] = f"{out_name} ignored!"
|
||||||
else:
|
else:
|
||||||
return self._check_output_exact(out_name, bytes())
|
return self._check_output_exact(out_name, bytes(), exact_name)
|
||||||
|
|
||||||
def _check_stderr(self) -> None:
|
def _check_stderr(self) -> None:
|
||||||
"""Checks the stderr output against the expectation."""
|
"""Checks the stderr output against the expectation."""
|
||||||
@@ -678,6 +684,11 @@ if __name__ == "__main__":
|
|||||||
"Scratch directory located in TEST_DIR/scratch/."
|
"Scratch directory located in TEST_DIR/scratch/."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--set-exact-output",
|
||||||
|
action="store_true",
|
||||||
|
help="Set stderr.exact and stdout.exact for all failing tests, unless .ignore or .glob already exists"
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"tests",
|
"tests",
|
||||||
nargs="*",
|
nargs="*",
|
||||||
@@ -714,6 +725,7 @@ if __name__ == "__main__":
|
|||||||
preserve=args.preserve,
|
preserve=args.preserve,
|
||||||
test_dir=args.test_dir,
|
test_dir=args.test_dir,
|
||||||
scratch_dir=scratch_dir,
|
scratch_dir=scratch_dir,
|
||||||
|
set_exact_output=args.set_exact_output,
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(args.tests) == 0:
|
if len(args.tests) == 0:
|
||||||
|
Reference in New Issue
Block a user