Skip to content

Commit

Permalink
Adds JSON/CBOR comparison and an Io-type option (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
cheqianh committed Mar 30, 2023
1 parent 614a93f commit b08b9a7
Show file tree
Hide file tree
Showing 9 changed files with 618 additions and 175 deletions.
6 changes: 3 additions & 3 deletions amazon/ionbenchmark/API.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
# Serialization/deserialization APIs to benchmark.
class API(Enum):
"""Enumeration of the APIs."""
SIMPLE_ION = 'simple_ion'
EVENT = 'event'
DEFAULT = 'simple_ion'
LOAD_DUMP = 'load_dump'
STREAMING = 'streaming'
DEFAULT = 'load_dump'
7 changes: 7 additions & 0 deletions amazon/ionbenchmark/Command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from enum import Enum


class Command(Enum):
"""Enumeration of the Command."""
READ = 'read'
WRITE = 'write'
28 changes: 28 additions & 0 deletions amazon/ionbenchmark/Format.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
from enum import Enum


def format_is_ion(format_option):
return (format_option == Format.ION_BINARY.value) or (format_option == Format.ION_TEXT.value)


def format_is_json(format_option):
return (format_option == Format.JSON.value) or (format_option == Format.SIMPLEJSON.value) \
or (format_option == Format.UJSON.value) or (format_option == Format.RAPIDJSON.value)


def format_is_cbor(format_option):
return (format_option == Format.CBOR.value) or (format_option == Format.CBOR2.value)


def format_is_binary(format_option):
return format_is_cbor(format_option) or (format_option == Format.ION_BINARY.value)


def rewrite_file_to_format(file, format_option):
return file


class Format(Enum):
"""Enumeration of the formats."""
ION_TEXT = 'ion_text'
ION_BINARY = 'ion_binary'
JSON = 'json'
SIMPLEJSON = 'simplejson'
UJSON = 'ujson'
RAPIDJSON = 'rapidjson'
CBOR = 'cbor'
CBOR2 = 'cbor2'
DEFAULT = 'ion_binary'

8 changes: 8 additions & 0 deletions amazon/ionbenchmark/Io_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from enum import Enum


class Io_type(Enum):
"""Enumeration of the IO types."""
FILE = 'file'
BUFFER = 'buffer'
DEFAULT = 'file'
532 changes: 383 additions & 149 deletions amazon/ionbenchmark/ion_benchmark_cli.py

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ tox==3.23.1
virtualenv==20.4.7
setuptools<=60.5.0
docopt==0.6.2
tabulate==0.9.0
tabulate==0.9.0
simplejson~=3.18.3
pip~=23.0
six~=1.16.0
cbor~=1.0.0
cbor2~=5.4.6
python-rapidjson~=1.9
ujson~=5.7.0
1 change: 1 addition & 0 deletions tests/benchmark_sample_data/cbor/sample
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sthis is a test file
1 change: 1 addition & 0 deletions tests/benchmark_sample_data/json/object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"John", "age":30, "car":null}
201 changes: 179 additions & 22 deletions tests/test_benchmark_cli.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import json
import time
from itertools import chain
from os.path import abspath, join, dirname

import cbor2
from docopt import docopt

from amazon.ion import simpleion
from amazon.ionbenchmark import ion_benchmark_cli
from amazon.ionbenchmark.ion_benchmark_cli import generate_simpleion_load_test_code, generate_simpleion_dump_test_code,\
ion_python_benchmark_cli
from amazon.ionbenchmark import ion_benchmark_cli, Format, Io_type
from amazon.ionbenchmark.Format import format_is_ion, format_is_cbor, format_is_json
from amazon.ionbenchmark.ion_benchmark_cli import generate_read_test_code, \
generate_write_test_code, ion_python_benchmark_cli
from amazon.ionbenchmark.util import str_to_bool, TOOL_VERSION
from tests import parametrize
from tests.test_simpleion import generate_scalars_text
Expand Down Expand Up @@ -44,12 +47,46 @@ def generate_test_path(p):
@parametrize(
generate_test_path('integers.ion')
)
def test_generate_simpleion_load_test_code(path):
actual = generate_simpleion_load_test_code(path, memory_profiling=False, single_value=False, emit_bare_values=False)
def test_generate_simpleion_read_test_code(path):
actual = generate_read_test_code(path, memory_profiling=False, single_value=False,
format_option=Format.Format.ION_TEXT.value, emit_bare_values=False,
io_type=Io_type.Io_type.FILE, binary=False)

# make sure we generated the desired load function
with open(path) as fp:
expect = simpleion.load(fp, single_value=False, parse_eagerly=True)
expect = simpleion.load(fp, single_value=False, emit_bare_values=False, parse_eagerly=True)

# make sure the return values are same
assert actual() == expect


