Skip to content

Commit

Permalink
refactor int and long fuzz generation;
Browse files Browse the repository at this point in the history
validate fuzz args in test case contructor;
  • Loading branch information
esaulpaugh committed Aug 16, 2020
1 parent 9d3ba8b commit a6de535
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 21 deletions.
49 changes: 28 additions & 21 deletions src/test/java/com/esaulpaugh/headlong/abi/MonteCarloTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package com.esaulpaugh.headlong.abi;

import com.esaulpaugh.headlong.TestUtils;
import com.esaulpaugh.headlong.abi.util.BizarroIntegers;
import com.esaulpaugh.headlong.util.Integers;
import com.esaulpaugh.headlong.util.Strings;
import com.esaulpaugh.headlong.util.SuperSerial;
import com.google.gson.Gson;
Expand Down Expand Up @@ -139,6 +141,7 @@ public class MonteCarloTestCase {
this.rawSignature = sig;
this.function = new Function(sig, null, md);
this.argsTuple = generateTuple(function.getParamTypes(), rng);
function.getParamTypes().validate(argsTuple);
}

JsonElement toJsonElement(Gson gson, String name, JsonPrimitive version) {
Expand Down Expand Up @@ -300,8 +303,8 @@ private Tuple generateTuple(TupleType tupleType, Random r) {
private Object generateValue(ABIType<?> type, Random r) {
switch (type.typeCode()) {
case TYPE_CODE_BOOLEAN: return r.nextBoolean();
case TYPE_CODE_BYTE: return generateByte(r);
case TYPE_CODE_INT: return generateInt(r, (IntType) type);
case TYPE_CODE_BYTE: return (byte) r.nextInt();
case TYPE_CODE_INT: return (int) generateLong(r, (IntType) type);
case TYPE_CODE_LONG: return generateLong(r, (LongType) type);
case TYPE_CODE_BIG_INTEGER: return generateBigInteger(r, (BigIntegerType) type);
case TYPE_CODE_BIG_DECIMAL: return generateBigDecimal(r, (BigDecimalType) type);
Expand All @@ -311,30 +314,34 @@ private Object generateValue(ABIType<?> type, Random r) {
}
}

private static byte generateByte(Random r) {
return (byte) r.nextInt();
private static long generateLong(Random r, UnitType<? extends Number> unitType) {
return generateLong(r, unitType.bitLength, 1 + r.nextInt(unitType.bitLength / Byte.SIZE), unitType.unsigned);
}

private static int generateInt(Random r, IntType intType) {
byte[] buffer = new byte[1 + r.nextInt(intType.bitLength >>> 3)]; // 1-4
r.nextBytes(buffer);
int x = new BigInteger(buffer).intValue();
if(intType.unsigned && x < 0) {
return (-(x + 1) << 1) + (r.nextBoolean() ? 1 : 0);
private static long generateLong(Random r, int bitLen, int len, boolean unsigned) {
long val = r.nextLong();
switch (len) {
case 1: val &= 0xFFL; break;
case 2: val &= 0xFFFFL; break;
case 3: val &= 0xFFFFFFL; break;
case 4: val &= 0xFFFFFFFFL; break;
case 5: val &= 0xFFFFFFFFFFL; break;
case 6: val &= 0xFFFFFFFFFFFFL; break;
case 7: val &= 0xFFFFFFFFFFFFFFL; break;
case 8: break;
default: throw new Error();
}
return x;
}

private static long generateLong(Random r, LongType longType) {
byte[] random = TestUtils.randomBytes(1 + r.nextInt(longType.bitLength / Byte.SIZE) /* 1-8 */, r);
long x = new BigInteger(random).longValue();
if(longType.unsigned && x < 0) {
return ((-(x + 1)) << 1) + (r.nextBoolean() ? 1 : 0);
val = unsigned || r.nextBoolean() ? val : val < 0 ? -(val + 1) : (-val - 1);
if(!unsigned) {
int valBitLen = val < 0 ? BizarroIntegers.bitLen(val) : Integers.bitLen(val);
if(valBitLen >= bitLen) {
val >>= 1;
}
}
return x;
return val;
}

private static BigInteger generateBigInteger(Random r, UnitType<?> type) {
private static BigInteger generateBigInteger(Random r, UnitType<? extends Number> type) {
byte[] magnitude = new byte[type.bitLength / Byte.SIZE];
r.nextBytes(magnitude);
boolean zero = true;
Expand Down Expand Up @@ -394,7 +401,7 @@ private static String generateASCIIString(final int len, Random r) {
private static int[] generateIntArray(final int len, IntType intType, Random r) {
int[] ints = new int[len];
for (int i = 0; i < len; i++) {
ints[i] = generateInt(r, intType);
ints[i] = (int) generateLong(r, intType);
}
return ints;
}
Expand Down
65 changes: 65 additions & 0 deletions src/test/java/com/esaulpaugh/headlong/abi/TupleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
package com.esaulpaugh.headlong.abi;

import com.esaulpaugh.headlong.TestUtils;
import com.esaulpaugh.headlong.abi.util.BizarroIntegers;
import com.esaulpaugh.headlong.util.Integers;
import com.joemelsha.crypto.hash.Keccak;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

import static org.junit.jupiter.api.Assertions.assertEquals;

Expand All @@ -46,6 +50,67 @@ public class TupleTest {
1.9d
};

@Disabled("meta test")
@Test
public void metaTest1() {
Random r = ThreadLocalRandom.current();

int bits = 24;

final int pow = (int) Math.pow(2.0, bits);
final int powMinus1 = pow - 1;
System.out.println(Long.toHexString(powMinus1));

System.out.println(pow);

boolean[] bools = new boolean[pow];

@SuppressWarnings("unchecked")
UnitType<? extends Number> type = (UnitType<? extends Number>) TupleType.parse("(int" + bits + ")").get(0);

for (int i = 0; i < 1_579_919_999; i++) {
bools[(int) generateLong(r, type) & powMinus1] = true;
}

int count = 0;
for (int i = 0; i < pow; i++) {
if(!bools[i]) {
count++;
System.err.println(i);
}
}

System.out.println("missed " + count);
System.out.println(pow - count + " / " + pow + " " + (1 - ((double) count / pow)));
}

private static long generateLong(Random r, UnitType<? extends Number> unitType) {
return generateLong(r, unitType.bitLength, 1 + r.nextInt(unitType.bitLength / Byte.SIZE), unitType.unsigned);
}

private static long generateLong(Random r, int bitLen, int len, boolean unsigned) {
long val = r.nextLong();
switch (len) {
case 1: val &= 0xFFL; break;
case 2: val &= 0xFFFFL; break;
case 3: val &= 0xFFFFFFL; break;
case 4: val &= 0xFFFFFFFFL; break;
case 5: val &= 0xFFFFFFFFFFL; break;
case 6: val &= 0xFFFFFFFFFFFFL; break;
case 7: val &= 0xFFFFFFFFFFFFFFL; break;
case 8: break;
default: throw new Error();
}
val = unsigned || r.nextBoolean() ? val : val < 0 ? -(val + 1) : (-val - 1);
if(!unsigned) {
int valBitLen = val < 0 ? BizarroIntegers.bitLen(val) : Integers.bitLen(val);
if(valBitLen >= bitLen) {
val >>= 1;
}
}
return val;
}

@Test
public void testTypeSafety() throws Throwable {

Expand Down

0 comments on commit a6de535

Please sign in to comment.