Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126128 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 7D3E51A00BD for ; Mon, 16 Dec 2024 15:04:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1734361314; bh=Pdyn5lFhsbilUBgLclz9Svccz95ZLvfjs9b5kRCB1Pc=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=PTLG9XEDWHnLZ7zaQB0B0QqKOYJF+OReSKW87CEWfZ84h/Z3V+lbYFYJGXvz/Lp2z I8jBS3gKesv1uBifSBZwwNqfz3HswtH9Xl+qXy/feTas18b3wjA/8+Jcj+aQ+Uw1a/ sN0EMHVxetncdEiSolM0HXvowyR4Ma8ULxsdZPFqB5O5FGPXAzOodKsGevv64PEK5R pdzcdakF/aBKvNS98V5E0RBBEfgMOsjiWO+8rVLGpTZ4T7zGUP4oGcCf00vD7jzQda MrmfIBcjfwFRhm3fxsiQNu0QCZngLw9E27fAWRFBaW2/hG/1LBDYXK6Emh0mEubbiL yC289SgDPW+cg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C5DE6180052 for ; Mon, 16 Dec 2024 15:01:53 +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=0.8 required=5.0 tests=BAYES_50,DMARC_MISSING, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from supercat.cmpct.info (supercat.cmpct.info [71.19.146.230]) (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 ; Mon, 16 Dec 2024 15:01:53 +0000 (UTC) Received: from smtpclient.apple (fctnnbsc38w-142-162-55-237.dhcp-dynamic.fibreop.nb.bellaliant.net [142.162.55.237]) by supercat.cmpct.info (Postfix) with ESMTPSA id C10F0558F3; Mon, 16 Dec 2024 15:04:54 +0000 (UTC) Content-Type: text/plain; charset=utf-8 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3776.700.51.11.1\)) Subject: Re: [PHP-DEV] C Unit testing and mocking In-Reply-To: Date: Mon, 16 Dec 2024 11:04:43 -0400 Cc: PHP internals list Content-Transfer-Encoding: quoted-printable Message-ID: References: To: Jakub Zelenka X-Mailer: Apple Mail (2.3776.700.51.11.1) From: calvin@cmpct.info (Calvin Buckley) On Dec 16, 2024, at 9:18=E2=80=AFAM, Jakub Zelenka = wrote: >=20 > Hi, >=20 > 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 . >=20 > 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. >=20 > 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. >=20 > 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. >=20 > 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. >=20 > 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. >=20 > Cheers >=20 > Jakub >=20 I'm assuming that uses ELF symbol interposition or something like that, which is why it seems Linux/BSD specific. That seems fragile to me. I think currently for wanting to test C functions, we're adding custom functions into ext/zend_test and writing PHPT. Would this work? We already have that, after all. If not, it'd be helpful to list the challenges that approach faces.=