< prev index next >

test/jdk/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/BinaryPrimitivesTest.java

Print this page


   1 /*
   2  * Copyright (c) 2014, 2016, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package jdk.incubator.http.internal.hpack;
  24 
  25 import org.testng.annotations.Test;
  26 


  27 import java.nio.ByteBuffer;
  28 import java.nio.CharBuffer;
  29 import java.nio.charset.StandardCharsets;
  30 import java.util.ArrayList;
  31 import java.util.List;
  32 import java.util.Random;
  33 
  34 import static org.testng.Assert.assertEquals;
  35 import static org.testng.Assert.fail;
  36 import static jdk.incubator.http.internal.hpack.BuffersTestingKit.*;
  37 import static jdk.incubator.http.internal.hpack.TestHelper.newRandom;
  38 
  39 //
  40 // Some of the tests below overlap in what they test. This allows to diagnose
  41 // bugs quicker and with less pain by simply ruling out common working bits.
  42 //
  43 public final class BinaryPrimitivesTest {
  44 
  45     private final Random rnd = newRandom();
  46 


  63     public void integerWrite1() {
  64         verifyWrite(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
  65     }
  66 
  67     @Test
  68     public void integerWrite2() {
  69         verifyWrite(bytes(0b00001010), 10, 5);
  70     }
  71 
  72     @Test
  73     public void integerWrite3() {
  74         verifyWrite(bytes(0b00101010), 42, 8);
  75     }
  76 
  77     //
  78     // Since readInteger(x) is the inverse of writeInteger(x), thus:
  79     //
  80     // for all x: readInteger(writeInteger(x)) == x
  81     //
  82     @Test
  83     public void integerIdentity() {
  84         final int MAX_VALUE = 1 << 22;
  85         int totalCases = 0;
  86         int maxFilling = 0;
  87         IntegerReader r = new IntegerReader();
  88         IntegerWriter w = new IntegerWriter();
  89         ByteBuffer buf = ByteBuffer.allocate(8);
  90         for (int N = 1; N < 9; N++) {
  91             for (int expected = 0; expected <= MAX_VALUE; expected++) {
  92                 w.reset().configure(expected, N, 1).write(buf);
  93                 buf.flip();
  94                 totalCases++;
  95                 maxFilling = Math.max(maxFilling, buf.remaining());
  96                 r.reset().configure(N).read(buf);
  97                 assertEquals(r.get(), expected);
  98                 buf.clear();
  99             }
 100         }
 101         System.out.printf("totalCases: %,d, maxFilling: %,d, maxValue: %,d%n",
 102                 totalCases, maxFilling, MAX_VALUE);
 103     }
 104 
 105     @Test
 106     public void integerReadChunked() {
 107         final int NUM_TESTS = 1024;
 108         IntegerReader r = new IntegerReader();
 109         ByteBuffer bb = ByteBuffer.allocate(8);
 110         IntegerWriter w = new IntegerWriter();
 111         for (int i = 0; i < NUM_TESTS; i++) {
 112             final int N = 1 + rnd.nextInt(8);
 113             final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
 114             w.reset().configure(expected, N, rnd.nextInt()).write(bb);
 115             bb.flip();
 116 
 117             forEachSplit(bb,
 118                     (buffers) -> {
 119                         Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
 120                         r.configure(N);
 121                         for (ByteBuffer b : buf) {

 122                             r.read(b);



 123                         }
 124                         assertEquals(r.get(), expected);
 125                         r.reset();
 126                     });
 127             bb.clear();
 128         }
 129     }
 130 
 131     // FIXME: use maxValue in the test
 132 
 133     @Test
 134     // FIXME: tune values for better coverage
 135     public void integerWriteChunked() {
 136         ByteBuffer bb = ByteBuffer.allocate(6);
 137         IntegerWriter w = new IntegerWriter();
 138         IntegerReader r = new IntegerReader();
 139         for (int i = 0; i < 1024; i++) { // number of tests
 140             final int N = 1 + rnd.nextInt(8);
 141             final int payload = rnd.nextInt(255);
 142             final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
 143 
 144             forEachSplit(bb,
 145                     (buffers) -> {
 146                         List<ByteBuffer> buf = new ArrayList<>();
 147                         relocateBuffers(injectEmptyBuffers(buffers)).forEach(buf::add);
 148                         boolean written = false;
 149                         w.configure(expected, N, payload); // TODO: test for payload it can be read after written
 150                         for (ByteBuffer b : buf) {
 151                             int pos = b.position();
 152                             written = w.write(b);
 153                             b.position(pos);
 154                         }
 155                         if (!written) {
 156                             fail("please increase bb size");
 157                         }

 158                         r.configure(N).read(concat(buf));



 159                         // TODO: check payload here
 160                         assertEquals(r.get(), expected);
 161                         w.reset();
 162                         r.reset();
 163                         bb.clear();
 164                     });
 165         }
 166     }
 167 
 168 
 169     //
 170     // Since readString(x) is the inverse of writeString(x), thus:
 171     //
 172     // for all x: readString(writeString(x)) == x
 173     //
 174     @Test
 175     public void stringIdentity() {
 176         final int MAX_STRING_LENGTH = 4096;
 177         ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6); // it takes 6 bytes to encode string length of Integer.MAX_VALUE
 178         CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
 179         StringReader reader = new StringReader();
 180         StringWriter writer = new StringWriter();
 181         for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
 182             for (int i = 0; i < 64; i++) {
 183                 // not so much "test in isolation", I know... we're testing .reset() as well
 184                 bytes.clear();
 185                 chars.clear();
 186 
 187                 byte[] b = new byte[len];
 188                 rnd.nextBytes(b);
 189 
 190                 String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
 191 
 192                 boolean written = writer
 193                         .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
 194                         .write(bytes);
 195 


 224         final StringReader reader = new StringReader();
 225         final StringWriter writer = new StringWriter();
 226         for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
 227 
 228             byte[] b = new byte[len];
 229             rnd.nextBytes(b);
 230 
 231             String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
 232 
 233             forEachSplit(bytes, (buffers) -> {
 234                 writer.configure(expected, 0, expected.length(), false);
 235                 boolean written = false;
 236                 for (ByteBuffer buf : buffers) {
 237                     int p0 = buf.position();
 238                     written = writer.write(buf);
 239                     buf.position(p0);
 240                 }
 241                 if (!written) {
 242                     fail("please increase 'bytes' size");
 243                 }

 244                 reader.read(concat(buffers), chars);



 245                 chars.flip();
 246                 assertEquals(chars.toString(), expected);
 247                 reader.reset();
 248                 writer.reset();
 249                 chars.clear();
 250                 bytes.clear();
 251             });
 252         }
 253     }
 254 
 255     @Test
 256     public void stringReadChunked() {
 257         final int MAX_STRING_LENGTH = 16;
 258         final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
 259         final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
 260         final StringReader reader = new StringReader();
 261         final StringWriter writer = new StringWriter();
 262         for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
 263 
 264             byte[] b = new byte[len];
 265             rnd.nextBytes(b);
 266 
 267             String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
 268 
 269             boolean written = writer
 270                     .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
 271                     .write(bytes);
 272             writer.reset();
 273 
 274             if (!written) {
 275                 fail("please increase 'bytes' size");
 276             }
 277             bytes.flip();
 278 
 279             forEachSplit(bytes, (buffers) -> {
 280                 for (ByteBuffer buf : buffers) {
 281                     int p0 = buf.position();

 282                     reader.read(buf, chars);



 283                     buf.position(p0);
 284                 }
 285                 chars.flip();
 286                 assertEquals(chars.toString(), expected);
 287                 reader.reset();
 288                 chars.clear();
 289             });
 290 
 291             bytes.clear();
 292         }
 293     }
 294 
 295 //    @Test
 296 //    public void test_Huffman_String_Identity() {
 297 //        StringWriter writer = new StringWriter();
 298 //        StringReader reader = new StringReader();
 299 //        // 256 * 8 gives 2048 bits in case of plain 8 bit coding
 300 //        // 256 * 30 gives you 7680 bits or 960 bytes in case of almost
 301 //        //          improbable event of 256 30 bits symbols in a row
 302 //        ByteBuffer binary = ByteBuffer.allocate(960);


 316 //                reader.read(binary, text);
 317 //                text.flip();
 318 //                assertEquals(text.toString(), s);
 319 //            }
 320 //        }
 321 //    }
 322 
 323     // TODO: atomic failures: e.g. readonly/overflow
 324 
 325     private static byte[] bytes(int... data) {
 326         byte[] bytes = new byte[data.length];
 327         for (int i = 0; i < data.length; i++) {
 328             bytes[i] = (byte) data[i];
 329         }
 330         return bytes;
 331     }
 332 
 333     private static void verifyRead(byte[] data, int expected, int N) {
 334         ByteBuffer buf = ByteBuffer.wrap(data, 0, data.length);
 335         IntegerReader reader = new IntegerReader();

 336         reader.configure(N).read(buf);



 337         assertEquals(expected, reader.get());
 338     }
 339 
 340     private void verifyWrite(byte[] expected, int data, int N) {
 341         IntegerWriter w = new IntegerWriter();
 342         ByteBuffer buf = ByteBuffer.allocate(2 * expected.length);
 343         w.configure(data, N, 1).write(buf);
 344         buf.flip();
 345         assertEquals(ByteBuffer.wrap(expected), buf);
 346     }
 347 }
   1 /*
   2  * Copyright (c) 2014, 2017, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package jdk.incubator.http.internal.hpack;
  24 
  25 import org.testng.annotations.Test;
  26 
  27 import java.io.IOException;
  28 import java.io.UncheckedIOException;
  29 import java.nio.ByteBuffer;
  30 import java.nio.CharBuffer;
  31 import java.nio.charset.StandardCharsets;
  32 import java.util.ArrayList;
  33 import java.util.List;
  34 import java.util.Random;
  35 
  36 import static org.testng.Assert.assertEquals;
  37 import static org.testng.Assert.fail;
  38 import static jdk.incubator.http.internal.hpack.BuffersTestingKit.*;
  39 import static jdk.incubator.http.internal.hpack.TestHelper.newRandom;
  40 
  41 //
  42 // Some of the tests below overlap in what they test. This allows to diagnose
  43 // bugs quicker and with less pain by simply ruling out common working bits.
  44 //
  45 public final class BinaryPrimitivesTest {
  46 
  47     private final Random rnd = newRandom();
  48 


  65     public void integerWrite1() {
  66         verifyWrite(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
  67     }
  68 
  69     @Test
  70     public void integerWrite2() {
  71         verifyWrite(bytes(0b00001010), 10, 5);
  72     }
  73 
  74     @Test
  75     public void integerWrite3() {
  76         verifyWrite(bytes(0b00101010), 42, 8);
  77     }
  78 
  79     //
  80     // Since readInteger(x) is the inverse of writeInteger(x), thus:
  81     //
  82     // for all x: readInteger(writeInteger(x)) == x
  83     //
  84     @Test
  85     public void integerIdentity() throws IOException {
  86         final int MAX_VALUE = 1 << 22;
  87         int totalCases = 0;
  88         int maxFilling = 0;
  89         IntegerReader r = new IntegerReader();
  90         IntegerWriter w = new IntegerWriter();
  91         ByteBuffer buf = ByteBuffer.allocate(8);
  92         for (int N = 1; N < 9; N++) {
  93             for (int expected = 0; expected <= MAX_VALUE; expected++) {
  94                 w.reset().configure(expected, N, 1).write(buf);
  95                 buf.flip();
  96                 totalCases++;
  97                 maxFilling = Math.max(maxFilling, buf.remaining());
  98                 r.reset().configure(N).read(buf);
  99                 assertEquals(r.get(), expected);
 100                 buf.clear();
 101             }
 102         }
 103         System.out.printf("totalCases: %,d, maxFilling: %,d, maxValue: %,d%n",
 104                 totalCases, maxFilling, MAX_VALUE);
 105     }
 106 
 107     @Test
 108     public void integerReadChunked() {
 109         final int NUM_TESTS = 1024;
 110         IntegerReader r = new IntegerReader();
 111         ByteBuffer bb = ByteBuffer.allocate(8);
 112         IntegerWriter w = new IntegerWriter();
 113         for (int i = 0; i < NUM_TESTS; i++) {
 114             final int N = 1 + rnd.nextInt(8);
 115             final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
 116             w.reset().configure(expected, N, rnd.nextInt()).write(bb);
 117             bb.flip();
 118 
 119             forEachSplit(bb,
 120                     (buffers) -> {
 121                         Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
 122                         r.configure(N);
 123                         for (ByteBuffer b : buf) {
 124                             try {
 125                                 r.read(b);
 126                             } catch (IOException e) {
 127                                 throw new UncheckedIOException(e);
 128                             }
 129                         }
 130                         assertEquals(r.get(), expected);
 131                         r.reset();
 132                     });
 133             bb.clear();
 134         }
 135     }
 136 
 137     // FIXME: use maxValue in the test
 138 
 139     @Test
 140     // FIXME: tune values for better coverage
 141     public void integerWriteChunked() {
 142         ByteBuffer bb = ByteBuffer.allocate(6);
 143         IntegerWriter w = new IntegerWriter();
 144         IntegerReader r = new IntegerReader();
 145         for (int i = 0; i < 1024; i++) { // number of tests
 146             final int N = 1 + rnd.nextInt(8);
 147             final int payload = rnd.nextInt(255);
 148             final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
 149 
 150             forEachSplit(bb,
 151                     (buffers) -> {
 152                         List<ByteBuffer> buf = new ArrayList<>();
 153                         relocateBuffers(injectEmptyBuffers(buffers)).forEach(buf::add);
 154                         boolean written = false;
 155                         w.configure(expected, N, payload); // TODO: test for payload it can be read after written
 156                         for (ByteBuffer b : buf) {
 157                             int pos = b.position();
 158                             written = w.write(b);
 159                             b.position(pos);
 160                         }
 161                         if (!written) {
 162                             fail("please increase bb size");
 163                         }
 164                         try {
 165                             r.configure(N).read(concat(buf));
 166                         } catch (IOException e) {
 167                             throw new UncheckedIOException(e);
 168                         }
 169                         // TODO: check payload here
 170                         assertEquals(r.get(), expected);
 171                         w.reset();
 172                         r.reset();
 173                         bb.clear();
 174                     });
 175         }
 176     }
 177 
 178 
 179     //
 180     // Since readString(x) is the inverse of writeString(x), thus:
 181     //
 182     // for all x: readString(writeString(x)) == x
 183     //
 184     @Test
 185     public void stringIdentity() throws IOException {
 186         final int MAX_STRING_LENGTH = 4096;
 187         ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6); // it takes 6 bytes to encode string length of Integer.MAX_VALUE
 188         CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
 189         StringReader reader = new StringReader();
 190         StringWriter writer = new StringWriter();
 191         for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
 192             for (int i = 0; i < 64; i++) {
 193                 // not so much "test in isolation", I know... we're testing .reset() as well
 194                 bytes.clear();
 195                 chars.clear();
 196 
 197                 byte[] b = new byte[len];
 198                 rnd.nextBytes(b);
 199 
 200                 String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
 201 
 202                 boolean written = writer
 203                         .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
 204                         .write(bytes);
 205 


 234         final StringReader reader = new StringReader();
 235         final StringWriter writer = new StringWriter();
 236         for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
 237 
 238             byte[] b = new byte[len];
 239             rnd.nextBytes(b);
 240 
 241             String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
 242 
 243             forEachSplit(bytes, (buffers) -> {
 244                 writer.configure(expected, 0, expected.length(), false);
 245                 boolean written = false;
 246                 for (ByteBuffer buf : buffers) {
 247                     int p0 = buf.position();
 248                     written = writer.write(buf);
 249                     buf.position(p0);
 250                 }
 251                 if (!written) {
 252                     fail("please increase 'bytes' size");
 253                 }
 254                 try {
 255                     reader.read(concat(buffers), chars);
 256                 } catch (IOException e) {
 257                     throw new UncheckedIOException(e);
 258                 }
 259                 chars.flip();
 260                 assertEquals(chars.toString(), expected);
 261                 reader.reset();
 262                 writer.reset();
 263                 chars.clear();
 264                 bytes.clear();
 265             });
 266         }
 267     }
 268 
 269     @Test
 270     public void stringReadChunked() {
 271         final int MAX_STRING_LENGTH = 16;
 272         final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
 273         final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
 274         final StringReader reader = new StringReader();
 275         final StringWriter writer = new StringWriter();
 276         for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
 277 
 278             byte[] b = new byte[len];
 279             rnd.nextBytes(b);
 280 
 281             String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
 282 
 283             boolean written = writer
 284                     .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
 285                     .write(bytes);
 286             writer.reset();
 287 
 288             if (!written) {
 289                 fail("please increase 'bytes' size");
 290             }
 291             bytes.flip();
 292 
 293             forEachSplit(bytes, (buffers) -> {
 294                 for (ByteBuffer buf : buffers) {
 295                     int p0 = buf.position();
 296                     try {
 297                         reader.read(buf, chars);
 298                     } catch (IOException e) {
 299                         throw new UncheckedIOException(e);
 300                     }
 301                     buf.position(p0);
 302                 }
 303                 chars.flip();
 304                 assertEquals(chars.toString(), expected);
 305                 reader.reset();
 306                 chars.clear();
 307             });
 308 
 309             bytes.clear();
 310         }
 311     }
 312 
 313 //    @Test
 314 //    public void test_Huffman_String_Identity() {
 315 //        StringWriter writer = new StringWriter();
 316 //        StringReader reader = new StringReader();
 317 //        // 256 * 8 gives 2048 bits in case of plain 8 bit coding
 318 //        // 256 * 30 gives you 7680 bits or 960 bytes in case of almost
 319 //        //          improbable event of 256 30 bits symbols in a row
 320 //        ByteBuffer binary = ByteBuffer.allocate(960);


 334 //                reader.read(binary, text);
 335 //                text.flip();
 336 //                assertEquals(text.toString(), s);
 337 //            }
 338 //        }
 339 //    }
 340 
 341     // TODO: atomic failures: e.g. readonly/overflow
 342 
 343     private static byte[] bytes(int... data) {
 344         byte[] bytes = new byte[data.length];
 345         for (int i = 0; i < data.length; i++) {
 346             bytes[i] = (byte) data[i];
 347         }
 348         return bytes;
 349     }
 350 
 351     private static void verifyRead(byte[] data, int expected, int N) {
 352         ByteBuffer buf = ByteBuffer.wrap(data, 0, data.length);
 353         IntegerReader reader = new IntegerReader();
 354         try {
 355             reader.configure(N).read(buf);
 356         } catch (IOException e) {
 357             throw new UncheckedIOException(e);
 358         }
 359         assertEquals(expected, reader.get());
 360     }
 361 
 362     private void verifyWrite(byte[] expected, int data, int N) {
 363         IntegerWriter w = new IntegerWriter();
 364         ByteBuffer buf = ByteBuffer.allocate(2 * expected.length);
 365         w.configure(data, N, 1).write(buf);
 366         buf.flip();
 367         assertEquals(ByteBuffer.wrap(expected), buf);
 368     }
 369 }
< prev index next >