| /** |
| * 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. |
| */ |
| package org.apache.avro.io; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Arrays; |
| import java.util.Collection; |
| |
| import org.apache.avro.Schema; |
| import org.apache.avro.io.TestValidatingIO.Encoding; |
| import org.junit.Test; |
| import org.junit.runners.Parameterized; |
| import org.junit.runner.RunWith; |
| |
| @RunWith(Parameterized.class) |
| public class TestResolvingIO { |
| |
| protected final Encoding eEnc; |
| protected final int iSkipL; |
| protected final String sJsWrtSchm; |
| protected final String sWrtCls; |
| protected final String sJsRdrSchm; |
| protected final String sRdrCls; |
| |
| public TestResolvingIO (Encoding encoding, |
| int skipLevel, String jsonWriterSchema, |
| String writerCalls, |
| String jsonReaderSchema, String readerCalls |
| ) { |
| this.eEnc = encoding; |
| this.iSkipL = skipLevel; |
| this.sJsWrtSchm = jsonWriterSchema; |
| this.sWrtCls = writerCalls; |
| this.sJsRdrSchm = jsonReaderSchema; |
| this.sRdrCls = readerCalls; |
| } |
| |
| @Test |
| public void testIdentical() throws IOException { |
| performTest(eEnc, iSkipL, sJsWrtSchm, sWrtCls, sJsWrtSchm, sWrtCls); |
| } |
| |
| private static final int COUNT = 10; |
| |
| @Test |
| public void testCompatible() throws IOException { |
| performTest(eEnc, iSkipL, sJsWrtSchm, sWrtCls, sJsRdrSchm, sRdrCls); |
| } |
| |
| private void performTest(Encoding encoding, |
| int skipLevel, String jsonWriterSchema, |
| String writerCalls, |
| String jsonReaderSchema, String readerCalls) |
| throws IOException { |
| for (int i = 0; i < COUNT; i++) { |
| testOnce(jsonWriterSchema, writerCalls, |
| jsonReaderSchema, readerCalls, encoding, skipLevel); |
| } |
| } |
| |
| private void testOnce(String jsonWriterSchema, |
| String writerCalls, |
| String jsonReaderSchema, |
| String readerCalls, |
| Encoding encoding, |
| int skipLevel) throws IOException { |
| Object[] values = TestValidatingIO.randomValues(writerCalls); |
| Object[] expected = TestValidatingIO.randomValues(readerCalls); |
| |
| Schema writerSchema = new Schema.Parser().parse(jsonWriterSchema); |
| byte[] bytes = TestValidatingIO.make(writerSchema, writerCalls, |
| values, encoding); |
| Schema readerSchema = new Schema.Parser().parse(jsonReaderSchema); |
| TestValidatingIO.print(encoding, skipLevel, writerSchema, readerSchema, values, expected); |
| check(writerSchema, readerSchema, bytes, readerCalls, |
| expected, |
| encoding, skipLevel); |
| } |
| |
| static void check(Schema wsc, Schema rsc, byte[] bytes, |
| String calls, Object[] values, Encoding encoding, |
| int skipLevel) |
| throws IOException { |
| // TestValidatingIO.dump(bytes); |
| // System.out.println(new String(bytes, "UTF-8")); |
| Decoder bvi = null; |
| switch (encoding) { |
| case BINARY: |
| case BLOCKING_BINARY: |
| bvi = DecoderFactory.get().binaryDecoder(bytes, null); |
| break; |
| case JSON: |
| InputStream in = new ByteArrayInputStream(bytes); |
| bvi = new JsonDecoder(wsc, in); |
| break; |
| } |
| Decoder vi = new ResolvingDecoder(wsc, rsc, bvi); |
| TestValidatingIO.check(vi, calls, values, skipLevel); |
| } |
| |
| @Parameterized.Parameters |
| public static Collection<Object[]> data2() { |
| return Arrays.asList(TestValidatingIO.convertTo2dArray(encodings, skipLevels, testSchemas())); |
| } |
| |
| static Object[][] encodings = new Object[][] { { Encoding.BINARY }, |
| { Encoding.BLOCKING_BINARY }, { Encoding.JSON } }; |
| static Object[][] skipLevels = |
| new Object[][] { { -1 }, { 0 }, { 1 }, { 2 } }; |
| private static Object[][] testSchemas() { |
| // The mnemonics are the same as {@link TestValidatingIO#testSchemas} |
| return new Object[][] { |
| { "\"int\"", "I", "\"float\"", "F" }, |
| { "\"int\"", "I", "\"double\"", "D" }, |
| { "\"int\"", "I", "\"long\"", "L" }, |
| { "\"long\"", "L", "\"float\"", "F" }, |
| { "\"long\"", "L", "\"double\"", "D" }, |
| { "\"float\"", "F", "\"double\"", "D" }, |
| |
| { "{\"type\":\"array\", \"items\": \"int\"}", "[]", |
| "{\"type\":\"array\", \"items\": \"long\"}", "[]", }, |
| { "{\"type\":\"array\", \"items\": \"int\"}", "[]", |
| "{\"type\":\"array\", \"items\": \"double\"}", "[]" }, |
| { "{\"type\":\"array\", \"items\": \"long\"}", "[]", |
| "{\"type\":\"array\", \"items\": \"double\"}", "[]" }, |
| { "{\"type\":\"array\", \"items\": \"float\"}", "[]", |
| "{\"type\":\"array\", \"items\": \"double\"}", "[]" }, |
| |
| { "{\"type\":\"array\", \"items\": \"int\"}", "[c1sI]", |
| "{\"type\":\"array\", \"items\": \"long\"}", "[c1sL]" }, |
| { "{\"type\":\"array\", \"items\": \"int\"}", "[c1sI]", |
| "{\"type\":\"array\", \"items\": \"double\"}", "[c1sD]" }, |
| { "{\"type\":\"array\", \"items\": \"long\"}", "[c1sL]", |
| "{\"type\":\"array\", \"items\": \"double\"}", "[c1sD]" }, |
| { "{\"type\":\"array\", \"items\": \"float\"}", "[c1sF]", |
| "{\"type\":\"array\", \"items\": \"double\"}", "[c1sD]" }, |
| |
| { "{\"type\":\"map\", \"values\": \"int\"}", "{}", |
| "{\"type\":\"map\", \"values\": \"long\"}", "{}" }, |
| { "{\"type\":\"map\", \"values\": \"int\"}", "{}", |
| "{\"type\":\"map\", \"values\": \"double\"}", "{}" }, |
| { "{\"type\":\"map\", \"values\": \"long\"}", "{}", |
| "{\"type\":\"map\", \"values\": \"double\"}", "{}" }, |
| { "{\"type\":\"map\", \"values\": \"float\"}", "{}", |
| "{\"type\":\"map\", \"values\": \"double\"}", "{}" }, |
| |
| { "{\"type\":\"map\", \"values\": \"int\"}", "{c1sK5I}", |
| "{\"type\":\"map\", \"values\": \"long\"}", "{c1sK5L}" }, |
| { "{\"type\":\"map\", \"values\": \"int\"}", "{c1sK5I}", |
| "{\"type\":\"map\", \"values\": \"double\"}", "{c1sK5D}" }, |
| { "{\"type\":\"map\", \"values\": \"long\"}", "{c1sK5L}", |
| "{\"type\":\"map\", \"values\": \"double\"}", "{c1sK5D}" }, |
| { "{\"type\":\"map\", \"values\": \"float\"}", "{c1sK5F}", |
| "{\"type\":\"map\", \"values\": \"double\"}", "{c1sK5D}" }, |
| |
| { "{\"type\":\"record\",\"name\":\"r\",\"fields\":[" |
| + "{\"name\":\"f\", \"type\":\"int\"}]}", "I", |
| "{\"type\":\"record\",\"name\":\"r\",\"fields\":[" |
| + "{\"name\":\"f\", \"type\":\"long\"}]}", "L" }, |
| { "{\"type\":\"record\",\"name\":\"r\",\"fields\":[" |
| + "{\"name\":\"f\", \"type\":\"int\"}]}", "I", |
| "{\"type\":\"record\",\"name\":\"r\",\"fields\":[" |
| + "{\"name\":\"f\", \"type\":\"double\"}]}", "D" }, |
| |
| // multi-field record with promotions |
| { "{\"type\":\"record\",\"name\":\"r\",\"fields\":[" |
| + "{\"name\":\"f0\", \"type\":\"boolean\"}," |
| + "{\"name\":\"f1\", \"type\":\"int\"}," |
| + "{\"name\":\"f2\", \"type\":\"float\"}," |
| + "{\"name\":\"f3\", \"type\":\"bytes\"}," |
| + "{\"name\":\"f4\", \"type\":\"string\"}]}", "BIFbS", |
| "{\"type\":\"record\",\"name\":\"r\",\"fields\":[" |
| + "{\"name\":\"f0\", \"type\":\"boolean\"}," |
| + "{\"name\":\"f1\", \"type\":\"long\"}," |
| + "{\"name\":\"f2\", \"type\":\"double\"}," |
| + "{\"name\":\"f3\", \"type\":\"string\"}," |
| + "{\"name\":\"f4\", \"type\":\"bytes\"}]}", "BLDSb" }, |
| |
| { "[\"int\"]", "U0I", |
| "[\"long\"]", "U0L" }, |
| { "[\"int\"]", "U0I", |
| "[\"double\"]", "U0D" }, |
| { "[\"long\"]", "U0L", |
| "[\"double\"]", "U0D" }, |
| { "[\"float\"]", "U0F", |
| "[\"double\"]", "U0D" }, |
| |
| { "\"int\"", "I", "[\"int\"]", "U0I" }, |
| |
| { "[\"int\"]", "U0I", "\"int\"", "I" }, |
| { "[\"int\"]", "U0I", "\"long\"", "L" }, |
| |
| { "[\"boolean\", \"int\"]", "U1I", |
| "[\"boolean\", \"long\"]", "U1L" }, |
| { "[\"boolean\", \"int\"]", "U1I", |
| "[\"long\", \"boolean\"]", "U0L" }, |
| }; |
| } |
| } |