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