我正在尝试模拟用于托管CI单元测试目的的elasticsearch数据。
我准备了一些我可以使用bulk()
成功加载的灯具,但是,由于未知原因,我无法匹配任何,即使test_index
似乎包含数据(因为我可以通过他们的ID get()
项目。)
fixtures.json
是我从实际生产索引中获取的ES文档的子集。使用真实世界索引,一切都按预期工作,所有测试都通过。
奇怪行为的一个人为例子如下:
class MyTestCase(TestCase):
es = Elasticsearch()
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.es.indices.create('test_index', SOME_SCHEMA)
with open('fixtures.json') as fixtures:
bulk(cls.es, json.load(fixtures))
@classmethod
def tearDownClass(cls):
super().tearDownClass()
cls.es.indices.delete('test_index')
def test_something(self):
# check all documents are there:
with open('fixtures.json') as fixtures:
for f in json.load(fixtures):
print(self.es.get(index='test_index', id=f['_id']))
# yes they are!
# BUT:
match_all = {"query": {"match_all": {}}}
print('hits:', self.es.search(index='test_index', body=match_all)['hits']['hits'])
# prints `hits: []` like there was nothing in
print('count:', self.es.count(index='test_index', body=match_all)['count'])
# prints `count: 0`
答案 0 :(得分:1)
虽然我可以完全理解你的痛苦(除了测试之外一切都有效),答案其实很简单:与你的实验相比,测试太快了。
所以修复将time.sleep()
给ES一些空间来创建它所需的所有魔法来给你带来结果。我会这样做:
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.es.indices.create('test_index', SOME_SCHEMA)
with open('fixtures.json') as fixtures:
bulk(cls.es, json.load(fixtures))
cls.wait_until_index_ready()
@classmethod
def wait_until_index_ready(cls, timeout=10):
for sec in range(timeout):
time.sleep(1)
if cls.es.cluster.health().get('status') in ('green', 'yellow'):
break
答案 1 :(得分:1)
虽然@ jsmesami的答案非常正确,但这样做可能更为清晰。如果您注意到,问题是因为ES没有重新编入索引。实际上,为此目的,API实际上有一些功能。 尝试类似的事情,
cls.es.indices.flush(wait_if_ongoing=True)
cls.es.indices.refresh(index='*')
更具体地说,您可以将index='test_index'
传递给这两个函数。我认为这比使用sleep(..)
更清晰,更具体。