001: package com.reeltwo.jumble.mutation;
002:
003: import junit.framework.Test;
004: import junit.framework.TestCase;
005: import junit.framework.TestSuite;
006: import org.apache.bcel.classfile.JavaClass;
007:
008: import java.util.Random;
009:
010: /**
011: * Tests the corresponding class.
012: *
013: * @author Sean A. Irvine
014: * @version $Revision: 501 $
015: */
016: public class MutaterTest extends TestCase {
017:
018: public MutaterTest(String name) {
019: super (name);
020: }
021:
022: public static Test suite() {
023: TestSuite suite = new TestSuite(MutaterTest.class);
024: return suite;
025: }
026:
027: public static void main(String[] args) {
028: junit.textui.TestRunner.run(suite());
029: }
030:
031: public void testCountMutationPointsX0()
032: throws ClassNotFoundException {
033: assertEquals(0, new Mutater().countMutationPoints("jumble.X0"));
034: }
035:
036: public void testCountMutationPointsX0I()
037: throws ClassNotFoundException {
038: assertEquals(-1, new Mutater()
039: .countMutationPoints("jumble.X0I"));
040: }
041:
042: public void testCountMutationPointsX1()
043: throws ClassNotFoundException {
044: assertEquals(1, new Mutater().countMutationPoints("jumble.X1"));
045: }
046:
047: public void testCountMutationPointsX2()
048: throws ClassNotFoundException {
049: assertEquals(9, new Mutater().countMutationPoints("jumble.X2"));
050: }
051:
052: public void testCountMutationPointsX2r()
053: throws ClassNotFoundException {
054: Mutater m = new Mutater();
055: m.setMutateReturnValues(true);
056: assertEquals(10, m.countMutationPoints("jumble.X2"));
057: }
058:
059: public void testCountMutationPointsX2i()
060: throws ClassNotFoundException {
061: Mutater m = new Mutater();
062: m.setMutateInlineConstants(true);
063: assertEquals(11, m.countMutationPoints("jumble.X2"));
064: }
065:
066: public void testCountMutationPointsX2ir()
067: throws ClassNotFoundException {
068: Mutater m = new Mutater();
069: m.setMutateInlineConstants(true);
070: m.setMutateReturnValues(true);
071: assertEquals(12, m.countMutationPoints("jumble.X2"));
072: }
073:
074: public void testCountMutationPointsLines()
075: throws ClassNotFoundException {
076: Mutater m = new Mutater();
077: assertEquals(3, m.countMutationPoints("DebugLines"));
078: }
079:
080: public void testCountMutationPointsNone()
081: throws ClassNotFoundException {
082: Mutater m = new Mutater();
083: assertEquals(3, m.countMutationPoints("DebugNone"));
084: }
085:
086: // private void testDescriptions(int x, String s) throws ClassNotFoundException {
087: // Mutater m = new Mutater(x);
088: // assertEquals(null, m.getModification());
089: // m.setMutateInlineConstants(true);
090: // m.setMutateReturnValues(true);
091: // m.jumbler("com.reeltwo.jumble.X2");
092: // assertEquals(m.getModification(), s, m.getModification());
093: // }
094:
095: private void testDescriptions(int x, String s, String className,
096: boolean constants, boolean returns, boolean negs)
097: throws ClassNotFoundException {
098:
099: Mutater m = new Mutater(x);
100: assertEquals(null, m.getModification());
101: m.setMutateInlineConstants(constants);
102: m.setMutateReturnValues(returns);
103: m.setMutateNegs(negs);
104: m.jumbler(className);
105: assertEquals(m.getModification(), s, m.getModification());
106: }
107:
108: private void testDescriptions(int x, String s, String className)
109: throws ClassNotFoundException {
110: testDescriptions(x, s, className, true, true, false);
111: }
112:
113: public void testCountNegs() throws ClassNotFoundException {
114: Mutater m = new Mutater();
115: m.setMutateNegs(true);
116: assertEquals(1, m
117: .countMutationPoints("experiments.instruction.INeg"));
118: assertEquals(1, m
119: .countMutationPoints("experiments.instruction.DNeg"));
120: assertEquals(1, m
121: .countMutationPoints("experiments.instruction.FNeg"));
122: assertEquals(1, m
123: .countMutationPoints("experiments.instruction.LNeg"));
124: }
125:
126: public void testDescriptionsNegs() throws ClassNotFoundException {
127: testDescriptions(0,
128: "experiments.instruction.INeg:10: removed negation",
129: "experiments.instruction.INeg", false, false, true);
130: testDescriptions(0,
131: "experiments.instruction.DNeg:10: removed negation",
132: "experiments.instruction.DNeg", false, false, true);
133: testDescriptions(0,
134: "experiments.instruction.FNeg:10: removed negation",
135: "experiments.instruction.FNeg", false, false, true);
136: testDescriptions(0,
137: "experiments.instruction.LNeg:10: removed negation",
138: "experiments.instruction.LNeg", false, false, true);
139: }
140:
141: public void testDescriptionsX2() throws ClassNotFoundException {
142: String className = "jumble.X2";
143:
144: testDescriptions(0, "jumble.X2:6: * -> /", className);
145: testDescriptions(1, "jumble.X2:6: / -> *", className);
146: testDescriptions(2, "jumble.X2:6: + -> -", className);
147: testDescriptions(3, "jumble.X2:6: % -> *", className);
148: testDescriptions(4, "jumble.X2:6: / -> *", className);
149: testDescriptions(5, "jumble.X2:6: - -> +", className);
150: testDescriptions(6, "jumble.X2:6: 5 -> -1", className);
151: testDescriptions(7, "jumble.X2:6: >> -> <<", className);
152: testDescriptions(8, "jumble.X2:6: << -> >>", className);
153: testDescriptions(9, "jumble.X2:6: 57 (9) -> 58 (:)", className);
154: testDescriptions(10, "jumble.X2:6: & -> |", className);
155: testDescriptions(11,
156: "jumble.X2:6: changed return value (ireturn)",
157: className);
158: testDescriptions(500, null, className);
159: }
160:
161: public void testDescriptionsX3() throws ClassNotFoundException {
162: final String className = "jumble.X3";
163: testDescriptions(0, "jumble.X3:6: 3 -> 4", className);
164: testDescriptions(1, "jumble.X3:6: * -> /", className);
165: testDescriptions(2, "jumble.X3:6: * -> /", className);
166: testDescriptions(3, "jumble.X3:6: + -> -", className);
167: testDescriptions(4, "jumble.X3:6: - -> +", className);
168: testDescriptions(5,
169: "jumble.X3:6: changed return value (areturn)",
170: className);
171: testDescriptions(500, null, className);
172: }
173:
174: public void testFindsClass() {
175: Mutater m = new Mutater();
176: try {
177: assertNotNull(m.jumbler("jumble.X3"));
178: } catch (ClassNotFoundException e) {
179: fail("IO problem");
180: }
181: }
182:
183: public void testDoesntFindClass() {
184: Mutater m = new Mutater();
185: try {
186: m.jumbler("poxweed");
187: fail("IO failed to fire");
188: } catch (ClassNotFoundException e) {
189: // ok
190: }
191: }
192:
193: private void testDescriptions4(int x, String s)
194: throws ClassNotFoundException {
195: Mutater m = new Mutater(x);
196: assertEquals(null, m.getModification());
197: m.setMutateInlineConstants(true);
198: m.setMutateReturnValues(true);
199: m.jumbler("jumble.X4");
200: assertEquals(m.getModification(), s, m.getModification());
201: }
202:
203: public void testDescriptionsX4() throws ClassNotFoundException {
204: testDescriptions4(0, "jumble.X4:6: * -> /");
205: testDescriptions4(1, "jumble.X4:6: / -> *");
206: testDescriptions4(2, "jumble.X4:6: + -> -");
207: testDescriptions4(3, "jumble.X4:6: % -> *");
208: testDescriptions4(4, "jumble.X4:6: / -> *");
209: testDescriptions4(5, "jumble.X4:6: - -> +");
210: testDescriptions4(6, "jumble.X4:6: 5 -> -1");
211: testDescriptions4(7, "jumble.X4:6: >> -> <<");
212: testDescriptions4(8, "jumble.X4:6: << -> >>");
213: testDescriptions4(9, "jumble.X4:6: & -> |");
214: testDescriptions4(10,
215: "jumble.X4:6: changed return value (lreturn)");
216: testDescriptions4(500, null);
217: }
218:
219: public void hash(String s, int mp, long h) {
220: try {
221: Mutater m = new Mutater(mp);
222: JavaClass c = m.jumbler(s);
223: assertEquals(h, irvineHash(c.getBytes(), 0,
224: c.getBytes().length));
225: } catch (Exception e) {
226: fail(e.getMessage());
227: }
228: }
229:
230: public void testGetMutatedMethodName()
231: throws ClassNotFoundException {
232: Mutater m = new Mutater();
233: assertEquals("add(II)I", m
234: .getMutatedMethodName("experiments.JumblerExperiment"));
235:
236: m = new Mutater(2);
237: assertEquals("add(II)I", m
238: .getMutatedMethodName("experiments.JumblerExperiment"));
239:
240: m = new Mutater(3);
241: assertEquals("multiply(II)I", m
242: .getMutatedMethodName("experiments.JumblerExperiment"));
243:
244: try {
245: m = new Mutater(500);
246: m.getMutatedMethodName("experiments.JumblerExperiment");
247: fail();
248: } catch (Exception e) {
249: ; // ok
250: }
251: }
252:
253: public void testGetMethodRelativeMutationPoint()
254: throws ClassNotFoundException {
255: Mutater m = new Mutater();
256: assertEquals(
257: 0,
258: m
259: .getMethodRelativeMutationPoint("experiments.JumblerExperiment"));
260:
261: m = new Mutater(2);
262: assertEquals(
263: 2,
264: m
265: .getMethodRelativeMutationPoint("experiments.JumblerExperiment"));
266:
267: m = new Mutater(3);
268: assertEquals(
269: 0,
270: m
271: .getMethodRelativeMutationPoint("experiments.JumblerExperiment"));
272:
273: try {
274: m = new Mutater(500);
275: m
276: .getMethodRelativeMutationPoint("experiments.JumblerExperiment");
277: fail();
278: } catch (Exception e) {
279: ; // ok
280: }
281: }
282:
283: /** Randomly generated arrays used to compute irvineHash codes */
284: private static final long[] HASH_BLOCKS;
285: static {
286: HASH_BLOCKS = new long[256];
287: Random r = new Random(1L); // use same seed for deterministic behavior
288: for (int i = 0; i < 256; i++) {
289: HASH_BLOCKS[i] = r.nextLong();
290: }
291: }
292:
293: /**
294: * Returns a 64 bit hash of the given string. This hash function exhibits
295: * better statistical behavior than String hashCode() and has speed comparable
296: * to CRC32.
297: *
298: * @param in
299: * bytes to checksum
300: * @param start
301: * first byte
302: * @param length
303: * length of input
304: * @return a hash
305: */
306: private static long irvineHash(final byte[] in, final int start,
307: final int length) {
308: long r = 0L;
309: for (int i = 0; i < length; i++) {
310: final long sgn = (r & 0x8000000000000000L) >>> 63;
311: r <<= 1;
312: r |= sgn;
313: r ^= HASH_BLOCKS[(in[i + start] + i) & 0xFF];
314: }
315: return r;
316: }
317:
318: }
|