Hi
On 9/26/22 09:28, Andreas Heigl wrote:
Isn't it already covered natively by https://wiki.php.net/rfc/rng_extension?
IMO Yes and No.
The rng_extension describes the Random\Engine interface. This interface
has only the `generate` method which returns a string. The length of
this string can not be specified.
Indeed, because the engines represent some externally specified
algorithm that operates on a well-specified "output size".
In general the idea of the whole package was to "Create a single
Randomizer class which provides various randomization methods (like get
int/bytes, shuffle string/arrays). This class will take an Engine
interface in the constructor which can be swapped based on users needs.
ext/random provides Random\Randomizer as a high-level interface to an
engine's randomness. It will call the underlying engine as needed to
obtain enough random bits to perform the requested operation, without
introducing any biases.
Some essential RNG engines will be prepackaged for convenience but an
Interface will also be provided so that algorithms can be easily added."
The main task here is to ease adding randomizers in the core later.
The task is only to a certain extend to allow interoperability (due to
everyone using those methods) but sadly not to ease testing as the
methods of the provided Randomizer class are not based on an interface.
So to be able to test this with fixed values you will have to depend on
the Random\Randomizer-class and inject your own fixed Random\Engine
implementation. There is no way to replace the Random\Randomizer with
something else.
The engine is intended to be the pluggable part, not the Randomizer. I'd
say if you pass along an instance of Random\Randomizer, then you are
doing it wrong. Your service should create a Randomizer based on the
provided engine by itself if it wants to use the Randomizer's high level
interface.
The same is true if the Randomizer's API does not provide what you need.
If you use a library providing additional high level functionality, then
that library should take an engine. If it uses the Randomizer internally
as a building block, then that should be considered an implementation
detail.
For testing purposes you can provide a engine that is seeded with a
fixed seed (new Xoshiro256StarStar(hash('sha256', 'My PHPUnit Seed',
true)) would work) - or you can provide your own userland engine that
provides whatever values you need. You just need to be careful that the
userland engine is not too biased, because otherwise the Randomizer
might be unable to generate an unbiased result and throw
(BrokenRandomEngineError).
So if that is enough of interoperability, then I'm fine with that and
there is no need for any further investigation.
I'd say that "testing randomness" in general pretty hard and the same is
true when mocking the randomness. You can't really verify that your
logic exhibits the properties it should have. For example you can't test
that Randomizer::getInt() really is unbiased:
https://dilbert.com/strip/2001-10-25.
The tests in PHP itself only verify that getInt() does not return
numbers outside of the request change for a sufficiently large number of
attempts:
https://github.com/php/php-src/blob/master/ext/random/tests/03_randomizer/methods/getInt.phpt
For some superficial tests based on hardcoded results, the pluggable
Engine should be sufficient.
Best regards
Tim Düsterhus
--
You received this message because you are subscribed to the Google Groups "PHP
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/php-fig/c34c3918-e44b-9cac-89e6-793927dca73d%40bastelstu.be.