blob: d40ca641f8aad1bb41e5e7482b9951f02d7f63e8 [file] [log] [blame]
<?php
/**
* 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
*
* https://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.
*/
namespace Apache\Avro\Tests;
use Apache\Avro\DataFile\AvroDataIO;
use PHPUnit\Framework\TestCase;
class DataFileTest extends TestCase
{
const REMOVE_DATA_FILES = true;
private $data_files;
public function test_write_read_nothing_round_trip()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-wr-nothing-null-%s.avr', $codec));
$writers_schema = '"null"';
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
$dw->close();
$dr = AvroDataIO::openFile($data_file);
$data = $dr->data();
$dr->close();
$this->assertEmpty($data);
}
}
protected function add_data_file($data_file)
{
if (is_null($this->data_files)) {
$this->data_files = array();
}
$data_file = "$data_file." . self::current_timestamp();
$full = join(DIRECTORY_SEPARATOR, array(TEST_TEMP_DIR, $data_file));
$this->data_files [] = $full;
return $full;
}
public static function current_timestamp()
{
return strftime("%Y%m%dT%H%M%S");
}
public function test_write_read_null_round_trip()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-wr-null-%s.avr', $codec));
$writers_schema = '"null"';
$data = null;
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
$dw->append($data);
$dw->close();
$dr = AvroDataIO::openFile($data_file);
$read_data = $dr->data();
$datum = reset($read_data);
$dr->close();
$this->assertEquals($data, $datum);
}
}
public function test_write_read_string_round_trip()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-wr-str-%s.avr', $codec));
$writers_schema = '"string"';
$data = 'foo';
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
$dw->append($data);
$dw->close();
$dr = AvroDataIO::openFile($data_file);
$read_data = $dr->data();
$datum = array_shift($read_data);
$dr->close();
$this->assertEquals($data, $datum);
}
}
public function test_write_read_round_trip()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-wr-int-%s.avr', $codec));
$writers_schema = '"int"';
$data = 1;
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
$dw->append(1);
$dw->close();
$dr = AvroDataIO::openFile($data_file);
$read_data = $dr->data();
$datum = array_shift($read_data);
$dr->close();
$this->assertEquals($data, $datum);
}
}
public function test_write_read_true_round_trip()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-wr-true-%s.avr', $codec));
$writers_schema = '"boolean"';
$datum = true;
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
$dw->append($datum);
$dw->close();
$dr = AvroDataIO::openFile($data_file);
$read_data = $dr->data();
$read_datum = array_shift($read_data);
$dr->close();
$this->assertEquals($datum, $read_datum);
}
}
public function test_write_read_false_round_trip()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-wr-false-%s.avr', $codec));
$writers_schema = '"boolean"';
$datum = false;
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
$dw->append($datum);
$dw->close();
$dr = AvroDataIO::openFile($data_file);
$read_data = $dr->data();
$read_datum = array_shift($read_data);
$dr->close();
$this->assertEquals($datum, $read_datum);
}
}
public function test_write_read_int_array_round_trip()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-wr-int-ary-%s.avr', $codec));
$writers_schema = '"int"';
$data = array(10, 20, 30, 40, 50, 60, 70, 567, 89012345);
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
foreach ($data as $datum) {
$dw->append($datum);
}
$dw->close();
$dr = AvroDataIO::openFile($data_file);
$read_data = $dr->data();
$dr->close();
$this->assertEquals($data, $read_data,
sprintf("in: %s\nout: %s",
json_encode($data), json_encode($read_data)));
}
}
public function test_differing_schemas_with_primitives()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-prim-%s.avr', $codec));
$writer_schema = <<<JSON
{ "type": "record",
"name": "User",
"fields" : [
{"name": "username", "type": "string"},
{"name": "age", "type": "int"},
{"name": "verified", "type": "boolean", "default": "false"}
]}
JSON;
$data = array(
array('username' => 'john', 'age' => 25, 'verified' => true),
array('username' => 'ryan', 'age' => 23, 'verified' => false)
);
$dw = AvroDataIO::openFile($data_file, 'w', $writer_schema, $codec);
foreach ($data as $datum) {
$dw->append($datum);
}
$dw->close();
$reader_schema = <<<JSON
{ "type": "record",
"name": "User",
"fields" : [
{"name": "username", "type": "string"}
]}
JSON;
$dr = AvroDataIO::openFile($data_file, 'r', $reader_schema);
foreach ($dr->data() as $index => $record) {
$this->assertEquals($data[$index]['username'], $record['username']);
}
}
}
public function test_differing_schemas_with_complex_objects()
{
foreach (AvroDataIO::validCodecs() as $codec) {
if (
($codec === AvroDataIO::SNAPPY_CODEC && !extension_loaded('snappy'))
|| ($codec === AvroDataIO::ZSTANDARD_CODEC && !extension_loaded('zstd'))
) {
continue;
}
$data_file = $this->add_data_file(sprintf('data-complex-%s.avr', $codec));
$writers_schema = <<<JSON
{ "type": "record",
"name": "something",
"fields": [
{"name": "something_fixed", "type": {"name": "inner_fixed",
"type": "fixed", "size": 3}},
{"name": "something_enum", "type": {"name": "inner_enum",
"type": "enum",
"symbols": ["hello", "goodbye"]}},
{"name": "something_array", "type": {"type": "array", "items": "int"}},
{"name": "something_map", "type": {"type": "map", "values": "int"}},
{"name": "something_record", "type": {"name": "inner_record",
"type": "record",
"fields": [
{"name": "inner", "type": "int"}
]}},
{"name": "username", "type": "string"}
]}
JSON;
$data = [
[
"username" => "john",
"something_fixed" => "foo",
"something_enum" => "hello",
"something_array" => [1, 2, 3],
"something_map" => ["a" => 1, "b" => 2],
"something_record" => ["inner" => 2],
"something_error" => ["code" => 403]
],
[
"username" => "ryan",
"something_fixed" => "bar",
"something_enum" => "goodbye",
"something_array" => [1, 2, 3],
"something_map" => ["a" => 2, "b" => 6],
"something_record" => ["inner" => 1],
"something_error" => ["code" => 401]
]
];
$dw = AvroDataIO::openFile($data_file, 'w', $writers_schema, $codec);
foreach ($data as $datum) {
$dw->append($datum);
}
$dw->close();
foreach (array(
'fixed',
'enum',
'record',
'error',
'array',
'map',
'union'
) as $s) {
$readers_schema = json_decode($writers_schema, true);
$dr = AvroDataIO::openFile($data_file, 'r', json_encode($readers_schema));
foreach ($dr->data() as $idx => $obj) {
foreach ($readers_schema['fields'] as $field) {
$field_name = $field['name'];
$this->assertEquals($data[$idx][$field_name], $obj[$field_name]);
}
}
$dr->close();
}
}
}
protected function setUp(): void
{
if (!file_exists(TEST_TEMP_DIR)) {
mkdir(TEST_TEMP_DIR);
}
$this->remove_data_files();
}
protected function remove_data_files()
{
if (self::REMOVE_DATA_FILES && $this->data_files) {
foreach ($this->data_files as $data_file) {
self::remove_data_file($data_file);
}
}
}
protected static function remove_data_file($data_file)
{
if (file_exists($data_file)) {
unlink($data_file);
}
}
protected function tearDown(): void
{
$this->remove_data_files();
}
}