Files
opensearch-pyd/test_elasticsearch/test_server/test_helpers.py
T

630 lines
22 KiB
Python
Raw Normal View History

2019-04-05 18:31:43 +03:00
from mock import patch
2015-01-05 20:39:39 +01:00
from elasticsearch import helpers, TransportError
2019-04-05 18:31:43 +03:00
from elasticsearch.helpers import ScanError
from . import ElasticsearchTestCase
2015-10-11 04:50:31 +02:00
from ..test_cases import SkipTest
2015-01-05 20:39:39 +01:00
class FailingBulkClient(object):
2019-03-29 09:25:23 -06:00
def __init__(
self, client, fail_at=(2,), fail_with=TransportError(599, "Error!", {})
):
2015-01-05 20:39:39 +01:00
self.client = client
2017-07-22 13:40:22 -04:00
self._called = 0
2015-01-05 20:39:39 +01:00
self._fail_at = fail_at
2015-09-30 19:25:17 +02:00
self.transport = client.transport
2017-07-22 13:40:22 -04:00
self._fail_with = fail_with
2015-01-05 20:39:39 +01:00
def bulk(self, *args, **kwargs):
self._called += 1
2017-07-22 13:40:22 -04:00
if self._called in self._fail_at:
raise self._fail_with
2019-03-29 09:25:23 -06:00
return self.client.bulk(*args, **kwargs)
2015-01-05 20:39:39 +01:00
class TestStreamingBulk(ElasticsearchTestCase):
def test_actions_remain_unchanged(self):
2019-03-29 09:25:23 -06:00
actions = [{"_id": 1}, {"_id": 2}]
for ok, item in helpers.streaming_bulk(
self.client, actions, index="test-index"
):
self.assertTrue(ok)
2019-03-29 09:25:23 -06:00
self.assertEquals([{"_id": 1}, {"_id": 2}], actions)
def test_all_documents_get_inserted(self):
2019-03-29 09:25:23 -06:00
docs = [{"answer": x, "_id": x} for x in range(100)]
for ok, item in helpers.streaming_bulk(
self.client, docs, index="test-index", refresh=True
):
2013-11-22 14:29:08 +01:00
self.assertTrue(ok)
2019-03-29 09:25:23 -06:00
self.assertEquals(100, self.client.count(index="test-index")["count"])
self.assertEquals(
{"answer": 42}, self.client.get(index="test-index", id=42)["_source"]
)
2013-11-22 14:29:08 +01:00
def test_all_errors_from_chunk_are_raised_on_failure(self):
2019-03-29 09:25:23 -06:00
self.client.indices.create(
"i",
2013-11-22 14:29:08 +01:00
{
2019-03-29 09:25:23 -06:00
"mappings": {"properties": {"a": {"type": "integer"}}},
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
},
)
2013-11-22 14:29:08 +01:00
self.client.cluster.health(wait_for_status="yellow")
try:
2019-03-29 09:25:23 -06:00
for ok, item in helpers.streaming_bulk(
self.client, [{"a": "b"}, {"a": "c"}], index="i", raise_on_error=True
):
2013-11-22 14:29:08 +01:00
self.assertTrue(ok)
except helpers.BulkIndexError as e:
self.assertEquals(2, len(e.errors))
else:
assert False, "exception should have been raised"
def test_different_op_types(self):
if self.es_version < (0, 90, 1):
2019-03-29 09:25:23 -06:00
raise SkipTest("update supported since 0.90.1")
self.client.index(index="i", id=45, body={})
self.client.index(index="i", id=42, body={})
2013-11-22 14:29:08 +01:00
docs = [
2019-03-29 09:25:23 -06:00
{"_index": "i", "_type": "_doc", "_id": 47, "f": "v"},
{"_op_type": "delete", "_index": "i", "_type": "_doc", "_id": 45},
{
"_op_type": "update",
"_index": "i",
"_type": "_doc",
"_id": 42,
"doc": {"answer": 42},
},
2013-11-22 14:29:08 +01:00
]
for ok, item in helpers.streaming_bulk(self.client, docs):
self.assertTrue(ok)
2019-03-29 09:25:23 -06:00
self.assertFalse(self.client.exists(index="i", id=45))
self.assertEquals({"answer": 42}, self.client.get(index="i", id=42)["_source"])
self.assertEquals({"f": "v"}, self.client.get(index="i", id=47)["_source"])
2013-11-22 14:29:08 +01:00
2015-01-05 20:39:39 +01:00
def test_transport_error_can_becaught(self):
failing_client = FailingBulkClient(self.client)
docs = [
2019-03-29 09:25:23 -06:00
{"_index": "i", "_type": "_doc", "_id": 47, "f": "v"},
{"_index": "i", "_type": "_doc", "_id": 45, "f": "v"},
{"_index": "i", "_type": "_doc", "_id": 42, "f": "v"},
2015-01-05 20:39:39 +01:00
]
2019-03-29 09:25:23 -06:00
results = list(
helpers.streaming_bulk(
failing_client,
docs,
raise_on_exception=False,
raise_on_error=False,
chunk_size=1,
)
)
2015-01-05 20:39:39 +01:00
self.assertEquals(3, len(results))
self.assertEquals([True, False, True], [r[0] for r in results])
2019-03-29 09:25:23 -06:00
exc = results[1][1]["index"].pop("exception")
2015-01-05 20:39:39 +01:00
self.assertIsInstance(exc, TransportError)
self.assertEquals(599, exc.status_code)
self.assertEquals(
{
2019-03-29 09:25:23 -06:00
"index": {
"_index": "i",
"_type": "_doc",
"_id": 45,
"data": {"f": "v"},
"error": "TransportError(599, 'Error!')",
"status": 599,
2015-01-05 20:39:39 +01:00
}
},
2019-03-29 09:25:23 -06:00
results[1][1],
2015-01-05 20:39:39 +01:00
)
2017-07-22 13:40:22 -04:00
def test_rejected_documents_are_retried(self):
2019-03-29 09:25:23 -06:00
failing_client = FailingBulkClient(
self.client, fail_with=TransportError(429, "Rejected!", {})
)
2017-07-22 13:40:22 -04:00
docs = [
2019-03-29 09:25:23 -06:00
{"_index": "i", "_type": "_doc", "_id": 47, "f": "v"},
{"_index": "i", "_type": "_doc", "_id": 45, "f": "v"},
{"_index": "i", "_type": "_doc", "_id": 42, "f": "v"},
2017-07-22 13:40:22 -04:00
]
2019-03-29 09:25:23 -06:00
results = list(
helpers.streaming_bulk(
failing_client,
docs,
raise_on_exception=False,
raise_on_error=False,
chunk_size=1,
max_retries=1,
initial_backoff=0,
)
)
2017-07-22 13:40:22 -04:00
self.assertEquals(3, len(results))
self.assertEquals([True, True, True], [r[0] for r in results])
2019-03-29 09:25:23 -06:00
self.client.indices.refresh(index="i")
res = self.client.search(index="i")
self.assertEquals({"value": 3, "relation": "eq"}, res["hits"]["total"])
2017-07-22 13:40:22 -04:00
self.assertEquals(4, failing_client._called)
def test_rejected_documents_are_retried_at_most_max_retries_times(self):
2019-03-29 09:25:23 -06:00
failing_client = FailingBulkClient(
self.client, fail_at=(1, 2), fail_with=TransportError(429, "Rejected!", {})
)
2017-07-22 13:40:22 -04:00
docs = [
2019-03-29 09:25:23 -06:00
{"_index": "i", "_type": "_doc", "_id": 47, "f": "v"},
{"_index": "i", "_type": "_doc", "_id": 45, "f": "v"},
{"_index": "i", "_type": "_doc", "_id": 42, "f": "v"},
2017-07-22 13:40:22 -04:00
]
2019-03-29 09:25:23 -06:00
results = list(
helpers.streaming_bulk(
failing_client,
docs,
raise_on_exception=False,
raise_on_error=False,
chunk_size=1,
max_retries=1,
initial_backoff=0,
)
)
2017-07-22 13:40:22 -04:00
self.assertEquals(3, len(results))
self.assertEquals([False, True, True], [r[0] for r in results])
2019-03-29 09:25:23 -06:00
self.client.indices.refresh(index="i")
res = self.client.search(index="i")
self.assertEquals({"value": 2, "relation": "eq"}, res["hits"]["total"])
2017-07-22 13:40:22 -04:00
self.assertEquals(4, failing_client._called)
def test_transport_error_is_raised_with_max_retries(self):
2019-03-29 09:25:23 -06:00
failing_client = FailingBulkClient(
self.client,
fail_at=(1, 2, 3, 4),
fail_with=TransportError(429, "Rejected!", {}),
)
def streaming_bulk():
2019-03-29 09:25:23 -06:00
results = list(
helpers.streaming_bulk(
failing_client,
[{"a": 42}, {"a": 39}],
raise_on_exception=True,
max_retries=3,
initial_backoff=0,
)
)
return results
self.assertRaises(TransportError, streaming_bulk)
self.assertEquals(4, failing_client._called)
2013-11-22 14:29:08 +01:00
class TestBulk(ElasticsearchTestCase):
def test_bulk_works_with_single_item(self):
2019-03-29 09:25:23 -06:00
docs = [{"answer": 42, "_id": 1}]
success, failed = helpers.bulk(
self.client, docs, index="test-index", refresh=True
)
self.assertEquals(1, success)
self.assertFalse(failed)
2019-03-29 09:25:23 -06:00
self.assertEquals(1, self.client.count(index="test-index")["count"])
self.assertEquals(
{"answer": 42}, self.client.get(index="test-index", id=1)["_source"]
)
2013-11-22 14:29:08 +01:00
def test_all_documents_get_inserted(self):
2019-03-29 09:25:23 -06:00
docs = [{"answer": x, "_id": x} for x in range(100)]
success, failed = helpers.bulk(
self.client, docs, index="test-index", refresh=True
)
self.assertEquals(100, success)
self.assertFalse(failed)
2019-03-29 09:25:23 -06:00
self.assertEquals(100, self.client.count(index="test-index")["count"])
self.assertEquals(
{"answer": 42}, self.client.get(index="test-index", id=42)["_source"]
)
def test_stats_only_reports_numbers(self):
docs = [{"answer": x} for x in range(100)]
2019-03-29 09:25:23 -06:00
success, failed = helpers.bulk(
self.client, docs, index="test-index", refresh=True, stats_only=True
)
self.assertEquals(100, success)
self.assertEquals(0, failed)
2019-03-29 09:25:23 -06:00
self.assertEquals(100, self.client.count(index="test-index")["count"])
def test_errors_are_reported_correctly(self):
2019-03-29 09:25:23 -06:00
self.client.indices.create(
"i",
{
2019-03-29 09:25:23 -06:00
"mappings": {"properties": {"a": {"type": "integer"}}},
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
},
)
self.client.cluster.health(wait_for_status="yellow")
2013-11-22 14:29:08 +01:00
success, failed = helpers.bulk(
self.client,
2019-03-29 09:25:23 -06:00
[{"a": 42}, {"a": "c", "_id": 42}],
index="i",
2019-03-29 09:25:23 -06:00
raise_on_error=False,
)
self.assertEquals(1, success)
self.assertEquals(1, len(failed))
error = failed[0]
2019-03-29 09:25:23 -06:00
self.assertEquals("42", error["index"]["_id"])
self.assertEquals("_doc", error["index"]["_type"])
self.assertEquals("i", error["index"]["_index"])
print(error["index"]["error"])
self.assertTrue(
"MapperParsingException" in repr(error["index"]["error"])
or "mapper_parsing_exception" in repr(error["index"]["error"])
)
2015-02-18 18:28:08 +01:00
def test_error_is_raised(self):
2019-03-29 09:25:23 -06:00
self.client.indices.create(
"i",
{
2019-03-29 09:25:23 -06:00
"mappings": {"properties": {"a": {"type": "integer"}}},
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
},
)
self.client.cluster.health(wait_for_status="yellow")
2019-03-29 09:25:23 -06:00
self.assertRaises(
helpers.BulkIndexError,
helpers.bulk,
self.client,
[{"a": 42}, {"a": "c"}],
index="i",
)
def test_errors_are_collected_properly(self):
2019-03-29 09:25:23 -06:00
self.client.indices.create(
"i",
{
2019-03-29 09:25:23 -06:00
"mappings": {"properties": {"a": {"type": "integer"}}},
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
},
)
self.client.cluster.health(wait_for_status="yellow")
2013-11-22 14:29:08 +01:00
success, failed = helpers.bulk(
self.client,
[{"a": 42}, {"a": "c"}],
index="i",
2015-02-18 18:28:08 +01:00
stats_only=True,
2019-03-29 09:25:23 -06:00
raise_on_error=False,
)
self.assertEquals(1, success)
self.assertEquals(1, failed)
class TestScan(ElasticsearchTestCase):
2019-04-05 18:31:43 +03:00
mock_scroll_responses = [
{
2019-05-10 09:16:33 -06:00
"_scroll_id": "dummy_id",
"_shards": {"successful": 4, "total": 5},
"hits": {"hits": [{"scroll_data": 42}]},
2019-04-05 18:31:43 +03:00
},
{
2019-05-10 09:16:33 -06:00
"_scroll_id": "dummy_id",
"_shards": {"successful": 4, "total": 5},
"hits": {"hits": []},
2019-04-05 18:31:43 +03:00
},
]
@classmethod
def tearDownClass(cls):
2019-05-10 09:16:33 -06:00
cls.client.transport.perform_request("DELETE", "/_search/scroll/_all")
2019-04-05 18:31:43 +03:00
super(TestScan, cls).tearDownClass()
def test_order_can_be_preserved(self):
bulk = []
for x in range(100):
2019-03-29 09:25:23 -06:00
bulk.append({"index": {"_index": "test_index", "_type": "_doc", "_id": x}})
bulk.append({"answer": x, "correct": x == 42})
self.client.bulk(bulk, refresh=True)
2019-03-29 09:25:23 -06:00
docs = list(
helpers.scan(
self.client,
index="test_index",
query={"sort": "answer"},
preserve_order=True,
)
)
self.assertEquals(100, len(docs))
2019-03-29 09:25:23 -06:00
self.assertEquals(list(map(str, range(100))), list(d["_id"] for d in docs))
self.assertEquals(list(range(100)), list(d["_source"]["answer"] for d in docs))
def test_all_documents_are_read(self):
bulk = []
for x in range(100):
2019-03-29 09:25:23 -06:00
bulk.append({"index": {"_index": "test_index", "_type": "_doc", "_id": x}})
bulk.append({"answer": x, "correct": x == 42})
self.client.bulk(bulk, refresh=True)
2019-03-29 09:25:23 -06:00
docs = list(helpers.scan(self.client, index="test_index", size=2))
self.assertEquals(100, len(docs))
2019-03-29 09:25:23 -06:00
self.assertEquals(set(map(str, range(100))), set(d["_id"] for d in docs))
self.assertEquals(set(range(100)), set(d["_source"]["answer"] for d in docs))
2019-04-05 18:31:43 +03:00
def test_scroll_error(self):
bulk = []
for x in range(4):
bulk.append({"index": {"_index": "test_index", "_type": "_doc"}})
bulk.append({"value": x})
self.client.bulk(bulk, refresh=True)
2019-05-10 09:16:33 -06:00
with patch.object(self.client, "scroll") as scroll_mock:
2019-04-05 18:31:43 +03:00
scroll_mock.side_effect = self.mock_scroll_responses
2019-05-10 09:16:33 -06:00
data = list(
helpers.scan(
self.client,
index="test_index",
size=2,
raise_on_error=False,
clear_scroll=False,
)
)
2019-04-05 18:31:43 +03:00
self.assertEqual(len(data), 3)
2019-05-10 09:16:33 -06:00
self.assertEqual(data[-1], {"scroll_data": 42})
2019-04-05 18:31:43 +03:00
scroll_mock.side_effect = self.mock_scroll_responses
with self.assertRaises(ScanError):
2019-05-10 09:16:33 -06:00
data = list(
helpers.scan(
self.client,
index="test_index",
size=2,
raise_on_error=True,
clear_scroll=False,
)
)
2019-04-05 18:31:43 +03:00
self.assertEqual(len(data), 3)
2019-05-10 09:16:33 -06:00
self.assertEqual(data[-1], {"scroll_data": 42})
2019-04-05 18:31:43 +03:00
def test_initial_search_error(self):
2019-05-10 09:16:33 -06:00
with patch.object(self, "client") as client_mock:
2019-04-05 18:31:43 +03:00
client_mock.search.return_value = {
2019-05-10 09:16:33 -06:00
"_scroll_id": "dummy_id",
"_shards": {"successful": 4, "total": 5},
"hits": {"hits": [{"search_data": 1}]},
2019-04-05 18:31:43 +03:00
}
client_mock.scroll.side_effect = self.mock_scroll_responses
2019-05-10 09:16:33 -06:00
data = list(
helpers.scan(
self.client, index="test_index", size=2, raise_on_error=False
)
)
self.assertEqual(data, [{"search_data": 1}, {"scroll_data": 42}])
2019-04-05 18:31:43 +03:00
client_mock.scroll.side_effect = self.mock_scroll_responses
with self.assertRaises(ScanError):
data = list(
2019-05-10 09:16:33 -06:00
helpers.scan(
self.client, index="test_index", size=2, raise_on_error=True
)
2019-04-05 18:31:43 +03:00
)
2019-05-10 09:16:33 -06:00
self.assertEqual(data, [{"search_data": 1}])
2019-04-05 18:31:43 +03:00
client_mock.scroll.assert_not_called()
def test_no_scroll_id_fast_route(self):
2019-05-10 09:16:33 -06:00
with patch.object(self, "client") as client_mock:
client_mock.search.return_value = {"no": "_scroll_id"}
data = list(helpers.scan(self.client, index="test_index"))
2019-04-05 18:31:43 +03:00
self.assertEqual(data, [])
client_mock.scroll.assert_not_called()
client_mock.clear_scroll.assert_not_called()
2019-05-10 09:16:33 -06:00
@patch("elasticsearch.helpers.actions.logger")
2019-04-05 18:31:43 +03:00
def test_logger(self, logger_mock):
bulk = []
for x in range(4):
2019-05-10 09:16:33 -06:00
bulk.append({"index": {"_index": "test_index", "_type": "_doc"}})
bulk.append({"value": x})
2019-04-05 18:31:43 +03:00
self.client.bulk(bulk, refresh=True)
2019-05-10 09:16:33 -06:00
with patch.object(self.client, "scroll") as scroll_mock:
2019-04-05 18:31:43 +03:00
scroll_mock.side_effect = self.mock_scroll_responses
2019-05-10 09:16:33 -06:00
list(
helpers.scan(
self.client,
index="test_index",
size=2,
raise_on_error=False,
clear_scroll=False,
)
)
2019-04-05 18:31:43 +03:00
logger_mock.warning.assert_called()
scroll_mock.side_effect = self.mock_scroll_responses
try:
2019-05-10 09:16:33 -06:00
list(
helpers.scan(
self.client,
index="test_index",
size=2,
raise_on_error=True,
clear_scroll=False,
)
)
2019-04-05 18:31:43 +03:00
except ScanError:
pass
logger_mock.warning.assert_called()
def test_clear_scroll(self):
bulk = []
for x in range(4):
2019-05-10 09:16:33 -06:00
bulk.append({"index": {"_index": "test_index", "_type": "_doc"}})
bulk.append({"value": x})
2019-04-05 18:31:43 +03:00
self.client.bulk(bulk, refresh=True)
2019-05-10 09:16:33 -06:00
with patch.object(
self.client, "clear_scroll", wraps=self.client.clear_scroll
) as spy:
list(helpers.scan(self.client, index="test_index", size=2))
2019-04-05 18:31:43 +03:00
spy.assert_called_once()
spy.reset_mock()
2019-05-10 09:16:33 -06:00
list(
helpers.scan(self.client, index="test_index", size=2, clear_scroll=True)
)
2019-04-05 18:31:43 +03:00
spy.assert_called_once()
spy.reset_mock()
2019-05-10 09:16:33 -06:00
list(
helpers.scan(
self.client, index="test_index", size=2, clear_scroll=False
)
)
2019-04-05 18:31:43 +03:00
spy.assert_not_called()
2013-08-01 15:05:29 +02:00
class TestReindex(ElasticsearchTestCase):
2015-01-03 01:54:34 +01:00
def setUp(self):
super(TestReindex, self).setUp()
2013-08-01 15:05:29 +02:00
bulk = []
for x in range(100):
2019-03-29 09:25:23 -06:00
bulk.append({"index": {"_index": "test_index", "_type": "_doc", "_id": x}})
bulk.append(
{
"answer": x,
"correct": x == 42,
"type": "answers" if x % 2 == 0 else "questions",
}
)
2013-08-01 15:05:29 +02:00
self.client.bulk(bulk, refresh=True)
def test_reindex_passes_kwargs_to_scan_and_bulk(self):
2019-03-29 09:25:23 -06:00
helpers.reindex(
self.client,
"test_index",
"prod_index",
scan_kwargs={"q": "type:answers"},
bulk_kwargs={"refresh": True},
)
self.assertTrue(self.client.indices.exists("prod_index"))
2019-03-29 09:25:23 -06:00
self.assertEquals(
50, self.client.count(index="prod_index", q="type:answers")["count"]
)
2019-03-29 09:25:23 -06:00
self.assertEquals(
{"answer": 42, "correct": True, "type": "answers"},
self.client.get(index="prod_index", id=42)["_source"],
)
2015-01-03 01:54:34 +01:00
def test_reindex_accepts_a_query(self):
2019-03-29 09:25:23 -06:00
helpers.reindex(
self.client,
"test_index",
"prod_index",
query={"query": {"bool": {"filter": {"term": {"type": "answers"}}}}},
)
2015-01-03 01:54:34 +01:00
self.client.indices.refresh()
self.assertTrue(self.client.indices.exists("prod_index"))
2019-03-29 09:25:23 -06:00
self.assertEquals(
50, self.client.count(index="prod_index", q="type:answers")["count"]
)
2015-01-03 01:54:34 +01:00
2019-03-29 09:25:23 -06:00
self.assertEquals(
{"answer": 42, "correct": True, "type": "answers"},
self.client.get(index="prod_index", id=42)["_source"],
)
2015-01-03 01:54:34 +01:00
def test_all_documents_get_moved(self):
2013-08-01 15:05:29 +02:00
helpers.reindex(self.client, "test_index", "prod_index")
self.client.indices.refresh()
self.assertTrue(self.client.indices.exists("prod_index"))
2019-03-29 09:25:23 -06:00
self.assertEquals(
50, self.client.count(index="prod_index", q="type:questions")["count"]
)
self.assertEquals(
50, self.client.count(index="prod_index", q="type:answers")["count"]
)
self.assertEquals(
{"answer": 42, "correct": True, "type": "answers"},
self.client.get(index="prod_index", id=42)["_source"],
)
2013-08-01 15:05:29 +02:00
class TestParentChildReindex(ElasticsearchTestCase):
def setUp(self):
super(TestParentChildReindex, self).setUp()
2019-03-29 09:25:23 -06:00
body = {
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
"mappings": {
"properties": {
"question_answer": {
"type": "join",
"relations": {"question": "answer"},
2017-08-01 15:54:59 -04:00
}
}
2019-03-29 09:25:23 -06:00
},
}
2019-03-29 09:25:23 -06:00
self.client.indices.create(index="test-index", body=body)
self.client.indices.create(index="real-index", body=body)
self.client.index(
2019-03-29 09:25:23 -06:00
index="test-index", id=42, body={"question_answer": "question"}
)
self.client.index(
2019-03-29 09:25:23 -06:00
index="test-index",
id=47,
2017-08-01 15:54:59 -04:00
routing=42,
2019-03-29 09:25:23 -06:00
body={"some": "data", "question_answer": {"name": "answer", "parent": 42}},
)
2019-03-29 09:25:23 -06:00
self.client.indices.refresh(index="test-index")
def test_children_are_reindexed_correctly(self):
2019-03-29 09:25:23 -06:00
helpers.reindex(self.client, "test-index", "real-index")
2019-03-29 09:25:23 -06:00
q = self.client.get(index="real-index", id=42)
self.assertEquals(
{
2019-03-29 09:25:23 -06:00
"_id": "42",
"_index": "real-index",
"_primary_term": 1,
"_seq_no": 0,
"_source": {"question_answer": "question"},
"_type": "_doc",
"_version": 1,
"found": True,
},
q,
2015-08-25 01:09:54 +02:00
)
2019-03-29 09:25:23 -06:00
q = self.client.get(index="test-index", id=47, routing=42)
self.assertEquals(
{
2019-03-29 09:25:23 -06:00
"_routing": "42",
"_id": "47",
"_index": "test-index",
"_primary_term": 1,
"_seq_no": 1,
"_source": {
"some": "data",
"question_answer": {"name": "answer", "parent": 42},
},
"_type": "_doc",
"_version": 1,
"found": True,
},
q,
)