Skip to content

Instantly share code, notes, and snippets.

@luchenqun
Created October 12, 2018 06:30
Show Gist options
  • Select an option

  • Save luchenqun/8163c75656eb412de20b09f28d1c793e to your computer and use it in GitHub Desktop.

Select an option

Save luchenqun/8163c75656eb412de20b09f28d1c793e to your computer and use it in GitHub Desktop.
合约权限单元测试
const mocha = require("mocha");
const expect = require("chai").expect;
const Web3 = require("web3");
const axios = require("axios");
require("mocha-steps");
// setting begin
const url = "http://10.10.8.160:6789";
const pwd = "12345678";
const address = {
ExtendedCall: "0x00000000000000000000000000000000000000ec",
RegisterManager: "0x0000000000000000000000000000000000000011",
Test: "0x0000000000000000000000000000001234567890"
};
const extendedCallAbi = [
{
constant: false,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }],
name: "clearForbidPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }],
name: "clearAllowPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }, { name: "_funcName", type: "string" }],
name: "addAllowPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: true,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }],
name: "getAllowPermission",
outputs: [{ name: "_ret", type: "string" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }, { name: "_funcName", type: "string" }],
name: "clearForbidFuncPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }],
name: "clearAllAllowPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: true,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }],
name: "getForbidPermission",
outputs: [{ name: "_ret", type: "string" }],
payable: false,
type: "function"
},
{
constant: true,
inputs: [{ name: "_contract", type: "string" }],
name: "firewall",
outputs: [{ name: "_ret", type: "uint256" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }],
name: "openFirewall",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: true,
inputs: [{ name: "_contract", type: "string" }],
name: "author",
outputs: [{ name: "_ret", type: "string" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }],
name: "closeFirewall",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }, { name: "_funcName", type: "string" }],
name: "addForbidPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }, { name: "_caller", type: "string" }, { name: "_funcName", type: "string" }],
name: "clearAllowFuncPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
},
{
constant: false,
inputs: [{ name: "_contract", type: "string" }],
name: "clearAllForbidPermission",
outputs: [{ name: "_ret", type: "bool" }],
payable: false,
type: "function"
}
];
const registerManagerAbi = [
{
constant: true,
inputs: [{ name: "_pageNum", type: "uint256" }, { name: "_pageSize", type: "uint256" }],
name: "getRegisteredContract",
outputs: [{ name: "_json", type: "string" }],
payable: false,
type: "function"
},
{ inputs: [], payable: false, type: "constructor" }
];
const monitorTestAbi = [
{
constant: false,
inputs: [{ name: "amount", type: "uint256" }],
name: "set",
outputs: [{ name: "", type: "address" }, { name: "", type: "uint256" }],
payable: false,
type: "function"
},
{
constant: true,
inputs: [],
name: "get",
outputs: [{ name: "", type: "uint256" }],
payable: false,
type: "function"
},
{ inputs: [], payable: false, type: "constructor" }
];
// setting end
function getId() {
Date.prototype.Format = function(fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
S: this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
return fmt;
};
let id = parseInt(new Date().Format("hhmmss"));
return id;
}
let client = axios.create({
baseURL: url
});
client.dispatch = async data => {
let replay = await client.post("", data);
return new Promise((resolve, reject) => {
if (replay.status === 200) {
resolve(replay.data.result);
} else {
reject("request error");
}
});
};
const web3 = new Web3(url);
var testCaseIndex = 1;
var skip = it.skip;
var only = it.only;
let ret = {};
let updatePermission = async (extendedCall, contractAddress, author, caller, funcName, callFunc) => {
let inputArr = [contractAddress];
caller && inputArr.push(caller);
funcName && inputArr.push(funcName);
let func = extendedCall.methods[callFunc].apply(extendedCall.methods, inputArr);
let options = {
gas: "0xe8d4a50fff",
gasPrice: "0x174876e800",
from: author
};
replay = await func.send(options);
return replay;
};
describe("开始合约权限测试...", function() {
before(function() {
console.log("before...");
// 在本区块的所有测试用例之前执行
});
step("Test Case " + testCaseIndex++ + " 获取后台账号", async function(done) {
let data = {
method: "eth_accounts",
jsonrpc: "2.0",
id: parseInt(getId()),
params: []
};
try {
let replay = await client.dispatch(data);
expect(replay).to.have.length.least(2);
ret["accounts"] = replay;
done();
} catch (error) {
done(error);
}
});
step("Test Case " + testCaseIndex++ + " 解锁账号", async function(done) {
for (const account of ret["accounts"]) {
let data = {
method: "personal_unlockAccount",
jsonrpc: "2.0",
id: parseInt(getId()),
params: [account, pwd, 24 * 60 * 60]
};
try {
let replay = await client.dispatch(data);
expect(replay).to.be.equal(true);
} catch (error) {
done(error);
}
}
done();
});
step("Test Case " + testCaseIndex++ + " 获取 MonitorTest 合约地址", async function(done) {
try {
let contract = new web3.eth.Contract(registerManagerAbi, address["RegisterManager"], null);
let from = ret["accounts"][0];
let func = contract.methods["getRegisteredContract"].apply(contract.methods, [0, 1000]);
let replay = await func.call({ from: from });
let replayObj = JSON.parse(replay);
let items = replayObj.data.items;
for (const item of items) {
let contractName = item.contractName;
let address = item.address;
if (contractName && address && contractName === "MonitorTest") {
ret["MonitorTestAddress"] = address;
done();
break;
}
}
!ret["MonitorTestAddress"] && done("not found MonitorTest address");
} catch (error) {
done(error);
}
});
step("Test Case " + testCaseIndex++ + " 获取 MonitorTest 发布人员地址", async function(done) {
try {
let contract = new web3.eth.Contract(extendedCallAbi, address["ExtendedCall"], null);
let from = ret["accounts"][0];
let func = contract.methods["author"].apply(contract.methods, [ret["MonitorTestAddress"]]);
let replay = await func.call({ from: from });
ret["author"] = replay;
for (const account of ret["accounts"]) {
if (account !== ret["author"]) {
ret["caller"] = account;
break;
}
}
done();
} catch (error) {
done(error);
}
});
step("Test Case " + testCaseIndex++ + " 测试关闭打开防火墙 closeFirewall openFirewall", async function(done) {
try {
let contract = new web3.eth.Contract(extendedCallAbi, address["ExtendedCall"], null);
let from = ret["author"];
let callFuncs = ["closeFirewall", "openFirewall"];
let expectRet = {
closeFirewall: "1",
openFirewall: "0"
};
for (const callFunc of callFuncs) {
let func = contract.methods[callFunc].apply(contract.methods, [ret["MonitorTestAddress"]]);
let options = {
gas: "0xe8d4a50fff",
gasPrice: "0x174876e800",
from: from
};
let replay = await func.send(options);
expect(replay).to.be.an.instanceof(Object);
func = contract.methods["firewall"].apply(contract.methods, [ret["MonitorTestAddress"]]);
replay = await func.call({ from: from });
expect(replay).to.be.equal(expectRet[callFunc]);
}
done();
} catch (error) {
done(error);
}
});
// 6
step("Test Case " + testCaseIndex++ + " 测试清除合约所有权限 clearAllAllowPermission clearAllForbidPermission ", async function(done) {
try {
let contract = new web3.eth.Contract(extendedCallAbi, address["ExtendedCall"], null);
let from = ret["author"];
let func, replay;
let callFuncs = ["clearAllAllowPermission", "clearAllForbidPermission"];
let callers = [ret["caller"], address["Test"]];
for (const callFunc of callFuncs) {
replay = await updatePermission(contract, ret["MonitorTestAddress"], from, null, null, callFunc);
expect(replay).to.be.an.instanceof(Object);
}
let callGetPermissionFuncs = ["getAllowPermission", "getForbidPermission"];
for (const callFunc of callGetPermissionFuncs) {
for (const caller of callers) {
func = contract.methods[callFunc].apply(contract.methods, [ret["MonitorTestAddress"], caller]);
try {
replay = await func.call({ from: from });
expect(replay).to.equal("[]");
} catch (error) {
}
}
}
done();
} catch (error) {
done(error);
}
});
// 7
step("Test Case " + testCaseIndex++ + " 测试添加允许权限与禁止权限 addAllowPermission addForbidPermission ", async function(done) {
try {
let contract = new web3.eth.Contract(extendedCallAbi, address["ExtendedCall"], null);
let from = ret["author"];
let func, replay;
let callAddPermissionFuncs = ["addAllowPermission", "addForbidPermission"];
let funcNames = ["set(uint256)", "get()", "hello()", "world()"];
let callers = [ret["caller"], address["Test"]];
for (const funcName of funcNames) {
for (const callFunc of callAddPermissionFuncs) {
for (const caller of callers) {
let replay = await updatePermission(contract, ret["MonitorTestAddress"], from, caller, funcName, callFunc);
expect(replay).to.be.an.instanceof(Object);
}
}
}
let callGetPermissionFuncs = ["getAllowPermission", "getForbidPermission"];
for (const callFunc of callGetPermissionFuncs) {
for (const caller of callers) {
func = contract.methods[callFunc].apply(contract.methods, [ret["MonitorTestAddress"], caller]);
replay = await func.call({ from: from });
expect(JSON.parse(replay)).to.deep.equal(funcNames);
}
}
done();
} catch (error) {
done(error);
}
});
step("Test Case " + testCaseIndex++ + " 测试清除单个禁入允许函数 clearAllowFuncPermission clearForbidFuncPermission", async function(done) {
try {
let contract = new web3.eth.Contract(extendedCallAbi, address["ExtendedCall"], null);
let from = ret["author"];
let callFuncs = ["clearAllowFuncPermission", "clearForbidFuncPermission"];
let getFuncs = {
clearAllowFuncPermission: "getAllowPermission",
clearForbidFuncPermission: "getForbidPermission"
};
let funcName = "world()";
for (const callFunc of callFuncs) {
let replay = await updatePermission(contract, ret["MonitorTestAddress"], from, address["Test"], funcName, callFunc);
expect(replay).to.be.an.instanceof(Object);
func = contract.methods[getFuncs[callFunc]].apply(contract.methods, [ret["MonitorTestAddress"], address["Test"]]);
replay = await func.call({ from: from });
expect(JSON.parse(replay)).to.deep.equal(["set(uint256)", "get()", "hello()"]);
}
done();
} catch (error) {
done(error);
}
});
// 9
step("Test Case " + testCaseIndex++ + " 测试清除某个调用者禁入允许函数 clearAllowPermission clearForbidPermission", async function(done) {
try {
let contract = new web3.eth.Contract(extendedCallAbi, address["ExtendedCall"], null);
let from = ret["author"];
let callFuncs = ["clearAllowPermission", "clearForbidPermission"];
let getFuncs = {
clearAllowPermission: "getAllowPermission",
clearForbidPermission: "getForbidPermission"
};
for (const callFunc of callFuncs) {
let replay = await updatePermission(contract, ret["MonitorTestAddress"], from, address["Test"], null, callFunc);
expect(replay).to.be.an.instanceof(Object);
func = contract.methods[getFuncs[callFunc]].apply(contract.methods, [ret["MonitorTestAddress"], address["Test"]]);
replay = await func.call({ from: from });
expect(JSON.parse(replay)).to.deep.equal([]);
}
done();
} catch (error) {
done(error);
}
});
step("Test Case " + testCaseIndex++ + " 测试权限对 MonitorTest 调用", async function(done) {
try {
let contractExtendedCall = new web3.eth.Contract(extendedCallAbi, address["ExtendedCall"], null);
let contractMonitorTest = new web3.eth.Contract(monitorTestAbi, ret["MonitorTestAddress"], null);
let from = ret["author"];
let caller = ret["caller"];
let sendNum = parseInt(Math.random() * 10000);
let callerSendNum = parseInt(Math.random() * 10000);
let options = {
gas: "0xe8d4a50fff",
gasPrice: "0x174876e800",
from: from
};
let func, replay;
ret["sendNum"] = sendNum;
ret["callerSendNum"] = callerSendNum;
// 自己调用
func = contractMonitorTest.methods["set"].apply(contractMonitorTest.methods, [sendNum]);
options.from = from;
replay = await func.send(options);
expect(replay).to.be.an.instanceof(Object);
func = contractMonitorTest.methods["get"].apply(contractMonitorTest.methods, []);
replay = await func.call({ from: from });
expect(parseInt(replay)).to.equal(sendNum);
// 给get()函数权限
replay = await updatePermission(contractExtendedCall, ret["MonitorTestAddress"], from, ret["caller"], "get()", "clearForbidFuncPermission");
expect(replay).to.be.an.instanceof(Object);
// set(uint256) 禁入
func = contractMonitorTest.methods["set"].apply(contractMonitorTest.methods, [callerSendNum]);
options.from = caller;
replay = await func.send(options);
func = contractMonitorTest.methods["get"].apply(contractMonitorTest.methods, []);
replay = await func.call({ from: caller });
expect(parseInt(replay)).to.equal(sendNum); // 还是应该等于发布者设置的
// 给set(uint256)函数权限
replay = await updatePermission(contractExtendedCall, ret["MonitorTestAddress"], from, ret["caller"], "set(uint256)", "clearForbidFuncPermission");
expect(replay).to.be.an.instanceof(Object);
// set(uint256) 允许调用
func = contractMonitorTest.methods["set"].apply(contractMonitorTest.methods, [callerSendNum]);
options.from = caller;
replay = await func.send(options);
func = contractMonitorTest.methods["get"].apply(contractMonitorTest.methods, []);
replay = await func.call({ from: caller });
expect(parseInt(replay)).to.equal(callerSendNum); // 应该等于自己设置的
done();
} catch (error) {
done(error);
}
});
step("Test Case " + testCaseIndex++ + " 测试 eth_getCallPermissions", async function(done) {
let data = {
method: "eth_getCallPermissions",
jsonrpc: "2.0",
id: parseInt(getId()),
params: [ ret["MonitorTestAddress"], "latest" ]
};
try {
let replay = await client.dispatch(data);
ret[ret["MonitorTestAddress"]] = replay;
done();
} catch (error) {
done(error);
}
});
step("Test Case " + testCaseIndex++ + " 测试 eth_getFirewallState", async function(done) {
let data = {
method: "eth_getFirewallState",
jsonrpc: "2.0",
id: parseInt(getId()),
params: [ ret["MonitorTestAddress"], "latest" ]
};
try {
let replay = await client.dispatch(data);
ret["FirewallState"] = replay;
done();
} catch (error) {
done(error);
}
});
after(function() {
// 在本区块的所有测试用例之后执行
console.log("after...");
console.log(JSON.stringify(ret, undefined, 4));
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment