001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest;
005:
006: import org.apache.commons.lang.ArrayUtils;
007:
008: import EDU.oswego.cs.dl.util.concurrent.Latch;
009:
010: import com.tc.object.config.ConfigVisitor;
011: import com.tc.object.config.DSOClientConfigHelper;
012: import com.tc.object.config.TransparencyClassSpec;
013: import com.tc.simulator.app.ApplicationConfig;
014: import com.tc.simulator.listener.ListenerProvider;
015: import com.tc.util.Assert;
016: import com.tctest.runner.AbstractTransparentApp;
017:
018: import java.util.ArrayList;
019: import java.util.Arrays;
020: import java.util.List;
021:
022: /**
023: * Makes sure that the methods in java.util.Arrays work with DSO managed arrays
024: */
025: public class JavaUtilArraysTestApp extends AbstractTransparentApp {
026:
027: private final List data = new ArrayList();
028: private final Latch latch;
029:
030: public JavaUtilArraysTestApp(String appId, ApplicationConfig cfg,
031: ListenerProvider listenerProvider) {
032: super (appId, cfg, listenerProvider);
033: if (getParticipantCount() != 2) {
034: throw new RuntimeException("invalid participant count "
035: + getParticipantCount());
036: }
037: this .latch = new Latch();
038: }
039:
040: public static void visitL1DSOConfig(ConfigVisitor visitor,
041: DSOClientConfigHelper config) {
042: String testClass = JavaUtilArraysTestApp.class.getName();
043: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
044: String methodExpression = "* " + testClass + "*.*(..)";
045: config.addWriteAutolock(methodExpression);
046: spec.addRoot("latch", "latch");
047: spec.addRoot("data", "data");
048: config.addIncludePattern(Data.class.getName());
049: String latchClassName = Latch.class.getName();
050: config.addIncludePattern(latchClassName);
051: // config.addWriteAutolock("* " + latchClassName + "*.*(..)");
052: }
053:
054: public void run() {
055: final boolean firstNode;
056:
057: synchronized (data) {
058: firstNode = data.size() == 0;
059: if (firstNode) {
060: data.add("temp");
061: }
062: }
063:
064: if (!firstNode) {
065: try {
066: synchronized (latch) {
067: latch.acquire();
068: }
069: } catch (InterruptedException e) {
070: throw new RuntimeException(e);
071: }
072: validateData();
073: } else {
074: setupData();
075: synchronized (latch) {
076: latch.release();
077: }
078: }
079: }
080:
081: private String expected(Object theWayItShouldBe, Object theWayItIs) {
082: return "expected " + ArrayUtils.toString(theWayItShouldBe)
083: + ", but found: " + ArrayUtils.toString(theWayItIs);
084: }
085:
086: private void validateData() {
087: Data d;
088:
089: synchronized (data) {
090: d = (Data) data.remove(0);
091: }
092:
093: synchronized (d) {
094: byte[] byteFillCompare = new byte[10];
095: Arrays.fill(byteFillCompare, (byte) 1);
096: if (!Arrays.equals(byteFillCompare, d.filledByte)) {
097: // formatting
098: throw new RuntimeException("filled bytes "
099: + expected(byteFillCompare, d.filledByte));
100: }
101: byte[] sortedByte = new byte[] { Byte.MIN_VALUE, 0, 1, 2,
102: 3, 4, 5, 6, 7, 8, 9, Byte.MAX_VALUE };
103: if (!Arrays.equals(sortedByte, d.sortedByte)) {
104: // formatting
105: throw new RuntimeException("sorted bytes: "
106: + expected(sortedByte, d.sortedByte));
107: }
108:
109: char[] charFillCompare = new char[10];
110: Arrays.fill(charFillCompare, 'z');
111: if (!Arrays.equals(charFillCompare, d.filledChar)) {
112: // formatting
113: throw new RuntimeException("filled chars: "
114: + expected(charFillCompare, d.filledChar));
115: }
116: char[] sortedChar = new char[] { Character.MIN_VALUE, 'c',
117: 'e', 'f', 'k', 'm', 'u', Character.MAX_VALUE };
118: if (!Arrays.equals(sortedChar, d.sortedChar)) {
119: // formatting
120: throw new RuntimeException("sorted chars: "
121: + expected(sortedChar, d.sortedChar));
122: }
123:
124: double[] doubleFillCompare = new double[10];
125: Arrays.fill(doubleFillCompare, Math.PI);
126: if (!Arrays.equals(doubleFillCompare, d.filledDouble)) {
127: // formatting
128: throw new RuntimeException("filled doubles: "
129: + expected(doubleFillCompare, d.filledDouble));
130: }
131: double[] sortedDouble = new double[] { -Double.MAX_VALUE,
132: -1.43D, -Double.MIN_VALUE, 0D, Double.MIN_VALUE,
133: Math.E, Math.PI, Double.MAX_VALUE };
134: if (!Arrays.equals(sortedDouble, d.sortedDouble)) {
135: // formatting
136: throw new RuntimeException("sorted doubles: "
137: + expected(sortedDouble, d.sortedDouble));
138: }
139:
140: float[] floatFillCompare = new float[10];
141: Arrays.fill(floatFillCompare, 8.1F);
142: if (!Arrays.equals(floatFillCompare, d.filledFloat)) {
143: // formatting
144: throw new RuntimeException("filled floats: "
145: + expected(floatFillCompare, d.filledFloat));
146: }
147: float[] sortedFloat = new float[] { -123F, 0F,
148: Float.MIN_VALUE, 3.14F, Float.MAX_VALUE };
149: if (!Arrays.equals(sortedFloat, d.sortedFloat)) {
150: // formatting
151: throw new RuntimeException("sorted floats: "
152: + expected(sortedFloat, d.sortedFloat));
153: }
154:
155: int[] intFillCompare = new int[10];
156: Arrays.fill(intFillCompare, 1);
157: if (!Arrays.equals(intFillCompare, d.filledInt)) {
158: // formatting
159: throw new RuntimeException("filled ints: "
160: + expected(intFillCompare, d.filledInt));
161: }
162: int[] sortedInt = new int[] { Integer.MIN_VALUE, 1, 2, 7,
163: 8, Integer.MAX_VALUE };
164: if (!Arrays.equals(sortedInt, d.sortedInt)) {
165: // formatting
166: throw new RuntimeException("sorted ints: "
167: + expected(sortedInt, d.sortedInt));
168: }
169:
170: long[] longFillCompare = new long[10];
171: Arrays.fill(longFillCompare, 42L);
172: if (!Arrays.equals(longFillCompare, d.filledLong)) {
173: // formatting
174: throw new RuntimeException("filled longs: "
175: + expected(longFillCompare, d.filledLong));
176: }
177: long[] sortedLong = new long[] { Long.MIN_VALUE, 1L, 5L,
178: 1000L, Long.MAX_VALUE };
179: if (!Arrays.equals(sortedLong, d.sortedLong)) {
180: // formatting
181: throw new RuntimeException("sorted longs: "
182: + expected(sortedLong, d.sortedLong));
183: }
184:
185: short[] shortFillCompare = new short[10];
186: Arrays.fill(shortFillCompare, (short) 69);
187: if (!Arrays.equals(shortFillCompare, d.filledShort)) {
188: // formatting
189: throw new RuntimeException("filled shorts: "
190: + expected(shortFillCompare, d.filledShort));
191: }
192: short[] sortedShort = new short[] { Short.MIN_VALUE, 0, 2,
193: Short.MAX_VALUE };
194: if (!Arrays.equals(sortedShort, d.sortedShort)) {
195: // formatting
196: throw new RuntimeException("sorted shorts: "
197: + expected(sortedShort, d.sortedShort));
198: }
199:
200: Object[] objectFillCompare = new Object[10];
201: Arrays.fill(objectFillCompare, new Integer(1));
202: if (!Arrays.equals(objectFillCompare, d.filledObject)) {
203: // formatting
204: throw new RuntimeException("filled objects: "
205: + expected(objectFillCompare, d.filledObject));
206: }
207: Object[] sortedObject = new Object[] { new Integer(-4),
208: new Integer(3) };
209: if (!Arrays.equals(sortedObject, d.sortedObject)) {
210: // formatting
211: throw new RuntimeException("sorted objects: "
212: + expected(sortedObject, d.sortedObject));
213: }
214:
215: boolean[] booleanFillCompare = new boolean[10];
216: Arrays.fill(booleanFillCompare, false);
217: if (!Arrays.equals(booleanFillCompare, d.filledBoolean)) {
218: // formatting
219: throw new RuntimeException("filled boolean: "
220: + expected(booleanFillCompare, d.filledBoolean));
221: }
222:
223: List list = d.asList;
224: if (list.size() != 2) {
225: throw new RuntimeException("list wrong size: "
226: + list.size());
227: }
228: if (!list.get(0).equals(new Integer(-4))) {
229: throw new RuntimeException("wrong data");
230: }
231: if (!list.get(1).equals(new Integer(3))) {
232: throw new RuntimeException("wrong data");
233: }
234:
235: Object[] array = d.dataBehindAsList2;
236: if (array.length != 4) {
237: throw new RuntimeException("array size wrong: "
238: + array.length);
239: }
240: Assert.assertEquals("put", array[0]);
241: Assert.assertEquals("the", array[1]);
242: Assert.assertEquals("rap", array[2]);
243: Assert.assertEquals("down", array[3]);
244: }
245: }
246:
247: private void setupData() {
248: Data d = new Data();
249:
250: synchronized (data) {
251: data.clear();
252: data.add(d);
253: }
254:
255: d.sort();
256: d.fill();
257: d.modifyAsList2();
258: }
259:
260: // NOTE: There is no such thing as sorted booleans
261: private static final byte[] unsortedByte = new byte[] { 0, 6, 3, 7,
262: Byte.MAX_VALUE, 4, 2, 9, 8, 1, 5, Byte.MIN_VALUE };
263: private static final char[] unsortedChar = new char[] { 'f',
264: Character.MAX_VALUE, 'e', 'u', 'k', 'c', 'm',
265: Character.MIN_VALUE };
266: private static final double[] unsortedDouble = new double[] {
267: Math.PI, Double.MIN_VALUE, -Double.MAX_VALUE, Math.E,
268: Double.MAX_VALUE, 0D, -Double.MIN_VALUE, -1.43D };
269: private static final float[] unsortedFloat = new float[] {
270: Float.MAX_VALUE, 0F, Float.MIN_VALUE, -123F, 3.14F };
271: private static final int[] unsortedInt = new int[] { 2,
272: Integer.MAX_VALUE, 7, Integer.MIN_VALUE, 8, 1 };
273: private static final long[] unsortedLong = new long[] { 1000L, 5L,
274: 1L, Long.MIN_VALUE, Long.MAX_VALUE };
275: private static final short[] unsortedShort = new short[] {
276: Short.MAX_VALUE, 2, Short.MIN_VALUE, 0 };
277: private static final Object[] unsortedObject = new Object[] {
278: new Integer(3), new Integer(-4) };
279:
280: private static class Data {
281:
282: private boolean[] filledBoolean;
283: // NOTE: There is no such thing as sorted booleans
284:
285: private final byte[] filledByte;
286: private final byte[] sortedByte;
287:
288: private final char[] filledChar;
289: private final char[] sortedChar;
290:
291: private final double[] filledDouble;
292: private final double[] sortedDouble;
293:
294: private final float[] filledFloat;
295: private final float[] sortedFloat;
296:
297: private final int[] filledInt;
298: private final int[] sortedInt;
299:
300: private final long[] filledLong;
301: private final long[] sortedLong;
302:
303: private final short[] filledShort;
304: private final short[] sortedShort;
305:
306: private final Object[] filledObject;
307: private final Object[] sortedObject;
308:
309: private final List asList;
310: private final List asList2;
311:
312: private final Object[] dataBehindAsList2;
313:
314: Data() {
315: this .filledBoolean = new boolean[10];
316: Arrays.fill(filledBoolean, true);
317:
318: this .filledByte = new byte[10];
319: this .sortedByte = (byte[]) unsortedByte.clone();
320:
321: this .filledChar = new char[10];
322: this .sortedChar = (char[]) unsortedChar.clone();
323:
324: this .filledDouble = new double[10];
325: this .sortedDouble = (double[]) unsortedDouble.clone();
326:
327: this .filledInt = new int[10];
328: this .sortedInt = (int[]) unsortedInt.clone();
329:
330: this .filledFloat = new float[10];
331: this .sortedFloat = (float[]) unsortedFloat.clone();
332:
333: this .filledLong = new long[10];
334: this .sortedLong = (long[]) unsortedLong.clone();
335:
336: this .filledShort = new short[10];
337: this .sortedShort = (short[]) unsortedShort.clone();
338:
339: this .filledObject = new Object[10];
340: this .sortedObject = (Object[]) unsortedObject.clone();
341:
342: // the underlying array will be sorted(), so we should expect the List to come out sorted on the other side
343: this .asList = Arrays.asList(this .sortedObject);
344:
345: this .dataBehindAsList2 = new Object[4];
346: this .dataBehindAsList2[0] = "put";
347: this .dataBehindAsList2[1] = "the";
348: this .dataBehindAsList2[2] = "smack";
349: this .dataBehindAsList2[3] = "down";
350:
351: this .asList2 = Arrays.asList(this .dataBehindAsList2);
352: }
353:
354: synchronized void fill() {
355: Arrays.fill(this .filledBoolean, false);
356: Arrays.fill(this .filledByte, (byte) 1);
357: Arrays.fill(this .filledChar, 'z');
358: Arrays.fill(this .filledDouble, Math.PI);
359: Arrays.fill(this .filledFloat, 8.1F);
360: Arrays.fill(this .filledInt, 1);
361: Arrays.fill(this .filledLong, 42L);
362: Arrays.fill(this .filledShort, (short) 69);
363: Arrays.fill(this .filledObject, new Integer(1));
364: }
365:
366: synchronized void sort() {
367: Arrays.sort(this .sortedByte);
368: // There is no boolean natural sort
369: Arrays.sort(this .sortedChar);
370: Arrays.sort(this .sortedDouble);
371: Arrays.sort(this .sortedFloat);
372: Arrays.sort(this .sortedInt);
373: Arrays.sort(this .sortedLong);
374: Arrays.sort(this .sortedShort);
375: Arrays.sort(this .sortedObject);
376: }
377:
378: synchronized void modifyAsList2() {
379: // test that the modifications made through the asList() makes it into the backend DSO managed array
380: this .asList2.set(2, "rap");
381: }
382:
383: }
384:
385: // private static class Latch {
386: // private boolean set = false;
387: //
388: // synchronized void acquire() {
389: // while (!set) {
390: // try {
391: // wait();
392: // } catch (InterruptedException e) {
393: // throw new RuntimeException(e);
394: // }
395: // }
396: // }
397: //
398: // synchronized void release() {
399: // set = true;
400: // notifyAll();
401: // }
402: // }
403:
404: }
|