LUCENE-7936: Committing a randomized serialization test on behalf of Ignacio Vera, along with fixes.

This commit is contained in:
Karl Wright 2017-08-25 07:58:33 -04:00
parent 0a1d1cf8bd
commit 26b7644d00
5 changed files with 138 additions and 37 deletions

View File

@ -82,11 +82,8 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> extends BasePlan
*/
public GeoBaseCompositeShape(final PlanetModel planetModel, final InputStream inputStream, final Class<T> clazz) throws IOException {
this(planetModel);
final SerializableObject[] array = SerializableObject.readHeterogeneousArray(planetModel, inputStream);
final T[] array = SerializableObject.readHeterogeneousArray(planetModel, inputStream, clazz);
for (final SerializableObject member : array) {
if (!(clazz.isAssignableFrom(member.getClass()))) {
throw new IOException("Can't deserialize composite because member has wrong type: "+member.getClass().getName());
}
addShape(clazz.cast(member));
}
}

View File

@ -78,7 +78,11 @@ class GeoConcavePolygon extends GeoBasePolygon {
public GeoConcavePolygon(final PlanetModel planetModel, final List<GeoPoint> pointList, final List<GeoPolygon> holes) {
super(planetModel);
this.points = pointList;
this.holes = holes;
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
this.isInternalEdges = new BitSet();
done(false);
}
@ -114,7 +118,11 @@ class GeoConcavePolygon extends GeoBasePolygon {
final boolean returnEdgeInternal) {
super(planetModel);
this.points = pointList;
this.holes = holes;
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
this.isInternalEdges = internalEdgeFlags;
done(returnEdgeInternal);
}
@ -146,7 +154,11 @@ class GeoConcavePolygon extends GeoBasePolygon {
final List<GeoPolygon> holes) {
super(planetModel);
points = new ArrayList<>();
this.holes = holes;
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
isInternalEdges = new BitSet();
points.add(new GeoPoint(planetModel, startLatitude, startLongitude));
}
@ -313,7 +325,12 @@ class GeoConcavePolygon extends GeoBasePolygon {
public GeoConcavePolygon(final PlanetModel planetModel, final InputStream inputStream) throws IOException {
super(planetModel);
this.points = java.util.Arrays.asList(SerializableObject.readPointArray(planetModel, inputStream));
this.holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream));
final List<GeoPolygon> holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream));
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
this.isInternalEdges = SerializableObject.readBitSet(inputStream);
done(this.isInternalEdges.get(points.size()-1));
}
@ -515,7 +532,7 @@ class GeoConcavePolygon extends GeoBasePolygon {
public boolean equals(Object o) {
if (!(o instanceof GeoConcavePolygon))
return false;
GeoConcavePolygon other = (GeoConcavePolygon) o;
final GeoConcavePolygon other = (GeoConcavePolygon) o;
if (!super.equals(other))
return false;
if (!other.isInternalEdges.equals(isInternalEdges))

View File

@ -76,7 +76,11 @@ class GeoConvexPolygon extends GeoBasePolygon {
public GeoConvexPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList, final List<GeoPolygon> holes) {
super(planetModel);
this.points = pointList;
this.holes = holes;
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
this.isInternalEdges = new BitSet();
done(false);
}
@ -112,7 +116,11 @@ class GeoConvexPolygon extends GeoBasePolygon {
final boolean returnEdgeInternal) {
super(planetModel);
this.points = pointList;
this.holes = holes;
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
this.isInternalEdges = internalEdgeFlags;
done(returnEdgeInternal);
}
@ -144,7 +152,11 @@ class GeoConvexPolygon extends GeoBasePolygon {
final List<GeoPolygon> holes) {
super(planetModel);
points = new ArrayList<>();
this.holes = holes;
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
isInternalEdges = new BitSet();
points.add(new GeoPoint(planetModel, startLatitude, startLongitude));
}
@ -309,7 +321,12 @@ class GeoConvexPolygon extends GeoBasePolygon {
public GeoConvexPolygon(final PlanetModel planetModel, final InputStream inputStream) throws IOException {
super(planetModel);
this.points = java.util.Arrays.asList(SerializableObject.readPointArray(planetModel, inputStream));
this.holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream));
final List<GeoPolygon> holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream));
if (holes != null && holes.size() == 0) {
this.holes = null;
} else {
this.holes = holes;
}
this.isInternalEdges = SerializableObject.readBitSet(inputStream);
done(this.isInternalEdges.get(points.size()-1));
}
@ -501,7 +518,7 @@ class GeoConvexPolygon extends GeoBasePolygon {
public boolean equals(Object o) {
if (!(o instanceof GeoConvexPolygon))
return false;
GeoConvexPolygon other = (GeoConvexPolygon) o;
final GeoConvexPolygon other = (GeoConvexPolygon) o;
if (!super.equals(other))
return false;
if (!other.isInternalEdges.equals(isInternalEdges))

View File

@ -22,6 +22,7 @@ import java.io.OutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.lang.reflect.Constructor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.BitSet;
@ -42,7 +43,7 @@ public interface SerializableObject {
* @param outputStream is the output stream.
* @param object is the object to write.
*/
static void writeObject(final OutputStream outputStream, final SerializableObject object) throws IOException {
public static void writeObject(final OutputStream outputStream, final SerializableObject object) throws IOException {
writeString(outputStream, object.getClass().getName());
object.write(outputStream);
}
@ -52,7 +53,7 @@ public interface SerializableObject {
* @param inputStream is the input stream.
* @return the deserialized object.
*/
static SerializableObject readObject(final PlanetModel planetModel, final InputStream inputStream) throws IOException {
public static SerializableObject readObject(final PlanetModel planetModel, final InputStream inputStream) throws IOException {
// Read the class name
final String className = readString(inputStream);
try {
@ -96,7 +97,7 @@ public interface SerializableObject {
* @param inputStream is the input stream.
* @return the deserialized object.
*/
static SerializableObject readObject(final InputStream inputStream) throws IOException {
public static SerializableObject readObject(final InputStream inputStream) throws IOException {
// Read the class name
final String className = readString(inputStream);
try {
@ -173,7 +174,7 @@ public interface SerializableObject {
* @return the array of points that was read.
*/
static GeoPoint[] readPointArray(final PlanetModel planetModel, final InputStream inputStream) throws IOException {
return (GeoPoint[])readHomogeneousArray(planetModel, inputStream, GeoPoint.class);
return readHomogeneousArray(planetModel, inputStream, GeoPoint.class);
}
/** Write a polgon array.
@ -198,7 +199,7 @@ public interface SerializableObject {
* @return the array of polygons that was read.
*/
static GeoPolygon[] readPolygonArray(final PlanetModel planetModel, final InputStream inputStream) throws IOException {
return (GeoPolygon[])readHeterogeneousArray(planetModel, inputStream);
return readHeterogeneousArray(planetModel, inputStream, GeoPolygon.class);
}
/** Write an array.
@ -206,9 +207,13 @@ public interface SerializableObject {
* @param values is the array.
*/
static void writeHomogeneousArray(final OutputStream outputStream, final SerializableObject[] values) throws IOException {
writeInt(outputStream, values.length);
for (final SerializableObject value : values) {
value.write(outputStream);
if (values == null) {
writeInt(outputStream, 0);
} else {
writeInt(outputStream, values.length);
for (final SerializableObject value : values) {
value.write(outputStream);
}
}
}
@ -217,9 +222,13 @@ public interface SerializableObject {
* @param values is the array.
*/
static void writeHomogeneousArray(final OutputStream outputStream, final List<? extends SerializableObject> values) throws IOException {
writeInt(outputStream, values.size());
for (final SerializableObject value : values) {
value.write(outputStream);
if (values == null) {
writeInt(outputStream, 0);
} else {
writeInt(outputStream, values.size());
for (final SerializableObject value : values) {
value.write(outputStream);
}
}
}
@ -229,11 +238,12 @@ public interface SerializableObject {
* @param clazz is the class of the objects to read.
* @return the array.
*/
static SerializableObject[] readHomogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class<?> clazz) throws IOException {
@SuppressWarnings("unchecked")
static <T extends SerializableObject> T[] readHomogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class<T> clazz) throws IOException {
final int count = readInt(inputStream);
final SerializableObject[] rval = new SerializableObject[count];
final T[] rval = (T[])Array.newInstance(clazz, count);
for (int i = 0; i < count; i++) {
rval[i] = readObject(planetModel, inputStream, clazz);
rval[i] = clazz.cast(readObject(planetModel, inputStream, clazz));
}
return rval;
}
@ -243,9 +253,13 @@ public interface SerializableObject {
* @param values is the array.
*/
static void writeHeterogeneousArray(final OutputStream outputStream, final SerializableObject[] values) throws IOException {
writeInt(outputStream, values.length);
for (final SerializableObject value : values) {
writeObject(outputStream, value);
if (values == null) {
writeInt(outputStream, 0);
} else {
writeInt(outputStream, values.length);
for (final SerializableObject value : values) {
writeObject(outputStream, value);
}
}
}
@ -254,9 +268,13 @@ public interface SerializableObject {
* @param values is the array.
*/
static void writeHeterogeneousArray(final OutputStream outputStream, final List<? extends SerializableObject> values) throws IOException {
writeInt(outputStream, values.size());
for (final SerializableObject value : values) {
writeObject(outputStream, value);
if (values == null) {
writeInt(outputStream, 0);
} else {
writeInt(outputStream, values.size());
for (final SerializableObject value : values) {
writeObject(outputStream, value);
}
}
}
@ -265,11 +283,12 @@ public interface SerializableObject {
* @param inputStream is the input stream.
* @return the array.
*/
static SerializableObject[] readHeterogeneousArray(final PlanetModel planetModel, final InputStream inputStream) throws IOException {
@SuppressWarnings("unchecked")
static <T extends SerializableObject> T[] readHeterogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class<T> clazz) throws IOException {
final int count = readInt(inputStream);
final SerializableObject[] rval = new SerializableObject[count];
final T[] rval = (T[])Array.newInstance(clazz, count);
for (int i = 0; i < count; i++) {
rval[i] = readObject(planetModel, inputStream);
rval[i] = clazz.cast(readObject(planetModel, inputStream));
}
return rval;
}

View File

@ -0,0 +1,51 @@
/*
* 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.lucene.spatial3d.geom;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
import org.junit.Test;
/**
* Test to check Serialization
*/
public class RandomBinaryCodecTest extends RandomGeoShapeGenerator{
@Test
@Repeat(iterations = 100)
public void testRandomShapeCodec() throws IOException{
PlanetModel planetModel = randomPlanetModel();
int type = randomShapeType();
while (type == COMPLEX_POLYGON){
//We need to implement equals method
type = randomShapeType();
}
GeoShape shape = randomGeoShape(type, planetModel);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
SerializableObject.writeObject(outputStream, shape);
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
SerializableObject shapeCopy = SerializableObject.readObject(planetModel, inputStream);
assertEquals(shape, shapeCopy);
}
}