# Preparations
Create `/test.php` file with following content:
```
lang=php
<?php
$start = microtime(true);
define('FULL_PATH', realpath(dirname(__FILE__)));
include_once(FULL_PATH.'/core/kernel/startup.php');
$application =& kApplication::Instance();
$application->Init();
echo '<h1>Random generator testing</h1>';
echo '<h2>Different resolving ways (numbers).</h2>';
echo '<div style="color: green;">value before/after "..." must match</div>';
$promise = SecurityGenerator::generateNumber(1, 100);
echo $promise->resolve() . ' ... ' . $promise->resolve() . '<br/>';
$promise = SecurityGenerator::generateNumber(1, 100);
echo $promise . ' ... ' . $promise . '<br/>';
$promise = SecurityGenerator::generateNumber(1, 100);
echo $promise->resolve() . ' ... ' . $promise . '<br/>';
echo '<h2>Different resolving ways (strings).</h2>';
echo '<div style="color: green;">value before/after "..." must match</div>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo $promise->resolve() . ' ... ' . $promise->resolve() . '<br/>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo $promise . ' ... ' . $promise . '<br/>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo $promise->resolve() . ' ... ' . $promise . '<br/>';
echo '<h2>Different resolving ways (bytes).</h2>';
echo '<div style="color: green;">value before/after "..." must match</div>';
$promise = SecurityGenerator::generateBytes(10);
echo $promise->resolve() . ' ... ' . $promise->resolve() . '<br/>';
$promise = SecurityGenerator::generateBytes(10);
echo $promise . ' ... ' . $promise . '<br/>';
$promise = SecurityGenerator::generateBytes(10);
echo $promise->resolve() . ' ... ' . $promise . '<br/>';
echo '<h2>Raw byte value is 2x shorter, then non-raw byte value.</h2>';
echo '<div style="color: green;">number before "..." must be 2x smaller, then number after "..."</div>';
$non_raw_promise = SecurityGenerator::generateBytes(10, false);
$raw_promise = SecurityGenerator::generateBytes(10, true);
echo strlen($raw_promise) . ' ... ' . strlen($non_raw_promise) . ' (non-raw value: ' . $non_raw_promise . ')<br/>';
echo '<h2>String generation supports char classes.</h2>';
echo '<div style="color: green;">random string after ":" must consist only from char class symbols listed before ":"</div>';
echo 'CHAR_UPPER: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_UPPER) . '<br/>';
echo 'CHAR_LOWER: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_LOWER) . '<br/>';
echo 'CHAR_ALPHA: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_ALPHA) . '<br/>';
echo 'CHAR_DIGITS: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_DIGITS) . '<br/>';
echo 'CHAR_ALNUM: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_ALNUM) . '<br/>';
echo 'CHAR_UPPER_HEX: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_UPPER_HEX) . '<br/>';
echo 'CHAR_LOWER_HEX: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_LOWER_HEX) . '<br/>';
echo 'CHAR_BASE64: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_BASE64) . '<br/>';
echo 'CHAR_SYMBOLS: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_SYMBOLS) . '<br/>';
echo 'CHAR_BRACKETS: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_BRACKETS) . '<br/>';
echo 'CHAR_PUNCT: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_PUNCT) . '<br/>';
echo 'CHAR_ALNUM+CHAR_SYMBOLS+EASY_TO_READ: ' . SecurityGenerator::generateString(10, SecurityGenerator::CHAR_ALNUM | SecurityGenerator::CHAR_SYMBOLS | SecurityGenerator::EASY_TO_READ) . '<br/>';
echo '<h2>By default resolved value is returned.</h2>';
echo '<div style="color: green;">value before/after "..." must match</div>';
$promise = SecurityGenerator::generateNumber(1, 100);
echo $promise->resolve() . ' ... ' . $promise->asValue()->resolve() . '<br/>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo $promise->resolve() . ' ... ' . $promise->asValue()->resolve() . '<br/>';
$promise = SecurityGenerator::generateBytes(10);
echo $promise->resolve() . ' ... ' . $promise->asValue()->resolve() . '<br/>';
echo '<h2>Signature of resolved value is returned.</h2>';
echo '<div style="color: green;">signature of generated value should be shown</div>';
$promise = SecurityGenerator::generateNumber(1, 100);
echo 'number: ' . $promise->asSignature()->resolve() . '<br/>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo 'string: ' . $promise->asSignature()->resolve() . '<br/>';
$promise = SecurityGenerator::generateBytes(10);
echo 'bytes: ' . $promise->asSignature()->resolve() . '<br/>';
echo '<h2>Raw signature is 2x shorter, than non-raw signature.</h2>';
echo '<div style="color: green;">number before "..." must be 2x smaller, then number after "..."</div>';
$promise = SecurityGenerator::generateNumber(1, 100);
echo 'number: ' . strlen($promise->asSignature(true)->resolve()) . ' ... ' . strlen($promise->asSignature()->resolve()) . '<br/>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo 'string: ' . strlen($promise->asSignature(true)->resolve()) . ' ... ' . strlen($promise->asSignature()->resolve()) . '<br/>';
$promise = SecurityGenerator::generateBytes(10);
echo 'bytes: ' . strlen($promise->asSignature(true)->resolve()) . ' ... ' . strlen($promise->asSignature()->resolve()) . '<br/>';
echo '<h2>Signature generation key can be overridden.</h2>';
echo '<div style="color: green;">values before "..." and after "..." must be different</div>';
$promise = SecurityGenerator::generateNumber(1, 100);
echo 'number: ' . $promise->asSignature()->resolve() . ' ... ' . $promise->asSignature(false, 'different key')->resolve() . '<br/>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo 'string: ' . $promise->asSignature()->resolve() . ' ... ' . $promise->asSignature(false, 'different key')->resolve() . '<br/>';
$promise = SecurityGenerator::generateBytes(10);
echo 'bytes: ' . $promise->asSignature()->resolve() . ' ... ' . $promise->asSignature(false, 'different key')->resolve() . '<br/>';
echo '<h2>Unique value generation for database.</h2>';
echo '<div style="color: green;">no could be thrown at some times (e.g. when random number hits db column value)</div>';
$promise = SecurityGenerator::generateNumber(1, 10);
echo 'number: ' . $promise->resolveForPersisting('lang', 'LanguageId') . '<br/>';
$promise = SecurityGenerator::generateString(10, 'abcdef');
echo 'string: ' . $promise->resolveForPersisting('phrases', 'Phrase') . '<br/>';
$promise = SecurityGenerator::generateBytes(10);
echo 'bytes: ' . $promise->resolveForPersisting('phrases', 'Phrase') . '<br/>';
echo '<h1>Encrypter testing</h1>';
/** @var SecurityEncrypter $encrypter */
$encrypter = $application->recallObject('SecurityEncrypter');
echo '<h2>Different signature generation ways.</h2>';
echo '<div style="color: green;">all values after ":" must be different</div>';
echo 'signature using default key + non-raw: ' . $encrypter->createSignature('the string') . '<br/>';
echo 'signature using default key + raw: ' . $encrypter->createSignature('the string', true) . '<br/>';
echo 'signature using custom key + non-raw: ' . $encrypter->createSignature('the string', false, 'custom key') . '<br/>';
echo 'signature using custom key + raw: ' . $encrypter->createSignature('the string', true, 'custom key') . '<br/>';
echo '<h2>Encrypt/decrypt testing.</h2>';
echo '<div style="color: green;">see value in parenthesis below to detect if each line passed</div>';
$plaintext = 'the text';
$cyphertext = $encrypter->encrypt($plaintext);
$plaintext_decrypted = $encrypter->decrypt($cyphertext);
echo 'decrypt(encrypt(plain text)) == plain text: ' . ($plaintext === $plaintext_decrypted ? 'yes' : 'no') . ' (yes - passed)<br/>';
$plaintext = 'the text';
$cyphertext = $encrypter->encrypt($plaintext, 'custom password');
$plaintext_decrypted = $encrypter->decrypt($cyphertext);
echo 'decrypt(encrypt(plain text, custom password)) == plain text: ' . ($plaintext === $plaintext_decrypted ? 'yes' : 'no') . ' (no - passed)<br/>';
echo '<h2>Invalid signature on decrypting.</h2>';
echo '<div style="color: green;">there must be an exception</div>';
$plaintext = 'the text';
$cyphertext = $encrypter->encrypt($plaintext);
$plaintext_decrypted = $encrypter->decrypt(base64_decode(base64_decode($cyphertext) . 'e'));
$end = microtime(true);
```
# Part 1
# perform an upgrade
# confirm, that after upgrade new "SecurityHmacKey" and "SecurityEncryptionKey" settings were added to "/system/config.php" and the have non-empty values
# Part 2
# perform clean install
# confirm, that after install new "SecurityHmacKey" and "SecurityEncryptionKey" settings were added to "/system/config.php" and the have non-empty values
# Part 3
# run `/test.php` script in browser
# confirm, that for each sub-section text in green is actually matching what is displayed in black after it