Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126175 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 3B3D41A00BD for ; Tue, 24 Dec 2024 19:22:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1735067959; bh=PLQE3J6bOiV97lavYro50eGLAk0rh69lRSu/nDR2bJ8=; h=From:Subject:Date:References:Cc:In-Reply-To:To:From; b=VvZnQ5phPIeCCi/DeBNiGCzvdKppA1b85M94EdIipEBufXksG0yKpjToumhhusr1P uDqEpZWgN767pgqAS0F8z8tldnF+yBUddrJOz4goQf6tf8AjXLMzMH9uYNIf8zuVpi DRuNfv/mReseqRU49LhlEbceQkY2NYghkT1Twz1TVQiMPmfH9njcj3LqTV596u27i1 BJdtWPKZ1rSWRheK7aFX/8YBp37oMjUR/jsGTCMsBStp0Nxc6trPs930iTnnkJbGZ6 AM1jiJiBXaQnl/RMmpJk24aCBcrTKROmWq+PV8xIuNoUk/MeaOgKt+/Y7FRBGDFueG sMRYMUFkcdOGg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0A0D6180003 for ; Tue, 24 Dec 2024 19:19:18 +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.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,HTML_MESSAGE, MIME_QP_LONG_LINE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-yb1-f179.google.com (mail-yb1-f179.google.com [209.85.219.179]) (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 ; Tue, 24 Dec 2024 19:19:17 +0000 (UTC) Received: by mail-yb1-f179.google.com with SMTP id 3f1490d57ef6-e53a5ff2233so3123586276.3 for ; Tue, 24 Dec 2024 11:22:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=benramsey.com; s=google; t=1735068137; x=1735672937; darn=lists.php.net; h=to:in-reply-to:cc:references:message-id:date:subject:mime-version :from:content-transfer-encoding:from:to:cc:subject:date:message-id :reply-to; bh=bmfw378vOqxW4HZvZtbYdjKyZ6YqgIPreHkeWFe110k=; b=euIUuCvvDKyklPCId/h3Bl5PWqPAMvhEMTweraCEebsFByTHJ1wLvijm9V+x67OVjb /J/HcyTKMMcrK8DWPM/il5IT/AVS72Qg+A5fjRageO9hCRJosQKJPi28ZnRSctZFJ5U6 +7AddyhG/dLtzsbV8rdL2OtfFEL0ujMgr5DIasXXZDFRuhb9NhG9Y1aOZ+GOD1xiLJSx egzQsWo9lxeB9XKs2IKVuNM2izSTBuBmgEYCNOvjeFjoh6LHqJ1VtN055DgXsz+CoTiO wX1pky+qfXaWTUBqDC9RznGDwkR04UJHCTKLhiXC1t/O2Fjp5WfCYyscT0DVAIBc6SLD jDgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735068137; x=1735672937; h=to:in-reply-to:cc:references:message-id:date:subject:mime-version :from:content-transfer-encoding:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bmfw378vOqxW4HZvZtbYdjKyZ6YqgIPreHkeWFe110k=; b=Piwfh9MGHyndc7hVisIMtswTV5pDux4LBiDt/YXULuwEldylQP7+RtfTYBCPQubFIy HfUzr4caYBq70jI7J05ly6hbo4ZZfTecKzDTZJYBKNyw4eNaY4JBX6auBWqWXMJRz7wd pcJfty4+aa3S7LkyAqTdXTbCOkzF1x9sT1o2FVqoDGEaO2bvezXgQW6GUYS2I0XE/WLX wmr8KjCaYWlLgTosmwDdIbzYA7Y80NCvWyQA550Y8PjQqH41sBYCi3p/bfEjwyrztD38 94PCPgtcXOYZlD6JgGyGpkDhvKkkd7CY9g4b8oDl0gs9HH5nkMWG+X6x5Q0zpIzojYhm 5BKA== X-Gm-Message-State: AOJu0YwKckBZwHWM9/k6UtBdRjPjDpIKULHFTKvxxM+ZiREnpMI9oWf6 8G9E4Vhy2FRuBrySb4dvuQGRFtro5MRQVaM6M3mTAI9T3etChCI/xejExs5tY2t3ZULNho9Dd0k = X-Gm-Gg: ASbGncuSg+YEnpSr/ROwJuNw6nhpoiMhfP925L59W6wGnln3ilgpB1GWLLBnFz8V5Mo Gfy48DeEn5MYAZML81zrVrsiAvDHVVB1C7EOZLwsHjxUDQ2RYM4xWX/0gybQSEIogX55DmgOxCe tRkNem90nChAx24xdUBBJATty7lJ7oXNi18YRPfd4ICuPPLZCBJ8J+6r7wEOTVgawVOwQostjFO Zndo+mshCkhI4S4BJclbS+0qYRrSz4mf8s2Ud+DWfgeEkTdx5thhFAL/Oy5h0Iln1yMgXecRvC1 NuI51GesetvwzjMF3MnyN12AxiJEZ6r7znE2arr9SQtX9e60 X-Google-Smtp-Source: AGHT+IF8mmgG5gXp7Jg1nPZT+ReeFZeotVesLcn+HLKRoHHbqvhbEsyJjD1b0DhJHJrGRbJklcrXWQ== X-Received: by 2002:a05:690c:6b02:b0:6ef:5ca3:d0f1 with SMTP id 00721157ae682-6f3f823f1d7mr127870187b3.40.1735068137519; Tue, 24 Dec 2024 11:22:17 -0800 (PST) Received: from smtpclient.apple (h96-61-170-179.lvrgtn.broadband.dynamic.tds.net. [96.61.170.179]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6f3e783a9ddsm29709627b3.112.2024.12.24.11.22.16 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 24 Dec 2024 11:22:16 -0800 (PST) Content-Type: multipart/alternative; boundary=Apple-Mail-39C07BC4-B061-493D-9851-473825241EEB Content-Transfer-Encoding: 7bit Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow Mime-Version: 1.0 (1.0) Subject: Re: [PHP-DEV] C Unit testing and mocking Date: Tue, 24 Dec 2024 13:22:06 -0600 Message-ID: References: Cc: PHP internals list In-Reply-To: To: Jakub Zelenka X-Mailer: iPhone Mail (22C152) From: ben@benramsey.com (Ben Ramsey) --Apple-Mail-39C07BC4-B061-493D-9851-473825241EEB Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable > On Dec 16, 2024, at 07:21, Jakub Zelenka wrote: >=20 > =EF=BB=BF > Hi, >=20 > I have been looking into how to test some cases where integration tests ar= e very difficult or even impossible to create for. Those are often found in n= etworking 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 r= esulted 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 jus= t an internal change / addition. But certainly some overview on internals sh= ould 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. I= t'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 ho= wever 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 plat= forms 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 com= piled statically. That limits number of extensions to use but the main use c= ases 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 Trompeloe= il that I looked into. I quickly discarded GUnit and Trompeloeil as they rel= ay on C++ virtual methods and require wrapping C code to C++ which is very i= nconvenient. FFF seems too simple and maybe quite inflexible for our needs a= s well. Criterion also optionally uses wrap so I didn't see much advantages c= ompare to cmocka. So it left Unity with CMock that allows generating custom m= ocks using a Ruby script. That seemed initially quite nice but after spendin= g around two hours with trying to make it works for PHP codebase, I just gav= e 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. A= nd if it becomes pain, we can just get rid of it. Has anyone got any objecti= ons to get this merged? If not I plan to merge it early in January. >=20 > Cheers >=20 > Jakub FWIW, as someone still very new to C, I found Criterion quite easy to use, a= nd I was able to quickly grasp its concepts and start using it right away. I= can=E2=80=99t say the same for other C testing libraries I tried. Cheers, Ben --Apple-Mail-39C07BC4-B061-493D-9851-473825241EEB Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
= On Dec 16, 2024, at 07:21, Jakub Zelenka <bukka@php.net> wrote:
=EF=BB=BFHi,

I have been looking into how to test som= e cases where integration tests are very difficult or even impossible to cre= ate for. Those are often found in networking related and system specific cod= e code (network.c, streams, FPM and more). I was recently fixing one such bu= g and decided to give a try which resulted in this PR: https://github.com/php/php-src/pull/16= 987 .

There was a suggestion of RFC but that mi= ght be a bit too much as it's just an internal change / addition. But certai= nly some overview on internals should be done so writing this instead.
=

I decided to use cmocka in that PR because I had some ex= perience with that. It's quite small and still very powerful and allow vast m= ocking options. It's a bit manual but it gives a bigger control over the moc= k. It relies on --wrap linking option that replaces original functions with w= raps. This is however available only on Linux (or maybe some other Unix vari= ants) but doesn't work on MacOS or Windows. The developers that want to use i= t 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 t= hat can be compiled statically. That limits number of extensions to use but t= he 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. T= here is a Unity with CMock, FFF and some C++ libs like GUnit, Criterion and T= rompeloeil that I looked into. I quickly discarded GUnit and Tromp= eloeil 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 allows= generating custom mocks using a Ruby script. That seemed initially quite ni= ce but after spending around two hours with trying to make it works for PHP c= odebase, I just gave up. It gets quite messy for complex scenarios and I jus= t didn't figure out how to nicely mock libc functions without any modificati= on to php-src.

In terms of CI. It has got its own b= uild which is very simple and it tests just specific parts so we could just l= imit it to run only for changed files which might be quite convenient.
=

So the proposed PR is probably the only reasonable unit t= esting that I can come up with. I think it should be completely optional ini= tially 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 anyo= ne 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 t= o C, I found Criterion quite easy to use, and I was able to quickly grasp it= s concepts and start using it right away. I can=E2=80=99t say the same for o= ther C testing libraries I tried.

Cheers,
Ben

= --Apple-Mail-39C07BC4-B061-493D-9851-473825241EEB--