001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: TupleOrderingTest.java,v 1.22.2.3 2008/01/07 15:14:23 cwl Exp $
007: */
008:
009: package com.sleepycat.bind.tuple.test;
010:
011: import junit.framework.Test;
012: import junit.framework.TestCase;
013: import junit.framework.TestSuite;
014:
015: import com.sleepycat.bind.tuple.TupleOutput;
016: import com.sleepycat.collections.test.DbTestUtil;
017:
018: /**
019: * @author Mark Hayes
020: */
021: public class TupleOrderingTest extends TestCase {
022:
023: private TupleOutput out;
024: private byte[] prevBuf;
025:
026: public static void main(String[] args) throws Exception {
027:
028: junit.framework.TestResult tr = junit.textui.TestRunner
029: .run(suite());
030: if (tr.errorCount() > 0 || tr.failureCount() > 0) {
031: System.exit(1);
032: } else {
033: System.exit(0);
034: }
035: }
036:
037: public static Test suite() throws Exception {
038:
039: TestSuite suite = new TestSuite(TupleOrderingTest.class);
040: return suite;
041: }
042:
043: public TupleOrderingTest(String name) {
044:
045: super (name);
046: }
047:
048: public void setUp() {
049:
050: DbTestUtil.printTestName("TupleOrderingTest." + getName());
051: out = new TupleOutput();
052: prevBuf = null;
053: }
054:
055: public void tearDown() {
056:
057: /* Ensure that GC can cleanup. */
058: out = null;
059: prevBuf = null;
060: }
061:
062: /**
063: * Each tuple written must be strictly less than (by comparison of bytes)
064: * the tuple written just before it. The check() method compares bytes
065: * just written to those written before the previous call to check().
066: */
067: private void check() {
068:
069: check(-1);
070: }
071:
072: private void check(int dataIndex) {
073:
074: byte[] buf = new byte[out.size()];
075: System.arraycopy(out.getBufferBytes(), out.getBufferOffset(),
076: buf, 0, buf.length);
077: if (prevBuf != null) {
078: int errOffset = -1;
079: int len = Math.min(prevBuf.length, buf.length);
080: boolean areEqual = true;
081: for (int i = 0; i < len; i += 1) {
082: int val1 = prevBuf[i] & 0xFF;
083: int val2 = buf[i] & 0xFF;
084: if (val1 < val2) {
085: areEqual = false;
086: break;
087: } else if (val1 > val2) {
088: errOffset = i;
089: break;
090: }
091: }
092: if (areEqual) {
093: if (prevBuf.length < buf.length) {
094: areEqual = false;
095: } else if (prevBuf.length > buf.length) {
096: areEqual = false;
097: errOffset = buf.length + 1;
098: }
099: }
100: if (errOffset != -1 || areEqual) {
101: StringBuffer msg = new StringBuffer();
102: if (errOffset != -1) {
103: msg.append("Left >= right at byte offset "
104: + errOffset);
105: } else if (areEqual) {
106: msg.append("Bytes are equal");
107: } else {
108: throw new IllegalStateException();
109: }
110: msg.append("\nLeft hex bytes: ");
111: for (int i = 0; i < prevBuf.length; i += 1) {
112: msg.append(' ');
113: int val = prevBuf[i] & 0xFF;
114: if ((val & 0xF0) == 0) {
115: msg.append('0');
116: }
117: msg.append(Integer.toHexString(val));
118: }
119: msg.append("\nRight hex bytes:");
120: for (int i = 0; i < buf.length; i += 1) {
121: msg.append(' ');
122: int val = buf[i] & 0xFF;
123: if ((val & 0xF0) == 0) {
124: msg.append('0');
125: }
126: msg.append(Integer.toHexString(val));
127: }
128: if (dataIndex >= 0) {
129: msg.append("\nData index: " + dataIndex);
130: }
131: fail(msg.toString());
132: }
133: }
134: prevBuf = buf;
135: out.reset();
136: }
137:
138: private void reset() {
139:
140: prevBuf = null;
141: out.reset();
142: }
143:
144: public void testString() {
145:
146: final String[] DATA = { "", "a", "ab", "b", "bb", "bba", };
147: for (int i = 0; i < DATA.length; i += 1) {
148: out.writeString(DATA[i]);
149: check(i);
150: }
151: reset();
152: out.writeString("a");
153: check();
154: out.writeString("a");
155: out.writeString("");
156: check();
157: out.writeString("a");
158: out.writeString("");
159: out.writeString("a");
160: check();
161: out.writeString("a");
162: out.writeString("b");
163: check();
164: out.writeString("aa");
165: check();
166: out.writeString("b");
167: check();
168: }
169:
170: public void testFixedString() {
171:
172: final char[][] DATA = { {}, { 'a' }, { 'a', 'b' }, { 'b' },
173: { 'b', 'b' }, { 0x7F }, { 0xFF }, };
174: for (int i = 0; i < DATA.length; i += 1) {
175: out.writeString(DATA[i]);
176: check(i);
177: }
178: }
179:
180: public void testChars() {
181:
182: final char[][] DATA = { {}, { 0 }, { 'a' }, { 'a', 0 },
183: { 'a', 'b' }, { 'b' }, { 'b', 'b' }, { 0x7F },
184: { 0x7F, 0 }, { 0xFF }, { 0xFF, 0 }, };
185: for (int i = 0; i < DATA.length; i += 1) {
186: out.writeChars(DATA[i]);
187: check(i);
188: }
189: }
190:
191: public void testBytes() {
192:
193: final char[][] DATA = { {}, { 0 }, { 'a' }, { 'a', 0 },
194: { 'a', 'b' }, { 'b' }, { 'b', 'b' }, { 0x7F },
195: { 0xFF }, };
196: for (int i = 0; i < DATA.length; i += 1) {
197: out.writeBytes(DATA[i]);
198: check(i);
199: }
200: }
201:
202: public void testBoolean() {
203:
204: final boolean[] DATA = { false, true };
205: for (int i = 0; i < DATA.length; i += 1) {
206: out.writeBoolean(DATA[i]);
207: check(i);
208: }
209: }
210:
211: public void testUnsignedByte() {
212:
213: final int[] DATA = { 0, 1, 0x7F, 0xFF };
214: for (int i = 0; i < DATA.length; i += 1) {
215: out.writeUnsignedByte(DATA[i]);
216: check(i);
217: }
218: }
219:
220: public void testUnsignedShort() {
221:
222: final int[] DATA = { 0, 1, 0xFE, 0xFF, 0x800, 0x7FFF, 0xFFFF };
223: for (int i = 0; i < DATA.length; i += 1) {
224: out.writeUnsignedShort(DATA[i]);
225: check(i);
226: }
227: }
228:
229: public void testUnsignedInt() {
230:
231: final long[] DATA = { 0, 1, 0xFE, 0xFF, 0x800, 0x7FFF, 0xFFFF,
232: 0x80000, 0x7FFFFFFF, 0x80000000, 0xFFFFFFFF };
233: for (int i = 0; i < DATA.length; i += 1) {
234: out.writeUnsignedInt(DATA[i]);
235: check(i);
236: }
237: }
238:
239: public void testByte() {
240:
241: final byte[] DATA = { Byte.MIN_VALUE, Byte.MIN_VALUE + 1, -1,
242: 0, 1, Byte.MAX_VALUE - 1, Byte.MAX_VALUE, };
243: for (int i = 0; i < DATA.length; i += 1) {
244: out.writeByte(DATA[i]);
245: check(i);
246: }
247: }
248:
249: public void testShort() {
250:
251: final short[] DATA = { Short.MIN_VALUE, Short.MIN_VALUE + 1,
252: Byte.MIN_VALUE, Byte.MIN_VALUE + 1, -1, 0, 1,
253: Byte.MAX_VALUE - 1, Byte.MAX_VALUE,
254: Short.MAX_VALUE - 1, Short.MAX_VALUE, };
255: for (int i = 0; i < DATA.length; i += 1) {
256: out.writeShort(DATA[i]);
257: check(i);
258: }
259: }
260:
261: public void testInt() {
262:
263: final int[] DATA = { Integer.MIN_VALUE, Integer.MIN_VALUE + 1,
264: Short.MIN_VALUE, Short.MIN_VALUE + 1, Byte.MIN_VALUE,
265: Byte.MIN_VALUE + 1, -1, 0, 1, Byte.MAX_VALUE - 1,
266: Byte.MAX_VALUE, Short.MAX_VALUE - 1, Short.MAX_VALUE,
267: Integer.MAX_VALUE - 1, Integer.MAX_VALUE, };
268: for (int i = 0; i < DATA.length; i += 1) {
269: out.writeInt(DATA[i]);
270: check(i);
271: }
272: }
273:
274: public void testLong() {
275:
276: final long[] DATA = { Long.MIN_VALUE, Long.MIN_VALUE + 1,
277: Integer.MIN_VALUE, Integer.MIN_VALUE + 1,
278: Short.MIN_VALUE, Short.MIN_VALUE + 1, Byte.MIN_VALUE,
279: Byte.MIN_VALUE + 1, -1, 0, 1, Byte.MAX_VALUE - 1,
280: Byte.MAX_VALUE, Short.MAX_VALUE - 1, Short.MAX_VALUE,
281: Integer.MAX_VALUE - 1, Integer.MAX_VALUE,
282: Long.MAX_VALUE - 1, Long.MAX_VALUE, };
283: for (int i = 0; i < DATA.length; i += 1) {
284: out.writeLong(DATA[i]);
285: check(i);
286: }
287: }
288:
289: public void testFloat() {
290:
291: // Only positive floats and doubles are ordered deterministically
292:
293: final float[] DATA = { 0, Float.MIN_VALUE, 2 * Float.MIN_VALUE,
294: (float) 0.01, (float) 0.02, (float) 0.99, 1,
295: (float) 1.01, (float) 1.02, (float) 1.99,
296: Byte.MAX_VALUE - 1, Byte.MAX_VALUE,
297: Short.MAX_VALUE - 1, Short.MAX_VALUE,
298: Integer.MAX_VALUE, Long.MAX_VALUE / 2, Long.MAX_VALUE,
299: Float.MAX_VALUE, Float.POSITIVE_INFINITY, Float.NaN, };
300: for (int i = 0; i < DATA.length; i += 1) {
301: out.writeFloat(DATA[i]);
302: check(i);
303: }
304: }
305:
306: public void testDouble() {
307:
308: // Only positive floats and doubles are ordered deterministically
309:
310: final double[] DATA = { 0, Double.MIN_VALUE,
311: 2 * Double.MIN_VALUE, 0.001, 0.002, 0.999, 1, 1.001,
312: 1.002, 1.999, Byte.MAX_VALUE - 1, Byte.MAX_VALUE,
313: Short.MAX_VALUE - 1, Short.MAX_VALUE,
314: Integer.MAX_VALUE - 1, Integer.MAX_VALUE,
315: Long.MAX_VALUE / 2, Long.MAX_VALUE, Float.MAX_VALUE,
316: Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN, };
317: for (int i = 0; i < DATA.length; i += 1) {
318: out.writeDouble(DATA[i]);
319: check(i);
320: }
321: }
322:
323: public void testSortedFloat() {
324:
325: final float[] DATA = { Float.NEGATIVE_INFINITY,
326: (-Float.MAX_VALUE), Long.MIN_VALUE, Long.MIN_VALUE / 2,
327: Integer.MIN_VALUE, Short.MIN_VALUE,
328: Short.MIN_VALUE + 1, Byte.MIN_VALUE,
329: Byte.MIN_VALUE + 1, (float) -1.99, (float) -1.02,
330: (float) -1.01, -1, (float) -0.99, (float) -0.02,
331: (float) -0.01, 2 * (-Float.MIN_VALUE),
332: (-Float.MIN_VALUE), 0, Float.MIN_VALUE,
333: 2 * Float.MIN_VALUE, (float) 0.01, (float) 0.02,
334: (float) 0.99, 1, (float) 1.01, (float) 1.02,
335: (float) 1.99, Byte.MAX_VALUE - 1, Byte.MAX_VALUE,
336: Short.MAX_VALUE - 1, Short.MAX_VALUE,
337: Integer.MAX_VALUE, Long.MAX_VALUE / 2, Long.MAX_VALUE,
338: Float.MAX_VALUE, Float.POSITIVE_INFINITY, Float.NaN, };
339: for (int i = 0; i < DATA.length; i += 1) {
340: out.writeSortedFloat(DATA[i]);
341: check(i);
342: }
343: }
344:
345: public void testSortedDouble() {
346:
347: final double[] DATA = { Double.NEGATIVE_INFINITY,
348: (-Double.MAX_VALUE), (-Float.MAX_VALUE),
349: Long.MIN_VALUE, Long.MIN_VALUE / 2, Integer.MIN_VALUE,
350: Short.MIN_VALUE, Short.MIN_VALUE + 1, Byte.MIN_VALUE,
351: Byte.MIN_VALUE + 1, -1.999, -1.002, -1.001, -1, -0.999,
352: -0.002, -0.001, 2 * (-Double.MIN_VALUE),
353: (-Double.MIN_VALUE), 0, Double.MIN_VALUE,
354: 2 * Double.MIN_VALUE, 0.001, 0.002, 0.999, 1, 1.001,
355: 1.002, 1.999, Byte.MAX_VALUE - 1, Byte.MAX_VALUE,
356: Short.MAX_VALUE - 1, Short.MAX_VALUE,
357: Integer.MAX_VALUE - 1, Integer.MAX_VALUE,
358: Long.MAX_VALUE / 2, Long.MAX_VALUE, Float.MAX_VALUE,
359: Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN, };
360: for (int i = 0; i < DATA.length; i += 1) {
361: out.writeSortedDouble(DATA[i]);
362: check(i);
363: }
364: }
365: }
|