@parametrize(
generate_test_path('integers.ion')
)
def test_generate_json_read_test_code(path):
actual = generate_read_test_code(path, memory_profiling=False, single_value=False,
format_option=Format.Format.JSON.value, emit_bare_values=False,
io_type=Io_type.Io_type.FILE, binary=False)

# make sure we generated the desired load function
with open(path) as fp:
expect = json.load(fp)

# make sure the return values are same
assert actual() == expect


@parametrize(
generate_test_path('integers.ion')
)
def test_generate_cbor_read_test_code(path):
actual = generate_read_test_code(path, memory_profiling=False, single_value=False,
format_option=Format.Format.CBOR2.value, emit_bare_values=False,
io_type=Io_type.Io_type.FILE, binary=True)

# make sure we generated the desired load function
with open(path, 'br') as fp:
expect = cbor2.load(fp)

# make sure the return values are same
assert actual() == expect
Expand All @@ -60,8 +97,9 @@ def test_generate_simpleion_load_test_code(path):
generate_scalars_text(SIMPLE_SCALARS_MAP_TEXT),
))
)
def test_generate_simpleion_dump_test_code(obj):
actual = generate_simpleion_dump_test_code(obj, memory_profiling=False, binary=False)
def test_generate_simpleion_write_test_code(obj):
actual = generate_write_test_code(obj, format_option=Format.Format.ION_TEXT.value, memory_profiling=False,
binary=False, io_type=Io_type.Io_type.BUFFER.value)

# make sure we generated the desired dumps function
expect = simpleion.dumps(obj, binary=False)
Expand All @@ -70,6 +108,38 @@ def test_generate_simpleion_dump_test_code(obj):
assert actual() == expect


@parametrize(
generate_test_path('json/object.json'),
)
def test_generate_json_write_test_code(file):
with open(file) as fp:
obj = json.load(fp)
actual = generate_write_test_code(obj, format_option=Format.Format.JSON.value, memory_profiling=False, binary=False,
io_type=Io_type.Io_type.BUFFER.value)

# make sure we generated the desired dumps function
expect = json.dumps(obj)

# make sure the return values are same
assert actual() == expect


@parametrize(
generate_test_path('cbor/sample')
)
def test_generate_cbor_write_test_code(file):
with open(file, 'br') as fp:
obj = cbor2.load(fp)
actual = generate_write_test_code(obj, format_option=Format.Format.CBOR2.value, memory_profiling=False,
binary=False, io_type=Io_type.Io_type.BUFFER.value)

# make sure we generated the desired dumps function
expect = cbor2.dumps(obj)

# make sure the return values are same
assert actual() == expect


def execution_with_command(c):
return ion_python_benchmark_cli(docopt(doc, argv=c))

Expand Down Expand Up @@ -134,40 +204,127 @@ def gather_all_options_in_list(table):


def test_read_multi_api(file=generate_test_path('integers.ion')):
table = execution_with_command(['read', file, '--api', 'simple_ion', '--api', 'event'])
assert gather_all_options_in_list(table) == sorted([('event', 'ion_binary'), ('simple_ion', 'ion_binary')])
table = execution_with_command(['read', file, '--api', 'load_dump', '--api', 'streaming'])
assert gather_all_options_in_list(table) == sorted(
[('streaming', 'ion_binary', 'file'), ('load_dump', 'ion_binary', 'file')])


def test_write_multi_api(file=generate_test_path('integers.ion')):
table = execution_with_command(['write', file, '--api', 'simple_ion', '--api', 'event'])
assert gather_all_options_in_list(table) == sorted([('event', 'ion_binary'), ('simple_ion', 'ion_binary')])
table = execution_with_command(['write', file, '--api', 'load_dump', '--api', 'streaming'])
assert gather_all_options_in_list(table) == sorted(
[('streaming', 'ion_binary', 'file'), ('load_dump', 'ion_binary', 'file')])


def test_read_multi_duplicated_api(file=generate_test_path('integers.ion')):
table = execution_with_command(['read', file, '--api', 'simple_ion', '--api', 'event', '--api', 'event'])
assert gather_all_options_in_list(table) == sorted([('event', 'ion_binary'), ('simple_ion', 'ion_binary')])
table = execution_with_command(['read', file, '--api', 'load_dump', '--api', 'streaming', '--api', 'streaming'])
assert gather_all_options_in_list(table) == sorted(
[('streaming', 'ion_binary', 'file'), ('load_dump', 'ion_binary', 'file')])


def test_write_multi_duplicated_api(file=generate_test_path('integers.ion')):
table = execution_with_command(['write', file, '--api', 'simple_ion', '--api', 'event', '--api', 'event'])
assert gather_all_options_in_list(table) == sorted([('event', 'ion_binary'), ('simple_ion', 'ion_binary')])
table = execution_with_command(['write', file, '--api', 'load_dump', '--api', 'streaming', '--api', 'streaming'])
assert gather_all_options_in_list(table) == sorted(
[('streaming', 'ion_binary', 'file'), ('load_dump', 'ion_binary', 'file')])


