зеркало из https://github.com/nextcloud/cookbook.git
Fix PHP exceptions and incompatibilities
Increased speed of integration tests Make tests run with syncs as well Signed-off-by: Christian Wolf <github@christianwolf.email>
This commit is contained in:
Родитель
ca7ac92952
Коммит
bab7b811d7
|
@ -1,42 +1,137 @@
|
|||
#! /bin/bash -e
|
||||
|
||||
BACKUP="$1"
|
||||
SUBFIXTURE="$1"
|
||||
|
||||
echo "Restoring backup with name $BACKUP"
|
||||
echo "Restoring sub-fixture $SUBFIXTURE"
|
||||
|
||||
echo "Cloning data files"
|
||||
rsync --archive --delete --delete-delay "/dumps/$BACKUP/data/" /nextcloud/data/
|
||||
SF_DIR="/dumps/current/$SUBFIXTURE"
|
||||
|
||||
echo "Restoring DB"
|
||||
case "$INPUT_DB" in
|
||||
mysql)
|
||||
mysql -u root -p"$MYSQL_ROOT_PASSWORD" -h mysql < "/dumps/$BACKUP/sql/dump.sql"
|
||||
;;
|
||||
pgsql)
|
||||
echo 'Dropping old data'
|
||||
PGPASSWORD="$POSTGRES_PASSWORD" \
|
||||
psql -d "$POSTGRES_DB" -h postgres -U "$POSTGRES_USER" -v 'ON_ERROR_STOP=1' <<- EOF || exit 1
|
||||
DROP SCHEMA public CASCADE;
|
||||
CREATE SCHEMA public;
|
||||
GRANT ALL ON SCHEMA public TO $POSTGRES_USER;
|
||||
GRANT ALL ON SCHEMA public TO public;
|
||||
EOF
|
||||
|
||||
is_file_dump () {
|
||||
test -f "$SF_DIR/sql/dump.sql"
|
||||
}
|
||||
|
||||
restore_mysql_dump () {
|
||||
echo "Dropping old data from the database"
|
||||
mysql -u root -p"$MYSQL_ROOT_PASSWORD" -h mysql <<- EOF | tail -n +2 > /tmp/mysql_tables
|
||||
SHOW TABLES;
|
||||
EOF
|
||||
cat /tmp/mysql_tables | sed 's@.*@DROP TABE \0;@' | mysql -u root -p"$MYSQL_ROOT_PASSWORD" -h mysql
|
||||
|
||||
echo "Restoring MySQL from single file dump"
|
||||
mysql -u root -p"$MYSQL_ROOT_PASSWORD" -h mysql < "$SF_DIR/sql/dump.sql"
|
||||
}
|
||||
|
||||
restore_postgres_dump () {
|
||||
echo "Restoring PostgreSQL from single file dump"
|
||||
echo 'Dropping old data'
|
||||
PGPASSWORD="$POSTGRES_PASSWORD" \
|
||||
psql -d "$POSTGRES_DB" -h postgres -U "$POSTGRES_USER" -v 'ON_ERROR_STOP=1' <<- EOF || exit 1
|
||||
DROP SCHEMA public CASCADE;
|
||||
CREATE SCHEMA public;
|
||||
GRANT ALL ON SCHEMA public TO $POSTGRES_USER;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO PUBLIC;
|
||||
EOF
|
||||
|
||||
# PGPASSWORD="$POSTGRES_PASSWORD" \
|
||||
# psql -d "$POSTGRES_DB" -h postgres -U "$POSTGRES_USER" <<- EOF
|
||||
# \l
|
||||
# \d
|
||||
# SELECT * FROM oc_preferences WHERE appid='cookbook';
|
||||
# EOF
|
||||
|
||||
echo 'Inserting dump data'
|
||||
PGPASSWORD="$POSTGRES_PASSWORD" \
|
||||
psql -d "$POSTGRES_DB" -h postgres -U "$POSTGRES_USER" -f "/dumps/$BACKUP/sql/dump.sql" -v 'ON_ERROR_STOP=1' || exit 1
|
||||
|
||||
|
||||
echo 'Inserting dump data'
|
||||
PGPASSWORD="$POSTGRES_PASSWORD" \
|
||||
psql -d "$POSTGRES_DB" -h postgres -U "$POSTGRES_USER" -f "$SF_DIR/sql/dump.sql" -v 'ON_ERROR_STOP=1' || exit 1
|
||||
|
||||
# PGPASSWORD="$POSTGRES_PASSWORD" \
|
||||
# psql -d "$POSTGRES_DB" -h postgres -U "$POSTGRES_USER" <<- EOF
|
||||
# SELECT * FROM oc_preferences WHERE appid='cookbook';
|
||||
# EOF
|
||||
}
|
||||
|
||||
get_container_name() {
|
||||
echo "cookbook_unittesting_${1}_1"
|
||||
}
|
||||
|
||||
kill_container() {
|
||||
local container_name="`get_container_name "$1"`"
|
||||
echo "Killing container $container_name"
|
||||
docker --log-level error kill "$container_name"
|
||||
}
|
||||
|
||||
start_container() {
|
||||
local container_name="`get_container_name "$1"`"
|
||||
echo "Starting container $container_name"
|
||||
docker --log-level error start "$container_name"
|
||||
}
|
||||
|
||||
restore_db_synced_data() {
|
||||
local db_path="/db/${1}"
|
||||
echo "Restoring synced DB data from $SF_DIR/sql to $db_path"
|
||||
sudo rsync -a --delete --delete-delay "$SF_DIR/sql/" "$db_path"
|
||||
}
|
||||
|
||||
test_mysql_is_running() {
|
||||
state=$(docker inspect --format '{{.State.Health.Status}}' "$(get_container_name mysql)")
|
||||
test "$state" = "healthy"
|
||||
}
|
||||
|
||||
test_postgres_is_running() {
|
||||
PGPASSWORD="$POSTGRES_PASSWORD" \
|
||||
psql -d "$POSTGRES_DB" -h postgres -U "$POSTGRES_USER" -v 'ON_ERROR_STOP=1' <<- EOF
|
||||
\q
|
||||
EOF
|
||||
}
|
||||
|
||||
wait_for_container() {
|
||||
container_test="$1"
|
||||
i=0
|
||||
while ! "$container_test"
|
||||
do
|
||||
sleep 0.1
|
||||
let i=$i+100
|
||||
if [ $i -gt 20000 ]; then
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
restore_mysql_sync () {
|
||||
echo "Restoring MySQL from synced dump"
|
||||
kill_container mysql
|
||||
restore_db_synced_data mysql
|
||||
start_container mysql
|
||||
wait_for_container test_mysql_is_running
|
||||
}
|
||||
|
||||
restore_postgres_sync () {
|
||||
echo "Restoring PostgreSQL from synced dump"
|
||||
kill_container postgres
|
||||
restore_db_synced_data postgres
|
||||
start_container postgres
|
||||
wait_for_container test_postgres_is_running
|
||||
}
|
||||
|
||||
# exec >> /output/reset.log 2>&1
|
||||
|
||||
echo "Cloning data files"
|
||||
rsync --archive --delete --delete-delay "$SF_DIR/data/" /nextcloud/data/
|
||||
|
||||
echo "Restoring DB"
|
||||
case "$INPUT_DB" in
|
||||
mysql)
|
||||
if is_file_dump ; then
|
||||
restore_mysql_dump
|
||||
else
|
||||
restore_mysql_sync
|
||||
fi
|
||||
;;
|
||||
pgsql)
|
||||
if is_file_dump; then
|
||||
restore_postgres_dump
|
||||
else
|
||||
restore_postgres_sync
|
||||
fi
|
||||
;;
|
||||
sqlite)
|
||||
echo "Doing nothing as it was already restored during data restoration."
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class CouldNotGuessEncodingException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class HtmlParsingException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class ImportException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class InvalidDurationException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class InvalidJSONFileException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class InvalidRecipeException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class InvalidThumbnailTypeException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class NoDownloadWasCarriedOutException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class NoRecipeImageFoundException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class NoRecipeNameGivenException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class RecipeExistsException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class RecipeImageExistsException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class UserFolderNotValidException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class UserFolderNotWritableException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Exception;
|
||||
|
||||
class UserNotLoggedInException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace OCA\Cookbook\Helper\HTMLParser;
|
||||
|
||||
class AttributeNotFoundException extends \Exception {
|
||||
public function __construct($message = null, $code = null, $previous = null) {
|
||||
public function __construct($message = '', $code = 0, $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ class UserFolderHelper {
|
|||
} catch (NotPermittedException $ex1) {
|
||||
throw new UserFolderNotValidException(
|
||||
$this->l->t('The user folder cannot be created due to missing permissions.'),
|
||||
null,
|
||||
0,
|
||||
$ex1
|
||||
);
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ class DbCacheService {
|
|||
}
|
||||
}
|
||||
|
||||
if (strlen(trim($category)) == 0) {
|
||||
if (strlen(trim($category)) === 0) {
|
||||
return null;
|
||||
}
|
||||
return $category;
|
||||
|
|
|
@ -123,7 +123,7 @@ class HtmlDownloadService {
|
|||
try {
|
||||
$this->downloadHelper->downloadFile($url, $opt);
|
||||
} catch (NoDownloadWasCarriedOutException $ex) {
|
||||
throw new ImportException($this->l->t('Exception while downloading recipe from %s.', [$url]), null, $ex);
|
||||
throw new ImportException($this->l->t('Exception while downloading recipe from %s.', [$url]), 0, $ex);
|
||||
}
|
||||
|
||||
$status = $this->downloadHelper->getStatus();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
bootstrap="tests/bootstrap_migration.php"
|
||||
colors="true"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\Cookbook\Helper;
|
||||
|
||||
function curl_exec($ch) {
|
||||
return \OCA\Cookbook\tests\Integration\Helper\DownloadHelper\DownloadHelperTest::mock_curl_exec($ch);
|
||||
}
|
||||
|
||||
namespace OCA\Cookbook\tests\Integration\Helper\DownloadHelper;
|
||||
|
||||
use OCA\Cookbook\Exception\NoDownloadWasCarriedOutException;
|
||||
|
@ -26,6 +32,8 @@ class DownloadHelperTest extends TestCase {
|
|||
if (file_exists('/www/.htaccess')) {
|
||||
unlink('/www/.htaccess');
|
||||
}
|
||||
|
||||
self::$useCurlMock = false;
|
||||
}
|
||||
|
||||
protected function tearDown(): void {
|
||||
|
@ -85,16 +93,20 @@ class DownloadHelperTest extends TestCase {
|
|||
$this->assertEquals(404, $this->dut->getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* @medium
|
||||
*/
|
||||
public function testFailedDownload() {
|
||||
$this->expectException(NoDownloadWasCarriedOutException::class);
|
||||
$opt = [
|
||||
CURLOPT_TIMEOUT => 1,
|
||||
CURLOPT_CONNECTTIMEOUT => 1,
|
||||
];
|
||||
$this->dut->downloadFile('http://www2/test.txt', $opt);
|
||||
// Using mock here as the timeout causes the test to be really slow
|
||||
self::$useCurlMock = true;
|
||||
$this->dut->downloadFile('http://www2/test.txt');
|
||||
}
|
||||
|
||||
private static $useCurlMock = false;
|
||||
public static function mock_curl_exec($ch) {
|
||||
if (self::$useCurlMock) {
|
||||
throw new NoDownloadWasCarriedOutException();
|
||||
} else {
|
||||
return curl_exec($ch);
|
||||
}
|
||||
}
|
||||
|
||||
public function testNoContentType() {
|
||||
|
|
|
@ -15,15 +15,15 @@ class AppTest extends TestCase {
|
|||
private $container;
|
||||
|
||||
public function setUp(): void {
|
||||
resetEnvironmentToBackup();
|
||||
|
||||
parent::setUp();
|
||||
$app = new App('cookbook');
|
||||
$this->container = $app->getContainer();
|
||||
}
|
||||
|
||||
public function testAppInstalled() {
|
||||
/** @var IAppManager $appManager */
|
||||
$appManager = $this->container->query(IAppManager::class);
|
||||
$appManager->enableApp('cookbook');
|
||||
$this->assertTrue($appManager->isInstalled('cookbook'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,8 +45,6 @@ abstract class AbstractMigrationTestCase extends TestCase {
|
|||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
resetEnvironmentToBackup('plain');
|
||||
|
||||
$this->hideMigrations();
|
||||
$this->enableApp();
|
||||
$this->restoreMigrations();
|
||||
|
|
|
@ -288,10 +288,15 @@ class RecipeControllerTest extends TestCase {
|
|||
$_GET['size'] = $size;
|
||||
}
|
||||
|
||||
/** @var File|Stub */
|
||||
$file = $this->createStub(File::class);
|
||||
$id = 123;
|
||||
$this->recipeService->method('getRecipeImageFileByFolderId')->with($id, $size)->willReturn($file);
|
||||
|
||||
// Make teh tests stable against PHP deprecation warnings
|
||||
$file->method('getMTime')->willReturn(100);
|
||||
$file->method('getName')->willReturn('image.jpg');
|
||||
|
||||
/**
|
||||
* @var FileDisplayResponse $ret
|
||||
*/
|
||||
|
|
|
@ -1,40 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/bootstrap_helper.php';
|
||||
|
||||
require_once __DIR__ . '/../../../tests/bootstrap.php';
|
||||
|
||||
// Fix for "Autoload path not allowed: .../cookbook/tests/testcase.php"
|
||||
\OC_App::loadApp('cookbook');
|
||||
|
||||
function resetEnvironmentToBackup(string $name = 'default', bool $forceprint = false) {
|
||||
$output = [];
|
||||
$ret = -1;
|
||||
exec("./.github/actions/run-tests/reset-from-container.sh $name 2>&1", $output, $ret);
|
||||
if ($ret !== 0 || $forceprint) {
|
||||
echo "\nStandard output:\n";
|
||||
print_r($output);
|
||||
echo "Return value: $ret\n";
|
||||
if ($ret !== 0) {
|
||||
throw new Exception("Could not reset environment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runOCCCommand(array $args, bool $forceprint = false) {
|
||||
$output = [];
|
||||
$ret = -1;
|
||||
$params = join(' ', array_map(function ($x) {
|
||||
return escapeshellarg($x);
|
||||
}, $args));
|
||||
|
||||
$cmd = "./.github/actions/run-tests/run-occ.sh $params 2>&1";
|
||||
|
||||
exec($cmd, $output, $ret);
|
||||
if ($ret !== 0 || $forceprint) {
|
||||
echo "\nStandard output:\n";
|
||||
print_r($output);
|
||||
echo "Return value: $ret\n";
|
||||
if ($ret !== 0) {
|
||||
throw new Exception("Could not run OCC command");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
function resetEnvironmentToBackup(string $name = 'main', bool $forceprint = false) {
|
||||
$output = [];
|
||||
$ret = -1;
|
||||
exec("./.github/actions/run-tests/reset-from-container.sh $name 2>&1", $output, $ret);
|
||||
if ($ret !== 0 || $forceprint) {
|
||||
echo "\nStandard output:\n";
|
||||
print_r($output);
|
||||
echo "Return value: $ret\n";
|
||||
if ($ret !== 0) {
|
||||
throw new Exception("Could not reset environment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runOCCCommand(array $args, bool $forceprint = false) {
|
||||
$output = [];
|
||||
$ret = -1;
|
||||
$params = join(' ', array_map(function ($x) {
|
||||
return escapeshellarg($x);
|
||||
}, $args));
|
||||
|
||||
$cmd = "./.github/actions/run-tests/run-occ.sh $params 2>&1";
|
||||
|
||||
exec($cmd, $output, $ret);
|
||||
if ($ret !== 0 || $forceprint) {
|
||||
echo "\nStandard output:\n";
|
||||
print_r($output);
|
||||
echo "Return value: $ret\n";
|
||||
if ($ret !== 0) {
|
||||
throw new Exception("Could not run OCC command");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/bootstrap_helper.php';
|
||||
|
||||
resetEnvironmentToBackup('plain', false);
|
||||
|
||||
require_once __DIR__ . '/../../../tests/bootstrap.php';
|
||||
|
||||
// Fix for "Autoload path not allowed: .../cookbook/tests/testcase.php"
|
||||
\OC_App::loadApp('cookbook');
|
Загрузка…
Ссылка в новой задаче