On Tue, Dec 24, 2024 at 8:22 PM Ben Ramsey <b...@benramsey.com> wrote:

> On Dec 16, 2024, at 07:21, Jakub Zelenka <bu...@php.net> wrote:
>
> 
> Hi,
>
> I have been looking into how to test some cases where integration tests
> are very difficult or even impossible to create for. Those are often found
> in networking related and system specific code code (network.c, streams,
> FPM and more). I was recently fixing one such bug and decided to give a try
> which resulted in this PR: https://github.com/php/php-src/pull/16987 .
>
> There was a suggestion of RFC but that might be a bit too much as it's
> just an internal change / addition. But certainly some overview on
> internals should be done so writing this instead.
>
> I decided to use cmocka in that PR because I had some experience with
> that. It's quite small and still very powerful and allow vast mocking
> options. It's a bit manual but it gives a bigger control over the mock. It
> relies on --wrap linking option that replaces original functions with
> wraps. This is however available only on Linux (or maybe some other Unix
> variants) but doesn't work on MacOS or Windows. The developers that want to
> use it on those platforms would need to use some Linux Virtualisation
> option (e.g. Docker). It also requires static library which is supported by
> embed SAPI that can be compiled statically. That limits number of
> extensions to use but the main use cases don't really have deps so it
> should be fine.
>
> I did also some research into the other mocking libraries in C. There is a
> Unity with CMock, FFF and some C++ libs like GUnit, Criterion and
> Trompeloeil that I looked into. I quickly discarded GUnit and Trompeloeil
> as they relay on C++ virtual methods and require wrapping C code to C++
> which is very inconvenient. FFF seems too simple and maybe quite inflexible
> for our needs as well. Criterion also optionally uses wrap so I didn't see
> much advantages compare to cmocka. So it left Unity with CMock that allows
> generating custom mocks using a Ruby script. That seemed initially quite
> nice but after spending around two hours with trying to make it works for
> PHP codebase, I just gave up. It gets quite messy for complex scenarios and
> I just didn't figure out how to nicely mock libc functions without any
> modification to php-src.
>
> In terms of CI. It has got its own build which is very simple and it tests
> just specific parts so we could just limit it to run only for changed files
> which might be quite convenient.
>
> So the proposed PR is probably the only reasonable unit testing that I can
> come up with. I think it should be completely optional initially for people
> to use - more like an experiment. If it becomes used, then good of course.
> And if it becomes pain, we can just get rid of it. Has anyone got any
> objections to get this merged? If not I plan to merge it early in January.
>
> Cheers
>
> Jakub
>
>
>
> FWIW, as someone still very new to C, I found Criterion quite easy to use,
> and I was able to quickly grasp its concepts and start using it right away.
> I can’t say the same for other C testing libraries I tried.
>

I just checked Criterion a bit more and it actually does not have built-in
mocking. It could be used with --wrap but it doesn't have any expectations
like cmocka. There's Mimick [1] from the same author which is indendent but
its docs still say that it's experimental so probably not a good idea to
use an experimental tool as its API can change. So all in all it's not
probably an option for us.

[1] https://github.com/Snaipe/Mimick

Cheers

Jakub

Reply via email to