WIP: #25-fix-64bit-values #26

Draft
Little Fluffy Clouds wants to merge 8 commits from lfclouds/baza:#25-fix-64bit-values into stable
7 changed files with 301 additions and 59 deletions

View File

@ -1,5 +1,10 @@
root = true
[*]
charset = utf-8
indent_style = tab
tab_width = 4
[README.md]
charset = utf-8
indent_style = tab

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace mirzaev\baza;
// Files of the project
use mirzaev\baza\enumerations\architecture;
// Built-in libraries
use DomainExceptionn as exception_domain;
/**
* Core
*
* @package mirzaev/baza
*
* @method void architecture() Get PHP distribution architecture
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class core
{
public static function architecture(): ?architecture {
return match(PHP_INT_SIZE) {
4 => architecture::x86,
8 => architecture::x86_64,
default => throw new exception_domain('Failed to determinate the system architecture'),
};
}
}

View File

@ -6,6 +6,7 @@ namespace mirzaev\baza;
// Files of the project
use mirzaev\baza\enumerations\encoding,
mirzaev\baza\enumerations\architecture,
mirzaev\baza\enumerations\type;
// Built-in libraries
@ -166,7 +167,7 @@ class database
*
* @param mixed[] $values Values of the record
*
* @throws exceptiin_invalid_argument if the balue type not matches the column values types
* @throws exception_invalid_argument if the balue type not matches the column values types
* @throws exception_logic if amount of columns not matches the amount of values
*
* @return record|null The record instance
@ -234,12 +235,37 @@ class database
// Converting to the database encoding
$value = mb_convert_encoding($record->values()[$column->name], $this->encoding->value);
// Packung the value and writing into the buffer of packed values
// Packing the value and writing into the buffer of packed values
$packed .= pack($column->type->value . $column->length, $value);
}
/**
* PHP builtin pack() ignores 64-bit integer values
* found on 64-bit PHP distributions
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* In case of integer type on 64-bit PHP distributions
* we got to splice 64-bit integer into two separate longs
* next to each other in binary representation
*/
else if (core::architecture() === architecture::x86_64 &&
($column->type === type::integer ||
$column->type === type::integer_unsigned))
{
// Initialize variables for left and right masks of the 64-bit variable
$left = 0xffffffff00000000;
$right = 0x00000000ffffffff;
// Bitwise and the value with the left mask with shift right by 32bits to get first half of the integer
$l = ($record->values()[$column->name] & $left) >> 32;
// Bitwise and the value with the right mask to get the second half
$r = $record->values()[$column->name] & $right;
// Pack into 64bit binary value with two longs
$packed .= pack('NN', $l, $r);
} else {
// Other types
// Packung the value and writing into the buffer of packed values
// Packing the value and writing into the buffer of packed values
$packed .= pack($column->type->value, $record->values()[$column->name]);
}
}
@ -282,6 +308,23 @@ class database
// Writing into the buffer of readed values
$unpacked[] = $encoded;
}
/**
p * PHP builtin pack() ignores 64-bit integer values
* found on 64-bit PHP distributions
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* In case of integer type on 64-bit PHP distributions
* we got to reconstruct previosly spliced integer value
*/
else if (core::architecture() === architecture::x86_64 &&
($column->type === type::integer ||
$column->type === type::integer_unsigned))
{
// Unpacking the integer values into array of two longs
$value = unpack('N2', $binary ?? "\0");
// Reconstructing original integer value
$unpacked[] = $value[1] << 32 | $value[2];
} else {
// Other types

View File

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace mirzaev\baza\enumerations;
/**
* Architecture
*
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* @package mirzaev\baza\enumerations
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
enum architecture: int
{
case x86 = 32;
case x86_64 = 64;
}

View File

@ -61,6 +61,18 @@ enum type: string
public function size(): int
{
// Exit (success)
return strlen(pack($this->value, 0));
/**
* PHP builtin pack() ignores 64-bit integer values
* found on 64-bit PHP distributions
* @see https://www.php.net/manual/en/function.pack.php#109382
*
* Architecture-specific size should always be returned
*/
// If type is (unsigned) integer, return size of integer
return (strtoupper($this->value) === 'I')
? PHP_INT_SIZE
: strlen(pack($this->value, 0));
}
}

