Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126127 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 F00B81A00BD for ; Mon, 16 Dec 2024 13:18:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1734354955; bh=8IfudZl4v/zZJxJCys6WxmjH9YMdqujd5wV5oGKbot4=; h=From:Date:Subject:To:From; b=I/FIg+J0YNfVL+mvXUr+CfZ0VtHQja9A/JqEgUzkEQL8xf1fEuAJnnq+OM+z8iRAQ BOnaMGQwlm215QMWY8cfQzbND/MW1pvslllIyPtCeMlA6oEz7CGtQVN1qNpWuhAh9M zfRLluf/M8VtkUIVocMJqQ4LYQVvgC3HUJ+4o4mWrvZVkjQlyNA5MY8v3mb8WS9yr/ nmDy85GCHTPZrVyKlKULd1NonCWF+ha5I3gHvYFXKBEARWI/9kmlsAEBczCciyDkqP RpEHo3/63VdcWR+YrbLJVzMQ+Thbe1OI81M8uOyRTTNL3CeBgf+qR/8MOF/xIOoH/a VCj45oF/9iM6A== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id F40551801D5 for ; Mon, 16 Dec 2024 13:15:54 +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-f49.google.com (mail-oo1-f49.google.com [209.85.161.49]) (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 13:15:54 +0000 (UTC) Received: by mail-oo1-f49.google.com with SMTP id 006d021491bc7-5f32fab5de9so753357eaf.2 for ; Mon, 16 Dec 2024 05:18:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734355137; x=1734959937; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=8IfudZl4v/zZJxJCys6WxmjH9YMdqujd5wV5oGKbot4=; b=CQDnLWeWaalsj5YIOjNLBk9A/O5367FbxdbKJdSXU0G4rip2lUaBAKnexiniHnRNon jhl+mHUPluzwJWRLHrPVtNHadE14Pu0sTg9hguhEEHHKoMZpTVSblHUcKzgOODYa+TKI 2jZTLyilHqc5mGjt6tfZzQ+WLdBG14IjXLY+oD2fvjC3wwxytcDWy5wfZtdtcfcBWAVB TJCyhebbWoFJbdPj4QkGfVDnlW7KKHoGV38W75Rww+oBbzCWX1FW0znal2BfIEgQ+j5l 5yhNlracs1QlXYAVaT/VW3tzd0N2pMxK/aT/5Zn6y7IEFwY2lqVlV2UDnaVTpTOVwoMB 8gxQ== X-Gm-Message-State: AOJu0Yz1DvS/uWVH3atFca96DAFSK/FpOevVYWVDn6o0DZO7zXPSTnPA 2nyrqQHn3B7ExplYgKABDFIatAHFqqzM/nQpb1n3WOl2KbjRrKfO1TtFMJ3GarTdgbjC7rhEUgL ClUqqdb0sJxUBEdtlBLI2HZ+TJ6FFFHEb X-Gm-Gg: ASbGncsM8ojvagFZ+UKcjwp6CphtsjmzQqCfgpp+u/1Z1+eapRbJn24JjQK0gmobguL lERld7uDT2EeH7A3LhPWbWP4eJkizDedB6pbQEQ== X-Google-Smtp-Source: AGHT+IHm0bTXERxVH0hG7+aTb8FKeNGKjlthHoVhj+LIWglXQdeszCL6B5M4FFLPm70sd7LpLYVsEQRNbsGDsR+QQWs= X-Received: by 2002:a05:6870:c906:b0:296:aef8:fe9a with SMTP id 586e51a60fabf-2a3ac4b4af7mr6114745fac.7.1734355137202; Mon, 16 Dec 2024 05:18:57 -0800 (PST) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Mon, 16 Dec 2024 14:18:46 +0100 Message-ID: Subject: [PHP-DEV] C Unit testing and mocking To: PHP internals list Content-Type: multipart/alternative; boundary="000000000000de12110629630562" From: bukka@php.net (Jakub Zelenka) --000000000000de12110629630562 Content-Type: text/plain; charset="UTF-8" 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 --000000000000de12110629630562 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

I have been looking into how to tes= t some cases where integration tests are very difficult or even impossible = to create for. Those are often found in networking related and system speci= fic 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-s= rc/pull/16987 .

There was a suggestion of RFC = but that might be a bit too much as it's just an internal change / addi= tion. But certainly some overview on internals should be done so writing th= is instead.

I decided to use cmocka in that PR bec= ause I had some experience with that. It's quite small and still very p= owerful 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 rep= laces original functions with wraps. This is however available only on Linu= x (or maybe some other Unix variants) but doesn't work on MacOS or Wind= ows. The developers that want to use it on those platforms would need to us= e some Linux Virtualisation option (e.g. Docker). It also requires static l= ibrary which is supported by embed SAPI that can be compiled statically. Th= at limits number of extensions to use but the main use cases don't real= ly have deps so it should be fine.

I did also some= research into the other mocking libraries in C. There is a Unity with CMoc= k, FFF and some C++ libs like GUnit, Criterion and Trompeloeil that I looke= d into. I quickly discarded=C2=A0GUnit and=C2=A0Trompeloeil as they relay o= n C++ virtual methods and require wrapping C code to C++ which is very inco= nvenient. FFF seems too simple and maybe quite inflexible for our needs as = well. Criterion also optionally uses wrap so I didn't see much advantag= es compare to cmocka. So it left Unity with CMock that allows generating cu= stom 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 lim= it it to run only for changed files which might be quite convenient.
<= div>
So the proposed PR is probably the only reasonable unit = testing that I can come up with. I think it should be completely optional i= nitially for people to use - more like an experiment. If it becomes used, t= hen 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 ear= ly in January.

Cheers

Jak= ub

--000000000000de12110629630562--