1616 */
1717package org .apache .jackrabbit .oak .plugins .document .mongo ;
1818
19+ import org .apache .commons .lang3 .RandomStringUtils ;
1920import org .apache .jackrabbit .oak .plugins .document .Collection ;
2021import org .apache .jackrabbit .oak .plugins .document .DocumentMK ;
2122import org .apache .jackrabbit .oak .plugins .document .DocumentStoreException ;
2627import org .apache .jackrabbit .oak .plugins .document .UpdateOp ;
2728import org .apache .jackrabbit .oak .plugins .document .util .Utils ;
2829import org .apache .jackrabbit .oak .commons .junit .LogCustomizer ;
30+ import org .bson .BSONException ;
2931import org .junit .After ;
3032import org .junit .Assume ;
3133import org .junit .Before ;
3234import org .junit .BeforeClass ;
3335import org .junit .Test ;
36+ import org .slf4j .event .Level ;
3437
3538import java .util .ArrayList ;
3639import java .util .Arrays ;
3740import java .util .List ;
3841
3942import static java .util .Collections .singletonList ;
43+ import static org .hamcrest .MatcherAssert .assertThat ;
4044import static org .hamcrest .Matchers .containsString ;
41- import static org .junit .Assert .assertThat ;
45+ import static org .junit .Assert .assertEquals ;
46+ import static org .junit .Assert .assertFalse ;
4247import static org .junit .Assert .assertTrue ;
4348import static org .junit .Assert .fail ;
44- import static org .junit .Assert .assertFalse ;
4549
4650public class MongoDBExceptionTest {
4751
@@ -157,6 +161,61 @@ public void createOrUpdate16MBDoc() {
157161 customizer .finished ();
158162 }
159163
164+ @ Test
165+ public void createOrUpdate16MBBatchWithMultiDocs () {
166+ LogCustomizer log = LogCustomizer .forLogger (MongoDocumentStore .class .getName ()).
167+ enable (Level .ERROR ).
168+ matchesRegex ("bulkUpdate.*biggest update.*approximate.*" ).
169+ create ();
170+
171+ try {
172+ log .starting ();
173+ List <String > ids = new ArrayList <>();
174+ List <UpdateOp > updateOps = new ArrayList <>();
175+
176+ String idOfReallyBig = "foo-really-big" ;
177+
178+ {
179+ String id = "/foo-1MB" ;
180+ ids .add (id );
181+ UpdateOp updateOp = new UpdateOp (id , true );
182+ updateOp = create1MBProp (updateOp );
183+ updateOps .add (updateOp );
184+ }
185+ {
186+ String id = idOfReallyBig ;
187+ ids .add (id );
188+ UpdateOp updateOp = new UpdateOp (id , true );
189+ updateOp .set ("big" , RandomStringUtils .secure ().next (20 * 1024 * 1024 ));
190+ updateOps .add (updateOp );
191+ }
192+ {
193+ String id = "/foo-small" ;
194+ ids .add (id );
195+ UpdateOp updateOp = new UpdateOp (id , true );
196+ updateOps .add (updateOp );
197+ }
198+
199+ store .remove (Collection .NODES , ids );
200+
201+ try {
202+ store .createOrUpdate (Collection .NODES , updateOps );
203+ fail ("createOrUpdate(many with one >16MB) should have failed" );
204+ } catch (BSONException expected ) {
205+ // currently expected but incorrect -> OAK-12113
206+ List <String > messages = log .getLogs ();
207+ assertEquals ("only 1 message expected, but got: " + messages .size (),
208+ 1 , messages .size ());
209+ String message = messages .get (0 );
210+ assertTrue ("log message should contain id " + idOfReallyBig + "/foo-really.big, got: " + message ,
211+ message .contains (idOfReallyBig ));
212+ }
213+
214+ } finally {
215+ log .finished ();
216+ }
217+ }
218+
160219 @ Test
161220 public void update16MBDoc () {
162221
@@ -263,7 +322,7 @@ private UpdateOp create1MBProp(UpdateOp op) {
263322 private UpdateOp create16MBProp (UpdateOp op ) {
264323 // create a 1 MB property
265324 String content = create1MBContent ();
266-
325+
267326
268327 //create 16MB property
269328 for (int i = 0 ; i < 16 ; i ++) {
@@ -272,6 +331,7 @@ private UpdateOp create16MBProp(UpdateOp op) {
272331 return op ;
273332 }
274333
334+ // RED ALERT: OAK-12114
275335 private String create1MBContent () {
276336 char [] chars = new char [1024 * 1024 ];
277337 Arrays .fill (chars , '0' );
0 commit comments