We currently only canonicalize the temp sandbox directory on macOS,
which is critical since `/tmp` is really `/private/tmp`. However, we
should do it everywhere, so that tests can actually expect a consistent
outcome by looking at `clar_sandbox_path()`.
In several circumstances, we get bug reports about things that happen in
situations where the environment is quite limited with regards to
available memory. While it's expected that functionality will fail if
memory allocations fail, the assumption is that we should do so in a
controlled way. Most importantly, we do not want to crash hard due to
e.g. accessing NULL pointers.
Naturally, it is quite hard to debug such situations. But since our
addition of pluggable allocators, we are able to implement allocators
that fail in deterministic ways, e.g. after a certain amount of bytes
has been allocated. This commit does exactly that.
To be able to properly keep track of the amount of bytes currently
allocated, allocated pointers contain tracking information. This
tracking information is currently limited to the number of bytes
allocated, so that we can correctly replenish them on calling `free` on
the pointer. In the future, it would be feasible to extend the tracked
information even further, e.g. by adding information about file and line
where the allocation has been performed. As this introduced some
overhead to allocations though, only information essential to limited
allocations is currently tracked.
`git__timer` is now `git_time_monotonic`, and returns milliseconds
since an arbitrary epoch.
Using a floating point to store the number of seconds elapsed was
clever, as it better supports the wide range of precision from the
different monotonic clocks of different systems. But we're a version
control system, not a real-time clock.
Milliseconds is a good enough precision for our work _and_ it's the
units that system calls like `poll` take and that our users interact
with.
Make `git_time_monotonic` return the monotonically increasing number
of milliseconds "ticked" since some arbitrary epoch.
Add functions to use convert a string with length, instead of assuming
NUL termination.
In addition, move the utf8 to 16 conversion routines into the `git_utf8`
namespace instead of using namespaceless `git__` prefixed names.
Now that we've split the notion of the home directory from the global
configuration store, our tests should use the appropriate one based on
what they're doing.
libgit2 can be built with optional, experimental sha256 support. This
allows consumers to begin testing and providing feedback for our sha256
support while we continue to develop it, and allows us to make API
breaking changes while we iterate on a final sha256 implementation.
The results will be `git2-experimental.dll` and installed as
`git2-experimental.h` to avoid confusion with a production libgit2.
This change makes it possible to build with newer versions of gcc
without warnings. There were two warnings issued:
* gcc 8 added
[`-Wstringop-truncation`](https://developers.redhat.com/blog/2018/05/24/detecting-string-truncation-with-gcc-8/),
which warns if a call to `strncpy(3)` is prone to accidentally
truncating the destination string, since `strncpy(3)` does NOT add a
terminating `NULL` if the destination buffer is not large enough to
hold the input.
This change uses the pattern suggested in
https://us-cert.cisa.gov/bsi/articles/knowledge/coding-practices/strncpy-and-strncat
to fix the locations flagged by gcc.
* There was a potentially uninitialized access of `dest` in `fs_copy`.
Similar to how clar has used `/bin/cp` to copy files, it's used
`/bin/rm` to remove them. This has similar deficiencies; meaning that
leaks is noisy and it's slow. Move it to an internal function.
clar has historically shelled out to `/bin/cp` to copy test fixtures
into a sandbox. This has two deficiencies:
1. It's slower than simply opening the source and destination and
copying them in a read/write loop. On my Mac, the `/bin/cp` based
approach takes ~2:40 for a full test pass. Using a read/write loop
to copy the files ourselves takes ~1:50.
2. It's noisy. Since the leak detector follows fork/exec, we'll end up
running the leak detector on `/bin/cp`. This would be fine, except
that the leak detector spams the console on startup and shutdown, so
it adds a _lot_ of additional information to the test runs that is
useless. By not forking and using this internal system, we see much
less output.
We use the `__LINE__` macro in several places throughout clar to allow
easier traceability when e.g. a test fails. While `__LINE__` is of type
`size_t`, the clar functions all accept an integer and thus may loose
precision. While unlikely that any file in our codebase will exceed a
linecount of `INT_MAX`, let's convert it anyway to silence any compiler
warnings.
motivation: (for someone new to the tests) it's puzzling to find the odd 'S' interspersed in the test output
proposed alternative test output (extract):
$ cmake --build . && ./libgit2_clar -srepo -v
...
Loaded 340 suites:
Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
repo::config...
repo::discover..........
repo::env.
repo::getters...
repo::hashfile..
repo::head......................
repo::headtree....
repo::init.........................S
repo::message..
repo::new..
repo::open.............
repo::pathspec..........
repo::reservedname.....
repo::setters.....
repo::shallow....
repo::state.............
Support hierarchical test resource data, such that you can have
`tests/resources/foo/bar` and move the `bar` directory in as
a fixture.
Calling `cl_fixture_sandbox` on a path that is not directly beneath
the test resources directory succeeds, placing that directory into
the test fixture. (For example, `cl_fixture_sandbox("foo/bar")`
will sandbox the `foo/bar` directory as `bar`).
Add support for cleaning up directories created this way, by only
cleaning up the basename (in this example, `bar`) from the fixture
directory.