Closed CrustyAuklet closed 2 months ago
This is a bit of an annoyance from the early design of the reporter configuration. The public report_callback
is there only for backwards compatibility, and should eventually be removed, I think.
I think the core or the issue is that registry
currently doesn't own the reporter state. We currently rely on global std::optional
variables, see e.g.:
https://github.com/snitch-org/snitch/blob/fe24bc41c5e2096914575e74a3b3350994bbd2dc/include/snitch/snitch_macros_reporter.hpp#L12-L16
It could be that the signature of the callbacks may have to change, see https://github.com/snitch-org/snitch/issues/80. Or we could reserve some storage space in the registry to allocate (in place) the reporter instance.
For this PR, I think we probably should stick with the current API and make it work (probably means having to create a global console reporter, or maybe store it as a member of the registry). If we can't, then we'll have to bite the bullet, break compatibility, and move to v2.0.
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 93.88%. Comparing base (
fe24bc4
) to head (4617561
).
For this PR, I think we probably should stick with the current API and make it work (probably means having to create a global console reporter, or maybe store it as a member of the registry). If we can't, then we'll have to bite the bullet, break compatibility, and move to v2.0.
making it a member wasn't a bad idea, at least for maintaining compatibility. Since the console reporter is the "default" reporter it's not that absurd I don't think.
I made it a static member, and added some private static functions that call it so that it can be registered with the add_reporter()
function. Then I added a public function (with the private API comment) called add_console_reporter()
that does the actual work of registering the console reporter so that it is in the registry as expected. These static functions can also be used to assign the report_callback
and finish_callback
members.
The add_console_reporter()
function can be called to initialize a static const
variable to replace the macro that registered the console reporter before. The same function can be used to register the console reporter in the mock framework in the tests to avoid adding more global instances.
Thanks, this is looking good!
I have only one issue with the implementation: the use of a static
member rather than a regular member. The instance of the reporter should really be tied to the instance of the registry
that uses it, otherwise there could be unexpected sharing of state. Granted, it's unlikely that there will be two registry
instances alive in a normal scenario, but it does happen in the snitch tests (testing snitch with itself).
The fault is actually mine; the REGISTER_REPORTER
macro that registers reporter classes already use global instances, rather than one instance per registry, which perhaps influenced your choice. It was a mistake on my part, and it needs correcting.
I have been experimenting on top of your PR to fix this, and have a working solution to remove this global state for all reporters, but this is out of scope of this PR. If this is OK with you, I propose we merge your PR as is, and I can follow up with my own changes in another PR to take it a step further.
I have only one issue with the implementation: the use of a static member rather than a regular member. The instance of the reporter should really be tied to the instance of the registry that uses it, otherwise there could be unexpected sharing of state. Granted, it's unlikely that there will be two registry instances alive in a normal scenario, but it does happen in the snitch tests (testing snitch with itself).
Agreed. The main reason was that the default value of report_callback
needed to be set, but if I added a constructor to registry
it would destroy it's ability to be constructed with aggregate initialization.
I took a closer look at the function_ref
type though and realized that it does in fact have storage for a pointer in addition to the function callable reference. This constructor fits the bill:
template<typename ObjectType, auto MemberFunction>
constexpr function_ref(ObjectType& obj, constant<MemberFunction>) noexcept;
So I just pushed a change where the console reporter isn't static and I use this constructor to set the default value of report_callback
and in registering the reporter.
Looks like CI got updated to MSVC 19.39 😄
could change
#if defined(SNITCH_COMPILER_MSVC) && _MSC_VER >= 1937 && _MSC_VER <= 1938
to
#if defined(__cpp_consteval) && __cpp_consteval <= 202211L
as suggested by horenmar in that issue.
If you don't mind, please!
This MR changes the console reporter from free functions to a struct, so that it can maintain state and count the tests when listing them.
I am stuck trying to figure out how to properly initialize the
report_callback
in the registry. When the console report function was a free function it could just get a reference to that function. But now that it is a struct there needs to be an instance somewhere. The registry isconstinit
so there shouldn't be a static order issue, but it also can't have a nonconstexpr
constructor.Some tests also required a reporter instance, and there I declared one either in the test function itself or in an anonymous namespace in the test file if the lifetime needed to outlast the spot it was used.