summaryrefslogtreecommitdiff
path: root/t/unit-tests
AgeCommit message (Collapse)Author
2024-10-17reftable: convert from `strbuf` to `reftable_buf`Patrick Steinhardt
Convert the reftable library to use the `reftable_buf` interface instead of the `strbuf` interface. This is mostly a mechanical change via sed(1) with some manual fixes where functions for `strbuf` and `reftable_buf` differ. The converted code does not yet handle allocation failures. This will be handled in subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2024-10-17reftable: stop using `strbuf_addf()`Patrick Steinhardt
We're about to introduce our own `reftable_buf` type to replace `strbuf`. One function we'll have to convert is `strbuf_addf()`, which is used in a handful of places. This function uses `snprintf()` internally, which makes porting it a bit more involved: - It is not available on all platforms. - Some platforms like Windows have broken implementations. So by using `snprintf()` we'd also push the burden on downstream users of the reftable library to make available a properly working version of it. Most callsites of `strbuf_addf()` are trivial to convert to not using it. We do end up using `snprintf()` in our unit tests, but that isn't much of a problem for downstream users of the reftable library. While at it, remove a useless call to `strbuf_reset()` in `t_reftable_stack_auto_compaction_with_locked_tables()`. We don't write to the buffer before this and initialize it with `STRBUF_INIT`, so there is no need to reset anything. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2024-10-10Merge branch 'ps/reftable-alloc-failures'Junio C Hamano
The reftable library is now prepared to expect that the memory allocation function given to it may fail to allocate and to deal with such an error. * ps/reftable-alloc-failures: (26 commits) reftable/basics: fix segfault when growing `names` array fails reftable/basics: ban standard allocator functions reftable: introduce `REFTABLE_FREE_AND_NULL()` reftable: fix calls to free(3P) reftable: handle trivial allocation failures reftable/tree: handle allocation failures reftable/pq: handle allocation failures when adding entries reftable/block: handle allocation failures reftable/blocksource: handle allocation failures reftable/iter: handle allocation failures when creating indexed table iter reftable/stack: handle allocation failures in auto compaction reftable/stack: handle allocation failures in `stack_compact_range()` reftable/stack: handle allocation failures in `reftable_new_stack()` reftable/stack: handle allocation failures on reload reftable/reader: handle allocation failures in `reader_init_iter()` reftable/reader: handle allocation failures for unindexed reader reftable/merged: handle allocation failures in `merged_table_init_iter()` reftable/writer: handle allocation failures in `reftable_new_writer()` reftable/writer: handle allocation failures in `writer_index_hash()` reftable/record: handle allocation failures when decoding records ...
2024-10-10t/unit-tests: fix typosAndrew Kreimer
Fix typos via codespell. Signed-off-by: Andrew Kreimer <algonell@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable: introduce `REFTABLE_FREE_AND_NULL()`Patrick Steinhardt
We have several calls to `FREE_AND_NULL()` in the reftable library, which of course uses free(3P). As the reftable allocators are pluggable we should rather call the reftable specific function, which is `reftable_free()`. Introduce a new macro `REFTABLE_FREE_AND_NULL()` and adapt the callsites accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable: fix calls to free(3P)Patrick Steinhardt
There are a small set of calls to free(3P) in the reftable library. As the reftable allocators are pluggable we should rather call the reftable specific function, which is `reftable_free()`. Convert the code accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable: handle trivial allocation failuresPatrick Steinhardt
Handle trivial allocation failures in the reftable library and its unit tests. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable/tree: handle allocation failuresPatrick Steinhardt
The tree interfaces of the reftable library handle both insertion and searching of tree nodes with a single function, where the behaviour is altered between the two via an `insert` bit. This makes it quit awkward to handle allocation failures because on inserting we'd have to check for `NULL` pointers and return an error, whereas on searching entries we don't have to handle it as an allocation error. Split up concerns of this function into two separate functions, one for inserting entries and one for searching entries. This makes it easy for us to check for allocation errors as `tree_insert()` should never return a `NULL` pointer now. Adapt callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable/block: handle allocation failuresPatrick Steinhardt
Handle allocation failures in `block_writer_init()` and `block_reader_init()`. This requires us to bubble up error codes into `writer_reinit_block_writer()`. Adapt call sites accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable/reader: handle allocation failures in `reader_init_iter()`Patrick Steinhardt
Handle allocation failures in `reader_init_iter()`. This requires us to also adapt `reftable_reader_init_*_iterator()` to bubble up the new error codes. Adapt callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable/merged: handle allocation failures in `merged_table_init_iter()`Patrick Steinhardt
Handle allocation failures in `merged_table_init_iter()`. While at it, merge `merged_iter_init()` into the function. It only has a single caller and merging them makes it easier to handle allocation failures consistently. This change also requires us to adapt `reftable_stack_init_*_iterator()` to bubble up the new error codes of `merged_table_iter_init()`. Adapt callsites accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable/writer: handle allocation failures in `reftable_new_writer()`Patrick Steinhardt
Handle allocation failures in `reftable_new_writer()`. Adapt the function to return an error code to return such failures. While at it, rename it to match our code style as we have to touch up every callsite anyway. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-02reftable/basics: handle allocation failures in `parse_names()`Patrick Steinhardt
Handle allocation failures in `parse_names()` by returning `NULL` in case any allocation fails. While at it, refactor the function to return the array directly instead of assigning it to an out-pointer. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-30Merge branch 'ps/reftable-concurrent-writes'Junio C Hamano
Give timeout to the locking code to write to reftable. * ps/reftable-concurrent-writes: refs/reftable: reload locked stack when preparing transaction reftable/stack: allow locking of outdated stacks refs/reftable: introduce "reftable.lockTimeout"
2024-09-25Merge branch 'ps/reftable-exclude'Junio C Hamano
The reftable backend learned to more efficiently handle exclude patterns while enumerating the refs. * ps/reftable-exclude: refs/reftable: wire up support for exclude patterns reftable/reader: make table iterator reseekable t/unit-tests: introduce reftable library Makefile: stop listing test library objects twice builtin/receive-pack: fix exclude patterns when announcing refs refs: properly apply exclude patterns to namespaced refs
2024-09-24reftable/stack: allow locking of outdated stacksPatrick Steinhardt
In `reftable_stack_new_addition()` we first lock the stack and then check whether it is still up-to-date. If it is not we return an error to the caller indicating that the stack is outdated. This is overly restrictive in our ref transaction interface though: we lock the stack right before we start to verify the transaction, so we do not really care whether it is outdated or not. What we really want is that the stack is up-to-date after it has been locked so that we can verify queued updates against its current state while we know that it is locked for concurrent modification. Introduce a new flag `REFTABLE_STACK_NEW_ADDITION_RELOAD` that alters the behaviour of `reftable_stack_init_addition()` in this case: when we notice that it is out-of-date we reload it instead of returning an error to the caller. This logic will be wired up in the reftable backend in the next commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-18Merge branch 'ps/clar-unit-test'Junio C Hamano
Import clar unit tests framework libgit2 folks invented for our use. * ps/clar-unit-test: Makefile: rename clar-related variables to avoid confusion clar: add CMake support t/unit-tests: convert ctype tests to use clar t/unit-tests: convert strvec tests to use clar t/unit-tests: implement test driver Makefile: wire up the clar unit testing framework Makefile: do not use sparse on third-party sources Makefile: make hdr-check depend on generated headers Makefile: fix sparse dependency on GENERATED_H clar: stop including `shellapi.h` unnecessarily clar(win32): avoid compile error due to unused `fs_copy()` clar: avoid compile error with mingw-w64 t/clar: fix compatibility with NonStop t: import the clar unit testing framework t: do not pass GIT_TEST_OPTS to unit tests with prove
2024-09-16Merge branch 'cp/unit-test-reftable-stack'Junio C Hamano
Another reftable test migrated to the unit-test framework. * cp/unit-test-reftable-stack: t-reftable-stack: add test for stack iterators t-reftable-stack: add test for non-default compaction factor t-reftable-stack: use reftable_ref_record_equal() to compare ref records t-reftable-stack: use Git's tempfile API instead of mkstemp() t: harmonize t-reftable-stack.c with coding guidelines t: move reftable/stack_test.c to the unit testing framework
2024-09-16Merge branch 'ps/reftable-exclude' into ps/reftable-alloc-failuresJunio C Hamano
* ps/reftable-exclude: refs/reftable: wire up support for exclude patterns reftable/reader: make table iterator reseekable t/unit-tests: introduce reftable library Makefile: stop listing test library objects twice builtin/receive-pack: fix exclude patterns when announcing refs refs: properly apply exclude patterns to namespaced refs
2024-09-16Merge branch 'cp/unit-test-reftable-stack' into ps/reftable-alloc-failuresJunio C Hamano
* cp/unit-test-reftable-stack: t-reftable-stack: add test for stack iterators t-reftable-stack: add test for non-default compaction factor t-reftable-stack: use reftable_ref_record_equal() to compare ref records t-reftable-stack: use Git's tempfile API instead of mkstemp() t: harmonize t-reftable-stack.c with coding guidelines t: move reftable/stack_test.c to the unit testing framework
2024-09-16reftable/reader: make table iterator reseekablePatrick Steinhardt
In 67ce50ba26 (Merge branch 'ps/reftable-reusable-iterator', 2024-05-30) we have refactored the interface of reftable iterators such that they can be reused in theory. This patch series only landed the required changes on the interface level, but didn't yet implement the actual logic to make iterators reusable. As it turns out almost all of the infrastructure already does support re-seeking. The only exception is the table iterator, which does not reset its `is_finished` bit. Do so and add a couple of tests that verify that we can re-seek iterators. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-16t/unit-tests: introduce reftable libraryPatrick Steinhardt
We have recently migrated all of the reftable unit tests that were part of the reftable library into our own unit testing framework. As part of that migration we have duplicated some of the functionality that was part of the reftable test framework into each of the migrated test suites. This was a sensible decision to not have all of the migrations dependent on each other, but now that the migration is done it makes sense to deduplicate the functionality again. Introduce a new reftable test library that hosts some shared code and adapt tests to use it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-12Merge branch 'gt/unit-test-oid-array'Junio C Hamano
Another unit-test. * gt/unit-test-oid-array: t: port helper/test-oid-array.c to unit-tests/t-oid-array.c
2024-09-09Merge branch 'cp/unit-test-reftable-stack' into ps/reftable-excludeJunio C Hamano
* cp/unit-test-reftable-stack: t-reftable-stack: add test for stack iterators t-reftable-stack: add test for non-default compaction factor t-reftable-stack: use reftable_ref_record_equal() to compare ref records t-reftable-stack: use Git's tempfile API instead of mkstemp() t: harmonize t-reftable-stack.c with coding guidelines t: move reftable/stack_test.c to the unit testing framework
2024-09-09t-reftable-stack: add test for stack iteratorsChandra Pratap
reftable_stack_init_ref_iterator and reftable_stack_init_log_iterator as defined by reftable/stack.{c,h} initialize a stack iterator to iterate over the ref and log records in a reftable stack respectively. Since these functions are not exercised by any of the existing tests, add a test for them. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-09t-reftable-stack: add test for non-default compaction factorChandra Pratap
In a recent codebase update (commit ae8e378430, merge branch 'ps/reftable-write-options', 2024/05/13) the geometric factor used in auto-compaction of reftable tables was made configurable. Add a test to verify the functionality introduced by this update. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-09t-reftable-stack: use reftable_ref_record_equal() to compare ref recordsChandra Pratap
In the current stack tests, ref records are compared for equality by sometimes using the dedicated function for ref-record comparison, reftable_ref_record_equal(), and sometimes by explicity comparing contents of the ref records. The latter method is undesired because there can exist unequal ref records with some of the contents being equal. Replace the latter instances of ref-record comparison with the former. This has the added benefit of preserving uniformity throughout the test file. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-08t-reftable-stack: use Git's tempfile API instead of mkstemp()Chandra Pratap
Git's tempfile API defined by $GIT_DIR/tempfile.{c,h} provides a unified interface for tempfile operations. Since reftable/stack.c uses this API for all its tempfile needs instead of raw functions like mkstemp(), make the ported stack test strictly use Git's tempfile API as well. A bigger benefit is the fact that we know to clean up the tempfile in case the test fails because it gets registered and pruned via a signal handler. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-08t: harmonize t-reftable-stack.c with coding guidelinesChandra Pratap
Harmonize the newly ported test unit-tests/t-reftable-stack.c with the following guidelines: - Single line 'for' statements must omit curly braces. - Structs must be 0-initialized with '= { 0 }' instead of '= { NULL }'. - Array sizes and indices should preferably be of type 'size_t' and not 'int'. - Function pointers should be passed as 'func' and not '&func'. While at it, remove initialization for those variables that are re-used multiple times, like loop variables. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-08t: move reftable/stack_test.c to the unit testing frameworkChandra Pratap
reftable/stack_test.c exercises the functions defined in reftable/stack.{c, h}. Migrate reftable/stack_test.c to the unit testing framework. Migration involves refactoring the tests to use the unit testing framework instead of reftable's test framework and renaming the tests to be in-line with unit-tests' standards. Since some of the tests use set_test_hash() defined by reftable/test_framework.{c, h} but these files are not '#included' in the test file, copy this function in the ported test file. With the migration of stack test to the unit-tests framework, "test-tool reftable" becomes a no-op. Hence, get rid of everything that uses "test-tool reftable" alongside everything that is used to implement it. While at it, alphabetically sort the cmds[] list in helper/test-tool.c by moving the entry for "dump-reftable". Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-06Merge branch 'jk/unused-parameters'Junio C Hamano
Make our codebase compilable with the -Werror=unused-parameter option. * jk/unused-parameters: CodingGuidelines: mention -Wunused-parameter and UNUSED config.mak.dev: enable -Wunused-parameter by default compat: mark unused parameters in win32/mingw functions compat: disable -Wunused-parameter in win32/headless.c compat: disable -Wunused-parameter in 3rd-party code t-reftable-readwrite: mark unused parameter in callback function gc: mark unused config parameter in virtual functions
2024-09-04t/unit-tests: convert ctype tests to use clarPatrick Steinhardt
Convert the ctype tests to use the new clar unit testing framework. Introduce a new function `cl_failf()` that allows us to print a formatted error message, which we can use to point out which of the characters was classified incorrectly. This results in output like this on failure: # start of suite 1: ctype not ok 1 - ctype::isspace --- reason: | Test failed. 0x0d is classified incorrectly: expected 0, got 1 at: file: 't/unit-tests/ctype.c' line: 36 function: 'test_ctype__isspace' --- ok 2 - ctype::isdigit ok 3 - ctype::isalpha ok 4 - ctype::isalnum ok 5 - ctype::is_glob_special ok 6 - ctype::is_regex_special ok 7 - ctype::is_pathspec_magic ok 8 - ctype::isascii ok 9 - ctype::islower ok 10 - ctype::isupper ok 11 - ctype::iscntrl ok 12 - ctype::ispunct ok 13 - ctype::isxdigit ok 14 - ctype::isprint Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04t/unit-tests: convert strvec tests to use clarPatrick Steinhardt
Convert the strvec tests to use the new clar unit testing framework. This is a first test balloon that demonstrates how the testing infra for clar-based tests looks like. The tests are part of the "t/unit-tests/bin/unit-tests" binary. When running that binary with an injected error, it generates TAP output: # ./t/unit-tests/bin/unit-tests TAP version 13 # start of suite 1: strvec ok 1 - strvec::init ok 2 - strvec::dynamic_init ok 3 - strvec::clear not ok 4 - strvec::push --- reason: | String mismatch: (&vec)->v[i] != expect[i] 'foo' != 'fo' (at byte 2) at: file: 't/unit-tests/strvec.c' line: 48 function: 'test_strvec__push' --- ok 5 - strvec::pushf ok 6 - strvec::pushl ok 7 - strvec::pushv ok 8 - strvec::replace_at_head ok 9 - strvec::replace_at_tail ok 10 - strvec::replace_in_between ok 11 - strvec::replace_with_substring ok 12 - strvec::remove_at_head ok 13 - strvec::remove_at_tail ok 14 - strvec::remove_in_between ok 15 - strvec::pop_empty_array ok 16 - strvec::pop_non_empty_array ok 17 - strvec::split_empty_string ok 18 - strvec::split_single_item ok 19 - strvec::split_multiple_items ok 20 - strvec::split_whitespace_only ok 21 - strvec::split_multiple_consecutive_whitespaces ok 22 - strvec::detach 1..22 The binary also supports some parameters that allow us to run only a subset of unit tests or alter the output: $ ./t/unit-tests/bin/unit-tests -h Usage: ./t/unit-tests/bin/unit-tests [options] Options: -sname Run only the suite with `name` (can go to individual test name) -iname Include the suite with `name` -xname Exclude the suite with `name` -v Increase verbosity (show suite names) -q Only report tests that had an error -Q Quit as soon as a test fails -t Display results in tap format -l Print suite names -r[filename] Write summary file (to the optional filename) Furthermore, running `make unit-tests` runs the binary along with all the other unit tests we have. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04t/unit-tests: implement test driverPatrick Steinhardt
The test driver in "unit-test.c" is responsible for setting up our unit tests and eventually running them. As such, it is also responsible for parsing the command line arguments. The clar unit testing framework provides function `clar_test()` that parses command line arguments and then executes the tests for us. In theory that would already be sufficient. We have the special requirement to always generate TAP-formatted output though, so we'd have to always pass the "-t" argument to clar. Furthermore, some of the options exposed by clar are ineffective when "-t" is used, but they would still be shown when the user passes the "-h" parameter to have the clar show its usage. Implement our own option handling instead of using the one provided by clar, which gives us greater flexibility in how exactly we set things up. We would ideally not use any "normal" code of ours for this such that the unit testing framework doesn't depend on it working correctly. But it is somewhat dubious whether we really want to reimplement all of the option parsing. So for now, let's be pragmatic and reuse it until we find a good reason in the future why we'd really want to avoid it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04Makefile: wire up the clar unit testing frameworkPatrick Steinhardt
Wire up the clar unit testing framework by introducing a new "unit-tests" executable. In contrast to the existing framework, this will result in a single executable for all test suites. The ability to pick specific tests to execute is retained via functionality built into the clar itself. Note that we need to be a bit careful about how we need to invalidate our Makefile rules. While we obviously have to regenerate the clar suite when our test suites change, we also have to invalidate it in case any of the test suites gets removed. We do so by using our typical pattern of creating a `GIT-TEST-SUITES` file that gets updated whenever the set of test suites changes, so that we can easily depend on that file. Another specialty is that we generate a "clar-decls.h" file. The test functions are neither static, nor do they have external declarations. This is because they are getting parsed via "generate.py", which then creates the external generations that get populated into an array. These declarations are only seen by the main function though. The consequence is that we will get a bunch of "missing prototypes" errors from our compiler for each of these test functions. To fix those errors, we extract the `extern` declarations from "clar.suite" and put them into a standalone header that then gets included by each of our unit tests. This gets rid of compiler warnings for every function which has been extracted by "generate.py". More importantly though, it does _not_ get rid of warnings in case a function really isn't being used by anything. Thus, it would cause a compiler error if a function name was mistyped and thus not picked up by "generate.py". The test driver "unit-test.c" is an empty stub for now. It will get implemented in the next commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04clar: stop including `shellapi.h` unnecessarilyJohannes Schindelin
The `shellapi.h` header was included as of https://github.com/clar-test/clar/commit/136e763211aa, to have `SHFileOperation()` declared so that it could be called. However, https://github.com/clar-test/clar/commit/5ce31b69b525 removed that call, and therefore that `#include <shellapi.h>` is unnecessary. It is also unwanted in Git because this project uses a subset of Git for Windows' SDK in its CI builds that (for bandwidth reasons) excludes tons of header files, including `shellapi.h`. So let's remove it. Note: Since the `windows.h` header would include `shellapi.h` anyway, we also define `WIN32_LEAN_AND_MEAN` to avoid this and similar other unnecessary includes before including `windows.h`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04clar(win32): avoid compile error due to unused `fs_copy()`Johannes Schindelin
When CLAR_FIXTURE_PATH is unset, the `fs_copy()` function seems not to be used. But it is declared as `static`, and GCC does not like that, complaining that it should not be declared/defined to begin with. We could mark this function as (potentially) unused by following the `MAYBE_UNUSED` pattern from Git's `git-compat-util.h`. However, this is a GCC-only construct that is not understood by Visual C. Besides, `clar` does not use that pattern at all. Instead, let's use the `((void)SYMBOL);` pattern that `clar` already uses elsewhere; This avoids the compile error by sorta kinda make the function used after a fashion. Note: GCC 14.x (which Git for Windows' SDK already uses) is able to figure out that this function is unused even though there are recursive calls between `fs_copy()` and `fs_copydir_helper()`; Earlier GCC versions do not detect that, and therefore the issue has been hidden from the regular Linux CI builds (where GCC 14.x is not yet used). That is the reason why this change is only made in the Windows-specific portion of `t/unit-tests/clar/clar/fs.h`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04clar: avoid compile error with mingw-w64Johannes Schindelin
When using mingw-w64 to compile the code, and using `_stat()`, it is necessary to use `struct _stat`, too, and not `struct stat` (as the latter is incompatible with the "dashed" version because it is limited to 32-bit time types for backwards compatibility). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04t/clar: fix compatibility with NonStopPatrick Steinhardt
The NonStop platform does not have `mkdtemp()` available, which we rely on in `build_sandbox_path()`. Fix this issue by using `mktemp()` and `mkdir()` instead on this platform. This has been cherry-picked from the upstream pull request at [1]. [1]: https://github.com/clar-test/clar/pull/96 Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-04t: import the clar unit testing frameworkPatrick Steinhardt
Our unit testing framework is a homegrown solution. While it supports most of our needs, it is likely that the volume of unit tests will grow quite a bit in the future such that we can exercise low-level subsystems directly. This surfaces several shortcomings that the current solution has: - There is no way to run only one specific tests. While some of our unit tests wire this up manually, others don't. In general, it requires quite a bit of boilerplate to get this set up correctly. - Failures do not cause a test to stop execution directly. Instead, the test author needs to return manually whenever an assertion fails. This is rather verbose and is not done correctly in most of our unit tests. - Wiring up a new testcase requires both implementing the test function and calling it in the respective test suite's main function, which is creating code duplication. We can of course fix all of these issues ourselves, but that feels rather pointless when there are already so many unit testing frameworks out there that have those features. We line out some requirements for any unit testing framework in "Documentation/technical/unit-tests.txt". The "clar" unit testing framework, which isn't listed in that table yet, ticks many of the boxes: - It is licensed under ISC, which is compatible. - It is easily vendorable because it is rather tiny at around 1200 lines of code. - It is easily hackable due to the same reason. - It has TAP support. - It has skippable tests. - It preprocesses test files in order to extract test functions, which then get wired up automatically. While it's not perfect, the fact that clar originates from the libgit2 project means that it should be rather easy for us to collaborate with upstream to plug any gaps. Import the clar unit testing framework at commit 1516124 (Merge pull request #97 from pks-t/pks-whitespace-fixes, 2024-08-15). The framework will be wired up in subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-03Merge branch 'ps/reftable-concurrent-compaction'Junio C Hamano
The code path for compacting reftable files saw some bugfixes against concurrent operation. * ps/reftable-concurrent-compaction: reftable/stack: fix segfault when reload with reused readers fails reftable/stack: reorder swapping in the reloaded stack contents reftable/reader: keep readers alive during iteration reftable/reader: introduce refcounting reftable/stack: fix broken refnames in `write_n_ref_tables()` reftable/reader: inline `reader_close()` reftable/reader: inline `init_reader()` reftable/reader: rename `reftable_new_reader()` reftable/stack: inline `stack_compact_range_stats()` reftable/blocksource: drop malloc block source
2024-09-01t: port helper/test-oid-array.c to unit-tests/t-oid-array.cGhanshyam Thakkar
helper/test-oid-array.c along with t0064-oid-array.sh test the oid-array.h API, which provides storage and processing efficiency over large lists of object identifiers. Migrate them to the unit testing framework for better runtime performance and efficiency. As we don't initialize a repository in these tests, the hash algo that functions like oid_array_lookup() use is not initialized, therefore call repo_set_hash_algo() to initialize it. And init_hash_algo():lib-oid.c can aid in this process, so make it public. Mentored-by: Christian Couder <chriscool@tuxfamily.org> Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com> Helped-by: Phillip Wood <phillip.wood123@gmail.com> Signed-off-by: Ghanshyam Thakkar <shyamthakkar001@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-08-29Merge branch 'cp/unit-test-reftable-block'Junio C Hamano
Another test for reftable library ported to the unit test framework. * cp/unit-test-reftable-block: t-reftable-block: mark unused argv/argc t-reftable-block: add tests for index blocks t-reftable-block: add tests for obj blocks t-reftable-block: add tests for log blocks t-reftable-block: remove unnecessary variable 'j' t-reftable-block: use xstrfmt() instead of xstrdup() t-reftable-block: use block_iter_reset() instead of block_iter_close() t-reftable-block: use reftable_record_key() instead of strbuf_addstr() t-reftable-block: use reftable_record_equal() instead of check_str() t-reftable-block: release used block reader t: harmonize t-reftable-block.c with coding guidelines t: move reftable/block_test.c to the unit testing framework
2024-08-29Merge branch 'ps/reftable-drop-generic'Junio C Hamano
The code in the reftable library has been cleaned up by discarding unused "generic" interface. * ps/reftable-drop-generic: reftable: mark unused parameters in empty iterator functions reftable/generic: drop interface t/helper: refactor to not use `struct reftable_table` t/helper: use `hash_to_hex_algop()` to print hashes t/helper: inline printing of reftable records t/helper: inline `reftable_table_print()` t/helper: inline `reftable_stack_print_directory()` t/helper: inline `reftable_reader_print_file()` t/helper: inline `reftable_dump_main()` reftable/dump: drop unused `compact_stack()` reftable/generic: move generic iterator code into iterator interface reftable/iter: drop double-checking logic reftable/stack: open-code reading refs reftable/merged: stop using generic tables in the merged table reftable/merged: rename `reftable_new_merged_table()` reftable/merged: expose functions to initialize iterators
2024-08-28Merge branch 'gt/unit-test-urlmatch-normalization'Junio C Hamano
Another rewrite of test. * gt/unit-test-urlmatch-normalization: t: migrate t0110-urlmatch-normalization to the new framework
2024-08-28t-reftable-block: mark unused argv/argcJeff King
This is conceptually the same as the cases in df9d638c24 (unit-tests: ignore unused argc/argv, 2024-08-17), but this unit test was migrated from the reftable tests in a parallel branch. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-08-28t-reftable-readwrite: mark unused parameter in callback functionJeff King
This spot was originally marked in in 4695c3f3a9 (reftable: mark unused parameters in virtual functions, 2024-08-17), but was copied in 5b539a5361 (t: move reftable/readwrite_test.c to the unit testing framework, 2024-08-13). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-08-26Merge branch 'jk/mark-unused-parameters'Junio C Hamano
Mark unused parameters as UNUSED to squelch -Wunused warnings. * jk/mark-unused-parameters: t-hashmap: stop calling setup() for t_intern() test scalar: mark unused parameters in dummy function daemon: mark unused parameters in non-posix fallbacks setup: mark unused parameter in config callback test-mergesort: mark unused parameters in trivial callback t-hashmap: mark unused parameters in callback function reftable: mark unused parameters in virtual functions reftable: drop obsolete test function declarations reftable: ignore unused argc/argv in test functions unit-tests: ignore unused argc/argv t/helper: mark more unused argv/argc arguments oss-fuzz: mark unused argv/argc argument refs: mark unused parameters in do_for_each_reflog_helper() refs: mark unused parameters in ref_store fsck callbacks update-ref: mark more unused parameters in parser callbacks imap-send: mark unused parameter in ssl_socket_connect() fallback
2024-08-23Merge branch 'cp/unit-test-reftable-readwrite'Junio C Hamano
* cp/unit-test-reftable-readwrite: t-reftable-readwrite: add test for known error t-reftable-readwrite: use 'for' in place of infinite 'while' loops t-reftable-readwrite: use free_names() instead of a for loop t: move reftable/readwrite_test.c to the unit testing framework
2024-08-23reftable/reader: introduce refcountingPatrick Steinhardt
It was recently reported that concurrent reads and writes may cause the reftable backend to segfault. The root cause of this is that we do not properly keep track of reftable readers across reloads. Suppose that you have a reftable iterator and then decide to reload the stack while iterating through the iterator. When the stack has been rewritten since we have created the iterator, then we would end up discarding a subset of readers that may still be in use by the iterator. The consequence is that we now try to reference deallocated memory, which of course segfaults. One way to trigger this is in t5616, where some background maintenance jobs have been leaking from one test into another. This leads to stack traces like the following one: + git -c protocol.version=0 -C pc1 fetch --filter=blob:limit=29999 --refetch origin AddressSanitizer:DEADLYSIGNAL ================================================================= ==657994==ERROR: AddressSanitizer: SEGV on unknown address 0x7fa0f0ec6089 (pc 0x55f23e52ddf9 bp 0x7ffe7bfa1700 sp 0x7ffe7bfa1700 T0) ==657994==The signal is caused by a READ memory access. #0 0x55f23e52ddf9 in get_var_int reftable/record.c:29 #1 0x55f23e53295e in reftable_decode_keylen reftable/record.c:170 #2 0x55f23e532cc0 in reftable_decode_key reftable/record.c:194 #3 0x55f23e54e72e in block_iter_next reftable/block.c:398 #4 0x55f23e5573dc in table_iter_next_in_block reftable/reader.c:240 #5 0x55f23e5573dc in table_iter_next reftable/reader.c:355 #6 0x55f23e5573dc in table_iter_next reftable/reader.c:339 #7 0x55f23e551283 in merged_iter_advance_subiter reftable/merged.c:69 #8 0x55f23e55169e in merged_iter_next_entry reftable/merged.c:123 #9 0x55f23e55169e in merged_iter_next_void reftable/merged.c:172 #10 0x55f23e537625 in reftable_iterator_next_ref reftable/generic.c:175 #11 0x55f23e2cf9c6 in reftable_ref_iterator_advance refs/reftable-backend.c:464 #12 0x55f23e2d996e in ref_iterator_advance refs/iterator.c:13 #13 0x55f23e2d996e in do_for_each_ref_iterator refs/iterator.c:452 #14 0x55f23dca6767 in get_ref_map builtin/fetch.c:623 #15 0x55f23dca6767 in do_fetch builtin/fetch.c:1659 #16 0x55f23dca6767 in fetch_one builtin/fetch.c:2133 #17 0x55f23dca6767 in cmd_fetch builtin/fetch.c:2432 #18 0x55f23dba7764 in run_builtin git.c:484 #19 0x55f23dba7764 in handle_builtin git.c:741 #20 0x55f23dbab61e in run_argv git.c:805 #21 0x55f23dbab61e in cmd_main git.c:1000 #22 0x55f23dba4781 in main common-main.c:64 #23 0x7fa0f063fc89 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #24 0x7fa0f063fd44 in __libc_start_main_impl ../csu/libc-start.c:360 #25 0x55f23dba6ad0 in _start (git+0xadfad0) (BuildId: 803b2b7f59beb03d7849fb8294a8e2145dd4aa27) While it is somewhat awkward that the maintenance processes survive tests in the first place, it is totally expected that reftables should work alright with concurrent writers. Seemingly they don't. The only underlying resource that we need to care about in this context is the reftable reader, which is responsible for reading a single table from disk. These readers get discarded immediately (unless reused) when calling `reftable_stack_reload()`, which is wrong. We can only close them once we know that there are no iterators using them anymore. Prepare for a fix by converting the reftable readers to be refcounted. Reported-by: Jeff King <peff@peff.net> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>