Completed
Push — master ( 09a07f...8de6a8 )
by Simonas
01:54
created

AbstractElasticsearchTestCase::runTest()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
c 0
b 0
f 0
rs 8.7624
cc 6
eloc 12
nc 6
nop 0
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\ElasticsearchBundle\Test;
13
14
use Elasticsearch\Common\Exceptions\ElasticsearchException;
15
use ONGR\ElasticsearchBundle\Service\Manager;
16
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
19
/**
20
 * Base test which creates unique connection to test with.
21
 */
22
abstract class AbstractElasticsearchTestCase extends WebTestCase
23
{
24
    /**
25
     * @var Manager[] Holds used managers.
26
     */
27
    private $managers = [];
28
29
    /**
30
     * @var ContainerInterface
31
     */
32
    private $container;
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    protected function setUp()
38
    {
39
        foreach ($this->getDataArray() as $manager => $data) {
40
            // Create index and populate data
41
            $this->getManager($manager);
42
        }
43
    }
44
45
    /**
46
     * Can be overwritten in child class to populate elasticsearch index with the data.
47
     *
48
     * Example:
49
     *      "manager_name" =>
50
     *      [
51
     *          'type_name' => [
52
     *              [
53
     *                  '_id' => 1,
54
     *                  'title' => 'foo',
55
     *              ],
56
     *              [
57
     *                  '_id' => 2,
58
     *                  'title' => 'bar',
59
     *              ]
60
     *          ]
61
     *      ]
62
     *
63
     * @return array
64
     */
65
    protected function getDataArray()
66
    {
67
        return [];
68
    }
69
70
    /**
71
     * Ignores versions specified.
72
     *
73
     * Returns two dimensional array, first item in sub array is version to ignore, second is comparator,
74
     * last test name. If no test name is provided it will be used on all test class.
75
     *
76
     * Comparator types can be found in `version_compare` documentation.
77
     *
78
     * Example: [
79
     *   ['1.2.7', '<='],
80
     *   ['1.2.9', '==', 'testSmth']
81
     * ]
82
     *
83
     * @return array
84
     */
85
    protected function getIgnoredVersions()
86
    {
87
        return [];
88
    }
89
90
    /**
91
     * Ignores version specified.
92
     *
93
     * @param Manager $manager
94
     */
95
    private function ignoreVersions(Manager $manager)
96
    {
97
        $currentVersion = $manager->getVersionNumber();
98
        $ignore = null;
99
100
        foreach ($this->getIgnoredVersions() as $ignoredVersion) {
101
            if (version_compare($currentVersion, $ignoredVersion[0], $ignoredVersion[1]) === true) {
102
                $ignore = true;
103
                if (isset($ignoredVersion[2])) {
104
                    if ($ignoredVersion[2] === $this->getName()) {
105
                        break;
106
                    }
107
                    $ignore = false;
108
                }
109
            }
110
        }
111
112
        if ($ignore === true) {
113
            $this->markTestSkipped("Elasticsearch version {$currentVersion} not supported by this test.");
114
        }
115
    }
116
117
    /**
118
     * Removes manager from local cache and drops its index.
119
     *
120
     * @param string $name
121
     */
122
    protected function removeManager($name)
123
    {
124
        if (isset($this->managers[$name])) {
125
            $this->managers[$name]->dropIndex();
126
            unset($this->managers[$name]);
127
        }
128
    }
129
130
    /**
131
     * Populates elasticsearch with data.
132
     *
133
     * @param Manager $manager
134
     * @param array   $data
135
     */
136
    private function populateElasticsearchWithData($manager, array $data)
137
    {
138
        if (!empty($data)) {
139
            foreach ($data as $type => $documents) {
140
                foreach ($documents as $document) {
141
                    $manager->bulk('index', $type, $document);
142
                }
143
            }
144
            $manager->commit();
145
            $manager->refresh();
146
        }
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    protected function tearDown()
153
    {
154
        parent::tearDown();
155
156
        foreach ($this->managers as $name => $manager) {
157
            try {
158
                $manager->dropIndex();
159
            } catch (\Exception $e) {
160
                // Do nothing.
161
            }
162
        }
163
    }
164
165
    /**
166
     * Returns service container.
167
     *
168
     * @param bool  $reinitialize  Force kernel reinitialization.
169
     * @param array $kernelOptions Options used passed to kernel if it needs to be initialized.
170
     *
171
     * @return ContainerInterface
172
     */
173
    protected function getContainer($reinitialize = false, $kernelOptions = [])
174
    {
175
        if ($this->container === null || $reinitialize) {
176
            static::bootKernel($kernelOptions);
177
            $this->container = static::$kernel->getContainer();
178
        }
179
180
        return $this->container;
181
    }
182
183
    /**
184
     * Returns manager instance with injected connection if does not exist creates new one.
185
     *
186
     * @param string $name Manager name
187
     *
188
     * @return Manager
189
     *
190
     * @throws \LogicException
191
     */
192
    protected function getManager($name = 'default')
193
    {
194
        $serviceName = sprintf('es.manager.%s', $name);
195
196
        // Looks for cached manager.
197
        if (array_key_exists($name, $this->managers)) {
198
            $this->ignoreVersions($this->managers[$name]);
199
200
            return $this->managers[$name];
201
        } elseif ($this->getContainer()->has($serviceName)) {
202
            /** @var Manager $manager */
203
            $manager = $this->getContainer()->get($serviceName);
204
            $this->managers[$name] = $manager;
205
        } else {
206
            throw new \LogicException(sprintf("Manager '%s' does not exist", $name));
207
        }
208
209
        $this->ignoreVersions($manager);
210
        $manager->dropAndCreateIndex();
211
212
        // Populates elasticsearch index with data
213
        $data = $this->getDataArray();
214
        if (!empty($data[$name])) {
215
            $this->populateElasticsearchWithData($manager, $data[$name]);
216
        }
217
218
        return $manager;
219
    }
220
}
221