View File

@ -17,7 +17,7 @@ use DomainException as exception_domain;
* @method void __construct(string|int|float $values) Constructor
* @method array values() Read all values of the record
* @method void __set(string $name, mixed $value) Write the record value
* @method mized __get(string $name) Read the record value
* @method mixed __get(string $name) Read the record value
* @method void __unset(string $name) Delete the record value
* @method bool __isset(string $name) Check for initializing of the record value
*

View File

@ -3,9 +3,11 @@
declare(strict_types=1);
use mirzaev\baza\database,
mirzaev\baza\core,
mirzaev\baza\record,
mirzaev\baza\column,
mirzaev\baza\enumerations\encoding,
mirzaev\baza\enumerations\architecture,
mirzaev\baza\enumerations\type;
// Initializing path to the composer loader file (main project)
@ -34,6 +36,9 @@ require($autoload);
// Initializing path to the database file
$file = __DIR__ . DIRECTORY_SEPARATOR . 'temporary' . DIRECTORY_SEPARATOR . 'database.baza';
// Initilized architecture runtime constant
define('ARCHITECTURE', core::architecture());
echo "Started testing\n\n\n";
// Initializing the counter of actions
@ -53,27 +58,57 @@ if (!file_exists($file) || unlink($file)) {
// Initializing the test database
/* $database = new database() */
$database = (new database())
->encoding(encoding::utf8)
->columns(
new column('name', type::string, ['length' => 32]),
new column('second_name', type::string, ['length' => 64]),
new column('age', type::integer),
new column('height', type::float),
new column('active', type::char)
)
->connect($file);
if (ARCHITECTURE === architecture::x86_64) {
$database = (new database())
->encoding(encoding::utf8)
->columns(
new column('name', type::string, ['length' => 32]),
new column('second_name', type::string, ['length' => 64]),
new column('age', type::integer),
new column('height', type::float),
// 64-bit values test
new column('neuron_count', type::integer_unsigned),
new column('motivation', type::double),
new column('reputation', type::integer),
new column('active', type::char)
)
->connect($file);
} else {
$database = (new database())
->encoding(encoding::utf8)
->columns(
new column('name', type::string, ['length' => 32]),
new column('second_name', type::string, ['length' => 64]),
new column('age', type::integer),
new column('height', type::float),
new column('active', type::char)
)
->connect($file);
}
echo '[' . ++$action . "] Initialized the database\n";
// Initializing the record
$record = $database->record(
'Arsen',
'Mirzaev',
24,
165.5,
1
);
if (ARCHITECTURE === architecture::x86_64) {
$record = $database->record(
'Arsen',
'Mirzaev',
24,
165.5,
91000000000,
1.7976931348623E+238,
7355608,
1
);
} else {
$record = $database->record(
'Arsen',
'Mirzaev',
24,
165.5,
1
);
}
echo '[' . ++$action . "] Initialized the record\n";
@ -84,6 +119,11 @@ echo '[' . ++$action . '][' . ++$test . '][' . ($record->name === 'Arsen' ? 'SUC
echo '[' . $action . '][' . ++$test . '][' . ($record->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . "][\"second_name\"] Expected: \"Mirzaev\" (string). Actual: \"$record->second_name\" (" . gettype($record->second_name) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($record->age === 24 ? 'SUCCESS' : 'FAIL') . "][\"age\"] Expected: \"24\" (integer). Actual: \"$record->age\" (" . gettype($record->age) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($record->height === 165.5 ? 'SUCCESS' : 'FAIL') . "][\"height\"] Expected: \"165.5\" (double). Actual: \"$record->height\" (" . gettype($record->height) . ")\n";
if (ARCHITECTURE === architecture::x86_64) {
echo '[' . $action . '][' . ++$test . '][' . ($record->neuron_count === 91000000000 ? 'SUCCESS' : 'FAIL') . "][\"neuron_count\"] Expected: \"91000000000\" (integer). Actual: \"$record->neuron_count\" (" . gettype($record->neuron_count) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($record->motivation === 1.7976931348623E+238 ? 'SUCCESS' : 'FAIL') . "][\"motivation\"] Expected: \"1.7976931348623E+238\" (double). Actual: \"$record->motivation\" (" . gettype($record->motivation) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($record->reputation === 7355608 ? 'SUCCESS' : 'FAIL') . "][\"reputation\"] Expected: \"7355608\" (integer). Actual: \"$record->reputation\" (" . gettype($record->reputation) . ")\n";
}
echo '[' . $action . '][' . ++$test . '][' . ($record->active === 1 ? 'SUCCESS' : 'FAIL') . "][\"active\"] Expected: \"1\" (integer). Actual: \"$record->active\" (" . gettype($record->active) . ")\n";
echo '[' . $action . "] The record parameters checks have been completed\n";
@ -97,13 +137,26 @@ $database->write($record);
echo '[' . ++$action . "] Writed the record into the database\n";
// Initializing the second record
$record_ivan = $database->record(
'Ivan',
'Ivanov',
24,
(float) 210,
0
);
if (ARCHITECTURE === architecture::x86_64) {
$record_ivan = $database->record(
'Ivan',
'Ivanov',
24,
(float) 210,
PHP_INT_MAX,
PHP_FLOAT_MIN,
PHP_INT_MIN,
0
);
} else {
$record_ivan = $database->record(
'Ivan',
'Ivanov',
24,
(float) 210,
0
);
}
echo '[' . ++$action . "] Initialized the record\n";
@ -113,18 +166,31 @@ $database->write($record_ivan);
echo '[' . ++$action . "] Writed the record into the database\n";
// Initializing the second record
$record_ivan = $database->record(
'Margarita',
'Esenina',
19,
(float) 165,
1
);
if (ARCHITECTURE === architecture::x86_64) {
$record_margarita = $database->record(
'Margarita',
'Esenina',
19,
(float) 165,
89000000000,
(float) 163,
PHP_INT_MAX,
1
);
} else {
$record_margarita = $database->record(
'Margarita',
'Esenina',
19,
(float) 165,
1
);
}
echo '[' . ++$action . "] Initialized the record\n";
// Writing the second record into the databasse
$database->write($record_ivan);
$database->write($record_margarita);
echo '[' . ++$action . "] Writed the record into the database\n";
@ -138,6 +204,9 @@ try {
echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_all) === 3 ? 'SUCCESS' : 'FAIL') . '][amount of readed records] Expected: 3 records. Actual: ' . count($records_readed_all) . " records\n";
echo '[' . $action . '][' . ++$test . '][' . (gettype($records_readed_all[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($records_readed_all[0]) . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_all[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_all[0]::class . "\"\n";
if (ARCHITECTURE === architecture::x86_64) {
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_all[0]->neuron_count === 91000000000 ? 'SUCCESS' : 'FAIL') . ']["neuron_count"] Expected: "91000000000" (integer). Actual: "' . $records_readed_all[0]->neuron_count . '" (' . gettype($records_readed_all[0]->neuron_count) . ")\n";
}
echo '[' . $action . "] The readed all records checks have been completed\n";
} catch (exception $e) {
@ -158,6 +227,9 @@ try {
echo '[' . $action . '][' . ++$test . '][' . (gettype($record_readed_first[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($record_readed_first[0]) . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_first[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $record_readed_first[0]::class . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_first[0]->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Mirzaev" (string). Actual: "' . $record_readed_first[0]->second_name . '" (' . gettype($record_readed_first[0]->second_name) . ")\n";
if (ARCHITECTURE === architecture::x86_64) {
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_first[0]->neuron_count === 91000000000 ? 'SUCCESS' : 'FAIL') . ']["neuron_count"] Expected: "91000000000" (integer). Actual: "' . $record_readed_first[0]->neuron_count . '" (' . gettype($record_readed_first[0]->neuron_count) . ")\n";
}
echo '[' . $action . "] The readed first record checks have been completed\n";
} catch (exception $e) {
@ -178,6 +250,15 @@ try {
echo '[' . $action . '][' . ++$test . '][' . (gettype($record_readed_second[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($record_readed_second[0]) . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_second[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $record_readed_second[0]::class . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_second[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $record_readed_second[0]->second_name . '" (' . gettype($record_readed_second[0]->second_name) . ")\n";
if (ARCHITECTURE === architecture::x86_64) {
/**
* Due to IEEE 754 double precision format double equality is problematic
*
* @see https://www.php.net/manual/en/language.types.float.php#113703
*/
echo '[' . $action . '][' . ++$test . '][' . (round($record_readed_second[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_readed_second[0]->motivation . '" (' . gettype($record_readed_second[0]->motivation) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_second[0]->reputation === (int) -9223372036854775808 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "-9223372036854775808" (integer). Actual: "' . $record_readed_second[0]->reputation . '" (' . gettype($record_readed_second[0]->reputation) . ")\n";
}
echo '[' . $action . "] The readed second record checks have been completed\n";
} catch (exception $e) {
@ -198,6 +279,15 @@ try {
echo '[' . $action . '][' . ++$test . '][' . (gettype($record_readed_filter[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($record_readed_filter[0]) . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_filter[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $record_readed_filter[0]::class . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_filter[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $record_readed_filter[0]->second_name . '" (' . gettype($record_readed_filter[0]->second_name) . ")\n";
if (ARCHITECTURE === architecture::x86_64) {
/**
* Due to IEEE 754 double precision format double equality is problematic
*
* @see https://www.php.net/manual/en/language.types.float.php#113703
*/
echo '[' . $action . '][' . ++$test . '][' . (round($record_readed_filter[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_readed_filter[0]->motivation . '" (' . gettype($record_readed_filter[0]->motivation) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_filter[0]->reputation === (int) -9223372036854775808 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "-9223372036854775808" (integer). Actual: "' . $record_readed_filter[0]->reputation . '" (' . gettype($record_readed_filter[0]->reputation) . ")\n";
}
echo '[' . $action . "] The readed record by filter checks have been completed\n";
} catch (exception $e) {
@ -219,6 +309,15 @@ try {
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_filter_amount[0]::class . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount[0]->age === 24 ? 'SUCCESS' : 'FAIL') . ']["age"] Expected: "24" (integer). Actual: "' . $records_readed_filter_amount[0]->age . '" (' . gettype($records_readed_filter_amount[0]->age) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount[0]->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Mirzaev" (string). Actual: "' . $records_readed_filter_amount[0]->second_name . '" (' . gettype($records_readed_filter_amount[0]->second_name) . ")\n";
if (ARCHITECTURE === architecture::x86_64) {
/**
* Due to IEEE 754 double precision format double equality is problematic
*
* @see https://www.php.net/manual/en/language.types.float.php#113703
*/
echo '[' . $action . '][' . ++$test . '][' . (round($record_readed_second[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_readed_second[0]->motivation . '" (' . gettype($record_readed_second[0]->motivation) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($record_readed_second[0]->reputation === (int) -9223372036854775808 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "-9223372036854775808" (integer). Actual: "' . $record_readed_second[0]->reputation . '" (' . gettype($record_readed_second[0]->reputation) . ")\n";
}
echo '[' . $action . "] The readed record by filter with amount limit checks have been completed\n";
} catch (exception $e) {
@ -240,6 +339,15 @@ try {
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount_offset[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_filter_amount_offset[0]::class . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount_offset[0]->age === 24 ? 'SUCCESS' : 'FAIL') . ']["age"] Expected: "24" (integer). Actual: "' . $records_readed_filter_amount_offset[0]->age . '" (' . gettype($records_readed_filter_amount_offset[0]->age) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount_offset[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $records_readed_filter_amount_offset[0]->second_name . '" (' . gettype($records_readed_filter_amount_offset[0]->second_name) . ")\n";
if (ARCHITECTURE === architecture::x86_64) {
/**
* Due to IEEE 754 double precision format double equality is problematic
*
* @see https://www.php.net/manual/en/language.types.float.php#113703
*/
echo '[' . $action . '][' . ++$test . '][' . (round($records_readed_filter_amount_offset[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $records_readed_filter_amount_offset[0]->motivation . '" (' . gettype($records_readed_filter_amount_offset[0]->motivation) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount_offset[0]->reputation === (int) -9223372036854775808 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "-9223372036854775808" (integer). Actual: "' . $records_readed_filter_amount_offset[0]->reputation . '" (' . gettype($records_readed_filter_amount_offset[0]->reputation) . ")\n";
}
echo '[' . $action . "] The readed record by filter with amount limit and offset checks have been completed\n";
} catch (exception $e) {
@ -266,6 +374,15 @@ try {
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_delete[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_filter_delete[0]::class . "\"\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_delete[0]->name === 'Ivan' ? 'SUCCESS' : 'FAIL') . ']["name"] Expected: "Ivan" (string). Actual: "' . $records_readed_filter_delete[0]->second_name . '" (' . gettype($records_readed_filter_delete[0]->second_name) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_delete_readed) === 2 ? 'SUCCESS' : 'FAIL') . '][amount of readed records after deleting] Expected: 2 records. Actual: ' . count($records_readed_filter_delete_readed) . " records\n";
if (ARCHITECTURE === architecture::x86_64) {
/**
* Due to IEEE 754 double precision format double equality is problematic
*
* @see https://www.php.net/manual/en/language.types.float.php#113703
*/
echo '[' . $action . '][' . ++$test . '][' . (round($records_readed_filter_delete_readed[1]->motivation, 2) === round(163, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "163" (double). Actual: "' . $records_readed_filter_delete_readed[1]->motivation . '" (' . gettype($records_readed_filter_delete_readed[1]->motivation) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_delete_readed[1]->reputation === (int) 9223372036854775807 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "9223372036854775807" (integer). Actual: "' . $records_readed_filter_delete_readed[1]->reputation . '" (' . gettype($records_readed_filter_delete_readed[1]->reputation) . ")\n";
}
echo '[' . $action . "] The deleted record by filter checks have been completed\n";
} catch (exception $e) {
@ -293,6 +410,15 @@ try {
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_update[0]->height === 165.5 ? 'SUCCESS' : 'FAIL') . ']["height"] Expected: "165.5" (double). Actual: "' . $records_readed_filter_update[0]->height . '" (' . gettype($records_readed_filter_update[0]->height) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_update_readed) === 2 ? 'SUCCESS' : 'FAIL') . '][amount of readed records after updating] Expected: 2 records. Actual: ' . count($records_readed_filter_update_readed) . " records\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_update_readed[1]->height === $records_readed_filter_update[0]->height ? 'SUCCESS' : 'FAIL') . "] Height from `update` process response matched height from the `read` preocess response\n";
if (ARCHITECTURE === architecture::x86_64) {
/**
* Due to IEEE 754 double precision format double equality is problematic
*
* @see https://www.php.net/manual/en/language.types.float.php#113703
*/
echo '[' . $action . '][' . ++$test . '][' . (round($records_readed_filter_update[0]->motivation, 2) === round(163, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "163" (double). Actual: "' . $records_readed_filter_update[0]->motivation . '" (' . gettype($records_readed_filter_update[0]->motivation) . ")\n";
echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_update[0]->reputation === (int) 9223372036854775807 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "9223372036854775807" (integer). Actual: "' . $records_readed_filter_update[0]->reputation . '" (' . gettype($records_readed_filter_update[0]->reputation) . ")\n";
}
echo '[' . $action . "] The updated record by filter checks have been completed\n";
} catch (exception $e) {