1 /*
   2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.webkit;
  27 
  28 import java.io.IOException;
  29 import java.util.LinkedList;
  30 import java.util.Random;
  31 import org.junit.After;
  32 import org.junit.BeforeClass;
  33 import org.junit.Ignore;
  34 import org.junit.Test;
  35 import static org.junit.Assert.assertArrayEquals;
  36 import static org.junit.Assert.assertEquals;
  37 import static org.junit.Assert.assertFalse;
  38 import static org.junit.Assert.assertTrue;
  39 import static org.junit.Assert.fail;
  40 
  41 public class SimpleSharedBufferInputStreamTest {
  42 
  43     private static final int SEGMENT_SIZE = 0x1000;
  44     private static final Random random = new Random();
  45 
  46     private final SharedBuffer sb = new SharedBuffer();
  47     private final SimpleSharedBufferInputStream is =
  48             new SimpleSharedBufferInputStream(sb);
  49 
  50 
  51     @BeforeClass
  52     public static void beforeClass() throws ClassNotFoundException {
  53         Class.forName(WebPage.class.getName());
  54     }
  55 
  56 
  57     @Test
  58     public void testConstructor() {
  59         new SimpleSharedBufferInputStream(sb);
  60     }
  61 
  62     @Test
  63     public void testConstructorNullSharedBuffer() {
  64         try {
  65             new SimpleSharedBufferInputStream(null);
  66             fail("NullPointerException expected but not thrown");
  67         } catch (NullPointerException expected) {}
  68     }
  69 
  70     @Test
  71     public void testRead1FirstSegmentFirstByte() {
  72         append(SEGMENT_SIZE * 2.5);
  73         assertEquals(0, is.read());
  74     }
  75 
  76     @Test
  77     public void testRead1FirstSegmentInteriorByte() {
  78         append(SEGMENT_SIZE * 2.5);
  79         readOut(2);
  80         assertEquals(2, is.read());
  81     }
  82 
  83     @Test
  84     public void testRead1FirstSegmentLastByte() {
  85         append(SEGMENT_SIZE * 2.5);
  86         readOut(SEGMENT_SIZE - 1);
  87         assertEquals((SEGMENT_SIZE - 1) & 0xff, is.read());
  88         assertEquals(SEGMENT_SIZE & 0xff, is.read());
  89     }
  90 
  91     @Test
  92     public void testRead1InteriorSegmentFirstByte() {
  93         append(SEGMENT_SIZE * 2.5);
  94         readOut(SEGMENT_SIZE);
  95         assertEquals(SEGMENT_SIZE & 0xff, is.read());
  96     }
  97 
  98     @Test
  99     public void testRead1InteriorSegmentInteriorByte() {
 100         append(SEGMENT_SIZE * 2.5);
 101         readOut(SEGMENT_SIZE + 2);
 102         assertEquals((SEGMENT_SIZE + 2) & 0xff, is.read());
 103     }
 104 
 105     @Test
 106     public void testRead1InteriorSegmentLastByte() {
 107         append(SEGMENT_SIZE * 2.5);
 108         readOut(SEGMENT_SIZE * 2 - 1);
 109         assertEquals((SEGMENT_SIZE * 2 - 1) & 0xff, is.read());
 110         assertEquals((SEGMENT_SIZE * 2) & 0xff, is.read());
 111     }
 112 
 113     @Test
 114     public void testRead1LastSegmentFirstByte() {
 115         append(SEGMENT_SIZE * 2.5);
 116         readOut(SEGMENT_SIZE * 2);
 117         assertEquals((SEGMENT_SIZE * 2) & 0xff, is.read());
 118     }
 119 
 120     @Test
 121     public void testRead1LastSegmentInteriorByte() {
 122         append(SEGMENT_SIZE * 2.5);
 123         readOut(SEGMENT_SIZE * 2 + 2);
 124         assertEquals((SEGMENT_SIZE * 2 + 2) & 0xff, is.read());
 125     }
 126 
 127     @Test
 128     public void testRead1LastSegmentLastByte() {
 129         append(SEGMENT_SIZE * 2.5);
 130         readOut(SEGMENT_SIZE * 2.5 - 1);
 131         assertEquals((int) (SEGMENT_SIZE * 2.5 - 1) & 0xff, is.read());
 132     }
 133 
 134     @Test
 135     public void testRead1ByteAfterLastByte() {
 136         append(SEGMENT_SIZE * 2.5);
 137         readOut(SEGMENT_SIZE * 2.5);
 138         assertEquals(-1, is.read());
 139     }
 140 
 141     @Test
 142     public void testRead1ByteFromEmptyBuffer() {
 143         assertEquals(-1, is.read());
 144     }
 145 
 146     @Test
 147     public void testRead3FirstSegmentFirstTenBytes() {
 148         append(SEGMENT_SIZE * 2.5);
 149         assertArrayEquals(g(0, 10), read(10));
 150     }
 151 
 152     @Test
 153     public void testRead3FirstSegmentInteriorTenBytes() {
 154         append(SEGMENT_SIZE * 2.5);
 155         readOut(7);
 156         assertArrayEquals(g(7, 10), read(10));
 157     }
 158 
 159     @Test
 160     public void testRead3FirstSegmentLastTenBytes() {
 161         append(SEGMENT_SIZE * 2.5);
 162         readOut(SEGMENT_SIZE - 10);
 163         assertArrayEquals(g(SEGMENT_SIZE - 10, 10), read(10));
 164     }
 165 
 166     @Test @Ignore
 167     public void testRead3InteriorSegmentFirstTenBytes() {
 168         append(SEGMENT_SIZE * 2.5);
 169         readOut(SEGMENT_SIZE);
 170         assertArrayEquals(g(SEGMENT_SIZE, 10), read(10));
 171     }
 172 
 173     @Test
 174     public void testRead3InteriorSegmentInteriorTenBytes() {
 175         append(SEGMENT_SIZE * 2.5);
 176         readOut(SEGMENT_SIZE + 7);
 177         assertArrayEquals(g(SEGMENT_SIZE + 7, 10), read(10));
 178     }
 179 
 180     @Test
 181     public void testRead3InteriorSegmentLastTenBytes() {
 182         append(SEGMENT_SIZE * 2.5);
 183         readOut(SEGMENT_SIZE * 2 - 10);
 184         assertArrayEquals(g(SEGMENT_SIZE * 2 - 10, 10), read(10));
 185     }
 186 
 187     @Test @Ignore
 188     public void testRead3LastSegmentFirstTenBytes() {
 189         append(SEGMENT_SIZE * 2.5);
 190         readOut(SEGMENT_SIZE * 2);
 191         assertArrayEquals(g(SEGMENT_SIZE * 2, 10), read(10));
 192     }
 193 
 194     @Test
 195     public void testRead3LastSegmentInteriorTenBytes() {
 196         append(SEGMENT_SIZE * 2.5);
 197         readOut(SEGMENT_SIZE * 2 + 7);
 198         assertArrayEquals(g(SEGMENT_SIZE * 2 + 7, 10), read(10));
 199     }
 200 
 201     @Test
 202     public void testRead3LastSegmentLastTenBytes() {
 203         append(SEGMENT_SIZE * 2.5);
 204         readOut(SEGMENT_SIZE * 2.5 - 10);
 205         assertArrayEquals(g(SEGMENT_SIZE * 2.5 - 10, 10), read(10));
 206     }
 207 
 208     @Test
 209     public void testRead3LastSegmentLastTenBytesWithTruncation() {
 210         append(SEGMENT_SIZE * 2.5);
 211         readOut(SEGMENT_SIZE * 2.5 - 5);
 212         assertArrayEquals(g(SEGMENT_SIZE * 2.5 - 5, 5), read(10));
 213     }
 214 
 215     @Test
 216     public void testRead3TenBytesAfterLastByte() {
 217         append(SEGMENT_SIZE * 2.5);
 218         readOut(SEGMENT_SIZE * 2.5);
 219         assertArrayEquals(null, read(10));
 220     }
 221 
 222     @Test
 223     public void testRead3TenBytesFromEmptyBuffer() {
 224         assertArrayEquals(null, read(10));
 225     }
 226 
 227     @Test
 228     public void testRead3FirstSegment() {
 229         append(SEGMENT_SIZE * 2.5);
 230         assertArrayEquals(g(0, SEGMENT_SIZE), read(SEGMENT_SIZE));
 231     }
 232 
 233     @Test @Ignore
 234     public void testRead3InteriorSegment() {
 235         append(SEGMENT_SIZE * 2.5);
 236         readOut(SEGMENT_SIZE);
 237         assertArrayEquals(g(SEGMENT_SIZE, SEGMENT_SIZE), read(SEGMENT_SIZE));
 238     }
 239 
 240     @Test @Ignore
 241     public void testRead3LastSegment() {
 242         append(SEGMENT_SIZE * 2.5);
 243         readOut(SEGMENT_SIZE * 2);
 244         assertArrayEquals(
 245                 g(SEGMENT_SIZE * 2, SEGMENT_SIZE * 0.5),
 246                 read(SEGMENT_SIZE));
 247     }
 248 
 249     @Test
 250     public void testRead3FirstSegmentFirstZeroBytes() {
 251         append(SEGMENT_SIZE * 2.5);
 252         assertArrayEquals(new byte[0], read(0));
 253     }
 254 
 255     @Test
 256     public void testRead3FirstSegmentInteriorZeroBytes() {
 257         append(SEGMENT_SIZE * 2.5);
 258         readOut(SEGMENT_SIZE * 0.5);
 259         assertArrayEquals(new byte[0], read(0));
 260     }
 261 
 262     @Test
 263     public void testRead3InteriorSegmentFirstZeroBytes() {
 264         append(SEGMENT_SIZE * 2.5);
 265         readOut(SEGMENT_SIZE);
 266         assertArrayEquals(new byte[0], read(0));
 267     }
 268 
 269     @Test
 270     public void testRead3InteriorSegmentInterriorZeroBytes() {
 271         append(SEGMENT_SIZE * 2.5);
 272         readOut(SEGMENT_SIZE * 1.5);
 273         assertArrayEquals(new byte[0], read(0));
 274     }
 275 
 276     @Test
 277     public void testRead3LastSegmentFirstZeroBytes() {
 278         append(SEGMENT_SIZE * 2.5);
 279         readOut(SEGMENT_SIZE * 2);
 280         assertArrayEquals(new byte[0], read(0));
 281     }
 282 
 283     @Test
 284     public void testRead3LastSegmentInteriorZeroBytes() {
 285         append(SEGMENT_SIZE * 2.5);
 286         readOut(SEGMENT_SIZE * 2 + 7);
 287         assertArrayEquals(new byte[0], read(0));
 288     }
 289 
 290     @Test
 291     public void testRead3ZeroBytesAfterLastByte() {
 292         append(SEGMENT_SIZE * 2.5);
 293         readOut(SEGMENT_SIZE * 2.5);
 294         assertArrayEquals(new byte[0], read(0));
 295     }
 296 
 297     @Test
 298     public void testRead3ZeroBytesFromEmptyBuffer() {
 299         assertArrayEquals(new byte[0], read(0));
 300     }
 301 
 302     @Test
 303     public void testRead3NullBuffer() {
 304         try {
 305             is.read(null, 0, 1);
 306             fail("NullPointerException expected but not thrown");
 307         } catch (NullPointerException expected) {}
 308     }
 309 
 310     @Test
 311     public void testRead3NegativeOffset() {
 312         try {
 313             is.read(new byte[0], -1, 1);
 314             fail("IndexOutOfBoundsException expected but not thrown");
 315         } catch (IndexOutOfBoundsException expected) {}
 316     }
 317 
 318     @Test
 319     public void testRead3NegativeLength() {
 320         try {
 321             is.read(new byte[0], 0, -1);
 322             fail("IndexOutOfBoundsException expected but not thrown");
 323         } catch (IndexOutOfBoundsException expected) {}
 324     }
 325 
 326     @Test
 327     public void testRead3IllegalBufferOrOffsetOrLength() {
 328         try {
 329             is.read(new byte[0], 0, 1);
 330             fail("IndexOutOfBoundsException expected but not thrown");
 331         } catch (IndexOutOfBoundsException expected) {}
 332 
 333         try {
 334             is.read(new byte[0], 1, 0);
 335             fail("IndexOutOfBoundsException expected but not thrown");
 336         } catch (IndexOutOfBoundsException expected) {}
 337 
 338         try {
 339             is.read(new byte[10], 0, 11);
 340             fail("IndexOutOfBoundsException expected but not thrown");
 341         } catch (IndexOutOfBoundsException expected) {}
 342 
 343         try {
 344             is.read(new byte[10], 1, 10);
 345             fail("IndexOutOfBoundsException expected but not thrown");
 346         } catch (IndexOutOfBoundsException expected) {}
 347     }
 348 
 349     private void testSkipSmallNumberOfBytes(long skip) {
 350         int streamSize = (int) (SEGMENT_SIZE * 2.5);
 351         int skipCount = streamSize / SEGMENT_SIZE + 1;
 352         append(streamSize);
 353         int position = 0;
 354         for (int i = 0; i < skipCount; i++) {
 355             long skipped = is.skip(skip);
 356             assertEquals(Math.max(skip, 0), skipped);
 357             position += skipped;
 358             long len = Math.min(SEGMENT_SIZE - skipped, streamSize - position);
 359             assertArrayEquals(g(position, len), read(SEGMENT_SIZE));
 360             position += len;
 361         }
 362     }
 363 
 364     @Test @Ignore
 365     public void testSkipZeroBytes() {
 366         testSkipSmallNumberOfBytes(0);
 367     }
 368 
 369     @Test
 370     public void testSkipMinusOneByte() {
 371         testSkipSmallNumberOfBytes(-1);
 372     }
 373 
 374     @Test
 375     public void testSkipMinusTenBytes() {
 376         testSkipSmallNumberOfBytes(-10);
 377     }
 378 
 379     @Test
 380     public void testSkipIntegerMinValueBytes() {
 381         testSkipSmallNumberOfBytes(Integer.MIN_VALUE);
 382     }
 383 
 384     @Test
 385     public void testSkipSegment() {
 386         append(SEGMENT_SIZE * 2.5);
 387         long skipped = is.skip(SEGMENT_SIZE);
 388         assertEquals(SEGMENT_SIZE, skipped);
 389         assertArrayEquals(g(SEGMENT_SIZE, SEGMENT_SIZE), read(SEGMENT_SIZE));
 390         skipped = is.skip(SEGMENT_SIZE);
 391         assertEquals((long) (SEGMENT_SIZE * 0.5), skipped);
 392         assertArrayEquals(null, read(SEGMENT_SIZE));
 393     }
 394 
 395     @Test
 396     public void testSkipTwoSegments() {
 397         append(SEGMENT_SIZE * 2.5);
 398         long skipped = is.skip(SEGMENT_SIZE * 2);
 399         assertEquals(SEGMENT_SIZE * 2, skipped);
 400         assertArrayEquals(
 401                 g(SEGMENT_SIZE * 2, SEGMENT_SIZE * 0.5),
 402                 read(SEGMENT_SIZE));
 403     }
 404 
 405     @Test
 406     public void testSkipAll() {
 407         append(SEGMENT_SIZE * 2.5);
 408         long skipped = is.skip(SEGMENT_SIZE * 3);
 409         assertEquals((long) (SEGMENT_SIZE * 2.5), skipped);
 410         assertArrayEquals(null, read(10));
 411     }
 412 
 413     @Test
 414     public void testSkipIntegerMaxValueBytes() {
 415         append(SEGMENT_SIZE * 2.5);
 416         long skipped = is.skip(Integer.MAX_VALUE);
 417         assertEquals((long) (SEGMENT_SIZE * 2.5), skipped);
 418         assertArrayEquals(null, read(10));
 419     }
 420 
 421     @Test
 422     public void testSkipLessThanAvailable() {
 423         append(SEGMENT_SIZE * 2.5);
 424         readOut(SEGMENT_SIZE * 2 + 10);
 425         long skipped = is.skip(SEGMENT_SIZE);
 426         assertEquals((long) (SEGMENT_SIZE * 0.5 - 10), skipped);
 427         assertArrayEquals(null, read(10));
 428     }
 429 
 430     @Test
 431     public void testSkipAfterLastByte() {
 432         append(SEGMENT_SIZE * 2.5);
 433         readOut(SEGMENT_SIZE * 2.5);
 434         assertEquals(0, is.skip(10));
 435         assertArrayEquals(null, read(10));
 436     }
 437 
 438     @Test
 439     public void testSkipEmptyBuffer() {
 440         assertEquals(0, is.skip(10));
 441         assertArrayEquals(null, read(10));
 442     }
 443 
 444     @Test
 445     public void testAvailableVariousPositions() {
 446         int streamSize = (int) (SEGMENT_SIZE * 2.5);
 447         append(streamSize);
 448 
 449         assertEquals(streamSize, is.available());
 450 
 451         readOut(1);
 452         streamSize -= 1;
 453         assertEquals(streamSize, is.available());
 454 
 455         readOut(2);
 456         streamSize -= 2;
 457         assertEquals(streamSize, is.available());
 458 
 459         readOut(10);
 460         streamSize -= 10;
 461         assertEquals(streamSize, is.available());
 462 
 463         readOut(SEGMENT_SIZE);
 464         streamSize -= SEGMENT_SIZE;
 465         assertEquals(streamSize, is.available());
 466 
 467         readOut(SEGMENT_SIZE);
 468         streamSize -= SEGMENT_SIZE;
 469         assertEquals(streamSize, is.available());
 470 
 471         read(SEGMENT_SIZE);
 472         assertEquals(0, is.available());
 473     }
 474 
 475     @Test
 476     public void testAvailableRandomPositions() {
 477         int streamSize = (int) (SEGMENT_SIZE * 2.5);
 478         append(streamSize);
 479         while (streamSize > 0) {
 480             int bytesToRead = Math.min(random.nextInt(100), streamSize);
 481             readOut(bytesToRead);
 482             streamSize -= bytesToRead;
 483             assertEquals(streamSize, is.available());
 484         }
 485         assertEquals(0, is.available());
 486     }
 487 
 488     @Test
 489     public void testAvailableAfterLastByte() {
 490         append(SEGMENT_SIZE * 2.5);
 491         readOut(SEGMENT_SIZE * 2.5);
 492         assertEquals(0, is.available());
 493     }
 494 
 495     @Test
 496     public void testAvailableEmptyBuffer() {
 497         assertEquals(0, is.available());
 498     }
 499 
 500     @Test
 501     public void testCloseBeforeFirstRead() throws IOException {
 502         append(SEGMENT_SIZE * 2.5);
 503         is.close();
 504         assertArrayEquals(g(0, SEGMENT_SIZE), read(SEGMENT_SIZE));
 505     }
 506 
 507     @Test
 508     public void testCloseEmptyBuffer() throws IOException {
 509         is.close();
 510         is.close();
 511         assertArrayEquals(null, read(SEGMENT_SIZE));
 512     }
 513 
 514     @Test
 515     public void testMarkVariousArguments() throws IOException {
 516         append(SEGMENT_SIZE * 2.5);
 517         int[] args = new int[] {-1000, -100, -1, 0, 1, 10, 100, 1000};
 518         for (int arg : args) {
 519             is.mark(arg);
 520         }
 521         readOut(1000);
 522         for (int arg : args) {
 523             is.mark(arg);
 524         }
 525     }
 526 
 527     @Test
 528     public void testMarkRandomArguments() throws IOException {
 529         append(SEGMENT_SIZE * 2.5);
 530         for (int i = 0; i < 100; i++) {
 531             is.mark(random.nextInt());
 532         }
 533         readOut(1000);
 534         for (int i = 0; i < 100; i++) {
 535             is.mark(random.nextInt());
 536         }
 537     }
 538 
 539     @Test
 540     public void testReset() {
 541         try {
 542             is.reset();
 543             fail("IOException expected but not thrown");
 544         } catch (IOException expected) {}
 545     }
 546 
 547     @Test
 548     public void testMarkSupported() {
 549         assertFalse(is.markSupported());
 550     }
 551 
 552 
 553     @After
 554     public void after() {
 555         sb.dispose();
 556     }
 557 
 558     private void append(double length) {
 559         byte[] data = g(0, (int) length);
 560         sb.append(data, 0, data.length);
 561     }
 562 
 563     private void readOut(double length) {
 564         int intLength = (int) length;
 565         byte[] buffer = new byte[intLength];
 566         while (intLength > 0) {
 567             int len = is.read(buffer, 0, intLength);
 568             if (len == -1) {
 569                 fail("Unexpected end of stream");
 570             }
 571             intLength -= len;
 572         }
 573     }
 574 
 575     private static byte[] g(double start, double count) {
 576         int intCount = (int) count;
 577         byte[] result = new byte[intCount];
 578         for (int i = 0; i < intCount; i++) {
 579             result[i] = (byte) ((i + (int) start) & 0xff);
 580         }
 581         return result;
 582     }
 583 
 584     private byte[] read(int length) {
 585         int offset = random.nextBoolean() ? random.nextInt(100) : 0;
 586         int extraLength = random.nextBoolean() ? random.nextInt(200) : 0;
 587         byte[] buffer = g(0, offset + length + extraLength);
 588         int len = is.read(buffer, offset, length);
 589         if (length == 0) {
 590             assertEquals("Unexpected len", 0, len);
 591         }
 592         if (len == -1) {
 593             for (int i = 0; i < buffer.length; i++) {
 594                 assertEquals((byte) (i & 0xff), buffer[i]);
 595             }
 596             return null;
 597         }
 598         assertTrue("Unexpected len: " + len, len >= 0);
 599         for (int i = 0; i < offset; i++) {
 600             assertEquals((byte) (i & 0xff), buffer[i]);
 601         }
 602         for (int i = offset + len; i < buffer.length; i++) {
 603             assertEquals((byte) (i & 0xff), buffer[i]);
 604         }
 605         byte[] result = new byte[len];
 606         System.arraycopy(buffer, offset, result, 0, len);
 607         return result;
 608     }
 609 }