зеркало из https://github.com/nextcloud/cookbook.git
Create first strucutre to test migration issue, implementation issue with PHPUnit
Signed-off-by: Christian Wolf <github@christianwolf.email> Make running test case valid Signed-off-by: Christian Wolf <github@christianwolf.email> Tidy up test case Signed-off-by: Christian Wolf <github@christianwolf.email> Update phpunit configuration file Signed-off-by: Christian Wolf <github@christianwolf.email> Rename cases to avoid spaces in names Signed-off-by: Christian Wolf <github@christianwolf.email> Corrected assertions and sorting Signed-off-by: Christian Wolf <github@christianwolf.email> Updated test code to have corrct array keys involved. Signed-off-by: Christian Wolf <github@christianwolf.email> Added some comments Signed-off-by: Christian Wolf <github@christianwolf.email>
This commit is contained in:
Родитель
bbd15f3942
Коммит
fe85aaa4b0
|
@ -0,0 +1,9 @@
|
|||
#! /bin/sh -e
|
||||
|
||||
#set -x
|
||||
|
||||
cd /nextcloud
|
||||
php occ "$@"
|
||||
|
||||
exit $?
|
||||
|
|
@ -1,4 +1,9 @@
|
|||
<phpunit bootstrap="tests/bootstrap.php" colors="true">
|
||||
<phpunit
|
||||
bootstrap="tests/bootstrap.php"
|
||||
colors="true"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="integration">
|
||||
<directory>./tests/Integration</directory>
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace tests\Integration\Setup\Migrations;
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OC\DB\SchemaWrapper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class Version000000Date20210701093123Test extends TestCase {
|
||||
|
||||
/**
|
||||
* @var IAppContainer
|
||||
*/
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* @var IDBConnection
|
||||
*/
|
||||
private $db;
|
||||
|
||||
public function setUp(): void {
|
||||
resetEnvironmentToBackup('default');
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$app = new App('cookbook');
|
||||
$this->container = $app->getContainer();
|
||||
|
||||
/**
|
||||
* @var IDBConnection $db
|
||||
*/
|
||||
$this->db = $this->container->query(IDBConnection::class);
|
||||
$this->assertIsObject($this->db);
|
||||
/**
|
||||
* @var SchemaWrapper $schema
|
||||
*/
|
||||
$schema = $this->container->query(SchemaWrapper::class);
|
||||
$this->assertIsObject($schema);
|
||||
|
||||
// undo all migrations of cookbook app
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$numRows = $qb->delete('migrations')
|
||||
->where('app=:app')
|
||||
->setParameter('app', 'cookbook')
|
||||
->execute();
|
||||
$this->assertGreaterThan(0, $numRows);
|
||||
|
||||
$schema->dropTable('cookbook_names');
|
||||
$this->assertFalse($schema->hasTable('cookbook_names'));
|
||||
$schema->dropTable('cookbook_categories');
|
||||
$this->assertFalse($schema->hasTable('cookbook_categories'));
|
||||
$schema->dropTable('cookbook_keywords');
|
||||
$this->assertFalse($schema->hasTable('cookbook_keywords'));
|
||||
|
||||
$schema->performDropTableCalls();
|
||||
|
||||
// Reinstall app partially (just before the migration)
|
||||
runOCCCommand(['migration:migrate', 'cookbook', '000000Date20210427082010']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProvider
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testRedundantEntriesInDB($data, $updatedUsers) {
|
||||
// Add recipe dummy data from data provider
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->insert('cookbook_names')
|
||||
->values([
|
||||
'recipe_id' => ':recipe',
|
||||
'user_id' => ':user',
|
||||
'name' => ':name',
|
||||
]);
|
||||
$qb->setParameter('name', 'name of the recipe');
|
||||
foreach ($data as $d) {
|
||||
$qb->setParameter('user', $d[0]);
|
||||
$qb->setParameter('recipe', $d[1]);
|
||||
|
||||
$this->assertEquals(1, $qb->execute());
|
||||
}
|
||||
|
||||
// Initialize configuration values to track reindex timestamps
|
||||
$current = time();
|
||||
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->insert('preferences')
|
||||
->values([
|
||||
'userid' => ':user',
|
||||
'appid' => ':appid',
|
||||
'configkey' => ':property',
|
||||
'configvalue' => ':value',
|
||||
]);
|
||||
|
||||
$qb->setParameter('value', $current, IQueryBuilder::PARAM_STR);
|
||||
$qb->setParameter('appid', 'cookbook');
|
||||
$qb->setParameter('property', 'last_index_update');
|
||||
|
||||
$users = array_unique(array_map(function ($x) {return $x[0];}, $data));
|
||||
foreach($users as $u){
|
||||
$qb->setParameter('user', $u);
|
||||
$this->assertEquals(1, $qb->execute());
|
||||
}
|
||||
|
||||
// Run the migration under test
|
||||
runOCCCommand(['migration:migrate', 'cookbook', '000000Date20210701093123']);
|
||||
|
||||
// Get the (updated) reindex timestamps
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('userid', 'configvalue')
|
||||
->from('preferences')
|
||||
->where(
|
||||
'appid = :appid',
|
||||
'configkey = :property'
|
||||
);
|
||||
$qb->setParameter('appid', 'cookbook');
|
||||
$qb->setParameter('property', 'last_index_update');
|
||||
|
||||
$cursor = $qb->execute();
|
||||
$result = $cursor->fetchAll();
|
||||
|
||||
// Filter those entries from the configuration that were marked as to be reindexed
|
||||
$result = array_filter($result, function ($x) use ($current) { return $x['configvalue'] < $current; });
|
||||
// Map the array to contain only the corresponding user names
|
||||
$changedUsers = array_map(function ($x) { return $x['userid']; }, $result);
|
||||
|
||||
// Sort the arrays to allow comparision of them
|
||||
sort($changedUsers);
|
||||
sort($updatedUsers);
|
||||
|
||||
$this->assertEquals($updatedUsers, $changedUsers);
|
||||
|
||||
$this->markTestIncomplete('Not yet implemented');
|
||||
}
|
||||
|
||||
public function dataProvider() {
|
||||
return [
|
||||
'caseA' => [
|
||||
[
|
||||
['alice', 123],
|
||||
['alice', 124],
|
||||
['bob', 125]
|
||||
],
|
||||
[],
|
||||
],
|
||||
'caseB' => [
|
||||
[
|
||||
['alice', 123],
|
||||
['alice', 124],
|
||||
['bob', 124],
|
||||
['bob', 125],
|
||||
],
|
||||
[],
|
||||
],
|
||||
'caseC' => [
|
||||
[
|
||||
['alice', 123],
|
||||
['alice', 124],
|
||||
['bob', 124],
|
||||
['bob', 124],
|
||||
['bob', 125],
|
||||
],
|
||||
['bob']
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -5,12 +5,31 @@ 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') {
|
||||
exec("./.github/actions/run-tests/reset-from-container.sh $name 2>&1", $output, $ret);
|
||||
if ($ret !== 0) {
|
||||
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";
|
||||
throw new Exception("Could not reset environment");
|
||||
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));
|
||||
exec("./.github/actions/run-tests/run-occ.sh $params 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 run OCC command");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче