PHP make test failures - php

I'm rebuilding and upgrading PHP(5.3.2 -> 5.5.14) to match the current installation except with the addition of the pthread module.
My main question is about the seriousness of make test failures. Currently I'm sitting with 29 failures out of roughly 12,000 tests. (They are mostly DBA related and I probably just need to re compile that with different options or something). A few of the failures give a number that relates to a PHP bug case. I've visited the pages for the cases and they are all closed from a year or two ago and are for PHP 4.3 or something like that and they say the issues have been fixed.
Everything is compiling and installing just fine (I haven't started apache yet, so I don't know if it works 100%, but I've been able to run PHP scripts via php command), so do I need to worry about the failures from make test? Or are they actually resolved as the case pages say and the tests just have not been updated? (I can link actually cases if need be).
Bug Codes:
Bug #36436 (DBA problem with Berkeley DB4) [ext/dba/tests/bug36436.phpt]
Bug #48240 (DBA Segmentation fault dba_nextkey) [ext/dba/tests/bug48240.phpt]
Bug #49125 (Error in dba_exists C code) [ext/dba/tests/bug49125.phpt]
Bug #42298 (pcre gives bogus results with /u) [ext/pcre/tests/bug42298.phpt]
Bug #42737 (preg_split('//u') triggers a E_NOTICE with newlines[ext/pcre/tests/bug42737.phpt]
Bug #52971 (PCRE-Meta-Characters not working with utf-8) [ext/pcre/tests/bug52971.phpt]

The point of a test is that is should pass. If a test passes after a change is made, then the tester can be confident that the underlying behavior under test has not been changed as a result of the change. If a test fails after you make a change, then it means that the change caused the underlying behavior to change or break altogether.
Typically, breaking tests in the test suite and not fixing them is not a good practice, because then you are losing the value of implementing the tests in the first place. If you are not trying to preserve the functionality then what is the point of the test in the first place?
Go back to your upgrade and see if any of those bugs are serious. If they aren't, then consider modifying or deleting them. It is possible that the tests failed because there are some differences between your PHP versions, or possibly because the way you upgraded the language caused a problem.

Related

PHP's pg_connect() appears to be slower on a new

Got an obscure one. Been at this one for weeks. Here is what we’re doing:
Upgrade of Silverstripe 3.1 -> 3.7
Upgrade of Platform. PHP 5.6 -> 7.4, Postgres 9.5 -> 13
Old system is running mod_php, New is running PHP_FPM
Parallel hosting systems running. Old and New. Both have identical resources.
Performance tests run on both systems for Old -> New comparisons.
Both platforms consist of two App nodes, and one DB node
Most tests are great. PHP 7.4 obviously smokes the old system. But one test is Apache Bench just hitting home page. Which shows a pretty serious degradation on the New system. Digging further into this, we created a series of test files for Apache Bench to hit that isolate specific things - Static HTML, Raw PHP, PHP + Raw pg_ commands and queries.
All thrash the old system except the latter. DB interactions. So drilling down further we created a new target file that simply does a pg_connect() and immediately closes it, then hit that with Apache Bench. Same result as the query test script. Suggesting the deficit is in the action of pg_connect(). Database connections.
Clearly there's a lot of variables in this issue. And I'm loath to pack this question out with a bunch of details about the tests (and other tests like pgbench) until needed. I'm more hoping to stumble across someone who has observed a similar issue with pg_connect() specifically, and has even the most random idea for an angle to test.
Other testing ideas would be welcome. One thing we are trying to work out right now is how to get connection timing from pgbench to see if the issue exists on Postgres itself. Our tests are as follows:
Apache Bench hitting several target pages
PGBench (showing the new system performing better than the old)
PHP test
jMeter is being set up now
UPDATE
We've done a bit of manual digging in the Postgres logs in each environment, and see something a bit strange looking at the received/authorised log entry pairs like this:
2021-05-19 11:34:25.708 NZST,,,404734,"10.220.218.21:50560",60a44f01.62cfe,1,"",2021-05-19 11:34:25 NZST,,0,LOG,00000,"connection received: host=xx.xx.xx.xx port=50560",,,,,,,,,""
2021-05-19 11:34:25.908 NZST,"db_user","db_name",404734,"xx.xx.xx.xx:50560",60a44f01.62cfe,2,"authentication",2021-05-19 11:34:25 NZST,7/486524,0,LOG,00000,"connection authorized: user=db_user database=db_name",,,,,,,,,""
I captured a bunch of these pairs on both environments (Old and New) and calculated the gap between the recieved log message and the authentication log message.
On Old, the average is 0.011s. On New, the average is 0.195s. Difference aside, this makes no sense, as the test page on the application node of that environment takes ~0.02s to complete in full.

Intermittent PHP Abstract Class Error

I've been fighting this for a bit, and can't figure it out, maybe someone else has or maybe there's a deeper issue here with Slim, PHP, Apache etc. After working just fine for hours, my Slim install will start giving this on all routes:
Fatal error: Class Slim\Collection contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (IteratorAggregate::getIterator) in F:\Projects\example\server\vendor\slim\slim\Slim\Collection.php on line 21
Maddeningly this issue goes away if I restart Apache. (For a few hours anyway.)
I found this where someone had a similar problem two years ago, and the person helping badgered them without actually assisting at all: https://community.apachefriends.org/viewtopic.php?p=250966&sid=96ef58aaeb7fe142a7dcdfd506a8683f
I've tried doing a clean wipe and install of my composer vendor directory. This doesn't fix it. I can clearly see that getIterator is implemented as expected in the file in the error message.
PHP Version 7.0.12, Windows 7, x86 PHP Build
It happened again after a few hours, with a different but similar error message:
Fatal error: Class Pimple\Container contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (ArrayAccess::sqlserver) in F:\Projects\example\server\vendor\pimple\pimple\src\Pimple\Container.php on line 34
This question has a similar problem and "solves" it by restarting PHP, but that clearly isn't an actual solution, and I don't have opcache enabled:
PHP 7, Symfony 3: Fatal error 1 abstract method and must therefore be declared abstract or implement the remaining methods
Any guesses? Remember: This message is in files I didn't write, and goes away on Apache restart. Is there some caching with PHP 7 that would cause this?
Edit 3/10/17:
Yes, I've opened a ticket with Slim. I also saw it in a non-slim file (Pimple) so I don't think it is a Slim issue.
https://github.com/slimphp/Slim/issues/2160
As I said, my opcache is off. I've confirmed this is true both in the php.ini file and looking at phpinfo().
I think you've run into this opcache bug. This isn't exactly the same situation but probably related.
After calling opcache_reset() function we encounter some weird errors.
It happens randomly on servers (10 of 400 servers production)
Some letter a replaced by others, Class seems to be already declared..
etc
Example of errors triggered after opcache_reset():
PHP Fatal error: Class XXX contains 1 abstract method and must therefore be declared abstract or implement the remaining methods
(YYY::funczzz) in /dir/dir/x.php on line 20
The ticket is closed because the developers don't have enough information to reproduce it. If you could come up with the smallest reproducible case I recommend reporting it. Create a very small Slim app and then use JMeter or another tool to make many requests. Post your findings.
Meanwhile the only workaround might be to turn off opcache in php.ini:
opcache.enable=0
Of course this will drastically hurt performance. Until it's fixed you'll have to choose between performance or periodically restarting Apache.
If turning the cache off doesn't work then the only cause I could think of is an intermittent problem with the opcode compiler. Cached or not the compiled version must have an error in it. Opening a reproducible ticket with the PHP devs or debugging the PHP source yourself would be the only way forward if this is the cause.
I had the same problem using CodeIgniter and PHP 7.1.x.
I upgraded to PHP 7.2 and the problem no longer occurred.
If you develop on Windows, I would recommend that you DON'T use XAMPP or WAMPP, and try out a real development server using Linux on a VM.
Try installing Vagrant and Virtualbox, then head to puphpet.com, which can generate you a virtual machine configuration. Unzip the download, cd in to the folder, type vagrant up. Then just point your host at the VM. I'll bet once you have a real development environment that this error will go away. Your other option is Docker, but that has a bit of a learning curve.
The problem isn't your code (or your vendor code), but your platform.
I have encountered this exact behaviour and it was not exactly an opcache bug, even if it was caused by opcache.
The problem was that we had several classes with the same base name, e.g.
Request\GenericProtocol\Dispatcher abstract
Request\Protocol1\Dispatcher
Request\Protocol2\Dispatcher
Now by default on our installation opcache used an "optimization" that used the basename only as cache key. As a result, whenever a script happened to instantiate a Protocol2 Dispatcher on a clean cache, it subtly sabotaged all subsequent calls with Protocol1. Due to usage patterns, this masqueraded as any other kind of bug.
In the end we just activated the appropriate option:
opcache.use_cwd boolean
If enabled, OPcache appends the current working directory to the script key, thereby eliminating possible collisions between files with the same base name. Disabling this directive improves performance, but may break existing applications.
The breaking condition is this: you have at least two classes with the same basename.
Our next iteration indeed is scheduled to rename a lot of classes
Request\Protocol1\Dispatcher ==> Request\Protocol1\Protocol1Dispatcher
to be able to re-disable use_cwd and squeeze a few percents of performance (PTBs and PHBs believe it is worth it), but I know that this may not be possible with every framework out there.

How to check if a PHP project works well with a new PHP Version

Is there a good way to test if a PHP project works well with a new version of PHP?
Lets say we have a project developed under PHP 5.0 and want to run it now with PHP 5.4. The project have no unit tests or something like that.
Just run it with PHP 5.4 and click around to see if there are errors is not save enough.
Run your tests. If you don't have tests, write some now under PHP 5.0. Then run them under 5.4. If they break, then you've found something that needs to be fixed. Having a suite of test scripts is good practice anyway so if you haven't got any, this is a good opportunity to start writing them. Look up phpUnit, which is the most common PHP tool for writing unit tests.
For creating a test suite on an existing project, I recommend using a tool like Selenium or Sahi which can record a browser session. Turn on the recording and start testing as normal. Voila: One repeatable test. You're going to have to do this kind of testing anyway, so you may as well record them. Granted, those are functional tests, rather than unit tests, but they are tests all the same, and if you can cover enough of your functionality with them then you'll have a fairly comprehensive demonstration that the system is working.
Syntax check: Use PHP's command-line -l option in a batch job to run a syntax check on all your files. This will prove that everything parses successfully.
That will eliminate the obvious problems.
Use a decent IDE to develop your code in. IDEs like Netbeans will highlight syntax issues and warning for you and underline the relevant code. This makes finding bugs much much easier.
If you're still developing in Notepad, you're missing out on a whole world of good stuff.
If you're using ereg() or related functions, they need to change to preg_match() etc. You can get away with still using mysql_query() for DB access, since that's only deprecated in 5.5, but if you're using it you may as well consider this to be a good time to make that change too.
Look up the Migration Guides provided by PHP. These give full details of all the code-breaking changes between PHP versions. In particular, pay attention to the deprecated features.
The most significant version for this was 5.3: A lot of old code was broken by the features which were deprected in 5.3. These were features like magic_quotes and register_globals; they had been considered bad practice for a very long time before that, but it took them until 5.3 to actually deprecate them. If you're using them, this will be the biggest problem you'll have to face.
Tools like PHPMD and PHPCodeSniffer, PHP Lint may help to analyse your code. They aren't really designed for version compatiblity checking, but may help you find issues.

Corrupt heap in PHP script

zend_mm_heap corrupted is coming up as an error message on a PHP program I wrote to pre-render a large environment.
I suspect it's being caused by having too many variable assignments in the script, although I'm uncertain of this since I wrote the script to only have about 20 variables at any given time, of which one is an array that may hold up to 500 elements. That said, the number of iterations in total is on the order of a few billion.
Am I correct in my suspicion, and if so is there anything that can be done about it? Would it be better, for instance, to run the script for a while, then dump out important variables to a file and restart the script, making it pick up those variables and continuing?
I've seen this problem, and can reproduce it using phalcon, but it seems to originate from APC cache. I fixed by switching from APC to zend opcache. You can try disabling APC to see if it goes away.
Best I can reason from my investigations is that APC is doing something to memory that zend is using. PS, it doesn't have anything to do with zend framework, it's an error related to the parts of zend that were merged into php.
The solution to your problem is to dowload the latest version of APC compatible with your PHP version.
You'll have to force install it making it overwrite the old version of APC. This will in many cases fix the issue you're having.

how to maintain older versions when php and its libraries keep upgrading

I had been using sqlite 2 which was included in the xampp bundle.
after while i installed latest xampp bundle which had sqlite3.
Now when i run my code i get error and found that sqlite 2 is not available with the bundle.
Things like this happens with php and all its related libraries for example split function others.
If it is the localsystem no problem we are going to update it anyway but in the shared hosting when they upgrade to new php versions the existing webpages through errors.
how do we know that php is going to remove some function and replace it with other new functions instead of retaining the same name but with upgraded functionality?
what happens is when they upgrade or change the versions of the current existing functions in the server is the website breaks. you can see errors all over the page. many page wont work. seo rating goes down if not noticed. the users will not trust the site. this happened with wordpress also and mediawiki which i had been using for a while and when they upgraded php recently the modules did not load instead i got fatal errors. this is nasty.
in this case it will be hectic to keep upgrading your code for a specific interval(whenever php upgrades their functionality)
this is going endless as far as i have known.
what is the solution for this in the server side and in localhost.
This is an issue indeed. And the only solution to this is:
Consider your dependencies very well before writing code against them.
Stay on the ball.
Before you decide to use any one particular technology to depend on, research whether it is slated for deprecation or is otherwise not recommended to be used in the future. The PHP guys are pretty good about pointing these things out in the manual, so reading the related pages on php.net is often good enough.
The PHP developers are pretty good about their deprecation process, having a very slow deprecation process for most of their APIs.
You will nevertheless need to stay on the ball. Follow the infrequent official announcements to get a feeling for what's changing and where you need to pay attention. The change logs for each major PHP release are usually worth studying.
If you have code running on a system which frequently changes without your doing, you need to pay attention to your host's announcements as well. If they don't announce major changes in advance, look for another host.
Build your error handlers so you'll be notified via email about serious errors. You may want to include a script which checks for the availability of major dependencies and notifies you if they're missing.
If you have critical code, you should not run it on shared hosts which do not offer you enough control over the platform. Run your own servers and be careful about upgrading PHP. There's a reason why old versions receive maintenance updates for a while.
Typically you have a system administrator manage the deployed code and the servers, you should communicate with this person what you require from the server and that person should talk to you if some major changes to the server are happening. If you are that person, like many sys-dev-ops are these days, you need to make this part of your job.
Good question.
I say you worry too much. The PHP team really cares of downward compatibility. I am using PHP for over 10 years now, web changed a lot in this time, so did PHP. Changes are running through a very long deprecation process and are announced very long before they actually happen. Even then, in the cases I remember, it still was possible to do the deprecated way with newer versions.
This all is valid for the PHP core and extensions which are delivered with PHP itself.
In case of SQLlite I can't recall what was the deal there, never really used it.
In one of the newer PHP 5 versions they introduced the deprecated bit in the log level.
If you switch your log level to E_ALL or -1 you'll get a line logged if you are using any deprecated function, so you are able to react early.
http://php.net/manual/en/function.error-reporting.php
In addition the release a list of depreciations and backward incompatible changes e.g.
http://php.net/manual/en/migration54.incompatible.php
All changes announced here were handled as bad practice many years before already so nobody should have to change code now.
I hope this is no longer killing you :) good luck

Categories