ionutzpi commented on code in PR #1526:
URL: https://github.com/apache/jackrabbit-oak/pull/1526#discussion_r1689259248
##########
oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentPropertyStateTest.java:
##########
@@ -81,4 +114,289 @@ public void multiValuedBinarySize() throws Exception {
assertEquals(0, reads.size());
}
-}
+ @Test
+ public void multiValuedAboveThresholdSize() throws Exception {
+ NodeBuilder builder = ns.getRoot().builder();
+ List<Blob> blobs = newArrayList();
+ for (int i = 0; i < 13; i++) {
+ blobs.add(builder.createBlob(new RandomStream(BLOB_SIZE, i)));
+ }
+ builder.child(TEST_NODE).setProperty("p", blobs, Type.BINARIES);
+ TestUtils.merge(ns, builder);
+
+ PropertyState p =
ns.getRoot().getChildNode(TEST_NODE).getProperty("p");
+ assertEquals(Type.BINARIES, Objects.requireNonNull(p).getType());
+ assertEquals(13, p.count());
+
+ reads.clear();
+ assertEquals(BLOB_SIZE, p.size(0));
+ // must not read the blob via stream
+ assertEquals(0, reads.size());
+ }
+
+ @Test
+ public void stringBelowThresholdSize() throws Exception {
+ NodeBuilder builder = ns.getRoot().builder();
+ builder.child(TEST_NODE).setProperty("p", "dummy", Type.STRING);
+ TestUtils.merge(ns, builder);
+
+ PropertyState p =
ns.getRoot().getChildNode(TEST_NODE).getProperty("p");
+ assertEquals(Type.STRING, Objects.requireNonNull(p).getType());
+ assertEquals(1, p.count());
+
+ reads.clear();
+ assertEquals(5, p.size(0));
+ // must not read the string via stream
+ assertEquals(0, reads.size());
+ }
+
+ @Test
+ public void stringAboveThresholdSize() throws Exception {
+ NodeBuilder builder = ns.getRoot().builder();
+ builder.child(TEST_NODE).setProperty("p", STRING_HUGEVALUE,
Type.STRING);
+ TestUtils.merge(ns, builder);
+
+ PropertyState p =
ns.getRoot().getChildNode(TEST_NODE).getProperty("p");
+ assertEquals(Type.STRING, Objects.requireNonNull(p).getType());
+ assertEquals(1, p.count());
+
+ reads.clear();
+ assertEquals(10050, p.size(0));
+ // must not read the string via streams
+ assertEquals(0, reads.size());
+ }
+
+ @Test
+ public void compressValueThrowsException() throws IOException,
NoSuchFieldException, IllegalAccessException {
+ DocumentNodeStore mockDocumentStore = mock(DocumentNodeStore.class);
+ Compression mockCompression = mock(Compression.class);
+
when(mockCompression.getOutputStream(any(OutputStream.class))).thenThrow(new
IOException("Compression failed"));
+
+
DocumentPropertyState.setCompressionThreshold(DEFAULT_COMPRESSION_THRESHOLD);
+ DocumentPropertyState documentPropertyState = new
DocumentPropertyState(mockDocumentStore, "p", "\"" + STRING_HUGEVALUE + "\"",
mockCompression);
+
+ assertEquals(documentPropertyState.getValue(Type.STRING),
STRING_HUGEVALUE);
+
+ verify(mockCompression,
times(1)).getOutputStream(any(OutputStream.class));
+ }
+
+ @Test
+ public void uncompressValueThrowsException() throws IOException,
NoSuchFieldException, IllegalAccessException {
+
+ DocumentNodeStore mockDocumentStore = mock(DocumentNodeStore.class);
+ Compression mockCompression = mock(Compression.class);
+ OutputStream mockOutputStream= mock(OutputStream.class);
+
when(mockCompression.getOutputStream(any(OutputStream.class))).thenReturn(mockOutputStream);
+
when(mockCompression.getInputStream(any(InputStream.class))).thenThrow(new
IOException("Compression failed"));
+
+
DocumentPropertyState.setCompressionThreshold(DEFAULT_COMPRESSION_THRESHOLD);
+ DocumentPropertyState documentPropertyState = new
DocumentPropertyState(mockDocumentStore, "p", STRING_HUGEVALUE,
mockCompression);
+
+ assertEquals(documentPropertyState.getValue(Type.STRING), "{}");
+
+ verify(mockCompression,
times(1)).getInputStream(any(InputStream.class));
+ }
+
+ @Test
+ public void defaultValueSetToMinusOne() throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException, NoSuchFieldException {
+ DocumentNodeStore store = mock(DocumentNodeStore.class);
+
+ DocumentPropertyState.setCompressionThreshold(-1);
+ DocumentPropertyState state = new DocumentPropertyState(store,
"propertyNameNew", "\"" + STRING_HUGEVALUE + "\"", Compression.GZIP);
+
+ byte[] result = state.getCompressedValue();
+
+ assertNull(result);
+ assertEquals(state.getValue(Type.STRING), STRING_HUGEVALUE);
+ }
+
+ @Test
+ public void stringAboveThresholdSizeNoCompression() {
+ DocumentNodeStore store = mock(DocumentNodeStore.class);
+
+
DocumentPropertyState.setCompressionThreshold(DEFAULT_COMPRESSION_THRESHOLD);
+
+ DocumentPropertyState state = new DocumentPropertyState(store,
"propertyName", "\"" + STRING_HUGEVALUE + "\"", Compression.NONE);
+
+ byte[] result = state.getCompressedValue();
+
+ assertEquals(result.length, STRING_HUGEVALUE.length() + 2 );
+
+ assertEquals(state.getValue(Type.STRING), STRING_HUGEVALUE);
+ assertEquals(STRING_HUGEVALUE, state.getValue(Type.STRING));
+ }
+
+ @Test
+ public void testInterestingStringsWithoutCompression() {
+ DocumentNodeStore store = mock(DocumentNodeStore.class);
+ String[] tests = new String[] { "simple:foo", "cr:a\n\b",
"dquote:a\"b", "bs:a\\b", "euro:a\u201c", "gclef:\uD834\uDD1E",
+ "tab:a\tb", "nul:a\u0000b"};
+
+ for (String test : tests) {
+ DocumentPropertyState state = new DocumentPropertyState(store,
"propertyName", test, Compression.GZIP);
+ assertEquals(test, state.getValue());
+ }
+ }
+
+ @Test
+ public void testInterestingStringsWithCompression() {
+ DocumentNodeStore store = mock(DocumentNodeStore.class);
+ String[] tests = new String[]{"simple:foo", "cr:a\n\b", "dquote:a\"b",
"bs:a\\b", "euro:a\u201c", "gclef:\uD834\uDD1E",
+ "tab:a\tb", "nul:a\u0000b"};
+
+ DocumentPropertyState.setCompressionThreshold(1);
+ for (String test : tests) {
+ DocumentPropertyState state = new DocumentPropertyState(store,
"propertyName", test, Compression.GZIP);
+ assertEquals(test, state.getValue());
+ }
+ }
+
+ @Test
+ public void testBrokenSurrogateWithoutCompressionForMongo() throws
CommitFailedException {
+ getBrokenSurrogateAndInitializeDifferentStores(MONGO, false);
+ }
+
+ @Test
+ public void testBrokenSurrogateWithoutCompressionForRDB() throws
CommitFailedException {
+ getBrokenSurrogateAndInitializeDifferentStores(RDB_H2, false);
+ }
+
+ @Test
+ public void testBrokenSurrogateWithoutCompressionForInMemory() throws
CommitFailedException {
+ getBrokenSurrogateAndInitializeDifferentStores(MEMORY, false);
+ }
+
+ @Test
+ public void testBrokenSurrogateWithCompressionForMongo() throws
CommitFailedException {
+ DocumentPropertyState.setCompressionThreshold(1);
+ getBrokenSurrogateAndInitializeDifferentStores(MONGO, true);
+ }
+
+ @Test
+ public void testBrokenSurrogateWithCompressionForRDB() throws
CommitFailedException {
+ DocumentPropertyState.setCompressionThreshold(1);
+ getBrokenSurrogateAndInitializeDifferentStores(RDB_H2, true);
+ }
+
+ @Test
+ public void testBrokenSurrogateWithCompressionForInMemory() throws
CommitFailedException {
+ DocumentPropertyState.setCompressionThreshold(1);
+ getBrokenSurrogateAndInitializeDifferentStores(MEMORY, true);
+ }
+
+ private void
getBrokenSurrogateAndInitializeDifferentStores(DocumentStoreFixture fixture,
boolean compressionEnabled) throws CommitFailedException {
+ String test = "brokensurrogate:dfsa\ud800";
+ DocumentStore store = null;
+ DocumentNodeStore nodeStore = null;
+
+ try {
+ store = fixture.createDocumentStore();
+
+ if (store instanceof MongoDocumentStore) {
+ // Enforce primary read preference, otherwise tests may fail
on a
+ // replica set with a read preference configured to secondary.
+ // Revision GC usually runs with a modified range way in the
past,
+ // which means changes made it to the secondary, but not in
this
+ // test using a virtual clock
+ MongoTestUtils.setReadPreference(store,
ReadPreference.primary());
+ }
+ nodeStore = new
DocumentMK.Builder().setDocumentStore(store).getNodeStore();
+
+ createPropAndCheckValue(nodeStore, test, compressionEnabled);
+
+ } finally {
+ if (nodeStore != null) {
+ nodeStore.dispose();
+ }
+ if (store != null) {
+ store.dispose();
+ }
+ }
+
+ }
+
+ private void createPropAndCheckValue(DocumentNodeStore nodeStore, String
test, boolean compressionEnabled) throws CommitFailedException {
+ NodeBuilder builder = nodeStore.getRoot().builder();
+ if (compressionEnabled) {
+ DocumentPropertyState.setCompressionThreshold(1);
+ }
+ DocumentPropertyState documentPropertyState = new
DocumentPropertyState(nodeStore, "p", test, Compression.GZIP);
+ builder.child(TEST_NODE).setProperty("p",
documentPropertyState.getValue(), Type.STRING);
Review Comment:
Done. Thanks.
##########
oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentPropertyStateTest.java:
##########
@@ -81,4 +114,289 @@ public void multiValuedBinarySize() throws Exception {
assertEquals(0, reads.size());
}
-}
+ @Test
+ public void multiValuedAboveThresholdSize() throws Exception {
+ NodeBuilder builder = ns.getRoot().builder();
+ List<Blob> blobs = newArrayList();
+ for (int i = 0; i < 13; i++) {
+ blobs.add(builder.createBlob(new RandomStream(BLOB_SIZE, i)));
+ }
+ builder.child(TEST_NODE).setProperty("p", blobs, Type.BINARIES);
+ TestUtils.merge(ns, builder);
+
+ PropertyState p =
ns.getRoot().getChildNode(TEST_NODE).getProperty("p");
+ assertEquals(Type.BINARIES, Objects.requireNonNull(p).getType());
+ assertEquals(13, p.count());
+
+ reads.clear();
+ assertEquals(BLOB_SIZE, p.size(0));
+ // must not read the blob via stream
+ assertEquals(0, reads.size());
+ }
+
+ @Test
+ public void stringBelowThresholdSize() throws Exception {
+ NodeBuilder builder = ns.getRoot().builder();
+ builder.child(TEST_NODE).setProperty("p", "dummy", Type.STRING);
+ TestUtils.merge(ns, builder);
+
+ PropertyState p =
ns.getRoot().getChildNode(TEST_NODE).getProperty("p");
+ assertEquals(Type.STRING, Objects.requireNonNull(p).getType());
+ assertEquals(1, p.count());
+
+ reads.clear();
+ assertEquals(5, p.size(0));
+ // must not read the string via stream
+ assertEquals(0, reads.size());
+ }
+
+ @Test
+ public void stringAboveThresholdSize() throws Exception {
+ NodeBuilder builder = ns.getRoot().builder();
+ builder.child(TEST_NODE).setProperty("p", STRING_HUGEVALUE,
Type.STRING);
+ TestUtils.merge(ns, builder);
+
+ PropertyState p =
ns.getRoot().getChildNode(TEST_NODE).getProperty("p");
+ assertEquals(Type.STRING, Objects.requireNonNull(p).getType());
+ assertEquals(1, p.count());
+
+ reads.clear();
+ assertEquals(10050, p.size(0));
+ // must not read the string via streams
+ assertEquals(0, reads.size());
+ }
+
+ @Test
+ public void compressValueThrowsException() throws IOException,
NoSuchFieldException, IllegalAccessException {
+ DocumentNodeStore mockDocumentStore = mock(DocumentNodeStore.class);
+ Compression mockCompression = mock(Compression.class);
+
when(mockCompression.getOutputStream(any(OutputStream.class))).thenThrow(new
IOException("Compression failed"));
+
+
DocumentPropertyState.setCompressionThreshold(DEFAULT_COMPRESSION_THRESHOLD);
+ DocumentPropertyState documentPropertyState = new
DocumentPropertyState(mockDocumentStore, "p", "\"" + STRING_HUGEVALUE + "\"",
mockCompression);
+
+ assertEquals(documentPropertyState.getValue(Type.STRING),
STRING_HUGEVALUE);
+
+ verify(mockCompression,
times(1)).getOutputStream(any(OutputStream.class));
+ }
+
+ @Test
+ public void uncompressValueThrowsException() throws IOException,
NoSuchFieldException, IllegalAccessException {
+
+ DocumentNodeStore mockDocumentStore = mock(DocumentNodeStore.class);
+ Compression mockCompression = mock(Compression.class);
+ OutputStream mockOutputStream= mock(OutputStream.class);
+
when(mockCompression.getOutputStream(any(OutputStream.class))).thenReturn(mockOutputStream);
+
when(mockCompression.getInputStream(any(InputStream.class))).thenThrow(new
IOException("Compression failed"));
+
+
DocumentPropertyState.setCompressionThreshold(DEFAULT_COMPRESSION_THRESHOLD);
+ DocumentPropertyState documentPropertyState = new
DocumentPropertyState(mockDocumentStore, "p", STRING_HUGEVALUE,
mockCompression);
+
+ assertEquals(documentPropertyState.getValue(Type.STRING), "{}");
+
+ verify(mockCompression,
times(1)).getInputStream(any(InputStream.class));
+ }
+
+ @Test
+ public void defaultValueSetToMinusOne() throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException, NoSuchFieldException {
+ DocumentNodeStore store = mock(DocumentNodeStore.class);
+
+ DocumentPropertyState.setCompressionThreshold(-1);
+ DocumentPropertyState state = new DocumentPropertyState(store,
"propertyNameNew", "\"" + STRING_HUGEVALUE + "\"", Compression.GZIP);
+
+ byte[] result = state.getCompressedValue();
+
+ assertNull(result);
+ assertEquals(state.getValue(Type.STRING), STRING_HUGEVALUE);
+ }
+
+ @Test
+ public void stringAboveThresholdSizeNoCompression() {
+ DocumentNodeStore store = mock(DocumentNodeStore.class);
+
+
DocumentPropertyState.setCompressionThreshold(DEFAULT_COMPRESSION_THRESHOLD);
+
+ DocumentPropertyState state = new DocumentPropertyState(store,
"propertyName", "\"" + STRING_HUGEVALUE + "\"", Compression.NONE);
+
+ byte[] result = state.getCompressedValue();
+
+ assertEquals(result.length, STRING_HUGEVALUE.length() + 2 );
+
+ assertEquals(state.getValue(Type.STRING), STRING_HUGEVALUE);
+ assertEquals(STRING_HUGEVALUE, state.getValue(Type.STRING));
+ }
+
+ @Test
+ public void testInterestingStringsWithoutCompression() {
+ DocumentNodeStore store = mock(DocumentNodeStore.class);
+ String[] tests = new String[] { "simple:foo", "cr:a\n\b",
"dquote:a\"b", "bs:a\\b", "euro:a\u201c", "gclef:\uD834\uDD1E",
+ "tab:a\tb", "nul:a\u0000b"};
+
+ for (String test : tests) {
+ DocumentPropertyState state = new DocumentPropertyState(store,
"propertyName", test, Compression.GZIP);
+ assertEquals(test, state.getValue());
Review Comment:
Done
##########
oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentPropertyStateTest.java:
##########
@@ -18,26 +18,50 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
import java.util.List;
+import java.util.Map;
Review Comment:
Done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]