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: oak-dev-unsubscr...@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to