def test_blocking_writer(p): buf = BytesIO() writer = blocking_writer(p.coroutine, buf) for i in range(p.input): result_type = writer.send(None) assert isinstance(result_type, WriteEventType) and result_type is not WriteEventType.HAS_PENDING assert p.expected == buf.getvalue()
def write_with_shared_symbol_table_events(): structs = get_csv_structs() table = shared_symbol_table(u'test.csv.columns', 1, (u'id', u'type', u'state')) data = BytesIO() writer = blocking_writer(binary_writer(imports=(table, )), data) for struct in structs: writer.send(IonEvent(IonEventType.CONTAINER_START, IonType.STRUCT)) writer.send( IonEvent(IonEventType.SCALAR, IonType.INT, field_name=u'id', value=struct[u'id'])) writer.send( IonEvent(IonEventType.SCALAR, IonType.STRING, field_name=u'type', value=struct[u'type'])) writer.send( IonEvent(IonEventType.SCALAR, IonType.BOOL, field_name=u'state', value=struct[u'state'])) writer.send(IonEvent(IonEventType.CONTAINER_END)) writer.send(ION_STREAM_END_EVENT) return data.getvalue()
def _run_test(writer_provider, events, algorithm): # capture behavior of an ion-python writer expected_bytes = BytesIO() w = blocking_writer(writer_provider(), expected_bytes) expected_write_event_types = _write_to(w, events) hw_bytes = BytesIO() hw = hash_writer(blocking_writer(writer_provider(), hw_bytes), hash_function_provider(algorithm)) hw_write_event_types = _write_to(hw, events) # assert writer/hash_writer response behavior is identical assert hw_write_event_types == expected_write_event_types # assert writer/hash_writer produced the same output assert hw_bytes.getvalue() == expected_bytes.getvalue()
def test_convert_csv_events(): # http://amzn.github.io/ion-docs/guides/cookbook.html#converting-non-hierarchical-data-to-ion structs = get_csv_structs() ion = BytesIO() writer = blocking_writer(binary_writer(), ion) for struct in structs: writer.send(IonEvent(IonEventType.CONTAINER_START, IonType.STRUCT)) writer.send( IonEvent(IonEventType.SCALAR, IonType.INT, field_name=u'id', value=struct[u'id'])) writer.send( IonEvent(IonEventType.SCALAR, IonType.STRING, field_name=u'type', value=struct[u'type'])) writer.send( IonEvent(IonEventType.SCALAR, IonType.BOOL, field_name=u'state', value=struct[u'state'])) writer.send(IonEvent(IonEventType.CONTAINER_END)) writer.send(ION_STREAM_END_EVENT) assert b'\xe0\x01\x00\xea\xee\x95\x81\x83\xde\x91\x87\xbe\x8e\x82id\x84type\x85state\xde\x8a\x8a!' \ b'\x01\x8b\x83foo\x8c\x10\xde\x8a\x8a!\x02\x8b\x83bar\x8c\x11\xde\x8a\x8a!\x03\x8b\x83baz\x8c\x11' \ == ion.getvalue()
def test_blocking_writer(p): buf = BytesIO() writer = blocking_writer(p.coroutine, buf) for i in range(p.input): result_type = writer.send(None) assert isinstance( result_type, WriteEventType) and result_type is not WriteEventType.HAS_PENDING assert p.expected == buf.getvalue()
def test_write_numeric_with_annotation_events(): # http://amzn.github.io/ion-docs/guides/cookbook.html#reading-numeric-types event = IonEvent(IonEventType.SCALAR, IonType.FLOAT, annotations=(u'abc', ), value=123.0) data = BytesIO() writer = blocking_writer(text_writer(), data) writer.send(event) writer.send(ION_STREAM_END_EVENT) assert u'abc::123.0e0' == data.getvalue().decode(u'utf-8')
def _f(algorithm): buf.seek(0) reader = ion_reader.blocking_reader( managed_reader(reader_provider(), None), buf) writer = hash_writer( blocking_writer(raw_writer(), BytesIO()), hash_function_provider(algorithm, _actual_updates, _actual_digests)) _consume(reader, writer) digest = writer.send(HashEvent.DIGEST) writer.send(IonEvent(IonEventType.STREAM_END)) return digest
def test_no_fieldname_in_hash(test_data): """ This test verifies a hash_reader/writer that receives field events but did not receive the preceeding "begin struct" event DOES NOT include the field_name as part of the hash. """ reader = binary_reader_over(test_data.ion_str) events = consume(reader) buf = BytesIO() writer = blocking_writer(raw_writer(), buf) writer.send(IonEvent(IonEventType.CONTAINER_START, IonType.STRUCT)) hw = hash_writer(writer, hash_function_provider("identity")) for e in events[:-1]: field_name = e.field_name if e.depth == 0: field_name = SymbolToken("field_name", None) new_event = IonEvent(e.event_type, e.ion_type, e.value, field_name, e.annotations, e.depth + 1) hw.send(new_event) writer.send(IonEvent(IonEventType.CONTAINER_END, IonType.STRUCT)) writer.send(events[-1]) # send the final event (which should be a STREAM_END event) output = buf.getvalue() hw_digest = hw.send(HashEvent.DIGEST) assert hw_digest == test_data.expected_digest reader = binary_reader_over(output) hr_digest = b'' while True: event = reader.send(NEXT_EVENT) if event.event_type == IonEventType.CONTAINER_START: hr = hash_reader(reader, hash_function_provider("identity")) for i in range(0, len(events) - 1): e = hr.send(NEXT_EVENT) hr_digest = hr.send(HashEvent.DIGEST) if event.event_type == IonEventType.STREAM_END: break assert hr_digest == test_data.expected_digest
def test_writing_events_blocking(): # http://amzn.github.io/ion-docs/guides/cookbook.html#reading-and-writing-ion-data data = BytesIO() writer = blocking_writer(binary_writer(), data) event_type = writer.send( IonEvent(IonEventType.CONTAINER_START, IonType.STRUCT)) # The value is not complete, so more events are required. assert event_type == WriteEventType.NEEDS_INPUT event_type = writer.send( IonEvent(IonEventType.SCALAR, IonType.STRING, field_name=u'hello', value=u'world')) # The value is not complete, so more events are required. assert event_type == WriteEventType.NEEDS_INPUT event_type = writer.send(IonEvent(IonEventType.CONTAINER_END)) # The value is not complete, so more events are required. assert event_type == WriteEventType.NEEDS_INPUT event_type = writer.send(ION_STREAM_END_EVENT) # The end of the stream was signaled, so the data has been flushed. assert event_type == WriteEventType.COMPLETE assert b'\xe0\x01\x00\xea\xec\x81\x83\xde\x88\x87\xb6\x85hello\xde\x87\x8a\x85world' == data.getvalue( )
def ion_hash(self, algorithm=None, hash_function_provider=None): """Given an algorithm or hash_function_provider, computes the Ion hash of this value. Args: algorithm: A string corresponding to the name of a hash algorithm supported by the `hashlib` module. hash_function_provider: A function that returns a new ``IonHasher`` instance when called. Note that multiple ``IonHasher`` instances may be required to hash a single value (depending on the type of the Ion value). Returns: `bytes` that represent the Ion hash of this value for the specified algorithm or hash_function_provider. """ if algorithm is None and hash_function_provider is None: raise Exception( "Either 'algorithm' or 'hash_function_provider' must be specified") if algorithm is not None and hash_function_provider is not None: raise Exception( "Either 'algorithm' or 'hash_function_provider' must be specified, not both" ) if algorithm is not None: hfp = hashlib_hash_function_provider(algorithm) else: hfp = hash_function_provider hw = hash_writer(blocking_writer(binary_writer(), BytesIO()), hfp) _dump(self, hw, _FROM_TYPE) hw.send(ION_STREAM_END_EVENT) return hw.send(HashEvent.DIGEST)
def new_writer(): out = BytesIO() return out, blocking_writer(_raw_binary_writer(BufferTree()), out)
def new_writer(): buf = BytesIO() return buf, blocking_writer(raw_writer(), buf)
def new_writer(imports=None): out = BytesIO() return out, blocking_writer(binary_writer(imports), out)
def test_pretty_print_events(): # http://amzn.github.io/ion-docs/guides/cookbook.html#pretty-printing pretty = BytesIO() writer = blocking_writer(text_writer(indent=u' '), pretty) writer.send(ION_STREAM_END_EVENT)