Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds JSON/CBOR support and an Io-type option #243

Merged
merged 6 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'
312 changes: 151 additions & 161 deletions amazon/ionbenchmark/ion_benchmark_cli.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the --api option, the allowed values should be changed to something like load_dump and streaming. The option simple_ion is no longer accurate for the other formats, and looks weird in the options list when those formats are selected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions install.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ def _download_ionc():

os.chdir(_CURRENT_ION_C_DIR)

# TODO Use ion-c 1.1.0 for now - https://github.com/amazon-ion/ion-python/issues/249
check_call(['git', 'reset', '--hard', 'v1.1.0'])

# Initialize submodule.
check_call(['git', 'submodule', 'update', '--init'])

Expand Down
2 changes: 1 addition & 1 deletion ion-c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this introduces test failures that haven't yet been resolved, let's leave the ion-c submodule update for a separate PR, and revert it here.

1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ simplejson~=3.18.3
pip~=23.0
six~=1.16.0
cbor~=1.0.0
orjson~=3.8.6
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
168 changes: 138 additions & 30 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, Format, Io_type
from amazon.ionbenchmark.ion_benchmark_cli import generate_simpleion_read_test_code, \
generate_simpleion_write_test_code, ion_python_benchmark_cli
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 @@ -45,12 +48,45 @@ def generate_test_path(p):
generate_test_path('integers.ion')
)
def test_generate_simpleion_read_test_code(path):
actual = generate_simpleion_read_test_code(path, memory_profiling=False, single_value=False,
emit_bare_values=False, io_type='buffer')
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=False)

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

# make sure the return values are same
assert actual() == expect
Expand All @@ -62,7 +98,8 @@ def test_generate_simpleion_read_test_code(path):
))
)
def test_generate_simpleion_write_test_code(obj):
actual = generate_simpleion_write_test_code(obj, memory_profiling=False, binary=False, io_type='buffer')
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 @@ -71,6 +108,38 @@ def test_generate_simpleion_write_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 @@ -135,88 +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', 'file'), ('simple_ion', 'ion_binary', 'file')])
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', 'file'), ('simple_ion', 'ion_binary', 'file')])
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', 'file'), ('simple_ion', 'ion_binary', 'file')])
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', 'file'), ('simple_ion', 'ion_binary', 'file')])
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', 'file'), ('simple_ion', 'ion_text', 'file')])
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', 'file'), ('simple_ion', 'ion_binary', 'file')])
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', 'file'), ('simple_ion', 'ion_binary', 'file')])
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', 'file'), ('simple_ion', 'ion_binary', 'file')])
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('integers.ion'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('simple_ion', f'{f}', 'file')])
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('integers.ion'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('simple_ion', f'{f}', 'file')])
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)))
*tuple((f.value for f in Format.Format if Format.format_is_cbor(f.value)))
)
def test_write_json_format(f):
def test_write_cbor_format(f):
table = execution_with_command(['write', generate_test_path('integers.ion'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('simple_ion', f'{f}', 'file')])
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('integers.ion'), '--format', f'{f}'])
assert gather_all_options_in_list(table) == sorted([('simple_ion', f'{f}', 'file')])
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([('simple_ion', 'json', f'{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([('simple_ion', 'json', f'{f}'), ('simple_ion', 'ion_binary', f'{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