diff --git a/lib/private/updater.php b/lib/private/updater.php index 04f8dcf722..9ec72bab2f 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -256,7 +256,7 @@ class Updater extends BasicEmitter { */ public function isUpgradePossible($oldVersion, $newVersion, $allowedPreviousVersion) { return (version_compare($allowedPreviousVersion, $oldVersion, '<=') - && version_compare($oldVersion, $newVersion, '<=')); + && (version_compare($oldVersion, $newVersion, '<=') || $this->config->getSystemValue('debug', false))); } /** diff --git a/lib/private/util.php b/lib/private/util.php index c9738b29ca..6a9980fc12 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -1483,6 +1483,7 @@ class OC_Util { * * @param \OCP\IConfig $config * @return bool whether the core or any app needs an upgrade + * @throws \OC\HintException When the upgrade from the given version is not allowed */ public static function needUpgrade(\OCP\IConfig $config) { if ($config->getSystemValue('installed', false)) { @@ -1491,6 +1492,19 @@ class OC_Util { $versionDiff = version_compare($currentVersion, $installedVersion); if ($versionDiff > 0) { return true; + } else if ($config->getSystemValue('debug', false) && $versionDiff < 0) { + // downgrade with debug + $installedMajor = explode('.', $installedVersion); + $installedMajor = $installedMajor[0] . '.' . $installedMajor[1]; + $currentMajor = explode('.', $currentVersion); + $currentMajor = $currentMajor[0] . '.' . $currentMajor[1]; + if ($installedMajor === $currentMajor) { + // Same major, allow downgrade for developers + return true; + } else { + // downgrade attempt, throw exception + throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')'); + } } else if ($versionDiff < 0) { // downgrade attempt, throw exception throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')'); diff --git a/tests/lib/updater.php b/tests/lib/updater.php index 313ffb6573..8ee77b9f81 100644 --- a/tests/lib/updater.php +++ b/tests/lib/updater.php @@ -27,7 +27,7 @@ use OCP\ILogger; use OC\IntegrityCheck\Checker; class UpdaterTest extends \Test\TestCase { - /** @var IConfig */ + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ private $config; /** @var HTTPHelper */ private $httpHelper; @@ -136,9 +136,33 @@ class UpdaterTest extends \Test\TestCase { ['9.0.0.0', '8.0.0.0', '7.0', false], ['9.1.0.0', '8.0.0.0', '7.0', false], ['8.2.0.0', '8.1.0.0', '8.0', false], + + // With debug enabled + ['8.0.0.0', '8.2.0.0', '8.1', false, true], + ['8.1.0.0', '8.2.0.0', '8.1', true, true], + ['8.2.0.1', '8.2.0.1', '8.1', true, true], + ['8.3.0.0', '8.2.0.0', '8.1', true, true], ]; } + /** + * @dataProvider versionCompatibilityTestData + * + * @param string $oldVersion + * @param string $newVersion + * @param string $allowedVersion + * @param bool $result + * @param bool $debug + */ + public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersion, $result, $debug = false) { + $this->config->expects($this->any()) + ->method('getSystemValue') + ->with('debug', false) + ->willReturn($debug); + + $this->assertSame($result, $this->updater->isUpgradePossible($oldVersion, $newVersion, $allowedVersion)); + } + public function testSetSimulateStepEnabled() { $this->updater->setSimulateStepEnabled(true); $this->assertSame(true, $this->invokePrivate($this->updater, 'simulateStepEnabled')); @@ -160,18 +184,6 @@ class UpdaterTest extends \Test\TestCase { $this->assertSame(false, $this->invokePrivate($this->updater, 'skip3rdPartyAppsDisable')); } - /** - * @dataProvider versionCompatibilityTestData - * - * @param string $oldVersion - * @param string $newVersion - * @param string $allowedVersion - * @param bool $result - */ - public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersion, $result) { - $this->assertSame($result, $this->updater->isUpgradePossible($oldVersion, $newVersion, $allowedVersion)); - } - public function testCheckInCache() { $expectedResult = [ 'version' => '8.0.4.2',