Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126177 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 0E2511A00BD for ; Thu, 26 Dec 2024 12:19:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1735215400; bh=xMdHBQWW3gMSnSfu4U0MKQ4lqwr5aiCOleZjjVQk0+8=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=ISQtws5a8DIABIJmwzFI7heb/b9F+fVs/fUZXQ9WGvjz9X7XyyY0Ki4XWZ0Cf7vFP kiC2PgLrFfcv4RFXdmX75NRPs5GHU+jMIcWDYA0/HNbjPKOQNT30cm1D1/5Z/PnuZA DnQ1VBFIUmCi4/Jn9ReZlhHUE5OFZWkwXsOO96dy3Ga3ctlSqelaOSy0ujBW/vs1pu impx6xZ6/JTHzJe2pgQUCkx6q95N+aAFH+8X6Y80a4eKwrGt2MU0hS/Rn43sYf0poz tFcZwURocU3qr6bDU7lVJwctqaPrJEhlh9xsHvohp+Vb02UasOjZBEUW8Njc5BN3Zn 4ttATn3zEEc3A== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 67E4D18003E for ; Thu, 26 Dec 2024 12:16:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: * X-Spam-Status: No, score=2.0 required=5.0 tests=BAYES_50,DMARC_NONE, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-oo1-f52.google.com (mail-oo1-f52.google.com [209.85.161.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 26 Dec 2024 12:16:38 +0000 (UTC) Received: by mail-oo1-f52.google.com with SMTP id 006d021491bc7-5f2efbc31deso3170629eaf.3 for ; Thu, 26 Dec 2024 04:19:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735215578; x=1735820378; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=xMdHBQWW3gMSnSfu4U0MKQ4lqwr5aiCOleZjjVQk0+8=; b=PUV0i+exG2a77ILOv41g2R5xOqYmiSHh6Vn3wOjgr6C92OkkoqWCsh0t8CDdMM8/oQ 4jQ1qtl8OGN20COmKOhAhoWiG8Qbzu6tv3H9eciAoFanfOpo/iDyq/0gvA2AL1Z36/ox MHbdUsHAdN8asSP4uQ9fKj2+3IkJFBsfNUkeDyQZ09Dit4w7qCcnq8eVVRPOnyQ2uQHf 3aKhQR9V7/WIMaj4r6YHrQHxGRAuZTEUfBkXUskgJFK/yizhdGoD596toeRN2S89+vST MhXYq0p/jYCyJoZjPuBDp/sUW+c2WQXTo4Cg8ZgtD9pA31+su1qT2v+lclphT3Sz+vcm bVOQ== X-Gm-Message-State: AOJu0YyZ9xB3TDgmAuvN2OHDUqYSA9HXozM3Ex1nMYBDTBZtHWmWm2SA v3D2tRXgB5VMcm8QH1rU6d/ony7af3LgB1dQkN+VYlD/1tue3FS2HH8aN7peRoMttWpIJsRpeRr XqNLVD7lSMVL6TX+Nb1A1ofbmc3w= X-Gm-Gg: ASbGncsWb81X1iS9nrn0b7iQ8cpVQYQwsNguiqq+PKbH0QmlpT1DRspn8ncvDM1D3b5 yMPTgZvuIHUnmM5YwreL80jwt4IR63eP1rqY= X-Google-Smtp-Source: AGHT+IFGHHNR+gmYjv3I0bzUUUPjBiO8KqfN1QBlBFowClvUCLEGTx0vXH/dKyI2zHLCwWCUI2hA6pJIzG1RgpiarWI= X-Received: by 2002:a05:6870:6986:b0:297:241b:c48 with SMTP id 586e51a60fabf-2a7fb3a528amr11092864fac.40.1735215578290; Thu, 26 Dec 2024 04:19:38 -0800 (PST) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 26 Dec 2024 13:19:27 +0100 Message-ID: Subject: Re: [PHP-DEV] C Unit testing and mocking To: Ben Ramsey Cc: PHP internals list Content-Type: multipart/alternative; boundary="00000000000027234b062a2b5ca4" From: bukka@php.net (Jakub Zelenka) --00000000000027234b062a2b5ca4 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Dec 24, 2024 at 8:22=E2=80=AFPM Ben Ramsey wrot= e: > On Dec 16, 2024, at 07:21, Jakub Zelenka wrote: > > =EF=BB=BF > 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 foun= d > 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 t= ry > 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. I= t > 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 inflexib= le > for our needs as well. Criterion also optionally uses wrap so I didn't se= e > much advantages compare to cmocka. So it left Unity with CMock that allow= s > 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 a= nd > 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 test= s > just specific parts so we could just limit it to run only for changed fil= es > which might be quite convenient. > > So the proposed PR is probably the only reasonable unit testing that I ca= n > come up with. I think it should be completely optional initially for peop= le > 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 awa= y. > I can=E2=80=99t 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 --00000000000027234b062a2b5ca4 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Tue, Dec 24, 2024 at 8:22=E2=80=AFPM B= en Ramsey <ben@benramsey.com>= ; wrote:
On Dec 16, 2024, at 07:21, Jakub Zelenka <bukka@php.net> wrote:
=EF=BB= =BF
Hi,

I have been looking into how to = test some cases where integration tests are very difficult or even impossib= le to create for. Those are often found in networking related and system sp= ecific 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:=C2=A0https:/= /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 i= nternal 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 s= mall 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 li= nking option that replaces original functions with wraps. This is however a= vailable 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 platf= orms would need to use some Linux Virtualisation option (e.g. Docker). It a= lso requires static library which is supported by embed SAPI that can be co= mpiled 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 Tro= mpeloeil that I looked into. I quickly discarded=C2=A0GUnit and=C2=A0Trompe= loeil 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 inflexi= ble for our needs as well. Criterion also optionally uses wrap so I didn= 9;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 scenario= s and I just didn't figure out how to nicely mock libc functions withou= t 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 qui= te 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 jus= t 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=E2=80=99t say the same fo= r other C testing libraries I tried.

I just checked Criterion a bit more and it actually does not have bui= lt-in mocking. It could be used with --wrap but it doesn't have any exp= ectations like cmocka. There's Mimick [1] from the same author which is= indendent but its docs still say that it's experimental so probably no= t 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.


Cheers

Jakub
--00000000000027234b062a2b5ca4--