Files
opensearch-pyd/test_elasticsearch/test_serializer.py
T

195 lines
6.5 KiB
Python
Raw Normal View History

2013-12-04 15:07:56 +01:00
# -*- coding: utf-8 -*-
# Licensed to Elasticsearch B.V. under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
2020-04-23 11:22:08 -05:00
2013-10-22 00:26:58 +02:00
import sys
2015-12-09 23:15:59 -08:00
import uuid
2013-05-02 23:42:11 +02:00
from datetime import datetime
2013-10-22 00:26:58 +02:00
from decimal import Decimal
2013-05-02 23:42:11 +02:00
import numpy as np
import pandas as pd
from elasticsearch.exceptions import ImproperlyConfigured, SerializationError
2019-05-10 09:16:33 -06:00
from elasticsearch.serializer import (
DEFAULT_SERIALIZERS,
Deserializer,
JSONSerializer,
2019-05-10 09:16:33 -06:00
TextSerializer,
)
2013-05-02 23:42:11 +02:00
from .test_cases import SkipTest, TestCase
2013-08-28 19:11:28 +02:00
2019-05-10 09:16:33 -06:00
2013-05-02 23:42:11 +02:00
class TestJSONSerializer(TestCase):
def test_datetime_serialization(self):
2020-05-08 16:07:52 -05:00
self.assertEqual(
2019-05-10 09:16:33 -06:00
'{"d":"2010-10-01T02:30:00"}',
JSONSerializer().dumps({"d": datetime(2010, 10, 1, 2, 30)}),
)
2013-05-03 17:56:27 +02:00
2013-10-22 00:26:58 +02:00
def test_decimal_serialization(self):
if sys.version_info[:2] == (2, 6):
raise SkipTest("Float rounding is broken in 2.6.")
2020-05-08 16:07:52 -05:00
self.assertEqual('{"d":3.8}', JSONSerializer().dumps({"d": Decimal("3.8")}))
2013-10-22 00:26:58 +02:00
2015-12-09 23:15:59 -08:00
def test_uuid_serialization(self):
2020-05-08 16:07:52 -05:00
self.assertEqual(
2019-05-10 09:16:33 -06:00
'{"d":"00000000-0000-0000-0000-000000000003"}',
JSONSerializer().dumps(
{"d": uuid.UUID("00000000-0000-0000-0000-000000000003")}
),
)
2015-12-09 23:15:59 -08:00
def test_serializes_numpy_bool(self):
2020-05-08 16:07:52 -05:00
self.assertEqual('{"d":true}', JSONSerializer().dumps({"d": np.bool_(True)}))
def test_serializes_numpy_integers(self):
ser = JSONSerializer()
for np_type in (
np.int_,
np.int8,
np.int16,
np.int32,
np.int64,
):
2020-05-08 16:07:52 -05:00
self.assertEqual(ser.dumps({"d": np_type(-1)}), '{"d":-1}')
for np_type in (
np.uint8,
np.uint16,
np.uint32,
np.uint64,
):
2020-05-08 16:07:52 -05:00
self.assertEqual(ser.dumps({"d": np_type(1)}), '{"d":1}')
def test_serializes_numpy_floats(self):
ser = JSONSerializer()
for np_type in (
np.float_,
np.float32,
np.float64,
):
self.assertRegexpMatches(
ser.dumps({"d": np_type(1.2)}), r'^\{"d":1\.2[\d]*}$'
)
def test_serializes_numpy_datetime(self):
2020-05-08 16:07:52 -05:00
self.assertEqual(
'{"d":"2010-10-01T02:30:00"}',
JSONSerializer().dumps({"d": np.datetime64("2010-10-01T02:30:00")}),
)
def test_serializes_numpy_ndarray(self):
2020-05-08 16:07:52 -05:00
self.assertEqual(
'{"d":[0,0,0,0,0]}',
JSONSerializer().dumps({"d": np.zeros((5,), dtype=np.uint8)}),
)
# This isn't useful for Elasticsearch, just want to make sure it works.
2020-05-08 16:07:52 -05:00
self.assertEqual(
'{"d":[[0,0],[0,0]]}',
JSONSerializer().dumps({"d": np.zeros((2, 2), dtype=np.uint8)}),
)
2020-06-29 10:10:05 -05:00
def test_serializes_numpy_nan_to_nan(self):
self.assertEqual(
2020-08-27 10:28:14 -05:00
'{"d":NaN}',
JSONSerializer().dumps({"d": np.nan}),
2020-06-29 10:10:05 -05:00
)
def test_serializes_pandas_timestamp(self):
2020-05-08 16:07:52 -05:00
self.assertEqual(
'{"d":"2010-10-01T02:30:00"}',
JSONSerializer().dumps({"d": pd.Timestamp("2010-10-01T02:30:00")}),
)
def test_serializes_pandas_series(self):
2020-05-08 16:07:52 -05:00
self.assertEqual(
'{"d":["a","b","c","d"]}',
JSONSerializer().dumps({"d": pd.Series(["a", "b", "c", "d"])}),
)
def test_serializes_pandas_na(self):
if not hasattr(pd, "NA"): # pandas.NA added in v1
raise SkipTest("pandas.NA required")
2020-05-08 16:07:52 -05:00
self.assertEqual(
2020-08-27 10:28:14 -05:00
'{"d":null}',
JSONSerializer().dumps({"d": pd.NA}),
)
2020-06-29 10:10:05 -05:00
def test_raises_serialization_error_pandas_nat(self):
if not hasattr(pd, "NaT"):
raise SkipTest("pandas.NaT required")
self.assertRaises(SerializationError, JSONSerializer().dumps, {"d": pd.NaT})
def test_serializes_pandas_category(self):
cat = pd.Categorical(["a", "c", "b", "a"], categories=["a", "b", "c"])
2020-05-08 16:07:52 -05:00
self.assertEqual(
2020-08-27 10:28:14 -05:00
'{"d":["a","c","b","a"]}',
JSONSerializer().dumps({"d": cat}),
)
cat = pd.Categorical([1, 2, 3], categories=[1, 2, 3])
2020-05-08 16:07:52 -05:00
self.assertEqual(
2020-08-27 10:28:14 -05:00
'{"d":[1,2,3]}',
JSONSerializer().dumps({"d": cat}),
)
2013-05-03 17:56:27 +02:00
def test_raises_serialization_error_on_dump_error(self):
self.assertRaises(SerializationError, JSONSerializer().dumps, object())
def test_raises_serialization_error_on_load_error(self):
self.assertRaises(SerializationError, JSONSerializer().loads, object())
2019-05-10 09:16:33 -06:00
self.assertRaises(SerializationError, JSONSerializer().loads, "")
self.assertRaises(SerializationError, JSONSerializer().loads, "{{")
2013-06-20 14:07:09 +02:00
def test_strings_are_left_untouched(self):
2020-05-08 16:07:52 -05:00
self.assertEqual("你好", JSONSerializer().dumps("你好"))
class TestTextSerializer(TestCase):
def test_strings_are_left_untouched(self):
2020-05-08 16:07:52 -05:00
self.assertEqual("你好", TextSerializer().dumps("你好"))
def test_raises_serialization_error_on_dump_error(self):
self.assertRaises(SerializationError, TextSerializer().dumps, {})
class TestDeserializer(TestCase):
2020-05-14 16:09:24 -05:00
def setup_method(self, _):
self.de = Deserializer(DEFAULT_SERIALIZERS)
def test_deserializes_json_by_default(self):
2020-05-08 16:07:52 -05:00
self.assertEqual({"some": "data"}, self.de.loads('{"some":"data"}'))
def test_deserializes_text_with_correct_ct(self):
2020-05-08 16:07:52 -05:00
self.assertEqual(
2019-05-10 09:16:33 -06:00
'{"some":"data"}', self.de.loads('{"some":"data"}', "text/plain")
)
2020-05-08 16:07:52 -05:00
self.assertEqual(
2019-05-10 09:16:33 -06:00
'{"some":"data"}',
self.de.loads('{"some":"data"}', "text/plain; charset=whatever"),
)
def test_raises_serialization_error_on_unknown_mimetype(self):
2019-05-10 09:16:33 -06:00
self.assertRaises(SerializationError, self.de.loads, "{}", "text/html")
2019-05-10 09:16:33 -06:00
def test_raises_improperly_configured_when_default_mimetype_cannot_be_deserialized(
2020-03-09 11:51:35 -05:00
self,
2019-05-10 09:16:33 -06:00
):
self.assertRaises(ImproperlyConfigured, Deserializer, {})