MigrationsTest.php 23 KB

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