GEODE-2206: Add junit-quickcheck to geode-core. * Rewrite a data serialization test to use junit-quickcheck. * Move junit-quickcheck version to gradle/dependency-versions.properties
This closes #383 Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/4e8bc154 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/4e8bc154 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/4e8bc154 Branch: refs/heads/feature/GEODE-2267 Commit: 4e8bc15419032ac7eb3249405ad304b334b02f1f Parents: 89c8038 Author: Galen O'Sullivan <[email protected]> Authored: Tue Jan 31 15:05:17 2017 -0800 Committer: Kirk Lund <[email protected]> Committed: Mon Feb 6 14:17:47 2017 -0800 ---------------------------------------------------------------------- geode-core/build.gradle | 4 + ...ernalDataSerializerQuickcheckStringTest.java | 63 +++++++ ...ternalDataSerializerRandomizedJUnitTest.java | 172 ------------------- gradle/dependency-versions.properties | 1 + 4 files changed, 68 insertions(+), 172 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/4e8bc154/geode-core/build.gradle ---------------------------------------------------------------------- diff --git a/geode-core/build.gradle b/geode-core/build.gradle index 3c2a2ab..8eba6d4 100755 --- a/geode-core/build.gradle +++ b/geode-core/build.gradle @@ -131,6 +131,10 @@ dependencies { testCompile 'org.powermock:powermock-core:' + project.'powermock.version' testCompile 'org.powermock:powermock-module-junit4:' + project.'powermock.version' testCompile 'org.powermock:powermock-api-mockito:' + project.'powermock.version' + + testCompile 'com.pholser:junit-quickcheck-core:' + project.'junit-quickcheck.version' + testCompile 'com.pholser:junit-quickcheck-generators:' + project.'junit-quickcheck.version' + testCompile 'com.pholser:junit-quickcheck-guava:' + project.'junit-quickcheck.version' } def generatedResources = "$buildDir/generated-resources/main" http://git-wip-us.apache.org/repos/asf/geode/blob/4e8bc154/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerQuickcheckStringTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerQuickcheckStringTest.java b/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerQuickcheckStringTest.java new file mode 100644 index 0000000..b60dd49 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerQuickcheckStringTest.java @@ -0,0 +1,63 @@ +/* + * 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.geode.internal; + +import static org.junit.Assert.*; + +import com.pholser.junit.quickcheck.Property; +import com.pholser.junit.quickcheck.runner.JUnitQuickcheck; +import org.apache.geode.DataSerializer; +import org.apache.geode.test.junit.categories.UnitTest; +import org.junit.Before; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Tests the serialization and deserialization of randomly generated Strings. + * + * The current implementation (0.7 or 0.8alpha2) of junit-quickcheck-generators only generates valid + * codepoints, and that it doesn't tend to test strings that are particularly long, though the more + * trials you run, the longer they get. + */ +@Category(UnitTest.class) +@RunWith(JUnitQuickcheck.class) +public class InternalDataSerializerQuickcheckStringTest { + @Property(trials = 1000) + public void StringSerializedDeserializesToSameValue(String originalString) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + + DataSerializer.writeString(originalString, dataOutputStream); + dataOutputStream.flush(); + + byte[] stringBytes = byteArrayOutputStream.toByteArray(); + DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(stringBytes)); + String returnedString = DataSerializer.readString(dataInputStream); + + assertEquals("Deserialized string matches original", originalString, returnedString); + } + + @Before + public void setUp() { + // this may be unnecessary, but who knows what tests run before us. + InternalDataSerializer.reinitialize(); + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/4e8bc154/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerRandomizedJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerRandomizedJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerRandomizedJUnitTest.java deleted file mode 100644 index f361de4..0000000 --- a/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerRandomizedJUnitTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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.geode.internal; - -import static org.junit.Assert.*; - -import org.apache.geode.DataSerializer; -import org.apache.geode.cache.query.functional.IndexUsageInNestedQueryJUnitTest; -import org.apache.geode.test.junit.categories.UnitTest; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import javax.xml.bind.DatatypeConverter; -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.Inet4Address; -import java.security.SecureRandom; - -/** - * Tests the serialization and deserialization of strings made up of random Unicode code points. - */ -@Category(UnitTest.class) -public class InternalDataSerializerRandomizedJUnitTest { - private static final int ITERATIONS = 1000; - - private static void testStringSerializedDeserializesToSameValue(String originalString) - throws IOException { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); - - DataSerializer.writeString(originalString, dataOutputStream); - dataOutputStream.flush(); - - byte[] stringBytes = byteArrayOutputStream.toByteArray(); - DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(stringBytes)); - String returnedString = DataSerializer.readString(dataInputStream); - - assertEquals("Deserialized string matches original", originalString, returnedString); - } - - @Before - public void setUp() { - // this may be unnecessary, but who knows what tests run before us. - InternalDataSerializer.reinitialize(); - } - - @Test - public void testRandomStringsSerializeThenDeserializeToSameValues() throws Exception { - RandomStringGenerator stringGenerator = new RandomStringGenerator(); - try { - for (int i = 0; i < ITERATIONS; i++) { - String str = stringGenerator.randomString(); - testStringSerializedDeserializesToSameValue(str); - } - } catch (Throwable throwable) { - throw new Exception("Failed with seed " + stringGenerator.getSeedString(), throwable); - } - } - - @Test - public void testEdgeCaseSerializationDeserialization() throws IOException { - testStringSerializedDeserializesToSameValue("\0"); - testStringSerializedDeserializesToSameValue(""); - - RandomStringGenerator stringGenerator = new RandomStringGenerator(); - testStringSerializedDeserializesToSameValue(stringGenerator.randomString(65534)); - testStringSerializedDeserializesToSameValue(stringGenerator.randomString(65535)); - testStringSerializedDeserializesToSameValue(stringGenerator.randomString(65536)); - testStringSerializedDeserializesToSameValue(stringGenerator.randomString(65537)); - - testStringSerializedDeserializesToSameValue(stringGenerator.randomString()); - } - - @Test - public void testABigString() throws IOException { - RandomStringGenerator stringGenerator = new RandomStringGenerator(); - final int strlen = 1024 * 1024 * 5; - - testStringSerializedDeserializesToSameValue(stringGenerator.randomString(strlen)); - } - - private static class RandomStringGenerator { - public static final int SEED_BYTES = 8; - public static final int MAX_STRING_LENGTH = 65538; - // UTF-16 can represent any codepoint with 2 chars. - public static final int MAX_UTF16_CHARS = MAX_STRING_LENGTH * 2; - public static final int UNICODE_MAX = Character.MAX_CODE_POINT; - private final byte[] seed; - private final SecureRandom randomNumberGenerator; - - public byte[] getSeed() { - return seed.clone(); - } - - /** - * Returns a string representation of the seed, in xsd:hexBinary. This can be passed directly to - * the String constructor of this class to recreate with the same seed. - */ - public String getSeedString() { - return DatatypeConverter.printHexBinary(seed); - } - - /** - * Generate and return a random string made up of a series of Unicode codepoints (integers). - * This can be any series of codepoints, even unreserved ones. - */ - public RandomStringGenerator() { - this(SecureRandom.getSeed(SEED_BYTES)); - } - - /** - * Construct based on a provided seed. Mostly this should be useful for reproducing tests. - * <p> - * Technically we can take any size of seed, but we use one of size SEED_BYTES for tests. - */ - public RandomStringGenerator(byte[] seed) { - this.seed = seed.clone(); - randomNumberGenerator = new SecureRandom(this.seed); - } - - /** - * @param seedString an xsd:hexBinary string representing a seed. Normally acquired from - * `getSeedString();` - */ - public RandomStringGenerator(String seedString) { - this(DatatypeConverter.parseHexBinary(seedString)); - } - - public int randomCodepoint() { - return randomNumberGenerator.nextInt(UNICODE_MAX); - } - - /** - * @return A random string made of Unicode codepoints in the range from 0 to UNICODE_MAX. These - * strings will not necessarily be valid, as some codepoints in that range may be - * unallocated in the Unicode spec. - */ - public String randomString() { - return randomString(randomNumberGenerator.nextInt(MAX_UTF16_CHARS)); - } - - public String randomString(int length) { - StringBuilder stringBuilder = new StringBuilder(length * 2); - - for (int i = 0; i < length; i++) { - int codepoint = randomCodepoint(); - try { - stringBuilder.appendCodePoint(codepoint); - } catch (IllegalArgumentException ex) { - System.out.println("Generated illegal codepoint " + codepoint); - } - } - return stringBuilder.toString(); - } - } -} http://git-wip-us.apache.org/repos/asf/geode/blob/4e8bc154/gradle/dependency-versions.properties ---------------------------------------------------------------------- diff --git a/gradle/dependency-versions.properties b/gradle/dependency-versions.properties index 88a4c9a..a0b291e 100644 --- a/gradle/dependency-versions.properties +++ b/gradle/dependency-versions.properties @@ -73,6 +73,7 @@ json-path-assert.version = 2.2.0 json4s.version = 3.2.4 jsr305.version = 3.0.1 junit.version = 4.12 +junit-quickcheck.version = 0.7 JUnitParams.version = 1.0.5 log4j.version = 2.6.1 lucene.version = 6.0.0
