Skip to content

Unify structure for ext/random's engine tests #9321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions ext/random/tests/02_engine/all_serialize_error.phpt

Large diffs are not rendered by default.

22 changes: 15 additions & 7 deletions ext/random/tests/02_engine/all_serialize_native.phpt
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
--TEST--
Random: Engine: serialize: native
Random: Engine: Serialization of native engines must preserve the sequence
--FILE--
<?php

use Random\Engine\Mt19937;
use Random\Engine\PcgOneseq128XslRr64;
use Random\Engine\Xoshiro256StarStar;

$engines = [];
$engines[] = new \Random\Engine\Mt19937(1234);
$engines[] = new \Random\Engine\PcgOneseq128XslRr64(1234);
$engines[] = new \Random\Engine\Xoshiro256StarStar(1234);
$engines[] = new Mt19937(1234);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of a form like the first PR, where the implemented class name is defined in a separate file and iterated over. e.g.) engines.inc.
https://github.com/zeriyoshi/php-src/blob/ed42ae2c2fe30ad9e608b6e693cd3ef3c60f1d85/ext/random/tests/number_generator/common.inc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this not as readable, because one needs to keep the contents of the include file in the head, instead of simply reading the test from top to bottom.

$engines[] = new PcgOneseq128XslRr64(1234);
$engines[] = new Xoshiro256StarStar(1234);

