MigrateWriteFailureTest.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php declare(strict_types=1);
  2. use PHPUnit\Framework\TestCase;
  3. use PrivateBin\Data\Filesystem;
  4. class MigrateWriteFailureTest extends TestCase
  5. {
  6. private $_path;
  7. private $_destinationPath;
  8. private $_source;
  9. public function setUp(): void
  10. {
  11. $this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_migrate_write_failure';
  12. Helper::rmDir($this->_path);
  13. mkdir($this->_path);
  14. mkdir($this->_path . DIRECTORY_SEPARATOR . 'source_cfg');
  15. mkdir($this->_path . DIRECTORY_SEPARATOR . 'destination_cfg');
  16. $options = parse_ini_file(CONF_SAMPLE, true);
  17. $options['model_options']['dir'] = $this->_path . DIRECTORY_SEPARATOR . 'source';
  18. $this->_source = new Filesystem($options['model_options']);
  19. Helper::createIniFile(
  20. $this->_path . DIRECTORY_SEPARATOR . 'source_cfg' . DIRECTORY_SEPARATOR . 'conf.php',
  21. $options
  22. );
  23. $this->_destinationPath = $this->_path . DIRECTORY_SEPARATOR . 'blocked';
  24. file_put_contents($this->_destinationPath, 'not a directory');
  25. $options['model_options']['dir'] = $this->_destinationPath;
  26. Helper::createIniFile(
  27. $this->_path . DIRECTORY_SEPARATOR . 'destination_cfg' . DIRECTORY_SEPARATOR . 'conf.php',
  28. $options
  29. );
  30. }
  31. public function tearDown(): void
  32. {
  33. Helper::rmDir($this->_path);
  34. }
  35. public function testSourceIsPreservedWhenDestinationWriteFails()
  36. {
  37. $paste = Helper::getPaste();
  38. $this->_source->create(Helper::getPasteId(), $paste);
  39. [$exitCode, $output] = $this->runMigration();
  40. $this->assertSame(1, $exitCode, $output);
  41. $this->assertStringContainsString(
  42. 'ERROR: Unable to save document ID ' . Helper::getPasteId(),
  43. $output
  44. );
  45. $this->assertTrue($this->_source->exists(Helper::getPasteId()));
  46. }
  47. public function testSourceIsPreservedWhenDestinationCommentWriteFails()
  48. {
  49. unlink($this->_destinationPath);
  50. mkdir(
  51. $this->_destinationPath . DIRECTORY_SEPARATOR .
  52. substr(Helper::getPasteId(), 0, 2) . DIRECTORY_SEPARATOR .
  53. substr(Helper::getPasteId(), 2, 2),
  54. 0777,
  55. true
  56. );
  57. file_put_contents(
  58. $this->_destinationPath . DIRECTORY_SEPARATOR .
  59. substr(Helper::getPasteId(), 0, 2) . DIRECTORY_SEPARATOR .
  60. substr(Helper::getPasteId(), 2, 2) . DIRECTORY_SEPARATOR .
  61. Helper::getPasteId() . '.discussion',
  62. 'not a directory'
  63. );
  64. $paste = Helper::getPaste();
  65. $this->_source->create(Helper::getPasteId(), $paste);
  66. $comment = Helper::getComment();
  67. $this->_source->createComment(
  68. Helper::getPasteId(),
  69. Helper::getPasteId(),
  70. Helper::getCommentId(),
  71. $comment
  72. );
  73. [$exitCode, $output] = $this->runMigration();
  74. $this->assertSame(1, $exitCode, $output);
  75. $this->assertStringContainsString(
  76. 'ERROR: Unable to save document ID ' . Helper::getPasteId() .
  77. ', parent id ' . Helper::getPasteId() .
  78. ', comment id ' . Helper::getCommentId(),
  79. $output
  80. );
  81. $this->assertTrue($this->_source->exists(Helper::getPasteId()));
  82. $this->assertTrue($this->_source->existsComment(
  83. Helper::getPasteId(),
  84. Helper::getPasteId(),
  85. Helper::getCommentId()
  86. ));
  87. }
  88. private function runMigration()
  89. {
  90. $command = escapeshellarg(PHP_BINARY) . ' ' .
  91. escapeshellarg(realpath(PATH . 'bin' . DIRECTORY_SEPARATOR . 'migrate')) .
  92. ' --delete-after ' .
  93. escapeshellarg($this->_path . DIRECTORY_SEPARATOR . 'source_cfg') . ' ' .
  94. escapeshellarg($this->_path . DIRECTORY_SEPARATOR . 'destination_cfg') .
  95. ' 2>&1';
  96. exec($command, $output, $exitCode);
  97. return [$exitCode, implode(PHP_EOL, $output)];
  98. }
  99. }