You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by to...@apache.org on 2014/06/09 13:36:35 UTC
svn commit: r1601345 - in /avro/trunk: ./
lang/java/avro/src/main/java/org/apache/avro/
lang/java/avro/src/main/java/org/apache/avro/io/parsing/
lang/java/avro/src/test/java/org/apache/avro/
Author: tomwhite
Date: Mon Jun 9 11:36:34 2014
New Revision: 1601345
URL: http://svn.apache.org/r1601345
Log:
AVRO-1315. Java: Schema Validation utilities. Contributed by scottcarey and tomwhite.
Added:
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationException.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationStrategy.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidator.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidatorBuilder.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateAll.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanBeRead.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanRead.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateLatest.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateMutualRead.java
avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaValidation.java
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java
Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1601345&r1=1601344&r2=1601345&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Mon Jun 9 11:36:34 2014
@@ -4,6 +4,8 @@ Trunk (not yet released)
NEW FEATURES
+ AVRO-1315. Java: Schema Validation utilities. (scottcarey and tomwhite)
+
AVRO-1439. Java: Add AvroMultipleInputs for mapred. (Harsh J via cutting)
AVRO-974. Add a Perl implementation of Avro. (Yann Kerhervé & John Karp)
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationException.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationException.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationException.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationException.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,39 @@
+/**
+ * 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;
+
+/**
+ * Thrown when {@link SchemaValidator} fails to validate a schema.
+ */
+public class SchemaValidationException extends Exception {
+
+ public SchemaValidationException(Schema reader, Schema writer) {
+ super(getMessage(reader, writer));
+ }
+
+ public SchemaValidationException(Schema reader, Schema writer,
+ Throwable cause) {
+ super(getMessage(reader, writer), cause);
+ }
+
+ private static String getMessage(Schema reader, Schema writer) {
+ return "Unable to read schema: \n"
+ + writer.toString(true) + "\nusing schema:\n" + reader.toString(true);
+ }
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationStrategy.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationStrategy.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationStrategy.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidationStrategy.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,20 @@
+package org.apache.avro;
+
+/**
+ * An interface for validating the compatibility of a single schema against
+ * another.
+ * <p>
+ * What makes one schema compatible with another is not defined by the contract.
+ * <p/>
+ */
+public interface SchemaValidationStrategy {
+
+ /**
+ * Validates that one schema is compatible with another.
+ *
+ * @throws SchemaValidationException if the schemas are not compatible.
+ */
+ void validate(Schema toValidate, Schema existing)
+ throws SchemaValidationException;
+
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidator.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidator.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidator.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidator.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,46 @@
+/**
+ * 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;
+
+/**
+ * <p>
+ * A SchemaValidator has one method, which validates that a {@link Schema} is
+ * <b>compatible<b/> with the other schemas provided.
+ * </p>
+ * <p>
+ * What makes one Schema compatible with another is not part of the interface
+ * contract.
+ * </p>
+ */
+public interface SchemaValidator {
+
+ /**
+ * Validate one schema against others. The order of the schemas to validate
+ * against is chronological from most recent to oldest, if there is a natural
+ * chronological order. This allows some validators to identify which schemas
+ * are the most "recent" in order to validate only against the mosst recent
+ * schema(s).
+ *
+ * @param toValidate The schema to validate
+ * @param existing The schemas to validate against, in order from most recent to latest if applicable
+ * @throws SchemaValidationException if the schema fails to validate.
+ */
+ void validate(Schema toValidate, Iterable<Schema> existing) throws SchemaValidationException;
+
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidatorBuilder.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidatorBuilder.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidatorBuilder.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/SchemaValidatorBuilder.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,77 @@
+/**
+ * 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;
+
+/**
+ * <p>
+ * A Builder for creating SchemaValidators.
+ * </p>
+ */
+public final class SchemaValidatorBuilder {
+ private SchemaValidationStrategy strategy;
+
+ public SchemaValidatorBuilder strategy(SchemaValidationStrategy strategy) {
+ this.strategy = strategy;
+ return this;
+ }
+
+ /**
+ * Use a strategy that validates that a schema can be used to read existing
+ * schema(s) according to the Avro default schema resolution.
+ */
+ public SchemaValidatorBuilder canReadStrategy() {
+ this.strategy = new ValidateCanRead();
+ return this;
+ }
+
+ /**
+ * Use a strategy that validates that a schema can be read by existing
+ * schema(s) according to the Avro default schema resolution.
+ */
+ public SchemaValidatorBuilder canBeReadStrategy() {
+ this.strategy = new ValidateCanBeRead();
+ return this;
+ }
+
+ /**
+ * Use a strategy that validates that a schema can read existing schema(s),
+ * and vice-versa, according to the Avro default schema resolution.
+ */
+ public SchemaValidatorBuilder mutualReadStrategy() {
+ this.strategy = new ValidateMutualRead();
+ return this;
+ }
+
+ public SchemaValidator validateLatest() {
+ valid();
+ return new ValidateLatest(strategy);
+ }
+
+ public SchemaValidator validateAll() {
+ valid();
+ return new ValidateAll(strategy);
+ }
+
+ private void valid() {
+ if(null == strategy) {
+ throw new AvroRuntimeException("SchemaValidationStrategy not specified in builder");
+ }
+ }
+
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateAll.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateAll.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateAll.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateAll.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,55 @@
+/**
+ * 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;
+
+import java.util.Iterator;
+
+/**
+ * <p>
+ * A {@link SchemaValidator} for validating the provided schema against all
+ * schemas in the Iterable in {@link #validate(Schema, Iterable)}.
+ * </p>
+ * <p>
+ * Uses the {@link SchemaValidationStrategy} provided in the constructor to
+ * validate the {@link Schema} against each Schema in the Iterable, in Iterator
+ * order, via {@link SchemaValidationStrategy#validate(Schema, Schema)}.
+ * </p>
+ */
+public final class ValidateAll implements SchemaValidator {
+ private final SchemaValidationStrategy strategy;
+
+ /**
+ * @param strategy
+ * The strategy to use for validation of pairwise schemas.
+ */
+ public ValidateAll(SchemaValidationStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ @Override
+ public void validate(Schema toValidate, Iterable<Schema> schemasInOrder)
+ throws SchemaValidationException {
+ Iterator<Schema> schemas = schemasInOrder.iterator();
+ while (schemas.hasNext()) {
+ Schema existing = schemas.next();
+ strategy.validate(toValidate, existing);
+ }
+ }
+
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanBeRead.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanBeRead.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanBeRead.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanBeRead.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,42 @@
+/**
+ * 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;
+
+/**
+ * A {@link SchemaValidationStrategy} that checks that the data written with the
+ * {@link Schema} to validate can be read by the existing schema according to
+ * the default Avro schema resolution rules.
+ *
+ */
+class ValidateCanBeRead implements SchemaValidationStrategy {
+
+ /**
+ * Validate that data written with first schema provided can be read using the
+ * second schema, according to the default Avro schema resolution rules.
+ *
+ * @throws SchemaValidationException
+ * if the second schema cannot read data written by the first.
+ */
+ @Override
+ public void validate(Schema toValidate, Schema existing)
+ throws SchemaValidationException {
+ ValidateMutualRead.canRead(toValidate, existing);
+ }
+
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanRead.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanRead.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanRead.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateCanRead.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,43 @@
+/**
+ * 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;
+
+/**
+ * A {@link SchemaValidationStrategy} that checks that the {@link Schema} to
+ * validate can read the existing schema according to the default Avro schema
+ * resolution rules.
+ *
+ */
+class ValidateCanRead implements SchemaValidationStrategy {
+
+ /**
+ * Validate that the first schema provided can be used to read data written
+ * with the second schema, according to the default Avro schema resolution
+ * rules.
+ *
+ * @throws SchemaValidationException
+ * if the first schema cannot read data written by the second.
+ */
+ @Override
+ public void validate(Schema toValidate, Schema existing)
+ throws SchemaValidationException {
+ ValidateMutualRead.canRead(existing, toValidate);
+ }
+
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateLatest.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateLatest.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateLatest.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateLatest.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,55 @@
+/**
+ * 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;
+
+import java.util.Iterator;
+
+/**
+ * <p>
+ * A {@link SchemaValidator} for validating the provided schema against the
+ * first {@link Schema} in the iterable in {@link #validate(Schema, Iterable)}.
+ * </p>
+ * <p>
+ * Uses the {@link SchemaValidationStrategy} provided in the constructor to
+ * validate the schema against the first Schema in the iterable, if it exists,
+ * via {@link SchemaValidationStrategy#validate(Schema, Schema)}.
+ * </p>
+ */
+public final class ValidateLatest implements SchemaValidator {
+ private final SchemaValidationStrategy strategy;
+
+ /**
+ * @param strategy
+ * The strategy to use for validation of pairwise schemas.
+ */
+ public ValidateLatest(SchemaValidationStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ @Override
+ public void validate(Schema toValidate, Iterable<Schema> schemasInOrder)
+ throws SchemaValidationException {
+ Iterator<Schema> schemas = schemasInOrder.iterator();
+ if (schemas.hasNext()) {
+ Schema existing = schemas.next();
+ strategy.validate(toValidate, existing);
+ }
+ }
+
+}
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateMutualRead.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateMutualRead.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateMutualRead.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/ValidateMutualRead.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,74 @@
+/**
+ * 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;
+
+import java.io.IOException;
+
+import org.apache.avro.io.parsing.ResolvingGrammarGenerator;
+import org.apache.avro.io.parsing.Symbol;
+
+/**
+ * A {@link SchemaValidationStrategy} that checks that the {@link Schema} to
+ * validate and the existing schema can mutually read each other according to
+ * the default Avro schema resolution rules.
+ *
+ */
+class ValidateMutualRead implements SchemaValidationStrategy {
+
+ /**
+ * Validate that the schemas provided can mutually read data written by each
+ * other according to the default Avro schema resolution rules.
+ *
+ * @throws SchemaValidationException if the schemas are not mutually compatible.
+ */
+ @Override
+ public void validate(Schema toValidate, Schema existing)
+ throws SchemaValidationException {
+ canRead(toValidate, existing);
+ canRead(existing, toValidate);
+ }
+
+ /**
+ * Validates that data written with one schema can be read using another,
+ * based on the default Avro schema resolution rules.
+ *
+ * @param writtenWith
+ * The "writer's" schema, representing data to be read.
+ * @param readUsing
+ * The "reader's" schema, representing how the reader will interpret
+ * data.
+ * @throws SchemaValidationException
+ * if the schema <b>readUsing<b/> cannot be used to read data
+ * written with <b>writtenWith<b/>
+ */
+ static void canRead(Schema writtenWith, Schema readUsing)
+ throws SchemaValidationException {
+ boolean error;
+ try {
+ error = Symbol.hasErrors(new ResolvingGrammarGenerator().generate(
+ writtenWith, readUsing));
+ } catch (IOException e) {
+ throw new SchemaValidationException(readUsing, writtenWith, e);
+ }
+ if (error) {
+ throw new SchemaValidationException(readUsing, writtenWith);
+ }
+ }
+
+}
Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java?rev=1601345&r1=1601344&r2=1601345&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java Mon Jun 9 11:36:34 2014
@@ -349,6 +349,45 @@ public abstract class Symbol {
}
}
+
+ /**
+ * Returns true if the Parser contains any Error symbol, indicating that it may fail
+ * for some inputs.
+ */
+ public static boolean hasErrors(Symbol symbol) {
+ switch(symbol.kind) {
+ case ALTERNATIVE:
+ return hasErrors(symbol, ((Alternative) symbol).symbols);
+ case EXPLICIT_ACTION:
+ return false;
+ case IMPLICIT_ACTION:
+ return symbol instanceof ErrorAction;
+ case REPEATER:
+ Repeater r = (Repeater) symbol;
+ return hasErrors(r.end) || hasErrors(symbol, r.production);
+ case ROOT:
+ case SEQUENCE:
+ return hasErrors(symbol, symbol.production);
+ case TERMINAL:
+ return false;
+ default:
+ throw new RuntimeException("unknown symbol kind: " + symbol.kind);
+ }
+ }
+
+ private static boolean hasErrors(Symbol root, Symbol[] symbols) {
+ if(null != symbols) {
+ for(Symbol s: symbols) {
+ if (s == root) {
+ continue;
+ }
+ if (hasErrors(s)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
public static class Alternative extends Symbol {
public final Symbol[] symbols;
Added: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaValidation.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaValidation.java?rev=1601345&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaValidation.java (added)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaValidation.java Mon Jun 9 11:36:34 2014
@@ -0,0 +1,147 @@
+/**
+ * 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;
+
+import java.util.ArrayList;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestSchemaValidation {
+
+ SchemaValidatorBuilder builder = new SchemaValidatorBuilder();
+
+ Schema rec = SchemaBuilder.record("test.Rec").fields()
+ .name("a").type().intType().intDefault(1)
+ .name("b").type().longType().noDefault()
+ .endRecord();
+
+ Schema rec2 = SchemaBuilder.record("test.Rec").fields()
+ .name("a").type().intType().intDefault(1)
+ .name("b").type().longType().noDefault()
+ .name("c").type().intType().intDefault(0)
+ .endRecord();
+
+ Schema rec3 = SchemaBuilder.record("test.Rec").fields()
+ .name("b").type().longType().noDefault()
+ .name("c").type().intType().intDefault(0)
+ .endRecord();
+
+ Schema rec4 = SchemaBuilder.record("test.Rec").fields()
+ .name("b").type().longType().noDefault()
+ .name("c").type().intType().noDefault()
+ .endRecord();
+
+ Schema rec5 = SchemaBuilder.record("test.Rec").fields()
+ .name("a").type().stringType().stringDefault("") // different type from original
+ .name("b").type().longType().noDefault()
+ .name("c").type().intType().intDefault(0)
+ .endRecord();
+
+ @Test
+ public void testAllTypes() throws SchemaValidationException {
+ Schema s = SchemaBuilder.record("r").fields()
+ .requiredBoolean("boolF")
+ .requiredInt("intF")
+ .requiredLong("longF")
+ .requiredFloat("floatF")
+ .requiredDouble("doubleF")
+ .requiredString("stringF")
+ .requiredBytes("bytesF")
+ .name("fixedF1").type().fixed("F1").size(1).noDefault()
+ .name("enumF").type().enumeration("E1").symbols("S").noDefault()
+ .name("mapF").type().map().values().stringType().noDefault()
+ .name("arrayF").type().array().items().stringType().noDefault()
+ .name("recordF").type().record("inner").fields()
+ .name("f").type().intType().noDefault()
+ .endRecord().noDefault()
+ .optionalBoolean("boolO")
+ .endRecord();
+ testValidatorPasses(builder.mutualReadStrategy().validateLatest(), s, s);
+ }
+
+ @Test
+ public void testReadOnePrior() throws SchemaValidationException {
+ testValidatorPasses(builder.canReadStrategy().validateLatest(), rec3, rec);
+ testValidatorPasses(builder.canReadStrategy().validateLatest(), rec5, rec3);
+ testValidatorFails(builder.canReadStrategy().validateLatest(), rec4, rec);
+ }
+
+ @Test
+ public void testReadAllPrior() throws SchemaValidationException {
+ testValidatorPasses(builder.canReadStrategy().validateAll(), rec3, rec, rec2);
+ testValidatorFails(builder.canReadStrategy().validateAll(), rec4, rec, rec2, rec3);
+ testValidatorFails(builder.canReadStrategy().validateAll(), rec5, rec, rec2, rec3);
+ }
+
+ @Test
+ public void testOnePriorCanRead() throws SchemaValidationException {
+ testValidatorPasses(builder.canBeReadStrategy().validateLatest(), rec, rec3);
+ testValidatorFails(builder.canBeReadStrategy().validateLatest(), rec, rec4);
+ }
+
+ @Test
+ public void testAllPriorCanRead() throws SchemaValidationException {
+ testValidatorPasses(builder.canBeReadStrategy().validateAll(), rec, rec3, rec2);
+ testValidatorFails(builder.canBeReadStrategy().validateAll(), rec, rec4, rec3, rec2);
+ }
+
+ @Test
+ public void testOnePriorCompatible() throws SchemaValidationException {
+ testValidatorPasses(builder.mutualReadStrategy().validateLatest(), rec, rec3);
+ testValidatorFails(builder.mutualReadStrategy().validateLatest(), rec, rec4);
+ }
+
+ @Test
+ public void testAllPriorCompatible() throws SchemaValidationException {
+ testValidatorPasses(builder.mutualReadStrategy().validateAll(), rec, rec3, rec2);
+ testValidatorFails(builder.mutualReadStrategy().validateAll(), rec, rec4, rec3, rec2);
+ }
+
+ @Test(expected=AvroRuntimeException.class)
+ public void testInvalidBuild() {
+ builder.strategy(null).validateAll();
+ }
+
+ private void testValidatorPasses(SchemaValidator validator,
+ Schema schema, Schema... prev) throws SchemaValidationException {
+ ArrayList<Schema> prior = new ArrayList<Schema>();
+ for(int i = prev.length - 1; i >= 0; i--) {
+ prior.add(prev[i]);
+ }
+ validator.validate(schema, prior);
+ }
+
+ private void testValidatorFails(SchemaValidator validator,
+ Schema schemaFails, Schema... prev) throws SchemaValidationException {
+ ArrayList<Schema> prior = new ArrayList<Schema>();
+ for(int i = prev.length - 1; i >= 0; i--) {
+ prior.add(prev[i]);
+ }
+ boolean threw = false;
+ try {
+ // should fail
+ validator.validate(schemaFails, prior);
+ } catch (SchemaValidationException sve) {
+ threw = true;
+ }
+ Assert.assertTrue(threw);
+ }
+
+}