~ubuntu-branches/debian/experimental/protobuf/experimental

« back to all changes in this revision

Viewing changes to java/src/test/java/com/google/protobuf/LiteralByteStringTest.java

  • Committer: Package Import Robot
  • Author(s): Robert S. Edmonds, Micah Anderson, Colin Watson, Steve Langasek, Robert S. Edmonds
  • Date: 2013-10-12 18:32:37 UTC
  • mfrom: (1.3.1) (10.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20131012183237-jz6tvmj9tn68atrf
Tags: 2.5.0-1
[ Micah Anderson ]
* New upstream version. (Closes: #704731.)
* Update debian/watch.
* Refresh patches.

[ Colin Watson ]
* Use the autotools-dev dh addon to update config.guess/config.sub for
  arm64. (Closes: #725976.)

[ Steve Langasek ]
* Don't recommend protobuf-compiler from the bindings, it's not used and
  this doesn't need to be pulled in at runtime. (Closes: #703628.)
* Mark protobuf-compiler Multi-Arch: foreign; the output of this command
  is architecture-independent source, we don't need the version of the
  compiler to match the target arch.
* Bump to debhelper compat 9, so that our libs get installed to the
  multiarch locations.
* Mark the library packages Multi-Arch: same.
* Fix debian/rules to support cross-building of the python bindings.
* Build-depend on libpython-dev, not python-dev, for cross-build
  compatibility.
* (Closes: #726083.)

[ Robert S. Edmonds ]
* Upload to experimental.
* Bump ABI version from 7 to 8.
* Bump Standards-Version to 3.9.4.
* Convert from python-support to dh-python.
* Drop support for python2.6.
* python-protobuf: switch back to the pure Python implementation, as
  upstream appears to no longer be maintaining the current C++ based Python
  binding. See the following upstream issues for details:
  - https://code.google.com/p/protobuf/issues/detail?id=434
  - https://code.google.com/p/protobuf/issues/detail?id=503

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Protocol Buffers - Google's data interchange format
 
2
// Copyright 2008 Google Inc.  All rights reserved.
 
3
// http://code.google.com/p/protobuf/
 
4
//
 
5
// Redistribution and use in source and binary forms, with or without
 
6
// modification, are permitted provided that the following conditions are
 
7
// met:
 
8
//
 
9
//     * Redistributions of source code must retain the above copyright
 
10
// notice, this list of conditions and the following disclaimer.
 
11
//     * Redistributions in binary form must reproduce the above
 
12
// copyright notice, this list of conditions and the following disclaimer
 
13
// in the documentation and/or other materials provided with the
 
14
// distribution.
 
15
//     * Neither the name of Google Inc. nor the names of its
 
16
// contributors may be used to endorse or promote products derived from
 
17
// this software without specific prior written permission.
 
18
//
 
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
30
 
 
31
package com.google.protobuf;
 
32
 
 
33
import junit.framework.TestCase;
 
34
 
 
35
import java.io.ByteArrayOutputStream;
 
36
import java.io.IOException;
 
37
import java.io.InputStream;
 
38
import java.io.OutputStream;
 
39
import java.io.UnsupportedEncodingException;
 
40
import java.nio.ByteBuffer;
 
41
import java.util.Arrays;
 
42
import java.util.List;
 
43
import java.util.NoSuchElementException;
 
44
 
 
45
/**
 
46
 * Test {@link LiteralByteString} by setting up a reference string in {@link #setUp()}.
 
47
 * This class is designed to be extended for testing extensions of {@link LiteralByteString}
 
48
 * such as {@link BoundedByteString}, see {@link BoundedByteStringTest}.
 
49
 *
 
50
 * @author carlanton@google.com (Carl Haverl)
 
51
 */
 
52
public class LiteralByteStringTest extends TestCase {
 
53
  protected static final String UTF_8 = "UTF-8";
 
54
 
 
55
  protected String classUnderTest;
 
56
  protected byte[] referenceBytes;
 
57
  protected ByteString stringUnderTest;
 
58
  protected int expectedHashCode;
 
59
 
 
60
  @Override
 
61
  protected void setUp() throws Exception {
 
62
    classUnderTest = "LiteralByteString";
 
63
    referenceBytes = ByteStringTest.getTestBytes(1234, 11337766L);
 
64
    stringUnderTest = ByteString.copyFrom(referenceBytes);
 
65
    expectedHashCode = 331161852;
 
66
  }
 
67
 
 
68
  public void testExpectedType() {
 
69
    String actualClassName = getActualClassName(stringUnderTest);
 
70
    assertEquals(classUnderTest + " should match type exactly", classUnderTest, actualClassName);
 
71
  }
 
72
 
 
73
  protected String getActualClassName(Object object) {
 
74
    String actualClassName = object.getClass().getName();
 
75
    actualClassName = actualClassName.substring(actualClassName.lastIndexOf('.') + 1);
 
76
    return actualClassName;
 
77
  }
 
78
 
 
79
  public void testByteAt() {
 
80
    boolean stillEqual = true;
 
81
    for (int i = 0; stillEqual && i < referenceBytes.length; ++i) {
 
82
      stillEqual = (referenceBytes[i] == stringUnderTest.byteAt(i));
 
83
    }
 
84
    assertTrue(classUnderTest + " must capture the right bytes", stillEqual);
 
85
  }
 
86
 
 
87
  public void testByteIterator() {
 
88
    boolean stillEqual = true;
 
89
    ByteString.ByteIterator iter = stringUnderTest.iterator();
 
90
    for (int i = 0; stillEqual && i < referenceBytes.length; ++i) {
 
91
      stillEqual = (iter.hasNext() && referenceBytes[i] == iter.nextByte());
 
92
    }
 
93
    assertTrue(classUnderTest + " must capture the right bytes", stillEqual);
 
94
    assertFalse(classUnderTest + " must have exhausted the itertor", iter.hasNext());
 
95
 
 
96
    try {
 
97
      iter.nextByte();
 
98
      fail("Should have thrown an exception.");
 
99
    } catch (NoSuchElementException e) {
 
100
      // This is success
 
101
    }
 
102
  }
 
103
 
 
104
  public void testByteIterable() {
 
105
    boolean stillEqual = true;
 
106
    int j = 0;
 
107
    for (byte quantum : stringUnderTest) {
 
108
      stillEqual = (referenceBytes[j] == quantum);
 
109
      ++j;
 
110
    }
 
111
    assertTrue(classUnderTest + " must capture the right bytes as Bytes", stillEqual);
 
112
    assertEquals(classUnderTest + " iterable character count", referenceBytes.length, j);
 
113
  }
 
114
 
 
115
  public void testSize() {
 
116
    assertEquals(classUnderTest + " must have the expected size", referenceBytes.length,
 
117
        stringUnderTest.size());
 
118
  }
 
119
 
 
120
  public void testGetTreeDepth() {
 
121
    assertEquals(classUnderTest + " must have depth 0", 0, stringUnderTest.getTreeDepth());
 
122
  }
 
123
 
 
124
  public void testIsBalanced() {
 
125
    assertTrue(classUnderTest + " is technically balanced", stringUnderTest.isBalanced());
 
126
  }
 
127
 
 
128
  public void testCopyTo_ByteArrayOffsetLength() {
 
129
    int destinationOffset = 50;
 
130
    int length = 100;
 
131
    byte[] destination = new byte[destinationOffset + length];
 
132
    int sourceOffset = 213;
 
133
    stringUnderTest.copyTo(destination, sourceOffset, destinationOffset, length);
 
134
    boolean stillEqual = true;
 
135
    for (int i = 0; stillEqual && i < length; ++i) {
 
136
      stillEqual = referenceBytes[i + sourceOffset] == destination[i + destinationOffset];
 
137
    }
 
138
    assertTrue(classUnderTest + ".copyTo(4 arg) must give the expected bytes", stillEqual);
 
139
  }
 
140
 
 
141
  public void testCopyTo_ByteArrayOffsetLengthErrors() {
 
142
    int destinationOffset = 50;
 
143
    int length = 100;
 
144
    byte[] destination = new byte[destinationOffset + length];
 
145
 
 
146
    try {
 
147
      // Copy one too many bytes
 
148
      stringUnderTest.copyTo(destination, stringUnderTest.size() + 1 - length,
 
149
          destinationOffset, length);
 
150
      fail("Should have thrown an exception when copying too many bytes of a "
 
151
          + classUnderTest);
 
152
    } catch (IndexOutOfBoundsException expected) {
 
153
      // This is success
 
154
    }
 
155
 
 
156
    try {
 
157
      // Copy with illegal negative sourceOffset
 
158
      stringUnderTest.copyTo(destination, -1, destinationOffset, length);
 
159
      fail("Should have thrown an exception when given a negative sourceOffset in "
 
160
          + classUnderTest);
 
161
    } catch (IndexOutOfBoundsException expected) {
 
162
      // This is success
 
163
    }
 
164
 
 
165
    try {
 
166
      // Copy with illegal negative destinationOffset
 
167
      stringUnderTest.copyTo(destination, 0, -1, length);
 
168
      fail("Should have thrown an exception when given a negative destinationOffset in "
 
169
          + classUnderTest);
 
170
    } catch (IndexOutOfBoundsException expected) {
 
171
      // This is success
 
172
    }
 
173
 
 
174
    try {
 
175
      // Copy with illegal negative size
 
176
      stringUnderTest.copyTo(destination, 0, 0, -1);
 
177
      fail("Should have thrown an exception when given a negative size in "
 
178
          + classUnderTest);
 
179
    } catch (IndexOutOfBoundsException expected) {
 
180
      // This is success
 
181
    }
 
182
 
 
183
    try {
 
184
      // Copy with illegal too-large sourceOffset
 
185
      stringUnderTest.copyTo(destination, 2 * stringUnderTest.size(), 0, length);
 
186
      fail("Should have thrown an exception when the destinationOffset is too large in "
 
187
          + classUnderTest);
 
188
    } catch (IndexOutOfBoundsException expected) {
 
189
      // This is success
 
190
    }
 
191
 
 
192
    try {
 
193
      // Copy with illegal too-large destinationOffset
 
194
      stringUnderTest.copyTo(destination, 0, 2 * destination.length, length);
 
195
      fail("Should have thrown an exception when the destinationOffset is too large in "
 
196
          + classUnderTest);
 
197
    } catch (IndexOutOfBoundsException expected) {
 
198
      // This is success
 
199
    }
 
200
  }
 
201
 
 
202
  public void testCopyTo_ByteBuffer() {
 
203
    ByteBuffer myBuffer = ByteBuffer.allocate(referenceBytes.length);
 
204
    stringUnderTest.copyTo(myBuffer);
 
205
    assertTrue(classUnderTest + ".copyTo(ByteBuffer) must give back the same bytes",
 
206
        Arrays.equals(referenceBytes, myBuffer.array()));
 
207
  }
 
208
 
 
209
  public void testAsReadOnlyByteBuffer() {
 
210
    ByteBuffer byteBuffer = stringUnderTest.asReadOnlyByteBuffer();
 
211
    byte[] roundTripBytes = new byte[referenceBytes.length];
 
212
    assertTrue(byteBuffer.remaining() == referenceBytes.length);
 
213
    assertTrue(byteBuffer.isReadOnly());
 
214
    byteBuffer.get(roundTripBytes);
 
215
    assertTrue(classUnderTest + ".asReadOnlyByteBuffer() must give back the same bytes",
 
216
        Arrays.equals(referenceBytes, roundTripBytes));
 
217
  }
 
218
 
 
219
  public void testAsReadOnlyByteBufferList() {
 
220
    List<ByteBuffer> byteBuffers = stringUnderTest.asReadOnlyByteBufferList();
 
221
    int bytesSeen = 0;
 
222
    byte[] roundTripBytes = new byte[referenceBytes.length];
 
223
    for (ByteBuffer byteBuffer : byteBuffers) {
 
224
      int thisLength = byteBuffer.remaining();
 
225
      assertTrue(byteBuffer.isReadOnly());
 
226
      assertTrue(bytesSeen + thisLength <= referenceBytes.length);
 
227
      byteBuffer.get(roundTripBytes, bytesSeen, thisLength);
 
228
      bytesSeen += thisLength;
 
229
    }
 
230
    assertTrue(bytesSeen == referenceBytes.length);
 
231
    assertTrue(classUnderTest + ".asReadOnlyByteBufferTest() must give back the same bytes",
 
232
        Arrays.equals(referenceBytes, roundTripBytes));
 
233
  }
 
234
 
 
235
  public void testToByteArray() {
 
236
    byte[] roundTripBytes = stringUnderTest.toByteArray();
 
237
    assertTrue(classUnderTest + ".toByteArray() must give back the same bytes",
 
238
        Arrays.equals(referenceBytes, roundTripBytes));
 
239
  }
 
240
 
 
241
  public void testWriteTo() throws IOException {
 
242
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
243
    stringUnderTest.writeTo(bos);
 
244
    byte[] roundTripBytes = bos.toByteArray();
 
245
    assertTrue(classUnderTest + ".writeTo() must give back the same bytes",
 
246
        Arrays.equals(referenceBytes, roundTripBytes));
 
247
  }
 
248
  
 
249
  public void testWriteTo_mutating() throws IOException {
 
250
    OutputStream os = new OutputStream() {
 
251
      @Override
 
252
      public void write(byte[] b, int off, int len) {
 
253
        for (int x = 0; x < len; ++x) {
 
254
          b[off + x] = (byte) 0;
 
255
        }
 
256
      }
 
257
 
 
258
      @Override
 
259
      public void write(int b) {
 
260
        // Purposefully left blank.
 
261
      }
 
262
    };
 
263
 
 
264
    stringUnderTest.writeTo(os);
 
265
    byte[] newBytes = stringUnderTest.toByteArray();
 
266
    assertTrue(classUnderTest + ".writeTo() must not grant access to underlying array",
 
267
        Arrays.equals(referenceBytes, newBytes));
 
268
  }
 
269
 
 
270
  public void testNewOutput() throws IOException {
 
271
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
272
    ByteString.Output output = ByteString.newOutput();
 
273
    stringUnderTest.writeTo(output);
 
274
    assertEquals("Output Size returns correct result",
 
275
        output.size(), stringUnderTest.size());
 
276
    output.writeTo(bos);
 
277
    assertTrue("Output.writeTo() must give back the same bytes",
 
278
        Arrays.equals(referenceBytes, bos.toByteArray()));
 
279
 
 
280
    // write the output stream to itself! This should cause it to double
 
281
    output.writeTo(output);
 
282
    assertEquals("Writing an output stream to itself is successful",
 
283
        stringUnderTest.concat(stringUnderTest), output.toByteString());
 
284
 
 
285
    output.reset();
 
286
    assertEquals("Output.reset() resets the output", 0, output.size());
 
287
    assertEquals("Output.reset() resets the output",
 
288
        ByteString.EMPTY, output.toByteString());
 
289
    
 
290
  }
 
291
 
 
292
  public void testToString() throws UnsupportedEncodingException {
 
293
    String testString = "I love unicode \u1234\u5678 characters";
 
294
    LiteralByteString unicode = new LiteralByteString(testString.getBytes(UTF_8));
 
295
    String roundTripString = unicode.toString(UTF_8);
 
296
    assertEquals(classUnderTest + " unicode must match", testString, roundTripString);
 
297
  }
 
298
 
 
299
  public void testEquals() {
 
300
    assertEquals(classUnderTest + " must not equal null", false, stringUnderTest.equals(null));
 
301
    assertEquals(classUnderTest + " must equal self", stringUnderTest, stringUnderTest);
 
302
    assertFalse(classUnderTest + " must not equal the empty string",
 
303
        stringUnderTest.equals(ByteString.EMPTY));
 
304
    assertEquals(classUnderTest + " empty strings must be equal",
 
305
        new LiteralByteString(new byte[]{}), stringUnderTest.substring(55, 55));
 
306
    assertEquals(classUnderTest + " must equal another string with the same value",
 
307
        stringUnderTest, new LiteralByteString(referenceBytes));
 
308
 
 
309
    byte[] mungedBytes = new byte[referenceBytes.length];
 
310
    System.arraycopy(referenceBytes, 0, mungedBytes, 0, referenceBytes.length);
 
311
    mungedBytes[mungedBytes.length - 5] ^= 0xFF;
 
312
    assertFalse(classUnderTest + " must not equal every string with the same length",
 
313
        stringUnderTest.equals(new LiteralByteString(mungedBytes)));
 
314
  }
 
315
 
 
316
  public void testHashCode() {
 
317
    int hash = stringUnderTest.hashCode();
 
318
    assertEquals(classUnderTest + " must have expected hashCode", expectedHashCode, hash);
 
319
  }
 
320
 
 
321
  public void testPeekCachedHashCode() {
 
322
    assertEquals(classUnderTest + ".peekCachedHashCode() should return zero at first", 0,
 
323
        stringUnderTest.peekCachedHashCode());
 
324
    stringUnderTest.hashCode();
 
325
    assertEquals(classUnderTest + ".peekCachedHashCode should return zero at first",
 
326
        expectedHashCode, stringUnderTest.peekCachedHashCode());
 
327
  }
 
328
 
 
329
  public void testPartialHash() {
 
330
    // partialHash() is more strenuously tested elsewhere by testing hashes of substrings.
 
331
    // This test would fail if the expected hash were 1.  It's not.
 
332
    int hash = stringUnderTest.partialHash(stringUnderTest.size(), 0, stringUnderTest.size());
 
333
    assertEquals(classUnderTest + ".partialHash() must yield expected hashCode",
 
334
        expectedHashCode, hash);
 
335
  }
 
336
 
 
337
  public void testNewInput() throws IOException {
 
338
    InputStream input = stringUnderTest.newInput();
 
339
    assertEquals("InputStream.available() returns correct value",
 
340
        stringUnderTest.size(), input.available());
 
341
    boolean stillEqual = true;
 
342
    for (byte referenceByte : referenceBytes) {
 
343
      int expectedInt = (referenceByte & 0xFF);
 
344
      stillEqual = (expectedInt == input.read());
 
345
    }
 
346
    assertEquals("InputStream.available() returns correct value",
 
347
        0, input.available());
 
348
    assertTrue(classUnderTest + " must give the same bytes from the InputStream", stillEqual);
 
349
    assertEquals(classUnderTest + " InputStream must now be exhausted", -1, input.read());
 
350
  }
 
351
 
 
352
  public void testNewInput_skip() throws IOException {
 
353
    InputStream input = stringUnderTest.newInput();
 
354
    int stringSize = stringUnderTest.size();
 
355
    int nearEndIndex = stringSize * 2 / 3;
 
356
    long skipped1 = input.skip(nearEndIndex);
 
357
    assertEquals("InputStream.skip()", skipped1, nearEndIndex);
 
358
    assertEquals("InputStream.available()",
 
359
        stringSize - skipped1, input.available());
 
360
    assertTrue("InputStream.mark() is available", input.markSupported());
 
361
    input.mark(0);
 
362
    assertEquals("InputStream.skip(), read()",
 
363
        stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
 
364
    assertEquals("InputStream.available()",
 
365
                 stringSize - skipped1 - 1, input.available());
 
366
    long skipped2 = input.skip(stringSize);
 
367
    assertEquals("InputStream.skip() incomplete",
 
368
        skipped2, stringSize - skipped1 - 1);
 
369
    assertEquals("InputStream.skip(), no more input", 0, input.available());
 
370
    assertEquals("InputStream.skip(), no more input", -1, input.read());
 
371
    input.reset();
 
372
    assertEquals("InputStream.reset() succeded",
 
373
                 stringSize - skipped1, input.available());
 
374
    assertEquals("InputStream.reset(), read()",
 
375
        stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
 
376
  }
 
377
 
 
378
  public void testNewCodedInput() throws IOException {
 
379
    CodedInputStream cis = stringUnderTest.newCodedInput();
 
380
    byte[] roundTripBytes = cis.readRawBytes(referenceBytes.length);
 
381
    assertTrue(classUnderTest + " must give the same bytes back from the CodedInputStream",
 
382
        Arrays.equals(referenceBytes, roundTripBytes));
 
383
    assertTrue(classUnderTest + " CodedInputStream must now be exhausted", cis.isAtEnd());
 
384
  }
 
385
 
 
386
  /**
 
387
   * Make sure we keep things simple when concatenating with empty. See also
 
388
   * {@link ByteStringTest#testConcat_empty()}.
 
389
   */
 
390
  public void testConcat_empty() {
 
391
    assertSame(classUnderTest + " concatenated with empty must give " + classUnderTest,
 
392
        stringUnderTest.concat(ByteString.EMPTY), stringUnderTest);
 
393
    assertSame("empty concatenated with " + classUnderTest + " must give " + classUnderTest,
 
394
        ByteString.EMPTY.concat(stringUnderTest), stringUnderTest);
 
395
  }
 
396
}