blob: 6f6886e860287712722c1ec22099f846071868cb [file] [log] [blame]
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF 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.
"""
import pytest
"""
Round trip testing of GraphSONV4 compared to a correct "model".
Set the IO_TEST_DIRECTORY environment variable to the directory where
the .gbin files that represent the serialized "model" are located.
"""
from gremlin_python.structure.io.graphsonV4 import GraphSONWriter, GraphSONReader
import math
import json
import os
from .model import model
gremlin_test_dir = "gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/structure/io/graphson/"
directory_search_pattern = "gremlin-python" + os.sep + "src" + os.sep + "main"
default_dir = __file__[:__file__.find(directory_search_pattern)]
test_resource_directory = os.environ.get('IO_TEST_DIRECTORY_GRAPHSON', default_dir + gremlin_test_dir)
writer = GraphSONWriter()
reader = GraphSONReader()
def get_entry(title):
return model[title]
def read_file_by_name(resource_name):
full_name = test_resource_directory + resource_name + "-" + "v4" + ".json"
with open(full_name, 'r') as resource_file:
return json.dumps(json.load(resource_file), separators=(',', ':'))
def test_pos_bigdecimal():
def decimal_cmp(x, y):
# python json library can only read a BigDecimal into float during deser, precision will be lost with GraphSON
# so compare float only
if float(x.value) == float(y.value):
return True
else:
return False
run_writeread("pos-bigdecimal", decimal_cmp)
def test_neg_bigdecimal():
def decimal_cmp(x, y):
if float(x.value) == float(y.value):
return True
else:
return False
run_writeread("neg-bigdecimal", decimal_cmp)
def test_pos_biginteger():
# gremlin-python adds an extra 0 byte to the value.
run_writeread("pos-biginteger")
def test_neg_biginteger():
# gremlin-python adds an extra 0 byte to the value.
run_writeread("neg-biginteger")
def test_min_byte():
run("min-byte")
def test_max_byte():
run("max-byte")
def test_empty_binary():
run("empty-binary")
def test_str_binary():
run("str-binary")
def test_max_double():
run("max-double")
def test_min_double():
run("min-double")
def test_neg_max_double():
run("neg-max-double")
def test_neg_min_double():
run("neg-min-double")
def test_nan_double():
def nan_cmp(x, y):
if math.isnan(x) and math.isnan(y):
return True
else:
return False
run("nan-double", nan_cmp)
def test_pos_inf_double():
run("pos-inf-double")
def test_neg_inf_double():
run("neg-inf-double")
def test_neg_zero_double():
run("neg-zero-double")
def test_zero_duration():
run("zero-duration")
def test_traversal_edge():
# properties aren't serialized in gremlin-python
run_writeread("traversal-edge")
def test_no_prop_edge():
# gremlin-python serializes/deserializes "null" for props not empty list
run_writeread("no-prop-edge")
def test_max_int():
run("max-int")
def test_min_int():
run("min-int")
def test_max_long():
# attempts to serialize a long as an int
run_writeread("max-long")
def test_min_long():
# attempts to serialize a long as an int
run_writeread("min-long")
def test_var_type_list():
run("var-type-list")
def test_empty_list():
run("empty-list")
def test_var_type_map():
# can't write tuple
run_read("var-type-map")
def test_empty_map():
run("empty-map")
# gremlin-python doesn't serialize path
def test_traversal_path():
run_read("traversal-path")
def test_empty_path():
run_read("empty-path")
def test_prop_path():
run_read("prop-path")
def test_edge_property():
run("edge-property")
def test_null_property():
run("null-property")
def test_var_type_set():
# ordering within set might be different
run_writeread("var-type-set")
def test_empty_set():
run("empty-set")
def test_max_short():
# short deserialized to int
run_writeread("max-short")
def test_min_short():
# short deserialized to int
run_writeread("min-short")
def test_specified_uuid():
run("specified-uuid")
def test_nil_uuid():
run("nil-uuid")
def test_no_prop_vertex():
# gremlin-python serializes/deserializes "null" for props not empty list
run_writeread("no-prop-vertex")
def test_traversal_vertexproperty():
# properties aren't serialized in gremlin-python
run_writeread("traversal-vertexproperty")
def test_meta_vertexproperty():
# properties aren't serialized in gremlin-python
run_writeread("meta-vertexproperty")
def test_set_cardinality_vertexproperty():
# properties aren't serialized in gremlin-python
run_writeread("set-cardinality-vertexproperty")
def test_id_t():
run("id-t")
def test_out_direction():
run("out-direction")
def test_var_bulklist():
run_read("var-bulklist")
def test_empty_bulklist():
run_read("empty-bulklist")
def test_single_byte_char():
# char is serialized as string
run_writeread("single-byte-char")
def test_multi_byte_char():
# char is serialized as string
run_writeread("multi-byte-char")
def test_unspecified_null():
# no serializer for plain null
run_writeread("unspecified-null")
def test_true_boolean():
run("true-boolean")
def test_false_boolean():
run("false-boolean")
def test_single_byte_string():
run("single-byte-string")
def test_mixed_string():
run("mixed-string")
def run(resource_name, comparator = None):
"""
Runs the regular set of tests for the type which is
1. model to deserialized object
2. written bytes to read bytes
3. round tripped (read then written) bytes to read bytes
Optionally takes in a comparator that used for comparison 1.
"""
resource_json = read_file_by_name(resource_name)
model = get_entry(resource_name)
read = reader.read_object(resource_json)
if comparator is not None:
assert comparator(model, read)
else:
assert model == read
written = writer.write_object(model)
assert resource_json == written
round_tripped = writer.write_object(reader.read_object(resource_json))
assert resource_json == round_tripped
def run_read(resource_name):
"""
Runs the read test which compares the model to deserialized object
This should only be used in cases where there is only a deserializer
but no serializer for the same type.
"""
resource_json = read_file_by_name(resource_name)
model = get_entry(resource_name)
read = reader.read_object(resource_json)
assert model == read
def run_writeread(resource_name, comparator = None):
"""
Runs a reduced set of tests for the type which is
1. model to deserialized object
2. model to round tripped (written then read) object
Optionally takes in a comparator that used for comparison 1.
Use this in cases where the regular run() function in too stringent.
E.g. when ordering doesn't matter like for sets. Ideally, a type
should be tested with run() instead when possible.
"""
resource_json = read_file_by_name(resource_name)
model = get_entry(resource_name)
read = reader.read_object(resource_json)
round_tripped = reader.read_object(writer.write_object(model))
if comparator is not None:
assert comparator(model, read)
assert comparator(model, round_tripped)
else:
assert model == read
assert model == round_tripped