From 0fd7ff78daf62e6faf4600ee2a8fcfda154952b3 Mon Sep 17 00:00:00 2001 From: otsch Date: Thu, 22 Jun 2023 01:13:48 +0200 Subject: [PATCH] Fix issue with writing the index file When the new content of the ppq index file was shorter than the old content, it wrote the new content starting from the beginning of the file and the part of the old content that was longer than the new content, remained at the end of the file. Fixed it be truncating the file before writing the new content. --- CHANGELOG.md | 5 ++ src/Drivers/FileDriver.php | 2 + tests/ConfigTest.php | 2 +- tests/Drivers/FileDriverTest.php | 32 +++++++++-- tests/KernelTest.php | 2 +- tests/ListCommandTest.php | 4 +- tests/Loggers/FileLoggerTest.php | 2 +- tests/LogsTest.php | 10 ++-- tests/Pest.php | 57 ++++++++++++++----- tests/ProcessTest.php | 4 +- tests/ProcessesTest.php | 6 +- tests/QueueTest.php | 2 +- tests/SignalTest.php | 6 +- tests/Stubs/Listeners/DefaultCancelled.php | 5 +- tests/Stubs/Listeners/DefaultFailed.php | 5 +- tests/Stubs/Listeners/DefaultFinished.php | 5 +- tests/Stubs/Listeners/DefaultLost.php | 5 +- tests/Stubs/Listeners/DefaultRunning.php | 5 +- tests/Stubs/Listeners/DefaultWaiting.php | 5 +- tests/Stubs/Listeners/OtherQueueFailedOne.php | 9 +-- .../Stubs/Listeners/OtherQueueFailedThree.php | 5 +- tests/Stubs/Listeners/OtherQueueFailedTwo.php | 5 +- .../Listeners/TestQueueEventListener.php | 17 ++++++ tests/WorkerProcessTest.php | 2 +- tests/WorkerTest.php | 4 +- tests/_integration/CancelJobTest.php | 4 +- tests/_integration/ClearQueueTest.php | 4 +- tests/_integration/FlushQueueTest.php | 4 +- tests/_integration/JobLogTest.php | 4 +- .../_integration/QueueEventListenersTest.php | 14 ++--- tests/_integration/WorkCommandTest.php | 2 +- 31 files changed, 150 insertions(+), 88 deletions(-) create mode 100644 tests/Stubs/Listeners/TestQueueEventListener.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 695065d..01ae661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,4 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.1] - 2022-06-22 + +### Fixed +* When the new content of the ppq index file was shorter than the old content, it wrote the new content starting from the beginning of the file and the part of the old content that was longer than the new content, remained at the end of the file. Fixed it be truncating the file before writing the new content. + ## [0.1.0] - 2022-06-21 diff --git a/src/Drivers/FileDriver.php b/src/Drivers/FileDriver.php index 4492a23..a748d4f 100644 --- a/src/Drivers/FileDriver.php +++ b/src/Drivers/FileDriver.php @@ -293,6 +293,8 @@ protected function getUnserializedFileContent(string $filepath, mixed $handle = */ protected function saveIndex(array $index, mixed $handle): void { + ftruncate($handle, 0); + fwrite($handle, serialize($index)); } diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php index 24b42a6..0c77d21 100644 --- a/tests/ConfigTest.php +++ b/tests/ConfigTest.php @@ -9,7 +9,7 @@ function helper_configFilePath(string $configFile = 'min.php'): string { - return __DIR__ . '/_testdata/config/' . $configFile; + return helper_testConfigPath($configFile); } test( diff --git a/tests/Drivers/FileDriverTest.php b/tests/Drivers/FileDriverTest.php index d758bf3..300e6bb 100644 --- a/tests/Drivers/FileDriverTest.php +++ b/tests/Drivers/FileDriverTest.php @@ -8,7 +8,7 @@ use Stubs\TestJob; beforeEach(function () { - Config::setPath(__DIR__ . '/../_testdata/config/ppq.php'); + Config::setPath(helper_testConfigPath('ppq.php')); helper_cleanUpDataPathQueueFiles(); }); @@ -76,7 +76,7 @@ }); test('the end of a previously longer content does not remain in a file when a shorter content is written', function () { - expect(file_get_contents(__DIR__ . '/../_testdata/datapath/queue-default'))->toBe('a:0:{}'); + expect(file_get_contents(helper_testDataPath('queue-default')))->toBe('a:0:{}'); $driver = new FileDriver(); @@ -86,7 +86,7 @@ $strlenId = strlen($job->id); - expect(file_get_contents(__DIR__ . '/../_testdata/datapath/queue-default'))->toBe( + expect(file_get_contents(helper_testDataPath('queue-default')))->toBe( 'a:1:{s:' . $strlenId . ':"' . $job->id .'";a:7:{s:2:"id";s:' . $strlenId .':"' . $job->id . '";s:5:"queue";' . 's:7:"default";s:8:"jobClass";s:13:"Stubs\TestJob";s:6:"status";s:7:"waiting";s:4:"args";a:0:{}s:3:"pid";N;' . 's:8:"doneTime";N;}}' @@ -96,13 +96,37 @@ $driver->update($job); - expect(file_get_contents(__DIR__ . '/../_testdata/datapath/queue-default'))->toBe( + expect(file_get_contents(helper_testDataPath('queue-default')))->toBe( 'a:1:{s:' . $strlenId . ':"' . $job->id .'";a:7:{s:2:"id";s:' . $strlenId .':"' . $job->id . '";s:5:"queue";' . 's:7:"default";s:8:"jobClass";s:13:"Stubs\TestJob";s:6:"status";s:4:"lost";s:4:"args";a:0:{}s:3:"pid";N;' . 's:8:"doneTime";N;}}' ); }); +test('there are also no remainders in the index file, e.g. when flushing a queue', function () { + expect(file_get_contents(helper_testDataPath('index')))->toBe('a:0:{}'); + + $driver = new FileDriver(); + + $job = new QueueRecord('default', TestJob::class); + + $driver->add($job); + + $contentAfterAdd = file_get_contents(helper_testDataPath('index')); + + if (!$contentAfterAdd) { + $contentAfterAdd = ''; + } + + expect(strlen($contentAfterAdd))->toBeGreaterThan(10); + + $driver->flush('default'); + + $contentAfterFlush = file_get_contents(helper_testDataPath('index')); + + expect($contentAfterFlush)->toBe('a:0:{}'); +}); + it('forgets a job', function () { $driver = new FileDriver(); diff --git a/tests/KernelTest.php b/tests/KernelTest.php index 0da9494..a801576 100644 --- a/tests/KernelTest.php +++ b/tests/KernelTest.php @@ -15,7 +15,7 @@ /** @var TestCase $this */ beforeEach(function () { - Config::setPath(__DIR__ . '/_testdata/config/ppq.php'); + Config::setPath(helper_testConfigPath('ppq.php')); }); it('returns an existing ppqPath', function () { diff --git a/tests/ListCommandTest.php b/tests/ListCommandTest.php index 22c9e99..a618e7f 100644 --- a/tests/ListCommandTest.php +++ b/tests/ListCommandTest.php @@ -11,9 +11,9 @@ it('lists all the waiting and running jobs in all queues', function () { // temporarily switch config, so the driver instance is reset. - Config::setPath(__DIR__ . '/_testdata/config/min.php'); + Config::setPath(helper_testConfigPath('min.php')); - Config::setPath(__DIR__ . '/_testdata/config/ppq.php'); + Config::setPath(helper_testConfigPath('ppq.php')); $driver = Config::getDriver(); diff --git a/tests/Loggers/FileLoggerTest.php b/tests/Loggers/FileLoggerTest.php index b7f5ad5..62e3549 100644 --- a/tests/Loggers/FileLoggerTest.php +++ b/tests/Loggers/FileLoggerTest.php @@ -5,7 +5,7 @@ function helper_testLogFilePath(): string { - return __DIR__ . '/../_testdata/datapath/logfile'; + return helper_testDataPath('logfile'); } function helper_getLogFileContent(): string diff --git a/tests/LogsTest.php b/tests/LogsTest.php index eb750d7..6452a7b 100644 --- a/tests/LogsTest.php +++ b/tests/LogsTest.php @@ -13,7 +13,7 @@ use Stubs\LogTestJob; beforeAll(function () { - Config::setPath(__DIR__ . '/_testdata/config/filesystem-ppq.php'); + Config::setPath(helper_testConfigPath('filesystem-ppq.php')); helper_cleanUpDataPathQueueFiles(); @@ -103,21 +103,21 @@ }); it('tells you the log base path', function () { - expect(realpath(Logs::logPath()))->toBe(__DIR__ . '/_testdata/datapath/logs'); + expect(realpath(Logs::logPath()))->toBe(helper_testDataPath('logs')); }); it('tells you the log path for a certain queue', function () { - expect(Logs::queueLogPath('other_queue'))->toBe(__DIR__ . '/_testdata/config/../datapath/logs/other_queue'); + expect(realpath(Logs::queueLogPath('other_queue')))->toBe(helper_testDataPath('logs/other_queue')); }); it('forgets the log file for a queue job', function () { $job = new QueueRecord('default', LogTestJob::class, id: '123abc'); - expect(file_exists(__DIR__ . '/_testdata/datapath/logs/default/' . $job->id . '.log'))->toBeTrue(); + expect(file_exists(helper_testDataPath('logs/default/' . $job->id . '.log')))->toBeTrue(); Logs::forget($job); - expect(file_exists(__DIR__ . '/_testdata/datapath/logs/default/' . $job->id . '.log'))->toBeFalse(); + expect(file_exists(helper_testDataPath('logs/default/' . $job->id . '.log')))->toBeFalse(); }); it('creates the log dirs if they don\'t exist yet', function () { diff --git a/tests/Pest.php b/tests/Pest.php index 749b769..ad6ce14 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -39,46 +39,73 @@ | */ +function helper_testDataPath(string $withinPath = ''): string +{ + if (!empty($withinPath)) { + $withinPath = str_starts_with($withinPath, '/') ? $withinPath : '/' . $withinPath; + } + + return __DIR__ . '/_testdata/datapath' . $withinPath; +} + +function helper_testConfigPath(string $withinPath = ''): string +{ + if (!empty($withinPath)) { + $withinPath = str_starts_with($withinPath, '/') ? $withinPath : '/' . $withinPath; + } + + return __DIR__ . '/_testdata/config' . $withinPath; +} + +function helper_testScriptPath(string $withinPath = ''): string +{ + if (!empty($withinPath)) { + $withinPath = str_starts_with($withinPath, '/') ? $withinPath : '/' . $withinPath; + } + + return __DIR__ . '/_testdata/scripts' . $withinPath; +} + function helper_cleanUpDataPathQueueFiles(): void { - if (file_exists(__DIR__ . '/_testdata/datapath/index')) { - file_put_contents(__DIR__ . '/_testdata/datapath/index', 'a:0:{}'); + if (file_exists(helper_testDataPath('index'))) { + file_put_contents(helper_testDataPath('index'), 'a:0:{}'); } - if (file_exists(__DIR__ . '/_testdata/datapath/queue-default')) { - file_put_contents(__DIR__ . '/_testdata/datapath/queue-default', 'a:0:{}'); + if (file_exists(helper_testDataPath('queue-default'))) { + file_put_contents(helper_testDataPath('queue-default'), 'a:0:{}'); } - if (file_exists(__DIR__ . '/_testdata/datapath/queue-other_queue')) { - file_put_contents(__DIR__ . '/_testdata/datapath/queue-other_queue', 'a:0:{}'); + if (file_exists(helper_testDataPath('queue-other_queue'))) { + file_put_contents(helper_testDataPath('queue-other_queue'), 'a:0:{}'); } - if (file_exists(__DIR__ . '/_testdata/datapath/queue-infinite_waiting_jobs_queue')) { - file_put_contents(__DIR__ . '/_testdata/datapath/queue-infinite_waiting_jobs_queue', 'a:0:{}'); + if (file_exists(helper_testDataPath('queue-infinite_waiting_jobs_queue'))) { + file_put_contents(helper_testDataPath('queue-infinite_waiting_jobs_queue'), 'a:0:{}'); } // clean up logs - if (file_exists(__DIR__ . '/_testdata/datapath/logs')) { + if (file_exists(helper_testDataPath('logs'))) { $queues = ['default', 'other_queue', 'infinite_waiting_jobs_queue']; foreach ($queues as $queue) { - if (file_exists(__DIR__ . '/_testdata/datapath/logs/' . $queue)) { - $filesInDir = scandir(__DIR__ . '/_testdata/datapath/logs/' . $queue); + if (file_exists(helper_testDataPath('logs/' . $queue))) { + $filesInDir = scandir(helper_testDataPath('logs/' . $queue)); if (is_array($filesInDir)) { foreach ($filesInDir as $file) { if (str_ends_with($file, '.log')) { - unlink(__DIR__ . '/_testdata/datapath/logs/' . $queue . '/' . $file); + unlink(helper_testDataPath('logs/' . $queue . '/' . $file)); } } } - rmdir(__DIR__ . '/_testdata/datapath/logs/' . $queue); + rmdir(helper_testDataPath('logs/' . $queue)); } } - if (file_exists(__DIR__ . '/_testdata/datapath/logs')) { - rmdir(__DIR__ . '/_testdata/datapath/logs'); + if (file_exists(helper_testDataPath('logs'))) { + rmdir(helper_testDataPath('logs')); } } } diff --git a/tests/ProcessTest.php b/tests/ProcessTest.php index 84643fd..4985c4d 100644 --- a/tests/ProcessTest.php +++ b/tests/ProcessTest.php @@ -11,7 +11,7 @@ /** @var TestCase $this */ it('finishes a process that was successfully finished', function () { - Config::setPath(__DIR__ . '/_testdata/config/ppq.php'); + Config::setPath(helper_testConfigPath('ppq.php')); $queueRecord = new QueueRecord('default', TestJob::class); @@ -35,7 +35,7 @@ }); it('finishes a process that failed', function () { - Config::setPath(__DIR__ . '/_testdata/config/ppq.php'); + Config::setPath(helper_testConfigPath('ppq.php')); $queueRecord = new QueueRecord('default', TestJob::class, QueueJobStatus::running); diff --git a/tests/ProcessesTest.php b/tests/ProcessesTest.php index 4754a25..5ea6ad7 100644 --- a/tests/ProcessesTest.php +++ b/tests/ProcessesTest.php @@ -4,7 +4,7 @@ it('checks if a running process with a certain pid exists', function () { $process = \Symfony\Component\Process\Process::fromShellCommandline( - 'php ' . __DIR__ . '/_testdata/scripts/do-something.php' + 'php ' . helper_testScriptPath('do-something.php') ); $process->start(); @@ -26,7 +26,7 @@ expect(Processes::processContainingStringsExists(['counting.php']))->toBeFalse(); $process = \Symfony\Component\Process\Process::fromShellCommandline( - 'php ' . __DIR__ . '/_testdata/scripts/counting.php' + 'php ' . helper_testScriptPath('counting.php') ); $process->start(); @@ -36,7 +36,7 @@ test('checking if a running process containing certain strings exists, exclude the current process', function () { $process = \Symfony\Component\Process\Process::fromShellCommandline( - 'php ' . __DIR__ . '/_testdata/scripts/check-process-already-running.php' + 'php ' . helper_testScriptPath('check-process-already-running.php') ); $process->run(); diff --git a/tests/QueueTest.php b/tests/QueueTest.php index 3e1a6ae..8274b3e 100644 --- a/tests/QueueTest.php +++ b/tests/QueueTest.php @@ -10,7 +10,7 @@ use Stubs\TestJob; beforeEach(function () { - Config::setPath(__DIR__ . '/_testdata/config/filesystem-ppq.php'); + Config::setPath(helper_testConfigPath('filesystem-ppq.php')); helper_cleanUpDataPathQueueFiles(); }); diff --git a/tests/SignalTest.php b/tests/SignalTest.php index fff128c..2a16118 100644 --- a/tests/SignalTest.php +++ b/tests/SignalTest.php @@ -4,10 +4,10 @@ use Otsch\Ppq\Signal; beforeEach(function () { - Config::setPath(__DIR__ . '/_testdata/config/ppq.php'); + Config::setPath(helper_testConfigPath('ppq.php')); - if (file_exists(__DIR__ . '/_testdata/datapath/signal')) { - file_put_contents(__DIR__ . '/_testdata/datapath/signal', ''); + if (file_exists(helper_testDataPath('signal'))) { + file_put_contents(helper_testDataPath('signal'), ''); } }); diff --git a/tests/Stubs/Listeners/DefaultCancelled.php b/tests/Stubs/Listeners/DefaultCancelled.php index c3fee03..7f7da04 100644 --- a/tests/Stubs/Listeners/DefaultCancelled.php +++ b/tests/Stubs/Listeners/DefaultCancelled.php @@ -2,13 +2,12 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class DefaultCancelled implements QueueEventListener +class DefaultCancelled extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { - file_put_contents(__DIR__ . '/../../_testdata/datapath/event-listeners-check-file', 'default cancelled called'); + file_put_contents($this->dataPath('event-listeners-check-file'), 'default cancelled called'); } } diff --git a/tests/Stubs/Listeners/DefaultFailed.php b/tests/Stubs/Listeners/DefaultFailed.php index 0816272..d5d0b8b 100644 --- a/tests/Stubs/Listeners/DefaultFailed.php +++ b/tests/Stubs/Listeners/DefaultFailed.php @@ -2,13 +2,12 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class DefaultFailed implements QueueEventListener +class DefaultFailed extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { - file_put_contents(__DIR__ . '/../../_testdata/datapath/event-listeners-check-file', 'default failed called'); + file_put_contents($this->dataPath('event-listeners-check-file'), 'default failed called'); } } diff --git a/tests/Stubs/Listeners/DefaultFinished.php b/tests/Stubs/Listeners/DefaultFinished.php index 3482ef0..29b9813 100644 --- a/tests/Stubs/Listeners/DefaultFinished.php +++ b/tests/Stubs/Listeners/DefaultFinished.php @@ -2,13 +2,12 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class DefaultFinished implements QueueEventListener +class DefaultFinished extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { - file_put_contents(__DIR__ . '/../../_testdata/datapath/event-listeners-check-file', 'default finished called'); + file_put_contents($this->dataPath('event-listeners-check-file'), 'default finished called'); } } diff --git a/tests/Stubs/Listeners/DefaultLost.php b/tests/Stubs/Listeners/DefaultLost.php index 77e911e..72b66a6 100644 --- a/tests/Stubs/Listeners/DefaultLost.php +++ b/tests/Stubs/Listeners/DefaultLost.php @@ -2,13 +2,12 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class DefaultLost implements QueueEventListener +class DefaultLost extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { - file_put_contents(__DIR__ . '/../../_testdata/datapath/event-listeners-check-file', 'default lost called'); + file_put_contents($this->dataPath('event-listeners-check-file'), 'default lost called'); } } diff --git a/tests/Stubs/Listeners/DefaultRunning.php b/tests/Stubs/Listeners/DefaultRunning.php index 906498e..fe4df80 100644 --- a/tests/Stubs/Listeners/DefaultRunning.php +++ b/tests/Stubs/Listeners/DefaultRunning.php @@ -2,13 +2,12 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class DefaultRunning implements QueueEventListener +class DefaultRunning extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { - file_put_contents(__DIR__ . '/../../_testdata/datapath/event-listeners-check-file', 'default running called'); + file_put_contents($this->dataPath('event-listeners-check-file'), 'default running called'); } } diff --git a/tests/Stubs/Listeners/DefaultWaiting.php b/tests/Stubs/Listeners/DefaultWaiting.php index f5a7747..cc54c66 100644 --- a/tests/Stubs/Listeners/DefaultWaiting.php +++ b/tests/Stubs/Listeners/DefaultWaiting.php @@ -2,13 +2,12 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class DefaultWaiting implements QueueEventListener +class DefaultWaiting extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { - file_put_contents(__DIR__ . '/../../_testdata/datapath/event-listeners-check-file', 'default waiting called'); + file_put_contents($this->dataPath('event-listeners-check-file'), 'default waiting called'); } } diff --git a/tests/Stubs/Listeners/OtherQueueFailedOne.php b/tests/Stubs/Listeners/OtherQueueFailedOne.php index 9d5c833..e08f1d4 100644 --- a/tests/Stubs/Listeners/OtherQueueFailedOne.php +++ b/tests/Stubs/Listeners/OtherQueueFailedOne.php @@ -2,17 +2,12 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class OtherQueueFailedOne implements QueueEventListener +class OtherQueueFailedOne extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { - file_put_contents( - __DIR__ . '/../../_testdata/datapath/event-listeners-check-file', - 'other queue failed one called ', - FILE_APPEND, - ); + file_put_contents($this->dataPath('event-listeners-check-file'), 'other queue failed one called ', FILE_APPEND); } } diff --git a/tests/Stubs/Listeners/OtherQueueFailedThree.php b/tests/Stubs/Listeners/OtherQueueFailedThree.php index 29e3155..409b69e 100644 --- a/tests/Stubs/Listeners/OtherQueueFailedThree.php +++ b/tests/Stubs/Listeners/OtherQueueFailedThree.php @@ -2,15 +2,14 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class OtherQueueFailedThree implements QueueEventListener +class OtherQueueFailedThree extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { file_put_contents( - __DIR__ . '/../../_testdata/datapath/event-listeners-check-file', + $this->dataPath('event-listeners-check-file'), 'other queue failed three called', FILE_APPEND, ); diff --git a/tests/Stubs/Listeners/OtherQueueFailedTwo.php b/tests/Stubs/Listeners/OtherQueueFailedTwo.php index 064fb6e..6a5bbcb 100644 --- a/tests/Stubs/Listeners/OtherQueueFailedTwo.php +++ b/tests/Stubs/Listeners/OtherQueueFailedTwo.php @@ -2,15 +2,14 @@ namespace Stubs\Listeners; -use Otsch\Ppq\Contracts\QueueEventListener; use Otsch\Ppq\Entities\QueueRecord; -class OtherQueueFailedTwo implements QueueEventListener +class OtherQueueFailedTwo extends TestQueueEventListener { public function invoke(QueueRecord $queueRecord): void { file_put_contents( - __DIR__ . '/../../_testdata/datapath/event-listeners-check-file', + $this->dataPath('event-listeners-check-file'), 'other queue failed two called ', FILE_APPEND, ); diff --git a/tests/Stubs/Listeners/TestQueueEventListener.php b/tests/Stubs/Listeners/TestQueueEventListener.php new file mode 100644 index 0000000..2b49095 --- /dev/null +++ b/tests/Stubs/Listeners/TestQueueEventListener.php @@ -0,0 +1,17 @@ +