summaryrefslogtreecommitdiff
path: root/t/unit-tests
diff options
context:
space:
mode:
Diffstat (limited to 't/unit-tests')
-rw-r--r--t/unit-tests/clar-generate.awk50
-rw-r--r--t/unit-tests/clar/.editorconfig13
-rw-r--r--t/unit-tests/clar/.github/workflows/ci.yml20
-rw-r--r--t/unit-tests/clar/.gitignore1
-rw-r--r--t/unit-tests/clar/CMakeLists.txt28
-rw-r--r--t/unit-tests/clar/clar.c127
-rw-r--r--t/unit-tests/clar/clar/print.h11
-rw-r--r--t/unit-tests/clar/clar/sandbox.h17
-rw-r--r--t/unit-tests/clar/clar/summary.h14
-rw-r--r--t/unit-tests/clar/test/.gitignore4
-rw-r--r--t/unit-tests/clar/test/CMakeLists.txt39
-rw-r--r--t/unit-tests/clar/test/Makefile39
-rwxr-xr-xt/unit-tests/generate-clar-decls.sh20
-rwxr-xr-xt/unit-tests/generate-clar-suites.sh63
-rw-r--r--t/unit-tests/lib-reftable.c7
-rw-r--r--t/unit-tests/lib-reftable.h2
-rw-r--r--t/unit-tests/t-example-decorate.c74
-rw-r--r--t/unit-tests/t-mem-pool.c31
-rw-r--r--t/unit-tests/t-prio-queue.c91
-rw-r--r--t/unit-tests/t-reftable-basics.c58
-rw-r--r--t/unit-tests/t-reftable-block.c41
-rw-r--r--t/unit-tests/t-reftable-merged.c103
-rw-r--r--t/unit-tests/t-reftable-pq.c3
-rw-r--r--t/unit-tests/t-reftable-reader.c4
-rw-r--r--t/unit-tests/t-reftable-readwrite.c98
-rw-r--r--t/unit-tests/t-reftable-record.c76
-rw-r--r--t/unit-tests/t-reftable-stack.c47
-rw-r--r--t/unit-tests/t-strbuf.c122
-rw-r--r--t/unit-tests/t-strcmp-offset.c35
-rw-r--r--t/unit-tests/t-trailer.c2
-rw-r--r--t/unit-tests/test-lib.c2
-rw-r--r--t/unit-tests/u-ctype.c (renamed from t/unit-tests/ctype.c)0
-rw-r--r--t/unit-tests/u-example-decorate.c64
-rw-r--r--t/unit-tests/u-hash.c (renamed from t/unit-tests/t-hash.c)77
-rw-r--r--t/unit-tests/u-hashmap.c (renamed from t/unit-tests/t-hashmap.c)226
-rw-r--r--t/unit-tests/u-mem-pool.c25
-rw-r--r--t/unit-tests/u-prio-queue.c94
-rw-r--r--t/unit-tests/u-reftable-tree.c (renamed from t/unit-tests/t-reftable-tree.c)30
-rw-r--r--t/unit-tests/u-strbuf.c119
-rw-r--r--t/unit-tests/u-strcmp-offset.c45
-rw-r--r--t/unit-tests/u-strvec.c (renamed from t/unit-tests/strvec.c)75
-rw-r--r--t/unit-tests/unit-test.c19
42 files changed, 1213 insertions, 803 deletions
diff --git a/t/unit-tests/clar-generate.awk b/t/unit-tests/clar-generate.awk
deleted file mode 100644
index ab71ce6c9f..0000000000
--- a/t/unit-tests/clar-generate.awk
+++ /dev/null
@@ -1,50 +0,0 @@
-function add_suite(suite, initialize, cleanup, count) {
- if (!suite) return
- suite_count++
- callback_count += count
- suites = suites " {\n"
- suites = suites " \"" suite "\",\n"
- suites = suites " " initialize ",\n"
- suites = suites " " cleanup ",\n"
- suites = suites " _clar_cb_" suite ", " count ", 1\n"
- suites = suites " },\n"
-}
-
-BEGIN {
- suites = "static struct clar_suite _clar_suites[] = {\n"
-}
-
-{
- print
- name = $3; sub(/\(.*$/, "", name)
- suite = name; sub(/^test_/, "", suite); sub(/__.*$/, "", suite)
- short_name = name; sub(/^.*__/, "", short_name)
- cb = "{ \"" short_name "\", &" name " }"
- if (suite != prev_suite) {
- add_suite(prev_suite, initialize, cleanup, count)
- if (callbacks) callbacks = callbacks "};\n"
- callbacks = callbacks "static const struct clar_func _clar_cb_" suite "[] = {\n"
- initialize = "{ NULL, NULL }"
- cleanup = "{ NULL, NULL }"
- count = 0
- prev_suite = suite
- }
- if (short_name == "initialize") {
- initialize = cb
- } else if (short_name == "cleanup") {
- cleanup = cb
- } else {
- callbacks = callbacks " " cb ",\n"
- count++
- }
-}
-
-END {
- add_suite(suite, initialize, cleanup, count)
- suites = suites "};"
- if (callbacks) callbacks = callbacks "};"
- print callbacks
- print suites
- print "static const size_t _clar_suite_count = " suite_count ";"
- print "static const size_t _clar_callback_count = " callback_count ";"
-}
diff --git a/t/unit-tests/clar/.editorconfig b/t/unit-tests/clar/.editorconfig
new file mode 100644
index 0000000000..aa343a4288
--- /dev/null
+++ b/t/unit-tests/clar/.editorconfig
@@ -0,0 +1,13 @@
+root = true
+
+[*]
+charset = utf-8
+insert_final_newline = true
+
+[*.{c,h}]
+indent_style = tab
+tab_width = 8
+
+[CMakeLists.txt]
+indent_style = tab
+tab_width = 8
diff --git a/t/unit-tests/clar/.github/workflows/ci.yml b/t/unit-tests/clar/.github/workflows/ci.yml
index b1ac2de460..0065843d17 100644
--- a/t/unit-tests/clar/.github/workflows/ci.yml
+++ b/t/unit-tests/clar/.github/workflows/ci.yml
@@ -10,14 +10,26 @@ jobs:
build:
strategy:
matrix:
- os: [ ubuntu-latest, macos-latest ]
+ platform:
+ - os: ubuntu-latest
+ generator: Unix Makefiles
+ - os: macos-latest
+ generator: Unix Makefiles
+ - os: windows-latest
+ generator: Visual Studio 17 2022
+ - os: windows-latest
+ generator: MSYS Makefiles
+ - os: windows-latest
+ generator: MinGW Makefiles
- runs-on: ${{ matrix.os }}
+ runs-on: ${{ matrix.platform.os }}
steps:
- name: Check out
uses: actions/checkout@v2
- name: Build
run: |
- cd test
- make
+ mkdir build
+ cd build
+ cmake .. -G "${{matrix.platform.generator}}"
+ cmake --build .
diff --git a/t/unit-tests/clar/.gitignore b/t/unit-tests/clar/.gitignore
new file mode 100644
index 0000000000..84c048a73c
--- /dev/null
+++ b/t/unit-tests/clar/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/t/unit-tests/clar/CMakeLists.txt b/t/unit-tests/clar/CMakeLists.txt
new file mode 100644
index 0000000000..12d4af114f
--- /dev/null
+++ b/t/unit-tests/clar/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 3.16..3.29)
+
+project(clar LANGUAGES C)
+
+option(BUILD_TESTS "Build test executable" ON)
+
+add_library(clar INTERFACE)
+target_sources(clar INTERFACE
+ clar.c
+ clar.h
+ clar/fixtures.h
+ clar/fs.h
+ clar/print.h
+ clar/sandbox.h
+ clar/summary.h
+)
+set_target_properties(clar PROPERTIES
+ C_STANDARD 90
+ C_STANDARD_REQUIRED ON
+ C_EXTENSIONS OFF
+)
+
+if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
+ include(CTest)
+ if(BUILD_TESTING)
+ add_subdirectory(test)
+ endif()
+endif()
diff --git a/t/unit-tests/clar/clar.c b/t/unit-tests/clar/clar.c
index cef0f023c2..d54e455367 100644
--- a/t/unit-tests/clar/clar.c
+++ b/t/unit-tests/clar/clar.c
@@ -4,7 +4,12 @@
* This file is part of clar, distributed under the ISC license.
* For full terms see the included COPYING file.
*/
-#include <assert.h>
+
+#define _BSD_SOURCE
+#define _DARWIN_C_SOURCE
+#define _DEFAULT_SOURCE
+
+#include <errno.h>
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
@@ -13,11 +18,22 @@
#include <stdarg.h>
#include <wchar.h>
#include <time.h>
+#include <inttypes.h>
/* required for sandboxing */
#include <sys/types.h>
#include <sys/stat.h>
+#if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_WCHAR__)
+ /*
+ * uClibc can optionally be built without wchar support, in which case
+ * the installed <wchar.h> is a stub that only defines the `whar_t`
+ * type but none of the functions typically declared by it.
+ */
+#else
+# define CLAR_HAVE_WCHAR
+#endif
+
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
@@ -28,6 +44,9 @@
# ifndef stat
# define stat(path, st) _stat(path, st)
+ typedef struct _stat STAT_T;
+# else
+ typedef struct stat STAT_T;
# endif
# ifndef mkdir
# define mkdir(path, mode) _mkdir(path)
@@ -60,30 +79,11 @@
# else
# define p_snprintf snprintf
# endif
-
-# ifndef PRIuZ
-# define PRIuZ "Iu"
-# endif
-# ifndef PRIxZ
-# define PRIxZ "Ix"
-# endif
-
-# if defined(_MSC_VER) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
- typedef struct stat STAT_T;
-# else
- typedef struct _stat STAT_T;
-# endif
#else
# include <sys/wait.h> /* waitpid(2) */
# include <unistd.h>
# define _MAIN_CC
# define p_snprintf snprintf
-# ifndef PRIuZ
-# define PRIuZ "zu"
-# endif
-# ifndef PRIxZ
-# define PRIxZ "zx"
-# endif
typedef struct stat STAT_T;
#endif
@@ -102,7 +102,7 @@ fixture_path(const char *base, const char *fixture_name);
struct clar_error {
const char *file;
const char *function;
- size_t line_number;
+ uintmax_t line_number;
const char *error_msg;
char *description;
@@ -195,11 +195,12 @@ 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);
static void clar_print_onsuite(const char *suite_name, int suite_index);
+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 int clar_sandbox(void);
+static void clar_sandbox(void);
/* From summary.h */
static struct clar_summary *clar_summary_init(const char *filename);
@@ -218,6 +219,15 @@ static int clar_summary_shutdown(struct clar_summary *fp);
_clar.trace_payload); \
} while (0)
+static void clar_abort(const char *msg, ...)
+{
+ va_list argp;
+ va_start(argp, msg);
+ clar_print_onabortv(msg, argp);
+ va_end(argp);
+ exit(-1);
+}
+
void cl_trace_register(cl_trace_cb *cb, void *payload)
{
_clar.pfn_trace_cb = cb;
@@ -271,9 +281,7 @@ static double clar_time_diff(clar_time *start, clar_time *end)
static void clar_time_now(clar_time *out)
{
- struct timezone tz;
-
- gettimeofday(out, &tz);
+ gettimeofday(out, NULL);
}
static double clar_time_diff(clar_time *start, clar_time *end)
@@ -386,7 +394,8 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
_clar.active_test = test[i].name;
- report = calloc(1, sizeof(struct clar_report));
+ if ((report = calloc(1, sizeof(*report))) == NULL)
+ clar_abort("Failed to allocate report.\n");
report->suite = _clar.active_suite;
report->test = _clar.active_test;
report->test_number = _clar.tests_ran;
@@ -479,9 +488,10 @@ clar_parse_args(int argc, char **argv)
switch (action) {
case 's': {
- struct clar_explicit *explicit =
- calloc(1, sizeof(struct clar_explicit));
- assert(explicit);
+ struct clar_explicit *explicit;
+
+ if ((explicit = calloc(1, sizeof(*explicit))) == NULL)
+ clar_abort("Failed to allocate explicit test.\n");
explicit->suite_idx = j;
explicit->filter = argument;
@@ -505,10 +515,8 @@ clar_parse_args(int argc, char **argv)
}
}
- if (!found) {
- clar_print_onabort("No suite matching '%s' found.\n", argument);
- exit(-1);
- }
+ if (!found)
+ clar_abort("No suite matching '%s' found.\n", argument);
break;
}
@@ -540,11 +548,17 @@ clar_parse_args(int argc, char **argv)
case 'r':
_clar.write_summary = 1;
free(_clar.summary_filename);
- _clar.summary_filename = *(argument + 2) ? strdup(argument + 2) : NULL;
+ 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:
- assert(!"Unexpected commandline argument!");
+ clar_abort("Unexpected commandline argument '%s'.\n",
+ argument[1]);
}
}
}
@@ -566,22 +580,18 @@ clar_test_init(int argc, char **argv)
if (!_clar.summary_filename &&
(summary_env = getenv("CLAR_SUMMARY")) != NULL) {
_clar.write_summary = 1;
- _clar.summary_filename = strdup(summary_env);
+ if ((_clar.summary_filename = strdup(summary_env)) == NULL)
+ clar_abort("Failed to allocate summary filename.\n");
}
if (_clar.write_summary && !_clar.summary_filename)
- _clar.summary_filename = strdup("summary.xml");
+ if ((_clar.summary_filename = strdup("summary.xml")) == NULL)
+ clar_abort("Failed to allocate summary filename.\n");
- if (_clar.write_summary &&
- !(_clar.summary = clar_summary_init(_clar.summary_filename))) {
- clar_print_onabort("Failed to open the summary file\n");
- exit(-1);
- }
+ if (_clar.write_summary)
+ _clar.summary = clar_summary_init(_clar.summary_filename);
- if (clar_sandbox() < 0) {
- clar_print_onabort("Failed to sandbox the test runner.\n");
- exit(-1);
- }
+ clar_sandbox();
}
int
@@ -615,10 +625,9 @@ clar_test_shutdown(void)
clar_unsandbox();
- if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) {
- clar_print_onabort("Failed to write the summary file\n");
- exit(-1);
- }
+ if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0)
+ clar_abort("Failed to write the summary file '%s: %s.\n",
+ _clar.summary_filename, strerror(errno));
for (explicit = _clar.explicit; explicit; explicit = explicit_next) {
explicit_next = explicit->next;
@@ -649,7 +658,7 @@ static void abort_test(void)
{
if (!_clar.trampoline_enabled) {
clar_print_onabort(
- "Fatal error: a cleanup method raised an exception.");
+ "Fatal error: a cleanup method raised an exception.\n");
clar_report_errors(_clar.last_report);
exit(-1);
}
@@ -673,7 +682,10 @@ void clar__fail(
const char *description,
int should_abort)
{
- struct clar_error *error = calloc(1, sizeof(struct clar_error));
+ struct clar_error *error;
+
+ if ((error = calloc(1, sizeof(*error))) == NULL)
+ clar_abort("Failed to allocate error.\n");
if (_clar.last_report->errors == NULL)
_clar.last_report->errors = error;
@@ -688,8 +700,9 @@ void clar__fail(
error->line_number = line;
error->error_msg = error_msg;
- if (description != NULL)
- error->description = strdup(description);
+ if (description != NULL &&
+ (error->description = strdup(description)) == NULL)
+ clar_abort("Failed to allocate description.\n");
_clar.total_errors++;
_clar.last_report->status = CL_TEST_FAILURE;
@@ -763,6 +776,7 @@ void clar__assert_equal(
}
}
}
+#ifdef CLAR_HAVE_WCHAR
else if (!strcmp("%ls", fmt)) {
const wchar_t *wcs1 = va_arg(args, const wchar_t *);
const wchar_t *wcs2 = va_arg(args, const wchar_t *);
@@ -798,8 +812,9 @@ void clar__assert_equal(
}
}
}
- else if (!strcmp("%"PRIuZ, fmt) || !strcmp("%"PRIxZ, fmt)) {
- size_t sz1 = va_arg(args, size_t), sz2 = va_arg(args, size_t);
+#endif /* CLAR_HAVE_WCHAR */
+ else if (!strcmp("%"PRIuMAX, fmt) || !strcmp("%"PRIxMAX, fmt)) {
+ uintmax_t sz1 = va_arg(args, uintmax_t), sz2 = va_arg(args, uintmax_t);
is_equal = (sz1 == sz2);
if (!is_equal) {
int offset = p_snprintf(buf, sizeof(buf), fmt, sz1);
diff --git a/t/unit-tests/clar/clar/print.h b/t/unit-tests/clar/clar/print.h
index c17e2f693b..69d0ee967e 100644
--- a/t/unit-tests/clar/clar/print.h
+++ b/t/unit-tests/clar/clar/print.h
@@ -21,7 +21,7 @@ static void clar_print_clap_error(int num, const struct clar_report *report, con
{
printf(" %d) Failure:\n", num);
- printf("%s::%s [%s:%"PRIuZ"]\n",
+ printf("%s::%s [%s:%"PRIuMAX"]\n",
report->suite,
report->test,
error->file,
@@ -136,7 +136,7 @@ static void clar_print_tap_ontest(const char *suite_name, const char *test_name,
printf(" at:\n");
printf(" file: '"); print_escaped(error->file); printf("'\n");
- printf(" line: %" PRIuZ "\n", error->line_number);
+ printf(" line: %" PRIuMAX "\n", error->line_number);
printf(" function: '%s'\n", error->function);
printf(" ---\n");
@@ -202,10 +202,15 @@ static void clar_print_onsuite(const char *suite_name, int suite_index)
PRINT(onsuite, suite_name, suite_index);
}
+static void clar_print_onabortv(const char *msg, va_list argp)
+{
+ PRINT(onabort, msg, argp);
+}
+
static void clar_print_onabort(const char *msg, ...)
{
va_list argp;
va_start(argp, msg);
- PRINT(onabort, msg, argp);
+ clar_print_onabortv(msg, argp);
va_end(argp);
}
diff --git a/t/unit-tests/clar/clar/sandbox.h b/t/unit-tests/clar/clar/sandbox.h
index e25057b7c4..bc960f50e0 100644
--- a/t/unit-tests/clar/clar/sandbox.h
+++ b/t/unit-tests/clar/clar/sandbox.h
@@ -122,14 +122,14 @@ static int build_sandbox_path(void)
if (mkdir(_clar_path, 0700) != 0)
return -1;
-#elif defined(__TANDEM)
- if (mktemp(_clar_path) == NULL)
+#elif defined(_WIN32)
+ if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0)
return -1;
if (mkdir(_clar_path, 0700) != 0)
return -1;
-#elif defined(_WIN32)
- if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0)
+#elif defined(__sun) || defined(__TANDEM)
+ if (mktemp(_clar_path) == NULL)
return -1;
if (mkdir(_clar_path, 0700) != 0)
@@ -142,15 +142,14 @@ static int build_sandbox_path(void)
return 0;
}
-static int clar_sandbox(void)
+static void clar_sandbox(void)
{
if (_clar_path[0] == '\0' && build_sandbox_path() < 0)
- return -1;
+ clar_abort("Failed to build sandbox path.\n");
if (chdir(_clar_path) != 0)
- return -1;
-
- return 0;
+ clar_abort("Failed to change into sandbox directory '%s': %s.\n",
+ _clar_path, strerror(errno));
}
const char *clar_sandbox_path(void)
diff --git a/t/unit-tests/clar/clar/summary.h b/t/unit-tests/clar/clar/summary.h
index 4dd352e28b..0d0b646fe7 100644
--- a/t/unit-tests/clar/clar/summary.h
+++ b/t/unit-tests/clar/clar/summary.h
@@ -66,16 +66,12 @@ struct clar_summary *clar_summary_init(const char *filename)
struct clar_summary *summary;
FILE *fp;
- if ((fp = fopen(filename, "w")) == NULL) {
- perror("fopen");
- return NULL;
- }
+ if ((fp = fopen(filename, "w")) == NULL)
+ clar_abort("Failed to open the summary file '%s': %s.\n",
+ filename, strerror(errno));
- if ((summary = malloc(sizeof(struct clar_summary))) == NULL) {
- perror("malloc");
- fclose(fp);
- return NULL;
- }
+ if ((summary = malloc(sizeof(struct clar_summary))) == NULL)
+ clar_abort("Failed to allocate summary.\n");
summary->filename = filename;
summary->fp = fp;
diff --git a/t/unit-tests/clar/test/.gitignore b/t/unit-tests/clar/test/.gitignore
deleted file mode 100644
index a477d0c40c..0000000000
--- a/t/unit-tests/clar/test/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-clar.suite
-.clarcache
-clar_test
-*.o
diff --git a/t/unit-tests/clar/test/CMakeLists.txt b/t/unit-tests/clar/test/CMakeLists.txt
new file mode 100644
index 0000000000..7f2c1dc17a
--- /dev/null
+++ b/t/unit-tests/clar/test/CMakeLists.txt
@@ -0,0 +1,39 @@
+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
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+add_executable(clar_test)
+set_target_properties(clar_test 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(clar_test PROPERTIES
+ COMPILE_WARNING_AS_ERROR ON
+ )
+endif()
+
+target_sources(clar_test PRIVATE
+ main.c
+ sample.c
+ "${CMAKE_CURRENT_BINARY_DIR}/clar.suite"
+)
+target_compile_definitions(clar_test PRIVATE
+ CLAR_FIXTURE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/"
+)
+target_compile_options(clar_test PRIVATE
+ $<IF:$<CXX_COMPILER_ID:MSVC>,/W4,-Wall>
+)
+target_include_directories(clar_test PRIVATE
+ "${CMAKE_SOURCE_DIR}"
+ "${CMAKE_CURRENT_BINARY_DIR}"
+)
+target_link_libraries(clar_test clar)
diff --git a/t/unit-tests/clar/test/Makefile b/t/unit-tests/clar/test/Makefile
deleted file mode 100644
index 93c6b2ad32..0000000000
--- a/t/unit-tests/clar/test/Makefile
+++ /dev/null
@@ -1,39 +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.
-#
-
-#
-# Set up the path to the clar sources and to the fixtures directory
-#
-# The fixture path needs to be an absolute path so it can be used
-# even after we have chdir'ed into the test directory while testing.
-#
-CURRENT_MAKEFILE := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
-TEST_DIRECTORY := $(abspath $(dir $(CURRENT_MAKEFILE)))
-CLAR_PATH := $(dir $(TEST_DIRECTORY))
-CLAR_FIXTURE_PATH := $(TEST_DIRECTORY)/resources/
-
-CFLAGS=-g -I.. -I. -Wall -DCLAR_FIXTURE_PATH=\"$(CLAR_FIXTURE_PATH)\"
-
-.PHONY: clean
-
-# list the objects that go into our test
-objects = main.o sample.o
-
-# build the test executable itself
-clar_test: $(objects) clar_test.h clar.suite $(CLAR_PATH)clar.c
- $(CC) $(CFLAGS) -o $@ "$(CLAR_PATH)clar.c" $(objects)
-
-# test object files depend on clar macros
-$(objects) : $(CLAR_PATH)clar.h
-
-# build the clar.suite file of test metadata
-clar.suite:
- python "$(CLAR_PATH)generate.py" .
-
-# remove all generated files
-clean:
- $(RM) -rf *.o clar.suite .clarcache clar_test clar_test.dSYM
diff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh
new file mode 100755
index 0000000000..abf6a2ea2a
--- /dev/null
+++ b/t/unit-tests/generate-clar-decls.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+if test $# -lt 2
+then
+ echo "USAGE: $0 <OUTPUT> <SUITE>..." 2>&1
+ exit 1
+fi
+
+OUTPUT="$1"
+shift
+
+for suite in "$@"
+do
+ suite_name=$(basename "$suite")
+ suite_name=${suite_name%.c}
+ suite_name=${suite_name#u-}
+ suite_name=$(echo "$suite_name" | tr '-' '_')
+ sed -ne "s/^\(void test_${suite_name}__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\)$/extern \1;/p" "$suite" ||
+ exit 1
+done >"$OUTPUT"
diff --git a/t/unit-tests/generate-clar-suites.sh b/t/unit-tests/generate-clar-suites.sh
new file mode 100755
index 0000000000..d5c712221e
--- /dev/null
+++ b/t/unit-tests/generate-clar-suites.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+if test $# -lt 2
+then
+ echo "USAGE: $0 <CLAR_DECLS_H> <OUTPUT>" 2>&1
+ exit 1
+fi
+
+CLAR_DECLS_H="$1"
+OUTPUT="$2"
+
+awk '
+ function add_suite(suite, initialize, cleanup, count) {
+ if (!suite) return
+ suite_count++
+ callback_count += count
+ suites = suites " {\n"
+ suites = suites " \"" suite "\",\n"
+ suites = suites " " initialize ",\n"
+ suites = suites " " cleanup ",\n"
+ suites = suites " _clar_cb_" suite ", " count ", 1\n"
+ suites = suites " },\n"
+ }
+
+ BEGIN {
+ suites = "static struct clar_suite _clar_suites[] = {\n"
+ }
+
+ {
+ print
+ name = $3; sub(/\(.*$/, "", name)
+ suite = name; sub(/^test_/, "", suite); sub(/__.*$/, "", suite)
+ short_name = name; sub(/^.*__/, "", short_name)
+ cb = "{ \"" short_name "\", &" name " }"
+ if (suite != prev_suite) {
+ add_suite(prev_suite, initialize, cleanup, count)
+ if (callbacks) callbacks = callbacks "};\n"
+ callbacks = callbacks "static const struct clar_func _clar_cb_" suite "[] = {\n"
+ initialize = "{ NULL, NULL }"
+ cleanup = "{ NULL, NULL }"
+ count = 0
+ prev_suite = suite
+ }
+ if (short_name == "initialize") {
+ initialize = cb
+ } else if (short_name == "cleanup") {
+ cleanup = cb
+ } else {
+ callbacks = callbacks " " cb ",\n"
+ count++
+ }
+ }
+
+ END {
+ add_suite(suite, initialize, cleanup, count)
+ suites = suites "};"
+ if (callbacks) callbacks = callbacks "};"
+ print callbacks
+ print suites
+ print "static const size_t _clar_suite_count = " suite_count ";"
+ print "static const size_t _clar_callback_count = " callback_count ";"
+ }
+' "$CLAR_DECLS_H" >"$OUTPUT"
diff --git a/t/unit-tests/lib-reftable.c b/t/unit-tests/lib-reftable.c
index 2ddf480588..8a69612266 100644
--- a/t/unit-tests/lib-reftable.c
+++ b/t/unit-tests/lib-reftable.c
@@ -1,9 +1,12 @@
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "lib-reftable.h"
#include "test-lib.h"
#include "reftable/constants.h"
#include "reftable/writer.h"
+#include "strbuf.h"
-void t_reftable_set_hash(uint8_t *p, int i, uint32_t id)
+void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id)
{
memset(p, (uint8_t)i, hash_size(id));
}
@@ -82,7 +85,7 @@ void t_reftable_write_to_buf(struct reftable_buf *buf,
size_t off = i * (opts.block_size ? opts.block_size
: DEFAULT_BLOCK_SIZE);
if (!off)
- off = header_size(opts.hash_id == GIT_SHA256_FORMAT_ID ? 2 : 1);
+ off = header_size(opts.hash_id == REFTABLE_HASH_SHA256 ? 2 : 1);
check_char(buf->buf[off], ==, 'r');
}
diff --git a/t/unit-tests/lib-reftable.h b/t/unit-tests/lib-reftable.h
index d4950fed3d..e4c360fa7e 100644
--- a/t/unit-tests/lib-reftable.h
+++ b/t/unit-tests/lib-reftable.h
@@ -6,7 +6,7 @@
struct reftable_buf;
-void t_reftable_set_hash(uint8_t *p, int i, uint32_t id);
+void t_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_write_options *opts);
diff --git a/t/unit-tests/t-example-decorate.c b/t/unit-tests/t-example-decorate.c
deleted file mode 100644
index 8bf0709c41..0000000000
--- a/t/unit-tests/t-example-decorate.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#define USE_THE_REPOSITORY_VARIABLE
-
-#include "test-lib.h"
-#include "object.h"
-#include "decorate.h"
-#include "repository.h"
-
-struct test_vars {
- struct object *one, *two, *three;
- struct decoration n;
- int decoration_a, decoration_b;
-};
-
-static void t_add(struct test_vars *vars)
-{
- void *ret = add_decoration(&vars->n, vars->one, &vars->decoration_a);
-
- check(ret == NULL);
- ret = add_decoration(&vars->n, vars->two, NULL);
- check(ret == NULL);
-}
-
-static void t_readd(struct test_vars *vars)
-{
- void *ret = add_decoration(&vars->n, vars->one, NULL);
-
- check(ret == &vars->decoration_a);
- ret = add_decoration(&vars->n, vars->two, &vars->decoration_b);
- check(ret == NULL);
-}
-
-static void t_lookup(struct test_vars *vars)
-{
- void *ret = lookup_decoration(&vars->n, vars->one);
-
- check(ret == NULL);
- ret = lookup_decoration(&vars->n, vars->two);
- check(ret == &vars->decoration_b);
- ret = lookup_decoration(&vars->n, vars->three);
- check(ret == NULL);
-}
-
-static void t_loop(struct test_vars *vars)
-{
- int i, objects_noticed = 0;
-
- for (i = 0; i < vars->n.size; i++) {
- if (vars->n.entries[i].base)
- objects_noticed++;
- }
- check_int(objects_noticed, ==, 2);
-}
-
-int cmd_main(int argc UNUSED, const char **argv UNUSED)
-{
- struct object_id one_oid = { { 1 } }, two_oid = { { 2 } }, three_oid = { { 3 } };
- struct test_vars vars = { 0 };
-
- vars.one = lookup_unknown_object(the_repository, &one_oid);
- vars.two = lookup_unknown_object(the_repository, &two_oid);
- vars.three = lookup_unknown_object(the_repository, &three_oid);
-
- TEST(t_add(&vars),
- "Add 2 objects, one with a non-NULL decoration and one with a NULL decoration.");
- TEST(t_readd(&vars),
- "When re-adding an already existing object, the old decoration is returned.");
- TEST(t_lookup(&vars),
- "Lookup returns the added declarations, or NULL if the object was never added.");
- TEST(t_loop(&vars), "The user can also loop through all entries.");
-
- clear_decoration(&vars.n, NULL);
-
- return test_done();
-}
diff --git a/t/unit-tests/t-mem-pool.c b/t/unit-tests/t-mem-pool.c
deleted file mode 100644
index fe500c704b..0000000000
--- a/t/unit-tests/t-mem-pool.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "test-lib.h"
-#include "mem-pool.h"
-
-static void setup_static(void (*f)(struct mem_pool *), size_t block_alloc)
-{
- struct mem_pool pool = { .block_alloc = block_alloc };
- f(&pool);
- mem_pool_discard(&pool, 0);
-}
-
-static void t_calloc_100(struct mem_pool *pool)
-{
- size_t size = 100;
- char *buffer = mem_pool_calloc(pool, 1, size);
- for (size_t i = 0; i < size; i++)
- check_int(buffer[i], ==, 0);
- if (!check(pool->mp_block != NULL))
- return;
- check(pool->mp_block->next_free != NULL);
- check(pool->mp_block->end != NULL);
-}
-
-int cmd_main(int argc UNUSED, const char **argv UNUSED)
-{
- TEST(setup_static(t_calloc_100, 1024 * 1024),
- "mem_pool_calloc returns 100 zeroed bytes with big block");
- TEST(setup_static(t_calloc_100, 1),
- "mem_pool_calloc returns 100 zeroed bytes with tiny block");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-prio-queue.c b/t/unit-tests/t-prio-queue.c
deleted file mode 100644
index fe6ae37935..0000000000
--- a/t/unit-tests/t-prio-queue.c
+++ /dev/null
@@ -1,91 +0,0 @@
-#include "test-lib.h"
-#include "prio-queue.h"
-
-static int intcmp(const void *va, const void *vb, void *data UNUSED)
-{
- const int *a = va, *b = vb;
- return *a - *b;
-}
-
-
-#define MISSING -1
-#define DUMP -2
-#define STACK -3
-#define GET -4
-#define REVERSE -5
-
-static int show(int *v)
-{
- return v ? *v : MISSING;
-}
-
-static void test_prio_queue(int *input, size_t input_size,
- int *result, size_t result_size)
-{
- struct prio_queue pq = { intcmp };
- int j = 0;
-
- for (int i = 0; i < input_size; i++) {
- void *peek, *get;
- switch(input[i]) {
- case GET:
- peek = prio_queue_peek(&pq);
- get = prio_queue_get(&pq);
- if (!check(peek == get))
- return;
- if (!check_uint(j, <, result_size))
- break;
- if (!check_int(result[j], ==, show(get)))
- test_msg(" j: %d", j);
- j++;
- break;
- case DUMP:
- while ((peek = prio_queue_peek(&pq))) {
- get = prio_queue_get(&pq);
- if (!check(peek == get))
- return;
- if (!check_uint(j, <, result_size))
- break;
- if (!check_int(result[j], ==, show(get)))
- test_msg(" j: %d", j);
- j++;
- }
- break;
- case STACK:
- pq.compare = NULL;
- break;
- case REVERSE:
- prio_queue_reverse(&pq);
- break;
- default:
- prio_queue_put(&pq, &input[i]);
- break;
- }
- }
- check_uint(j, ==, result_size);
- clear_prio_queue(&pq);
-}
-
-#define TEST_INPUT(input, result) \
- test_prio_queue(input, ARRAY_SIZE(input), result, ARRAY_SIZE(result))
-
-int cmd_main(int argc UNUSED, const char **argv UNUSED)
-{
- TEST(TEST_INPUT(((int []){ 2, 6, 3, 10, 9, 5, 7, 4, 5, 8, 1, DUMP }),
- ((int []){ 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10 })),
- "prio-queue works for basic input");
- TEST(TEST_INPUT(((int []){ 6, 2, 4, GET, 5, 3, GET, GET, 1, DUMP }),
- ((int []){ 2, 3, 4, 1, 5, 6 })),
- "prio-queue works for mixed put & get commands");
- TEST(TEST_INPUT(((int []){ 1, 2, GET, GET, GET, 1, 2, GET, GET, GET }),
- ((int []){ 1, 2, MISSING, 1, 2, MISSING })),
- "prio-queue works when queue is empty");
- TEST(TEST_INPUT(((int []){ STACK, 8, 1, 5, 4, 6, 2, 3, DUMP }),
- ((int []){ 3, 2, 6, 4, 5, 1, 8 })),
- "prio-queue works when used as a LIFO stack");
- TEST(TEST_INPUT(((int []){ STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP }),
- ((int []){ 1, 2, 3, 4, 5, 6 })),
- "prio-queue works when LIFO stack is reversed");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c
index 65d50df091..9ba7eb05ad 100644
--- a/t/unit-tests/t-reftable-basics.c
+++ b/t/unit-tests/t-reftable-basics.c
@@ -20,6 +20,11 @@ static int integer_needle_lesseq(size_t i, void *_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") {
@@ -115,7 +120,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
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_int(common_prefix_size(&a, &b), ==, cases[i].want);
+ check_uint(common_prefix_size(&a, &b), ==, cases[i].want);
reftable_buf_reset(&a);
reftable_buf_reset(&b);
}
@@ -141,5 +146,56 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
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/t-reftable-block.c b/t/unit-tests/t-reftable-block.c
index f9af907117..22040aeefa 100644
--- a/t/unit-tests/t-reftable-block.c
+++ b/t/unit-tests/t-reftable-block.c
@@ -11,6 +11,7 @@ https://developers.google.com/open-source/licenses/bsd
#include "reftable/blocksource.h"
#include "reftable/constants.h"
#include "reftable/reftable-error.h"
+#include "strbuf.h"
static void t_ref_block_read_write(void)
{
@@ -36,7 +37,7 @@ static void t_ref_block_read_write(void)
block.len = block_size;
block_source_from_buf(&block.source ,&buf);
ret = block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size,
- header_off, hash_size(GIT_SHA1_FORMAT_ID));
+ header_off, hash_size(REFTABLE_HASH_SHA1));
check(!ret);
rec.u.ref.refname = (char *) "";
@@ -47,7 +48,7 @@ static void t_ref_block_read_write(void)
for (i = 0; i < N; i++) {
rec.u.ref.refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i);
rec.u.ref.value_type = REFTABLE_REF_VAL1;
- memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ);
+ memset(rec.u.ref.value.val1, i, REFTABLE_HASH_SIZE_SHA1);
recs[i] = rec;
ret = block_writer_add(&bw, &rec);
@@ -61,7 +62,7 @@ static void t_ref_block_read_write(void)
block_writer_release(&bw);
- block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ);
+ block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
block_iter_seek_start(&it, &br);
@@ -72,7 +73,7 @@ static void t_ref_block_read_write(void)
check_int(i, ==, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
}
for (i = 0; i < N; i++) {
@@ -85,7 +86,7 @@ static void t_ref_block_read_write(void)
ret = block_iter_next(&it, &rec);
check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
want.len--;
ret = block_iter_seek_key(&it, &br, &want);
@@ -93,7 +94,7 @@ static void t_ref_block_read_write(void)
ret = block_iter_next(&it, &rec);
check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1));
}
block_reader_release(&br);
@@ -130,7 +131,7 @@ static void t_log_block_read_write(void)
block.len = block_size;
block_source_from_buf(&block.source ,&buf);
ret = block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size,
- header_off, hash_size(GIT_SHA1_FORMAT_ID));
+ header_off, hash_size(REFTABLE_HASH_SHA1));
check(!ret);
for (i = 0; i < N; i++) {
@@ -150,7 +151,7 @@ static void t_log_block_read_write(void)
block_writer_release(&bw);
- block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ);
+ block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
block_iter_seek_start(&it, &br);
@@ -161,7 +162,7 @@ static void t_log_block_read_write(void)
check_int(i, ==, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
}
for (i = 0; i < N; i++) {
@@ -175,7 +176,7 @@ static void t_log_block_read_write(void)
ret = block_iter_next(&it, &rec);
check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
want.len--;
ret = block_iter_seek_key(&it, &br, &want);
@@ -183,7 +184,7 @@ static void t_log_block_read_write(void)
ret = block_iter_next(&it, &rec);
check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1));
}
block_reader_release(&br);
@@ -220,7 +221,7 @@ static void t_obj_block_read_write(void)
block.len = block_size;
block_source_from_buf(&block.source, &buf);
ret = block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size,
- header_off, hash_size(GIT_SHA1_FORMAT_ID));
+ header_off, hash_size(REFTABLE_HASH_SHA1));
check(!ret);
for (i = 0; i < N; i++) {
@@ -242,7 +243,7 @@ static void t_obj_block_read_write(void)
block_writer_release(&bw);
- block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ);
+ block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
block_iter_seek_start(&it, &br);
@@ -253,7 +254,7 @@ static void t_obj_block_read_write(void)
check_int(i, ==, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
}
for (i = 0; i < N; i++) {
@@ -266,7 +267,7 @@ static void t_obj_block_read_write(void)
ret = block_iter_next(&it, &rec);
check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
}
block_reader_release(&br);
@@ -304,7 +305,7 @@ static void t_index_block_read_write(void)
block.len = block_size;
block_source_from_buf(&block.source, &buf);
ret = block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size,
- header_off, hash_size(GIT_SHA1_FORMAT_ID));
+ header_off, hash_size(REFTABLE_HASH_SHA1));
check(!ret);
for (i = 0; i < N; i++) {
@@ -326,7 +327,7 @@ static void t_index_block_read_write(void)
block_writer_release(&bw);
- block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ);
+ block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1);
block_iter_seek_start(&it, &br);
@@ -337,7 +338,7 @@ static void t_index_block_read_write(void)
check_int(i, ==, N);
break;
}
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
}
for (i = 0; i < N; i++) {
@@ -350,7 +351,7 @@ static void t_index_block_read_write(void)
ret = block_iter_next(&it, &rec);
check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1));
want.len--;
ret = block_iter_seek_key(&it, &br, &want);
@@ -358,7 +359,7 @@ static void t_index_block_read_write(void)
ret = block_iter_next(&it, &rec);
check_int(ret, ==, 0);
- check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1));
}
block_reader_release(&br);
diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c
index 4c25ee5334..60836f80d6 100644
--- a/t/unit-tests/t-reftable-merged.c
+++ b/t/unit-tests/t-reftable-merged.c
@@ -42,7 +42,7 @@ merged_table_from_records(struct reftable_ref_record **refs,
check(!err);
}
- err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID);
+ err = reftable_merged_table_new(&mt, *readers, n, REFTABLE_HASH_SHA1);
check(!err);
return mt;
}
@@ -91,7 +91,7 @@ static void t_merged_single_record(void)
err = reftable_iterator_next_ref(&it, &ref);
check(!err);
- check(reftable_ref_record_equal(&r2[0], &ref, GIT_SHA1_RAWSZ));
+ check(reftable_ref_record_equal(&r2[0], &ref, REFTABLE_HASH_SIZE_SHA1));
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
readers_destroy(readers, 3);
@@ -168,7 +168,7 @@ static void t_merged_refs(void)
check(!err);
err = reftable_iterator_seek_ref(&it, "a");
check(!err);
- check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID);
+ 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);
@@ -178,7 +178,7 @@ static void t_merged_refs(void)
if (err > 0)
break;
- REFTABLE_ALLOC_GROW(out, len + 1, cap);
+ check(!REFTABLE_ALLOC_GROW(out, len + 1, cap));
out[len++] = ref;
}
reftable_iterator_destroy(&it);
@@ -186,7 +186,7 @@ static void t_merged_refs(void)
check_int(ARRAY_SIZE(want), ==, len);
for (i = 0; i < len; i++)
check(reftable_ref_record_equal(want[i], &out[i],
- GIT_SHA1_RAWSZ));
+ REFTABLE_HASH_SIZE_SHA1));
for (i = 0; i < len; i++)
reftable_ref_record_release(&out[i]);
reftable_free(out);
@@ -252,12 +252,12 @@ static void t_merged_seek_multiple_times(void)
err = reftable_iterator_next_ref(&it, &rec);
check(!err);
- err = reftable_ref_record_equal(&rec, &r1[1], GIT_SHA1_RAWSZ);
+ err = reftable_ref_record_equal(&rec, &r1[1], REFTABLE_HASH_SIZE_SHA1);
check(err == 1);
err = reftable_iterator_next_ref(&it, &rec);
check(!err);
- err = reftable_ref_record_equal(&rec, &r2[1], GIT_SHA1_RAWSZ);
+ err = reftable_ref_record_equal(&rec, &r2[1], REFTABLE_HASH_SIZE_SHA1);
check(err == 1);
err = reftable_iterator_next_ref(&it, &rec);
@@ -273,6 +273,78 @@ static void t_merged_seek_multiple_times(void)
reftable_free(sources);
}
+static void t_merged_seek_multiple_times_without_draining(void)
+{
+ struct reftable_ref_record r1[] = {
+ {
+ .refname = (char *) "a",
+ .update_index = 1,
+ .value_type = REFTABLE_REF_VAL1,
+ .value.val1 = { 1 },
+ },
+ {
+ .refname = (char *) "c",
+ .update_index = 1,
+ .value_type = REFTABLE_REF_VAL1,
+ .value.val1 = { 2 },
+ }
+ };
+ struct reftable_ref_record r2[] = {
+ {
+ .refname = (char *) "b",
+ .update_index = 2,
+ .value_type = REFTABLE_REF_VAL1,
+ .value.val1 = { 3 },
+ },
+ {
+ .refname = (char *) "d",
+ .update_index = 2,
+ .value_type = REFTABLE_REF_VAL1,
+ .value.val1 = { 4 },
+ },
+ };
+ struct reftable_ref_record *refs[] = {
+ r1, r2,
+ };
+ size_t sizes[] = {
+ ARRAY_SIZE(r1), ARRAY_SIZE(r2),
+ };
+ struct reftable_buf bufs[] = {
+ REFTABLE_BUF_INIT, REFTABLE_BUF_INIT,
+ };
+ struct reftable_block_source *sources = NULL;
+ struct reftable_reader **readers = NULL;
+ 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, &readers, sizes, bufs, 2);
+ merged_table_init_iter(mt, &it, 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);
+
+ 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);
+
+ for (size_t i = 0; i < ARRAY_SIZE(bufs); i++)
+ reftable_buf_release(&bufs[i]);
+ readers_destroy(readers, ARRAY_SIZE(refs));
+ reftable_ref_record_release(&rec);
+ reftable_iterator_destroy(&it);
+ reftable_merged_table_free(mt);
+ reftable_free(sources);
+}
+
static struct reftable_merged_table *
merged_table_from_log_records(struct reftable_log_record **logs,
struct reftable_block_source **source,
@@ -300,7 +372,7 @@ merged_table_from_log_records(struct reftable_log_record **logs,
check(!err);
}
- err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID);
+ err = reftable_merged_table_new(&mt, *readers, n, REFTABLE_HASH_SHA1);
check(!err);
return mt;
}
@@ -377,7 +449,7 @@ static void t_merged_logs(void)
check(!err);
err = reftable_iterator_seek_log(&it, "a");
check(!err);
- check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID);
+ 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);
@@ -387,7 +459,7 @@ static void t_merged_logs(void)
if (err > 0)
break;
- REFTABLE_ALLOC_GROW(out, len + 1, cap);
+ check(!REFTABLE_ALLOC_GROW(out, len + 1, cap));
out[len++] = log;
}
reftable_iterator_destroy(&it);
@@ -395,7 +467,7 @@ static void t_merged_logs(void)
check_int(ARRAY_SIZE(want), ==, len);
for (i = 0; i < len; i++)
check(reftable_log_record_equal(want[i], &out[i],
- GIT_SHA1_RAWSZ));
+ REFTABLE_HASH_SIZE_SHA1));
err = merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG);
check(!err);
@@ -404,7 +476,7 @@ static void t_merged_logs(void)
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], GIT_SHA1_RAWSZ));
+ check(reftable_log_record_equal(&out[0], &r3[0], REFTABLE_HASH_SIZE_SHA1));
reftable_iterator_destroy(&it);
for (i = 0; i < len; i++)
@@ -448,11 +520,11 @@ static void t_default_write_opts(void)
check(!err);
hash_id = reftable_reader_hash_id(rd);
- check_int(hash_id, ==, GIT_SHA1_FORMAT_ID);
+ check_int(hash_id, ==, REFTABLE_HASH_SHA1);
- err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA256_FORMAT_ID);
+ err = reftable_merged_table_new(&merged, &rd, 1, REFTABLE_HASH_SHA256);
check_int(err, ==, REFTABLE_FORMAT_ERROR);
- err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA1_FORMAT_ID);
+ err = reftable_merged_table_new(&merged, &rd, 1, REFTABLE_HASH_SHA1);
check(!err);
reftable_reader_decref(rd);
@@ -467,6 +539,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
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/t-reftable-pq.c
index ada4c19f18..f3f8a0cdf3 100644
--- a/t/unit-tests/t-reftable-pq.c
+++ b/t/unit-tests/t-reftable-pq.c
@@ -9,6 +9,7 @@ https://developers.google.com/open-source/licenses/bsd
#include "test-lib.h"
#include "reftable/constants.h"
#include "reftable/pq.h"
+#include "strbuf.h"
static void merged_iter_pqueue_check(const struct merged_iter_pqueue *pq)
{
@@ -132,7 +133,7 @@ static void t_merged_iter_pqueue_top(void)
merged_iter_pqueue_check(&pq);
check(pq_entry_equal(&top, &e));
- check(reftable_record_equal(top.rec, &recs[i], GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(top.rec, &recs[i], REFTABLE_HASH_SIZE_SHA1));
for (size_t j = 0; i < pq.len; j++) {
check(pq_less(&top, &pq.heap[j]));
check_int(top.index, >, j);
diff --git a/t/unit-tests/t-reftable-reader.c b/t/unit-tests/t-reftable-reader.c
index 19cb53b641..546df6005e 100644
--- a/t/unit-tests/t-reftable-reader.c
+++ b/t/unit-tests/t-reftable-reader.c
@@ -31,7 +31,7 @@ static int t_reader_seek_once(void)
ret = reftable_iterator_next_ref(&it, &ref);
check(!ret);
- ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ);
+ ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1);
check_int(ret, ==, 1);
ret = reftable_iterator_next_ref(&it, &ref);
@@ -74,7 +74,7 @@ static int t_reader_reseek(void)
ret = reftable_iterator_next_ref(&it, &ref);
check(!ret);
- ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ);
+ ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1);
check_int(ret, ==, 1);
ret = reftable_iterator_next_ref(&it, &ref);
diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/t-reftable-readwrite.c
index d279b86df0..c9626831da 100644
--- a/t/unit-tests/t-reftable-readwrite.c
+++ b/t/unit-tests/t-reftable-readwrite.c
@@ -6,6 +6,8 @@ license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "test-lib.h"
#include "lib-reftable.h"
#include "reftable/basics.h"
@@ -13,6 +15,7 @@ https://developers.google.com/open-source/licenses/bsd
#include "reftable/reader.h"
#include "reftable/reftable-error.h"
#include "reftable/reftable-writer.h"
+#include "strbuf.h"
static const int update_index = 5;
@@ -41,7 +44,7 @@ static void t_buffer(void)
}
static void write_table(char ***names, struct reftable_buf *buf, int N,
- int block_size, uint32_t hash_id)
+ int block_size, enum reftable_hash hash_id)
{
struct reftable_write_options opts = {
.block_size = block_size,
@@ -62,7 +65,7 @@ static void write_table(char ***names, struct reftable_buf *buf, int N,
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, GIT_SHA1_FORMAT_ID);
+ t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1);
}
for (i = 0; i < N; i++) {
@@ -70,7 +73,7 @@ static void write_table(char ***names, struct reftable_buf *buf, int N,
logs[i].update_index = update_index;
logs[i].value_type = REFTABLE_LOG_UPDATE;
t_reftable_set_hash(logs[i].value.update.new_hash, i,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
logs[i].value.update.message = (char *) "message";
}
@@ -90,7 +93,7 @@ static void t_log_buffer_size(void)
int i;
struct reftable_log_record
log = { .refname = (char *) "refs/heads/master",
- .update_index = 0xa,
+ .update_index = update_index,
.value_type = REFTABLE_LOG_UPDATE,
.value = { .update = {
.name = (char *) "Han-Wen Nienhuys",
@@ -104,9 +107,9 @@ static void t_log_buffer_size(void)
/* This tests buffer extension for log compression. Must use a random
hash, to ensure that the compressed part is larger than the original.
*/
- for (i = 0; i < GIT_SHA1_RAWSZ; i++) {
- log.value.update.old_hash[i] = (uint8_t)(git_rand() % 256);
- log.value.update.new_hash[i] = (uint8_t)(git_rand() % 256);
+ for (i = 0; i < REFTABLE_HASH_SIZE_SHA1; i++) {
+ log.value.update.old_hash[i] = (uint8_t)(git_rand(0) % 256);
+ 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);
@@ -127,7 +130,7 @@ static void t_log_overflow(void)
int err;
struct reftable_log_record log = {
.refname = (char *) "refs/heads/master",
- .update_index = 0xa,
+ .update_index = update_index,
.value_type = REFTABLE_LOG_UPDATE,
.value = {
.update = {
@@ -151,6 +154,48 @@ static void t_log_overflow(void)
reftable_buf_release(&buf);
}
+static void t_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_log_record log = {
+ .refname = (char *)"refs/head/master",
+ .update_index = 0,
+ .value_type = REFTABLE_LOG_UPDATE,
+ .value = {
+ .update = {
+ .old_hash = { 1 },
+ .new_hash = { 2 },
+ .name = (char *)"Han-Wen Nienhuys",
+ .email = (char *)"hanwen@google.com",
+ .tz_offset = 100,
+ .time = 0x5e430672,
+ },
+ },
+ };
+ 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);
+
+ /* 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);
+
+ /* 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);
+
+ reftable_writer_free(w);
+ reftable_buf_release(&buf);
+}
+
static void t_log_write_read(void)
{
struct reftable_write_options opts = {
@@ -191,9 +236,9 @@ static void t_log_write_read(void)
log.update_index = i;
log.value_type = REFTABLE_LOG_UPDATE;
t_reftable_set_hash(log.value.update.old_hash, i,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
t_reftable_set_hash(log.value.update.new_hash, i + 1,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
err = reftable_writer_add_log(w, &log);
check(!err);
@@ -280,7 +325,7 @@ static void t_log_zlib_corruption(void)
};
for (i = 0; i < sizeof(message) - 1; i++)
- message[i] = (uint8_t)(git_rand() % 64 + ' ');
+ message[i] = (uint8_t)(git_rand(0) % 64 + ' ');
reftable_writer_set_limits(w, 1, 1);
@@ -326,7 +371,7 @@ static void t_table_read_write_sequential(void)
int err = 0;
int j = 0;
- write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID);
+ write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1);
block_source_from_buf(&source, &buf);
@@ -361,7 +406,7 @@ static void t_table_write_small_table(void)
char **names;
struct reftable_buf buf = REFTABLE_BUF_INIT;
int N = 1;
- write_table(&names, &buf, N, 4096, GIT_SHA1_FORMAT_ID);
+ write_table(&names, &buf, N, 4096, REFTABLE_HASH_SHA1);
check_int(buf.len, <, 200);
reftable_buf_release(&buf);
free_names(names);
@@ -378,7 +423,7 @@ static void t_table_read_api(void)
struct reftable_log_record log = { 0 };
struct reftable_iterator it = { 0 };
- write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID);
+ write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1);
block_source_from_buf(&source, &buf);
@@ -400,7 +445,7 @@ static void t_table_read_api(void)
reftable_buf_release(&buf);
}
-static void t_table_read_write_seek(int index, int hash_id)
+static void t_table_read_write_seek(int index, enum reftable_hash hash_id)
{
char **names;
struct reftable_buf buf = REFTABLE_BUF_INIT;
@@ -467,24 +512,24 @@ static void t_table_read_write_seek(int index, int hash_id)
static void t_table_read_write_seek_linear(void)
{
- t_table_read_write_seek(0, GIT_SHA1_FORMAT_ID);
+ t_table_read_write_seek(0, REFTABLE_HASH_SHA1);
}
static void t_table_read_write_seek_linear_sha256(void)
{
- t_table_read_write_seek(0, GIT_SHA256_FORMAT_ID);
+ t_table_read_write_seek(0, REFTABLE_HASH_SHA256);
}
static void t_table_read_write_seek_index(void)
{
- t_table_read_write_seek(1, GIT_SHA1_FORMAT_ID);
+ t_table_read_write_seek(1, REFTABLE_HASH_SHA1);
}
static void t_table_refs_for(int indexed)
{
char **want_names;
int want_names_len = 0;
- uint8_t want_hash[GIT_SHA1_RAWSZ];
+ uint8_t want_hash[REFTABLE_HASH_SIZE_SHA1];
struct reftable_write_options opts = {
.block_size = 256,
@@ -500,10 +545,10 @@ static void t_table_refs_for(int indexed)
want_names = reftable_calloc(N + 1, sizeof(*want_names));
check(want_names != NULL);
- t_reftable_set_hash(want_hash, 4, GIT_SHA1_FORMAT_ID);
+ t_reftable_set_hash(want_hash, 4, REFTABLE_HASH_SHA1);
for (i = 0; i < N; i++) {
- uint8_t hash[GIT_SHA1_RAWSZ];
+ uint8_t hash[REFTABLE_HASH_SIZE_SHA1];
char fill[51] = { 0 };
char name[100];
struct reftable_ref_record ref = { 0 };
@@ -517,9 +562,9 @@ static void t_table_refs_for(int indexed)
ref.value_type = REFTABLE_REF_VAL2;
t_reftable_set_hash(ref.value.val2.value, i / 4,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
t_reftable_set_hash(ref.value.val2.target_value, 3 + i / 4,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
/* 80 bytes / entry, so 3 entries per block. Yields 17
*/
@@ -527,8 +572,8 @@ static void t_table_refs_for(int indexed)
n = reftable_writer_add_ref(w, &ref);
check_int(n, ==, 0);
- if (!memcmp(ref.value.val2.value, want_hash, GIT_SHA1_RAWSZ) ||
- !memcmp(ref.value.val2.target_value, want_hash, GIT_SHA1_RAWSZ))
+ 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);
}
@@ -598,7 +643,7 @@ static void t_write_empty_table(void)
check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR);
reftable_writer_free(w);
- check_int(buf.len, ==, header_size(1) + footer_size(1));
+ check_uint(buf.len, ==, header_size(1) + footer_size(1));
block_source_from_buf(&source, &buf);
@@ -917,6 +962,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
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");
diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/t-reftable-record.c
index eb98bf2da9..d49d2a2729 100644
--- a/t/unit-tests/t-reftable-record.c
+++ b/t/unit-tests/t-reftable-record.c
@@ -7,6 +7,7 @@
*/
#include "test-lib.h"
+#include "reftable/basics.h"
#include "reftable/constants.h"
#include "reftable/record.h"
@@ -17,10 +18,10 @@ static void t_copy(struct reftable_record *rec)
typ = reftable_record_type(rec);
reftable_record_init(&copy, typ);
- reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
+ reftable_record_copy_from(&copy, rec, REFTABLE_HASH_SIZE_SHA1);
/* do it twice to catch memory leaks */
- reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
- check(reftable_record_equal(rec, &copy, GIT_SHA1_RAWSZ));
+ reftable_record_copy_from(&copy, rec, REFTABLE_HASH_SIZE_SHA1);
+ check(reftable_record_equal(rec, &copy, REFTABLE_HASH_SIZE_SHA1));
reftable_record_release(&copy);
}
@@ -57,9 +58,25 @@ static void t_varint_roundtrip(void)
}
}
+static void t_varint_overflow(void)
+{
+ unsigned char buf[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00,
+ };
+ struct string_view view = {
+ .buf = buf,
+ .len = sizeof(buf),
+ };
+ uint64_t value;
+ int err = get_var_int(&value, &view);
+ check_int(err, ==, -1);
+}
+
static void set_hash(uint8_t *h, int j)
{
- for (int i = 0; i < hash_size(GIT_SHA1_FORMAT_ID); i++)
+ for (size_t i = 0; i < hash_size(REFTABLE_HASH_SHA1); i++)
h[i] = (j >> i) & 0xff;
}
@@ -84,14 +101,14 @@ static void t_reftable_ref_record_comparison(void)
},
};
- check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
check(!reftable_record_cmp(&in[0], &in[1]));
- check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1));
check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
in[1].u.ref.value_type = in[0].u.ref.value_type;
- check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
check(!reftable_record_cmp(&in[0], &in[1]));
}
@@ -155,15 +172,15 @@ static void t_reftable_ref_record_roundtrip(void)
check_int(reftable_record_is_deletion(&in), ==, i == REFTABLE_REF_DELETION);
reftable_record_key(&in, &key);
- n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
+ n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1);
check_int(n, >, 0);
/* decode into a non-zero reftable_record to test for leaks. */
- m = reftable_record_decode(&out, key, i, dest, GIT_SHA1_RAWSZ, &scratch);
+ m = reftable_record_decode(&out, key, i, dest, REFTABLE_HASH_SIZE_SHA1, &scratch);
check_int(n, ==, m);
check(reftable_ref_record_equal(&in.u.ref, &out.u.ref,
- GIT_SHA1_RAWSZ));
+ REFTABLE_HASH_SIZE_SHA1));
reftable_record_release(&in);
reftable_buf_release(&key);
@@ -193,15 +210,15 @@ static void t_reftable_log_record_comparison(void)
},
};
- check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
- check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ 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_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
/* comparison should be reversed for equal keys, because
* comparison is now performed on the basis of update indices */
check_int(reftable_record_cmp(&in[0], &in[1]), <, 0);
in[1].u.log.update_index = in[0].u.log.update_index;
- check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
check(!reftable_record_cmp(&in[0], &in[1]));
}
@@ -303,15 +320,15 @@ static void t_reftable_log_record_roundtrip(void)
reftable_record_key(&rec, &key);
- n = reftable_record_encode(&rec, dest, GIT_SHA1_RAWSZ);
+ n = reftable_record_encode(&rec, dest, REFTABLE_HASH_SIZE_SHA1);
check_int(n, >=, 0);
valtype = reftable_record_val_type(&rec);
m = reftable_record_decode(&out, key, valtype, dest,
- GIT_SHA1_RAWSZ, &scratch);
+ REFTABLE_HASH_SIZE_SHA1, &scratch);
check_int(n, ==, m);
check(reftable_log_record_equal(&in[i], &out.u.log,
- GIT_SHA1_RAWSZ));
+ REFTABLE_HASH_SIZE_SHA1));
reftable_log_record_release(&in[i]);
reftable_buf_release(&key);
reftable_record_release(&out);
@@ -380,20 +397,20 @@ static void t_reftable_obj_record_comparison(void)
},
};
- check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
check(!reftable_record_cmp(&in[0], &in[1]));
- check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1));
check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
in[1].u.obj.offset_len = in[0].u.obj.offset_len;
- check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
check(!reftable_record_cmp(&in[0], &in[1]));
}
static void t_reftable_obj_record_roundtrip(void)
{
- uint8_t testHash1[GIT_SHA1_RAWSZ] = { 1, 2, 3, 4, 0 };
+ uint8_t testHash1[REFTABLE_HASH_SIZE_SHA1] = { 1, 2, 3, 4, 0 };
uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 };
struct reftable_obj_record recs[3] = {
{
@@ -435,14 +452,14 @@ static void t_reftable_obj_record_roundtrip(void)
check(!reftable_record_is_deletion(&in));
t_copy(&in);
reftable_record_key(&in, &key);
- n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
+ n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1);
check_int(n, >, 0);
extra = reftable_record_val_type(&in);
m = reftable_record_decode(&out, key, extra, dest,
- GIT_SHA1_RAWSZ, &scratch);
+ REFTABLE_HASH_SIZE_SHA1, &scratch);
check_int(n, ==, m);
- check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1));
reftable_buf_release(&key);
reftable_record_release(&out);
}
@@ -473,14 +490,14 @@ static void t_reftable_index_record_comparison(void)
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"));
- check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
check(!reftable_record_cmp(&in[0], &in[1]));
- check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ));
+ check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1));
check_int(reftable_record_cmp(&in[1], &in[2]), >, 0);
in[1].u.idx.offset = in[0].u.idx.offset;
- check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1));
check(!reftable_record_cmp(&in[0], &in[1]));
for (size_t i = 0; i < ARRAY_SIZE(in); i++)
@@ -516,15 +533,15 @@ static void t_reftable_index_record_roundtrip(void)
check(!reftable_record_is_deletion(&in));
check(!reftable_buf_cmp(&key, &in.u.idx.last_key));
- n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
+ n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1);
check_int(n, >, 0);
extra = reftable_record_val_type(&in);
- m = reftable_record_decode(&out, key, extra, dest, GIT_SHA1_RAWSZ,
+ m = reftable_record_decode(&out, key, extra, dest, REFTABLE_HASH_SIZE_SHA1,
&scratch);
check_int(m, ==, n);
- check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
+ check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1));
reftable_record_release(&out);
reftable_buf_release(&key);
@@ -543,6 +560,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
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");
diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c
index 72f6747064..aeec195b2b 100644
--- a/t/unit-tests/t-reftable-stack.c
+++ b/t/unit-tests/t-reftable-stack.c
@@ -6,12 +6,17 @@ license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "test-lib.h"
#include "lib-reftable.h"
+#include "dir.h"
#include "reftable/merged.h"
#include "reftable/reader.h"
#include "reftable/reftable-error.h"
#include "reftable/stack.h"
+#include "strbuf.h"
+#include "tempfile.h"
#include <dirent.h>
static void clear_dir(const char *dirname)
@@ -120,7 +125,7 @@ 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, GIT_SHA1_FORMAT_ID);
+ t_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1);
err = reftable_stack_add(st, &write_test_ref, &ref);
check(!err);
@@ -168,7 +173,7 @@ static void t_reftable_stack_add_one(void)
err = reftable_stack_read_ref(st, ref.refname, &dest);
check(!err);
- check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));
+ check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1));
check_int(st->readers_len, >, 0);
#ifndef GIT_WINDOWS_NATIVE
@@ -279,7 +284,7 @@ static void t_reftable_stack_transaction_api(void)
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, GIT_SHA1_RAWSZ));
+ check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1));
reftable_ref_record_release(&dest);
reftable_stack_destroy(st);
@@ -339,7 +344,7 @@ static void t_reftable_stack_transaction_with_reload(void)
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, GIT_SHA1_RAWSZ));
+ check(reftable_ref_record_equal(&refs[i], &ref, REFTABLE_HASH_SIZE_SHA1));
}
reftable_ref_record_release(&ref);
@@ -529,13 +534,13 @@ 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, GIT_SHA1_FORMAT_ID);
+ t_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, GIT_SHA1_FORMAT_ID);
+ t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1);
}
for (i = 0; i < N; i++) {
@@ -561,7 +566,7 @@ static void t_reftable_stack_add(void)
int err = reftable_stack_read_ref(st, refs[i].refname, &dest);
check(!err);
check(reftable_ref_record_equal(&dest, refs + i,
- GIT_SHA1_RAWSZ));
+ REFTABLE_HASH_SIZE_SHA1));
reftable_ref_record_release(&dest);
}
@@ -570,7 +575,7 @@ static void t_reftable_stack_add(void)
int err = reftable_stack_read_log(st, refs[i].refname, &dest);
check(!err);
check(reftable_log_record_equal(&dest, logs + i,
- GIT_SHA1_RAWSZ));
+ REFTABLE_HASH_SIZE_SHA1));
reftable_log_record_release(&dest);
}
@@ -621,14 +626,14 @@ static void t_reftable_stack_iterator(void)
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, GIT_SHA1_FORMAT_ID);
+ t_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, GIT_SHA1_FORMAT_ID);
+ t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1);
}
for (i = 0; i < N; i++) {
@@ -655,7 +660,7 @@ static void t_reftable_stack_iterator(void)
if (err > 0)
break;
check(!err);
- check(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ));
+ check(reftable_ref_record_equal(&ref, &refs[i], REFTABLE_HASH_SIZE_SHA1));
reftable_ref_record_release(&ref);
}
check_int(i, ==, N);
@@ -673,7 +678,7 @@ static void t_reftable_stack_iterator(void)
if (err > 0)
break;
check(!err);
- check(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ));
+ check(reftable_log_record_equal(&log, &logs[i], REFTABLE_HASH_SIZE_SHA1));
reftable_log_record_release(&log);
}
check_int(i, ==, N);
@@ -766,16 +771,20 @@ static void t_reftable_stack_tombstone(void)
if (i % 2 == 0) {
refs[i].value_type = REFTABLE_REF_VAL1;
t_reftable_set_hash(refs[i].value.val1, i,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
}
logs[i].refname = xstrdup(buf);
- /* update_index is part of the key. */
- logs[i].update_index = 42;
+ /*
+ * update_index is part of the key so should be constant.
+ * The value itself should be less than the writer's upper
+ * limit.
+ */
+ 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,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
logs[i].value.update.email =
xstrdup("identity@invalid");
}
@@ -835,7 +844,7 @@ static void t_reftable_stack_hash_id(void)
.value.symref = (char *) "target",
.update_index = 1,
};
- struct reftable_write_options opts32 = { .hash_id = GIT_SHA256_FORMAT_ID };
+ struct reftable_write_options opts32 = { .hash_id = REFTABLE_HASH_SHA256 };
struct reftable_stack *st32 = NULL;
struct reftable_write_options opts_default = { 0 };
struct reftable_stack *st_default = NULL;
@@ -858,7 +867,7 @@ static void t_reftable_stack_hash_id(void)
err = reftable_stack_read_ref(st_default, "master", &dest);
check(!err);
- check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ));
+ check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1));
reftable_ref_record_release(&dest);
reftable_stack_destroy(st);
reftable_stack_destroy(st_default);
@@ -908,7 +917,7 @@ static void t_reflog_expire(void)
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,
- GIT_SHA1_FORMAT_ID);
+ REFTABLE_HASH_SHA1);
}
for (i = 1; i <= N; i++) {
diff --git a/t/unit-tests/t-strbuf.c b/t/unit-tests/t-strbuf.c
deleted file mode 100644
index 3f4044d697..0000000000
--- a/t/unit-tests/t-strbuf.c
+++ /dev/null
@@ -1,122 +0,0 @@
-#include "test-lib.h"
-#include "strbuf.h"
-
-/* wrapper that supplies tests with an empty, initialized strbuf */
-static void setup(void (*f)(struct strbuf*, const void*),
- const void *data)
-{
- struct strbuf buf = STRBUF_INIT;
-
- f(&buf, data);
- strbuf_release(&buf);
- check_uint(buf.len, ==, 0);
- check_uint(buf.alloc, ==, 0);
-}
-
-/* wrapper that supplies tests with a populated, initialized strbuf */
-static void setup_populated(void (*f)(struct strbuf*, const void*),
- const char *init_str, const void *data)
-{
- struct strbuf buf = STRBUF_INIT;
-
- strbuf_addstr(&buf, init_str);
- check_uint(buf.len, ==, strlen(init_str));
- f(&buf, data);
- strbuf_release(&buf);
- check_uint(buf.len, ==, 0);
- check_uint(buf.alloc, ==, 0);
-}
-
-static int assert_sane_strbuf(struct strbuf *buf)
-{
- /* Initialized strbufs should always have a non-NULL buffer */
- if (!check(!!buf->buf))
- return 0;
- /* Buffers should always be NUL-terminated */
- if (!check_char(buf->buf[buf->len], ==, '\0'))
- return 0;
- /*
- * Freshly-initialized strbufs may not have a dynamically allocated
- * buffer
- */
- if (buf->len == 0 && buf->alloc == 0)
- return 1;
- /* alloc must be at least one byte larger than len */
- return check_uint(buf->len, <, buf->alloc);
-}
-
-static void t_static_init(void)
-{
- struct strbuf buf = STRBUF_INIT;
-
- check_uint(buf.len, ==, 0);
- check_uint(buf.alloc, ==, 0);
- check_char(buf.buf[0], ==, '\0');
-}
-
-static void t_dynamic_init(void)
-{
- struct strbuf buf;
-
- strbuf_init(&buf, 1024);
- check(assert_sane_strbuf(&buf));
- check_uint(buf.len, ==, 0);
- check_uint(buf.alloc, >=, 1024);
- check_char(buf.buf[0], ==, '\0');
- strbuf_release(&buf);
-}
-
-static void t_addch(struct strbuf *buf, const void *data)
-{
- const char *p_ch = data;
- const char ch = *p_ch;
- size_t orig_alloc = buf->alloc;
- size_t orig_len = buf->len;
-
- if (!check(assert_sane_strbuf(buf)))
- return;
- strbuf_addch(buf, ch);
- if (!check(assert_sane_strbuf(buf)))
- return;
- if (!(check_uint(buf->len, ==, orig_len + 1) &&
- check_uint(buf->alloc, >=, orig_alloc)))
- return; /* avoid de-referencing buf->buf */
- check_char(buf->buf[buf->len - 1], ==, ch);
- check_char(buf->buf[buf->len], ==, '\0');
-}
-
-static void t_addstr(struct strbuf *buf, const void *data)
-{
- const char *text = data;
- size_t len = strlen(text);
- size_t orig_alloc = buf->alloc;
- size_t orig_len = buf->len;
-
- if (!check(assert_sane_strbuf(buf)))
- return;
- strbuf_addstr(buf, text);
- if (!check(assert_sane_strbuf(buf)))
- return;
- if (!(check_uint(buf->len, ==, orig_len + len) &&
- check_uint(buf->alloc, >=, orig_alloc) &&
- check_uint(buf->alloc, >, orig_len + len) &&
- check_char(buf->buf[orig_len + len], ==, '\0')))
- return;
- check_str(buf->buf + orig_len, text);
-}
-
-int cmd_main(int argc UNUSED, const char **argv UNUSED)
-{
- if (!TEST(t_static_init(), "static initialization works"))
- test_skip_all("STRBUF_INIT is broken");
- TEST(t_dynamic_init(), "dynamic initialization works");
- TEST(setup(t_addch, "a"), "strbuf_addch adds char");
- TEST(setup(t_addch, ""), "strbuf_addch adds NUL char");
- TEST(setup_populated(t_addch, "initial value", "a"),
- "strbuf_addch appends to initial value");
- TEST(setup(t_addstr, "hello there"), "strbuf_addstr adds string");
- TEST(setup_populated(t_addstr, "initial value", "hello there"),
- "strbuf_addstr appends string to initial value");
-
- return test_done();
-}
diff --git a/t/unit-tests/t-strcmp-offset.c b/t/unit-tests/t-strcmp-offset.c
deleted file mode 100644
index 6880f21161..0000000000
--- a/t/unit-tests/t-strcmp-offset.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "test-lib.h"
-#include "read-cache-ll.h"
-
-static void check_strcmp_offset(const char *string1, const char *string2,
- int expect_result, uintmax_t expect_offset)
-{
- size_t offset;
- int result = strcmp_offset(string1, string2, &offset);
-
- /*
- * Because different CRTs behave differently, only rely on signs of the
- * result values.
- */
- result = (result < 0 ? -1 :
- result > 0 ? 1 :
- 0);
-
- check_int(result, ==, expect_result);
- check_uint((uintmax_t)offset, ==, expect_offset);
-}
-
-#define TEST_STRCMP_OFFSET(string1, string2, expect_result, expect_offset) \
- TEST(check_strcmp_offset(string1, string2, expect_result, \
- expect_offset), \
- "strcmp_offset(%s, %s) works", #string1, #string2)
-
-int cmd_main(int argc UNUSED, const char **argv UNUSED)
-{
- TEST_STRCMP_OFFSET("abc", "abc", 0, 3);
- TEST_STRCMP_OFFSET("abc", "def", -1, 0);
- TEST_STRCMP_OFFSET("abc", "abz", -1, 2);
- TEST_STRCMP_OFFSET("abc", "abcdef", -1, 3);
-
- return test_done();
-}
diff --git a/t/unit-tests/t-trailer.c b/t/unit-tests/t-trailer.c
index e1c6ad7461..184593e73d 100644
--- a/t/unit-tests/t-trailer.c
+++ b/t/unit-tests/t-trailer.c
@@ -1,3 +1,5 @@
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "test-lib.h"
#include "trailer.h"
diff --git a/t/unit-tests/test-lib.c b/t/unit-tests/test-lib.c
index fa1f95965c..87e1f5c201 100644
--- a/t/unit-tests/test-lib.c
+++ b/t/unit-tests/test-lib.c
@@ -1,3 +1,5 @@
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "test-lib.h"
enum result {
diff --git a/t/unit-tests/ctype.c b/t/unit-tests/u-ctype.c
index 32e65867cd..32e65867cd 100644
--- a/t/unit-tests/ctype.c
+++ b/t/unit-tests/u-ctype.c
diff --git a/t/unit-tests/u-example-decorate.c b/t/unit-tests/u-example-decorate.c
new file mode 100644
index 0000000000..9b1d1ce753
--- /dev/null
+++ b/t/unit-tests/u-example-decorate.c
@@ -0,0 +1,64 @@
+#define USE_THE_REPOSITORY_VARIABLE
+
+#include "unit-test.h"
+#include "object.h"
+#include "decorate.h"
+#include "repository.h"
+
+struct test_vars {
+ struct object *one, *two, *three;
+ struct decoration n;
+ int decoration_a, decoration_b;
+};
+
+static struct test_vars vars;
+
+void test_example_decorate__initialize(void)
+{
+ struct object_id one_oid = { { 1 } }, two_oid = { { 2 } }, three_oid = { { 3 } };
+
+ vars.one = lookup_unknown_object(the_repository, &one_oid);
+ vars.two = lookup_unknown_object(the_repository, &two_oid);
+ vars.three = lookup_unknown_object(the_repository, &three_oid);
+}
+
+void test_example_decorate__cleanup(void)
+{
+ clear_decoration(&vars.n, NULL);
+}
+
+void test_example_decorate__add(void)
+{
+ cl_assert_equal_p(add_decoration(&vars.n, vars.one, &vars.decoration_a), NULL);
+ cl_assert_equal_p(add_decoration(&vars.n, vars.two, NULL), NULL);
+}
+
+void test_example_decorate__readd(void)
+{
+ cl_assert_equal_p(add_decoration(&vars.n, vars.one, &vars.decoration_a), NULL);
+ cl_assert_equal_p(add_decoration(&vars.n, vars.two, NULL), NULL);
+ cl_assert_equal_p(add_decoration(&vars.n, vars.one, NULL), &vars.decoration_a);
+ cl_assert_equal_p(add_decoration(&vars.n, vars.two, &vars.decoration_b), NULL);
+}
+
+void test_example_decorate__lookup(void)
+{
+ cl_assert_equal_p(add_decoration(&vars.n, vars.two, &vars.decoration_b), NULL);
+ cl_assert_equal_p(add_decoration(&vars.n, vars.one, NULL), NULL);
+ cl_assert_equal_p(lookup_decoration(&vars.n, vars.two), &vars.decoration_b);
+ cl_assert_equal_p(lookup_decoration(&vars.n, vars.one), NULL);
+}
+
+void test_example_decorate__loop(void)
+{
+ int objects_noticed = 0;
+
+ cl_assert_equal_p(add_decoration(&vars.n, vars.one, &vars.decoration_a), NULL);
+ cl_assert_equal_p(add_decoration(&vars.n, vars.two, &vars.decoration_b), NULL);
+
+ for (size_t i = 0; i < vars.n.size; i++)
+ if (vars.n.entries[i].base)
+ objects_noticed++;
+
+ cl_assert_equal_i(objects_noticed, 2);
+}
diff --git a/t/unit-tests/t-hash.c b/t/unit-tests/u-hash.c
index e62647019b..bd4ac6a6e1 100644
--- a/t/unit-tests/t-hash.c
+++ b/t/unit-tests/u-hash.c
@@ -1,84 +1,109 @@
-#include "test-lib.h"
+#include "unit-test.h"
#include "hex.h"
#include "strbuf.h"
static void check_hash_data(const void *data, size_t data_length,
const char *expected_hashes[])
{
- if (!check(data != NULL)) {
- test_msg("BUG: NULL data pointer provided");
- return;
- }
+ cl_assert(data != NULL);
for (size_t i = 1; i < ARRAY_SIZE(hash_algos); i++) {
- git_hash_ctx ctx;
+ struct git_hash_ctx ctx;
unsigned char hash[GIT_MAX_HEXSZ];
const struct git_hash_algo *algop = &hash_algos[i];
algop->init_fn(&ctx);
- algop->update_fn(&ctx, data, data_length);
- algop->final_fn(hash, &ctx);
+ git_hash_update(&ctx, data, data_length);
+ git_hash_final(hash, &ctx);
- if (!check_str(hash_to_hex_algop(hash, algop), expected_hashes[i - 1]))
- test_msg("result does not match with the expected for %s\n", hash_algos[i].name);
+ cl_assert_equal_s(hash_to_hex_algop(hash,algop), expected_hashes[i - 1]);
}
}
/* Works with a NUL terminated string. Doesn't work if it should contain a NUL character. */
#define TEST_HASH_STR(data, expected_sha1, expected_sha256) do { \
const char *expected_hashes[] = { expected_sha1, expected_sha256 }; \
- TEST(check_hash_data(data, strlen(data), expected_hashes), \
- "SHA1 and SHA256 (%s) works", #data); \
+ check_hash_data(data, strlen(data), expected_hashes); \
} while (0)
/* Only works with a literal string, useful when it contains a NUL character. */
#define TEST_HASH_LITERAL(literal, expected_sha1, expected_sha256) do { \
const char *expected_hashes[] = { expected_sha1, expected_sha256 }; \
- TEST(check_hash_data(literal, (sizeof(literal) - 1), expected_hashes), \
- "SHA1 and SHA256 (%s) works", #literal); \
+ check_hash_data(literal, (sizeof(literal) - 1), expected_hashes); \
} while (0)
-int cmd_main(int argc UNUSED, const char **argv UNUSED)
+void test_hash__empty_string(void)
{
- struct strbuf aaaaaaaaaa_100000 = STRBUF_INIT;
- struct strbuf alphabet_100000 = STRBUF_INIT;
-
- strbuf_addstrings(&aaaaaaaaaa_100000, "aaaaaaaaaa", 100000);
- strbuf_addstrings(&alphabet_100000, "abcdefghijklmnopqrstuvwxyz", 100000);
-
TEST_HASH_STR("",
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+}
+
+void test_hash__single_character(void)
+{
TEST_HASH_STR("a",
"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8",
"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb");
+}
+
+void test_hash__multi_character(void)
+{
TEST_HASH_STR("abc",
"a9993e364706816aba3e25717850c26c9cd0d89d",
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
+}
+
+void test_hash__message_digest(void)
+{
TEST_HASH_STR("message digest",
"c12252ceda8be8994d5fa0290a47231c1d16aae3",
"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650");
+}
+
+void test_hash__alphabet(void)
+{
TEST_HASH_STR("abcdefghijklmnopqrstuvwxyz",
"32d10c7b8cf96570ca04ce37f2a19d84240d3a89",
"71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73");
+}
+
+void test_hash__aaaaaaaaaa_100000(void)
+{
+ struct strbuf aaaaaaaaaa_100000 = STRBUF_INIT;
+ strbuf_addstrings(&aaaaaaaaaa_100000, "aaaaaaaaaa", 100000);
TEST_HASH_STR(aaaaaaaaaa_100000.buf,
"34aa973cd4c4daa4f61eeb2bdbad27316534016f",
"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
+ strbuf_release(&aaaaaaaaaa_100000);
+}
+
+void test_hash__alphabet_100000(void)
+{
+ struct strbuf alphabet_100000 = STRBUF_INIT;
+ strbuf_addstrings(&alphabet_100000, "abcdefghijklmnopqrstuvwxyz", 100000);
TEST_HASH_STR(alphabet_100000.buf,
"e7da7c55b3484fdf52aebec9cbe7b85a98f02fd4",
"e406ba321ca712ad35a698bf0af8d61fc4dc40eca6bdcea4697962724ccbde35");
+ strbuf_release(&alphabet_100000);
+}
+
+void test_hash__zero_blob_literal(void)
+{
TEST_HASH_LITERAL("blob 0\0",
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
"473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813");
+}
+
+void test_hash__three_blob_literal(void)
+{
TEST_HASH_LITERAL("blob 3\0abc",
"f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f",
"c1cf6e465077930e88dc5136641d402f72a229ddd996f627d60e9639eaba35a6");
+}
+
+void test_hash__zero_tree_literal(void)
+{
TEST_HASH_LITERAL("tree 0\0",
"4b825dc642cb6eb9a060e54bf8d69288fbee4904",
"6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321");
-
- strbuf_release(&aaaaaaaaaa_100000);
- strbuf_release(&alphabet_100000);
-
- return test_done();
}
diff --git a/t/unit-tests/t-hashmap.c b/t/unit-tests/u-hashmap.c
index 83b79dff39..eb80aa1348 100644
--- a/t/unit-tests/t-hashmap.c
+++ b/t/unit-tests/u-hashmap.c
@@ -1,4 +1,4 @@
-#include "test-lib.h"
+#include "unit-test.h"
#include "hashmap.h"
#include "strbuf.h"
@@ -83,23 +83,23 @@ static void t_replace(struct hashmap *map, unsigned int ignore_case)
struct test_entry *entry;
entry = alloc_test_entry("key1", "value1", ignore_case);
- check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL);
+ cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL);
entry = alloc_test_entry(ignore_case ? "Key1" : "key1", "value2",
ignore_case);
entry = hashmap_put_entry(map, entry, ent);
- if (check(entry != NULL))
- check_str(get_value(entry), "value1");
+ cl_assert(entry != NULL);
+ cl_assert_equal_s(get_value(entry), "value1");
free(entry);
entry = alloc_test_entry("fooBarFrotz", "value3", ignore_case);
- check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL);
+ cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL);
entry = alloc_test_entry(ignore_case ? "FOObarFrotz" : "fooBarFrotz",
"value4", ignore_case);
entry = hashmap_put_entry(map, entry, ent);
- if (check(entry != NULL))
- check_str(get_value(entry), "value3");
+ cl_assert(entry != NULL);
+ cl_assert_equal_s(get_value(entry), "value3");
free(entry);
}
@@ -122,20 +122,18 @@ static void t_get(struct hashmap *map, unsigned int ignore_case)
for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) {
entry = alloc_test_entry(key_val[i][0], key_val[i][1],
ignore_case);
- check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL);
+ cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL);
}
for (size_t i = 0; i < ARRAY_SIZE(query); i++) {
entry = get_test_entry(map, query[i][0], ignore_case);
- if (check(entry != NULL))
- check_str(get_value(entry), query[i][1]);
- else
- test_msg("query key: %s", query[i][0]);
+ cl_assert(entry != NULL);
+ cl_assert_equal_s(get_value(entry), query[i][1]);
}
- check_pointer_eq(get_test_entry(map, "notInMap", ignore_case), NULL);
- check_int(map->tablesize, ==, 64);
- check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val));
+ cl_assert_equal_p(get_test_entry(map, "notInMap", ignore_case), NULL);
+ cl_assert_equal_i(map->tablesize, 64);
+ cl_assert_equal_i(hashmap_get_size(map), ARRAY_SIZE(key_val));
}
static void t_add(struct hashmap *map, unsigned int ignore_case)
@@ -165,39 +163,19 @@ static void t_add(struct hashmap *map, unsigned int ignore_case)
hashmap_for_each_entry_from(map, entry, ent)
{
- int ret;
- if (!check_int((ret = key_val_contains(
- key_val, seen,
- ARRAY_SIZE(key_val), entry)),
- ==, 0)) {
- switch (ret) {
- case 1:
- test_msg("found entry was not given in the input\n"
- " key: %s\n value: %s",
- entry->key, get_value(entry));
- break;
- case 2:
- test_msg("duplicate entry detected\n"
- " key: %s\n value: %s",
- entry->key, get_value(entry));
- break;
- }
- } else {
- count++;
- }
+ int ret = key_val_contains(key_val, seen,
+ ARRAY_SIZE(key_val), entry);
+ cl_assert_equal_i(ret, 0);
+ count++;
}
- check_int(count, ==, 2);
+ cl_assert_equal_i(count, 2);
}
- for (size_t i = 0; i < ARRAY_SIZE(seen); i++) {
- if (!check_int(seen[i], ==, 1))
- test_msg("following key-val pair was not iterated over:\n"
- " key: %s\n value: %s",
- key_val[i][0], key_val[i][1]);
- }
+ for (size_t i = 0; i < ARRAY_SIZE(seen); i++)
+ cl_assert_equal_i(seen[i], 1);
- check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val));
- check_pointer_eq(get_test_entry(map, "notInMap", ignore_case), NULL);
+ cl_assert_equal_i(hashmap_get_size(map), ARRAY_SIZE(key_val));
+ cl_assert_equal_p(get_test_entry(map, "notInMap", ignore_case), NULL);
}
static void t_remove(struct hashmap *map, unsigned int ignore_case)
@@ -211,24 +189,25 @@ static void t_remove(struct hashmap *map, unsigned int ignore_case)
for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) {
entry = alloc_test_entry(key_val[i][0], key_val[i][1], ignore_case);
- check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL);
+ cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL);
}
for (size_t i = 0; i < ARRAY_SIZE(remove); i++) {
entry = alloc_test_entry(remove[i][0], "", ignore_case);
removed = hashmap_remove_entry(map, entry, ent, remove[i][0]);
- if (check(removed != NULL))
- check_str(get_value(removed), remove[i][1]);
+ cl_assert(removed != NULL);
+ cl_assert_equal_s(get_value(removed), remove[i][1]);
free(entry);
free(removed);
}
entry = alloc_test_entry("notInMap", "", ignore_case);
- check_pointer_eq(hashmap_remove_entry(map, entry, ent, "notInMap"), NULL);
+ cl_assert_equal_p(hashmap_remove_entry(map, entry, ent, "notInMap"), NULL);
free(entry);
- check_int(map->tablesize, ==, 64);
- check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val) - ARRAY_SIZE(remove));
+ cl_assert_equal_i(map->tablesize, 64);
+ cl_assert_equal_i(hashmap_get_size(map),
+ ARRAY_SIZE(key_val) - ARRAY_SIZE(remove));
}
static void t_iterate(struct hashmap *map, unsigned int ignore_case)
@@ -242,38 +221,21 @@ static void t_iterate(struct hashmap *map, unsigned int ignore_case)
for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) {
entry = alloc_test_entry(key_val[i][0], key_val[i][1], ignore_case);
- check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL);
+ cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL);
}
hashmap_for_each_entry(map, &iter, entry, ent /* member name */)
{
- int ret;
- if (!check_int((ret = key_val_contains(key_val, seen,
- ARRAY_SIZE(key_val),
- entry)), ==, 0)) {
- switch (ret) {
- case 1:
- test_msg("found entry was not given in the input\n"
- " key: %s\n value: %s",
- entry->key, get_value(entry));
- break;
- case 2:
- test_msg("duplicate entry detected\n"
- " key: %s\n value: %s",
- entry->key, get_value(entry));
- break;
- }
- }
+ int ret = key_val_contains(key_val, seen,
+ ARRAY_SIZE(key_val),
+ entry);
+ cl_assert(ret == 0);
}
- for (size_t i = 0; i < ARRAY_SIZE(seen); i++) {
- if (!check_int(seen[i], ==, 1))
- test_msg("following key-val pair was not iterated over:\n"
- " key: %s\n value: %s",
- key_val[i][0], key_val[i][1]);
- }
+ for (size_t i = 0; i < ARRAY_SIZE(seen); i++)
+ cl_assert_equal_i(seen[i], 1);
- check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val));
+ cl_assert_equal_i(hashmap_get_size(map), ARRAY_SIZE(key_val));
}
static void t_alloc(struct hashmap *map, unsigned int ignore_case)
@@ -284,17 +246,17 @@ static void t_alloc(struct hashmap *map, unsigned int ignore_case)
char *key = xstrfmt("key%d", i);
char *value = xstrfmt("value%d", i);
entry = alloc_test_entry(key, value, ignore_case);
- check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL);
+ cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL);
free(key);
free(value);
}
- check_int(map->tablesize, ==, 64);
- check_int(hashmap_get_size(map), ==, 51);
+ cl_assert_equal_i(map->tablesize, 64);
+ cl_assert_equal_i(hashmap_get_size(map), 51);
entry = alloc_test_entry("key52", "value52", ignore_case);
- check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL);
- check_int(map->tablesize, ==, 256);
- check_int(hashmap_get_size(map), ==, 52);
+ cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL);
+ cl_assert_equal_i(map->tablesize, 256);
+ cl_assert_equal_i(hashmap_get_size(map), 52);
for (int i = 1; i <= 12; i++) {
char *key = xstrfmt("key%d", i);
@@ -302,27 +264,27 @@ static void t_alloc(struct hashmap *map, unsigned int ignore_case)
entry = alloc_test_entry(key, "", ignore_case);
removed = hashmap_remove_entry(map, entry, ent, key);
- if (check(removed != NULL))
- check_str(value, get_value(removed));
+ cl_assert(removed != NULL);
+ cl_assert_equal_s(value, get_value(removed));
free(key);
free(value);
free(entry);
free(removed);
}
- check_int(map->tablesize, ==, 256);
- check_int(hashmap_get_size(map), ==, 40);
+ cl_assert_equal_i(map->tablesize, 256);
+ cl_assert_equal_i(hashmap_get_size(map), 40);
entry = alloc_test_entry("key40", "", ignore_case);
removed = hashmap_remove_entry(map, entry, ent, "key40");
- if (check(removed != NULL))
- check_str("value40", get_value(removed));
- check_int(map->tablesize, ==, 64);
- check_int(hashmap_get_size(map), ==, 39);
+ cl_assert(removed != NULL);
+ cl_assert_equal_s("value40", get_value(removed));
+ cl_assert_equal_i(map->tablesize, 64);
+ cl_assert_equal_i(hashmap_get_size(map), 39);
free(entry);
free(removed);
}
-static void t_intern(void)
+void test_hashmap__intern(void)
{
const char *values[] = { "value1", "Value1", "value2", "value2" };
@@ -330,32 +292,68 @@ static void t_intern(void)
const char *i1 = strintern(values[i]);
const char *i2 = strintern(values[i]);
- if (!check(!strcmp(i1, values[i])))
- test_msg("strintern(%s) returns %s\n", values[i], i1);
- else if (!check(i1 != values[i]))
- test_msg("strintern(%s) returns input pointer\n",
- values[i]);
- else if (!check_pointer_eq(i1, i2))
- test_msg("address('%s') != address('%s'), so strintern('%s') != strintern('%s')",
- i1, i2, values[i], values[i]);
- else
- check_str(i1, values[i]);
+ cl_assert_equal_s(i1, values[i]);
+ cl_assert(i1 != values[i]);
+ cl_assert_equal_p(i1, i2);
}
}
-int cmd_main(int argc UNUSED, const char **argv UNUSED)
+void test_hashmap__replace_case_sensitive(void)
+{
+ setup(t_replace, 0);
+}
+
+void test_hashmap__replace_case_insensitive(void)
+{
+ setup(t_replace, 1);
+}
+
+void test_hashmap__get_case_sensitive(void)
+{
+ setup(t_get, 0);
+}
+
+void test_hashmap__get_case_insensitive(void)
+{
+ setup(t_get, 1);
+}
+
+void test_hashmap__add_case_sensitive(void)
+{
+ setup(t_add, 0);
+}
+
+void test_hashmap__add_case_insensitive(void)
+{
+ setup(t_add, 1);
+}
+
+void test_hashmap__remove_case_sensitive(void)
+{
+ setup(t_remove, 0);
+}
+
+void test_hashmap__remove_case_insensitive(void)
+{
+ setup(t_remove, 1);
+}
+
+void test_hashmap__iterate_case_sensitive(void)
+{
+ setup(t_iterate, 0);
+}
+
+void test_hashmap__iterate_case_insensitive(void)
+{
+ setup(t_iterate, 1);
+}
+
+void test_hashmap__alloc_case_sensitive(void)
+{
+ setup(t_alloc, 0);
+}
+
+void test_hashmap__alloc_case_insensitive(void)
{
- TEST(setup(t_replace, 0), "replace works");
- TEST(setup(t_replace, 1), "replace (case insensitive) works");
- TEST(setup(t_get, 0), "get works");
- TEST(setup(t_get, 1), "get (case insensitive) works");
- TEST(setup(t_add, 0), "add works");
- TEST(setup(t_add, 1), "add (case insensitive) works");
- TEST(setup(t_remove, 0), "remove works");
- TEST(setup(t_remove, 1), "remove (case insensitive) works");
- TEST(setup(t_iterate, 0), "iterate works");
- TEST(setup(t_iterate, 1), "iterate (case insensitive) works");
- TEST(setup(t_alloc, 0), "grow / shrink works");
- TEST(t_intern(), "string interning works");
- return test_done();
+ setup(t_alloc, 1);
}
diff --git a/t/unit-tests/u-mem-pool.c b/t/unit-tests/u-mem-pool.c
new file mode 100644
index 0000000000..2bc2493b7e
--- /dev/null
+++ b/t/unit-tests/u-mem-pool.c
@@ -0,0 +1,25 @@
+#include "unit-test.h"
+#include "mem-pool.h"
+
+static void test_many_pool_allocations(size_t block_alloc)
+{
+ struct mem_pool pool = { .block_alloc = block_alloc };
+ size_t size = 100;
+ char *buffer = mem_pool_calloc(&pool, 1, size);
+ for (size_t i = 0; i < size; i++)
+ cl_assert_equal_i(0, buffer[i]);
+ cl_assert(pool.mp_block != NULL);
+ cl_assert(pool.mp_block->next_free != NULL);
+ cl_assert(pool.mp_block->end != NULL);
+ mem_pool_discard(&pool, 0);
+}
+
+void test_mem_pool__big_block(void)
+{
+ test_many_pool_allocations(1024 * 1024);
+}
+
+void test_mem_pool__tiny_block(void)
+{
+ test_many_pool_allocations(1);
+}
diff --git a/t/unit-tests/u-prio-queue.c b/t/unit-tests/u-prio-queue.c
new file mode 100644
index 0000000000..145e689c9c
--- /dev/null
+++ b/t/unit-tests/u-prio-queue.c
@@ -0,0 +1,94 @@
+#include "unit-test.h"
+#include "prio-queue.h"
+
+static int intcmp(const void *va, const void *vb, void *data UNUSED)
+{
+ const int *a = va, *b = vb;
+ return *a - *b;
+}
+
+
+#define MISSING -1
+#define DUMP -2
+#define STACK -3
+#define GET -4
+#define REVERSE -5
+
+static int show(int *v)
+{
+ return v ? *v : MISSING;
+}
+
+static void test_prio_queue(int *input, size_t input_size,
+ int *result, size_t result_size)
+{
+ struct prio_queue pq = { intcmp };
+ size_t j = 0;
+
+ for (size_t i = 0; i < input_size; i++) {
+ void *peek, *get;
+ switch(input[i]) {
+ case GET:
+ peek = prio_queue_peek(&pq);
+ get = prio_queue_get(&pq);
+ cl_assert(peek == get);
+ cl_assert(j < result_size);
+ cl_assert_equal_i(result[j], show(get));
+ j++;
+ break;
+ case DUMP:
+ while ((peek = prio_queue_peek(&pq))) {
+ get = prio_queue_get(&pq);
+ cl_assert(peek == get);
+ cl_assert(j < result_size);
+ cl_assert_equal_i(result[j], show(get));
+ j++;
+ }
+ break;
+ case STACK:
+ pq.compare = NULL;
+ break;
+ case REVERSE:
+ prio_queue_reverse(&pq);
+ break;
+ default:
+ prio_queue_put(&pq, &input[i]);
+ break;
+ }
+ }
+ cl_assert_equal_i(j, result_size);
+ clear_prio_queue(&pq);
+}
+
+#define TEST_INPUT(input, result) \
+ test_prio_queue(input, ARRAY_SIZE(input), result, ARRAY_SIZE(result))
+
+void test_prio_queue__basic(void)
+{
+ TEST_INPUT(((int []){ 2, 6, 3, 10, 9, 5, 7, 4, 5, 8, 1, DUMP }),
+ ((int []){ 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10 }));
+}
+
+void test_prio_queue__mixed(void)
+{
+ TEST_INPUT(((int []){ 6, 2, 4, GET, 5, 3, GET, GET, 1, DUMP }),
+ ((int []){ 2, 3, 4, 1, 5, 6 }));
+}
+
+void test_prio_queue__empty(void)
+{
+ TEST_INPUT(((int []){ 1, 2, GET, GET, GET, 1, 2, GET, GET, GET }),
+ ((int []){ 1, 2, MISSING, 1, 2, MISSING }));
+}
+
+void test_prio_queue__stack(void)
+{
+ TEST_INPUT(((int []){ STACK, 8, 1, 5, 4, 6, 2, 3, DUMP }),
+ ((int []){ 3, 2, 6, 4, 5, 1, 8 }));
+}
+
+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 }));
+}
diff --git a/t/unit-tests/t-reftable-tree.c b/t/unit-tests/u-reftable-tree.c
index 79b175a45a..bcf9061071 100644
--- a/t/unit-tests/t-reftable-tree.c
+++ b/t/unit-tests/u-reftable-tree.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 "reftable/tree.h"
static int t_compare(const void *a, const void *b)
@@ -25,7 +25,7 @@ static void store(void *arg, void *key)
c->arr[c->len++] = key;
}
-static void t_tree_search(void)
+void test_reftable_tree__tree_search(void)
{
struct tree_node *root = NULL;
void *values[11] = { 0 };
@@ -38,20 +38,20 @@ static void t_tree_search(void)
*/
do {
nodes[i] = tree_insert(&root, &values[i], &t_compare);
- check(nodes[i] != NULL);
+ cl_assert(nodes[i] != NULL);
i = (i * 7) % 11;
} while (i != 1);
for (i = 1; i < ARRAY_SIZE(nodes); i++) {
- check_pointer_eq(&values[i], nodes[i]->key);
- check_pointer_eq(nodes[i], tree_search(root, &values[i], &t_compare));
+ cl_assert_equal_p(&values[i], nodes[i]->key);
+ cl_assert_equal_p(nodes[i], tree_search(root, &values[i], &t_compare));
}
- check(!tree_search(root, values, t_compare));
+ cl_assert(tree_search(root, values, t_compare) == NULL);
tree_free(root);
}
-static void t_infix_walk(void)
+void test_reftable_tree__infix_walk(void)
{
struct tree_node *root = NULL;
void *values[11] = { 0 };
@@ -64,23 +64,15 @@ static void t_infix_walk(void)
do {
struct tree_node *node = tree_insert(&root, &values[i], t_compare);
- check(node != NULL);
+ cl_assert(node != NULL);
i = (i * 7) % 11;
count++;
} while (i != 1);
infix_walk(root, &store, &c);
for (i = 1; i < ARRAY_SIZE(values); i++)
- check_pointer_eq(&values[i], out[i - 1]);
- check(!out[i - 1]);
- check_int(c.len, ==, count);
+ cl_assert_equal_p(&values[i], out[i - 1]);
+ cl_assert(out[i - 1] == NULL);
+ cl_assert_equal_i(c.len, count);
tree_free(root);
}
-
-int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
-{
- TEST(t_tree_search(), "tree_search works");
- TEST(t_infix_walk(), "infix_walk works");
-
- return test_done();
-}
diff --git a/t/unit-tests/u-strbuf.c b/t/unit-tests/u-strbuf.c
new file mode 100644
index 0000000000..caa5d78aa3
--- /dev/null
+++ b/t/unit-tests/u-strbuf.c
@@ -0,0 +1,119 @@
+#include "unit-test.h"
+#include "strbuf.h"
+
+/* wrapper that supplies tests with an empty, initialized strbuf */
+static void setup(void (*f)(struct strbuf*, const void*),
+ const void *data)
+{
+ struct strbuf buf = STRBUF_INIT;
+
+ f(&buf, data);
+ strbuf_release(&buf);
+ cl_assert_equal_i(buf.len, 0);
+ cl_assert_equal_i(buf.alloc, 0);
+}
+
+/* wrapper that supplies tests with a populated, initialized strbuf */
+static void setup_populated(void (*f)(struct strbuf*, const void*),
+ const char *init_str, const void *data)
+{
+ struct strbuf buf = STRBUF_INIT;
+
+ strbuf_addstr(&buf, init_str);
+ cl_assert_equal_i(buf.len, strlen(init_str));
+ f(&buf, data);
+ strbuf_release(&buf);
+ cl_assert_equal_i(buf.len, 0);
+ cl_assert_equal_i(buf.alloc, 0);
+}
+
+static void assert_sane_strbuf(struct strbuf *buf)
+{
+ /* Initialized strbufs should always have a non-NULL buffer */
+ cl_assert(buf->buf != NULL);
+ /* Buffers should always be NUL-terminated */
+ cl_assert(buf->buf[buf->len] == '\0');
+ /*
+ * In case the buffer contains anything, `alloc` must alloc must
+ * be at least one byte larger than `len`.
+ */
+ if (buf->len)
+ cl_assert(buf->len < buf->alloc);
+}
+
+void test_strbuf__static_init(void)
+{
+ struct strbuf buf = STRBUF_INIT;
+
+ cl_assert_equal_i(buf.len, 0);
+ cl_assert_equal_i(buf.alloc, 0);
+ cl_assert(buf.buf[0] == '\0');
+}
+
+void test_strbuf__dynamic_init(void)
+{
+ struct strbuf buf;
+
+ strbuf_init(&buf, 1024);
+ assert_sane_strbuf(&buf);
+ cl_assert_equal_i(buf.len, 0);
+ cl_assert(buf.alloc >= 1024);
+ cl_assert(buf.buf[0] == '\0');
+ strbuf_release(&buf);
+}
+
+static void t_addch(struct strbuf *buf, const void *data)
+{
+ const char *p_ch = data;
+ const char ch = *p_ch;
+ size_t orig_alloc = buf->alloc;
+ size_t orig_len = buf->len;
+
+ assert_sane_strbuf(buf);
+ strbuf_addch(buf, ch);
+ assert_sane_strbuf(buf);
+ cl_assert_equal_i(buf->len, orig_len + 1);
+ cl_assert(buf->alloc >= orig_alloc);
+ cl_assert(buf->buf[buf->len] == '\0');
+}
+
+static void t_addstr(struct strbuf *buf, const void *data)
+{
+ const char *text = data;
+ size_t len = strlen(text);
+ size_t orig_alloc = buf->alloc;
+ size_t orig_len = buf->len;
+
+ assert_sane_strbuf(buf);
+ strbuf_addstr(buf, text);
+ assert_sane_strbuf(buf);
+ cl_assert_equal_i(buf->len, orig_len + len);
+ cl_assert(buf->alloc >= orig_alloc);
+ cl_assert(buf->buf[buf->len] == '\0');
+ cl_assert_equal_s(buf->buf + orig_len, text);
+}
+
+void test_strbuf__add_single_char(void)
+{
+ setup(t_addch, "a");
+}
+
+void test_strbuf__add_empty_char(void)
+{
+ setup(t_addch, "");
+}
+
+void test_strbuf__add_append_char(void)
+{
+ setup_populated(t_addch, "initial value", "a");
+}
+
+void test_strbuf__add_single_str(void)
+{
+ setup(t_addstr, "hello there");
+}
+
+void test_strbuf__add_append_str(void)
+{
+ setup_populated(t_addstr, "initial value", "hello there");
+}
diff --git a/t/unit-tests/u-strcmp-offset.c b/t/unit-tests/u-strcmp-offset.c
new file mode 100644
index 0000000000..7e8e9acf3c
--- /dev/null
+++ b/t/unit-tests/u-strcmp-offset.c
@@ -0,0 +1,45 @@
+#include "unit-test.h"
+#include "read-cache-ll.h"
+
+static void check_strcmp_offset(const char *string1, const char *string2,
+ int expect_result, uintmax_t expect_offset)
+{
+ size_t offset;
+ int result = strcmp_offset(string1, string2, &offset);
+
+ /*
+ * Because different CRTs behave differently, only rely on signs of the
+ * result values.
+ */
+ result = (result < 0 ? -1 :
+ result > 0 ? 1 :
+ 0);
+
+ cl_assert_equal_i(result, expect_result);
+ cl_assert_equal_i((uintmax_t)offset, expect_offset);
+}
+
+void test_strcmp_offset__empty(void)
+{
+ check_strcmp_offset("", "", 0, 0);
+}
+
+void test_strcmp_offset__equal(void)
+{
+ check_strcmp_offset("abc", "abc", 0, 3);
+}
+
+void test_strcmp_offset__different(void)
+{
+ check_strcmp_offset("abc", "def", -1, 0);
+}
+
+void test_strcmp_offset__mismatch(void)
+{
+ check_strcmp_offset("abc", "abz", -1, 2);
+}
+
+void test_strcmp_offset__different_length(void)
+{
+ check_strcmp_offset("abc", "abcdef", -1, 3);
+}
diff --git a/t/unit-tests/strvec.c b/t/unit-tests/u-strvec.c
index bf4c0cb172..e66b7bbfae 100644
--- a/t/unit-tests/strvec.c
+++ b/t/unit-tests/u-strvec.c
@@ -88,6 +88,81 @@ void test_strvec__pushv(void)
strvec_clear(&vec);
}
+void test_strvec__splice_just_initialized_strvec(void)
+{
+ struct strvec vec = STRVEC_INIT;
+ const char *replacement[] = { "foo" };
+
+ strvec_splice(&vec, 0, 0, replacement, ARRAY_SIZE(replacement));
+ check_strvec(&vec, "foo", NULL);
+ strvec_clear(&vec);
+}
+
+void test_strvec__splice_with_same_size_replacement(void)
+{
+ struct strvec vec = STRVEC_INIT;
+ const char *replacement[] = { "1" };
+
+ strvec_pushl(&vec, "foo", "bar", "baz", NULL);
+ strvec_splice(&vec, 1, 1, replacement, ARRAY_SIZE(replacement));
+ check_strvec(&vec, "foo", "1", "baz", NULL);
+ strvec_clear(&vec);
+}
+
+void test_strvec__splice_with_smaller_replacement(void)
+{
+ struct strvec vec = STRVEC_INIT;
+ const char *replacement[] = { "1" };
+
+ strvec_pushl(&vec, "foo", "bar", "baz", NULL);
+ strvec_splice(&vec, 1, 2, replacement, ARRAY_SIZE(replacement));
+ check_strvec(&vec, "foo", "1", NULL);
+ strvec_clear(&vec);
+}
+
+void test_strvec__splice_with_bigger_replacement(void)
+{
+ struct strvec vec = STRVEC_INIT;
+ const char *replacement[] = { "1", "2", "3" };
+
+ strvec_pushl(&vec, "foo", "bar", "baz", NULL);
+ strvec_splice(&vec, 0, 2, replacement, ARRAY_SIZE(replacement));
+ check_strvec(&vec, "1", "2", "3", "baz", NULL);
+ strvec_clear(&vec);
+}
+
+void test_strvec__splice_with_empty_replacement(void)
+{
+ struct strvec vec = STRVEC_INIT;
+
+ strvec_pushl(&vec, "foo", "bar", "baz", NULL);
+ strvec_splice(&vec, 0, 2, NULL, 0);
+ check_strvec(&vec, "baz", NULL);
+ strvec_clear(&vec);
+}
+
+void test_strvec__splice_with_empty_original(void)
+{
+ struct strvec vec = STRVEC_INIT;
+ const char *replacement[] = { "1", "2" };
+
+ strvec_pushl(&vec, "foo", "bar", "baz", NULL);
+ strvec_splice(&vec, 1, 0, replacement, ARRAY_SIZE(replacement));
+ check_strvec(&vec, "foo", "1", "2", "bar", "baz", NULL);
+ strvec_clear(&vec);
+}
+
+void test_strvec__splice_at_tail(void)
+{
+ struct strvec vec = STRVEC_INIT;
+ const char *replacement[] = { "1", "2" };
+
+ strvec_pushl(&vec, "foo", "bar", NULL);
+ strvec_splice(&vec, 2, 0, replacement, ARRAY_SIZE(replacement));
+ check_strvec(&vec, "foo", "bar", "1", "2", NULL);
+ strvec_clear(&vec);
+}
+
void test_strvec__replace_at_head(void)
{
struct strvec vec = STRVEC_INIT;
diff --git a/t/unit-tests/unit-test.c b/t/unit-tests/unit-test.c
index a474cdcfd3..fa8818842a 100644
--- a/t/unit-tests/unit-test.c
+++ b/t/unit-tests/unit-test.c
@@ -18,8 +18,25 @@ int cmd_main(int argc, const char **argv)
N_("immediately exit upon the first failed test")),
OPT_STRING_LIST('r', "run", &run_args, N_("suite[::test]"),
N_("run only test suite or individual test <suite[::test]>")),
- OPT_STRING_LIST('x', "exclude", &exclude_args, N_("suite"),
+ OPT_STRING_LIST(0, "exclude", &exclude_args, N_("suite"),
N_("exclude test suite <suite>")),
+ /*
+ * Compatibility wrappers so that we don't have to filter
+ * options understood by integration tests.
+ */
+ OPT_NOOP_NOARG('d', "debug"),
+ OPT_NOOP_NOARG(0, "github-workflow-markup"),
+ OPT_NOOP_NOARG(0, "no-bin-wrappers"),
+ OPT_NOOP_ARG(0, "root"),
+ OPT_NOOP_ARG(0, "stress"),
+ OPT_NOOP_NOARG(0, "tee"),
+ OPT_NOOP_NOARG(0, "with-dashes"),
+ OPT_NOOP_ARG(0, "valgrind"),
+ OPT_NOOP_ARG(0, "valgrind-only"),
+ OPT_NOOP_NOARG('v', "verbose"),
+ OPT_NOOP_NOARG('V', "verbose-log"),
+ OPT_NOOP_ARG(0, "verbose-only"),
+ OPT_NOOP_NOARG('x', NULL),
OPT_END(),
};
struct strvec args = STRVEC_INIT;