Skip to content

Commit

Permalink
fix quadratic random tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vgorin committed Feb 10, 2019
1 parent c672ceb commit ad33b17
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 26 deletions.
9 changes: 6 additions & 3 deletions contracts/RandomTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,17 @@ contract RandomTest {
* @param n how many grade values to generate
* @return an array of grade values of length n
*/
function randomGradeValues(uint32 n) public constant returns(uint24[]) {
function randomGradeValues(uint32 n, uint32 iterations) public constant returns(uint24[]) {
// declare a container to store all the generated grades
uint24[] memory result = new uint24[](n);

// generate amount of random grade values requested
for(uint32 i = 0; i < n; i++) {
// generate random using exactly the same logic as in Workshop.randomGradeValue
result[i] = uint24(Random.__quadraticRandom(i, 0, GRADE_VALUES));
// perform `iterations` number of iterations
for(uint32 j = 0; j < iterations; j++) {
// generate random using exactly the same logic as in Workshop.randomGradeValue,
result[i] = uint24(Random.__quadraticRandom(i, result[i], GRADE_VALUES - result[i]));
}
}

// return the result
Expand Down
2 changes: 1 addition & 1 deletion test/gold_silver.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ contract('GoldERC20', (accounts) => {
assert.equal(amt, await tk.balanceOf(player2), "wrong player 2 balance after several transfers");
});

it("minting and burning: minting, burning, zer-value checks", async() => {
it("minting and burning: minting, burning, zero-value checks", async() => {
const tk = await Gold.new();

// token creator
Expand Down
55 changes: 33 additions & 22 deletions test/workshop_rnd.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ contract('Workshop (RND)', (accounts) => {
// verify GRADE_VALUES constant is the same in both smart contracts
assert((await rndTest.GRADE_VALUES()).eq(await workshop.GRADE_VALUES()), "GRADE_VALUES mismatch");
});
it("random: verify properties required", async() => {
it("random: generate a set of iterations for grade values", async() => {
// construct random test helper smart contract
const rndTest = await RandomTest.new();

Expand All @@ -47,40 +47,51 @@ contract('Workshop (RND)', (accounts) => {
// maximum possible grade value
const maxGrade = (await rndTest.GRADE_VALUES()).toNumber();

// generate some amount of random grade values
const gradeValues = await rndTest.randomGradeValues(n);
// call a function to generate n iterations n = [1, 6]
for(let i = 0; i < 6; i++) {
await generateN(rndTest, n, i + 1, maxGrade);
}
});
});

async function generateN(rndTest, n, i, maxGrade) {
assert(i > 0, "incorrect n!");

// generate some amount of random grade values
const gradeValues = await rndTest.randomGradeValues(n, i);

// sort the array
gradeValues.sort((a, b) => a.minus(b).toNumber());
// sort the array
gradeValues.sort((a, b) => a.minus(b).toNumber());

// write statistical raw data into the file
fs.writeFileSync("./quadratic_random_" + TEST_DEPTH + ".csv", gradeValues.map((a) => a.toNumber()).join("\n"));
// write statistical raw data into the file
fs.writeFileSync("./quadratic_random_" + TEST_DEPTH + "_" + i + ".csv", gradeValues.map((a) => a.toNumber()).join("\n"));

// calculate the minimum
const min = gradeValues[0].toNumber();
// calculate the minimum
const min = gradeValues[0].toNumber();

// calculate the maximum
const max = gradeValues[gradeValues.length - 1].toNumber();
// calculate the maximum
const max = gradeValues[gradeValues.length - 1].toNumber();

// calculate an average
const avg = gradeValues.reduce((a, b) => a.plus(b), web3.toBigNumber(0)).dividedToIntegerBy(gradeValues.length).toNumber();
// calculate an average
const avg = gradeValues.reduce((a, b) => a.plus(b), web3.toBigNumber(0)).dividedToIntegerBy(gradeValues.length).toNumber();

// calculate the median
const median = gradeValues[Math.floor(gradeValues.length / 2)].toNumber();
// calculate the median
const median = gradeValues[Math.floor(gradeValues.length / 2)].toNumber();

// print the values into the console
console.log("\tmin: %o\n\tmax: %o\n\tavg: %o\n\tmed: %o", min, max, avg, median);
// print the values into the console
console.log("\t%o iteration(s)\n\t\tmin: %o\n\t\tmax: %o\n\t\tavg: %o\n\t\tmed: %o", i, min, max, avg, median);

if(i === 1) {
// verify the distribution properties are correct
assertEqualWith(0, min, 1000, "wrong minimum");
assertEqualWith(maxGrade, max, 100000, "wrong maximum");
assertEqualWith(maxGrade / 4, avg, 25000, "wrong average");
}

// verify random didn't exceed the bounds
assert(min >= 0, "minimum less than zero!");
assert(max < 1000000, "maximum exceeded 1000000!");
});
});
// verify random didn't exceed the bounds
assert(min >= 0, "minimum less than zero!");
assert(max < maxGrade, "maximum exceeded GRADE_VALUES!");
}


// asserts equal with the precisions defined in leeway (absolute value)
Expand Down

0 comments on commit ad33b17

Please sign in to comment.