Skip to content

Conversation

@rroelke
Copy link
Member

@rroelke rroelke commented Jan 5, 2026

This pull request adds an "interception" capability which allows us to run arbitrary code at pre-defined "interception points" which could be placed either in other unit test code, or within the library code itself.

Interception points can be used to strengthen our tests in several ways. We can log seemingly arbitrary details of an execution to assert that certain conditions are met by a user input; we can simulate errors occurring at specific points in an execution; we can synchronize multiple threads to ensure a deterministic outcome from multi-threaded code; and more.

This pull request adds macros DECLARE_INTERCEPT, DEFINE_INTERCEPT, and INTERCEPT for instrumenting code with interception points, and also add a unit test which demonstrates instrumenting a "library function" in each of the aforementioned ways.


TYPE: NO_HISTORY
DESC: Add interception capability

@rroelke
Copy link
Member Author

rroelke commented Jan 5, 2026

To spread awareness I have added all core developers as reviewers.

Copy link
Member

@teo-tsirpanis teo-tsirpanis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can log seemingly arbitrary details of an execution to assert that certain conditions are met by a user input

Why is (p|i)assert not sufficient?

Comment on lines 113 to 118
#define INTERCEPT(name, ...) \
do { \
([](auto... args) { \
name().event(std::forward<decltype(args)>(args)...); \
})(__VA_ARGS__); \
} while (0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be not a macro?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macro is useful for

#ifdef TILEDB_INTERCEPTS
#define INTERCEPT(name, ...) <etc>
#else
#define INTERCEPT(...)
#endif

@rroelke
Copy link
Member Author

rroelke commented Jan 7, 2026

We can log seemingly arbitrary details of an execution to assert that certain conditions are met by a user input

Why is (p|i)assert not sufficient?

I don't think I was clear. What I am thinking is something more analogous to code coverage than to an assert - i.e. does a certain input cause a particular event to happen.

For example, with #5700 we want to observe that the read query thread waits for memory to become available if it does not have enough to buffer at least one cell. We can set up input which we expect to cause this to happen but we don't have a way to ask afterwards if it actually did. But we could place an INTERCEPT at the right spot to record when it happens, and then have the test check.

Copy link
Member

@kounelisagis kounelisagis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@bekadavis9 bekadavis9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for adding this

@rroelke rroelke merged commit 242e27c into main Jan 23, 2026
56 checks passed
@rroelke rroelke deleted the rr/unit-test-intercepts branch January 23, 2026 01:56
rroelke added a commit that referenced this pull request Jan 23, 2026
This is a follow-up to #5725 which added the `INTERCEPT` capability to
inject essentially arbitrary code into pre-defined points in the
execution of the core library (when enabled by the feature, of course).

This pull request uses this new capability to replace an older class
whose goal was quite similar: the `UnitTestConfig`. This class was a
singleton with some predefined parameters which could be set by unit
tests and then checked in-line by the library code in order to simulate
specific behaviors. Based on its broad inclusion in test sources, this
class probably used to do more than it does now; as of this writing it
has just one parameter which is used in one place.

This is an excellent use case for interception since we can move the
test parameter exclusively into the test code, with the library code
just intercepting relevant variables from its stack frame. So, this pull
request replaces the old with the new.

---
TYPE: NO_HISTORY
DESC: replace UnitTestConfig with INTERCEPT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants