summaryrefslogtreecommitdiffstats
path: root/.scrutinizer.yml
Commit message (Expand)AuthorAgeFilesLines
* Scrutinizer should not check generated composer filesRoeland Jago Douma2016-03-101-1/+1
* Initialize submodules for Scrutinizer as wellLukas Reschke2016-03-071-0/+3
* No more code coverage on scrutinizerThomas Müller2016-02-161-4/+0
* Limit scope of scrutinizer to actual application codeMorris Jobke2016-02-141-0/+4
* Revert "Specify PHP 5.4 as version for scrutinizer"Lukas Reschke2015-10-291-10/+0
* Specify PHP 5.4 as version for scrutinizerLukas Reschke2015-10-141-0/+10
* Update commentLukas Reschke2015-06-281-1/+1
* Increase timeout againLukas Reschke2015-06-281-1/+1
* [scrutinizer] Increase timeout of external code coverage Morris Jobke2015-05-271-1/+1
* Enable code coverage on scrutinizerThomas Müller2015-04-301-0/+4
* bower jquery-ui - exported changes to a separate css fileMorris Jobke2014-12-131-1/+0
* Migrate multiselect to user_ldapMorris Jobke2014-11-131-1/+1
* bower snapjsMorris Jobke2014-11-061-2/+1
* bower underscoreMorris Jobke2014-11-051-1/+0
* Merge pull request #11936 from owncloud/bower-jqueryLukas Reschke2014-11-051-4/+1
|\
| * ignore core/vendor in scrutinizerMorris Jobke2014-11-051-4/+1
* | drop unused jquery.placeholderMorris Jobke2014-11-051-1/+0
* | drop jquery.inview as it is unusedMorris Jobke2014-11-051-1/+0
|/
* Disable external code coverageLukas Reschke2014-09-241-3/+0
* Travis supportMorris Jobke2014-08-051-0/+2
* Ignore core/js/jquery.placeholder.jsThomas Müller2014-07-081-0/+1
* Ignore core/js/snap.jsThomas Müller2014-07-081-0/+1
* move to updated version of placeholderMorris Jobke2014-06-031-3/+3
* remove scruntinizer config for infieldMorris Jobke2014-06-031-1/+0
* Add new jquery files to exclude listVolkan Gezer2014-04-231-0/+2
* Ignore jquery.multiselect.js - it's 3rdpartyThomas Müller2014-04-141-0/+1
* ignore underscore.js in scrutinizer.ymlThomas Müller2014-04-071-0/+1
* Exclude javascript specs from code analysisThomas Müller2014-04-031-0/+1
* Remove duplicate rowThomas Müller2014-03-031-1/+0
* add .scrutinizer.ymlThomas Müller2014-03-031-0/+24
ld } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<?php
/**
 * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
 * This file is licensed under the Affero General Public License version 3 or
 * later.
 * See the COPYING-README file.
 */

namespace Test\Repair;

use OC\Files\Cache\Cache;
use OC\Files\Cache\Storage;
use OCP\Migration\IOutput;
use PHPUnit_Framework_MockObject_MockObject;
use Test\TestCase;

/**
 * Tests for the converting of legacy storages to home storages.
 *
 * @group DB
 *
 * @see \OC\Repair\RepairLegacyStorages
 */
class RepairLegacyStoragesTest extends TestCase {
	/** @var \OCP\IDBConnection */
	private $connection;
	/** @var \OCP\IConfig */
	private $config;
	private $user;
	/** @var \OC\Repair\RepairLegacyStorages */
	private $repair;

	private $dataDir;
	private $oldDataDir;

	private $legacyStorageId;
	private $newStorageId;

	/** @var IOutput | PHPUnit_Framework_MockObject_MockObject */
	private $outputMock;

	protected function setUp() {
		parent::setUp();

		$this->config = \OC::$server->getConfig();
		$this->connection = \OC::$server->getDatabaseConnection();
		$this->oldDataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');

		$this->repair = new \OC\Repair\RepairLegacyStorages($this->config, $this->connection);

		$this->outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
			->disableOriginalConstructor()
			->getMock();
	}

	protected function tearDown() {
		$user = \OC::$server->getUserManager()->get($this->user);
		if ($user) {
			$user->delete();
		}

		$sql = 'DELETE FROM `*PREFIX*storages`';
		$this->connection->executeQuery($sql);
		$sql = 'DELETE FROM `*PREFIX*filecache`';
		$this->connection->executeQuery($sql);
		$this->config->setSystemValue('datadirectory', $this->oldDataDir);
		$this->config->setAppValue('core', 'repairlegacystoragesdone', 'no');

		parent::tearDown();
	}

	/**
	 * @param string $dataDir
	 * @param string $userId
	 * @throws \Exception
	 */
	function prepareSettings($dataDir, $userId) {
		// hard-coded string as we want a predictable fixed length
		// no data will be written there
		$this->dataDir = $dataDir;
		$this->config->setSystemValue('datadirectory', $this->dataDir);

		$this->user = $userId;
		$this->legacyStorageId = 'local::' . $this->dataDir . $this->user . '/';
		$this->newStorageId = 'home::' . $this->user;
		\OC::$server->getUserManager()->createUser($this->user, $this->user);
	}

	/**
	 * Create a storage entry
	 *
	 * @param string $storageId
	 * @return int
	 */
	private function createStorage($storageId) {
		$sql = 'INSERT INTO `*PREFIX*storages` (`id`)'
			. ' VALUES (?)';

		$storageId = Storage::adjustStorageId($storageId);
		$numRows = $this->connection->executeUpdate($sql, array($storageId));
		$this->assertSame(1, $numRows);

		return (int)\OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*storages');
	}

	/**
	 * Create dummy data in the filecache for the given storage numeric id
	 *
	 * @param string $storageId storage id
	 */
	private function createData($storageId) {
		$cache = new Cache($storageId);
		$cache->put(
			'dummyfile.txt',
			array('size' => 5, 'mtime' => 12, 'mimetype' => 'text/plain')
		);
	}

	/**
	 * Test that existing home storages are left alone when valid.
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testNoopWithExistingHomeStorage($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$newStorageNumId = $this->createStorage($this->newStorageId);

		$this->repair->run($this->outputMock);

		$this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
		$this->assertSame($newStorageNumId, Storage::getNumericStorageId($this->newStorageId));
	}

	/**
	 * Test that legacy storages are converted to home storages when
	 * the latter does not exist.
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testConvertLegacyToHomeStorage($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$legacyStorageNumId = $this->createStorage($this->legacyStorageId);

		$this->repair->run($this->outputMock);

		$this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
		$this->assertSame($legacyStorageNumId, Storage::getNumericStorageId($this->newStorageId));
	}

	/**
	 * Test that legacy storages are converted to home storages
	 * when home storage already exists but has no data.
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testConvertLegacyToExistingEmptyHomeStorage($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$legacyStorageNumId = $this->createStorage($this->legacyStorageId);
		$this->createStorage($this->newStorageId);

		$this->createData($this->legacyStorageId);

		$this->repair->run($this->outputMock);

		$this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
		$this->assertSame($legacyStorageNumId, Storage::getNumericStorageId($this->newStorageId));
	}

	/**
	 * Test that legacy storages are converted to home storages
	 * when home storage already exists and the legacy storage
	 * has no data.
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testConvertEmptyLegacyToHomeStorage($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$this->createStorage($this->legacyStorageId);
		$newStorageNumId = $this->createStorage($this->newStorageId);

		$this->createData($this->newStorageId);

		$this->repair->run($this->outputMock);

		$this->assertNull(Storage::getNumericStorageId($this->legacyStorageId));
		$this->assertSame($newStorageNumId, Storage::getNumericStorageId($this->newStorageId));
	}

	/**
	 * Test that nothing is done when both conflicting legacy
	 * and home storage have data.
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testConflictNoop($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$legacyStorageNumId = $this->createStorage($this->legacyStorageId);
		$newStorageNumId = $this->createStorage($this->newStorageId);

		$this->createData($this->legacyStorageId);
		$this->createData($this->newStorageId);

		$this->outputMock->expects($this->exactly(2))->method('warning');
		$this->repair->run($this->outputMock);

		// storages left alone
		$this->assertSame($legacyStorageNumId, Storage::getNumericStorageId($this->legacyStorageId));
		$this->assertSame($newStorageNumId, Storage::getNumericStorageId($this->newStorageId));

		// do not set the done flag
		$this->assertNotEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
	}

	/**
	 * Test that the data dir local entry is left alone
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testDataDirEntryNoop($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$storageId = 'local::' . $this->dataDir;
		$numId = $this->createStorage($storageId);

		$this->repair->run($this->outputMock);

		$this->assertSame($numId, Storage::getNumericStorageId($storageId));
	}

	/**
	 * Test that external local storages are left alone
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testLocalExtStorageNoop($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$storageId = 'local::/tmp/somedir/' . $this->user;
		$numId = $this->createStorage($storageId);

		$this->repair->run($this->outputMock);

		$this->assertSame($numId, Storage::getNumericStorageId($storageId));
	}

	/**
	 * Test that other external storages are left alone
	 *
	 * @dataProvider settingsProvider
	 *
	 * @param string $dataDir
	 * @param string $userId
	 */
	public function testExtStorageNoop($dataDir, $userId) {
		$this->prepareSettings($dataDir, $userId);
		$storageId = 'smb::user@password/tmp/somedir/' . $this->user;
		$numId = $this->createStorage($storageId);

		$this->repair->run($this->outputMock);

		$this->assertSame($numId, Storage::getNumericStorageId($storageId));
	}

	/**
	 * Provides data dir and user name
	 */
	function settingsProvider() {
		return array(
			// regular data dir
			array(
				'/tmp/oc-autotest/datadir/',
				$this->getUniqueID('user_'),
			),
			// long datadir / short user
			array(
				'/tmp/oc-autotest/datadir01234567890123456789012345678901234567890123456789END/',
				$this->getUniqueID('user_'),
			),
			// short datadir / long user
			array(
				'/tmp/oc-autotest/datadir/',
				'u123456789012345678901234567890123456789012345678901234567890END', // 64 chars
			),
		);
	}

	/**
	 * Only run the repair once
	 */
	public function testOnlyRunOnce() {
		$this->outputMock->expects($this->exactly(1))->method('info');

		$this->prepareSettings('/tmp/oc-autotest/datadir', $this->getUniqueID('user_'));
		$this->assertNotEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
		$this->repair->run($this->outputMock);
		$this->assertEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));

		$this->outputMock->expects($this->never())->method('info');
		$this->repair->run($this->outputMock);
		$this->assertEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
	}
}