def test_read_multi_format(file=generate_test_path('integers.ion')):
table = execution_with_command(['read', file, '--format', 'ion_text', '--format', 'ion_binary'])
assert gather_all_options_in_list(table) == sorted([('simple_ion', 'ion_binary'), ('simple_ion', 'ion_text')])
assert gather_all_options_in_list(table) == sorted(
[('load_dump', 'ion_binary', 'file'), ('load_dump', 'ion_text', 'file')])


def test_write_multi_format(file=generate_test_path('integers.ion')):
table = execution_with_command(['write', file, '--format', 'ion_text', '--format', 'ion_binary'])
assert gather_all_options_in_list(table) == sorted([('simple_ion', 'ion_text'), ('simple_ion', 'ion_binary')])
assert gather_all_options_in_list(table) == sorted(
[('load_dump', 'ion_text', 'file'), ('load_dump', 'ion_binary', 'file')])


def test_read_multi_duplicated_format(file=generate_test_path('integers.ion')):
table = execution_with_command(['read', file, '--format', 'ion_text', '--format', 'ion_binary', '--format', 'ion_text'])
assert gather_all_options_in_list(table) == sorted([('simple_ion', 'ion_text'), ('simple_ion', 'ion_binary')])
table = execution_with_command(
['read', file, '--format', 'ion_text', '--format', 'ion_binary', '--format', 'ion_text'])
assert gather_all_options_in_list(table) == sorted(
[('load_dump', 'ion_text', 'file'), ('load_dump', 'ion_binary', 'file')])


def test_write_multi_duplicated_format(file=generate_test_path('integers.ion')):
table = execution_with_command(['write', file, '--format', 'ion_text', '--format', 'ion_binary', '--format', 'ion_text',])
assert gather_all_options_in_list(table) == sorted([('simple_ion', 'ion_text'), ('simple_ion', 'ion_binary')])
table = execution_with_command(
['write', file, '--format', 'ion_text', '--format', 'ion_binary', '--format', 'ion_text', ])
assert gather_all_options_in_list(table) == sorted(
[('load_dump', 'ion_text', 'file'), ('load_dump', 'ion_binary', 'file')])


@parametrize(
*tuple((f.value for f in Format.Format if Format.format_is_json(f.value)))
)
def test_write_json_format(f):
table = execution_with_command(['write', generate_test_path('json/object.json'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('load_dump', f'{f}', 'file')])


@parametrize(
*tuple((f.value for f in Format.Format if Format.format_is_json(f.value)))
)
def test_read_json_format(f):
table = execution_with_command(['read', generate_test_path('json/object.json'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('load_dump', f'{f}', 'file')])


@parametrize(
*tuple((f.value for f in Format.Format if Format.format_is_cbor(f.value)))
)
def test_write_cbor_format(f):
table = execution_with_command(['write', generate_test_path('cbor/sample'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('load_dump', f'{f}', 'file')])


@parametrize(
*tuple((f.value for f in Format.Format if Format.format_is_cbor(f.value)))
)
def test_read_cbor_format(f):
table = execution_with_command(['read', generate_test_path('cbor/sample'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('load_dump', f'{f}', 'file')])


@parametrize(
*tuple((io.value for io in Io_type.Io_type))
)
def test_write_io_type(f):
table = execution_with_command(
['write', generate_test_path('integers.ion'), '--io-type', f'{f}', '--format', 'json'])
assert gather_all_options_in_list(table) == sorted([('load_dump', 'json', f'{f}')])


@parametrize(
*tuple((io.value for io in Io_type.Io_type))
)
def test_read_io_type(f):
table = execution_with_command(
['read', generate_test_path('integers.ion'), '--io-type', f'{f}', '--format', 'json', '--format', 'ion_binary'])
assert gather_all_options_in_list(table) == sorted(
[('load_dump', 'json', f'{f}'), ('load_dump', 'ion_binary', f'{f}')])


@parametrize(
*tuple((Format.Format.ION_TEXT, Format.Format.ION_BINARY))
)
def test_format_is_ion(f):
assert format_is_ion(f.value) is True


@parametrize(
*tuple((Format.Format.JSON,
Format.Format.UJSON,
Format.Format.RAPIDJSON,
Format.Format.SIMPLEJSON
))
)
def test_format_is_json(f):
assert format_is_json(f.value) is True


@parametrize(
Format.Format.CBOR,
Format.Format.CBOR2
)
def test_format_is_cbor(f):
assert format_is_cbor(f.value) is True

0 comments on commit b08b9a7

Please sign in to comment.