Passed
Pull Request — master (#57)
by Matthew
07:36
created

PruneCommandTest   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 13
dl 0
loc 152
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Dtc\QueueBundle\Tests\Command;
4
5
use Doctrine\ODM\MongoDB\DocumentRepository;
6
use Dtc\QueueBundle\Command\PruneCommand;
7
use Dtc\QueueBundle\Document\Job;
8
use Dtc\QueueBundle\Util\Util;
9
use PHPUnit\Framework\TestCase;
10
use Dtc\QueueBundle\ODM\JobManager;
11
use Dtc\QueueBundle\EventDispatcher\EventDispatcher;
12
use Dtc\QueueBundle\Manager\WorkerManager;
13
use Dtc\QueueBundle\Tests\FibonacciWorker;
14
use Symfony\Component\DependencyInjection\Container;
15
16
class PruneCommandTest extends TestCase
17
{
18
    use CommandTrait;
19
20
    public function testPruneCommandExpired()
21
    {
22
        \Dtc\QueueBundle\Tests\ODM\JobManagerTest::setUpBeforeClass();
23
24
        /** @var JobManager $jobManager */
25
        $jobManager = \Dtc\QueueBundle\Tests\ODM\JobManagerTest::$jobManager;
26
        $eventDispatcher = new EventDispatcher();
27
        $workerManager = new WorkerManager($jobManager, $eventDispatcher);
28
        $worker = new FibonacciWorker();
29
        $workerManager->addWorker($worker);
30
        $worker->setJobManager($jobManager);
31
32
        $container = new Container();
33
        $container->set('dtc_queue.manager.job', $jobManager);
34
35
        /** @var Job $job */
36
        $time = time() - 1;
37
        $date = new \DateTime("@$time");
38
        $job = $worker->later()->setExpiresAt($date)->fibonacci(1);
39
        self::assertNotNull($job->getId(), 'Job id should be generated');
40
41
        /** @var JobManager $jobManager $ */
42
        /** @var DocumentRepository $repository */
43
        $repository = $jobManager->getRepository();
44
        $count = $repository->createQueryBuilder()->getQuery()->count(true);
45
        self::assertEquals(1, $count);
46
        $archiveRepository = $jobManager->getObjectManager()->getRepository($jobManager->getJobArchiveClass());
47
        $countArchive = $archiveRepository->createQueryBuilder()->getQuery()->count(true);
48
        self::assertEquals(0, $countArchive);
49
50
        $this->runCommand('\Dtc\QueueBundle\Command\PruneCommand', $container, ['type' => 'expired']);
51
52
        $count = $repository->createQueryBuilder()->getQuery()->count(true);
53
        self::assertEquals(0, $count);
54
55
        $countArchive = $archiveRepository->createQueryBuilder()->getQuery()->count(true);
56
        self::assertEquals(1, $countArchive);
57
    }
58
59
    public function testPruneCommandError()
60
    {
61
        $this->runPruneCommand(['type' => 'error'], 'pruneErroneousJobs');
62
    }
63
64
    public function testPruneCommandStalled()
65
    {
66
        $this->runPruneCommand(['type' => 'stalled'], 'pruneStalledJobs');
67
    }
68
69
    public function testPruneCommandStalledRuns()
70
    {
71
        $this->runPruneCommand(['type' => 'stalled_runs'], 'pruneStalledRuns');
72
    }
73
74
    protected function getPruneCommandOlderDateDiff($older, $type = 'old', $call = 'pruneArchivedJobs')
75
    {
76
        $startDate = new \DateTime();
77
        /** @var \DateTime $dateVal */
78
        $dateVal = $this->runPruneCommandOlder($older, 0, $type, $call);
79
        $endTime = time();
80
        $dateDiff = $startDate->diff($dateVal);
81
82
        return [$dateDiff, ($endTime - $startDate->getTimestamp()) + 1];
83
    }
84
85
    protected function getPruneCommandOlderDateDays($older, $type = 'old', $call = 'pruneArchivedJobs')
86
    {
87
        list($dateDiff) = $this->getPruneCommandOlderDateDiff($older, $type, $call);
88
89
        return $dateDiff->format('%a');
90
    }
91
92
    protected function getPruneCommandOlderDateSeconds($older, $type = 'old', $call = 'pruneArchivedJobs')
93
    {
94
        list($dateDiff, $varianceSeconds) = $this->getPruneCommandOlderDateDiff($older, $type, $call);
95
        $date1 = Util::getMicrotimeDateTime();
96
        $date2 = clone $date1;
97
        $date2->sub($dateDiff);
98
99
        return [$date2->getTimestamp() - $date1->getTimestamp(), $varianceSeconds];
100
    }
101
102
    public function testPruneOldRuns()
103
    {
104
        // Test invalid
105
        $this->runPruneOld();
106
        $this->runPruneOld('old_runs', 'pruneArchivedRuns');
107
        $this->runPruneOld('old_job_timings', 'pruneJobTimings');
108
    }
109
110
    public function runPruneOld($type = 'old', $call = 'pruneArchivedJobs')
111
    {
112
        // Test invalid
113
        $this->runPruneCommandOlder(null, 1, $type, $call);
114
        $this->runPruneCommandOlder('1x', 1, $type, $call);
115
        $this->runPruneCommandOlder('1dd', 1, $type, $call);
116
117
        // Test by day / month / year
118
        $result = $this->getPruneCommandOlderDateDays('1d', $type, $call);
119
        self::assertEquals(1, intval($result));
120
        $result = $this->getPruneCommandOlderDateDays('1m', $type, $call);
121
        self::assertGreaterThanOrEqual(28, intval($result));
122
        self::assertLessThanOrEqual(31, intval($result));
123
        $result = $this->getPruneCommandOlderDateDays('1y', $type, $call);
124
        self::assertGreaterThanOrEqual(364, intval($result));
125
        self::assertLessThanOrEqual(366, intval($result));
126
127
        // Test by time
128
        $this->runPruneCommandOlderSeconds('2h', 7200, $type, $call);
129
        $this->runPruneCommandOlderSeconds('1h', 3600, $type, $call);
130
        $this->runPruneCommandOlderSeconds('5i', 300, $type, $call);
131
        $this->runPruneCommandOlderSeconds('1i', 60, $type, $call);
132
        $this->runPruneCommandOlderSeconds('5s', 5, $type, $call);
133
        $this->runPruneCommandOlderSeconds('1s', 1, $type, $call);
134
135
        // Test timestamps
136
        $this->runPruneCommandOlderSeconds(time() - 1, 1, $type, $call);
137
        $this->runPruneCommandOlderSeconds(time() - 60, 60, $type, $call);
138
        $this->runPruneCommandOlderSeconds(time() - 86400, 86400, $type, $call);
139
    }
140
141
    protected function runPruneCommandOlderSeconds($older, $expected, $type = 'old', $call = 'pruneArchivedJobs')
142
    {
143
        list($result, $variance) = $this->getPruneCommandOlderDateSeconds($older, $type, $call);
144
        self::assertGreaterThanOrEqual($expected - $variance, intval($result));
145
        self::assertLessThanOrEqual($expected + $variance, intval($result));
146
    }
147
148
    protected function runPruneCommand($params, $call, $expectedResult = 0)
149
    {
150
        return $this->runStubCommand(PruneCommand::class, $params, $call, $expectedResult);
151
    }
152
153
    protected function runPruneCommandOlder($older, $expectedResult = 0, $type = 'old', $call = 'pruneArchivedJobs')
154
    {
155
        $params = ['type' => $type];
156
        if (null !== $older) {
157
            $params['--older'] = $older;
158
        }
159
        $manager = $this->runPruneCommand($params, $call, $expectedResult);
160
        if (0 === $expectedResult) {
161
            self::assertTrue(isset($manager->calls[$call][0][0]));
162
            self::assertTrue(!isset($manager->calls[$call][0][1]));
163
164
            return $manager->calls[$call][0][0];
165
        }
166
    }
167
}
168