foreach ($engines as $engine) {
for ($i = 0; $i < 1000; $i++) {
for ($i = 0; $i < 10_000; $i++) {
$engine->generate();
}

$engine2 = unserialize(serialize($engine));
for ($i = 0; $i < 5000; $i++) {

for ($i = 0; $i < 10_000; $i++) {
if ($engine->generate() !== $engine2->generate()) {
$className = $engine::class;
die("failure class: {$className} i: {$i}");

die("failure: {$className} at {$i}");
}
}
}

die('success');

?>
--EXPECT--
success
28 changes: 17 additions & 11 deletions ext/random/tests/02_engine/all_serialize_user.phpt
Original file line number Diff line number Diff line change
@@ -1,48 +1,54 @@
--TEST--
Random: Engine: serialize: user
Random: Engine: Serialization of user engines must preserve the sequence
--FILE--
<?php

final class User64 implements \Random\Engine
use Random\Engine;

final class User64 implements Engine
{
private int $count = 0;

public function generate(): string
{
return \pack('P*', ++$this->count);
return pack('P*', ++$this->count);
}
}

final class User32 implements \Random\Engine
final class User32 implements Engine
{
private int $count = 0;

public function generate(): string
{
return \pack('V', ++$this->count);
return pack('V', ++$this->count);
}
}

$engines = [];
if (\PHP_INT_SIZE >= 8) {
$engines[] = new \User64();
if (PHP_INT_SIZE >= 8) {
$engines[] = new User64();
}
$engines[] = new \User32();
$engines[] = new User32();

foreach ($engines as $engine) {
for ($i = 0; $i < 1000; $i++) {
for ($i = 0; $i < 10_000; $i++) {
$engine->generate();
}

$engine2 = unserialize(serialize($engine));
for ($i = 0; $i < 5000; $i++) {

for ($i = 0; $i < 10_000; $i++) {
if ($engine->generate() !== $engine2->generate()) {
$className = $engine::class;
die("failure class: {$className} i: {$i}");

die("failure: {$className} at {$i}");
}
}
}

die('success');

?>
--EXPECT--
success
8 changes: 5 additions & 3 deletions ext/random/tests/02_engine/mt19937_error.phpt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
--TEST--
Random: Engine: Mt19937: error pattern
Random: Engine: Mt19937: Invalid $mode parameter values must be rejected
--FILE--
<?php

use Random\Engine\Mt19937;

try {
new \Random\Engine\Mt19937(1234, 2);
} catch (\ValueError $e) {
new Mt19937(1234, 2);
} catch (ValueError $e) {
echo $e->getMessage(), PHP_EOL;
}

Expand Down
6 changes: 4 additions & 2 deletions ext/random/tests/02_engine/mt19937_serialize.phpt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
--TEST--
Random: Engine: Mt19937: serialize
Random: Engine: Mt19937: The serialization output must be stable
--FILE--
<?php

echo serialize(new \Random\Engine\Mt19937(1234));
use Random\Engine\Mt19937;

echo serialize(new Mt19937(1234));

?>
--EXPECT--
Expand Down
13 changes: 8 additions & 5 deletions ext/random/tests/02_engine/mt19937_value.phpt
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
--TEST--
Random: Engine: Mt19937: value
Random: Engine: Mt19937: For a reference seed a fixed reference value must be generated
--FILE--
<?php

$engine = new \Random\Engine\Mt19937(1234);
use Random\Engine\Mt19937;

for ($i = 0; $i < 10000; $i++) {
$engine = new Mt19937(1234);

for ($i = 0; $i < 10_000; $i++) {
$engine->generate();
}

echo \bin2hex($engine->generate());
var_dump(bin2hex($engine->generate()));

?>
--EXPECT--
60fe95d9
string(8) "60fe95d9"
15 changes: 10 additions & 5 deletions ext/random/tests/02_engine/pcgoneseq128xslrr64_jump_error.phpt
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
--TEST--
Random: Engine: PcgOneseq128XslRr64: Jump with negative $advance
Random: Engine: PcgOneseq128XslRr64: Negative jumps must be rejected
--FILE--
<?php

$engine = new \Random\Engine\PcgOneseq128XslRr64(1234);
$referenceEngine = new \Random\Engine\PcgOneseq128XslRr64(1234);
use Random\Engine\PcgOneseq128XslRr64;

$engine = new PcgOneseq128XslRr64(1234);
$referenceEngine = new PcgOneseq128XslRr64(1234);

try {
$engine->jump(-1);
} catch (ValueError $e) {
echo $e->getMessage(), PHP_EOL;
}

if ($engine->generate() !== $referenceEngine->generate()) {
die('failure: state changed');
for ($i = 0; $i < 10_000; $i++) {
if ($engine->generate() !== $referenceEngine->generate()) {
die('failure: state changed');
}
}

die('success');

?>
--EXPECT--
Random\Engine\PcgOneseq128XslRr64::jump(): Argument #1 ($advance) must be greater than or equal to 0
Expand Down
54 changes: 40 additions & 14 deletions ext/random/tests/02_engine/pcgoneseq128xslrr64_seed.phpt
Original file line number Diff line number Diff line change
@@ -1,37 +1,63 @@
--TEST--
Random: Engine: PcgOneseq128XslRr64: seed
Random: Engine: PcgOneseq128XslRr64: The seed parameter must work as expected
--FILE--
<?php declare(strict_types = 1);

$engine = new \Random\Engine\PcgOneseq128XslRr64(\random_int(\PHP_INT_MIN, \PHP_INT_MAX));
$engine = new \Random\Engine\PcgOneseq128XslRr64(\random_bytes(16));
use Random\Engine\PcgOneseq128XslRr64;

echo "Random integer seed", PHP_EOL;
$engine = new PcgOneseq128XslRr64(random_int(PHP_INT_MIN, PHP_INT_MAX));
echo PHP_EOL, PHP_EOL;

echo "Random string seed", PHP_EOL;
$engine = new PcgOneseq128XslRr64(random_bytes(16));
echo PHP_EOL, PHP_EOL;

echo "Invalid data type", PHP_EOL;
try {
$engine = new Random\Engine\PcgOneseq128XslRr64(1.0);
} catch (\Throwable $e) {
echo $e->getMessage() . PHP_EOL;
$engine = new PcgOneseq128XslRr64(1.0);
} catch (TypeError $e) {
echo $e->getMessage(), PHP_EOL;
}
echo PHP_EOL, PHP_EOL;

echo "Invalid string seed length", PHP_EOL;
try {
$engine = new Random\Engine\PcgOneseq128XslRr64('foobar');
} catch (\Throwable $e) {
echo $e->getMessage() . PHP_EOL;
$engine = new PcgOneseq128XslRr64('foobar');
} catch (ValueError $e) {
echo $e->getMessage(), PHP_EOL;
}
echo PHP_EOL, PHP_EOL;

$engine = new \Random\Engine\PcgOneseq128XslRr64("\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08");
echo "Valid string seed", PHP_EOL;
$engine = new PcgOneseq128XslRr64(str_repeat("\x01\x02\x03\x04\x05\x06\x07\x08", 2));

\var_dump($engine);
var_dump($engine);

for ($i = 0; $i < 1000; $i++) {
$engine->generate();
}
\var_dump(\bin2hex($engine->generate()));

var_dump(bin2hex($engine->generate()));

?>
--EXPECTF--
--EXPECT--
Random integer seed


Random string seed


Invalid data type
Random\Engine\PcgOneseq128XslRr64::__construct(): Argument #1 ($seed) must be of type string|int|null, float given


Invalid string seed length
Random\Engine\PcgOneseq128XslRr64::__construct(): Argument #1 ($seed) must be a 16 byte (128 bit) string
object(Random\Engine\PcgOneseq128XslRr64)#%d (%d) {


Valid string seed
object(Random\Engine\PcgOneseq128XslRr64)#3 (1) {
["__states"]=>
array(2) {
[0]=>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
--TEST--
Random: Engine: PcgOneseq128XslRr64: serialize
Random: Engine: PcgOneseq128XslRr64: The serialization output must be stable
--FILE--
<?php

echo serialize(new \Random\Engine\PcgOneseq128XslRr64(1234));
use Random\Engine\PcgOneseq128XslRr64;

echo serialize(new PcgOneseq128XslRr64(1234));

?>
--EXPECT--
Expand Down
13 changes: 8 additions & 5 deletions ext/random/tests/02_engine/pcgoneseq128xslrr64_value.phpt
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
--TEST--
Random: Engine: PcgOneseq128XslRr64: value
Random: Engine: PcgOneseq128XslRr64: For a reference seed a fixed reference value must be generated
--FILE--
<?php

$engine = new \Random\Engine\PcgOneseq128XslRr64(1234);
use Random\Engine\PcgOneseq128XslRr64;

for ($i = 0; $i < 10000; $i++) {
$engine = new PcgOneseq128XslRr64(1234);

for ($i = 0; $i < 10_000; $i++) {
$engine->generate();
}

$engine->jump(1234567);

echo \bin2hex($engine->generate());
var_dump(bin2hex($engine->generate()));

?>
--EXPECT--
b88e2a0f23720a1d
string(16) "b88e2a0f23720a1d"
61 changes: 21 additions & 40 deletions ext/random/tests/02_engine/user_compatibility.phpt
Original file line number Diff line number Diff line change
@@ -1,63 +1,44 @@
--TEST--
Random: Engine: User: compatibility
Random: Engine: Native engines can be wrapped without changing their sequence
--FILE--
<?php

$native_engine = new \Random\Engine\Mt19937(1234);
$user_engine = new class () implements \Random\Engine {
public function __construct(private $engine = new \Random\Engine\Mt19937(1234))
{
}

public function generate(): string
{
return $this->engine->generate();
}
};

for ($i = 0; $i < 1000; $i++) {
if ($native_engine->generate() !== $user_engine->generate()) {
die('failure Mt19937');
}
}
use Random\Engine;
use Random\Engine\Mt19937;
use Random\Engine\PcgOneseq128XslRr64;
use Random\Engine\Xoshiro256StarStar;

$native_engine = new \Random\Engine\PcgOneseq128XslRr64(1234);
$user_engine = new class () implements \Random\Engine {
public function __construct(private $engine = new \Random\Engine\PcgOneseq128XslRr64(1234))
class WrapperEngine implements Engine
{
public function __construct(private readonly Engine $engine)
{
}

public function generate(): string
{
return $this->engine->generate();
}
};

for ($i = 0; $i < 1000; $i++) {
if ($native_engine->generate() !== $user_engine->generate()) {
die('failure PcgOneseq128XslRr64');
}
}

$native_engine = new \Random\Engine\Xoshiro256StarStar(1234);
$user_engine = new class () implements \Random\Engine {
public function __construct(private $engine = new \Random\Engine\Xoshiro256StarStar(1234))
{
}
$engines = [];
$engines[] = new Mt19937(1234);
$engines[] = new PcgOneseq128XslRr64(1234);
$engines[] = new Xoshiro256StarStar(1234);

public function generate(): string
{
return $this->engine->generate();
}
};
foreach ($engines as $engine) {
$native_engine = clone $engine;
$user_engine = new WrapperEngine(clone $engine);

for ($i = 0; $i < 1000; $i++) {
if ($native_engine->generate() !== $user_engine->generate()) {
die('failure Xoshiro256StarStar');
for ($i = 0; $i < 10_000; $i++) {
if ($native_engine->generate() !== $user_engine->generate()) {
$className = $engine::class;
die("failure: {$className} at {$i}");
}
}
}

die('success');

?>
--EXPECT--
success
Loading