MigrationsTest.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\DB;
  8. use Doctrine\DBAL\Schema\Column;
  9. use Doctrine\DBAL\Schema\ForeignKeyConstraint;
  10. use Doctrine\DBAL\Schema\Index;
  11. use Doctrine\DBAL\Schema\Schema;
  12. use Doctrine\DBAL\Schema\SchemaException;
  13. use Doctrine\DBAL\Schema\Sequence;
  14. use Doctrine\DBAL\Schema\Table;
  15. use Doctrine\DBAL\Types\Type;
  16. use OC\DB\Connection;
  17. use OC\DB\MigrationService;
  18. use OC\DB\SchemaWrapper;
  19. use OCP\IDBConnection;
  20. use OCP\Migration\IMigrationStep;
  21. /**
  22. * Class MigrationsTest
  23. *
  24. * @package Test\DB
  25. */
  26. class MigrationsTest extends \Test\TestCase {
  27. /** @var MigrationService | \PHPUnit\Framework\MockObject\MockObject */
  28. private $migrationService;
  29. /** @var \PHPUnit\Framework\MockObject\MockObject | IDBConnection $db */
  30. private $db;
  31. protected function setUp(): void {
  32. parent::setUp();
  33. $this->db = $this->createMock(Connection::class);
  34. $this->db->expects($this->any())->method('getPrefix')->willReturn('test_oc_');
  35. $this->migrationService = new MigrationService('testing', $this->db);
  36. }
  37. public function testGetters() {
  38. $this->assertEquals('testing', $this->migrationService->getApp());
  39. $this->assertEquals(\OC::$SERVERROOT . '/apps/testing/lib/Migration', $this->migrationService->getMigrationsDirectory());
  40. $this->assertEquals('OCA\Testing\Migration', $this->migrationService->getMigrationsNamespace());
  41. $this->assertEquals('test_oc_migrations', $this->migrationService->getMigrationsTableName());
  42. }
  43. public function testCore() {
  44. $this->migrationService = new MigrationService('core', $this->db);
  45. $this->assertEquals('core', $this->migrationService->getApp());
  46. $this->assertEquals(\OC::$SERVERROOT . '/core/Migrations', $this->migrationService->getMigrationsDirectory());
  47. $this->assertEquals('OC\Core\Migrations', $this->migrationService->getMigrationsNamespace());
  48. $this->assertEquals('test_oc_migrations', $this->migrationService->getMigrationsTableName());
  49. }
  50. public function testExecuteUnknownStep() {
  51. $this->expectException(\InvalidArgumentException::class);
  52. $this->expectExceptionMessage('Version 20170130180000 is unknown.');
  53. $this->migrationService->executeStep('20170130180000');
  54. }
  55. public function testUnknownApp() {
  56. $this->expectException(\Exception::class);
  57. $this->expectExceptionMessage('App not found');
  58. $migrationService = new MigrationService('unknown-bloody-app', $this->db);
  59. }
  60. public function testExecuteStepWithUnknownClass() {
  61. $this->expectException(\Exception::class);
  62. $this->expectExceptionMessage('Migration step \'X\' is unknown');
  63. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  64. ->setMethods(['findMigrations'])
  65. ->setConstructorArgs(['testing', $this->db])
  66. ->getMock();
  67. $this->migrationService->expects($this->any())->method('findMigrations')->willReturn(
  68. ['20170130180000' => 'X', '20170130180001' => 'Y', '20170130180002' => 'Z', '20170130180003' => 'A']
  69. );
  70. $this->migrationService->executeStep('20170130180000');
  71. }
  72. public function testExecuteStepWithSchemaChange() {
  73. $schema = $this->createMock(Schema::class);
  74. $this->db->expects($this->any())
  75. ->method('createSchema')
  76. ->willReturn($schema);
  77. $this->db->expects($this->once())
  78. ->method('migrateToSchema');
  79. $wrappedSchema = $this->createMock(Schema::class);
  80. $wrappedSchema->expects($this->exactly(2))
  81. ->method('getTables')
  82. ->willReturn([]);
  83. $wrappedSchema->expects($this->exactly(2))
  84. ->method('getSequences')
  85. ->willReturn([]);
  86. $schemaResult = $this->createMock(SchemaWrapper::class);
  87. $schemaResult->expects($this->once())
  88. ->method('getWrappedSchema')
  89. ->willReturn($wrappedSchema);
  90. $step = $this->createMock(IMigrationStep::class);
  91. $step->expects($this->once())
  92. ->method('preSchemaChange');
  93. $step->expects($this->once())
  94. ->method('changeSchema')
  95. ->willReturn($schemaResult);
  96. $step->expects($this->once())
  97. ->method('postSchemaChange');
  98. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  99. ->setMethods(['createInstance'])
  100. ->setConstructorArgs(['testing', $this->db])
  101. ->getMock();
  102. $this->migrationService->expects($this->any())
  103. ->method('createInstance')
  104. ->with('20170130180000')
  105. ->willReturn($step);
  106. $this->migrationService->executeStep('20170130180000');
  107. }
  108. public function testExecuteStepWithoutSchemaChange() {
  109. $schema = $this->createMock(Schema::class);
  110. $this->db->expects($this->any())
  111. ->method('createSchema')
  112. ->willReturn($schema);
  113. $this->db->expects($this->never())
  114. ->method('migrateToSchema');
  115. $step = $this->createMock(IMigrationStep::class);
  116. $step->expects($this->once())
  117. ->method('preSchemaChange');
  118. $step->expects($this->once())
  119. ->method('changeSchema')
  120. ->willReturn(null);
  121. $step->expects($this->once())
  122. ->method('postSchemaChange');
  123. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  124. ->setMethods(['createInstance'])
  125. ->setConstructorArgs(['testing', $this->db])
  126. ->getMock();
  127. $this->migrationService->expects($this->any())
  128. ->method('createInstance')
  129. ->with('20170130180000')
  130. ->willReturn($step);
  131. $this->migrationService->executeStep('20170130180000');
  132. }
  133. public function dataGetMigration() {
  134. return [
  135. ['current', '20170130180001'],
  136. ['prev', '20170130180000'],
  137. ['next', '20170130180002'],
  138. ['latest', '20170130180003'],
  139. ];
  140. }
  141. /**
  142. * @dataProvider dataGetMigration
  143. * @param string $alias
  144. * @param string $expected
  145. */
  146. public function testGetMigration($alias, $expected) {
  147. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  148. ->setMethods(['getMigratedVersions', 'findMigrations'])
  149. ->setConstructorArgs(['testing', $this->db])
  150. ->getMock();
  151. $this->migrationService->expects($this->any())->method('getMigratedVersions')->willReturn(
  152. ['20170130180000', '20170130180001']
  153. );
  154. $this->migrationService->expects($this->any())->method('findMigrations')->willReturn(
  155. ['20170130180000' => 'X', '20170130180001' => 'Y', '20170130180002' => 'Z', '20170130180003' => 'A']
  156. );
  157. $this->assertEquals(
  158. ['20170130180000', '20170130180001', '20170130180002', '20170130180003'],
  159. $this->migrationService->getAvailableVersions());
  160. $migration = $this->migrationService->getMigration($alias);
  161. $this->assertEquals($expected, $migration);
  162. }
  163. public function testMigrate() {
  164. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  165. ->setMethods(['getMigratedVersions', 'findMigrations', 'executeStep'])
  166. ->setConstructorArgs(['testing', $this->db])
  167. ->getMock();
  168. $this->migrationService->expects($this->any())->method('getMigratedVersions')->willReturn(
  169. ['20170130180000', '20170130180001']
  170. );
  171. $this->migrationService->expects($this->any())->method('findMigrations')->willReturn(
  172. ['20170130180000' => 'X', '20170130180001' => 'Y', '20170130180002' => 'Z', '20170130180003' => 'A']
  173. );
  174. $this->assertEquals(
  175. ['20170130180000', '20170130180001', '20170130180002', '20170130180003'],
  176. $this->migrationService->getAvailableVersions());
  177. $this->migrationService->expects($this->exactly(2))->method('executeStep')
  178. ->withConsecutive(['20170130180002'], ['20170130180003']);
  179. $this->migrationService->migrate();
  180. }
  181. public function testEnsureOracleConstraintsValid() {
  182. $column = $this->createMock(Column::class);
  183. $column->expects($this->once())
  184. ->method('getName')
  185. ->willReturn(\str_repeat('a', 30));
  186. $index = $this->createMock(Index::class);
  187. $index->expects($this->once())
  188. ->method('getName')
  189. ->willReturn(\str_repeat('a', 30));
  190. $foreignKey = $this->createMock(ForeignKeyConstraint::class);
  191. $foreignKey->expects($this->once())
  192. ->method('getName')
  193. ->willReturn(\str_repeat('a', 30));
  194. $table = $this->createMock(Table::class);
  195. $table->expects($this->atLeastOnce())
  196. ->method('getName')
  197. ->willReturn(\str_repeat('a', 30));
  198. $sequence = $this->createMock(Sequence::class);
  199. $sequence->expects($this->atLeastOnce())
  200. ->method('getName')
  201. ->willReturn(\str_repeat('a', 30));
  202. $primaryKey = $this->createMock(Index::class);
  203. $primaryKey->expects($this->once())
  204. ->method('getName')
  205. ->willReturn(\str_repeat('a', 30));
  206. $table->expects($this->once())
  207. ->method('getColumns')
  208. ->willReturn([$column]);
  209. $table->expects($this->once())
  210. ->method('getIndexes')
  211. ->willReturn([$index]);
  212. $table->expects($this->once())
  213. ->method('getForeignKeys')
  214. ->willReturn([$foreignKey]);
  215. $table->expects($this->once())
  216. ->method('getPrimaryKey')
  217. ->willReturn($primaryKey);
  218. $schema = $this->createMock(Schema::class);
  219. $schema->expects($this->once())
  220. ->method('getTables')
  221. ->willReturn([$table]);
  222. $schema->expects($this->once())
  223. ->method('getSequences')
  224. ->willReturn([$sequence]);
  225. $sourceSchema = $this->createMock(Schema::class);
  226. $sourceSchema->expects($this->any())
  227. ->method('getTable')
  228. ->willThrowException(new SchemaException());
  229. $sourceSchema->expects($this->any())
  230. ->method('hasSequence')
  231. ->willReturn(false);
  232. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  233. }
  234. public function testEnsureOracleConstraintsValidWithPrimaryKey() {
  235. $index = $this->createMock(Index::class);
  236. $index->expects($this->any())
  237. ->method('getName')
  238. ->willReturn(\str_repeat('a', 30));
  239. $table = $this->createMock(Table::class);
  240. $table->expects($this->any())
  241. ->method('getName')
  242. ->willReturn(\str_repeat('a', 26));
  243. $table->expects($this->once())
  244. ->method('getColumns')
  245. ->willReturn([]);
  246. $table->expects($this->once())
  247. ->method('getIndexes')
  248. ->willReturn([]);
  249. $table->expects($this->once())
  250. ->method('getForeignKeys')
  251. ->willReturn([]);
  252. $table->expects($this->once())
  253. ->method('getPrimaryKey')
  254. ->willReturn($index);
  255. $schema = $this->createMock(Schema::class);
  256. $schema->expects($this->once())
  257. ->method('getTables')
  258. ->willReturn([$table]);
  259. $schema->expects($this->once())
  260. ->method('getSequences')
  261. ->willReturn([]);
  262. $sourceSchema = $this->createMock(Schema::class);
  263. $sourceSchema->expects($this->any())
  264. ->method('getTable')
  265. ->willThrowException(new SchemaException());
  266. $sourceSchema->expects($this->any())
  267. ->method('hasSequence')
  268. ->willReturn(false);
  269. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  270. }
  271. public function testEnsureOracleConstraintsValidWithPrimaryKeyDefault() {
  272. $defaultName = 'PRIMARY';
  273. if ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
  274. $defaultName = \str_repeat('a', 26) . '_' . \str_repeat('b', 30) . '_seq';
  275. } elseif ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
  276. $defaultName = \str_repeat('a', 26) . '_seq';
  277. }
  278. $index = $this->createMock(Index::class);
  279. $index->expects($this->any())
  280. ->method('getName')
  281. ->willReturn($defaultName);
  282. $index->expects($this->any())
  283. ->method('getColumns')
  284. ->willReturn([\str_repeat('b', 30)]);
  285. $table = $this->createMock(Table::class);
  286. $table->expects($this->any())
  287. ->method('getName')
  288. ->willReturn(\str_repeat('a', 25));
  289. $table->expects($this->once())
  290. ->method('getColumns')
  291. ->willReturn([]);
  292. $table->expects($this->once())
  293. ->method('getIndexes')
  294. ->willReturn([]);
  295. $table->expects($this->once())
  296. ->method('getForeignKeys')
  297. ->willReturn([]);
  298. $table->expects($this->once())
  299. ->method('getPrimaryKey')
  300. ->willReturn($index);
  301. $schema = $this->createMock(Schema::class);
  302. $schema->expects($this->once())
  303. ->method('getTables')
  304. ->willReturn([$table]);
  305. $schema->expects($this->once())
  306. ->method('getSequences')
  307. ->willReturn([]);
  308. $sourceSchema = $this->createMock(Schema::class);
  309. $sourceSchema->expects($this->any())
  310. ->method('getTable')
  311. ->willThrowException(new SchemaException());
  312. $sourceSchema->expects($this->any())
  313. ->method('hasSequence')
  314. ->willReturn(false);
  315. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  316. }
  317. public function testEnsureOracleConstraintsTooLongTableName() {
  318. $this->expectException(\InvalidArgumentException::class);
  319. $table = $this->createMock(Table::class);
  320. $table->expects($this->any())
  321. ->method('getName')
  322. ->willReturn(\str_repeat('a', 31));
  323. $schema = $this->createMock(Schema::class);
  324. $schema->expects($this->once())
  325. ->method('getTables')
  326. ->willReturn([$table]);
  327. $sourceSchema = $this->createMock(Schema::class);
  328. $sourceSchema->expects($this->any())
  329. ->method('getTable')
  330. ->willThrowException(new SchemaException());
  331. $sourceSchema->expects($this->any())
  332. ->method('hasSequence')
  333. ->willReturn(false);
  334. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  335. }
  336. public function testEnsureOracleConstraintsTooLongPrimaryWithDefault() {
  337. $this->expectException(\InvalidArgumentException::class);
  338. $defaultName = 'PRIMARY';
  339. if ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
  340. $defaultName = \str_repeat('a', 27) . '_' . \str_repeat('b', 30) . '_seq';
  341. } elseif ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
  342. $defaultName = \str_repeat('a', 27) . '_seq';
  343. }
  344. $index = $this->createMock(Index::class);
  345. $index->expects($this->any())
  346. ->method('getName')
  347. ->willReturn($defaultName);
  348. $index->expects($this->any())
  349. ->method('getColumns')
  350. ->willReturn([\str_repeat('b', 30)]);
  351. $table = $this->createMock(Table::class);
  352. $table->expects($this->any())
  353. ->method('getName')
  354. ->willReturn(\str_repeat('a', 27));
  355. $table->expects($this->once())
  356. ->method('getColumns')
  357. ->willReturn([]);
  358. $table->expects($this->once())
  359. ->method('getIndexes')
  360. ->willReturn([]);
  361. $table->expects($this->once())
  362. ->method('getForeignKeys')
  363. ->willReturn([]);
  364. $table->expects($this->once())
  365. ->method('getPrimaryKey')
  366. ->willReturn($index);
  367. $schema = $this->createMock(Schema::class);
  368. $schema->expects($this->once())
  369. ->method('getTables')
  370. ->willReturn([$table]);
  371. $sourceSchema = $this->createMock(Schema::class);
  372. $sourceSchema->expects($this->any())
  373. ->method('getTable')
  374. ->willThrowException(new SchemaException());
  375. $sourceSchema->expects($this->any())
  376. ->method('hasSequence')
  377. ->willReturn(false);
  378. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  379. }
  380. public function testEnsureOracleConstraintsTooLongPrimaryWithName() {
  381. $this->expectException(\InvalidArgumentException::class);
  382. $index = $this->createMock(Index::class);
  383. $index->expects($this->any())
  384. ->method('getName')
  385. ->willReturn(\str_repeat('a', 31));
  386. $table = $this->createMock(Table::class);
  387. $table->expects($this->any())
  388. ->method('getName')
  389. ->willReturn(\str_repeat('a', 26));
  390. $table->expects($this->once())
  391. ->method('getColumns')
  392. ->willReturn([]);
  393. $table->expects($this->once())
  394. ->method('getIndexes')
  395. ->willReturn([]);
  396. $table->expects($this->once())
  397. ->method('getForeignKeys')
  398. ->willReturn([]);
  399. $table->expects($this->once())
  400. ->method('getPrimaryKey')
  401. ->willReturn($index);
  402. $schema = $this->createMock(Schema::class);
  403. $schema->expects($this->once())
  404. ->method('getTables')
  405. ->willReturn([$table]);
  406. $sourceSchema = $this->createMock(Schema::class);
  407. $sourceSchema->expects($this->any())
  408. ->method('getTable')
  409. ->willThrowException(new SchemaException());
  410. $sourceSchema->expects($this->any())
  411. ->method('hasSequence')
  412. ->willReturn(false);
  413. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  414. }
  415. public function testEnsureOracleConstraintsTooLongColumnName() {
  416. $this->expectException(\InvalidArgumentException::class);
  417. $column = $this->createMock(Column::class);
  418. $column->expects($this->any())
  419. ->method('getName')
  420. ->willReturn(\str_repeat('a', 31));
  421. $table = $this->createMock(Table::class);
  422. $table->expects($this->any())
  423. ->method('getName')
  424. ->willReturn(\str_repeat('a', 30));
  425. $table->expects($this->once())
  426. ->method('getColumns')
  427. ->willReturn([$column]);
  428. $schema = $this->createMock(Schema::class);
  429. $schema->expects($this->once())
  430. ->method('getTables')
  431. ->willReturn([$table]);
  432. $sourceSchema = $this->createMock(Schema::class);
  433. $sourceSchema->expects($this->any())
  434. ->method('getTable')
  435. ->willThrowException(new SchemaException());
  436. $sourceSchema->expects($this->any())
  437. ->method('hasSequence')
  438. ->willReturn(false);
  439. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  440. }
  441. public function testEnsureOracleConstraintsTooLongIndexName() {
  442. $this->expectException(\InvalidArgumentException::class);
  443. $index = $this->createMock(Index::class);
  444. $index->expects($this->any())
  445. ->method('getName')
  446. ->willReturn(\str_repeat('a', 31));
  447. $table = $this->createMock(Table::class);
  448. $table->expects($this->any())
  449. ->method('getName')
  450. ->willReturn(\str_repeat('a', 30));
  451. $table->expects($this->once())
  452. ->method('getColumns')
  453. ->willReturn([]);
  454. $table->expects($this->once())
  455. ->method('getIndexes')
  456. ->willReturn([$index]);
  457. $schema = $this->createMock(Schema::class);
  458. $schema->expects($this->once())
  459. ->method('getTables')
  460. ->willReturn([$table]);
  461. $sourceSchema = $this->createMock(Schema::class);
  462. $sourceSchema->expects($this->any())
  463. ->method('getTable')
  464. ->willThrowException(new SchemaException());
  465. $sourceSchema->expects($this->any())
  466. ->method('hasSequence')
  467. ->willReturn(false);
  468. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  469. }
  470. public function testEnsureOracleConstraintsTooLongForeignKeyName() {
  471. $this->expectException(\InvalidArgumentException::class);
  472. $foreignKey = $this->createMock(ForeignKeyConstraint::class);
  473. $foreignKey->expects($this->any())
  474. ->method('getName')
  475. ->willReturn(\str_repeat('a', 31));
  476. $table = $this->createMock(Table::class);
  477. $table->expects($this->any())
  478. ->method('getName')
  479. ->willReturn(\str_repeat('a', 30));
  480. $table->expects($this->once())
  481. ->method('getColumns')
  482. ->willReturn([]);
  483. $table->expects($this->once())
  484. ->method('getIndexes')
  485. ->willReturn([]);
  486. $table->expects($this->once())
  487. ->method('getForeignKeys')
  488. ->willReturn([$foreignKey]);
  489. $schema = $this->createMock(Schema::class);
  490. $schema->expects($this->once())
  491. ->method('getTables')
  492. ->willReturn([$table]);
  493. $sourceSchema = $this->createMock(Schema::class);
  494. $sourceSchema->expects($this->any())
  495. ->method('getTable')
  496. ->willThrowException(new SchemaException());
  497. $sourceSchema->expects($this->any())
  498. ->method('hasSequence')
  499. ->willReturn(false);
  500. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  501. }
  502. public function testEnsureOracleConstraintsNoPrimaryKey() {
  503. $this->markTestSkipped('Test disabled for now due to multiple reasons, see https://github.com/nextcloud/server/pull/31580#issuecomment-1069182234 for details.');
  504. $this->expectException(\InvalidArgumentException::class);
  505. $table = $this->createMock(Table::class);
  506. $table->expects($this->atLeastOnce())
  507. ->method('getName')
  508. ->willReturn(\str_repeat('a', 30));
  509. $table->expects($this->once())
  510. ->method('getColumns')
  511. ->willReturn([]);
  512. $table->expects($this->once())
  513. ->method('getIndexes')
  514. ->willReturn([]);
  515. $table->expects($this->once())
  516. ->method('getForeignKeys')
  517. ->willReturn([]);
  518. $table->expects($this->once())
  519. ->method('getPrimaryKey')
  520. ->willReturn(null);
  521. $schema = $this->createMock(Schema::class);
  522. $schema->expects($this->once())
  523. ->method('getTables')
  524. ->willReturn([$table]);
  525. $schema->expects($this->once())
  526. ->method('getSequences')
  527. ->willReturn([]);
  528. $sourceSchema = $this->createMock(Schema::class);
  529. $sourceSchema->expects($this->any())
  530. ->method('getTable')
  531. ->willThrowException(new SchemaException());
  532. $sourceSchema->expects($this->any())
  533. ->method('hasSequence')
  534. ->willReturn(false);
  535. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  536. }
  537. public function testEnsureOracleConstraintsTooLongSequenceName() {
  538. $this->expectException(\InvalidArgumentException::class);
  539. $sequence = $this->createMock(Sequence::class);
  540. $sequence->expects($this->any())
  541. ->method('getName')
  542. ->willReturn(\str_repeat('a', 31));
  543. $schema = $this->createMock(Schema::class);
  544. $schema->expects($this->once())
  545. ->method('getTables')
  546. ->willReturn([]);
  547. $schema->expects($this->once())
  548. ->method('getSequences')
  549. ->willReturn([$sequence]);
  550. $sourceSchema = $this->createMock(Schema::class);
  551. $sourceSchema->expects($this->any())
  552. ->method('getTable')
  553. ->willThrowException(new SchemaException());
  554. $sourceSchema->expects($this->any())
  555. ->method('hasSequence')
  556. ->willReturn(false);
  557. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  558. }
  559. public function testEnsureOracleConstraintsBooleanNotNull() {
  560. $this->expectException(\InvalidArgumentException::class);
  561. $column = $this->createMock(Column::class);
  562. $column->expects($this->any())
  563. ->method('getName')
  564. ->willReturn('aaaa');
  565. $column->expects($this->any())
  566. ->method('getType')
  567. ->willReturn(Type::getType('boolean'));
  568. $column->expects($this->any())
  569. ->method('getNotnull')
  570. ->willReturn(true);
  571. $table = $this->createMock(Table::class);
  572. $table->expects($this->any())
  573. ->method('getName')
  574. ->willReturn(\str_repeat('a', 30));
  575. $table->expects($this->once())
  576. ->method('getColumns')
  577. ->willReturn([$column]);
  578. $schema = $this->createMock(Schema::class);
  579. $schema->expects($this->once())
  580. ->method('getTables')
  581. ->willReturn([$table]);
  582. $sourceSchema = $this->createMock(Schema::class);
  583. $sourceSchema->expects($this->any())
  584. ->method('getTable')
  585. ->willThrowException(new SchemaException());
  586. $sourceSchema->expects($this->any())
  587. ->method('hasSequence')
  588. ->willReturn(false);
  589. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  590. }
  591. public function testEnsureOracleConstraintsStringLength4000() {
  592. $this->expectException(\InvalidArgumentException::class);
  593. $column = $this->createMock(Column::class);
  594. $column->expects($this->any())
  595. ->method('getName')
  596. ->willReturn('aaaa');
  597. $column->expects($this->any())
  598. ->method('getType')
  599. ->willReturn(Type::getType('string'));
  600. $column->expects($this->any())
  601. ->method('getLength')
  602. ->willReturn(4001);
  603. $table = $this->createMock(Table::class);
  604. $table->expects($this->any())
  605. ->method('getName')
  606. ->willReturn(\str_repeat('a', 30));
  607. $table->expects($this->once())
  608. ->method('getColumns')
  609. ->willReturn([$column]);
  610. $schema = $this->createMock(Schema::class);
  611. $schema->expects($this->once())
  612. ->method('getTables')
  613. ->willReturn([$table]);
  614. $sourceSchema = $this->createMock(Schema::class);
  615. $sourceSchema->expects($this->any())
  616. ->method('getTable')
  617. ->willThrowException(new SchemaException());
  618. $sourceSchema->expects($this->any())
  619. ->method('hasSequence')
  620. ->willReturn(false);
  621. self::invokePrivate($this->migrationService, 'ensureOracleConstraints', [$sourceSchema, $schema, 3]);
  622. }
  623. }