summaryrefslogtreecommitdiff
path: root/t/unit-tests
diff options
context:
space:
mode:
Diffstat (limited to 't/unit-tests')
-rw-r--r--t/unit-tests/clar/.github/workflows/ci.yml37
-rw-r--r--t/unit-tests/clar/CMakeLists.txt13
-rw-r--r--t/unit-tests/clar/README.md37
-rw-r--r--t/unit-tests/clar/clar.c156
-rw-r--r--t/unit-tests/clar/clar.h83
-rw-r--r--t/unit-tests/clar/clar/fixtures.h6
-rw-r--r--t/unit-tests/clar/clar/fs.h29
-rw-r--r--t/unit-tests/clar/clar/print.h71
-rw-r--r--t/unit-tests/clar/clar/sandbox.h226
-rw-r--r--t/unit-tests/clar/clar/summary.h5
-rw-r--r--t/unit-tests/clar/example/CMakeLists.txt28
-rw-r--r--t/unit-tests/clar/example/example.c6
-rw-r--r--t/unit-tests/clar/example/main.c (renamed from t/unit-tests/clar/test/main.c.sample)2
-rwxr-xr-xt/unit-tests/clar/generate.py28
-rw-r--r--t/unit-tests/clar/test/CMakeLists.txt34
-rw-r--r--t/unit-tests/clar/test/clar_test.h16
-rw-r--r--t/unit-tests/clar/test/expected/help12
-rw-r--r--t/unit-tests/clar/test/expected/quiet44
-rw-r--r--t/unit-tests/clar/test/expected/specific_test9
-rw-r--r--t/unit-tests/clar/test/expected/stop_on_failure8
-rw-r--r--t/unit-tests/clar/test/expected/suite_names2
-rw-r--r--t/unit-tests/clar/test/expected/summary.xml41
-rw-r--r--t/unit-tests/clar/test/expected/summary_with_filename49
-rw-r--r--t/unit-tests/clar/test/expected/summary_without_filename49
-rw-r--r--t/unit-tests/clar/test/expected/tap92
-rw-r--r--t/unit-tests/clar/test/expected/without_arguments48
-rw-r--r--t/unit-tests/clar/test/main.c41
-rw-r--r--t/unit-tests/clar/test/selftest.c370
-rw-r--r--t/unit-tests/clar/test/selftest.h3
-rw-r--r--t/unit-tests/clar/test/suites/CMakeLists.txt53
-rw-r--r--t/unit-tests/clar/test/suites/combined.c (renamed from t/unit-tests/clar/test/sample.c)37
-rw-r--r--t/unit-tests/clar/test/suites/main.c27
-rw-r--r--t/unit-tests/clar/test/suites/pointer.c13
-rw-r--r--t/unit-tests/clar/test/suites/resources/test/file (renamed from t/unit-tests/clar/test/resources/test/file)0
-rw-r--r--t/unit-tests/lib-reftable.c35
-rw-r--r--t/unit-tests/lib-reftable.h15
-rw-r--r--t/unit-tests/t-reftable-basics.c219
-rw-r--r--t/unit-tests/u-dir.c47
-rw-r--r--t/unit-tests/u-prio-queue.c23
-rw-r--r--t/unit-tests/u-reftable-basics.c243
-rw-r--r--t/unit-tests/u-reftable-block.c (renamed from t/unit-tests/t-reftable-block.c)164
-rw-r--r--t/unit-tests/u-reftable-merged.c (renamed from t/unit-tests/t-reftable-merged.c)160
-rw-r--r--t/unit-tests/u-reftable-pq.c (renamed from t/unit-tests/t-reftable-pq.c)59
-rw-r--r--t/unit-tests/u-reftable-readwrite.c (renamed from t/unit-tests/t-reftable-readwrite.c)403
-rw-r--r--t/unit-tests/u-reftable-record.c (renamed from t/unit-tests/t-reftable-record.c)250
-rw-r--r--t/unit-tests/u-reftable-stack.c (renamed from t/unit-tests/t-reftable-stack.c)789
-rw-r--r--t/unit-tests/u-reftable-table.c (renamed from t/unit-tests/t-reftable-table.c)73
-rw-r--r--t/unit-tests/u-string-list.c306
-rw-r--r--t/unit-tests/unit-test.h7
49 files changed, 2916 insertions, 1552 deletions
diff --git a/t/unit-tests/clar/.github/workflows/ci.yml b/t/unit-tests/clar/.github/workflows/ci.yml
index 0065843d17..4d4724222c 100644
--- a/t/unit-tests/clar/.github/workflows/ci.yml
+++ b/t/unit-tests/clar/.github/workflows/ci.yml
@@ -13,23 +13,56 @@ jobs:
platform:
- os: ubuntu-latest
generator: Unix Makefiles
+ env:
+ CFLAGS: "-Werror -Wall -Wextra"
+ - os: ubuntu-latest
+ generator: Unix Makefiles
+ env:
+ CC: "clang"
+ CFLAGS: "-Werror -Wall -Wextra -fsanitize=leak"
+ - os: ubuntu-latest
+ generator: Unix Makefiles
+ image: i386/debian:latest
+ env:
+ CFLAGS: "-Werror -Wall -Wextra"
- os: macos-latest
generator: Unix Makefiles
+ env:
+ CFLAGS: "-Werror -Wall -Wextra"
- os: windows-latest
generator: Visual Studio 17 2022
- os: windows-latest
generator: MSYS Makefiles
+ env:
+ CFLAGS: "-Werror -Wall -Wextra"
- os: windows-latest
generator: MinGW Makefiles
+ env:
+ CFLAGS: "-Werror -Wall -Wextra"
+ fail-fast: false
runs-on: ${{ matrix.platform.os }}
+ container: ${{matrix.platform.image}}
+
+ env:
+ CC: ${{matrix.platform.env.CC}}
+ CFLAGS: ${{matrix.platform.env.CFLAGS}}
steps:
+ - name: Prepare 32 bit container image
+ if: matrix.platform.image == 'i386/debian:latest'
+ run: apt -q update && apt -q -y install cmake gcc libc6-amd64 lib64stdc++6 make python3
- name: Check out
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Build
+ shell: bash
run: |
mkdir build
cd build
cmake .. -G "${{matrix.platform.generator}}"
- cmake --build .
+ cmake --build . --verbose
+ - name: Test
+ shell: bash
+ run: |
+ cd build
+ CTEST_OUTPUT_ON_FAILURE=1 ctest --build-config Debug
diff --git a/t/unit-tests/clar/CMakeLists.txt b/t/unit-tests/clar/CMakeLists.txt
index 12d4af114f..125db05bc1 100644
--- a/t/unit-tests/clar/CMakeLists.txt
+++ b/t/unit-tests/clar/CMakeLists.txt
@@ -1,8 +1,15 @@
+include(CheckFunctionExists)
+
cmake_minimum_required(VERSION 3.16..3.29)
project(clar LANGUAGES C)
-option(BUILD_TESTS "Build test executable" ON)
+option(BUILD_EXAMPLE "Build the example." ON)
+
+check_function_exists(realpath CLAR_HAS_REALPATH)
+if(CLAR_HAS_REALPATH)
+ add_compile_definitions(-DCLAR_HAS_REALPATH)
+endif()
add_library(clar INTERFACE)
target_sources(clar INTERFACE
@@ -25,4 +32,8 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
if(BUILD_TESTING)
add_subdirectory(test)
endif()
+
+ if(BUILD_EXAMPLE)
+ add_subdirectory(example)
+ endif()
endif()
diff --git a/t/unit-tests/clar/README.md b/t/unit-tests/clar/README.md
index a8961c5f10..41595989ca 100644
--- a/t/unit-tests/clar/README.md
+++ b/t/unit-tests/clar/README.md
@@ -26,8 +26,7 @@ Can you count to funk?
~~~~ sh
$ mkdir tests
$ cp -r $CLAR_ROOT/clar* tests
- $ cp $CLAR_ROOT/test/clar_test.h tests
- $ cp $CLAR_ROOT/test/main.c.sample tests/main.c
+ $ cp $CLAR_ROOT/example/*.c tests
~~~~
- **One: Write some tests**
@@ -147,7 +146,7 @@ To use Clar:
1. copy the Clar boilerplate to your test directory
2. copy (and probably modify) the sample `main.c` (from
- `$CLAR_PATH/test/main.c.sample`)
+ `$CLAR_PATH/example/main.c`)
3. run the Clar mixer (a.k.a. `generate.py`) to scan your test directory and
write out the test suite metadata.
4. compile your test files and the Clar boilerplate into a single test
@@ -159,7 +158,7 @@ The Clar boilerplate gives you a set of useful test assertions and features
the `clar.c` and `clar.h` files, plus the code in the `clar/` subdirectory.
You should not need to edit these files.
-The sample `main.c` (i.e. `$CLAR_PATH/test/main.c.sample`) file invokes
+The sample `main.c` (i.e. `$CLAR_PATH/example/main.c`) file invokes
`clar_test(argc, argv)` to run the tests. Usually, you will edit this file
to perform any framework specific initialization and teardown that you need.
@@ -251,11 +250,16 @@ suite.
- `cl_fixture(const char *)`: Gets the full path to a fixture file.
-Please do note that these methods are *always* available whilst running a
-test, even when calling auxiliary/static functions inside the same file.
+### Auxiliary / helper functions
-It's strongly encouraged to perform test assertions in auxiliary methods,
-instead of returning error values. This is considered good Clar style.
+The clar API is always available while running a test, even when calling
+"auxiliary" (helper) functions.
+
+You're encouraged to perform test assertions in those auxiliary
+methods, instead of returning error values. This is considered good
+Clar style. _However_, when you do this, you need to call `cl_invoke`
+to preserve the current state; this ensures that failures are reported
+as coming from the actual test, instead of the auxiliary method.
Style Example:
@@ -310,20 +314,19 @@ static void check_string(const char *str)
void test_example__a_test_with_auxiliary_methods(void)
{
- check_string("foo");
- check_string("bar");
+ cl_invoke(check_string("foo"));
+ cl_invoke(check_string("bar"));
}
~~~~
About Clar
==========
-Clar has been written from scratch by [Vicent Martí](https://github.com/vmg),
-to replace the old testing framework in [libgit2][libgit2].
-
-Do you know what languages are *in* on the SF startup scene? Node.js *and*
-Latin. Follow [@vmg](https://www.twitter.com/vmg) on Twitter to
-receive more lessons on word etymology. You can be hip too.
-
+Clar was originally written by [Vicent Martí](https://github.com/vmg),
+to replace the old testing framework in [libgit2][libgit2]. It is
+currently maintained by [Edward Thomson](https://github.com/ethomson),
+and used by the [libgit2][libgit2] and [git][git] projects, amongst
+others.
[libgit2]: https://github.com/libgit2/libgit2
+[git]: https://github.com/git/git
diff --git a/t/unit-tests/clar/clar.c b/t/unit-tests/clar/clar.c
index d54e455367..d6176e50b2 100644
--- a/t/unit-tests/clar/clar.c
+++ b/t/unit-tests/clar/clar.c
@@ -79,6 +79,8 @@
# else
# define p_snprintf snprintf
# endif
+
+# define localtime_r(timer, buf) (localtime_s(buf, timer) == 0 ? buf : NULL)
#else
# include <sys/wait.h> /* waitpid(2) */
# include <unistd.h>
@@ -150,7 +152,6 @@ static struct {
enum cl_output_format output_format;
- int report_errors_only;
int exit_on_error;
int verbosity;
@@ -164,6 +165,10 @@ static struct {
struct clar_report *reports;
struct clar_report *last_report;
+ const char *invoke_file;
+ const char *invoke_func;
+ size_t invoke_line;
+
void (*local_cleanup)(void *);
void *local_cleanup_payload;
@@ -190,7 +195,7 @@ struct clar_suite {
};
/* From clar_print_*.c */
-static void clar_print_init(int test_count, int suite_count, const char *suite_names);
+static void clar_print_init(int test_count, int suite_count);
static void clar_print_shutdown(int test_count, int suite_count, int error_count);
static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error);
static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status failed);
@@ -199,8 +204,10 @@ static void clar_print_onabortv(const char *msg, va_list argp);
static void clar_print_onabort(const char *msg, ...);
/* From clar_sandbox.c */
-static void clar_unsandbox(void);
-static void clar_sandbox(void);
+static void clar_tempdir_init(void);
+static void clar_tempdir_shutdown(void);
+static int clar_sandbox_create(const char *suite_name, const char *test_name);
+static int clar_sandbox_cleanup(void);
/* From summary.h */
static struct clar_summary *clar_summary_init(const char *filename);
@@ -304,6 +311,8 @@ clar_run_test(
CL_TRACE(CL_TRACE__TEST__BEGIN);
+ clar_sandbox_create(suite->name, test->name);
+
_clar.last_report->start = time(NULL);
clar_time_now(&start);
@@ -328,9 +337,13 @@ clar_run_test(
if (_clar.local_cleanup != NULL)
_clar.local_cleanup(_clar.local_cleanup_payload);
+ clar__clear_invokepoint();
+
if (cleanup->ptr != NULL)
cleanup->ptr();
+ clar_sandbox_cleanup();
+
CL_TRACE(CL_TRACE__TEST__END);
_clar.tests_ran++;
@@ -339,18 +352,14 @@ clar_run_test(
_clar.local_cleanup = NULL;
_clar.local_cleanup_payload = NULL;
- if (_clar.report_errors_only) {
- clar_report_errors(_clar.last_report);
- } else {
- clar_print_ontest(suite->name, test->name, _clar.tests_ran, _clar.last_report->status);
- }
+ clar_print_ontest(suite->name, test->name, _clar.tests_ran, _clar.last_report->status);
}
static void
clar_run_suite(const struct clar_suite *suite, const char *filter)
{
const struct clar_func *test = suite->tests;
- size_t i, matchlen;
+ size_t i, matchlen = 0;
struct clar_report *report;
int exact = 0;
@@ -360,8 +369,7 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
if (_clar.exit_on_error && _clar.total_errors)
return;
- if (!_clar.report_errors_only)
- clar_print_onsuite(suite->name, ++_clar.suites_ran);
+ clar_print_onsuite(suite->name, ++_clar.suites_ran);
_clar.active_suite = suite->name;
_clar.active_test = NULL;
@@ -428,12 +436,12 @@ clar_usage(const char *arg)
printf(" -iname Include the suite with `name`\n");
printf(" -xname Exclude the suite with `name`\n");
printf(" -v Increase verbosity (show suite names)\n");
- printf(" -q Only report tests that had an error\n");
+ printf(" -q Decrease verbosity, inverse to -v\n");
printf(" -Q Quit as soon as a test fails\n");
printf(" -t Display results in tap format\n");
printf(" -l Print suite names\n");
printf(" -r[filename] Write summary file (to the optional filename)\n");
- exit(-1);
+ exit(1);
}
static void
@@ -441,18 +449,11 @@ clar_parse_args(int argc, char **argv)
{
int i;
- /* Verify options before execute */
for (i = 1; i < argc; ++i) {
char *argument = argv[i];
- if (argument[0] != '-' || argument[1] == '\0'
- || strchr("sixvqQtlr", argument[1]) == NULL) {
+ if (argument[0] != '-' || argument[1] == '\0')
clar_usage(argv[0]);
- }
- }
-
- for (i = 1; i < argc; ++i) {
- char *argument = argv[i];
switch (argument[1]) {
case 's':
@@ -465,8 +466,13 @@ clar_parse_args(int argc, char **argv)
argument += offset;
arglen = strlen(argument);
- if (arglen == 0)
- clar_usage(argv[0]);
+ if (arglen == 0) {
+ if (i + 1 == argc)
+ clar_usage(argv[0]);
+
+ argument = argv[++i];
+ arglen = strlen(argument);
+ }
for (j = 0; j < _clar_suite_count; ++j) {
suitelen = strlen(_clar_suites[j].name);
@@ -483,9 +489,6 @@ clar_parse_args(int argc, char **argv)
++found;
- if (!exact)
- _clar.verbosity = MAX(_clar.verbosity, 1);
-
switch (action) {
case 's': {
struct clar_explicit *explicit;
@@ -517,23 +520,37 @@ clar_parse_args(int argc, char **argv)
if (!found)
clar_abort("No suite matching '%s' found.\n", argument);
+
break;
}
case 'q':
- _clar.report_errors_only = 1;
+ if (argument[2] != '\0')
+ clar_usage(argv[0]);
+
+ _clar.verbosity--;
break;
case 'Q':
+ if (argument[2] != '\0')
+ clar_usage(argv[0]);
+
_clar.exit_on_error = 1;
break;
case 't':
+ if (argument[2] != '\0')
+ clar_usage(argv[0]);
+
_clar.output_format = CL_OUTPUT_TAP;
break;
case 'l': {
size_t j;
+
+ if (argument[2] != '\0')
+ clar_usage(argv[0]);
+
printf("Test suites (use -s<name> to run just one):\n");
for (j = 0; j < _clar_suite_count; ++j)
printf(" %3d: %s\n", (int)j, _clar_suites[j].name);
@@ -542,23 +559,27 @@ clar_parse_args(int argc, char **argv)
}
case 'v':
+ if (argument[2] != '\0')
+ clar_usage(argv[0]);
+
_clar.verbosity++;
break;
case 'r':
_clar.write_summary = 1;
free(_clar.summary_filename);
+
if (*(argument + 2)) {
if ((_clar.summary_filename = strdup(argument + 2)) == NULL)
clar_abort("Failed to allocate summary filename.\n");
} else {
_clar.summary_filename = NULL;
}
+
break;
default:
- clar_abort("Unexpected commandline argument '%s'.\n",
- argument[1]);
+ clar_usage(argv[0]);
}
}
}
@@ -571,11 +592,7 @@ clar_test_init(int argc, char **argv)
if (argc > 1)
clar_parse_args(argc, argv);
- clar_print_init(
- (int)_clar_callback_count,
- (int)_clar_suite_count,
- ""
- );
+ clar_print_init((int)_clar_callback_count, (int)_clar_suite_count);
if (!_clar.summary_filename &&
(summary_env = getenv("CLAR_SUMMARY")) != NULL) {
@@ -591,7 +608,7 @@ clar_test_init(int argc, char **argv)
if (_clar.write_summary)
_clar.summary = clar_summary_init(_clar.summary_filename);
- clar_sandbox();
+ clar_tempdir_init();
}
int
@@ -623,7 +640,7 @@ clar_test_shutdown(void)
_clar.total_errors
);
- clar_unsandbox();
+ clar_tempdir_shutdown();
if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0)
clar_abort("Failed to write the summary file '%s: %s.\n",
@@ -635,6 +652,14 @@ clar_test_shutdown(void)
}
for (report = _clar.reports; report; report = report_next) {
+ struct clar_error *error, *error_next;
+
+ for (error = report->errors; error; error = error_next) {
+ free(error->description);
+ error_next = error->next;
+ free(error);
+ }
+
report_next = report->next;
free(report);
}
@@ -660,7 +685,7 @@ static void abort_test(void)
clar_print_onabort(
"Fatal error: a cleanup method raised an exception.\n");
clar_report_errors(_clar.last_report);
- exit(-1);
+ exit(1);
}
CL_TRACE(CL_TRACE__TEST__LONGJMP);
@@ -695,9 +720,9 @@ void clar__fail(
_clar.last_report->last_error = error;
- error->file = file;
- error->function = function;
- error->line_number = line;
+ error->file = _clar.invoke_file ? _clar.invoke_file : file;
+ error->function = _clar.invoke_func ? _clar.invoke_func : function;
+ error->line_number = _clar.invoke_line ? _clar.invoke_line : line;
error->error_msg = error_msg;
if (description != NULL &&
@@ -754,7 +779,12 @@ void clar__assert_equal(
p_snprintf(buf, sizeof(buf), "'%s' != '%s' (at byte %d)",
s1, s2, pos);
} else {
- p_snprintf(buf, sizeof(buf), "'%s' != '%s'", s1, s2);
+ const char *q1 = s1 ? "'" : "";
+ const char *q2 = s2 ? "'" : "";
+ s1 = s1 ? s1 : "NULL";
+ s2 = s2 ? s2 : "NULL";
+ p_snprintf(buf, sizeof(buf), "%s%s%s != %s%s%s",
+ q1, s1, q1, q2, s2, q2);
}
}
}
@@ -767,12 +797,17 @@ void clar__assert_equal(
if (!is_equal) {
if (s1 && s2) {
int pos;
- for (pos = 0; s1[pos] == s2[pos] && pos < len; ++pos)
+ for (pos = 0; pos < len && s1[pos] == s2[pos]; ++pos)
/* find differing byte offset */;
p_snprintf(buf, sizeof(buf), "'%.*s' != '%.*s' (at byte %d)",
len, s1, len, s2, pos);
} else {
- p_snprintf(buf, sizeof(buf), "'%.*s' != '%.*s'", len, s1, len, s2);
+ const char *q1 = s1 ? "'" : "";
+ const char *q2 = s2 ? "'" : "";
+ s1 = s1 ? s1 : "NULL";
+ s2 = s2 ? s2 : "NULL";
+ p_snprintf(buf, sizeof(buf), "%s%.*s%s != %s%.*s%s",
+ q1, len, s1, q1, q2, len, s2, q2);
}
}
}
@@ -790,7 +825,12 @@ void clar__assert_equal(
p_snprintf(buf, sizeof(buf), "'%ls' != '%ls' (at byte %d)",
wcs1, wcs2, pos);
} else {
- p_snprintf(buf, sizeof(buf), "'%ls' != '%ls'", wcs1, wcs2);
+ const char *q1 = wcs1 ? "'" : "";
+ const char *q2 = wcs2 ? "'" : "";
+ wcs1 = wcs1 ? wcs1 : L"NULL";
+ wcs2 = wcs2 ? wcs2 : L"NULL";
+ p_snprintf(buf, sizeof(buf), "%s%ls%s != %s%ls%s",
+ q1, wcs1, q1, q2, wcs2, q2);
}
}
}
@@ -803,12 +843,17 @@ void clar__assert_equal(
if (!is_equal) {
if (wcs1 && wcs2) {
int pos;
- for (pos = 0; wcs1[pos] == wcs2[pos] && pos < len; ++pos)
+ for (pos = 0; pos < len && wcs1[pos] == wcs2[pos]; ++pos)
/* find differing byte offset */;
p_snprintf(buf, sizeof(buf), "'%.*ls' != '%.*ls' (at byte %d)",
len, wcs1, len, wcs2, pos);
} else {
- p_snprintf(buf, sizeof(buf), "'%.*ls' != '%.*ls'", len, wcs1, len, wcs2);
+ const char *q1 = wcs1 ? "'" : "";
+ const char *q2 = wcs2 ? "'" : "";
+ wcs1 = wcs1 ? wcs1 : L"NULL";
+ wcs2 = wcs2 ? wcs2 : L"NULL";
+ p_snprintf(buf, sizeof(buf), "%s%.*ls%s != %s%.*ls%s",
+ q1, len, wcs1, q1, q2, len, wcs2, q2);
}
}
}
@@ -850,6 +895,23 @@ void cl_set_cleanup(void (*cleanup)(void *), void *opaque)
_clar.local_cleanup_payload = opaque;
}
+void clar__set_invokepoint(
+ const char *file,
+ const char *func,
+ size_t line)
+{
+ _clar.invoke_file = file;
+ _clar.invoke_func = func;
+ _clar.invoke_line = line;
+}
+
+void clar__clear_invokepoint(void)
+{
+ _clar.invoke_file = NULL;
+ _clar.invoke_func = NULL;
+ _clar.invoke_line = 0;
+}
+
#include "clar/sandbox.h"
#include "clar/fixtures.h"
#include "clar/fs.h"
diff --git a/t/unit-tests/clar/clar.h b/t/unit-tests/clar/clar.h
index 8c22382bd5..ca72292ae9 100644
--- a/t/unit-tests/clar/clar.h
+++ b/t/unit-tests/clar/clar.h
@@ -8,6 +8,25 @@
#define __CLAR_TEST_H__
#include <stdlib.h>
+#include <limits.h>
+
+#if defined(_WIN32) && defined(CLAR_WIN32_LONGPATHS)
+# define CLAR_MAX_PATH 4096
+#elif defined(_WIN32)
+# define CLAR_MAX_PATH MAX_PATH
+#else
+# define CLAR_MAX_PATH PATH_MAX
+#endif
+
+#ifndef CLAR_SELFTEST
+# define CLAR_CURRENT_FILE __FILE__
+# define CLAR_CURRENT_LINE __LINE__
+# define CLAR_CURRENT_FUNC __func__
+#else
+# define CLAR_CURRENT_FILE "file"
+# define CLAR_CURRENT_LINE 42
+# define CLAR_CURRENT_FUNC "func"
+#endif
enum cl_test_status {
CL_TEST_OK,
@@ -30,6 +49,7 @@ void clar_test_shutdown(void);
int clar_test(int argc, char *argv[]);
const char *clar_sandbox_path(void);
+const char *clar_tempdir_path(void);
void cl_set_cleanup(void (*cleanup)(void *), void *opaque);
void cl_fs_cleanup(void);
@@ -84,18 +104,32 @@ const char *cl_fixture_basename(const char *fixture_name);
#endif
/**
+ * Invoke a helper function, which itself will use `cl_assert`
+ * constructs. This will preserve the stack information of the
+ * current call point, so that function name and line number
+ * information is shown from the line of the test, instead of
+ * the helper function.
+ */
+#define cl_invoke(expr) \
+ do { \
+ clar__set_invokepoint(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE); \
+ expr; \
+ clar__clear_invokepoint(); \
+ } while(0)
+
+/**
* Assertion macros with explicit error message
*/
-#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 1)
-#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 1)
-#define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 1)
+#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Function call failed: " #expr, desc, 1)
+#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Expected function call to fail: " #expr, desc, 1)
+#define cl_assert_(expr, desc) clar__assert((expr) != 0, CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Expression is not true: " #expr, desc, 1)
/**
* Check macros with explicit error message
*/
-#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 0)
-#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 0)
-#define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 0)
+#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Function call failed: " #expr, desc, 0)
+#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Expected function call to fail: " #expr, desc, 0)
+#define cl_check_(expr, desc) clar__assert((expr) != 0, CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Expression is not true: " #expr, desc, 0)
/**
* Assertion macros with no error message
@@ -114,33 +148,33 @@ const char *cl_fixture_basename(const char *fixture_name);
/**
* Forced failure/warning
*/
-#define cl_fail(desc) clar__fail(__FILE__, __func__, __LINE__, "Test failed.", desc, 1)
-#define cl_warning(desc) clar__fail(__FILE__, __func__, __LINE__, "Warning during test execution:", desc, 0)
+#define cl_fail(desc) clar__fail(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Test failed.", desc, 1)
+#define cl_warning(desc) clar__fail(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Warning during test execution:", desc, 0)
#define cl_skip() clar__skip()
/**
* Typed assertion macros
*/
-#define cl_assert_equal_s(s1,s2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%s", (s1), (s2))
-#define cl_assert_equal_s_(s1,s2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%s", (s1), (s2))
+#define cl_assert_equal_s(s1,s2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #s1 " != " #s2, 1, "%s", (s1), (s2))
+#define cl_assert_equal_s_(s1,s2,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%s", (s1), (s2))
-#define cl_assert_equal_wcs(wcs1,wcs2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%ls", (wcs1), (wcs2))
-#define cl_assert_equal_wcs_(wcs1,wcs2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%ls", (wcs1), (wcs2))
+#define cl_assert_equal_wcs(wcs1,wcs2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2, 1, "%ls", (wcs1), (wcs2))
+#define cl_assert_equal_wcs_(wcs1,wcs2,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%ls", (wcs1), (wcs2))
-#define cl_assert_equal_strn(s1,s2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%.*s", (s1), (s2), (int)(len))
-#define cl_assert_equal_strn_(s1,s2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%.*s", (s1), (s2), (int)(len))
+#define cl_assert_equal_strn(s1,s2,len) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #s1 " != " #s2, 1, "%.*s", (s1), (s2), (int)(len))
+#define cl_assert_equal_strn_(s1,s2,len,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%.*s", (s1), (s2), (int)(len))
-#define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len))
-#define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len))
+#define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len))
+#define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len))
-#define cl_assert_equal_i(i1,i2) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
-#define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2))
-#define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2))
+#define cl_assert_equal_i(i1,i2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
+#define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2))
+#define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2))
-#define cl_assert_equal_b(b1,b2) clar__assert_equal(__FILE__,__func__,__LINE__,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))
+#define cl_assert_equal_b(b1,b2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))
-#define cl_assert_equal_p(p1,p2) clar__assert_equal(__FILE__,__func__,__LINE__,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2))
+#define cl_assert_equal_p(p1,p2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2))
void clar__skip(void);
@@ -170,4 +204,11 @@ void clar__assert_equal(
const char *fmt,
...);
+void clar__set_invokepoint(
+ const char *file,
+ const char *func,
+ size_t line);
+
+void clar__clear_invokepoint(void);
+
#endif
diff --git a/t/unit-tests/clar/clar/fixtures.h b/t/unit-tests/clar/clar/fixtures.h
index 6ec6423484..9f1023df59 100644
--- a/t/unit-tests/clar/clar/fixtures.h
+++ b/t/unit-tests/clar/clar/fixtures.h
@@ -2,7 +2,7 @@
static const char *
fixture_path(const char *base, const char *fixture_name)
{
- static char _path[4096];
+ static char _path[CLAR_MAX_PATH];
size_t root_len;
root_len = strlen(base);
@@ -28,7 +28,7 @@ const char *cl_fixture(const char *fixture_name)
void cl_fixture_sandbox(const char *fixture_name)
{
- fs_copy(cl_fixture(fixture_name), _clar_path);
+ fs_copy(cl_fixture(fixture_name), clar_sandbox_path());
}
const char *cl_fixture_basename(const char *fixture_name)
@@ -45,6 +45,6 @@ const char *cl_fixture_basename(const char *fixture_name)
void cl_fixture_cleanup(const char *fixture_name)
{
- fs_rm(fixture_path(_clar_path, cl_fixture_basename(fixture_name)));
+ fs_rm(fixture_path(clar_sandbox_path(), cl_fixture_basename(fixture_name)));
}
#endif
diff --git a/t/unit-tests/clar/clar/fs.h b/t/unit-tests/clar/clar/fs.h
index 2203743fb4..f1311d91e8 100644
--- a/t/unit-tests/clar/clar/fs.h
+++ b/t/unit-tests/clar/clar/fs.h
@@ -8,12 +8,6 @@
#ifdef _WIN32
-#ifdef CLAR_WIN32_LONGPATHS
-# define CLAR_MAX_PATH 4096
-#else
-# define CLAR_MAX_PATH MAX_PATH
-#endif
-
#define RM_RETRY_COUNT 5
#define RM_RETRY_DELAY 10
@@ -296,7 +290,7 @@ void
cl_fs_cleanup(void)
{
#ifdef CLAR_FIXTURE_PATH
- fs_rm(fixture_path(_clar_path, "*"));
+ fs_rm(fixture_path(clar_tempdir_path(), "*"));
#else
((void)fs_copy); /* unused */
#endif
@@ -371,17 +365,19 @@ static void
fs_copydir_helper(const char *source, const char *dest, int dest_mode)
{
DIR *source_dir;
- struct dirent *d;
mkdir(dest, dest_mode);
cl_assert_(source_dir = opendir(source), "Could not open source dir");
- for (;;) {
+ while (1) {
+ struct dirent *d;
char *child;
errno = 0;
- if ((d = readdir(source_dir)) == NULL)
+ d = readdir(source_dir);
+ if (!d)
break;
+
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
@@ -479,15 +475,18 @@ static void
fs_rmdir_helper(const char *path)
{
DIR *dir;
- struct dirent *d;
cl_assert_(dir = opendir(path), "Could not open dir");
- for (;;) {
+
+ while (1) {
+ struct dirent *d;
char *child;
errno = 0;
- if ((d = readdir(dir)) == NULL)
+ d = readdir(dir);
+ if (!d)
break;
+
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
@@ -524,7 +523,7 @@ fs_rm(const char *path)
void
cl_fs_cleanup(void)
{
- clar_unsandbox();
- clar_sandbox();
+ clar_tempdir_shutdown();
+ clar_tempdir_init();
}
#endif
diff --git a/t/unit-tests/clar/clar/print.h b/t/unit-tests/clar/clar/print.h
index 69d0ee967e..89b66591d7 100644
--- a/t/unit-tests/clar/clar/print.h
+++ b/t/unit-tests/clar/clar/print.h
@@ -1,9 +1,13 @@
/* clap: clar protocol, the traditional clar output format */
-static void clar_print_clap_init(int test_count, int suite_count, const char *suite_names)
+static void clar_print_clap_init(int test_count, int suite_count)
{
(void)test_count;
- printf("Loaded %d suites: %s\n", (int)suite_count, suite_names);
+
+ if (_clar.verbosity < 0)
+ return;
+
+ printf("Loaded %d suites:\n", (int)suite_count);
printf("Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')\n");
}
@@ -13,10 +17,27 @@ static void clar_print_clap_shutdown(int test_count, int suite_count, int error_
(void)suite_count;
(void)error_count;
- printf("\n\n");
+ if (_clar.verbosity >= 0)
+ printf("\n\n");
clar_report_all();
}
+
+static void clar_print_indented(const char *str, int indent)
+{
+ const char *bol, *eol;
+
+ for (bol = str; *bol; bol = eol) {
+ eol = strchr(bol, '\n');
+ if (eol)
+ eol++;
+ else
+ eol = bol + strlen(bol);
+ printf("%*s%.*s", indent, "", (int)(eol - bol), bol);
+ }
+ putc('\n', stdout);
+}
+
static void clar_print_clap_error(int num, const struct clar_report *report, const struct clar_error *error)
{
printf(" %d) Failure:\n", num);
@@ -27,10 +48,10 @@ static void clar_print_clap_error(int num, const struct clar_report *report, con
error->file,
error->line_number);
- printf(" %s\n", error->error_msg);
+ clar_print_indented(error->error_msg, 2);
if (error->description != NULL)
- printf(" %s\n", error->description);
+ clar_print_indented(error->description, 2);
printf("\n");
fflush(stdout);
@@ -41,14 +62,17 @@ static void clar_print_clap_ontest(const char *suite_name, const char *test_name
(void)test_name;
(void)test_number;
+ if (_clar.verbosity < 0)
+ return;
+
if (_clar.verbosity > 1) {
printf("%s::%s: ", suite_name, test_name);
switch (status) {
case CL_TEST_OK: printf("ok\n"); break;
case CL_TEST_FAILURE: printf("fail\n"); break;
- case CL_TEST_SKIP: printf("skipped"); break;
- case CL_TEST_NOTRUN: printf("notrun"); break;
+ case CL_TEST_SKIP: printf("skipped\n"); break;
+ case CL_TEST_NOTRUN: printf("notrun\n"); break;
}
} else {
switch (status) {
@@ -64,6 +88,8 @@ static void clar_print_clap_ontest(const char *suite_name, const char *test_name
static void clar_print_clap_onsuite(const char *suite_name, int suite_index)
{
+ if (_clar.verbosity < 0)
+ return;
if (_clar.verbosity == 1)
printf("\n%s", suite_name);
@@ -77,11 +103,10 @@ static void clar_print_clap_onabort(const char *fmt, va_list arg)
/* tap: test anywhere protocol format */
-static void clar_print_tap_init(int test_count, int suite_count, const char *suite_names)
+static void clar_print_tap_init(int test_count, int suite_count)
{
(void)test_count;
(void)suite_count;
- (void)suite_names;
printf("TAP version 13\n");
}
@@ -127,18 +152,20 @@ static void clar_print_tap_ontest(const char *suite_name, const char *test_name,
case CL_TEST_FAILURE:
printf("not ok %d - %s::%s\n", test_number, suite_name, test_name);
- printf(" ---\n");
- printf(" reason: |\n");
- printf(" %s\n", error->error_msg);
+ if (_clar.verbosity >= 0) {
+ printf(" ---\n");
+ printf(" reason: |\n");
+ clar_print_indented(error->error_msg, 6);
- if (error->description)
- printf(" %s\n", error->description);
+ if (error->description)
+ clar_print_indented(error->description, 6);
- printf(" at:\n");
- printf(" file: '"); print_escaped(error->file); printf("'\n");
- printf(" line: %" PRIuMAX "\n", error->line_number);
- printf(" function: '%s'\n", error->function);
- printf(" ---\n");
+ printf(" at:\n");
+ printf(" file: '"); print_escaped(error->file); printf("'\n");
+ printf(" line: %" PRIuMAX "\n", error->line_number);
+ printf(" function: '%s'\n", error->function);
+ printf(" ---\n");
+ }
break;
case CL_TEST_SKIP:
@@ -152,6 +179,8 @@ static void clar_print_tap_ontest(const char *suite_name, const char *test_name,
static void clar_print_tap_onsuite(const char *suite_name, int suite_index)
{
+ if (_clar.verbosity < 0)
+ return;
printf("# start of suite %d: %s\n", suite_index, suite_name);
}
@@ -177,9 +206,9 @@ static void clar_print_tap_onabort(const char *fmt, va_list arg)
} \
} while (0)
-static void clar_print_init(int test_count, int suite_count, const char *suite_names)
+static void clar_print_init(int test_count, int suite_count)
{
- PRINT(init, test_count, suite_count, suite_names);
+ PRINT(init, test_count, suite_count);
}
static void clar_print_shutdown(int test_count, int suite_count, int error_count)
diff --git a/t/unit-tests/clar/clar/sandbox.h b/t/unit-tests/clar/clar/sandbox.h
index bc960f50e0..52add8aceb 100644
--- a/t/unit-tests/clar/clar/sandbox.h
+++ b/t/unit-tests/clar/clar/sandbox.h
@@ -2,7 +2,17 @@
#include <sys/syslimits.h>
#endif
-static char _clar_path[4096 + 1];
+/*
+ * The tempdir is the temporary directory for the entirety of the clar
+ * process execution. The sandbox is an individual temporary directory
+ * for the execution of an individual test. Sandboxes are deleted
+ * entirely after test execution to avoid pollution across tests.
+ */
+
+static char _clar_tempdir[CLAR_MAX_PATH];
+static size_t _clar_tempdir_len;
+
+static char _clar_sandbox[CLAR_MAX_PATH];
static int
is_valid_tmp_path(const char *path)
@@ -15,7 +25,10 @@ is_valid_tmp_path(const char *path)
if (!S_ISDIR(st.st_mode))
return 0;
- return (access(path, W_OK) == 0);
+ if (access(path, W_OK) != 0)
+ return 0;
+
+ return (strlen(path) < CLAR_MAX_PATH);
}
static int
@@ -31,14 +44,11 @@ find_tmp_path(char *buffer, size_t length)
for (i = 0; i < var_count; ++i) {
const char *env = getenv(env_vars[i]);
+
if (!env)
continue;
if (is_valid_tmp_path(env)) {
-#ifdef __APPLE__
- if (length >= PATH_MAX && realpath(env, buffer) != NULL)
- return 0;
-#endif
strncpy(buffer, env, length - 1);
buffer[length - 1] = '\0';
return 0;
@@ -47,21 +57,18 @@ find_tmp_path(char *buffer, size_t length)
/* If the environment doesn't say anything, try to use /tmp */
if (is_valid_tmp_path("/tmp")) {
-#ifdef __APPLE__
- if (length >= PATH_MAX && realpath("/tmp", buffer) != NULL)
- return 0;
-#endif
strncpy(buffer, "/tmp", length - 1);
buffer[length - 1] = '\0';
return 0;
}
#else
- DWORD env_len = GetEnvironmentVariable("CLAR_TMP", buffer, (DWORD)length);
- if (env_len > 0 && env_len < (DWORD)length)
+ DWORD len = GetEnvironmentVariable("CLAR_TMP", buffer, (DWORD)length);
+ if (len > 0 && len < (DWORD)length)
return 0;
- if (GetTempPath((DWORD)length, buffer))
+ len = GetTempPath((DWORD)length, buffer);
+ if (len > 0 && len < (DWORD)length)
return 0;
#endif
@@ -75,17 +82,53 @@ find_tmp_path(char *buffer, size_t length)
return -1;
}
-static void clar_unsandbox(void)
+static int canonicalize_tmp_path(char *buffer)
+{
+#ifdef _WIN32
+ char tmp[CLAR_MAX_PATH], *p;
+ DWORD ret;
+
+ ret = GetFullPathName(buffer, CLAR_MAX_PATH, tmp, NULL);
+
+ if (ret == 0 || ret > CLAR_MAX_PATH)
+ return -1;
+
+ ret = GetLongPathName(tmp, buffer, CLAR_MAX_PATH);
+
+ if (ret == 0 || ret > CLAR_MAX_PATH)
+ return -1;
+
+ /* normalize path to POSIX forward slashes */
+ for (p = buffer; *p; p++)
+ if (*p == '\\')
+ *p = '/';
+
+ return 0;
+#elif defined(CLAR_HAS_REALPATH)
+ char tmp[CLAR_MAX_PATH];
+
+ if (realpath(buffer, tmp) == NULL)
+ return -1;
+
+ strcpy(buffer, tmp);
+ return 0;
+#else
+ (void)buffer;
+ return 0;
+#endif
+}
+
+static void clar_tempdir_shutdown(void)
{
- if (_clar_path[0] == '\0')
+ if (_clar_tempdir[0] == '\0')
return;
cl_must_pass(chdir(".."));
- fs_rm(_clar_path);
+ fs_rm(_clar_tempdir);
}
-static int build_sandbox_path(void)
+static int build_tempdir_path(void)
{
#ifdef CLAR_TMPDIR
const char path_tail[] = CLAR_TMPDIR "_XXXXXX";
@@ -95,64 +138,153 @@ static int build_sandbox_path(void)
size_t len;
- if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0)
+ if (find_tmp_path(_clar_tempdir, sizeof(_clar_tempdir)) < 0 ||
+ canonicalize_tmp_path(_clar_tempdir) < 0)
return -1;
- len = strlen(_clar_path);
+ len = strlen(_clar_tempdir);
-#ifdef _WIN32
- { /* normalize path to POSIX forward slashes */
- size_t i;
- for (i = 0; i < len; ++i) {
- if (_clar_path[i] == '\\')
- _clar_path[i] = '/';
- }
- }
-#endif
+ if (len + strlen(path_tail) + 2 > CLAR_MAX_PATH)
+ return -1;
- if (_clar_path[len - 1] != '/') {
- _clar_path[len++] = '/';
- }
+ if (_clar_tempdir[len - 1] != '/')
+ _clar_tempdir[len++] = '/';
- strncpy(_clar_path + len, path_tail, sizeof(_clar_path) - len);
+ strncpy(_clar_tempdir + len, path_tail, sizeof(_clar_tempdir) - len);
#if defined(__MINGW32__)
- if (_mktemp(_clar_path) == NULL)
+ if (_mktemp(_clar_tempdir) == NULL)
return -1;
- if (mkdir(_clar_path, 0700) != 0)
+ if (mkdir(_clar_tempdir, 0700) != 0)
return -1;
#elif defined(_WIN32)
- if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0)
+ if (_mktemp_s(_clar_tempdir, sizeof(_clar_tempdir)) != 0)
return -1;
- if (mkdir(_clar_path, 0700) != 0)
+ if (mkdir(_clar_tempdir, 0700) != 0)
return -1;
-#elif defined(__sun) || defined(__TANDEM)
- if (mktemp(_clar_path) == NULL)
+#elif defined(__sun) || defined(__TANDEM) || defined(__hpux)
+ if (mktemp(_clar_tempdir) == NULL)
return -1;
- if (mkdir(_clar_path, 0700) != 0)
+ if (mkdir(_clar_tempdir, 0700) != 0)
return -1;
#else
- if (mkdtemp(_clar_path) == NULL)
+ if (mkdtemp(_clar_tempdir) == NULL)
return -1;
#endif
+ _clar_tempdir_len = strlen(_clar_tempdir);
return 0;
}
-static void clar_sandbox(void)
+static void clar_tempdir_init(void)
{
- if (_clar_path[0] == '\0' && build_sandbox_path() < 0)
- clar_abort("Failed to build sandbox path.\n");
+ if (_clar_tempdir[0] == '\0' && build_tempdir_path() < 0)
+ clar_abort("Failed to build tempdir path.\n");
- if (chdir(_clar_path) != 0)
- clar_abort("Failed to change into sandbox directory '%s': %s.\n",
- _clar_path, strerror(errno));
+ if (chdir(_clar_tempdir) != 0)
+ clar_abort("Failed to change into tempdir '%s': %s.\n",
+ _clar_tempdir, strerror(errno));
+
+#if !defined(CLAR_SANDBOX_TEST_NAMES) && defined(_WIN32)
+ srand(clock() ^ (unsigned int)time(NULL) ^ GetCurrentProcessId() ^ GetCurrentThreadId());
+#elif !defined(CLAR_SANDBOX_TEST_NAMES)
+ srand(clock() ^ time(NULL) ^ ((unsigned)getpid() << 16));
+#endif
+}
+
+static void append(char *dst, const char *src)
+{
+ char *d;
+ const char *s;
+
+ for (d = dst; *d; d++)
+ ;
+
+ for (s = src; *s; d++, s++)
+ if (*s == ':')
+ *d = '_';
+ else
+ *d = *s;
+
+ *d = '\0';
+}
+
+static int clar_sandbox_create(const char *suite_name, const char *test_name)
+{
+#ifndef CLAR_SANDBOX_TEST_NAMES
+ char alpha[] = "0123456789abcdef";
+ int num = rand();
+#endif
+
+ cl_assert(_clar_sandbox[0] == '\0');
+
+ /*
+ * We may want to use test names as sandbox directory names for
+ * readability, _however_ on platforms with restrictions for short
+ * file / folder names (eg, Windows), this may be too long.
+ */
+#ifdef CLAR_SANDBOX_TEST_NAMES
+ cl_assert(strlen(_clar_tempdir) + strlen(suite_name) + strlen(test_name) + 3 < CLAR_MAX_PATH);
+
+ strcpy(_clar_sandbox, _clar_tempdir);
+ _clar_sandbox[_clar_tempdir_len] = '/';
+ _clar_sandbox[_clar_tempdir_len + 1] = '\0';
+
+ append(_clar_sandbox, suite_name);
+ append(_clar_sandbox, "__");
+ append(_clar_sandbox, test_name);
+#else
+ ((void)suite_name);
+ ((void)test_name);
+ ((void)append);
+
+ cl_assert(strlen(_clar_tempdir) + 9 < CLAR_MAX_PATH);
+
+ strcpy(_clar_sandbox, _clar_tempdir);
+ _clar_sandbox[_clar_tempdir_len] = '/';
+
+ _clar_sandbox[_clar_tempdir_len + 1] = alpha[(num & 0xf0000000) >> 28];
+ _clar_sandbox[_clar_tempdir_len + 2] = alpha[(num & 0x0f000000) >> 24];
+ _clar_sandbox[_clar_tempdir_len + 3] = alpha[(num & 0x00f00000) >> 20];
+ _clar_sandbox[_clar_tempdir_len + 4] = alpha[(num & 0x000f0000) >> 16];
+ _clar_sandbox[_clar_tempdir_len + 5] = alpha[(num & 0x0000f000) >> 12];
+ _clar_sandbox[_clar_tempdir_len + 6] = alpha[(num & 0x00000f00) >> 8];
+ _clar_sandbox[_clar_tempdir_len + 7] = alpha[(num & 0x000000f0) >> 4];
+ _clar_sandbox[_clar_tempdir_len + 8] = alpha[(num & 0x0000000f) >> 0];
+ _clar_sandbox[_clar_tempdir_len + 9] = '\0';
+#endif
+
+ if (mkdir(_clar_sandbox, 0700) != 0)
+ return -1;
+
+ if (chdir(_clar_sandbox) != 0)
+ return -1;
+
+ return 0;
+}
+
+static int clar_sandbox_cleanup(void)
+{
+ cl_assert(_clar_sandbox[0] != '\0');
+
+ if (chdir(_clar_tempdir) != 0)
+ return -1;
+
+ fs_rm(_clar_sandbox);
+ _clar_sandbox[0] = '\0';
+
+ return 0;
+}
+
+const char *clar_tempdir_path(void)
+{
+ return _clar_tempdir;
}
const char *clar_sandbox_path(void)
{
- return _clar_path;
+ return _clar_sandbox;
}
diff --git a/t/unit-tests/clar/clar/summary.h b/t/unit-tests/clar/clar/summary.h
index 0d0b646fe7..7b85f162d8 100644
--- a/t/unit-tests/clar/clar/summary.h
+++ b/t/unit-tests/clar/clar/summary.h
@@ -23,10 +23,11 @@ static int clar_summary_testsuite(struct clar_summary *summary,
int idn, const char *name, time_t timestamp,
int test_count, int fail_count, int error_count)
{
- struct tm *tm = localtime(&timestamp);
+ struct tm tm;
char iso_dt[20];
- if (strftime(iso_dt, sizeof(iso_dt), "%Y-%m-%dT%H:%M:%S", tm) == 0)
+ localtime_r(&timestamp, &tm);
+ if (strftime(iso_dt, sizeof(iso_dt), "%Y-%m-%dT%H:%M:%S", &tm) == 0)
return -1;
return fprintf(summary->fp, "\t<testsuite"
diff --git a/t/unit-tests/clar/example/CMakeLists.txt b/t/unit-tests/clar/example/CMakeLists.txt
new file mode 100644
index 0000000000..b72f187523
--- /dev/null
+++ b/t/unit-tests/clar/example/CMakeLists.txt
@@ -0,0 +1,28 @@
+find_package(Python COMPONENTS Interpreter REQUIRED)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/clar.suite"
+ COMMAND "${Python_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/generate.py" --output "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPENDS main.c example.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+add_executable(example)
+set_target_properties(example PROPERTIES
+ C_STANDARD 90
+ C_STANDARD_REQUIRED ON
+ C_EXTENSIONS OFF
+)
+target_sources(example PRIVATE
+ main.c
+ example.c
+ "${CMAKE_CURRENT_BINARY_DIR}/clar.suite"
+)
+target_compile_definitions(example PRIVATE)
+target_compile_options(example PRIVATE
+ $<IF:$<CXX_COMPILER_ID:MSVC>,/W4,-Wall>
+)
+target_include_directories(example PRIVATE
+ "${CMAKE_SOURCE_DIR}"
+ "${CMAKE_CURRENT_BINARY_DIR}"
+)
+target_link_libraries(example clar)
diff --git a/t/unit-tests/clar/example/example.c b/t/unit-tests/clar/example/example.c
new file mode 100644
index 0000000000..c07d6bf68e
--- /dev/null
+++ b/t/unit-tests/clar/example/example.c
@@ -0,0 +1,6 @@
+#include "clar.h"
+
+void test_example__simple_assert(void)
+{
+ cl_assert_equal_i(1, 1);
+}
diff --git a/t/unit-tests/clar/test/main.c.sample b/t/unit-tests/clar/example/main.c
index a4d91b72fa..f8def7fa6e 100644
--- a/t/unit-tests/clar/test/main.c.sample
+++ b/t/unit-tests/clar/example/main.c
@@ -5,7 +5,7 @@
* For full terms see the included COPYING file.
*/
-#include "clar_test.h"
+#include "clar.h"
/*
* Minimal main() for clar tests.
diff --git a/t/unit-tests/clar/generate.py b/t/unit-tests/clar/generate.py
index 80996ac3e7..fd2f0ee83b 100755
--- a/t/unit-tests/clar/generate.py
+++ b/t/unit-tests/clar/generate.py
@@ -158,17 +158,24 @@ class TestSuite(object):
def find_modules(self):
modules = []
- for root, _, files in os.walk(self.path):
- module_root = root[len(self.path):]
- module_root = [c for c in module_root.split(os.sep) if c]
- tests_in_module = fnmatch.filter(files, "*.c")
+ if os.path.isfile(self.path):
+ full_path = os.path.abspath(self.path)
+ module_name = os.path.basename(self.path)
+ module_name = os.path.splitext(module_name)[0]
+ modules.append((full_path, module_name))
+ else:
+ for root, _, files in os.walk(self.path):
+ module_root = root[len(self.path):]
+ module_root = [c for c in module_root.split(os.sep) if c]
- for test_file in tests_in_module:
- full_path = os.path.join(root, test_file)
- module_name = "_".join(module_root + [test_file[:-2]]).replace("-", "_")
+ tests_in_module = fnmatch.filter(files, "*.c")
- modules.append((full_path, module_name))
+ for test_file in tests_in_module:
+ full_path = os.path.join(root, test_file)
+ module_name = "_".join(module_root + [test_file[:-2]]).replace("-", "_")
+
+ modules.append((full_path, module_name))
return modules
@@ -217,6 +224,7 @@ class TestSuite(object):
def write(self):
output = os.path.join(self.output, 'clar.suite')
+ os.makedirs(self.output, exist_ok=True)
if not self.should_generate(output):
return False
@@ -258,7 +266,11 @@ if __name__ == '__main__':
sys.exit(1)
path = args.pop() if args else '.'
+ if os.path.isfile(path) and not options.output:
+ print("Must provide --output when specifying a file")
+ sys.exit(1)
output = options.output or path
+
suite = TestSuite(path, output)
suite.load(options.force)
suite.disable(options.excluded)
diff --git a/t/unit-tests/clar/test/CMakeLists.txt b/t/unit-tests/clar/test/CMakeLists.txt
index 7f2c1dc17a..f240166439 100644
--- a/t/unit-tests/clar/test/CMakeLists.txt
+++ b/t/unit-tests/clar/test/CMakeLists.txt
@@ -2,12 +2,12 @@ find_package(Python COMPONENTS Interpreter REQUIRED)
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/clar.suite"
COMMAND "${Python_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/generate.py" --output "${CMAKE_CURRENT_BINARY_DIR}"
- DEPENDS main.c sample.c clar_test.h
+ DEPENDS main.c selftest.c
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
-add_executable(clar_test)
-set_target_properties(clar_test PROPERTIES
+add_executable(selftest)
+set_target_properties(selftest PROPERTIES
C_STANDARD 90
C_STANDARD_REQUIRED ON
C_EXTENSIONS OFF
@@ -15,25 +15,35 @@ set_target_properties(clar_test PROPERTIES
# MSVC generates all kinds of warnings. We may want to fix these in the future
# and then unconditionally treat warnings as errors.
-if(NOT MSVC)
- set_target_properties(clar_test PROPERTIES
+if (NOT MSVC)
+ set_target_properties(selftest PROPERTIES
COMPILE_WARNING_AS_ERROR ON
)
endif()
-target_sources(clar_test PRIVATE
+target_sources(selftest PRIVATE
main.c
- sample.c
+ selftest.c
"${CMAKE_CURRENT_BINARY_DIR}/clar.suite"
)
-target_compile_definitions(clar_test PRIVATE
- CLAR_FIXTURE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/"
+target_compile_definitions(selftest PRIVATE
+ CLAR_FIXTURE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/expected/"
)
-target_compile_options(clar_test PRIVATE
+target_compile_options(selftest PRIVATE
$<IF:$<CXX_COMPILER_ID:MSVC>,/W4,-Wall>
)
-target_include_directories(clar_test PRIVATE
+target_include_directories(selftest PRIVATE
"${CMAKE_SOURCE_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}"
)
-target_link_libraries(clar_test clar)
+target_link_libraries(selftest clar)
+
+add_test(NAME build_selftest
+ COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --config "$<CONFIG>" --target selftest
+)
+set_tests_properties(build_selftest PROPERTIES FIXTURES_SETUP clar_test_fixture)
+
+add_subdirectory(suites)
+
+add_test(NAME selftest COMMAND "${CMAKE_CURRENT_BINARY_DIR}/selftest" $<TARGET_FILE_DIR:combined_suite>)
+set_tests_properties(selftest PROPERTIES FIXTURES_REQUIRED clar_test_fixture)
diff --git a/t/unit-tests/clar/test/clar_test.h b/t/unit-tests/clar/test/clar_test.h
deleted file mode 100644
index 0fcaa639aa..0000000000
--- a/t/unit-tests/clar/test/clar_test.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) Vicent Marti. All rights reserved.
- *
- * This file is part of clar, distributed under the ISC license.
- * For full terms see the included COPYING file.
- */
-#ifndef __CLAR_TEST__
-#define __CLAR_TEST__
-
-/* Import the standard clar helper functions */
-#include "clar.h"
-
-/* Your custom shared includes / defines here */
-extern int global_test_counter;
-
-#endif
diff --git a/t/unit-tests/clar/test/expected/help b/t/unit-tests/clar/test/expected/help
new file mode 100644
index 0000000000..9428def2d7
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/help
@@ -0,0 +1,12 @@
+Usage: combined [options]
+
+Options:
+ -sname Run only the suite with `name` (can go to individual test name)
+ -iname Include the suite with `name`
+ -xname Exclude the suite with `name`
+ -v Increase verbosity (show suite names)
+ -q Decrease verbosity, inverse to -v
+ -Q Quit as soon as a test fails
+ -t Display results in tap format
+ -l Print suite names
+ -r[filename] Write summary file (to the optional filename)
diff --git a/t/unit-tests/clar/test/expected/quiet b/t/unit-tests/clar/test/expected/quiet
new file mode 100644
index 0000000000..280c99d8ad
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/quiet
@@ -0,0 +1,44 @@
+ 1) Failure:
+combined::1 [file:42]
+ Function call failed: -1
+
+ 2) Failure:
+combined::2 [file:42]
+ Expression is not true: 100 == 101
+
+ 3) Failure:
+combined::strings [file:42]
+ String mismatch: "mismatched" != actual ("this one fails")
+ 'mismatched' != 'expected' (at byte 0)
+
+ 4) Failure:
+combined::strings_with_length [file:42]
+ String mismatch: "exactly" != actual ("this one fails")
+ 'exa' != 'exp' (at byte 2)
+
+ 5) Failure:
+combined::int [file:42]
+ 101 != value ("extra note on failing test")
+ 101 != 100
+
+ 6) Failure:
+combined::int_fmt [file:42]
+ 022 != value
+ 0022 != 0144
+
+ 7) Failure:
+combined::bool [file:42]
+ 0 != value
+ 0 != 1
+
+ 8) Failure:
+combined::multiline_description [file:42]
+ Function call failed: -1
+ description line 1
+ description line 2
+
+ 9) Failure:
+combined::null_string [file:42]
+ String mismatch: "expected" != actual ("this one fails")
+ 'expected' != NULL
+
diff --git a/t/unit-tests/clar/test/expected/specific_test b/t/unit-tests/clar/test/expected/specific_test
new file mode 100644
index 0000000000..6c22e9f507
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/specific_test
@@ -0,0 +1,9 @@
+Loaded 1 suites:
+Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
+F
+
+ 1) Failure:
+combined::bool [file:42]
+ 0 != value
+ 0 != 1
+
diff --git a/t/unit-tests/clar/test/expected/stop_on_failure b/t/unit-tests/clar/test/expected/stop_on_failure
new file mode 100644
index 0000000000..c23610754f
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/stop_on_failure
@@ -0,0 +1,8 @@
+Loaded 1 suites:
+Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
+F
+
+ 1) Failure:
+combined::1 [file:42]
+ Function call failed: -1
+
diff --git a/t/unit-tests/clar/test/expected/suite_names b/t/unit-tests/clar/test/expected/suite_names
new file mode 100644
index 0000000000..10d1538427
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/suite_names
@@ -0,0 +1,2 @@
+Test suites (use -s<name> to run just one):
+ 0: combined
diff --git a/t/unit-tests/clar/test/expected/summary.xml b/t/unit-tests/clar/test/expected/summary.xml
new file mode 100644
index 0000000000..9a89d43a59
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/summary.xml
@@ -0,0 +1,41 @@
+<testsuites>
+ <testsuite id="0" name="selftest" hostname="localhost" timestamp="2024-09-06T10:04:08" tests="8" failures="8" errors="0">
+ <testcase name="1" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[Function call failed: -1
+(null)]]></failure>
+ </testcase>
+ <testcase name="2" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[Expression is not true: 100 == 101
+(null)]]></failure>
+ </testcase>
+ <testcase name="strings" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[String mismatch: "mismatched" != actual ("this one fails")
+'mismatched' != 'expected' (at byte 0)]]></failure>
+ </testcase>
+ <testcase name="strings_with_length" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[String mismatch: "exactly" != actual ("this one fails")
+'exa' != 'exp' (at byte 2)]]></failure>
+ </testcase>
+ <testcase name="int" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[101 != value ("extra note on failing test")
+101 != 100]]></failure>
+ </testcase>
+ <testcase name="int_fmt" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[022 != value
+0022 != 0144]]></failure>
+ </testcase>
+ <testcase name="bool" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[0 != value
+0 != 1]]></failure>
+ </testcase>
+ <testcase name="multiline_description" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[Function call failed: −1
+description line 1
+description line 2]]></failure>
+ </testcase>
+ <testcase name="null_string" classname="selftest" time="0.00">
+ <failure type="assert"><![CDATA[String mismatch: "expected" != actual ("this one fails")
+'expected' != NULL]]></failure>
+ </testcase>
+ </testsuite>
+</testsuites>
diff --git a/t/unit-tests/clar/test/expected/summary_with_filename b/t/unit-tests/clar/test/expected/summary_with_filename
new file mode 100644
index 0000000000..460160791d
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/summary_with_filename
@@ -0,0 +1,49 @@
+Loaded 1 suites:
+Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
+FFFFFFFFF
+
+ 1) Failure:
+combined::1 [file:42]
+ Function call failed: -1
+
+ 2) Failure:
+combined::2 [file:42]
+ Expression is not true: 100 == 101
+
+ 3) Failure:
+combined::strings [file:42]
+ String mismatch: "mismatched" != actual ("this one fails")
+ 'mismatched' != 'expected' (at byte 0)
+
+ 4) Failure:
+combined::strings_with_length [file:42]
+ String mismatch: "exactly" != actual ("this one fails")
+ 'exa' != 'exp' (at byte 2)
+
+ 5) Failure:
+combined::int [file:42]
+ 101 != value ("extra note on failing test")
+ 101 != 100
+
+ 6) Failure:
+combined::int_fmt [file:42]
+ 022 != value
+ 0022 != 0144
+
+ 7) Failure:
+combined::bool [file:42]
+ 0 != value
+ 0 != 1
+
+ 8) Failure:
+combined::multiline_description [file:42]
+ Function call failed: -1
+ description line 1
+ description line 2
+
+ 9) Failure:
+combined::null_string [file:42]
+ String mismatch: "expected" != actual ("this one fails")
+ 'expected' != NULL
+
+written summary file to different.xml
diff --git a/t/unit-tests/clar/test/expected/summary_without_filename b/t/unit-tests/clar/test/expected/summary_without_filename
new file mode 100644
index 0000000000..7874c1d98b
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/summary_without_filename
@@ -0,0 +1,49 @@
+Loaded 1 suites:
+Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
+FFFFFFFFF
+
+ 1) Failure:
+combined::1 [file:42]
+ Function call failed: -1
+
+ 2) Failure:
+combined::2 [file:42]
+ Expression is not true: 100 == 101
+
+ 3) Failure:
+combined::strings [file:42]
+ String mismatch: "mismatched" != actual ("this one fails")
+ 'mismatched' != 'expected' (at byte 0)
+
+ 4) Failure:
+combined::strings_with_length [file:42]
+ String mismatch: "exactly" != actual ("this one fails")
+ 'exa' != 'exp' (at byte 2)
+
+ 5) Failure:
+combined::int [file:42]
+ 101 != value ("extra note on failing test")
+ 101 != 100
+
+ 6) Failure:
+combined::int_fmt [file:42]
+ 022 != value
+ 0022 != 0144
+
+ 7) Failure:
+combined::bool [file:42]
+ 0 != value
+ 0 != 1
+
+ 8) Failure:
+combined::multiline_description [file:42]
+ Function call failed: -1
+ description line 1
+ description line 2
+
+ 9) Failure:
+combined::null_string [file:42]
+ String mismatch: "expected" != actual ("this one fails")
+ 'expected' != NULL
+
+written summary file to summary.xml
diff --git a/t/unit-tests/clar/test/expected/tap b/t/unit-tests/clar/test/expected/tap
new file mode 100644
index 0000000000..bddbd5dfe9
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/tap
@@ -0,0 +1,92 @@
+TAP version 13
+# start of suite 1: combined
+not ok 1 - combined::1
+ ---
+ reason: |
+ Function call failed: -1
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 2 - combined::2
+ ---
+ reason: |
+ Expression is not true: 100 == 101
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 3 - combined::strings
+ ---
+ reason: |
+ String mismatch: "mismatched" != actual ("this one fails")
+ 'mismatched' != 'expected' (at byte 0)
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 4 - combined::strings_with_length
+ ---
+ reason: |
+ String mismatch: "exactly" != actual ("this one fails")
+ 'exa' != 'exp' (at byte 2)
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 5 - combined::int
+ ---
+ reason: |
+ 101 != value ("extra note on failing test")
+ 101 != 100
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 6 - combined::int_fmt
+ ---
+ reason: |
+ 022 != value
+ 0022 != 0144
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 7 - combined::bool
+ ---
+ reason: |
+ 0 != value
+ 0 != 1
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 8 - combined::multiline_description
+ ---
+ reason: |
+ Function call failed: -1
+ description line 1
+ description line 2
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+not ok 9 - combined::null_string
+ ---
+ reason: |
+ String mismatch: "expected" != actual ("this one fails")
+ 'expected' != NULL
+ at:
+ file: 'file'
+ line: 42
+ function: 'func'
+ ---
+1..9
diff --git a/t/unit-tests/clar/test/expected/without_arguments b/t/unit-tests/clar/test/expected/without_arguments
new file mode 100644
index 0000000000..1111d418a0
--- /dev/null
+++ b/t/unit-tests/clar/test/expected/without_arguments
@@ -0,0 +1,48 @@
+Loaded 1 suites:
+Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
+FFFFFFFFF
+
+ 1) Failure:
+combined::1 [file:42]
+ Function call failed: -1
+
+ 2) Failure:
+combined::2 [file:42]
+ Expression is not true: 100 == 101
+
+ 3) Failure:
+combined::strings [file:42]
+ String mismatch: "mismatched" != actual ("this one fails")
+ 'mismatched' != 'expected' (at byte 0)
+
+ 4) Failure:
+combined::strings_with_length [file:42]
+ String mismatch: "exactly" != actual ("this one fails")
+ 'exa' != 'exp' (at byte 2)
+
+ 5) Failure:
+combined::int [file:42]
+ 101 != value ("extra note on failing test")
+ 101 != 100
+
+ 6) Failure:
+combined::int_fmt [file:42]
+ 022 != value
+ 0022 != 0144
+
+ 7) Failure:
+combined::bool [file:42]
+ 0 != value
+ 0 != 1
+
+ 8) Failure:
+combined::multiline_description [file:42]
+ Function call failed: -1
+ description line 1
+ description line 2
+
+ 9) Failure:
+combined::null_string [file:42]
+ String mismatch: "expected" != actual ("this one fails")
+ 'expected' != NULL
+
diff --git a/t/unit-tests/clar/test/main.c b/t/unit-tests/clar/test/main.c
index 59e56ad255..94af440643 100644
--- a/t/unit-tests/clar/test/main.c
+++ b/t/unit-tests/clar/test/main.c
@@ -1,23 +1,9 @@
-/*
- * Copyright (c) Vicent Marti. All rights reserved.
- *
- * This file is part of clar, distributed under the ISC license.
- * For full terms see the included COPYING file.
- */
+#include <stdio.h>
+#include <string.h>
-#include "clar_test.h"
+#include "selftest.h"
-/*
- * Sample main() for clar tests.
- *
- * You should write your own main routine for clar tests that does specific
- * setup and teardown as necessary for your application. The only required
- * line is the call to `clar_test(argc, argv)`, which will execute the test
- * suite. If you want to check the return value of the test application,
- * your main() should return the same value returned by clar_test().
- */
-
-int global_test_counter = 0;
+const char *selftest_suite_directory;
#ifdef _WIN32
int __cdecl main(int argc, char *argv[])
@@ -25,16 +11,15 @@ int __cdecl main(int argc, char *argv[])
int main(int argc, char *argv[])
#endif
{
- int ret;
-
- /* Your custom initialization here */
- global_test_counter = 0;
-
- /* Run the test suite */
- ret = clar_test(argc, argv);
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <selftest-suite-directory> <options>\n",
+ argv[0]);
+ exit(1);
+ }
- /* Your custom cleanup here */
- cl_assert_equal_i(8, global_test_counter);
+ selftest_suite_directory = argv[1];
+ memmove(argv + 1, argv + 2, argc - 1);
+ argc -= 1;
- return ret;
+ return clar_test(argc, argv);
}
diff --git a/t/unit-tests/clar/test/selftest.c b/t/unit-tests/clar/test/selftest.c
new file mode 100644
index 0000000000..eed83e4512
--- /dev/null
+++ b/t/unit-tests/clar/test/selftest.c
@@ -0,0 +1,370 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "selftest.h"
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+static char *read_full(HANDLE h, int is_pipe)
+{
+ char *data = NULL;
+ size_t data_size = 0;
+
+ while (1) {
+ CHAR buf[4096];
+ DWORD bytes_read;
+
+ if (!ReadFile(h, buf, sizeof(buf), &bytes_read, NULL)) {
+ if (!is_pipe)
+ cl_fail("Failed reading file handle.");
+ cl_assert_equal_i(GetLastError(), ERROR_BROKEN_PIPE);
+ break;
+ }
+ if (!bytes_read)
+ break;
+
+ data = realloc(data, data_size + bytes_read);
+ cl_assert(data);
+ memcpy(data + data_size, buf, bytes_read);
+ data_size += bytes_read;
+ }
+
+ data = realloc(data, data_size + 1);
+ cl_assert(data);
+ data[data_size] = '\0';
+
+ while (strstr(data, "\r\n")) {
+ char *ptr = strstr(data, "\r\n");
+ memmove(ptr, ptr + 1, strlen(ptr));
+ }
+
+ return data;
+}
+
+static char *read_file(const char *path)
+{
+ char *content;
+ HANDLE file;
+
+ file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ cl_assert(file != INVALID_HANDLE_VALUE);
+ content = read_full(file, 0);
+ cl_assert_equal_b(1, CloseHandle(file));
+
+ return content;
+}
+
+static char *execute(const char *suite, int expected_error_code, const char **args, size_t nargs)
+{
+ SECURITY_ATTRIBUTES security_attributes = { 0 };
+ PROCESS_INFORMATION process_info = { 0 };
+ STARTUPINFO startup_info = { 0 };
+ char binary_path[4096] = { 0 };
+ char cmdline[4096] = { 0 };
+ char *output = NULL;
+ HANDLE stdout_write;
+ HANDLE stdout_read;
+ DWORD exit_code;
+ size_t i;
+
+ snprintf(binary_path, sizeof(binary_path), "%s/%s_suite.exe",
+ selftest_suite_directory, suite);
+
+ /*
+ * Assemble command line arguments. In theory we'd have to properly
+ * quote them. In practice none of our tests actually care.
+ */
+ snprintf(cmdline, sizeof(cmdline), suite);
+ for (i = 0; i < nargs; i++) {
+ size_t cmdline_len = strlen(cmdline);
+ const char *arg = args[i];
+ cl_assert(cmdline_len + strlen(arg) < sizeof(cmdline));
+ snprintf(cmdline + cmdline_len, sizeof(cmdline) - cmdline_len,
+ " %s", arg);
+ }
+
+ /*
+ * Create a pipe that we will use to read data from the child process.
+ * The writing side needs to be inheritable such that the child can use
+ * it as stdout and stderr. The reading side should only be used by the
+ * parent.
+ */
+ security_attributes.nLength = sizeof(security_attributes);
+ security_attributes.bInheritHandle = TRUE;
+ cl_assert_equal_b(1, CreatePipe(&stdout_read, &stdout_write, &security_attributes, 0));
+ cl_assert_equal_b(1, SetHandleInformation(stdout_read, HANDLE_FLAG_INHERIT, 0));
+
+ /*
+ * Create the child process with our pipe.
+ */
+ startup_info.cb = sizeof(startup_info);
+ startup_info.hStdError = stdout_write;
+ startup_info.hStdOutput = stdout_write;
+ startup_info.dwFlags |= STARTF_USESTDHANDLES;
+ cl_assert_equal_b(1, CreateProcess(binary_path, cmdline, NULL, NULL, TRUE,
+ 0, NULL, NULL, &startup_info, &process_info));
+ cl_assert_equal_b(1, CloseHandle(stdout_write));
+
+ output = read_full(stdout_read, 1);
+ cl_assert_equal_b(1, CloseHandle(stdout_read));
+ cl_assert_equal_b(1, GetExitCodeProcess(process_info.hProcess, &exit_code));
+ cl_assert_equal_i(exit_code, expected_error_code);
+
+ return output;
+}
+
+static void assert_output(const char *suite, const char *expected_output_file, int expected_error_code, ...)
+{
+ char *expected_output = NULL;
+ char *output = NULL;
+ const char *args[16];
+ va_list ap;
+ size_t i;
+
+ va_start(ap, expected_error_code);
+ for (i = 0; ; i++) {
+ const char *arg = va_arg(ap, const char *);
+ if (!arg)
+ break;
+ cl_assert(i < sizeof(args) / sizeof(*args));
+ args[i] = arg;
+ }
+ va_end(ap);
+
+ output = execute(suite, expected_error_code, args, i);
+ expected_output = read_file(cl_fixture(expected_output_file));
+ cl_assert_equal_s(output, expected_output);
+
+ free(expected_output);
+ free(output);
+}
+
+#else
+# include <errno.h>
+# include <fcntl.h>
+# include <limits.h>
+# include <unistd.h>
+# include <sys/wait.h>
+
+static char *read_full(int fd)
+{
+ size_t data_bytes = 0;
+ char *data = NULL;
+
+ while (1) {
+ char buf[4096];
+ ssize_t n;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ cl_fail("Failed reading from child process.");
+ }
+ if (!n)
+ break;
+
+ data = realloc(data, data_bytes + n);
+ cl_assert(data);
+
+ memcpy(data + data_bytes, buf, n);
+ data_bytes += n;
+ }
+
+ data = realloc(data, data_bytes + 1);
+ cl_assert(data);
+ data[data_bytes] = '\0';
+
+ return data;
+}
+
+static char *read_file(const char *path)
+{
+ char *data;
+ int fd;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ cl_fail("Failed reading expected file.");
+
+ data = read_full(fd);
+ cl_must_pass(close(fd));
+
+ return data;
+}
+
+static char *execute(const char *suite, int expected_error_code, const char **args, size_t nargs)
+{
+ int pipe_fds[2];
+ pid_t pid;
+
+ cl_must_pass(pipe(pipe_fds));
+
+ pid = fork();
+ if (!pid) {
+ const char *final_args[17] = { NULL };
+ char binary_path[4096];
+ size_t len = 0;
+ size_t i;
+
+ cl_assert(nargs < sizeof(final_args) / sizeof(*final_args));
+ final_args[0] = suite;
+ for (i = 0; i < nargs; i++)
+ final_args[i + 1] = args[i];
+
+ if (dup2(pipe_fds[1], STDOUT_FILENO) < 0 ||
+ dup2(pipe_fds[1], STDERR_FILENO) < 0 ||
+ close(0) < 0 ||
+ close(pipe_fds[0]) < 0 ||
+ close(pipe_fds[1]) < 0)
+ exit(1);
+
+ cl_assert(len + strlen(selftest_suite_directory) < sizeof(binary_path));
+ strcpy(binary_path, selftest_suite_directory);
+ len += strlen(selftest_suite_directory);
+
+ cl_assert(len + 1 < sizeof(binary_path));
+ binary_path[len] = '/';
+ len += 1;
+
+ cl_assert(len + strlen(suite) < sizeof(binary_path));
+ strcpy(binary_path + len, suite);
+ len += strlen(suite);
+
+ cl_assert(len + strlen("_suite") < sizeof(binary_path));
+ strcpy(binary_path + len, "_suite");
+ len += strlen("_suite");
+
+ binary_path[len] = '\0';
+
+ execv(binary_path, (char **) final_args);
+ exit(1);
+ } else if (pid > 0) {
+ pid_t waited_pid;
+ char *output;
+ int stat;
+
+ cl_must_pass(close(pipe_fds[1]));
+
+ output = read_full(pipe_fds[0]);
+
+ waited_pid = waitpid(pid, &stat, 0);
+ cl_assert_equal_i(pid, waited_pid);
+ cl_assert(WIFEXITED(stat));
+ cl_assert_equal_i(WEXITSTATUS(stat), expected_error_code);
+
+ return output;
+ } else {
+ cl_fail("Fork failed.");
+ }
+
+ return NULL;
+}
+
+static void assert_output(const char *suite, const char *expected_output_file, int expected_error_code, ...)
+{
+ char *expected_output, *output;
+ const char *args[16];
+ va_list ap;
+ size_t i;
+
+ va_start(ap, expected_error_code);
+ for (i = 0; ; i++) {
+ cl_assert(i < sizeof(args) / sizeof(*args));
+ args[i] = va_arg(ap, const char *);
+ if (!args[i])
+ break;
+ }
+ va_end(ap);
+
+ output = execute(suite, expected_error_code, args, i);
+ expected_output = read_file(cl_fixture(expected_output_file));
+ cl_assert_equal_s(output, expected_output);
+
+ free(expected_output);
+ free(output);
+}
+#endif
+
+void test_selftest__help(void)
+{
+ cl_invoke(assert_output("combined", "help", 1, "-h", NULL));
+}
+
+void test_selftest__without_arguments(void)
+{
+ cl_invoke(assert_output("combined", "without_arguments", 9, NULL));
+}
+
+void test_selftest__specific_test(void)
+{
+ cl_invoke(assert_output("combined", "specific_test", 1, "-scombined::bool", NULL));
+}
+
+void test_selftest__stop_on_failure(void)
+{
+ cl_invoke(assert_output("combined", "stop_on_failure", 1, "-Q", NULL));
+}
+
+void test_selftest__quiet(void)
+{
+ cl_invoke(assert_output("combined", "quiet", 9, "-q", NULL));
+}
+
+void test_selftest__tap(void)
+{
+ cl_invoke(assert_output("combined", "tap", 9, "-t", NULL));
+}
+
+void test_selftest__suite_names(void)
+{
+ cl_invoke(assert_output("combined", "suite_names", 0, "-l", NULL));
+}
+
+void test_selftest__summary_without_filename(void)
+{
+ struct stat st;
+ cl_invoke(assert_output("combined", "summary_without_filename", 9, "-r", NULL));
+ /* The summary contains timestamps, so we cannot verify its contents. */
+ cl_must_pass(stat("summary.xml", &st));
+}
+
+void test_selftest__summary_with_filename(void)
+{
+ struct stat st;
+ cl_invoke(assert_output("combined", "summary_with_filename", 9, "-rdifferent.xml", NULL));
+ /* The summary contains timestamps, so we cannot verify its contents. */
+ cl_must_pass(stat("different.xml", &st));
+}
+
+void test_selftest__pointer_equal(void)
+{
+ const char *args[] = {
+ "-spointer::equal",
+ "-t"
+ };
+ char *output = execute("pointer", 0, args, 2);
+ cl_assert_equal_s(output,
+ "TAP version 13\n"
+ "# start of suite 1: pointer\n"
+ "ok 1 - pointer::equal\n"
+ "1..1\n"
+ );
+ free(output);
+}
+
+void test_selftest__pointer_unequal(void)
+{
+ const char *args[] = {
+ "-spointer::unequal",
+ };
+ char *output = execute("pointer", 1, args, 1);
+ cl_assert(output);
+ cl_assert(strstr(output, "Pointer mismatch: "));
+ free(output);
+}
diff --git a/t/unit-tests/clar/test/selftest.h b/t/unit-tests/clar/test/selftest.h
new file mode 100644
index 0000000000..c24e0c5af4
--- /dev/null
+++ b/t/unit-tests/clar/test/selftest.h
@@ -0,0 +1,3 @@
+#include "clar.h"
+
+extern const char *selftest_suite_directory;
diff --git a/t/unit-tests/clar/test/suites/CMakeLists.txt b/t/unit-tests/clar/test/suites/CMakeLists.txt
new file mode 100644
index 0000000000..fa8ab9416a
--- /dev/null
+++ b/t/unit-tests/clar/test/suites/CMakeLists.txt
@@ -0,0 +1,53 @@
+list(APPEND suites
+ "combined"
+ "pointer"
+)
+
+foreach(suite IN LISTS suites)
+ add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${suite}/clar.suite"
+ COMMAND "${Python_EXECUTABLE}"
+ "${CMAKE_SOURCE_DIR}/generate.py"
+ "${CMAKE_CURRENT_SOURCE_DIR}/${suite}.c"
+ --output "${CMAKE_CURRENT_BINARY_DIR}/${suite}"
+ DEPENDS ${suite}.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ )
+
+ add_executable(${suite}_suite)
+ set_target_properties(${suite}_suite PROPERTIES
+ C_STANDARD 90
+ C_STANDARD_REQUIRED ON
+ C_EXTENSIONS OFF
+ )
+
+ # MSVC generates all kinds of warnings. We may want to fix these in the future
+ # and then unconditionally treat warnings as errors.
+ if(NOT MSVC)
+ set_target_properties(${suite}_suite PROPERTIES
+ COMPILE_WARNING_AS_ERROR ON
+ )
+ endif()
+
+ target_sources(${suite}_suite PRIVATE
+ main.c
+ ${suite}.c
+ "${CMAKE_CURRENT_BINARY_DIR}/${suite}/clar.suite"
+ )
+ target_compile_definitions(${suite}_suite PRIVATE
+ CLAR_FIXTURE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/"
+ CLAR_SELFTEST
+ )
+ target_compile_options(${suite}_suite PRIVATE
+ $<IF:$<CXX_COMPILER_ID:MSVC>,/W4,-Wall>
+ )
+ target_include_directories(${suite}_suite PRIVATE
+ "${CMAKE_SOURCE_DIR}"
+ "${CMAKE_CURRENT_BINARY_DIR}/${suite}"
+ )
+ target_link_libraries(${suite}_suite clar)
+
+ add_test(NAME build_${suite}_suite
+ COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --config "$<CONFIG>" --target selftest
+ )
+ set_tests_properties(build_${suite}_suite PROPERTIES FIXTURES_SETUP clar_test_fixture)
+endforeach()
diff --git a/t/unit-tests/clar/test/sample.c b/t/unit-tests/clar/test/suites/combined.c
index faa1209262..e8b41c98c3 100644
--- a/t/unit-tests/clar/test/sample.c
+++ b/t/unit-tests/clar/test/suites/combined.c
@@ -1,6 +1,7 @@
-#include "clar_test.h"
#include <sys/stat.h>
+#include "clar.h"
+
static int file_size(const char *filename)
{
struct stat st;
@@ -10,19 +11,14 @@ static int file_size(const char *filename)
return -1;
}
-void test_sample__initialize(void)
-{
- global_test_counter++;
-}
-
-void test_sample__cleanup(void)
+void test_combined__cleanup(void)
{
cl_fixture_cleanup("test");
cl_assert(file_size("test/file") == -1);
}
-void test_sample__1(void)
+void test_combined__1(void)
{
cl_assert(1);
cl_must_pass(0); /* 0 == success */
@@ -30,7 +26,7 @@ void test_sample__1(void)
cl_must_pass(-1); /* demonstrate a failing call */
}
-void test_sample__2(void)
+void test_combined__2(void)
{
cl_fixture_sandbox("test");
@@ -39,7 +35,7 @@ void test_sample__2(void)
cl_assert(100 == 101);
}
-void test_sample__strings(void)
+void test_combined__strings(void)
{
const char *actual = "expected";
cl_assert_equal_s("expected", actual);
@@ -47,7 +43,7 @@ void test_sample__strings(void)
cl_assert_equal_s_("mismatched", actual, "this one fails");
}
-void test_sample__strings_with_length(void)
+void test_combined__strings_with_length(void)
{
const char *actual = "expected";
cl_assert_equal_strn("expected_", actual, 8);
@@ -56,29 +52,34 @@ void test_sample__strings_with_length(void)
cl_assert_equal_strn_("exactly", actual, 3, "this one fails");
}
-void test_sample__int(void)
+void test_combined__int(void)
{
int value = 100;
cl_assert_equal_i(100, value);
cl_assert_equal_i_(101, value, "extra note on failing test");
}
-void test_sample__int_fmt(void)
+void test_combined__int_fmt(void)
{
int value = 100;
cl_assert_equal_i_fmt(022, value, "%04o");
}
-void test_sample__bool(void)
+void test_combined__bool(void)
{
int value = 100;
cl_assert_equal_b(1, value); /* test equality as booleans */
cl_assert_equal_b(0, value);
}
-void test_sample__ptr(void)
+void test_combined__multiline_description(void)
{
- const char *actual = "expected";
- cl_assert_equal_p(actual, actual); /* pointers to same object */
- cl_assert_equal_p(&actual, actual);
+ cl_must_pass_(-1, "description line 1\ndescription line 2");
+}
+
+void test_combined__null_string(void)
+{
+ const char *actual = NULL;
+ cl_assert_equal_s(actual, actual);
+ cl_assert_equal_s_("expected", actual, "this one fails");
}
diff --git a/t/unit-tests/clar/test/suites/main.c b/t/unit-tests/clar/test/suites/main.c
new file mode 100644
index 0000000000..3ab581d390
--- /dev/null
+++ b/t/unit-tests/clar/test/suites/main.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) Vicent Marti. All rights reserved.
+ *
+ * This file is part of clar, distributed under the ISC license.
+ * For full terms see the included COPYING file.
+ */
+
+#include "clar.h"
+
+/*
+ * Selftest main() for clar tests.
+ *
+ * You should write your own main routine for clar tests that does specific
+ * setup and teardown as necessary for your application. The only required
+ * line is the call to `clar_test(argc, argv)`, which will execute the test
+ * suite. If you want to check the return value of the test application,
+ * your main() should return the same value returned by clar_test().
+ */
+
+#ifdef _WIN32
+int __cdecl main(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ return clar_test(argc, argv);
+}
diff --git a/t/unit-tests/clar/test/suites/pointer.c b/t/unit-tests/clar/test/suites/pointer.c
new file mode 100644
index 0000000000..20535b159e
--- /dev/null
+++ b/t/unit-tests/clar/test/suites/pointer.c
@@ -0,0 +1,13 @@
+#include "clar.h"
+
+void test_pointer__equal(void)
+{
+ void *p1 = (void *)0x1;
+ cl_assert_equal_p(p1, p1);
+}
+
+void test_pointer__unequal(void)
+{
+ void *p1 = (void *)0x1, *p2 = (void *)0x2;
+ cl_assert_equal_p(p1, p2);
+}
diff --git a/t/unit-tests/clar/test/resources/test/file b/t/unit-tests/clar/test/suites/resources/test/file
index 220f4aa98a..220f4aa98a 100644
--- a/t/unit-tests/clar/test/resources/test/file
+++ b/t/unit-tests/clar/test/suites/resources/test/file
diff --git a/t/unit-tests/lib-reftable.c b/t/unit-tests/lib-reftable.c
index 8a69612266..fdb5b11a20 100644
--- a/t/unit-tests/lib-reftable.c
+++ b/t/unit-tests/lib-reftable.c
@@ -1,12 +1,14 @@
-#define DISABLE_SIGN_COMPARE_WARNINGS
-
+#include "unit-test.h"
#include "lib-reftable.h"
-#include "test-lib.h"
+#include "hex.h"
+#include "parse-options.h"
#include "reftable/constants.h"
#include "reftable/writer.h"
#include "strbuf.h"
+#include "string-list.h"
+#include "strvec.h"
-void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id)
+void cl_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id)
{
memset(p, (uint8_t)i, hash_size(id));
}
@@ -22,17 +24,17 @@ static int strbuf_writer_flush(void *arg UNUSED)
return 0;
}
-struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf,
+struct reftable_writer *cl_reftable_strbuf_writer(struct reftable_buf *buf,
struct reftable_write_options *opts)
{
struct reftable_writer *writer;
int ret = reftable_writer_new(&writer, &strbuf_writer_write, &strbuf_writer_flush,
buf, opts);
- check(!ret);
+ cl_assert(!ret);
return writer;
}
-void t_reftable_write_to_buf(struct reftable_buf *buf,
+void cl_reftable_write_to_buf(struct reftable_buf *buf,
struct reftable_ref_record *refs,
size_t nrefs,
struct reftable_log_record *logs,
@@ -64,35 +66,36 @@ void t_reftable_write_to_buf(struct reftable_buf *buf,
min = ui;
}
- writer = t_reftable_strbuf_writer(buf, &opts);
- reftable_writer_set_limits(writer, min, max);
+ writer = cl_reftable_strbuf_writer(buf, &opts);
+ ret = reftable_writer_set_limits(writer, min, max);
+ cl_assert(!ret);
if (nrefs) {
ret = reftable_writer_add_refs(writer, refs, nrefs);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
}
if (nlogs) {
ret = reftable_writer_add_logs(writer, logs, nlogs);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
}
ret = reftable_writer_close(writer);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
stats = reftable_writer_stats(writer);
- for (size_t i = 0; i < stats->ref_stats.blocks; i++) {
+ for (size_t i = 0; i < (size_t)stats->ref_stats.blocks; i++) {
size_t off = i * (opts.block_size ? opts.block_size
: DEFAULT_BLOCK_SIZE);
if (!off)
off = header_size(opts.hash_id == REFTABLE_HASH_SHA256 ? 2 : 1);
- check_char(buf->buf[off], ==, 'r');
+ cl_assert(buf->buf[off] == 'r');
}
if (nrefs)
- check_int(stats->ref_stats.blocks, >, 0);
+ cl_assert(stats->ref_stats.blocks > 0);
if (nlogs)
- check_int(stats->log_stats.blocks, >, 0);
+ cl_assert(stats->log_stats.blocks > 0);
reftable_writer_free(writer);
}
diff --git a/t/unit-tests/lib-reftable.h b/t/unit-tests/lib-reftable.h
index e4c360fa7e..d7e6d3136f 100644
--- a/t/unit-tests/lib-reftable.h
+++ b/t/unit-tests/lib-reftable.h
@@ -1,21 +1,20 @@
-#ifndef LIB_REFTABLE_H
-#define LIB_REFTABLE_H
-
+#include "git-compat-util.h"
+#include "clar/clar.h"
+#include "clar-decls.h"
#include "git-compat-util.h"
#include "reftable/reftable-writer.h"
+#include "strbuf.h"
struct reftable_buf;
-void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id);
+void cl_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id);
-struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf,
+struct reftable_writer *cl_reftable_strbuf_writer(struct reftable_buf *buf,
struct reftable_write_options *opts);
-void t_reftable_write_to_buf(struct reftable_buf *buf,
+void cl_reftable_write_to_buf(struct reftable_buf *buf,
struct reftable_ref_record *refs,
size_t nrecords,
struct reftable_log_record *logs,
size_t nlogs,
struct reftable_write_options *opts);
-
-#endif
diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c
deleted file mode 100644
index c9e751e49e..0000000000
--- a/t/unit-tests/t-reftable-basics.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-Copyright 2020 Google LLC
-
-Use of this source code is governed by a BSD-style
-license that can be found in the LICENSE file or at
-https://developers.google.com/open-source/licenses/bsd
-*/
-
-#include "test-lib.h"
-#include "reftable/basics.h"
-
-struct integer_needle_lesseq_args {
- int needle;
- int *haystack;
-};
-
-static int integer_needle_lesseq(size_t i, void *_args)
-{
- struct integer_needle_lesseq_args *args = _args;
- return args->needle <= args->haystack[i];
-}
-
-static void *realloc_stub(void *p UNUSED, size_t size UNUSED)
-{
- return NULL;
-}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- if_test ("binary search with binsearch works") {
- int haystack[] = { 2, 4, 6, 8, 10 };
- struct {
- int needle;
- size_t expected_idx;
- } testcases[] = {
- {-9000, 0},
- {-1, 0},
- {0, 0},
- {2, 0},
- {3, 1},
- {4, 1},
- {7, 3},
- {9, 4},
- {10, 4},
- {11, 5},
- {9000, 5},
- };
-
- for (size_t i = 0; i < ARRAY_SIZE(testcases); i++) {
- struct integer_needle_lesseq_args args = {
- .haystack = haystack,
- .needle = testcases[i].needle,
- };
- size_t idx;
-
- idx = binsearch(ARRAY_SIZE(haystack),
- &integer_needle_lesseq, &args);
- check_int(idx, ==, testcases[i].expected_idx);
- }
- }
-
- if_test ("names_length returns size of a NULL-terminated string array") {
- const char *a[] = { "a", "b", NULL };
- check_int(names_length(a), ==, 2);
- }
-
- if_test ("names_equal compares NULL-terminated string arrays") {
- const char *a[] = { "a", "b", "c", NULL };
- const char *b[] = { "a", "b", "d", NULL };
- const char *c[] = { "a", "b", NULL };
-
- check(names_equal(a, a));
- check(!names_equal(a, b));
- check(!names_equal(a, c));
- }
-
- if_test ("parse_names works for basic input") {
- char in1[] = "line\n";
- char in2[] = "a\nb\nc";
- char **out = parse_names(in1, strlen(in1));
- check(out != NULL);
- check_str(out[0], "line");
- check(!out[1]);
- free_names(out);
-
- out = parse_names(in2, strlen(in2));
- check(out != NULL);
- check_str(out[0], "a");
- check_str(out[1], "b");
- check_str(out[2], "c");
- check(!out[3]);
- free_names(out);
- }
-
- if_test ("parse_names drops empty string") {
- char in[] = "a\n\nb\n";
- char **out = parse_names(in, strlen(in));
- check(out != NULL);
- check_str(out[0], "a");
- /* simply '\n' should be dropped as empty string */
- check_str(out[1], "b");
- check(!out[2]);
- free_names(out);
- }
-
- if_test ("common_prefix_size works") {
- struct reftable_buf a = REFTABLE_BUF_INIT;
- struct reftable_buf b = REFTABLE_BUF_INIT;
- struct {
- const char *a, *b;
- int want;
- } cases[] = {
- {"abcdef", "abc", 3},
- { "abc", "ab", 2 },
- { "", "abc", 0 },
- { "abc", "abd", 2 },
- { "abc", "pqr", 0 },
- };
-
- for (size_t i = 0; i < ARRAY_SIZE(cases); i++) {
- check(!reftable_buf_addstr(&a, cases[i].a));
- check(!reftable_buf_addstr(&b, cases[i].b));
- check_uint(common_prefix_size(&a, &b), ==, cases[i].want);
- reftable_buf_reset(&a);
- reftable_buf_reset(&b);
- }
- reftable_buf_release(&a);
- reftable_buf_release(&b);
- }
-
- if_test ("reftable_put_be64 and reftable_get_be64 work") {
- uint64_t in = 0x1122334455667788;
- uint8_t dest[8];
- uint64_t out;
- reftable_put_be64(dest, in);
- out = reftable_get_be64(dest);
- check_int(in, ==, out);
- }
-
- if_test ("reftable_put_be32 and reftable_get_be32 work") {
- uint32_t in = 0x11223344;
- uint8_t dest[4];
- uint32_t out;
- reftable_put_be32(dest, in);
- out = reftable_get_be32(dest);
- check_int(in, ==, out);
- }
-
- if_test ("reftable_put_be24 and reftable_get_be24 work") {
- uint32_t in = 0x112233;
- uint8_t dest[3];
- uint32_t out;
- reftable_put_be24(dest, in);
- out = reftable_get_be24(dest);
- check_int(in, ==, out);
- }
-
- if_test ("put_be16 and get_be16 work") {
- uint32_t in = 0xfef1;
- uint8_t dest[3];
- uint32_t out;
- reftable_put_be16(dest, in);
- out = reftable_get_be16(dest);
- check_int(in, ==, out);
- }
-
- if_test ("REFTABLE_ALLOC_GROW works") {
- int *arr = NULL, *old_arr;
- size_t alloc = 0, old_alloc;
-
- check(!REFTABLE_ALLOC_GROW(arr, 1, alloc));
- check(arr != NULL);
- check_uint(alloc, >=, 1);
- arr[0] = 42;
-
- old_alloc = alloc;
- old_arr = arr;
- reftable_set_alloc(NULL, realloc_stub, NULL);
- check(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc));
- check(arr == old_arr);
- check_uint(alloc, ==, old_alloc);
-
- old_alloc = alloc;
- reftable_set_alloc(NULL, NULL, NULL);
- check(!REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc));
- check(arr != NULL);
- check_uint(alloc, >, old_alloc);
- arr[alloc - 1] = 42;
-
- reftable_free(arr);
- }
-
- if_test ("REFTABLE_ALLOC_GROW_OR_NULL works") {
- int *arr = NULL;
- size_t alloc = 0, old_alloc;
-
- REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc);
- check(arr != NULL);
- check_uint(alloc, >=, 1);
- arr[0] = 42;
-
- old_alloc = alloc;
- REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
- check(arr != NULL);
- check_uint(alloc, >, old_alloc);
- arr[alloc - 1] = 42;
-
- old_alloc = alloc;
- reftable_set_alloc(NULL, realloc_stub, NULL);
- REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
- check(arr == NULL);
- check_uint(alloc, ==, 0);
- reftable_set_alloc(NULL, NULL, NULL);
-
- reftable_free(arr);
- }
-
- return test_done();
-}
diff --git a/t/unit-tests/u-dir.c b/t/unit-tests/u-dir.c
new file mode 100644
index 0000000000..2d0adaa39e
--- /dev/null
+++ b/t/unit-tests/u-dir.c
@@ -0,0 +1,47 @@
+#include "unit-test.h"
+#include "dir.h"
+
+#define TEST_WITHIN_DEPTH(path, depth, max_depth, expect) do { \
+ int actual = within_depth(path, strlen(path), \
+ depth, max_depth); \
+ if (actual != expect) \
+ cl_failf("path '%s' with depth '%d' and max-depth '%d': expected %d, got %d", \
+ path, depth, max_depth, expect, actual); \
+ } while (0)
+
+void test_dir__within_depth(void)
+{
+ /* depth = 0; max_depth = 0 */
+ TEST_WITHIN_DEPTH("", 0, 0, 1);
+ TEST_WITHIN_DEPTH("file", 0, 0, 1);
+ TEST_WITHIN_DEPTH("a", 0, 0, 1);
+ TEST_WITHIN_DEPTH("a/file", 0, 0, 0);
+ TEST_WITHIN_DEPTH("a/b", 0, 0, 0);
+ TEST_WITHIN_DEPTH("a/b/file", 0, 0, 0);
+
+ /* depth = 0; max_depth = 1 */
+ TEST_WITHIN_DEPTH("", 0, 1, 1);
+ TEST_WITHIN_DEPTH("file", 0, 1, 1);
+ TEST_WITHIN_DEPTH("a", 0, 1, 1);
+ TEST_WITHIN_DEPTH("a/file", 0, 1, 1);
+ TEST_WITHIN_DEPTH("a/b", 0, 1, 1);
+ TEST_WITHIN_DEPTH("a/b/file", 0, 1, 0);
+
+ /* depth = 1; max_depth = 1 */
+ TEST_WITHIN_DEPTH("", 1, 1, 1);
+ TEST_WITHIN_DEPTH("file", 1, 1, 1);
+ TEST_WITHIN_DEPTH("a", 1, 1, 1);
+ TEST_WITHIN_DEPTH("a/file", 1, 1, 0);
+ TEST_WITHIN_DEPTH("a/b", 1, 1, 0);
+ TEST_WITHIN_DEPTH("a/b/file", 1, 1, 0);
+
+ /* depth = 1; max_depth = 0 */
+ TEST_WITHIN_DEPTH("", 1, 0, 0);
+ TEST_WITHIN_DEPTH("file", 1, 0, 0);
+ TEST_WITHIN_DEPTH("a", 1, 0, 0);
+ TEST_WITHIN_DEPTH("a/file", 1, 0, 0);
+ TEST_WITHIN_DEPTH("a/b", 1, 0, 0);
+ TEST_WITHIN_DEPTH("a/b/file", 1, 0, 0);
+
+
+}
diff --git a/t/unit-tests/u-prio-queue.c b/t/unit-tests/u-prio-queue.c
index 145e689c9c..63e58114ae 100644
--- a/t/unit-tests/u-prio-queue.c
+++ b/t/unit-tests/u-prio-queue.c
@@ -13,6 +13,7 @@ static int intcmp(const void *va, const void *vb, void *data UNUSED)
#define STACK -3
#define GET -4
#define REVERSE -5
+#define REPLACE -6
static int show(int *v)
{
@@ -51,6 +52,15 @@ static void test_prio_queue(int *input, size_t input_size,
case REVERSE:
prio_queue_reverse(&pq);
break;
+ case REPLACE:
+ peek = prio_queue_peek(&pq);
+ cl_assert(i + 1 < input_size);
+ cl_assert(input[i + 1] >= 0);
+ cl_assert(j < result_size);
+ cl_assert_equal_i(result[j], show(peek));
+ j++;
+ prio_queue_replace(&pq, &input[++i]);
+ break;
default:
prio_queue_put(&pq, &input[i]);
break;
@@ -81,6 +91,13 @@ void test_prio_queue__empty(void)
((int []){ 1, 2, MISSING, 1, 2, MISSING }));
}
+void test_prio_queue__replace(void)
+{
+ TEST_INPUT(((int []){ REPLACE, 6, 2, 4, REPLACE, 5, 7, GET,
+ REPLACE, 1, DUMP }),
+ ((int []){ MISSING, 2, 4, 5, 1, 6, 7 }));
+}
+
void test_prio_queue__stack(void)
{
TEST_INPUT(((int []){ STACK, 8, 1, 5, 4, 6, 2, 3, DUMP }),
@@ -92,3 +109,9 @@ void test_prio_queue__reverse_stack(void)
TEST_INPUT(((int []){ STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP }),
((int []){ 1, 2, 3, 4, 5, 6 }));
}
+
+void test_prio_queue__replace_stack(void)
+{
+ TEST_INPUT(((int []){ STACK, 8, 1, 5, REPLACE, 4, 6, 2, 3, DUMP }),
+ ((int []){ 5, 3, 2, 6, 4, 1, 8 }));
+}
diff --git a/t/unit-tests/u-reftable-basics.c b/t/unit-tests/u-reftable-basics.c
new file mode 100644
index 0000000000..73566ed0eb
--- /dev/null
+++ b/t/unit-tests/u-reftable-basics.c
@@ -0,0 +1,243 @@
+/*
+Copyright 2020 Google LLC
+
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file or at
+https://developers.google.com/open-source/licenses/bsd
+*/
+
+#include "unit-test.h"
+#include "lib-reftable.h"
+#include "reftable/basics.h"
+#include "reftable/reftable-error.h"
+
+struct integer_needle_lesseq_args {
+ int needle;
+ int *haystack;
+};
+
+static int integer_needle_lesseq(size_t i, void *_args)
+{
+ struct integer_needle_lesseq_args *args = _args;
+ return args->needle <= args->haystack[i];
+}
+
+static void *realloc_stub(void *p UNUSED, size_t size UNUSED)
+{
+ return NULL;
+}
+
+void test_reftable_basics__binsearch(void)
+{
+ int haystack[] = { 2, 4, 6, 8, 10 };
+ struct {
+ int needle;
+ size_t expected_idx;
+ } testcases[] = {
+ {-9000, 0},
+ {-1, 0},
+ {0, 0},
+ {2, 0},
+ {3, 1},
+ {4, 1},
+ {7, 3},
+ {9, 4},
+ {10, 4},
+ {11, 5},
+ {9000, 5},
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(testcases); i++) {
+ struct integer_needle_lesseq_args args = {
+ .haystack = haystack,
+ .needle = testcases[i].needle,
+ };
+ size_t idx;
+
+ idx = binsearch(ARRAY_SIZE(haystack),
+ &integer_needle_lesseq, &args);
+ cl_assert_equal_i(idx, testcases[i].expected_idx);
+ }
+}
+
+void test_reftable_basics__names_length(void)
+{
+ const char *a[] = { "a", "b", NULL };
+ cl_assert_equal_i(names_length(a), 2);
+}
+
+void test_reftable_basics__names_equal(void)
+{
+ const char *a[] = { "a", "b", "c", NULL };
+ const char *b[] = { "a", "b", "d", NULL };
+ const char *c[] = { "a", "b", NULL };
+
+ cl_assert(names_equal(a, a));
+ cl_assert(!names_equal(a, b));
+ cl_assert(!names_equal(a, c));
+}
+
+void test_reftable_basics__parse_names(void)
+{
+ char in1[] = "line\n";
+ char in2[] = "a\nb\nc\n";
+ char **out = NULL;
+ int err = parse_names(in1, strlen(in1), &out);
+ cl_assert(err == 0);
+ cl_assert(out != NULL);
+ cl_assert_equal_s(out[0], "line");
+ cl_assert(!out[1]);
+ free_names(out);
+
+ out = NULL;
+ err = parse_names(in2, strlen(in2), &out);
+ cl_assert(err == 0);
+ cl_assert(out != NULL);
+ cl_assert_equal_s(out[0], "a");
+ cl_assert_equal_s(out[1], "b");
+ cl_assert_equal_s(out[2], "c");
+ cl_assert(!out[3]);
+ free_names(out);
+}
+
+void test_reftable_basics__parse_names_missing_newline(void)
+{
+ char in1[] = "line\nline2";
+ char **out = NULL;
+ int err = parse_names(in1, strlen(in1), &out);
+ cl_assert(err == REFTABLE_FORMAT_ERROR);
+ cl_assert(out == NULL);
+}
+
+void test_reftable_basics__parse_names_drop_empty_string(void)
+{
+ char in[] = "a\n\nb\n";
+ char **out = NULL;
+ int err = parse_names(in, strlen(in), &out);
+ cl_assert(err == 0);
+ cl_assert(out != NULL);
+ cl_assert_equal_s(out[0], "a");
+ /* simply '\n' should be dropped as empty string */
+ cl_assert_equal_s(out[1], "b");
+ cl_assert(out[2] == NULL);
+ free_names(out);
+}
+
+void test_reftable_basics__common_prefix_size(void)
+{
+ struct reftable_buf a = REFTABLE_BUF_INIT;
+ struct reftable_buf b = REFTABLE_BUF_INIT;
+ struct {
+ const char *a, *b;
+ int want;
+ } cases[] = {
+ {"abcdef", "abc", 3},
+ { "abc", "ab", 2 },
+ { "", "abc", 0 },
+ { "abc", "abd", 2 },
+ { "abc", "pqr", 0 },
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(cases); i++) {
+ cl_assert_equal_i(reftable_buf_addstr(&a, cases[i].a), 0);
+ cl_assert_equal_i(reftable_buf_addstr(&b, cases[i].b), 0);
+ cl_assert_equal_i(common_prefix_size(&a, &b), cases[i].want);
+ reftable_buf_reset(&a);
+ reftable_buf_reset(&b);
+ }
+ reftable_buf_release(&a);
+ reftable_buf_release(&b);
+}
+
+void test_reftable_basics__put_get_be64(void)
+{
+ uint64_t in = 0x1122334455667788;
+ uint8_t dest[8];
+ uint64_t out;
+ reftable_put_be64(dest, in);
+ out = reftable_get_be64(dest);
+ cl_assert(in == out);
+}
+
+void test_reftable_basics__put_get_be32(void)
+{
+ uint32_t in = 0x11223344;
+ uint8_t dest[4];
+ uint32_t out;
+ reftable_put_be32(dest, in);
+ out = reftable_get_be32(dest);
+ cl_assert_equal_i(in, out);
+}
+
+void test_reftable_basics__put_get_be24(void)
+{
+ uint32_t in = 0x112233;
+ uint8_t dest[3];
+ uint32_t out;
+ reftable_put_be24(dest, in);
+ out = reftable_get_be24(dest);
+ cl_assert_equal_i(in, out);
+}
+
+void test_reftable_basics__put_get_be16(void)
+{
+ uint32_t in = 0xfef1;
+ uint8_t dest[3];
+ uint32_t out;
+ reftable_put_be16(dest, in);
+ out = reftable_get_be16(dest);
+ cl_assert_equal_i(in, out);
+}
+
+void test_reftable_basics__alloc_grow(void)
+{
+ int *arr = NULL, *old_arr;
+ size_t alloc = 0, old_alloc;
+
+ cl_assert_equal_i(REFTABLE_ALLOC_GROW(arr, 1, alloc), 0);
+ cl_assert(arr != NULL);
+ cl_assert(alloc >= 1);
+ arr[0] = 42;
+
+ old_alloc = alloc;
+ old_arr = arr;
+ reftable_set_alloc(NULL, realloc_stub, NULL);
+ cl_assert(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc));
+ cl_assert(arr == old_arr);
+ cl_assert_equal_i(alloc, old_alloc);
+
+ old_alloc = alloc;
+ reftable_set_alloc(NULL, NULL, NULL);
+ cl_assert_equal_i(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc), 0);
+ cl_assert(arr != NULL);
+ cl_assert(alloc > old_alloc);
+ arr[alloc - 1] = 42;
+
+ reftable_free(arr);
+}
+
+void test_reftable_basics__alloc_grow_or_null(void)
+{
+ int *arr = NULL;
+ size_t alloc = 0, old_alloc;
+
+ REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc);
+ cl_assert(arr != NULL);
+ cl_assert(alloc >= 1);
+ arr[0] = 42;
+
+ old_alloc = alloc;
+ REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
+ cl_assert(arr != NULL);
+ cl_assert(alloc > old_alloc);
+ arr[alloc - 1] = 42;
+
+ old_alloc = alloc;
+ reftable_set_alloc(NULL, realloc_stub, NULL);
+ REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
+ cl_assert(arr == NULL);
+ cl_assert_equal_i(alloc, 0);
+ reftable_set_alloc(NULL, NULL, NULL);
+
+ reftable_free(arr);
+}
diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/u-reftable-block.c
index 52f1dae1c9..f4bded7d26 100644
--- a/t/unit-tests/t-reftable-block.c
+++ b/t/unit-tests/u-reftable-block.c
@@ -6,14 +6,15 @@ license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
-#include "test-lib.h"
+#include "unit-test.h"
+#include "lib-reftable.h"
#include "reftable/block.h"
#include "reftable/blocksource.h"
#include "reftable/constants.h"
#include "reftable/reftable-error.h"
#include "strbuf.h"
-static void t_ref_block_read_write(void)
+void test_reftable_block__read_write(void)
{
const int header_off = 21; /* random */
struct reftable_record recs[30];
@@ -34,17 +35,18 @@ static void t_ref_block_read_write(void)
struct reftable_buf block_data = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block_data.buf, block_size);
- check(block_data.buf != NULL);
+ cl_assert(block_data.buf != NULL);
block_data.len = block_size;
- ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_REF, (uint8_t *) block_data.buf, block_size,
+ ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_REF,
+ (uint8_t *) block_data.buf, block_size,
header_off, hash_size(REFTABLE_HASH_SHA1));
- check(!ret);
+ cl_assert(!ret);
rec.u.ref.refname = (char *) "";
rec.u.ref.value_type = REFTABLE_REF_DELETION;
ret = block_writer_add(&bw, &rec);
- check_int(ret, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(ret, REFTABLE_API_ERROR);
for (i = 0; i < N; i++) {
rec.u.ref.refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i);
@@ -55,11 +57,11 @@ static void t_ref_block_read_write(void)
ret = block_writer_add(&bw, &rec);
rec.u.ref.refname = NULL;
rec.u.ref.value_type = REFTABLE_REF_DELETION;
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
}
ret = block_writer_finish(&bw);
- check_int(ret, >, 0);
+ cl_assert(ret > 0);
block_writer_release(&bw);
@@ -71,32 +73,32 @@ static void t_ref_block_read_write(void)
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
- check_int(ret, >=, 0);
+ cl_assert(ret >= 0);
if (ret > 0) {
- check_int(i, ==, N);
+ cl_assert_equal_i(i, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
for (i = 0; i < N; i++) {
reftable_record_key(&recs[i], &want);
ret = block_iter_seek_key(&it, &want);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
ret = block_iter_next(&it, &rec);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
want.len--;
ret = block_iter_seek_key(&it, &want);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
ret = block_iter_next(&it, &rec);
- check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(ret, 0);
+ cl_assert_equal_i(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
reftable_block_release(&block);
@@ -108,7 +110,7 @@ static void t_ref_block_read_write(void)
reftable_record_release(&recs[i]);
}
-static void t_log_block_read_write(void)
+void test_reftable_block__log_read_write(void)
{
const int header_off = 21;
struct reftable_record recs[30];
@@ -129,12 +131,12 @@ static void t_log_block_read_write(void)
struct reftable_buf block_data = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block_data.buf, block_size);
- check(block_data.buf != NULL);
+ cl_assert(block_data.buf != NULL);
block_data.len = block_size;
ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_LOG, (uint8_t *) block_data.buf, block_size,
header_off, hash_size(REFTABLE_HASH_SHA1));
- check(!ret);
+ cl_assert(!ret);
for (i = 0; i < N; i++) {
rec.u.log.refname = xstrfmt("branch%02"PRIuMAX , (uintmax_t)i);
@@ -145,11 +147,11 @@ static void t_log_block_read_write(void)
ret = block_writer_add(&bw, &rec);
rec.u.log.refname = NULL;
rec.u.log.value_type = REFTABLE_LOG_DELETION;
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
}
ret = block_writer_finish(&bw);
- check_int(ret, >, 0);
+ cl_assert(ret > 0);
block_writer_release(&bw);
@@ -161,33 +163,33 @@ static void t_log_block_read_write(void)
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
- check_int(ret, >=, 0);
+ cl_assert(ret >= 0);
if (ret > 0) {
- check_int(i, ==, N);
+ cl_assert_equal_i(i, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
for (i = 0; i < N; i++) {
reftable_buf_reset(&want);
- check(!reftable_buf_addstr(&want, recs[i].u.log.refname));
+ cl_assert(reftable_buf_addstr(&want, recs[i].u.log.refname) == 0);
ret = block_iter_seek_key(&it, &want);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
ret = block_iter_next(&it, &rec);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
want.len--;
ret = block_iter_seek_key(&it, &want);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
ret = block_iter_next(&it, &rec);
- check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(ret, 0);
+ cl_assert_equal_i(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
reftable_block_release(&block);
@@ -199,7 +201,7 @@ static void t_log_block_read_write(void)
reftable_record_release(&recs[i]);
}
-static void t_obj_block_read_write(void)
+void test_reftable_block__obj_read_write(void)
{
const int header_off = 21;
struct reftable_record recs[30];
@@ -220,12 +222,12 @@ static void t_obj_block_read_write(void)
struct reftable_buf block_data = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block_data.buf, block_size);
- check(block_data.buf != NULL);
+ cl_assert(block_data.buf != NULL);
block_data.len = block_size;
ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_OBJ, (uint8_t *) block_data.buf, block_size,
header_off, hash_size(REFTABLE_HASH_SHA1));
- check(!ret);
+ cl_assert(!ret);
for (i = 0; i < N; i++) {
uint8_t bytes[] = { i, i + 1, i + 2, i + 3, i + 5 }, *allocated;
@@ -238,11 +240,11 @@ static void t_obj_block_read_write(void)
ret = block_writer_add(&bw, &rec);
rec.u.obj.hash_prefix = NULL;
rec.u.obj.hash_prefix_len = 0;
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
}
ret = block_writer_finish(&bw);
- check_int(ret, >, 0);
+ cl_assert(ret > 0);
block_writer_release(&bw);
@@ -254,24 +256,24 @@ static void t_obj_block_read_write(void)
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
- check_int(ret, >=, 0);
+ cl_assert(ret >= 0);
if (ret > 0) {
- check_int(i, ==, N);
+ cl_assert_equal_i(i, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
for (i = 0; i < N; i++) {
reftable_record_key(&recs[i], &want);
ret = block_iter_seek_key(&it, &want);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
ret = block_iter_next(&it, &rec);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
reftable_block_release(&block);
@@ -283,7 +285,7 @@ static void t_obj_block_read_write(void)
reftable_record_release(&recs[i]);
}
-static void t_index_block_read_write(void)
+void test_reftable_block__ref_read_write(void)
{
const int header_off = 21;
struct reftable_record recs[30];
@@ -305,12 +307,12 @@ static void t_index_block_read_write(void)
struct reftable_buf block_data = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block_data.buf, block_size);
- check(block_data.buf != NULL);
+ cl_assert(block_data.buf != NULL);
block_data.len = block_size;
ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_INDEX, (uint8_t *) block_data.buf, block_size,
header_off, hash_size(REFTABLE_HASH_SHA1));
- check(!ret);
+ cl_assert(!ret);
for (i = 0; i < N; i++) {
char buf[128];
@@ -319,15 +321,15 @@ static void t_index_block_read_write(void)
reftable_buf_init(&recs[i].u.idx.last_key);
recs[i].type = REFTABLE_BLOCK_TYPE_INDEX;
- check(!reftable_buf_addstr(&recs[i].u.idx.last_key, buf));
+ cl_assert(!reftable_buf_addstr(&recs[i].u.idx.last_key, buf));
recs[i].u.idx.offset = i;
ret = block_writer_add(&bw, &recs[i]);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
}
ret = block_writer_finish(&bw);
- check_int(ret, >, 0);
+ cl_assert(ret > 0);
block_writer_release(&bw);
@@ -339,32 +341,32 @@ static void t_index_block_read_write(void)
for (i = 0; ; i++) {
ret = block_iter_next(&it, &rec);
- check_int(ret, >=, 0);
+ cl_assert(ret >= 0);
if (ret > 0) {
- check_int(i, ==, N);
+ cl_assert_equal_i(i, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
for (i = 0; i < N; i++) {
reftable_record_key(&recs[i], &want);
ret = block_iter_seek_key(&it, &want);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
ret = block_iter_next(&it, &rec);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
- check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
want.len--;
ret = block_iter_seek_key(&it, &want);
- check_int(ret, ==, 0);
+ cl_assert_equal_i(ret, 0);
ret = block_iter_next(&it, &rec);
- check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(ret, 0);
+ cl_assert_equal_i(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1), 1);
}
reftable_block_release(&block);
@@ -376,7 +378,7 @@ static void t_index_block_read_write(void)
reftable_record_release(&recs[i]);
}
-static void t_block_iterator(void)
+void test_reftable_block__iterator(void)
{
struct reftable_block_source source = { 0 };
struct block_writer writer = {
@@ -391,11 +393,12 @@ static void t_block_iterator(void)
data.len = 1024;
REFTABLE_CALLOC_ARRAY(data.buf, data.len);
- check(data.buf != NULL);
+ cl_assert(data.buf != NULL);
- err = block_writer_init(&writer, REFTABLE_BLOCK_TYPE_REF, (uint8_t *) data.buf, data.len,
+ err = block_writer_init(&writer, REFTABLE_BLOCK_TYPE_REF,
+ (uint8_t *) data.buf, data.len,
0, hash_size(REFTABLE_HASH_SHA1));
- check(!err);
+ cl_assert(!err);
for (size_t i = 0; i < ARRAY_SIZE(expected_refs); i++) {
expected_refs[i] = (struct reftable_record) {
@@ -408,42 +411,42 @@ static void t_block_iterator(void)
memset(expected_refs[i].u.ref.value.val1, i, REFTABLE_HASH_SIZE_SHA1);
err = block_writer_add(&writer, &expected_refs[i]);
- check_int(err, ==, 0);
+ cl_assert_equal_i(err, 0);
}
err = block_writer_finish(&writer);
- check_int(err, >, 0);
+ cl_assert(err > 0);
block_source_from_buf(&source, &data);
reftable_block_init(&block, &source, 0, 0, data.len,
REFTABLE_HASH_SIZE_SHA1, REFTABLE_BLOCK_TYPE_REF);
err = reftable_block_init_iterator(&block, &it);
- check_int(err, ==, 0);
+ cl_assert_equal_i(err, 0);
for (size_t i = 0; ; i++) {
err = reftable_iterator_next_ref(&it, &ref);
if (err > 0) {
- check_int(i, ==, ARRAY_SIZE(expected_refs));
+ cl_assert_equal_i(i, ARRAY_SIZE(expected_refs));
break;
}
- check_int(err, ==, 0);
+ cl_assert_equal_i(err, 0);
- check(reftable_ref_record_equal(&ref, &expected_refs[i].u.ref,
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_ref_record_equal(&ref,
+ &expected_refs[i].u.ref, REFTABLE_HASH_SIZE_SHA1));
}
err = reftable_iterator_seek_ref(&it, "refs/heads/does-not-exist");
- check_int(err, ==, 0);
+ cl_assert_equal_i(err, 0);
err = reftable_iterator_next_ref(&it, &ref);
- check_int(err, ==, 1);
+ cl_assert_equal_i(err, 1);
err = reftable_iterator_seek_ref(&it, "refs/heads/branch-13");
- check_int(err, ==, 0);
+ cl_assert_equal_i(err, 0);
err = reftable_iterator_next_ref(&it, &ref);
- check_int(err, ==, 0);
- check(reftable_ref_record_equal(&ref, &expected_refs[13].u.ref,
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(err, 0);
+ cl_assert(reftable_ref_record_equal(&ref,
+ &expected_refs[13].u.ref,REFTABLE_HASH_SIZE_SHA1));
for (size_t i = 0; i < ARRAY_SIZE(expected_refs); i++)
reftable_free(expected_refs[i].u.ref.refname);
@@ -453,14 +456,3 @@ static void t_block_iterator(void)
block_writer_release(&writer);
reftable_buf_release(&data);
}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_index_block_read_write(), "read-write operations on index blocks work");
- TEST(t_log_block_read_write(), "read-write operations on log blocks work");
- TEST(t_obj_block_read_write(), "read-write operations on obj blocks work");
- TEST(t_ref_block_read_write(), "read-write operations on ref blocks work");
- TEST(t_block_iterator(), "block iterator works");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/u-reftable-merged.c
index 18c3251a56..54cb7fc2a7 100644
--- a/t/unit-tests/t-reftable-merged.c
+++ b/t/unit-tests/u-reftable-merged.c
@@ -6,7 +6,7 @@ license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
-#include "test-lib.h"
+#include "unit-test.h"
#include "lib-reftable.h"
#include "reftable/blocksource.h"
#include "reftable/constants.h"
@@ -29,21 +29,21 @@ merged_table_from_records(struct reftable_ref_record **refs,
int err;
REFTABLE_CALLOC_ARRAY(*tables, n);
- check(*tables != NULL);
+ cl_assert(*tables != NULL);
REFTABLE_CALLOC_ARRAY(*source, n);
- check(*source != NULL);
+ cl_assert(*source != NULL);
for (size_t i = 0; i < n; i++) {
- t_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts);
+ cl_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts);
block_source_from_buf(&(*source)[i], &buf[i]);
err = reftable_table_new(&(*tables)[i], &(*source)[i],
"name");
- check(!err);
+ cl_assert(!err);
}
err = reftable_merged_table_new(&mt, *tables, n, REFTABLE_HASH_SHA1);
- check(!err);
+ cl_assert(!err);
return mt;
}
@@ -54,7 +54,7 @@ static void tables_destroy(struct reftable_table **tables, const size_t n)
reftable_free(tables);
}
-static void t_merged_single_record(void)
+void test_reftable_merged__single_record(void)
{
struct reftable_ref_record r1[] = { {
.refname = (char *) "b",
@@ -85,13 +85,14 @@ static void t_merged_single_record(void)
int err;
err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_REF);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, "a");
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_next_ref(&it, &ref);
- check(!err);
- check(reftable_ref_record_equal(&r2[0], &ref, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(!err);
+ cl_assert(reftable_ref_record_equal(&r2[0], &ref,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
tables_destroy(tables, 3);
@@ -101,7 +102,7 @@ static void t_merged_single_record(void)
reftable_free(bs);
}
-static void t_merged_refs(void)
+void test_reftable_merged__refs(void)
{
struct reftable_ref_record r1[] = {
{
@@ -165,12 +166,12 @@ static void t_merged_refs(void)
size_t i;
err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_REF);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, "a");
- check(!err);
- check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1);
- check_int(reftable_merged_table_min_update_index(mt), ==, 1);
- check_int(reftable_merged_table_max_update_index(mt), ==, 3);
+ cl_assert(err == 0);
+ cl_assert_equal_i(reftable_merged_table_hash_id(mt), REFTABLE_HASH_SHA1);
+ cl_assert_equal_i(reftable_merged_table_min_update_index(mt), 1);
+ cl_assert_equal_i(reftable_merged_table_max_update_index(mt), 3);
while (len < 100) { /* cap loops/recursion. */
struct reftable_ref_record ref = { 0 };
@@ -178,15 +179,15 @@ static void t_merged_refs(void)
if (err > 0)
break;
- check(!REFTABLE_ALLOC_GROW(out, len + 1, cap));
+ cl_assert(REFTABLE_ALLOC_GROW(out, len + 1, cap) == 0);
out[len++] = ref;
}
reftable_iterator_destroy(&it);
- check_int(ARRAY_SIZE(want), ==, len);
+ cl_assert_equal_i(ARRAY_SIZE(want), len);
for (i = 0; i < len; i++)
- check(reftable_ref_record_equal(want[i], &out[i],
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_ref_record_equal(want[i], &out[i],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
for (i = 0; i < len; i++)
reftable_ref_record_release(&out[i]);
reftable_free(out);
@@ -198,7 +199,7 @@ static void t_merged_refs(void)
reftable_free(bs);
}
-static void t_merged_seek_multiple_times(void)
+void test_reftable_merged__seek_multiple_times(void)
{
struct reftable_ref_record r1[] = {
{
@@ -248,20 +249,17 @@ static void t_merged_seek_multiple_times(void)
for (size_t i = 0; i < 5; i++) {
int err = reftable_iterator_seek_ref(&it, "c");
- check(!err);
+ cl_assert(!err);
- err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- err = reftable_ref_record_equal(&rec, &r1[1], REFTABLE_HASH_SIZE_SHA1);
- check(err == 1);
+ cl_assert(reftable_iterator_next_ref(&it, &rec) == 0);
+ cl_assert_equal_i(reftable_ref_record_equal(&rec, &r1[1],
+ REFTABLE_HASH_SIZE_SHA1), 1);
- err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- err = reftable_ref_record_equal(&rec, &r2[1], REFTABLE_HASH_SIZE_SHA1);
- check(err == 1);
+ cl_assert(reftable_iterator_next_ref(&it, &rec) == 0);
+ cl_assert_equal_i(reftable_ref_record_equal(&rec, &r2[1],
+ REFTABLE_HASH_SIZE_SHA1), 1);
- err = reftable_iterator_next_ref(&it, &rec);
- check(err > 0);
+ cl_assert(reftable_iterator_next_ref(&it, &rec) > 0);
}
for (size_t i = 0; i < ARRAY_SIZE(bufs); i++)
@@ -273,7 +271,7 @@ static void t_merged_seek_multiple_times(void)
reftable_free(sources);
}
-static void t_merged_seek_multiple_times_without_draining(void)
+void test_reftable_merged__seek_multiple_times_no_drain(void)
{
struct reftable_ref_record r1[] = {
{
@@ -317,24 +315,19 @@ static void t_merged_seek_multiple_times_without_draining(void)
struct reftable_ref_record rec = { 0 };
struct reftable_iterator it = { 0 };
struct reftable_merged_table *mt;
- int err;
mt = merged_table_from_records(refs, &sources, &tables, sizes, bufs, 2);
merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_REF);
- err = reftable_iterator_seek_ref(&it, "b");
- check(!err);
- err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- err = reftable_ref_record_equal(&rec, &r2[0], REFTABLE_HASH_SIZE_SHA1);
- check(err == 1);
+ cl_assert(reftable_iterator_seek_ref(&it, "b") == 0);
+ cl_assert(reftable_iterator_next_ref(&it, &rec) == 0);
+ cl_assert_equal_i(reftable_ref_record_equal(&rec, &r2[0],
+ REFTABLE_HASH_SIZE_SHA1), 1);
- err = reftable_iterator_seek_ref(&it, "a");
- check(!err);
- err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- err = reftable_ref_record_equal(&rec, &r1[0], REFTABLE_HASH_SIZE_SHA1);
- check(err == 1);
+ cl_assert(reftable_iterator_seek_ref(&it, "a") == 0);
+ cl_assert(reftable_iterator_next_ref(&it, &rec) == 0);
+ cl_assert_equal_i(reftable_ref_record_equal(&rec, &r1[0],
+ REFTABLE_HASH_SIZE_SHA1), 1);
for (size_t i = 0; i < ARRAY_SIZE(bufs); i++)
reftable_buf_release(&bufs[i]);
@@ -359,25 +352,25 @@ merged_table_from_log_records(struct reftable_log_record **logs,
int err;
REFTABLE_CALLOC_ARRAY(*tables, n);
- check(*tables != NULL);
+ cl_assert(*tables != NULL);
REFTABLE_CALLOC_ARRAY(*source, n);
- check(*source != NULL);
+ cl_assert(*source != NULL);
for (size_t i = 0; i < n; i++) {
- t_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts);
+ cl_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts);
block_source_from_buf(&(*source)[i], &buf[i]);
err = reftable_table_new(&(*tables)[i], &(*source)[i],
"name");
- check(!err);
+ cl_assert(!err);
}
err = reftable_merged_table_new(&mt, *tables, n, REFTABLE_HASH_SHA1);
- check(!err);
+ cl_assert(!err);
return mt;
}
-static void t_merged_logs(void)
+void test_reftable_merged__logs(void)
{
struct reftable_log_record r1[] = {
{
@@ -439,19 +432,19 @@ static void t_merged_logs(void)
struct reftable_merged_table *mt = merged_table_from_log_records(
logs, &bs, &tables, sizes, bufs, 3);
struct reftable_iterator it = { 0 };
- int err;
struct reftable_log_record *out = NULL;
size_t len = 0;
size_t cap = 0;
size_t i;
+ int err;
err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_LOG);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_log(&it, "a");
- check(!err);
- check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1);
- check_int(reftable_merged_table_min_update_index(mt), ==, 1);
- check_int(reftable_merged_table_max_update_index(mt), ==, 3);
+ cl_assert(!err);
+ cl_assert_equal_i(reftable_merged_table_hash_id(mt), REFTABLE_HASH_SHA1);
+ cl_assert_equal_i(reftable_merged_table_min_update_index(mt), 1);
+ cl_assert_equal_i(reftable_merged_table_max_update_index(mt), 3);
while (len < 100) { /* cap loops/recursion. */
struct reftable_log_record log = { 0 };
@@ -459,24 +452,24 @@ static void t_merged_logs(void)
if (err > 0)
break;
- check(!REFTABLE_ALLOC_GROW(out, len + 1, cap));
+ cl_assert(REFTABLE_ALLOC_GROW(out, len + 1, cap) == 0);
out[len++] = log;
}
reftable_iterator_destroy(&it);
- check_int(ARRAY_SIZE(want), ==, len);
+ cl_assert_equal_i(ARRAY_SIZE(want), len);
for (i = 0; i < len; i++)
- check(reftable_log_record_equal(want[i], &out[i],
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_log_record_equal(want[i], &out[i],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_LOG);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_log_at(&it, "a", 2);
- check(!err);
+ cl_assert(!err);
reftable_log_record_release(&out[0]);
- err = reftable_iterator_next_log(&it, &out[0]);
- check(!err);
- check(reftable_log_record_equal(&out[0], &r3[0], REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_iterator_next_log(&it, &out[0]) == 0);
+ cl_assert(reftable_log_record_equal(&out[0], &r3[0],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_iterator_destroy(&it);
for (i = 0; i < len; i++)
@@ -490,11 +483,11 @@ static void t_merged_logs(void)
reftable_free(bs);
}
-static void t_default_write_opts(void)
+void test_reftable_merged__default_write_opts(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record rec = {
.refname = (char *) "master",
.update_index = 1,
@@ -507,40 +500,25 @@ static void t_default_write_opts(void)
reftable_writer_set_limits(w, 1, 1);
- err = reftable_writer_add_ref(w, &rec);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &rec), 0);
- err = reftable_writer_close(w);
- check(!err);
+ cl_assert_equal_i(reftable_writer_close(w), 0);
reftable_writer_free(w);
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "filename");
- check(!err);
+ cl_assert(!err);
hash_id = reftable_table_hash_id(table);
- check_int(hash_id, ==, REFTABLE_HASH_SHA1);
+ cl_assert_equal_i(hash_id, REFTABLE_HASH_SHA1);
err = reftable_merged_table_new(&merged, &table, 1, REFTABLE_HASH_SHA256);
- check_int(err, ==, REFTABLE_FORMAT_ERROR);
+ cl_assert_equal_i(err, REFTABLE_FORMAT_ERROR);
err = reftable_merged_table_new(&merged, &table, 1, REFTABLE_HASH_SHA1);
- check(!err);
+ cl_assert(!err);
reftable_table_decref(table);
reftable_merged_table_free(merged);
reftable_buf_release(&buf);
}
-
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_default_write_opts(), "merged table with default write opts");
- TEST(t_merged_logs(), "merged table with multiple log updates for same ref");
- TEST(t_merged_refs(), "merged table with multiple updates to same ref");
- TEST(t_merged_seek_multiple_times(), "merged table can seek multiple times");
- TEST(t_merged_seek_multiple_times_without_draining(), "merged table can seek multiple times without draining");
- TEST(t_merged_single_record(), "ref occurring in only one record can be fetched");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-reftable-pq.c b/t/unit-tests/u-reftable-pq.c
index fb5a4eb187..f8a28f6e07 100644
--- a/t/unit-tests/t-reftable-pq.c
+++ b/t/unit-tests/u-reftable-pq.c
@@ -6,7 +6,8 @@ license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
-#include "test-lib.h"
+#include "unit-test.h"
+#include "lib-reftable.h"
#include "reftable/constants.h"
#include "reftable/pq.h"
#include "strbuf.h"
@@ -15,18 +16,18 @@ static void merged_iter_pqueue_check(const struct merged_iter_pqueue *pq)
{
for (size_t i = 1; i < pq->len; i++) {
size_t parent = (i - 1) / 2;
- check(pq_less(&pq->heap[parent], &pq->heap[i]));
+ cl_assert(pq_less(&pq->heap[parent], &pq->heap[i]) != 0);
}
}
static int pq_entry_equal(struct pq_entry *a, struct pq_entry *b)
{
int cmp;
- check(!reftable_record_cmp(a->rec, b->rec, &cmp));
+ cl_assert_equal_i(reftable_record_cmp(a->rec, b->rec, &cmp), 0);
return !cmp && (a->index == b->index);
}
-static void t_pq_record(void)
+void test_reftable_pq__record(void)
{
struct merged_iter_pqueue pq = { 0 };
struct reftable_record recs[54];
@@ -34,7 +35,8 @@ static void t_pq_record(void)
char *last = NULL;
for (i = 0; i < N; i++) {
- check(!reftable_record_init(&recs[i], REFTABLE_BLOCK_TYPE_REF));
+ cl_assert(!reftable_record_init(&recs[i],
+ REFTABLE_BLOCK_TYPE_REF));
recs[i].u.ref.refname = xstrfmt("%02"PRIuMAX, (uintmax_t)i);
}
@@ -53,13 +55,13 @@ static void t_pq_record(void)
struct pq_entry top = merged_iter_pqueue_top(pq);
struct pq_entry e;
- check(!merged_iter_pqueue_remove(&pq, &e));
+ cl_assert_equal_i(merged_iter_pqueue_remove(&pq, &e), 0);
merged_iter_pqueue_check(&pq);
- check(pq_entry_equal(&top, &e));
- check(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF);
+ cl_assert(pq_entry_equal(&top, &e));
+ cl_assert(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF);
if (last)
- check_int(strcmp(last, e.rec->u.ref.refname), <, 0);
+ cl_assert(strcmp(last, e.rec->u.ref.refname) < 0);
last = e.rec->u.ref.refname;
}
@@ -68,7 +70,7 @@ static void t_pq_record(void)
merged_iter_pqueue_release(&pq);
}
-static void t_pq_index(void)
+void test_reftable_pq__index(void)
{
struct merged_iter_pqueue pq = { 0 };
struct reftable_record recs[13];
@@ -76,7 +78,8 @@ static void t_pq_index(void)
size_t N = ARRAY_SIZE(recs), i;
for (i = 0; i < N; i++) {
- check(!reftable_record_init(&recs[i], REFTABLE_BLOCK_TYPE_REF));
+ cl_assert(!reftable_record_init(&recs[i],
+ REFTABLE_BLOCK_TYPE_REF));
recs[i].u.ref.refname = (char *) "refs/heads/master";
}
@@ -96,28 +99,29 @@ static void t_pq_index(void)
struct pq_entry top = merged_iter_pqueue_top(pq);
struct pq_entry e;
- check(!merged_iter_pqueue_remove(&pq, &e));
+ cl_assert_equal_i(merged_iter_pqueue_remove(&pq, &e), 0);
merged_iter_pqueue_check(&pq);
- check(pq_entry_equal(&top, &e));
- check(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF);
- check_int(e.index, ==, i);
+ cl_assert(pq_entry_equal(&top, &e));
+ cl_assert(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF);
+ cl_assert_equal_i(e.index, i);
if (last)
- check_str(last, e.rec->u.ref.refname);
+ cl_assert_equal_s(last, e.rec->u.ref.refname);
last = e.rec->u.ref.refname;
}
merged_iter_pqueue_release(&pq);
}
-static void t_merged_iter_pqueue_top(void)
+void test_reftable_pq__merged_iter_pqueue_top(void)
{
struct merged_iter_pqueue pq = { 0 };
struct reftable_record recs[13];
size_t N = ARRAY_SIZE(recs), i;
for (i = 0; i < N; i++) {
- check(!reftable_record_init(&recs[i], REFTABLE_BLOCK_TYPE_REF));
+ cl_assert(!reftable_record_init(&recs[i],
+ REFTABLE_BLOCK_TYPE_REF));
recs[i].u.ref.refname = (char *) "refs/heads/master";
}
@@ -137,25 +141,16 @@ static void t_merged_iter_pqueue_top(void)
struct pq_entry top = merged_iter_pqueue_top(pq);
struct pq_entry e;
- check(!merged_iter_pqueue_remove(&pq, &e));
+ cl_assert_equal_i(merged_iter_pqueue_remove(&pq, &e), 0);
merged_iter_pqueue_check(&pq);
- check(pq_entry_equal(&top, &e));
- check(reftable_record_equal(top.rec, &recs[i], REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(pq_entry_equal(&top, &e) != 0);
+ cl_assert(reftable_record_equal(top.rec, &recs[i], REFTABLE_HASH_SIZE_SHA1) != 0);
for (size_t j = 0; i < pq.len; j++) {
- check(pq_less(&top, &pq.heap[j]));
- check_int(top.index, >, j);
+ cl_assert(pq_less(&top, &pq.heap[j]) != 0);
+ cl_assert(top.index > j);
}
}
merged_iter_pqueue_release(&pq);
}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_pq_record(), "pq works with record-based comparison");
- TEST(t_pq_index(), "pq works with index-based comparison");
- TEST(t_merged_iter_pqueue_top(), "merged_iter_pqueue_top works");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/u-reftable-readwrite.c
index 4c49129439..4d8c4be5f1 100644
--- a/t/unit-tests/t-reftable-readwrite.c
+++ b/t/unit-tests/u-reftable-readwrite.c
@@ -8,7 +8,7 @@ https://developers.google.com/open-source/licenses/bsd
#define DISABLE_SIGN_COMPARE_WARNINGS
-#include "test-lib.h"
+#include "unit-test.h"
#include "lib-reftable.h"
#include "reftable/basics.h"
#include "reftable/blocksource.h"
@@ -19,24 +19,24 @@ https://developers.google.com/open-source/licenses/bsd
static const int update_index = 5;
-static void t_buffer(void)
+void test_reftable_readwrite__buffer(void)
{
struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
struct reftable_block_data out = { 0 };
int n;
uint8_t in[] = "hello";
- check(!reftable_buf_add(&buf, in, sizeof(in)));
+ cl_assert_equal_i(reftable_buf_add(&buf, in, sizeof(in)), 0);
block_source_from_buf(&source, &buf);
- check_int(block_source_size(&source), ==, 6);
+ cl_assert_equal_i(block_source_size(&source), 6);
n = block_source_read_data(&source, &out, 0, sizeof(in));
- check_int(n, ==, sizeof(in));
- check(!memcmp(in, out.data, n));
+ cl_assert_equal_i(n, sizeof(in));
+ cl_assert(!memcmp(in, out.data, n));
block_source_release_data(&out);
n = block_source_read_data(&source, &out, 1, 2);
- check_int(n, ==, 2);
- check(!memcmp(out.data, "el", 2));
+ cl_assert_equal_i(n, 2);
+ cl_assert(!memcmp(out.data, "el", 2));
block_source_release_data(&out);
block_source_close(&source);
@@ -55,41 +55,41 @@ static void write_table(char ***names, struct reftable_buf *buf, int N,
int i;
REFTABLE_CALLOC_ARRAY(*names, N + 1);
- check(*names != NULL);
+ cl_assert(*names != NULL);
REFTABLE_CALLOC_ARRAY(refs, N);
- check(refs != NULL);
+ cl_assert(refs != NULL);
REFTABLE_CALLOC_ARRAY(logs, N);
- check(logs != NULL);
+ cl_assert(logs != NULL);
for (i = 0; i < N; i++) {
refs[i].refname = (*names)[i] = xstrfmt("refs/heads/branch%02d", i);
refs[i].update_index = update_index;
refs[i].value_type = REFTABLE_REF_VAL1;
- t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(refs[i].value.val1, i,
+ REFTABLE_HASH_SHA1);
}
for (i = 0; i < N; i++) {
logs[i].refname = (*names)[i];
logs[i].update_index = update_index;
logs[i].value_type = REFTABLE_LOG_UPDATE;
- t_reftable_set_hash(logs[i].value.update.new_hash, i,
- REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(logs[i].value.update.new_hash, i,
+ REFTABLE_HASH_SHA1);
logs[i].value.update.message = (char *) "message";
}
- t_reftable_write_to_buf(buf, refs, N, logs, N, &opts);
+ cl_reftable_write_to_buf(buf, refs, N, logs, N, &opts);
reftable_free(refs);
reftable_free(logs);
}
-static void t_log_buffer_size(void)
+void test_reftable_readwrite__log_buffer_size(void)
{
struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_write_options opts = {
.block_size = 4096,
};
- int err;
int i;
struct reftable_log_record
log = { .refname = (char *) "refs/heads/master",
@@ -102,7 +102,8 @@ static void t_log_buffer_size(void)
.time = 0x5e430672,
.message = (char *) "commit: 9\n",
} } };
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
+ &opts);
/* This tests buffer extension for log compression. Must use a random
hash, to ensure that the compressed part is larger than the original.
@@ -112,22 +113,19 @@ static void t_log_buffer_size(void)
log.value.update.new_hash[i] = (uint8_t)(git_rand(0) % 256);
}
reftable_writer_set_limits(w, update_index, update_index);
- err = reftable_writer_add_log(w, &log);
- check(!err);
- err = reftable_writer_close(w);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_log(w, &log), 0);
+ cl_assert_equal_i(reftable_writer_close(w), 0);
reftable_writer_free(w);
reftable_buf_release(&buf);
}
-static void t_log_overflow(void)
+void test_reftable_readwrite__log_overflow(void)
{
struct reftable_buf buf = REFTABLE_BUF_INIT;
char msg[256] = { 0 };
struct reftable_write_options opts = {
.block_size = ARRAY_SIZE(msg),
};
- int err;
struct reftable_log_record log = {
.refname = (char *) "refs/heads/master",
.update_index = update_index,
@@ -144,21 +142,22 @@ static void t_log_overflow(void)
},
},
};
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
+ &opts);
memset(msg, 'x', sizeof(msg) - 1);
reftable_writer_set_limits(w, update_index, update_index);
- err = reftable_writer_add_log(w, &log);
- check_int(err, ==, REFTABLE_ENTRY_TOO_BIG_ERROR);
+ cl_assert_equal_i(reftable_writer_add_log(w, &log), REFTABLE_ENTRY_TOO_BIG_ERROR);
reftable_writer_free(w);
reftable_buf_release(&buf);
}
-static void t_log_write_limits(void)
+void test_reftable_readwrite__log_write_limits(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
+ &opts);
struct reftable_log_record log = {
.refname = (char *)"refs/head/master",
.update_index = 0,
@@ -174,29 +173,25 @@ static void t_log_write_limits(void)
},
},
};
- int err;
reftable_writer_set_limits(w, 1, 1);
/* write with update_index (0) below set limits (1, 1) */
- err = reftable_writer_add_log(w, &log);
- check_int(err, ==, 0);
+ cl_assert_equal_i(reftable_writer_add_log(w, &log), 0);
/* write with update_index (1) in the set limits (1, 1) */
log.update_index = 1;
- err = reftable_writer_add_log(w, &log);
- check_int(err, ==, 0);
+ cl_assert_equal_i(reftable_writer_add_log(w, &log), 0);
/* write with update_index (3) above set limits (1, 1) */
log.update_index = 3;
- err = reftable_writer_add_log(w, &log);
- check_int(err, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(reftable_writer_add_log(w, &log), REFTABLE_API_ERROR);
reftable_writer_free(w);
reftable_buf_release(&buf);
}
-static void t_log_write_read(void)
+void test_reftable_readwrite__log_write_read(void)
{
struct reftable_write_options opts = {
.block_size = 256,
@@ -207,13 +202,14 @@ static void t_log_write_read(void)
struct reftable_table *table;
struct reftable_block_source source = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
const struct reftable_stats *stats = NULL;
- int N = 2, err, i, n;
+ int N = 2, i;
char **names;
+ int err;
names = reftable_calloc(N + 1, sizeof(*names));
- check(names != NULL);
+ cl_assert(names != NULL);
reftable_writer_set_limits(w, 0, N);
@@ -225,8 +221,7 @@ static void t_log_write_read(void)
ref.refname = name;
ref.update_index = i;
- err = reftable_writer_add_ref(w, &ref);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &ref), 0);
}
for (i = 0; i < N; i++) {
@@ -235,60 +230,57 @@ static void t_log_write_read(void)
log.refname = names[i];
log.update_index = i;
log.value_type = REFTABLE_LOG_UPDATE;
- t_reftable_set_hash(log.value.update.old_hash, i,
- REFTABLE_HASH_SHA1);
- t_reftable_set_hash(log.value.update.new_hash, i + 1,
- REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(log.value.update.old_hash, i,
+ REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(log.value.update.new_hash, i + 1,
+ REFTABLE_HASH_SHA1);
- err = reftable_writer_add_log(w, &log);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_log(w, &log), 0);
}
- n = reftable_writer_close(w);
- check_int(n, ==, 0);
+ cl_assert_equal_i(reftable_writer_close(w), 0);
stats = reftable_writer_stats(w);
- check_int(stats->log_stats.blocks, >, 0);
+ cl_assert(stats->log_stats.blocks > 0);
reftable_writer_free(w);
w = NULL;
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.log");
- check(!err);
+ cl_assert(!err);
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, names[N - 1]);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_next_ref(&it, &ref);
- check(!err);
+ cl_assert(!err);
/* end of iteration. */
- err = reftable_iterator_next_ref(&it, &ref);
- check_int(err, >, 0);
+ cl_assert(reftable_iterator_next_ref(&it, &ref) > 0);
reftable_iterator_destroy(&it);
reftable_ref_record_release(&ref);
err = reftable_table_init_log_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_log(&it, "");
- check(!err);
+ cl_assert(!err);
for (i = 0; ; i++) {
int err = reftable_iterator_next_log(&it, &log);
if (err > 0)
break;
- check(!err);
- check_str(names[i], log.refname);
- check_int(i, ==, log.update_index);
+ cl_assert(!err);
+ cl_assert_equal_s(names[i], log.refname);
+ cl_assert_equal_i(i, log.update_index);
reftable_log_record_release(&log);
}
- check_int(i, ==, N);
+ cl_assert_equal_i(i, N);
reftable_iterator_destroy(&it);
/* cleanup. */
@@ -297,7 +289,7 @@ static void t_log_write_read(void)
reftable_table_decref(table);
}
-static void t_log_zlib_corruption(void)
+void test_reftable_readwrite__log_zlib_corruption(void)
{
struct reftable_write_options opts = {
.block_size = 256,
@@ -306,10 +298,12 @@ static void t_log_zlib_corruption(void)
struct reftable_table *table;
struct reftable_block_source source = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
+ &opts);
const struct reftable_stats *stats = NULL;
char message[100] = { 0 };
- int err, i, n;
+ int i;
+ int err;
struct reftable_log_record log = {
.refname = (char *) "refname",
.value_type = REFTABLE_LOG_UPDATE,
@@ -329,14 +323,11 @@ static void t_log_zlib_corruption(void)
reftable_writer_set_limits(w, 1, 1);
- err = reftable_writer_add_log(w, &log);
- check(!err);
-
- n = reftable_writer_close(w);
- check_int(n, ==, 0);
+ cl_assert_equal_i(reftable_writer_add_log(w, &log), 0);
+ cl_assert_equal_i(reftable_writer_close(w), 0);
stats = reftable_writer_stats(w);
- check_int(stats->log_stats.blocks, >, 0);
+ cl_assert(stats->log_stats.blocks > 0);
reftable_writer_free(w);
w = NULL;
@@ -346,12 +337,12 @@ static void t_log_zlib_corruption(void)
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.log");
- check(!err);
+ cl_assert(!err);
err = reftable_table_init_log_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_log(&it, "refname");
- check_int(err, ==, REFTABLE_ZLIB_ERROR);
+ cl_assert_equal_i(err, REFTABLE_ZLIB_ERROR);
reftable_iterator_destroy(&it);
@@ -360,7 +351,7 @@ static void t_log_zlib_corruption(void)
reftable_buf_release(&buf);
}
-static void t_table_read_write_sequential(void)
+void test_reftable_readwrite__table_read_write_sequential(void)
{
char **names;
struct reftable_buf buf = REFTABLE_BUF_INIT;
@@ -376,24 +367,24 @@ static void t_table_read_write_sequential(void)
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.ref");
- check(!err);
+ cl_assert(!err);
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, "");
- check(!err);
+ cl_assert(!err);
for (j = 0; ; j++) {
struct reftable_ref_record ref = { 0 };
int r = reftable_iterator_next_ref(&it, &ref);
- check_int(r, >=, 0);
+ cl_assert(r >= 0);
if (r > 0)
break;
- check_str(names[j], ref.refname);
- check_int(update_index, ==, ref.update_index);
+ cl_assert_equal_s(names[j], ref.refname);
+ cl_assert_equal_i(update_index, ref.update_index);
reftable_ref_record_release(&ref);
}
- check_int(j, ==, N);
+ cl_assert_equal_i(j, N);
reftable_iterator_destroy(&it);
reftable_table_decref(table);
@@ -401,42 +392,42 @@ static void t_table_read_write_sequential(void)
free_names(names);
}
-static void t_table_write_small_table(void)
+void test_reftable_readwrite__table_write_small_table(void)
{
char **names;
struct reftable_buf buf = REFTABLE_BUF_INIT;
int N = 1;
write_table(&names, &buf, N, 4096, REFTABLE_HASH_SHA1);
- check_int(buf.len, <, 200);
+ cl_assert(buf.len < 200);
reftable_buf_release(&buf);
free_names(names);
}
-static void t_table_read_api(void)
+void test_reftable_readwrite__table_read_api(void)
{
char **names;
struct reftable_buf buf = REFTABLE_BUF_INIT;
int N = 50;
struct reftable_table *table;
struct reftable_block_source source = { 0 };
- int err;
struct reftable_log_record log = { 0 };
struct reftable_iterator it = { 0 };
+ int err;
write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1);
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.ref");
- check(!err);
+ cl_assert(!err);
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, names[0]);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_next_log(&it, &log);
- check_int(err, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(err, REFTABLE_API_ERROR);
reftable_buf_release(&buf);
free_names(names);
@@ -464,42 +455,43 @@ static void t_table_read_write_seek(int index, enum reftable_hash hash_id)
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.ref");
- check(!err);
- check_int(hash_id, ==, reftable_table_hash_id(table));
+ cl_assert(!err);
+ cl_assert_equal_i(hash_id, reftable_table_hash_id(table));
if (!index) {
table->ref_offsets.index_offset = 0;
} else {
- check_int(table->ref_offsets.index_offset, >, 0);
+ cl_assert(table->ref_offsets.index_offset > 0);
}
for (i = 1; i < N; i++) {
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, names[i]);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_next_ref(&it, &ref);
- check(!err);
- check_str(names[i], ref.refname);
- check_int(REFTABLE_REF_VAL1, ==, ref.value_type);
- check_int(i, ==, ref.value.val1[0]);
+ cl_assert(!err);
+ cl_assert_equal_s(names[i], ref.refname);
+ cl_assert_equal_i(REFTABLE_REF_VAL1, ref.value_type);
+ cl_assert_equal_i(i, ref.value.val1[0]);
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
}
- check(!reftable_buf_addstr(&pastLast, names[N - 1]));
- check(!reftable_buf_addstr(&pastLast, "/"));
+ cl_assert_equal_i(reftable_buf_addstr(&pastLast, names[N - 1]),
+ 0);
+ cl_assert_equal_i(reftable_buf_addstr(&pastLast, "/"), 0);
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, pastLast.buf);
if (err == 0) {
struct reftable_ref_record ref = { 0 };
int err = reftable_iterator_next_ref(&it, &ref);
- check_int(err, >, 0);
+ cl_assert(err > 0);
} else {
- check_int(err, >, 0);
+ cl_assert(err > 0);
}
reftable_buf_release(&pastLast);
@@ -510,17 +502,17 @@ static void t_table_read_write_seek(int index, enum reftable_hash hash_id)
reftable_table_decref(table);
}
-static void t_table_read_write_seek_linear(void)
+void test_reftable_readwrite__table_read_write_seek_linear(void)
{
t_table_read_write_seek(0, REFTABLE_HASH_SHA1);
}
-static void t_table_read_write_seek_linear_sha256(void)
+void test_reftable_readwrite__table_read_write_seek_linear_sha256(void)
{
t_table_read_write_seek(0, REFTABLE_HASH_SHA256);
}
-static void t_table_read_write_seek_index(void)
+void test_reftable_readwrite__table_read_write_seek_index(void)
{
t_table_read_write_seek(1, REFTABLE_HASH_SHA1);
}
@@ -538,14 +530,16 @@ static void t_table_refs_for(int indexed)
struct reftable_table *table;
struct reftable_block_source source = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf,
+ &opts);
struct reftable_iterator it = { 0 };
- int N = 50, n, j, err, i;
+ int N = 50, j, i;
+ int err;
want_names = reftable_calloc(N + 1, sizeof(*want_names));
- check(want_names != NULL);
+ cl_assert(want_names != NULL);
- t_reftable_set_hash(want_hash, 4, REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(want_hash, 4, REFTABLE_HASH_SHA1);
for (i = 0; i < N; i++) {
uint8_t hash[REFTABLE_HASH_SIZE_SHA1];
@@ -561,24 +555,22 @@ static void t_table_refs_for(int indexed)
ref.refname = name;
ref.value_type = REFTABLE_REF_VAL2;
- t_reftable_set_hash(ref.value.val2.value, i / 4,
- REFTABLE_HASH_SHA1);
- t_reftable_set_hash(ref.value.val2.target_value, 3 + i / 4,
- REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(ref.value.val2.value, i / 4,
+ REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(ref.value.val2.target_value,
+ 3 + i / 4, REFTABLE_HASH_SHA1);
/* 80 bytes / entry, so 3 entries per block. Yields 17
*/
/* blocks. */
- n = reftable_writer_add_ref(w, &ref);
- check_int(n, ==, 0);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &ref), 0);
if (!memcmp(ref.value.val2.value, want_hash, REFTABLE_HASH_SIZE_SHA1) ||
!memcmp(ref.value.val2.target_value, want_hash, REFTABLE_HASH_SIZE_SHA1))
want_names[want_names_len++] = xstrdup(name);
}
- n = reftable_writer_close(w);
- check_int(n, ==, 0);
+ cl_assert_equal_i(reftable_writer_close(w), 0);
reftable_writer_free(w);
w = NULL;
@@ -586,29 +578,29 @@ static void t_table_refs_for(int indexed)
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.ref");
- check(!err);
+ cl_assert(!err);
if (!indexed)
table->obj_offsets.is_present = 0;
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, "");
- check(!err);
+ cl_assert(!err);
reftable_iterator_destroy(&it);
err = reftable_table_refs_for(table, &it, want_hash);
- check(!err);
+ cl_assert(!err);
for (j = 0; ; j++) {
int err = reftable_iterator_next_ref(&it, &ref);
- check_int(err, >=, 0);
+ cl_assert(err >= 0);
if (err > 0)
break;
- check_int(j, <, want_names_len);
- check_str(ref.refname, want_names[j]);
+ cl_assert(j < want_names_len);
+ cl_assert_equal_s(ref.refname, want_names[j]);
reftable_ref_record_release(&ref);
}
- check_int(j, ==, want_names_len);
+ cl_assert_equal_i(j, want_names_len);
reftable_buf_release(&buf);
free_names(want_names);
@@ -616,21 +608,21 @@ static void t_table_refs_for(int indexed)
reftable_table_decref(table);
}
-static void t_table_refs_for_no_index(void)
+void test_reftable_readwrite__table_refs_for_no_index(void)
{
t_table_refs_for(0);
}
-static void t_table_refs_for_obj_index(void)
+void test_reftable_readwrite__table_refs_for_obj_index(void)
{
t_table_refs_for(1);
}
-static void t_write_empty_table(void)
+void test_reftable_readwrite__write_empty_table(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
struct reftable_block_source source = { 0 };
struct reftable_table *table = NULL;
struct reftable_ref_record rec = { 0 };
@@ -639,43 +631,41 @@ static void t_write_empty_table(void)
reftable_writer_set_limits(w, 1, 1);
- err = reftable_writer_close(w);
- check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR);
+ cl_assert_equal_i(reftable_writer_close(w), REFTABLE_EMPTY_TABLE_ERROR);
reftable_writer_free(w);
- check_uint(buf.len, ==, header_size(1) + footer_size(1));
+ cl_assert_equal_i(buf.len, header_size(1) + footer_size(1));
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "filename");
- check(!err);
+ cl_assert(!err);
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, "");
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_next_ref(&it, &rec);
- check_int(err, >, 0);
+ cl_assert(err > 0);
reftable_iterator_destroy(&it);
reftable_table_decref(table);
reftable_buf_release(&buf);
}
-static void t_write_object_id_min_length(void)
+void test_reftable_readwrite__write_object_id_min_length(void)
{
struct reftable_write_options opts = {
.block_size = 75,
};
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record ref = {
.update_index = 1,
.value_type = REFTABLE_REF_VAL1,
.value.val1 = {42},
};
- int err;
int i;
reftable_writer_set_limits(w, 1, 1);
@@ -686,30 +676,27 @@ static void t_write_object_id_min_length(void)
char name[256];
snprintf(name, sizeof(name), "ref%05d", i);
ref.refname = name;
- err = reftable_writer_add_ref(w, &ref);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &ref), 0);
}
- err = reftable_writer_close(w);
- check(!err);
- check_int(reftable_writer_stats(w)->object_id_len, ==, 2);
+ cl_assert_equal_i(reftable_writer_close(w), 0);
+ cl_assert_equal_i(reftable_writer_stats(w)->object_id_len, 2);
reftable_writer_free(w);
reftable_buf_release(&buf);
}
-static void t_write_object_id_length(void)
+void test_reftable_readwrite__write_object_id_length(void)
{
struct reftable_write_options opts = {
.block_size = 75,
};
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record ref = {
.update_index = 1,
.value_type = REFTABLE_REF_VAL1,
.value.val1 = {42},
};
- int err;
int i;
reftable_writer_set_limits(w, 1, 1);
@@ -721,44 +708,39 @@ static void t_write_object_id_length(void)
snprintf(name, sizeof(name), "ref%05d", i);
ref.refname = name;
ref.value.val1[15] = i;
- err = reftable_writer_add_ref(w, &ref);
- check(!err);
+ cl_assert(reftable_writer_add_ref(w, &ref) == 0);
}
- err = reftable_writer_close(w);
- check(!err);
- check_int(reftable_writer_stats(w)->object_id_len, ==, 16);
+ cl_assert_equal_i(reftable_writer_close(w), 0);
+ cl_assert_equal_i(reftable_writer_stats(w)->object_id_len, 16);
reftable_writer_free(w);
reftable_buf_release(&buf);
}
-static void t_write_empty_key(void)
+void test_reftable_readwrite__write_empty_key(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record ref = {
.refname = (char *) "",
.update_index = 1,
.value_type = REFTABLE_REF_DELETION,
};
- int err;
reftable_writer_set_limits(w, 1, 1);
- err = reftable_writer_add_ref(w, &ref);
- check_int(err, ==, REFTABLE_API_ERROR);
-
- err = reftable_writer_close(w);
- check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &ref), REFTABLE_API_ERROR);
+ cl_assert_equal_i(reftable_writer_close(w),
+ REFTABLE_EMPTY_TABLE_ERROR);
reftable_writer_free(w);
reftable_buf_release(&buf);
}
-static void t_write_key_order(void)
+void test_reftable_readwrite__write_key_order(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
- struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
+ struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record refs[2] = {
{
.refname = (char *) "b",
@@ -776,24 +758,21 @@ static void t_write_key_order(void)
},
}
};
- int err;
reftable_writer_set_limits(w, 1, 1);
- err = reftable_writer_add_ref(w, &refs[0]);
- check(!err);
- err = reftable_writer_add_ref(w, &refs[1]);
- check_int(err, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &refs[0]), 0);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &refs[1]),
+ REFTABLE_API_ERROR);
refs[0].update_index = 2;
- err = reftable_writer_add_ref(w, &refs[0]);
- check_int(err, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(reftable_writer_add_ref(w, &refs[0]), REFTABLE_API_ERROR);
reftable_writer_close(w);
reftable_writer_free(w);
reftable_buf_release(&buf);
}
-static void t_write_multiple_indices(void)
+void test_reftable_readwrite__write_multiple_indices(void)
{
struct reftable_write_options opts = {
.block_size = 100,
@@ -805,9 +784,10 @@ static void t_write_multiple_indices(void)
struct reftable_writer *writer;
struct reftable_table *table;
char buf[128];
- int err, i;
+ int i;
+ int err;
- writer = t_reftable_strbuf_writer(&writer_buf, &opts);
+ writer = cl_reftable_strbuf_writer(&writer_buf, &opts);
reftable_writer_set_limits(writer, 1, 1);
for (i = 0; i < 100; i++) {
struct reftable_ref_record ref = {
@@ -819,8 +799,7 @@ static void t_write_multiple_indices(void)
snprintf(buf, sizeof(buf), "refs/heads/%04d", i);
ref.refname = buf;
- err = reftable_writer_add_ref(writer, &ref);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_ref(writer, &ref), 0);
}
for (i = 0; i < 100; i++) {
@@ -836,8 +815,7 @@ static void t_write_multiple_indices(void)
snprintf(buf, sizeof(buf), "refs/heads/%04d", i);
log.refname = buf;
- err = reftable_writer_add_log(writer, &log);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_log(writer, &log), 0);
}
reftable_writer_close(writer);
@@ -847,22 +825,22 @@ static void t_write_multiple_indices(void)
* for each of the block types.
*/
stats = reftable_writer_stats(writer);
- check_int(stats->ref_stats.index_offset, >, 0);
- check_int(stats->obj_stats.index_offset, >, 0);
- check_int(stats->log_stats.index_offset, >, 0);
+ cl_assert(stats->ref_stats.index_offset > 0);
+ cl_assert(stats->obj_stats.index_offset > 0);
+ cl_assert(stats->log_stats.index_offset > 0);
block_source_from_buf(&source, &writer_buf);
err = reftable_table_new(&table, &source, "filename");
- check(!err);
+ cl_assert(!err);
/*
* Seeking the log uses the log index now. In case there is any
* confusion regarding indices we would notice here.
*/
err = reftable_table_init_log_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_log(&it, "");
- check(!err);
+ cl_assert(!err);
reftable_iterator_destroy(&it);
reftable_writer_free(writer);
@@ -870,7 +848,7 @@ static void t_write_multiple_indices(void)
reftable_buf_release(&writer_buf);
}
-static void t_write_multi_level_index(void)
+void test_reftable_readwrite__write_multi_level_index(void)
{
struct reftable_write_options opts = {
.block_size = 100,
@@ -883,7 +861,7 @@ static void t_write_multi_level_index(void)
struct reftable_table *table;
int err;
- writer = t_reftable_strbuf_writer(&writer_buf, &opts);
+ writer = cl_reftable_strbuf_writer(&writer_buf, &opts);
reftable_writer_set_limits(writer, 1, 1);
for (size_t i = 0; i < 200; i++) {
struct reftable_ref_record ref = {
@@ -896,8 +874,7 @@ static void t_write_multi_level_index(void)
snprintf(buf, sizeof(buf), "refs/heads/%03" PRIuMAX, (uintmax_t)i);
ref.refname = buf;
- err = reftable_writer_add_ref(writer, &ref);
- check(!err);
+ cl_assert_equal_i(reftable_writer_add_ref(writer, &ref), 0);
}
reftable_writer_close(writer);
@@ -906,19 +883,19 @@ static void t_write_multi_level_index(void)
* multi-level index.
*/
stats = reftable_writer_stats(writer);
- check_int(stats->ref_stats.max_index_level, ==, 2);
+ cl_assert_equal_i(stats->ref_stats.max_index_level, 2);
block_source_from_buf(&source, &writer_buf);
err = reftable_table_new(&table, &source, "filename");
- check(!err);
+ cl_assert(!err);
/*
* Seeking the last ref should work as expected.
*/
err = reftable_table_init_ref_iterator(table, &it);
- check(!err);
+ cl_assert(!err);
err = reftable_iterator_seek_ref(&it, "refs/heads/199");
- check(!err);
+ cl_assert(!err);
reftable_iterator_destroy(&it);
reftable_writer_free(writer);
@@ -927,7 +904,7 @@ static void t_write_multi_level_index(void)
reftable_buf_release(&buf);
}
-static void t_corrupt_table_empty(void)
+void test_reftable_readwrite__corrupt_table_empty(void)
{
struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
@@ -936,50 +913,22 @@ static void t_corrupt_table_empty(void)
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.log");
- check_int(err, ==, REFTABLE_FORMAT_ERROR);
+ cl_assert_equal_i(err, REFTABLE_FORMAT_ERROR);
}
-static void t_corrupt_table(void)
+void test_reftable_readwrite__corrupt_table(void)
{
uint8_t zeros[1024] = { 0 };
struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
struct reftable_table *table;
int err;
- check(!reftable_buf_add(&buf, zeros, sizeof(zeros)));
+
+ cl_assert(!reftable_buf_add(&buf, zeros, sizeof(zeros)));
block_source_from_buf(&source, &buf);
err = reftable_table_new(&table, &source, "file.log");
- check_int(err, ==, REFTABLE_FORMAT_ERROR);
+ cl_assert_equal_i(err, REFTABLE_FORMAT_ERROR);
reftable_buf_release(&buf);
}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_buffer(), "strbuf works as blocksource");
- TEST(t_corrupt_table(), "read-write on corrupted table");
- TEST(t_corrupt_table_empty(), "read-write on an empty table");
- TEST(t_log_buffer_size(), "buffer extension for log compression");
- TEST(t_log_overflow(), "log overflow returns expected error");
- TEST(t_log_write_limits(), "writer limits for writing log records");
- TEST(t_log_write_read(), "read-write on log records");
- TEST(t_log_zlib_corruption(), "reading corrupted log record returns expected error");
- TEST(t_table_read_api(), "read on a table");
- TEST(t_table_read_write_seek_index(), "read-write on a table with index");
- TEST(t_table_read_write_seek_linear(), "read-write on a table without index (SHA1)");
- TEST(t_table_read_write_seek_linear_sha256(), "read-write on a table without index (SHA256)");
- TEST(t_table_read_write_sequential(), "sequential read-write on a table");
- TEST(t_table_refs_for_no_index(), "refs-only table with no index");
- TEST(t_table_refs_for_obj_index(), "refs-only table with index");
- TEST(t_table_write_small_table(), "write_table works");
- TEST(t_write_empty_key(), "write on refs with empty keys");
- TEST(t_write_empty_table(), "read-write on empty tables");
- TEST(t_write_key_order(), "refs must be written in increasing order");
- TEST(t_write_multi_level_index(), "table with multi-level index");
- TEST(t_write_multiple_indices(), "table with indices for multiple block types");
- TEST(t_write_object_id_length(), "prefix compression on writing refs");
- TEST(t_write_object_id_min_length(), "prefix compression on writing refs");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/u-reftable-record.c
index 553a007664..6c8c0d5374 100644
--- a/t/unit-tests/t-reftable-record.c
+++ b/t/unit-tests/u-reftable-record.c
@@ -6,7 +6,8 @@
https://developers.google.com/open-source/licenses/bsd
*/
-#include "test-lib.h"
+#include "unit-test.h"
+#include "lib-reftable.h"
#include "reftable/basics.h"
#include "reftable/constants.h"
#include "reftable/record.h"
@@ -17,16 +18,17 @@ static void t_copy(struct reftable_record *rec)
uint8_t typ;
typ = reftable_record_type(rec);
- check(!reftable_record_init(&copy, typ));
+ cl_assert_equal_i(reftable_record_init(&copy, typ), 0);
reftable_record_copy_from(&copy, rec, REFTABLE_HASH_SIZE_SHA1);
/* do it twice to catch memory leaks */
reftable_record_copy_from(&copy, rec, REFTABLE_HASH_SIZE_SHA1);
- check(reftable_record_equal(rec, &copy, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_record_equal(rec, &copy,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_record_release(&copy);
}
-static void t_varint_roundtrip(void)
+void test_reftable_record__varint_roundtrip(void)
{
uint64_t inputs[] = { 0,
1,
@@ -49,16 +51,16 @@ static void t_varint_roundtrip(void)
int n = put_var_int(&out, in);
uint64_t got = 0;
- check_int(n, >, 0);
+ cl_assert(n > 0);
out.len = n;
n = get_var_int(&got, &out);
- check_int(n, >, 0);
+ cl_assert(n > 0);
- check_int(got, ==, in);
+ cl_assert_equal_i(got, in);
}
}
-static void t_varint_overflow(void)
+void test_reftable_record__varint_overflow(void)
{
unsigned char buf[] = {
0xFF, 0xFF, 0xFF, 0xFF,
@@ -70,8 +72,7 @@ static void t_varint_overflow(void)
.len = sizeof(buf),
};
uint64_t value;
- int err = get_var_int(&value, &view);
- check_int(err, ==, -1);
+ cl_assert_equal_i(get_var_int(&value, &view), -1);
}
static void set_hash(uint8_t *h, int j)
@@ -80,7 +81,7 @@ static void set_hash(uint8_t *h, int j)
h[i] = (j >> i) & 0xff;
}
-static void t_reftable_ref_record_comparison(void)
+void test_reftable_record__ref_record_comparison(void)
{
struct reftable_record in[3] = {
{
@@ -102,21 +103,23 @@ static void t_reftable_ref_record_comparison(void)
};
int cmp;
- check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
- check(!cmp);
+ cl_assert(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1) == 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
+ cl_assert(!cmp);
- check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[1], &in[2], &cmp));
- check_int(cmp, >, 0);
+ cl_assert(reftable_record_equal(&in[1], &in[2],
+ REFTABLE_HASH_SIZE_SHA1) == 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0);
+ cl_assert(cmp > 0);
in[1].u.ref.value_type = in[0].u.ref.value_type;
- check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
- check(!cmp);
+ cl_assert(reftable_record_equal(&in[0], &in[1],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
+ cl_assert(!cmp);
}
-static void t_reftable_ref_record_compare_name(void)
+void test_reftable_record__ref_record_compare_name(void)
{
struct reftable_ref_record recs[3] = {
{
@@ -130,12 +133,15 @@ static void t_reftable_ref_record_compare_name(void)
},
};
- check_int(reftable_ref_record_compare_name(&recs[0], &recs[1]), <, 0);
- check_int(reftable_ref_record_compare_name(&recs[1], &recs[0]), >, 0);
- check_int(reftable_ref_record_compare_name(&recs[0], &recs[2]), ==, 0);
+ cl_assert(reftable_ref_record_compare_name(&recs[0],
+ &recs[1]) < 0);
+ cl_assert(reftable_ref_record_compare_name(&recs[1],
+ &recs[0]) > 0);
+ cl_assert_equal_i(reftable_ref_record_compare_name(&recs[0],
+ &recs[2]), 0);
}
-static void t_reftable_ref_record_roundtrip(void)
+void test_reftable_record__ref_record_roundtrip(void)
{
struct reftable_buf scratch = REFTABLE_BUF_INIT;
@@ -172,19 +178,21 @@ static void t_reftable_ref_record_roundtrip(void)
t_copy(&in);
- check_int(reftable_record_val_type(&in), ==, i);
- check_int(reftable_record_is_deletion(&in), ==, i == REFTABLE_REF_DELETION);
+ cl_assert_equal_i(reftable_record_val_type(&in), i);
+ cl_assert_equal_i(reftable_record_is_deletion(&in),
+ i == REFTABLE_REF_DELETION);
reftable_record_key(&in, &key);
n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1);
- check_int(n, >, 0);
+ cl_assert(n > 0);
/* decode into a non-zero reftable_record to test for leaks. */
m = reftable_record_decode(&out, key, i, dest, REFTABLE_HASH_SIZE_SHA1, &scratch);
- check_int(n, ==, m);
+ cl_assert_equal_i(n, m);
- check(reftable_ref_record_equal(&in.u.ref, &out.u.ref,
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_ref_record_equal(&in.u.ref,
+ &out.u.ref,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_record_release(&in);
reftable_buf_release(&key);
@@ -194,7 +202,7 @@ static void t_reftable_ref_record_roundtrip(void)
reftable_buf_release(&scratch);
}
-static void t_reftable_log_record_comparison(void)
+void test_reftable_record__log_record_comparison(void)
{
struct reftable_record in[3] = {
{
@@ -215,21 +223,24 @@ static void t_reftable_log_record_comparison(void)
};
int cmp;
- check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[1], &in[2], &cmp));
- check_int(cmp, >, 0);
+ cl_assert_equal_i(reftable_record_equal(&in[0], &in[1],
+ REFTABLE_HASH_SIZE_SHA1), 0);
+ cl_assert_equal_i(reftable_record_equal(&in[1], &in[2],
+ REFTABLE_HASH_SIZE_SHA1), 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0);
+ cl_assert(cmp > 0);
/* comparison should be reversed for equal keys, because
* comparison is now performed on the basis of update indices */
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
- check_int(cmp, <, 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
+ cl_assert(cmp < 0);
in[1].u.log.update_index = in[0].u.log.update_index;
- check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
+ cl_assert(reftable_record_equal(&in[0], &in[1],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
}
-static void t_reftable_log_record_compare_key(void)
+void test_reftable_record__log_record_compare_key(void)
{
struct reftable_log_record logs[3] = {
{
@@ -246,19 +257,24 @@ static void t_reftable_log_record_compare_key(void)
},
};
- check_int(reftable_log_record_compare_key(&logs[0], &logs[1]), <, 0);
- check_int(reftable_log_record_compare_key(&logs[1], &logs[0]), >, 0);
+ cl_assert(reftable_log_record_compare_key(&logs[0],
+ &logs[1]) < 0);
+ cl_assert(reftable_log_record_compare_key(&logs[1],
+ &logs[0]) > 0);
logs[1].update_index = logs[0].update_index;
- check_int(reftable_log_record_compare_key(&logs[0], &logs[1]), <, 0);
+ cl_assert(reftable_log_record_compare_key(&logs[0],
+ &logs[1]) < 0);
- check_int(reftable_log_record_compare_key(&logs[0], &logs[2]), >, 0);
- check_int(reftable_log_record_compare_key(&logs[2], &logs[0]), <, 0);
+ cl_assert(reftable_log_record_compare_key(&logs[0],
+ &logs[2]) > 0);
+ cl_assert(reftable_log_record_compare_key(&logs[2],
+ &logs[0]) < 0);
logs[2].update_index = logs[0].update_index;
- check_int(reftable_log_record_compare_key(&logs[0], &logs[2]), ==, 0);
+ cl_assert_equal_i(reftable_log_record_compare_key(&logs[0], &logs[2]), 0);
}
-static void t_reftable_log_record_roundtrip(void)
+void test_reftable_record__log_record_roundtrip(void)
{
struct reftable_log_record in[] = {
{
@@ -292,9 +308,9 @@ static void t_reftable_log_record_roundtrip(void)
set_hash(in[2].value.update.new_hash, 3);
set_hash(in[2].value.update.old_hash, 4);
- check(!reftable_log_record_is_deletion(&in[0]));
- check(reftable_log_record_is_deletion(&in[1]));
- check(!reftable_log_record_is_deletion(&in[2]));
+ cl_assert_equal_i(reftable_log_record_is_deletion(&in[0]), 0);
+ cl_assert(reftable_log_record_is_deletion(&in[1]) != 0);
+ cl_assert_equal_i(reftable_log_record_is_deletion(&in[2]), 0);
for (size_t i = 0; i < ARRAY_SIZE(in); i++) {
struct reftable_record rec = { .type = REFTABLE_BLOCK_TYPE_LOG };
@@ -328,14 +344,14 @@ static void t_reftable_log_record_roundtrip(void)
reftable_record_key(&rec, &key);
n = reftable_record_encode(&rec, dest, REFTABLE_HASH_SIZE_SHA1);
- check_int(n, >=, 0);
+ cl_assert(n >= 0);
valtype = reftable_record_val_type(&rec);
m = reftable_record_decode(&out, key, valtype, dest,
REFTABLE_HASH_SIZE_SHA1, &scratch);
- check_int(n, ==, m);
+ cl_assert_equal_i(n, m);
- check(reftable_log_record_equal(&in[i], &out.u.log,
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_log_record_equal(&in[i], &out.u.log,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_log_record_release(&in[i]);
reftable_buf_release(&key);
reftable_record_release(&out);
@@ -344,7 +360,7 @@ static void t_reftable_log_record_roundtrip(void)
reftable_buf_release(&scratch);
}
-static void t_key_roundtrip(void)
+void test_reftable_record__key_roundtrip(void)
{
uint8_t buffer[1024] = { 0 };
struct string_view dest = {
@@ -359,25 +375,28 @@ static void t_key_roundtrip(void)
int n, m;
uint8_t rt_extra;
- check(!reftable_buf_addstr(&last_key, "refs/heads/master"));
- check(!reftable_buf_addstr(&key, "refs/tags/bla"));
+ cl_assert_equal_i(reftable_buf_addstr(&last_key,
+ "refs/heads/master"), 0);
+ cl_assert_equal_i(reftable_buf_addstr(&key,
+ "refs/tags/bla"), 0);
extra = 6;
n = reftable_encode_key(&restart, dest, last_key, key, extra);
- check(!restart);
- check_int(n, >, 0);
+ cl_assert(!restart);
+ cl_assert(n > 0);
- check(!reftable_buf_addstr(&roundtrip, "refs/heads/master"));
+ cl_assert_equal_i(reftable_buf_addstr(&roundtrip,
+ "refs/heads/master"), 0);
m = reftable_decode_key(&roundtrip, &rt_extra, dest);
- check_int(n, ==, m);
- check(!reftable_buf_cmp(&key, &roundtrip));
- check_int(rt_extra, ==, extra);
+ cl_assert_equal_i(n, m);
+ cl_assert_equal_i(reftable_buf_cmp(&key, &roundtrip), 0);
+ cl_assert_equal_i(rt_extra, extra);
reftable_buf_release(&last_key);
reftable_buf_release(&key);
reftable_buf_release(&roundtrip);
}
-static void t_reftable_obj_record_comparison(void)
+void test_reftable_record__obj_record_comparison(void)
{
uint8_t id_bytes[] = { 0, 1, 2, 3, 4, 5, 6 };
@@ -405,21 +424,23 @@ static void t_reftable_obj_record_comparison(void)
};
int cmp;
- check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
- check(!cmp);
+ cl_assert_equal_i(reftable_record_equal(&in[0], &in[1],
+ REFTABLE_HASH_SIZE_SHA1), 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
+ cl_assert(!cmp);
- check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[1], &in[2], &cmp));
- check_int(cmp, >, 0);
+ cl_assert_equal_i(reftable_record_equal(&in[1], &in[2],
+ REFTABLE_HASH_SIZE_SHA1), 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0);
+ cl_assert(cmp > 0);
in[1].u.obj.offset_len = in[0].u.obj.offset_len;
- check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
- check(!cmp);
+ cl_assert(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1) != 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
+ cl_assert(!cmp);
}
-static void t_reftable_obj_record_roundtrip(void)
+void test_reftable_record__obj_record_roundtrip(void)
{
uint8_t testHash1[REFTABLE_HASH_SIZE_SHA1] = { 1, 2, 3, 4, 0 };
uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
@@ -460,17 +481,18 @@ static void t_reftable_obj_record_roundtrip(void)
int n, m;
uint8_t extra;
- check(!reftable_record_is_deletion(&in));
+ cl_assert_equal_i(reftable_record_is_deletion(&in), 0);
t_copy(&in);
reftable_record_key(&in, &key);
n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1);
- check_int(n, >, 0);
+ cl_assert(n > 0);
extra = reftable_record_val_type(&in);
m = reftable_record_decode(&out, key, extra, dest,
REFTABLE_HASH_SIZE_SHA1, &scratch);
- check_int(n, ==, m);
+ cl_assert_equal_i(n, m);
- check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_record_equal(&in, &out,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_buf_release(&key);
reftable_record_release(&out);
}
@@ -478,7 +500,7 @@ static void t_reftable_obj_record_roundtrip(void)
reftable_buf_release(&scratch);
}
-static void t_reftable_index_record_comparison(void)
+void test_reftable_record__index_record_comparison(void)
{
struct reftable_record in[3] = {
{
@@ -499,28 +521,33 @@ static void t_reftable_index_record_comparison(void)
};
int cmp;
- check(!reftable_buf_addstr(&in[0].u.idx.last_key, "refs/heads/master"));
- check(!reftable_buf_addstr(&in[1].u.idx.last_key, "refs/heads/master"));
- check(!reftable_buf_addstr(&in[2].u.idx.last_key, "refs/heads/branch"));
+ cl_assert_equal_i(reftable_buf_addstr(&in[0].u.idx.last_key,
+ "refs/heads/master"), 0);
+ cl_assert_equal_i(reftable_buf_addstr(&in[1].u.idx.last_key, "refs/heads/master"), 0);
+ cl_assert(reftable_buf_addstr(&in[2].u.idx.last_key,
+ "refs/heads/branch") == 0);
- check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
- check(!cmp);
+ cl_assert_equal_i(reftable_record_equal(&in[0], &in[1],
+ REFTABLE_HASH_SIZE_SHA1), 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
+ cl_assert(!cmp);
- check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[1], &in[2], &cmp));
- check_int(cmp, >, 0);
+ cl_assert_equal_i(reftable_record_equal(&in[1], &in[2],
+ REFTABLE_HASH_SIZE_SHA1), 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0);
+ cl_assert(cmp > 0);
in[1].u.idx.offset = in[0].u.idx.offset;
- check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
- check(!reftable_record_cmp(&in[0], &in[1], &cmp));
- check(!cmp);
+ cl_assert(reftable_record_equal(&in[0], &in[1],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
+ cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0);
+ cl_assert(!cmp);
for (size_t i = 0; i < ARRAY_SIZE(in); i++)
reftable_record_release(&in[i]);
}
-static void t_reftable_index_record_roundtrip(void)
+void test_reftable_record__index_record_roundtrip(void)
{
struct reftable_record in = {
.type = REFTABLE_BLOCK_TYPE_INDEX,
@@ -543,43 +570,26 @@ static void t_reftable_index_record_roundtrip(void)
int n, m;
uint8_t extra;
- check(!reftable_buf_addstr(&in.u.idx.last_key, "refs/heads/master"));
+ cl_assert_equal_i(reftable_buf_addstr(&in.u.idx.last_key,
+ "refs/heads/master"), 0);
reftable_record_key(&in, &key);
t_copy(&in);
- check(!reftable_record_is_deletion(&in));
- check(!reftable_buf_cmp(&key, &in.u.idx.last_key));
+ cl_assert_equal_i(reftable_record_is_deletion(&in), 0);
+ cl_assert_equal_i(reftable_buf_cmp(&key, &in.u.idx.last_key), 0);
n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1);
- check_int(n, >, 0);
+ cl_assert(n > 0);
extra = reftable_record_val_type(&in);
- m = reftable_record_decode(&out, key, extra, dest, REFTABLE_HASH_SIZE_SHA1,
- &scratch);
- check_int(m, ==, n);
+ m = reftable_record_decode(&out, key, extra, dest,
+ REFTABLE_HASH_SIZE_SHA1, &scratch);
+ cl_assert_equal_i(m, n);
- check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(reftable_record_equal(&in, &out,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_record_release(&out);
reftable_buf_release(&key);
reftable_buf_release(&scratch);
reftable_buf_release(&in.u.idx.last_key);
}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_reftable_ref_record_comparison(), "comparison operations work on ref record");
- TEST(t_reftable_log_record_comparison(), "comparison operations work on log record");
- TEST(t_reftable_index_record_comparison(), "comparison operations work on index record");
- TEST(t_reftable_obj_record_comparison(), "comparison operations work on obj record");
- TEST(t_reftable_ref_record_compare_name(), "reftable_ref_record_compare_name works");
- TEST(t_reftable_log_record_compare_key(), "reftable_log_record_compare_key works");
- TEST(t_reftable_log_record_roundtrip(), "record operations work on log record");
- TEST(t_reftable_ref_record_roundtrip(), "record operations work on ref record");
- TEST(t_varint_roundtrip(), "put_var_int and get_var_int work");
- TEST(t_varint_overflow(), "get_var_int notices an integer overflow");
- TEST(t_key_roundtrip(), "reftable_encode_key and reftable_decode_key work");
- TEST(t_reftable_obj_record_roundtrip(), "record operations work on obj record");
- TEST(t_reftable_index_record_roundtrip(), "record operations work on index record");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/u-reftable-stack.c
index 2f49c97519..a8b91812e8 100644
--- a/t/unit-tests/t-reftable-stack.c
+++ b/t/unit-tests/u-reftable-stack.c
@@ -8,9 +8,9 @@ https://developers.google.com/open-source/licenses/bsd
#define DISABLE_SIGN_COMPARE_WARNINGS
-#include "test-lib.h"
-#include "lib-reftable.h"
+#include "unit-test.h"
#include "dir.h"
+#include "lib-reftable.h"
#include "reftable/merged.h"
#include "reftable/reftable-error.h"
#include "reftable/stack.h"
@@ -70,11 +70,11 @@ static char *get_tmp_template(int linenumber)
static char *get_tmp_dir(int linenumber)
{
char *dir = get_tmp_template(linenumber);
- check(mkdtemp(dir) != NULL);
+ cl_assert(mkdtemp(dir) != NULL);
return dir;
}
-static void t_read_file(void)
+void test_reftable_stack__read_file(void)
{
char *fn = get_tmp_template(__LINE__);
struct tempfile *tmp = mks_tempfile(fn);
@@ -84,17 +84,17 @@ static void t_read_file(void)
char **names = NULL;
const char *want[] = { "line1", "line2", "line3" };
- check_int(fd, >, 0);
+ cl_assert(fd > 0);
n = write_in_full(fd, out, strlen(out));
- check_int(n, ==, strlen(out));
+ cl_assert_equal_i(n, strlen(out));
err = close(fd);
- check_int(err, >=, 0);
+ cl_assert(err >= 0);
err = read_lines(fn, &names);
- check(!err);
+ cl_assert(!err);
for (size_t i = 0; names[i]; i++)
- check_str(want[i], names[i]);
+ cl_assert_equal_s(want[i], names[i]);
free_names(names);
(void) remove(fn);
delete_tempfile(&tmp);
@@ -103,8 +103,8 @@ static void t_read_file(void)
static int write_test_ref(struct reftable_writer *wr, void *arg)
{
struct reftable_ref_record *ref = arg;
- check(!reftable_writer_set_limits(wr, ref->update_index,
- ref->update_index));
+ cl_assert_equal_i(reftable_writer_set_limits(wr,
+ ref->update_index, ref->update_index), 0);
return reftable_writer_add_ref(wr, ref);
}
@@ -112,7 +112,6 @@ static void write_n_ref_tables(struct reftable_stack *st,
size_t n)
{
int disable_auto_compact;
- int err;
disable_auto_compact = st->opts.disable_auto_compact;
st->opts.disable_auto_compact = 1;
@@ -126,10 +125,10 @@ static void write_n_ref_tables(struct reftable_stack *st,
snprintf(buf, sizeof(buf), "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i);
ref.refname = buf;
- t_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1);
- err = reftable_stack_add(st, &write_test_ref, &ref);
- check(!err);
+ cl_assert_equal_i(reftable_stack_add(st,
+ &write_test_ref, &ref, 0), 0);
}
st->opts.disable_auto_compact = disable_auto_compact;
@@ -144,12 +143,13 @@ static int write_test_log(struct reftable_writer *wr, void *arg)
{
struct write_log_arg *wla = arg;
- check(!reftable_writer_set_limits(wr, wla->update_index,
- wla->update_index));
+ cl_assert_equal_i(reftable_writer_set_limits(wr,
+ wla->update_index,
+ wla->update_index), 0);
return reftable_writer_add_log(wr, wla->log);
}
-static void t_reftable_stack_add_one(void)
+void test_reftable_stack__add_one(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_buf scratch = REFTABLE_BUF_INIT;
@@ -158,7 +158,6 @@ static void t_reftable_stack_add_one(void)
.default_permissions = 0660,
};
struct reftable_stack *st = NULL;
- int err;
struct reftable_ref_record ref = {
.refname = (char *) "HEAD",
.update_index = 1,
@@ -167,32 +166,37 @@ static void t_reftable_stack_add_one(void)
};
struct reftable_ref_record dest = { 0 };
struct stat stat_result = { 0 };
+ int err;
+
err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert(!err);
- err = reftable_stack_add(st, write_test_ref, &ref);
- check(!err);
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
+ cl_assert(!err);
err = reftable_stack_read_ref(st, ref.refname, &dest);
- check(!err);
- check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1));
- check_int(st->tables_len, >, 0);
+ cl_assert(!err);
+ cl_assert(reftable_ref_record_equal(&ref, &dest,
+ REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(st->tables_len > 0);
#ifndef GIT_WINDOWS_NATIVE
- check(!reftable_buf_addstr(&scratch, dir));
- check(!reftable_buf_addstr(&scratch, "/tables.list"));
- err = stat(scratch.buf, &stat_result);
- check(!err);
- check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
+ cl_assert_equal_i(reftable_buf_addstr(&scratch, dir), 0);
+ cl_assert_equal_i(reftable_buf_addstr(&scratch,
+ "/tables.list"), 0);
+ cl_assert_equal_i(stat(scratch.buf, &stat_result), 0);
+ cl_assert_equal_i((stat_result.st_mode & 0777),
+ opts.default_permissions);
reftable_buf_reset(&scratch);
- check(!reftable_buf_addstr(&scratch, dir));
- check(!reftable_buf_addstr(&scratch, "/"));
+ cl_assert_equal_i(reftable_buf_addstr(&scratch, dir), 0);
+ cl_assert_equal_i(reftable_buf_addstr(&scratch, "/"), 0);
/* do not try at home; not an external API for reftable. */
- check(!reftable_buf_addstr(&scratch, st->tables[0]->name));
+ cl_assert(!reftable_buf_addstr(&scratch, st->tables[0]->name));
err = stat(scratch.buf, &stat_result);
- check(!err);
- check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
+ cl_assert(!err);
+ cl_assert_equal_i((stat_result.st_mode & 0777),
+ opts.default_permissions);
#else
(void) stat_result;
#endif
@@ -204,14 +208,13 @@ static void t_reftable_stack_add_one(void)
umask(mask);
}
-static void t_reftable_stack_uptodate(void)
+void test_reftable_stack__uptodate(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL;
struct reftable_stack *st2 = NULL;
char *dir = get_tmp_dir(__LINE__);
- int err;
struct reftable_ref_record ref1 = {
.refname = (char *) "HEAD",
.update_index = 1,
@@ -229,34 +232,25 @@ static void t_reftable_stack_uptodate(void)
/* simulate multi-process access to the same stack
by creating two stacks for the same directory.
*/
- err = reftable_new_stack(&st1, dir, &opts);
- check(!err);
-
- err = reftable_new_stack(&st2, dir, &opts);
- check(!err);
-
- err = reftable_stack_add(st1, write_test_ref, &ref1);
- check(!err);
-
- err = reftable_stack_add(st2, write_test_ref, &ref2);
- check_int(err, ==, REFTABLE_OUTDATED_ERROR);
-
- err = reftable_stack_reload(st2);
- check(!err);
-
- err = reftable_stack_add(st2, write_test_ref, &ref2);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_add(st1, write_test_ref,
+ &ref1, 0), 0);
+ cl_assert_equal_i(reftable_stack_add(st2, write_test_ref,
+ &ref2, 0), REFTABLE_OUTDATED_ERROR);
+ cl_assert_equal_i(reftable_stack_reload(st2), 0);
+ cl_assert_equal_i(reftable_stack_add(st2, write_test_ref,
+ &ref2, 0), 0);
reftable_stack_destroy(st1);
reftable_stack_destroy(st2);
clear_dir(dir);
}
-static void t_reftable_stack_transaction_api(void)
+void test_reftable_stack__transaction_api(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
- int err;
struct reftable_addition *add = NULL;
struct reftable_ref_record ref = {
@@ -267,37 +261,32 @@ static void t_reftable_stack_transaction_api(void)
};
struct reftable_ref_record dest = { 0 };
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
reftable_addition_destroy(add);
- err = reftable_stack_new_addition(&add, st, 0);
- check(!err);
-
- err = reftable_addition_add(add, write_test_ref, &ref);
- check(!err);
-
- err = reftable_addition_commit(add);
- check(!err);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0);
+ cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
+ &ref), 0);
+ cl_assert_equal_i(reftable_addition_commit(add), 0);
reftable_addition_destroy(add);
- err = reftable_stack_read_ref(st, ref.refname, &dest);
- check(!err);
- check_int(REFTABLE_REF_SYMREF, ==, dest.value_type);
- check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_stack_read_ref(st, ref.refname,
+ &dest), 0);
+ cl_assert_equal_i(REFTABLE_REF_SYMREF, dest.value_type);
+ cl_assert(reftable_ref_record_equal(&ref, &dest,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_ref_record_release(&dest);
reftable_stack_destroy(st);
clear_dir(dir);
}
-static void t_reftable_stack_transaction_with_reload(void)
+void test_reftable_stack__transaction_with_reload(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_stack *st1 = NULL, *st2 = NULL;
- int err;
struct reftable_addition *add = NULL;
struct reftable_ref_record refs[2] = {
{
@@ -315,17 +304,12 @@ static void t_reftable_stack_transaction_with_reload(void)
};
struct reftable_ref_record ref = { 0 };
- err = reftable_new_stack(&st1, dir, NULL);
- check(!err);
- err = reftable_new_stack(&st2, dir, NULL);
- check(!err);
-
- err = reftable_stack_new_addition(&add, st1, 0);
- check(!err);
- err = reftable_addition_add(add, write_test_ref, &refs[0]);
- check(!err);
- err = reftable_addition_commit(add);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st1, 0), 0);
+ cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
+ &refs[0]), 0);
+ cl_assert_equal_i(reftable_addition_commit(add), 0);
reftable_addition_destroy(add);
/*
@@ -333,20 +317,20 @@ static void t_reftable_stack_transaction_with_reload(void)
* create the addition and lock the stack by default, but allow the
* reload to happen when REFTABLE_STACK_NEW_ADDITION_RELOAD is set.
*/
- err = reftable_stack_new_addition(&add, st2, 0);
- check_int(err, ==, REFTABLE_OUTDATED_ERROR);
- err = reftable_stack_new_addition(&add, st2, REFTABLE_STACK_NEW_ADDITION_RELOAD);
- check(!err);
- err = reftable_addition_add(add, write_test_ref, &refs[1]);
- check(!err);
- err = reftable_addition_commit(add);
- check(!err);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st2, 0),
+ REFTABLE_OUTDATED_ERROR);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st2,
+ REFTABLE_STACK_NEW_ADDITION_RELOAD), 0);
+ cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
+ &refs[1]), 0);
+ cl_assert_equal_i(reftable_addition_commit(add), 0);
reftable_addition_destroy(add);
for (size_t i = 0; i < ARRAY_SIZE(refs); i++) {
- err = reftable_stack_read_ref(st2, refs[i].refname, &ref);
- check(!err);
- check(reftable_ref_record_equal(&refs[i], &ref, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_stack_read_ref(st2,
+ refs[i].refname, &ref) , 0);
+ cl_assert(reftable_ref_record_equal(&refs[i], &ref,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
}
reftable_ref_record_release(&ref);
@@ -355,17 +339,15 @@ static void t_reftable_stack_transaction_with_reload(void)
clear_dir(dir);
}
-static void t_reftable_stack_transaction_api_performs_auto_compaction(void)
+void test_reftable_stack__transaction_api_performs_auto_compaction(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_write_options opts = {0};
struct reftable_addition *add = NULL;
struct reftable_stack *st = NULL;
size_t n = 20;
- int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
for (size_t i = 0; i <= n; i++) {
struct reftable_ref_record ref = {
@@ -385,14 +367,11 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)
*/
st->opts.disable_auto_compact = i != n;
- err = reftable_stack_new_addition(&add, st, 0);
- check(!err);
-
- err = reftable_addition_add(add, write_test_ref, &ref);
- check(!err);
-
- err = reftable_addition_commit(add);
- check(!err);
+ cl_assert_equal_i(reftable_stack_new_addition(&add,
+ st, 0), 0);
+ cl_assert_equal_i(reftable_addition_add(add,
+ write_test_ref, &ref), 0);
+ cl_assert_equal_i(reftable_addition_commit(add), 0);
reftable_addition_destroy(add);
@@ -402,16 +381,16 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void)
* all tables in the stack.
*/
if (i != n)
- check_int(st->merged->tables_len, ==, i + 1);
+ cl_assert_equal_i(st->merged->tables_len, i + 1);
else
- check_int(st->merged->tables_len, ==, 1);
+ cl_assert_equal_i(st->merged->tables_len, 1);
}
reftable_stack_destroy(st);
clear_dir(dir);
}
-static void t_reftable_stack_auto_compaction_fails_gracefully(void)
+void test_reftable_stack__auto_compaction_fails_gracefully(void)
{
struct reftable_ref_record ref = {
.refname = (char *) "refs/heads/master",
@@ -425,32 +404,31 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)
char *dir = get_tmp_dir(__LINE__);
int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
-
- err = reftable_stack_add(st, write_test_ref, &ref);
- check(!err);
- check_int(st->merged->tables_len, ==, 1);
- check_int(st->stats.attempts, ==, 0);
- check_int(st->stats.failures, ==, 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &ref, 0), 0);
+ cl_assert_equal_i(st->merged->tables_len, 1);
+ cl_assert_equal_i(st->stats.attempts, 0);
+ cl_assert_equal_i(st->stats.failures, 0);
/*
* Lock the newly written table such that it cannot be compacted.
* Adding a new table to the stack should not be impacted by this, even
* though auto-compaction will now fail.
*/
- check(!reftable_buf_addstr(&table_path, dir));
- check(!reftable_buf_addstr(&table_path, "/"));
- check(!reftable_buf_addstr(&table_path, st->tables[0]->name));
- check(!reftable_buf_addstr(&table_path, ".lock"));
+ cl_assert(!reftable_buf_addstr(&table_path, dir));
+ cl_assert(!reftable_buf_addstr(&table_path, "/"));
+ cl_assert(!reftable_buf_addstr(&table_path,
+ st->tables[0]->name));
+ cl_assert(!reftable_buf_addstr(&table_path, ".lock"));
write_file_buf(table_path.buf, "", 0);
ref.update_index = 2;
- err = reftable_stack_add(st, write_test_ref, &ref);
- check(!err);
- check_int(st->merged->tables_len, ==, 2);
- check_int(st->stats.attempts, ==, 1);
- check_int(st->stats.failures, ==, 1);
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
+ cl_assert(!err);
+ cl_assert_equal_i(st->merged->tables_len, 2);
+ cl_assert_equal_i(st->stats.attempts, 1);
+ cl_assert_equal_i(st->stats.failures, 1);
reftable_stack_destroy(st);
reftable_buf_release(&table_path);
@@ -462,12 +440,11 @@ static int write_error(struct reftable_writer *wr UNUSED, void *arg)
return *((int *)arg);
}
-static void t_reftable_stack_update_index_check(void)
+void test_reftable_stack__update_index_check(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
- int err;
struct reftable_ref_record ref1 = {
.refname = (char *) "name1",
.update_index = 1,
@@ -481,39 +458,33 @@ static void t_reftable_stack_update_index_check(void)
.value.symref = (char *) "master",
};
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
-
- err = reftable_stack_add(st, write_test_ref, &ref1);
- check(!err);
-
- err = reftable_stack_add(st, write_test_ref, &ref2);
- check_int(err, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &ref1, 0), 0);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &ref2, 0), REFTABLE_API_ERROR);
reftable_stack_destroy(st);
clear_dir(dir);
}
-static void t_reftable_stack_lock_failure(void)
+void test_reftable_stack__lock_failure(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
- int err, i;
+ int i;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
- for (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) {
- err = reftable_stack_add(st, write_error, &i);
- check_int(err, ==, i);
- }
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ for (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--)
+ cl_assert_equal_i(reftable_stack_add(st, write_error,
+ &i, 0), i);
reftable_stack_destroy(st);
clear_dir(dir);
}
-static void t_reftable_stack_add(void)
+void test_reftable_stack__add(void)
{
- int err = 0;
struct reftable_write_options opts = {
.exact_log_message = 1,
.default_permissions = 0660,
@@ -526,9 +497,10 @@ static void t_reftable_stack_add(void)
struct reftable_buf path = REFTABLE_BUF_INIT;
struct stat stat_result;
size_t i, N = ARRAY_SIZE(refs);
+ int err = 0;
err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert(!err);
for (i = 0; i < N; i++) {
char buf[256];
@@ -536,66 +508,66 @@ static void t_reftable_stack_add(void)
refs[i].refname = xstrdup(buf);
refs[i].update_index = i + 1;
refs[i].value_type = REFTABLE_REF_VAL1;
- t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(refs[i].value.val1, i,
+ REFTABLE_HASH_SHA1);
logs[i].refname = xstrdup(buf);
logs[i].update_index = N + i + 1;
logs[i].value_type = REFTABLE_LOG_UPDATE;
logs[i].value.update.email = xstrdup("identity@invalid");
- t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(logs[i].value.update.new_hash, i,
+ REFTABLE_HASH_SHA1);
}
- for (i = 0; i < N; i++) {
- int err = reftable_stack_add(st, write_test_ref, &refs[i]);
- check(!err);
- }
+ for (i = 0; i < N; i++)
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &refs[i], 0), 0);
for (i = 0; i < N; i++) {
struct write_log_arg arg = {
.log = &logs[i],
.update_index = reftable_stack_next_update_index(st),
};
- int err = reftable_stack_add(st, write_test_log, &arg);
- check(!err);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_log,
+ &arg, 0), 0);
}
- err = reftable_stack_compact_all(st, NULL);
- check(!err);
+ cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
for (i = 0; i < N; i++) {
struct reftable_ref_record dest = { 0 };
- int err = reftable_stack_read_ref(st, refs[i].refname, &dest);
- check(!err);
- check(reftable_ref_record_equal(&dest, refs + i,
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_stack_read_ref(st,
+ refs[i].refname, &dest), 0);
+ cl_assert(reftable_ref_record_equal(&dest, refs + i,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_ref_record_release(&dest);
}
for (i = 0; i < N; i++) {
struct reftable_log_record dest = { 0 };
- int err = reftable_stack_read_log(st, refs[i].refname, &dest);
- check(!err);
- check(reftable_log_record_equal(&dest, logs + i,
- REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_stack_read_log(st,
+ refs[i].refname, &dest), 0);
+ cl_assert(reftable_log_record_equal(&dest, logs + i,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_log_record_release(&dest);
}
#ifndef GIT_WINDOWS_NATIVE
- check(!reftable_buf_addstr(&path, dir));
- check(!reftable_buf_addstr(&path, "/tables.list"));
- err = stat(path.buf, &stat_result);
- check(!err);
- check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
+ cl_assert_equal_i(reftable_buf_addstr(&path, dir), 0);
+ cl_assert_equal_i(reftable_buf_addstr(&path, "/tables.list"), 0);
+ cl_assert_equal_i(stat(path.buf, &stat_result), 0);
+ cl_assert_equal_i((stat_result.st_mode & 0777), opts.default_permissions);
reftable_buf_reset(&path);
- check(!reftable_buf_addstr(&path, dir));
- check(!reftable_buf_addstr(&path, "/"));
+ cl_assert_equal_i(reftable_buf_addstr(&path, dir), 0);
+ cl_assert_equal_i(reftable_buf_addstr(&path, "/"), 0);
/* do not try at home; not an external API for reftable. */
- check(!reftable_buf_addstr(&path, st->tables[0]->name));
+ cl_assert(!reftable_buf_addstr(&path, st->tables[0]->name));
err = stat(path.buf, &stat_result);
- check(!err);
- check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
+ cl_assert(!err);
+ cl_assert_equal_i((stat_result.st_mode & 0777),
+ opts.default_permissions);
#else
(void) stat_result;
#endif
@@ -610,7 +582,7 @@ static void t_reftable_stack_add(void)
clear_dir(dir);
}
-static void t_reftable_stack_iterator(void)
+void test_reftable_stack__iterator(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
@@ -621,27 +593,27 @@ static void t_reftable_stack_iterator(void)
size_t N = ARRAY_SIZE(refs), i;
int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
for (i = 0; i < N; i++) {
refs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i);
refs[i].update_index = i + 1;
refs[i].value_type = REFTABLE_REF_VAL1;
- t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(refs[i].value.val1, i,
+ REFTABLE_HASH_SHA1);
logs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i);
logs[i].update_index = i + 1;
logs[i].value_type = REFTABLE_LOG_UPDATE;
logs[i].value.update.email = xstrdup("johndoe@invalid");
logs[i].value.update.message = xstrdup("commit\n");
- t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(logs[i].value.update.new_hash, i,
+ REFTABLE_HASH_SHA1);
}
- for (i = 0; i < N; i++) {
- err = reftable_stack_add(st, write_test_ref, &refs[i]);
- check(!err);
- }
+ for (i = 0; i < N; i++)
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &refs[i], 0), 0);
for (i = 0; i < N; i++) {
struct write_log_arg arg = {
@@ -649,8 +621,8 @@ static void t_reftable_stack_iterator(void)
.update_index = reftable_stack_next_update_index(st),
};
- err = reftable_stack_add(st, write_test_log, &arg);
- check(!err);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_log,
+ &arg, 0), 0);
}
reftable_stack_init_ref_iterator(st, &it);
@@ -661,16 +633,16 @@ static void t_reftable_stack_iterator(void)
err = reftable_iterator_next_ref(&it, &ref);
if (err > 0)
break;
- check(!err);
- check(reftable_ref_record_equal(&ref, &refs[i], REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(!err);
+ cl_assert(reftable_ref_record_equal(&ref, &refs[i],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_ref_record_release(&ref);
}
- check_int(i, ==, N);
+ cl_assert_equal_i(i, N);
reftable_iterator_destroy(&it);
- err = reftable_stack_init_log_iterator(st, &it);
- check(!err);
+ cl_assert_equal_i(reftable_stack_init_log_iterator(st, &it), 0);
reftable_iterator_seek_log(&it, logs[0].refname);
for (i = 0; ; i++) {
@@ -679,11 +651,12 @@ static void t_reftable_stack_iterator(void)
err = reftable_iterator_next_log(&it, &log);
if (err > 0)
break;
- check(!err);
- check(reftable_log_record_equal(&log, &logs[i], REFTABLE_HASH_SIZE_SHA1));
+ cl_assert(!err);
+ cl_assert(reftable_log_record_equal(&log, &logs[i],
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_log_record_release(&log);
}
- check_int(i, ==, N);
+ cl_assert_equal_i(i, N);
reftable_stack_destroy(st);
reftable_iterator_destroy(&it);
@@ -694,9 +667,8 @@ static void t_reftable_stack_iterator(void)
clear_dir(dir);
}
-static void t_reftable_stack_log_normalize(void)
+void test_reftable_stack__log_normalize(void)
{
- int err = 0;
struct reftable_write_options opts = {
0,
};
@@ -721,28 +693,26 @@ static void t_reftable_stack_log_normalize(void)
.update_index = 1,
};
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
input.value.update.message = (char *) "one\ntwo";
- err = reftable_stack_add(st, write_test_log, &arg);
- check_int(err, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_log,
+ &arg, 0), REFTABLE_API_ERROR);
input.value.update.message = (char *) "one";
- err = reftable_stack_add(st, write_test_log, &arg);
- check(!err);
-
- err = reftable_stack_read_log(st, input.refname, &dest);
- check(!err);
- check_str(dest.value.update.message, "one\n");
+ cl_assert_equal_i(reftable_stack_add(st, write_test_log,
+ &arg, 0), 0);
+ cl_assert_equal_i(reftable_stack_read_log(st, input.refname,
+ &dest), 0);
+ cl_assert_equal_s(dest.value.update.message, "one\n");
input.value.update.message = (char *) "two\n";
arg.update_index = 2;
- err = reftable_stack_add(st, write_test_log, &arg);
- check(!err);
- err = reftable_stack_read_log(st, input.refname, &dest);
- check(!err);
- check_str(dest.value.update.message, "two\n");
+ cl_assert_equal_i(reftable_stack_add(st, write_test_log,
+ &arg, 0), 0);
+ cl_assert_equal_i(reftable_stack_read_log(st, input.refname,
+ &dest), 0);
+ cl_assert_equal_s(dest.value.update.message, "two\n");
/* cleanup */
reftable_stack_destroy(st);
@@ -750,20 +720,18 @@ static void t_reftable_stack_log_normalize(void)
clear_dir(dir);
}
-static void t_reftable_stack_tombstone(void)
+void test_reftable_stack__tombstone(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
- int err;
struct reftable_ref_record refs[2] = { 0 };
struct reftable_log_record logs[2] = { 0 };
size_t i, N = ARRAY_SIZE(refs);
struct reftable_ref_record dest = { 0 };
struct reftable_log_record log_dest = { 0 };
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
/* even entries add the refs, odd entries delete them. */
for (i = 0; i < N; i++) {
@@ -772,8 +740,8 @@ static void t_reftable_stack_tombstone(void)
refs[i].update_index = i + 1;
if (i % 2 == 0) {
refs[i].value_type = REFTABLE_REF_VAL1;
- t_reftable_set_hash(refs[i].value.val1, i,
- REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(refs[i].value.val1, i,
+ REFTABLE_HASH_SHA1);
}
logs[i].refname = xstrdup(buf);
@@ -785,42 +753,37 @@ static void t_reftable_stack_tombstone(void)
logs[i].update_index = 1;
if (i % 2 == 0) {
logs[i].value_type = REFTABLE_LOG_UPDATE;
- t_reftable_set_hash(logs[i].value.update.new_hash, i,
- REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1);
logs[i].value.update.email =
xstrdup("identity@invalid");
}
}
- for (i = 0; i < N; i++) {
- int err = reftable_stack_add(st, write_test_ref, &refs[i]);
- check(!err);
- }
+ for (i = 0; i < N; i++)
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &refs[i], 0), 0);
for (i = 0; i < N; i++) {
struct write_log_arg arg = {
.log = &logs[i],
.update_index = reftable_stack_next_update_index(st),
};
- int err = reftable_stack_add(st, write_test_log, &arg);
- check(!err);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_log,
+ &arg, 0), 0);
}
- err = reftable_stack_read_ref(st, "branch", &dest);
- check_int(err, ==, 1);
+ cl_assert_equal_i(reftable_stack_read_ref(st, "branch",
+ &dest), 1);
reftable_ref_record_release(&dest);
- err = reftable_stack_read_log(st, "branch", &log_dest);
- check_int(err, ==, 1);
+ cl_assert_equal_i(reftable_stack_read_log(st, "branch",
+ &log_dest), 1);
reftable_log_record_release(&log_dest);
- err = reftable_stack_compact_all(st, NULL);
- check(!err);
-
- err = reftable_stack_read_ref(st, "branch", &dest);
- check_int(err, ==, 1);
-
- err = reftable_stack_read_log(st, "branch", &log_dest);
- check_int(err, ==, 1);
+ cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
+ cl_assert_equal_i(reftable_stack_read_ref(st, "branch",
+ &dest), 1);
+ cl_assert_equal_i(reftable_stack_read_log(st, "branch",
+ &log_dest), 1);
reftable_ref_record_release(&dest);
reftable_log_record_release(&log_dest);
@@ -833,12 +796,11 @@ static void t_reftable_stack_tombstone(void)
clear_dir(dir);
}
-static void t_reftable_stack_hash_id(void)
+void test_reftable_stack__hash_id(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
- int err;
struct reftable_ref_record ref = {
.refname = (char *) "master",
@@ -852,62 +814,57 @@ static void t_reftable_stack_hash_id(void)
struct reftable_stack *st_default = NULL;
struct reftable_ref_record dest = { 0 };
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
-
- err = reftable_stack_add(st, write_test_ref, &ref);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &ref, 0), 0);
/* can't read it with the wrong hash ID. */
- err = reftable_new_stack(&st32, dir, &opts32);
- check_int(err, ==, REFTABLE_FORMAT_ERROR);
+ cl_assert_equal_i(reftable_new_stack(&st32, dir,
+ &opts32), REFTABLE_FORMAT_ERROR);
/* check that we can read it back with default opts too. */
- err = reftable_new_stack(&st_default, dir, &opts_default);
- check(!err);
-
- err = reftable_stack_read_ref(st_default, "master", &dest);
- check(!err);
-
- check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1));
+ cl_assert_equal_i(reftable_new_stack(&st_default, dir,
+ &opts_default), 0);
+ cl_assert_equal_i(reftable_stack_read_ref(st_default, "master",
+ &dest), 0);
+ cl_assert(reftable_ref_record_equal(&ref, &dest,
+ REFTABLE_HASH_SIZE_SHA1) != 0);
reftable_ref_record_release(&dest);
reftable_stack_destroy(st);
reftable_stack_destroy(st_default);
clear_dir(dir);
}
-static void t_suggest_compaction_segment(void)
+void test_reftable_stack__suggest_compaction_segment(void)
{
uint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 };
struct segment min =
suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);
- check_int(min.start, ==, 1);
- check_int(min.end, ==, 10);
+ cl_assert_equal_i(min.start, 1);
+ cl_assert_equal_i(min.end, 10);
}
-static void t_suggest_compaction_segment_nothing(void)
+void test_reftable_stack__suggest_compaction_segment_nothing(void)
{
uint64_t sizes[] = { 64, 32, 16, 8, 4, 2 };
struct segment result =
suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2);
- check_int(result.start, ==, result.end);
+ cl_assert_equal_i(result.start, result.end);
}
-static void t_reflog_expire(void)
+void test_reftable_stack__reflog_expire(void)
{
char *dir = get_tmp_dir(__LINE__);
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
struct reftable_log_record logs[20] = { 0 };
size_t i, N = ARRAY_SIZE(logs) - 1;
- int err;
struct reftable_log_expiry_config expiry = {
.time = 10,
};
struct reftable_log_record log = { 0 };
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
for (i = 1; i <= N; i++) {
char buf[256];
@@ -918,8 +875,8 @@ static void t_reflog_expire(void)
logs[i].value_type = REFTABLE_LOG_UPDATE;
logs[i].value.update.time = i;
logs[i].value.update.email = xstrdup("identity@invalid");
- t_reftable_set_hash(logs[i].value.update.new_hash, i,
- REFTABLE_HASH_SHA1);
+ cl_reftable_set_hash(logs[i].value.update.new_hash, i,
+ REFTABLE_HASH_SHA1);
}
for (i = 1; i <= N; i++) {
@@ -927,31 +884,23 @@ static void t_reflog_expire(void)
.log = &logs[i],
.update_index = reftable_stack_next_update_index(st),
};
- int err = reftable_stack_add(st, write_test_log, &arg);
- check(!err);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_log,
+ &arg, 0), 0);
}
- err = reftable_stack_compact_all(st, NULL);
- check(!err);
-
- err = reftable_stack_compact_all(st, &expiry);
- check(!err);
-
- err = reftable_stack_read_log(st, logs[9].refname, &log);
- check_int(err, ==, 1);
-
- err = reftable_stack_read_log(st, logs[11].refname, &log);
- check(!err);
+ cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0);
+ cl_assert_equal_i(reftable_stack_read_log(st, logs[9].refname,
+ &log), 1);
+ cl_assert_equal_i(reftable_stack_read_log(st, logs[11].refname,
+ &log), 0);
expiry.min_update_index = 15;
- err = reftable_stack_compact_all(st, &expiry);
- check(!err);
-
- err = reftable_stack_read_log(st, logs[14].refname, &log);
- check_int(err, ==, 1);
-
- err = reftable_stack_read_log(st, logs[16].refname, &log);
- check(!err);
+ cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0);
+ cl_assert_equal_i(reftable_stack_read_log(st, logs[14].refname,
+ &log), 1);
+ cl_assert_equal_i(reftable_stack_read_log(st, logs[16].refname,
+ &log), 0);
/* cleanup */
reftable_stack_destroy(st);
@@ -963,26 +912,21 @@ static void t_reflog_expire(void)
static int write_nothing(struct reftable_writer *wr, void *arg UNUSED)
{
- check(!reftable_writer_set_limits(wr, 1, 1));
+ cl_assert_equal_i(reftable_writer_set_limits(wr, 1, 1), 0);
return 0;
}
-static void t_empty_add(void)
+void test_reftable_stack__empty_add(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
- int err;
char *dir = get_tmp_dir(__LINE__);
struct reftable_stack *st2 = NULL;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
-
- err = reftable_stack_add(st, write_nothing, NULL);
- check(!err);
-
- err = reftable_new_stack(&st2, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_add(st, write_nothing,
+ NULL, 0), 0);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
clear_dir(dir);
reftable_stack_destroy(st);
reftable_stack_destroy(st2);
@@ -998,18 +942,17 @@ static int fastlogN(uint64_t sz, uint64_t N)
return l - 1;
}
-static void t_reftable_stack_auto_compaction(void)
+void test_reftable_stack__auto_compaction(void)
{
struct reftable_write_options opts = {
.disable_auto_compact = 1,
};
struct reftable_stack *st = NULL;
char *dir = get_tmp_dir(__LINE__);
- int err;
size_t i, N = 100;
+ int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
for (i = 0; i < N; i++) {
char name[100];
@@ -1021,33 +964,32 @@ static void t_reftable_stack_auto_compaction(void)
};
snprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
- err = reftable_stack_add(st, write_test_ref, &ref);
- check(!err);
+ err = reftable_stack_add(st, write_test_ref, &ref, 0);
+ cl_assert(!err);
err = reftable_stack_auto_compact(st);
- check(!err);
- check(i < 2 || st->merged->tables_len < 2 * fastlogN(i, 2));
+ cl_assert(!err);
+ cl_assert(i < 2 || st->merged->tables_len < 2 * fastlogN(i, 2));
}
- check_int(reftable_stack_compaction_stats(st)->entries_written, <,
- (uint64_t)(N * fastlogN(N, 2)));
+ cl_assert(reftable_stack_compaction_stats(st)->entries_written <
+ (uint64_t)(N * fastlogN(N, 2)));
reftable_stack_destroy(st);
clear_dir(dir);
}
-static void t_reftable_stack_auto_compaction_factor(void)
+void test_reftable_stack__auto_compaction_factor(void)
{
struct reftable_write_options opts = {
.auto_compaction_factor = 5,
};
struct reftable_stack *st = NULL;
char *dir = get_tmp_dir(__LINE__);
- int err;
size_t N = 100;
+ int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
for (size_t i = 0; i < N; i++) {
char name[20];
@@ -1058,17 +1000,17 @@ static void t_reftable_stack_auto_compaction_factor(void)
};
xsnprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
- err = reftable_stack_add(st, &write_test_ref, &ref);
- check(!err);
+ err = reftable_stack_add(st, &write_test_ref, &ref, 0);
+ cl_assert(!err);
- check(i < 5 || st->merged->tables_len < 5 * fastlogN(i, 5));
+ cl_assert(i < 5 || st->merged->tables_len < 5 * fastlogN(i, 5));
}
reftable_stack_destroy(st);
clear_dir(dir);
}
-static void t_reftable_stack_auto_compaction_with_locked_tables(void)
+void test_reftable_stack__auto_compaction_with_locked_tables(void)
{
struct reftable_write_options opts = {
.disable_auto_compact = 1,
@@ -1078,21 +1020,20 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void)
char *dir = get_tmp_dir(__LINE__);
int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
write_n_ref_tables(st, 5);
- check_int(st->merged->tables_len, ==, 5);
+ cl_assert_equal_i(st->merged->tables_len, 5);
/*
* Given that all tables we have written should be roughly the same
* size, we expect that auto-compaction will want to compact all of the
* tables. Locking any of the tables will keep it from doing so.
*/
- check(!reftable_buf_addstr(&buf, dir));
- check(!reftable_buf_addstr(&buf, "/"));
- check(!reftable_buf_addstr(&buf, st->tables[2]->name));
- check(!reftable_buf_addstr(&buf, ".lock"));
+ cl_assert(!reftable_buf_addstr(&buf, dir));
+ cl_assert(!reftable_buf_addstr(&buf, "/"));
+ cl_assert(!reftable_buf_addstr(&buf, st->tables[2]->name));
+ cl_assert(!reftable_buf_addstr(&buf, ".lock"));
write_file_buf(buf.buf, "", 0);
/*
@@ -1102,25 +1043,23 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void)
* only compact the newest two tables.
*/
err = reftable_stack_auto_compact(st);
- check(!err);
- check_int(st->stats.failures, ==, 0);
- check_int(st->merged->tables_len, ==, 4);
+ cl_assert(!err);
+ cl_assert_equal_i(st->stats.failures, 0);
+ cl_assert_equal_i(st->merged->tables_len, 4);
reftable_stack_destroy(st);
reftable_buf_release(&buf);
clear_dir(dir);
}
-static void t_reftable_stack_add_performs_auto_compaction(void)
+void test_reftable_stack__add_performs_auto_compaction(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
char *dir = get_tmp_dir(__LINE__);
- int err;
size_t i, n = 20;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
for (i = 0; i <= n; i++) {
struct reftable_ref_record ref = {
@@ -1140,8 +1079,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)
snprintf(buf, sizeof(buf), "branch-%04"PRIuMAX, (uintmax_t)i);
ref.refname = buf;
- err = reftable_stack_add(st, write_test_ref, &ref);
- check(!err);
+ cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
+ &ref, 0), 0);
/*
* The stack length should grow continuously for all runs where
@@ -1149,16 +1088,16 @@ static void t_reftable_stack_add_performs_auto_compaction(void)
* all tables in the stack.
*/
if (i != n)
- check_int(st->merged->tables_len, ==, i + 1);
+ cl_assert_equal_i(st->merged->tables_len, i + 1);
else
- check_int(st->merged->tables_len, ==, 1);
+ cl_assert_equal_i(st->merged->tables_len, 1);
}
reftable_stack_destroy(st);
clear_dir(dir);
}
-static void t_reftable_stack_compaction_with_locked_tables(void)
+void test_reftable_stack__compaction_with_locked_tables(void)
{
struct reftable_write_options opts = {
.disable_auto_compact = 1,
@@ -1168,17 +1107,16 @@ static void t_reftable_stack_compaction_with_locked_tables(void)
char *dir = get_tmp_dir(__LINE__);
int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
write_n_ref_tables(st, 3);
- check_int(st->merged->tables_len, ==, 3);
+ cl_assert_equal_i(st->merged->tables_len, 3);
/* Lock one of the tables that we're about to compact. */
- check(!reftable_buf_addstr(&buf, dir));
- check(!reftable_buf_addstr(&buf, "/"));
- check(!reftable_buf_addstr(&buf, st->tables[1]->name));
- check(!reftable_buf_addstr(&buf, ".lock"));
+ cl_assert(!reftable_buf_addstr(&buf, dir));
+ cl_assert(!reftable_buf_addstr(&buf, "/"));
+ cl_assert(!reftable_buf_addstr(&buf, st->tables[1]->name));
+ cl_assert(!reftable_buf_addstr(&buf, ".lock"));
write_file_buf(buf.buf, "", 0);
/*
@@ -1186,36 +1124,31 @@ static void t_reftable_stack_compaction_with_locked_tables(void)
* compact all tables.
*/
err = reftable_stack_compact_all(st, NULL);
- check_int(err, ==, REFTABLE_LOCK_ERROR);
- check_int(st->stats.failures, ==, 1);
- check_int(st->merged->tables_len, ==, 3);
+ cl_assert_equal_i(err, REFTABLE_LOCK_ERROR);
+ cl_assert_equal_i(st->stats.failures, 1);
+ cl_assert_equal_i(st->merged->tables_len, 3);
reftable_stack_destroy(st);
reftable_buf_release(&buf);
clear_dir(dir);
}
-static void t_reftable_stack_compaction_concurrent(void)
+void test_reftable_stack__compaction_concurrent(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL, *st2 = NULL;
char *dir = get_tmp_dir(__LINE__);
- int err;
- err = reftable_new_stack(&st1, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
write_n_ref_tables(st1, 3);
- err = reftable_new_stack(&st2, dir, &opts);
- check(!err);
-
- err = reftable_stack_compact_all(st1, NULL);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0);
reftable_stack_destroy(st1);
reftable_stack_destroy(st2);
- check_int(count_dir_entries(dir), ==, 2);
+ cl_assert_equal_i(count_dir_entries(dir), 2);
clear_dir(dir);
}
@@ -1228,32 +1161,24 @@ static void unclean_stack_close(struct reftable_stack *st)
REFTABLE_FREE_AND_NULL(st->tables);
}
-static void t_reftable_stack_compaction_concurrent_clean(void)
+void test_reftable_stack__compaction_concurrent_clean(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;
char *dir = get_tmp_dir(__LINE__);
- int err;
- err = reftable_new_stack(&st1, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
write_n_ref_tables(st1, 3);
- err = reftable_new_stack(&st2, dir, &opts);
- check(!err);
-
- err = reftable_stack_compact_all(st1, NULL);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0);
unclean_stack_close(st1);
unclean_stack_close(st2);
- err = reftable_new_stack(&st3, dir, &opts);
- check(!err);
-
- err = reftable_stack_clean(st3);
- check(!err);
- check_int(count_dir_entries(dir), ==, 2);
+ cl_assert_equal_i(reftable_new_stack(&st3, dir, &opts), 0);
+ cl_assert_equal_i(reftable_stack_clean(st3), 0);
+ cl_assert_equal_i(count_dir_entries(dir), 2);
reftable_stack_destroy(st1);
reftable_stack_destroy(st2);
@@ -1262,7 +1187,7 @@ static void t_reftable_stack_compaction_concurrent_clean(void)
clear_dir(dir);
}
-static void t_reftable_stack_read_across_reload(void)
+void test_reftable_stack__read_across_reload(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL, *st2 = NULL;
@@ -1272,37 +1197,35 @@ static void t_reftable_stack_read_across_reload(void)
int err;
/* Create a first stack and set up an iterator for it. */
- err = reftable_new_stack(&st1, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
write_n_ref_tables(st1, 2);
- check_int(st1->merged->tables_len, ==, 2);
+ cl_assert_equal_i(st1->merged->tables_len, 2);
reftable_stack_init_ref_iterator(st1, &it);
- err = reftable_iterator_seek_ref(&it, "");
- check(!err);
+ cl_assert_equal_i(reftable_iterator_seek_ref(&it, ""), 0);
/* Set up a second stack for the same directory and compact it. */
err = reftable_new_stack(&st2, dir, &opts);
- check(!err);
- check_int(st2->merged->tables_len, ==, 2);
+ cl_assert(!err);
+ cl_assert_equal_i(st2->merged->tables_len, 2);
err = reftable_stack_compact_all(st2, NULL);
- check(!err);
- check_int(st2->merged->tables_len, ==, 1);
+ cl_assert(!err);
+ cl_assert_equal_i(st2->merged->tables_len, 1);
/*
* Verify that we can continue to use the old iterator even after we
* have reloaded its stack.
*/
err = reftable_stack_reload(st1);
- check(!err);
- check_int(st1->merged->tables_len, ==, 1);
+ cl_assert(!err);
+ cl_assert_equal_i(st1->merged->tables_len, 1);
err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- check_str(rec.refname, "refs/heads/branch-0000");
+ cl_assert(!err);
+ cl_assert_equal_s(rec.refname, "refs/heads/branch-0000");
err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- check_str(rec.refname, "refs/heads/branch-0001");
+ cl_assert(!err);
+ cl_assert_equal_s(rec.refname, "refs/heads/branch-0001");
err = reftable_iterator_next_ref(&it, &rec);
- check_int(err, >, 0);
+ cl_assert(err > 0);
reftable_ref_record_release(&rec);
reftable_iterator_destroy(&it);
@@ -1311,7 +1234,7 @@ static void t_reftable_stack_read_across_reload(void)
clear_dir(dir);
}
-static void t_reftable_stack_reload_with_missing_table(void)
+void test_reftable_stack__reload_with_missing_table(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
@@ -1322,46 +1245,40 @@ static void t_reftable_stack_reload_with_missing_table(void)
int err;
/* Create a first stack and set up an iterator for it. */
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
write_n_ref_tables(st, 2);
- check_int(st->merged->tables_len, ==, 2);
+ cl_assert_equal_i(st->merged->tables_len, 2);
reftable_stack_init_ref_iterator(st, &it);
- err = reftable_iterator_seek_ref(&it, "");
- check(!err);
+ cl_assert_equal_i(reftable_iterator_seek_ref(&it, ""), 0);
/*
* Update the tables.list file with some garbage data, while reusing
* our old tables. This should trigger a partial reload of the stack,
* where we try to reuse our old tables.
*/
- check(!reftable_buf_addstr(&content, st->tables[0]->name));
- check(!reftable_buf_addstr(&content, "\n"));
- check(!reftable_buf_addstr(&content, st->tables[1]->name));
- check(!reftable_buf_addstr(&content, "\n"));
- check(!reftable_buf_addstr(&content, "garbage\n"));
- check(!reftable_buf_addstr(&table_path, st->list_file));
- check(!reftable_buf_addstr(&table_path, ".lock"));
+ cl_assert(!reftable_buf_addstr(&content, st->tables[0]->name));
+ cl_assert(!reftable_buf_addstr(&content, "\n"));
+ cl_assert(!reftable_buf_addstr(&content, st->tables[1]->name));
+ cl_assert(!reftable_buf_addstr(&content, "\n"));
+ cl_assert(!reftable_buf_addstr(&content, "garbage\n"));
+ cl_assert(!reftable_buf_addstr(&table_path, st->list_file));
+ cl_assert(!reftable_buf_addstr(&table_path, ".lock"));
write_file_buf(table_path.buf, content.buf, content.len);
- err = rename(table_path.buf, st->list_file);
- check(!err);
+ cl_assert_equal_i(rename(table_path.buf, st->list_file), 0);
err = reftable_stack_reload(st);
- check_int(err, ==, -4);
- check_int(st->merged->tables_len, ==, 2);
+ cl_assert_equal_i(err, -4);
+ cl_assert_equal_i(st->merged->tables_len, 2);
/*
* Even though the reload has failed, we should be able to continue
* using the iterator.
*/
- err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- check_str(rec.refname, "refs/heads/branch-0000");
- err = reftable_iterator_next_ref(&it, &rec);
- check(!err);
- check_str(rec.refname, "refs/heads/branch-0001");
- err = reftable_iterator_next_ref(&it, &rec);
- check_int(err, >, 0);
+ cl_assert_equal_i(reftable_iterator_next_ref(&it, &rec), 0);
+ cl_assert_equal_s(rec.refname, "refs/heads/branch-0000");
+ cl_assert_equal_i(reftable_iterator_next_ref(&it, &rec), 0);
+ cl_assert_equal_s(rec.refname, "refs/heads/branch-0001");
+ cl_assert(reftable_iterator_next_ref(&it, &rec) > 0);
reftable_ref_record_release(&rec);
reftable_iterator_destroy(&it);
@@ -1374,12 +1291,13 @@ static void t_reftable_stack_reload_with_missing_table(void)
static int write_limits_after_ref(struct reftable_writer *wr, void *arg)
{
struct reftable_ref_record *ref = arg;
- check(!reftable_writer_set_limits(wr, ref->update_index, ref->update_index));
- check(!reftable_writer_add_ref(wr, ref));
+ cl_assert_equal_i(reftable_writer_set_limits(wr,
+ ref->update_index, ref->update_index), 0);
+ cl_assert_equal_i(reftable_writer_add_ref(wr, ref), 0);
return reftable_writer_set_limits(wr, ref->update_index, ref->update_index);
}
-static void t_reftable_invalid_limit_updates(void)
+void test_reftable_stack__invalid_limit_updates(void)
{
struct reftable_ref_record ref = {
.refname = (char *) "HEAD",
@@ -1393,59 +1311,22 @@ static void t_reftable_invalid_limit_updates(void)
struct reftable_addition *add = NULL;
char *dir = get_tmp_dir(__LINE__);
struct reftable_stack *st = NULL;
- int err;
- err = reftable_new_stack(&st, dir, &opts);
- check(!err);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
reftable_addition_destroy(add);
- err = reftable_stack_new_addition(&add, st, 0);
- check(!err);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0);
/*
* write_limits_after_ref also updates the update indexes after adding
* the record. This should cause an err to be returned, since the limits
* must be set at the start.
*/
- err = reftable_addition_add(add, write_limits_after_ref, &ref);
- check_int(err, ==, REFTABLE_API_ERROR);
+ cl_assert_equal_i(reftable_addition_add(add,
+ write_limits_after_ref, &ref), REFTABLE_API_ERROR);
reftable_addition_destroy(add);
reftable_stack_destroy(st);
clear_dir(dir);
}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_empty_add(), "empty addition to stack");
- TEST(t_read_file(), "read_lines works");
- TEST(t_reflog_expire(), "expire reflog entries");
- TEST(t_reftable_invalid_limit_updates(), "prevent limit updates after adding records");
- TEST(t_reftable_stack_add(), "add multiple refs and logs to stack");
- TEST(t_reftable_stack_add_one(), "add a single ref record to stack");
- TEST(t_reftable_stack_add_performs_auto_compaction(), "addition to stack triggers auto-compaction");
- TEST(t_reftable_stack_auto_compaction(), "stack must form geometric sequence after compaction");
- TEST(t_reftable_stack_auto_compaction_factor(), "auto-compaction with non-default geometric factor");
- TEST(t_reftable_stack_auto_compaction_fails_gracefully(), "failure on auto-compaction");
- TEST(t_reftable_stack_auto_compaction_with_locked_tables(), "auto compaction with locked tables");
- TEST(t_reftable_stack_compaction_concurrent(), "compaction with concurrent stack");
- TEST(t_reftable_stack_compaction_concurrent_clean(), "compaction with unclean stack shutdown");
- TEST(t_reftable_stack_compaction_with_locked_tables(), "compaction with locked tables");
- TEST(t_reftable_stack_hash_id(), "read stack with wrong hash ID");
- TEST(t_reftable_stack_iterator(), "log and ref iterator for reftable stack");
- TEST(t_reftable_stack_lock_failure(), "stack addition with lockfile failure");
- TEST(t_reftable_stack_log_normalize(), "log messages should be normalized");
- TEST(t_reftable_stack_read_across_reload(), "stack iterators work across reloads");
- TEST(t_reftable_stack_reload_with_missing_table(), "stack iteration with garbage tables");
- TEST(t_reftable_stack_tombstone(), "'tombstone' refs in stack");
- TEST(t_reftable_stack_transaction_api(), "update transaction to stack");
- TEST(t_reftable_stack_transaction_with_reload(), "transaction with reload");
- TEST(t_reftable_stack_transaction_api_performs_auto_compaction(), "update transaction triggers auto-compaction");
- TEST(t_reftable_stack_update_index_check(), "update transactions with equal update indices");
- TEST(t_reftable_stack_uptodate(), "stack must be reloaded before ref update");
- TEST(t_suggest_compaction_segment(), "suggest_compaction_segment with basic input");
- TEST(t_suggest_compaction_segment_nothing(), "suggest_compaction_segment with pre-compacted input");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-reftable-table.c b/t/unit-tests/u-reftable-table.c
index 7e1eb533d0..14fae8b199 100644
--- a/t/unit-tests/t-reftable-table.c
+++ b/t/unit-tests/u-reftable-table.c
@@ -1,4 +1,4 @@
-#include "test-lib.h"
+#include "unit-test.h"
#include "lib-reftable.h"
#include "reftable/blocksource.h"
#include "reftable/constants.h"
@@ -6,7 +6,7 @@
#include "reftable/table.h"
#include "strbuf.h"
-static int t_table_seek_once(void)
+void test_reftable_table__seek_once(void)
{
struct reftable_ref_record records[] = {
{
@@ -22,32 +22,32 @@ static int t_table_seek_once(void)
struct reftable_buf buf = REFTABLE_BUF_INIT;
int ret;
- t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
+ cl_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
block_source_from_buf(&source, &buf);
ret = reftable_table_new(&table, &source, "name");
- check(!ret);
+ cl_assert(!ret);
reftable_table_init_ref_iterator(table, &it);
ret = reftable_iterator_seek_ref(&it, "");
- check(!ret);
+ cl_assert(!ret);
ret = reftable_iterator_next_ref(&it, &ref);
- check(!ret);
+ cl_assert(!ret);
- ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1);
- check_int(ret, ==, 1);
+ ret = reftable_ref_record_equal(&ref, &records[0],
+ REFTABLE_HASH_SIZE_SHA1);
+ cl_assert_equal_i(ret, 1);
ret = reftable_iterator_next_ref(&it, &ref);
- check_int(ret, ==, 1);
+ cl_assert_equal_i(ret, 1);
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
reftable_table_decref(table);
reftable_buf_release(&buf);
- return 0;
}
-static int t_table_reseek(void)
+void test_reftable_table__reseek(void)
{
struct reftable_ref_record records[] = {
{
@@ -63,35 +63,35 @@ static int t_table_reseek(void)
struct reftable_buf buf = REFTABLE_BUF_INIT;
int ret;
- t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
+ cl_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records),
+ NULL, 0, NULL);
block_source_from_buf(&source, &buf);
ret = reftable_table_new(&table, &source, "name");
- check(!ret);
+ cl_assert(!ret);
reftable_table_init_ref_iterator(table, &it);
for (size_t i = 0; i < 5; i++) {
ret = reftable_iterator_seek_ref(&it, "");
- check(!ret);
+ cl_assert(!ret);
ret = reftable_iterator_next_ref(&it, &ref);
- check(!ret);
+ cl_assert(!ret);
ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1);
- check_int(ret, ==, 1);
+ cl_assert_equal_i(ret, 1);
ret = reftable_iterator_next_ref(&it, &ref);
- check_int(ret, ==, 1);
+ cl_assert_equal_i(ret, 1);
}
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
reftable_table_decref(table);
reftable_buf_release(&buf);
- return 0;
}
-static int t_table_block_iterator(void)
+void test_reftable_table__block_iterator(void)
{
struct reftable_block_source source = { 0 };
struct reftable_table_iterator it = { 0 };
@@ -147,14 +147,14 @@ static int t_table_block_iterator(void)
(uintmax_t) i);
}
- t_reftable_write_to_buf(&buf, records, nrecords, NULL, 0, NULL);
+ cl_reftable_write_to_buf(&buf, records, nrecords, NULL, 0, NULL);
block_source_from_buf(&source, &buf);
ret = reftable_table_new(&table, &source, "name");
- check(!ret);
+ cl_assert(!ret);
ret = reftable_table_iterator_init(&it, table);
- check(!ret);
+ cl_assert(!ret);
for (size_t i = 0; i < ARRAY_SIZE(expected_blocks); i++) {
struct reftable_iterator record_it = { 0 };
@@ -163,22 +163,26 @@ static int t_table_block_iterator(void)
};
ret = reftable_table_iterator_next(&it, &block);
- check(!ret);
+ cl_assert(!ret);
- check_int(block->block_type, ==, expected_blocks[i].block_type);
- check_int(block->header_off, ==, expected_blocks[i].header_off);
- check_int(block->restart_count, ==, expected_blocks[i].restart_count);
+ cl_assert_equal_i(block->block_type,
+ expected_blocks[i].block_type);
+ cl_assert_equal_i(block->header_off,
+ expected_blocks[i].header_off);
+ cl_assert_equal_i(block->restart_count,
+ expected_blocks[i].restart_count);
ret = reftable_block_init_iterator(block, &record_it);
- check(!ret);
+ cl_assert(!ret);
for (size_t j = 0; ; j++) {
ret = iterator_next(&record_it, &record);
if (ret > 0) {
- check_int(j, ==, expected_blocks[i].record_count);
+ cl_assert_equal_i(j,
+ expected_blocks[i].record_count);
break;
}
- check(!ret);
+ cl_assert(!ret);
}
reftable_iterator_destroy(&record_it);
@@ -186,7 +190,7 @@ static int t_table_block_iterator(void)
}
ret = reftable_table_iterator_next(&it, &block);
- check_int(ret, ==, 1);
+ cl_assert_equal_i(ret, 1);
for (size_t i = 0; i < nrecords; i++)
reftable_free(records[i].refname);
@@ -194,13 +198,4 @@ static int t_table_block_iterator(void)
reftable_table_decref(table);
reftable_buf_release(&buf);
reftable_free(records);
- return 0;
-}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_table_seek_once(), "table can seek once");
- TEST(t_table_reseek(), "table can reseek multiple times");
- TEST(t_table_block_iterator(), "table can iterate through blocks");
- return test_done();
}
diff --git a/t/unit-tests/u-string-list.c b/t/unit-tests/u-string-list.c
new file mode 100644
index 0000000000..a2457d7b1e
--- /dev/null
+++ b/t/unit-tests/u-string-list.c
@@ -0,0 +1,306 @@
+#include "unit-test.h"
+#include "string-list.h"
+
+static void t_vcreate_string_list_dup(struct string_list *list,
+ int free_util, va_list ap)
+{
+ const char *arg;
+
+ cl_assert(list->strdup_strings);
+
+ string_list_clear(list, free_util);
+ while ((arg = va_arg(ap, const char *)))
+ string_list_append(list, arg);
+}
+
+static void t_create_string_list_dup(struct string_list *list, int free_util, ...)
+{
+ va_list ap;
+
+ cl_assert(list->strdup_strings);
+
+ string_list_clear(list, free_util);
+ va_start(ap, free_util);
+ t_vcreate_string_list_dup(list, free_util, ap);
+ va_end(ap);
+}
+
+static void t_string_list_clear(struct string_list *list, int free_util)
+{
+ string_list_clear(list, free_util);
+ cl_assert_equal_p(list->items, NULL);
+ cl_assert_equal_i(list->nr, 0);
+ cl_assert_equal_i(list->alloc, 0);
+}
+
+static void t_string_list_equal(struct string_list *list,
+ struct string_list *expected_strings)
+{
+ cl_assert_equal_i(list->nr, expected_strings->nr);
+ cl_assert(list->nr <= list->alloc);
+ for (size_t i = 0; i < expected_strings->nr; i++)
+ cl_assert_equal_s(list->items[i].string,
+ expected_strings->items[i].string);
+}
+
+static void t_string_list_split(const char *data, const char *delim, int maxsplit, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_DUP;
+ va_list ap;
+ int len;
+
+ va_start(ap, maxsplit);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split(&list, data, delim, maxsplit);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+static void t_string_list_split_f(const char *data, const char *delim,
+ int maxsplit, unsigned flags, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_DUP;
+ va_list ap;
+ int len;
+
+ va_start(ap, flags);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split_f(&list, data, delim, maxsplit, flags);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+void test_string_list__split_f(void)
+{
+ t_string_list_split_f("::foo:bar:baz:", ":", -1, 0,
+ "", "", "foo", "bar", "baz", "", NULL);
+ t_string_list_split_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM,
+ "foo", "bar", "baz", NULL);
+ t_string_list_split_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM,
+ "a", "b c", NULL);
+ t_string_list_split_f("::foo::bar:baz:", ":", -1, STRING_LIST_SPLIT_NONEMPTY,
+ "foo", "bar", "baz", NULL);
+ t_string_list_split_f("foo:baz", ":", -1, STRING_LIST_SPLIT_NONEMPTY,
+ "foo", "baz", NULL);
+ t_string_list_split_f("foo :: : baz", ":", -1,
+ STRING_LIST_SPLIT_NONEMPTY | STRING_LIST_SPLIT_TRIM,
+ "foo", "baz", NULL);
+}
+
+static void t_string_list_split_in_place_f(const char *data_, const char *delim,
+ int maxsplit, unsigned flags, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_NODUP;
+ char *data = xstrdup(data_);
+ va_list ap;
+ int len;
+
+ va_start(ap, flags);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split_in_place_f(&list, data, delim, maxsplit, flags);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ free(data);
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+void test_string_list__split_in_place_f(void)
+{
+ t_string_list_split_in_place_f("::foo:bar:baz:", ":", -1, 0,
+ "", "", "foo", "bar", "baz", "", NULL);
+ t_string_list_split_in_place_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM,
+ "foo", "bar", "baz", NULL);
+ t_string_list_split_in_place_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM,
+ "a", "b c", NULL);
+ t_string_list_split_in_place_f("::foo::bar:baz:", ":", -1,
+ STRING_LIST_SPLIT_NONEMPTY,
+ "foo", "bar", "baz", NULL);
+ t_string_list_split_in_place_f("foo:baz", ":", -1, STRING_LIST_SPLIT_NONEMPTY,
+ "foo", "baz", NULL);
+ t_string_list_split_in_place_f("foo :: : baz", ":", -1,
+ STRING_LIST_SPLIT_NONEMPTY | STRING_LIST_SPLIT_TRIM,
+ "foo", "baz", NULL);
+}
+
+void test_string_list__split(void)
+{
+ t_string_list_split("foo:bar:baz", ":", -1, "foo", "bar", "baz", NULL);
+ t_string_list_split("foo:bar:baz", ":", 0, "foo:bar:baz", NULL);
+ t_string_list_split("foo:bar:baz", ":", 1, "foo", "bar:baz", NULL);
+ t_string_list_split("foo:bar:baz", ":", 2, "foo", "bar", "baz", NULL);
+ t_string_list_split("foo:bar:", ":", -1, "foo", "bar", "", NULL);
+ t_string_list_split("", ":", -1, "", NULL);
+ t_string_list_split(":", ":", -1, "", "", NULL);
+}
+
+static void t_string_list_split_in_place(const char *data, const char *delim,
+ int maxsplit, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_NODUP;
+ char *string = xstrdup(data);
+ va_list ap;
+ int len;
+
+ va_start(ap, maxsplit);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split_in_place(&list, string, delim, maxsplit);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ free(string);
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+void test_string_list__split_in_place(void)
+{
+ t_string_list_split_in_place("foo:;:bar:;:baz:;:", ":;", -1,
+ "foo", "", "", "bar", "", "", "baz", "", "", "", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 0,
+ "foo:;:bar:;:baz", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 1,
+ "foo", ";:bar:;:baz", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 2,
+ "foo", "", ":bar:;:baz", NULL);
+ t_string_list_split_in_place("foo:;:bar:;:", ":;", -1,
+ "foo", "", "", "bar", "", "", "", NULL);
+}
+
+static int prefix_cb(struct string_list_item *item, void *cb_data)
+{
+ const char *prefix = (const char *)cb_data;
+ return starts_with(item->string, prefix);
+}
+
+static void t_string_list_filter(struct string_list *list, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ const char *prefix = "y";
+ va_list ap;
+
+ va_start(ap, list);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ filter_string_list(list, 0, prefix_cb, (void *)prefix);
+ t_string_list_equal(list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+}
+
+void test_string_list__filter(void)
+{
+ struct string_list list = STRING_LIST_INIT_DUP;
+
+ t_create_string_list_dup(&list, 0, NULL);
+ t_string_list_filter(&list, NULL);
+
+ t_create_string_list_dup(&list, 0, "no", NULL);
+ t_string_list_filter(&list, NULL);
+
+ t_create_string_list_dup(&list, 0, "yes", NULL);
+ t_string_list_filter(&list, "yes", NULL);
+
+ t_create_string_list_dup(&list, 0, "no", "yes", NULL);
+ t_string_list_filter(&list, "yes", NULL);
+
+ t_create_string_list_dup(&list, 0, "yes", "no", NULL);
+ t_string_list_filter(&list, "yes", NULL);
+
+ t_create_string_list_dup(&list, 0, "y1", "y2", NULL);
+ t_string_list_filter(&list, "y1", "y2", NULL);
+
+ t_create_string_list_dup(&list, 0, "y2", "y1", NULL);
+ t_string_list_filter(&list, "y2", "y1", NULL);
+
+ t_create_string_list_dup(&list, 0, "x1", "x2", NULL);
+ t_string_list_filter(&list, NULL);
+
+ t_string_list_clear(&list, 0);
+}
+
+static void t_string_list_remove_duplicates(struct string_list *list, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ va_list ap;
+
+ va_start(ap, list);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_remove_duplicates(list, 0);
+ t_string_list_equal(list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+}
+
+void test_string_list__remove_duplicates(void)
+{
+ struct string_list list = STRING_LIST_INIT_DUP;
+
+ t_create_string_list_dup(&list, 0, NULL);
+ t_string_list_remove_duplicates(&list, NULL);
+
+ t_create_string_list_dup(&list, 0, "", NULL);
+ t_string_list_remove_duplicates(&list, "", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", NULL);
+ t_string_list_remove_duplicates(&list, "a", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", NULL);
+ t_string_list_remove_duplicates(&list, "a", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "a", NULL);
+ t_string_list_remove_duplicates(&list, "a", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "b", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "b", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "b", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "b", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "b", "c", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "b", "b", "c", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_create_string_list_dup(&list, 0, "a", "a", "a", "b", "b", "b",
+ "c", "c", "c", NULL);
+ t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
+
+ t_string_list_clear(&list, 0);
+}
diff --git a/t/unit-tests/unit-test.h b/t/unit-tests/unit-test.h
index 85e5d6a948..39a0b72a05 100644
--- a/t/unit-tests/unit-test.h
+++ b/t/unit-tests/unit-test.h
@@ -1,8 +1,13 @@
#include "git-compat-util.h"
#include "clar/clar.h"
-#include "clar-decls.h"
#include "strbuf.h"
+#ifndef GIT_CLAR_DECLS_H
+# include "clar-decls.h"
+#else
+# include GIT_CLAR_DECLS_H
+#endif
+
#define cl_failf(fmt, ...) do { \
char desc[4096]; \
snprintf(desc, sizeof(desc), fmt, __VA_ARGS__); \