Created
October 12, 2018 06:30
-
-
Save luchenqun/8163c75656eb412de20b09f28d1c793e to your computer and use it in GitHub Desktop.
合约权限单元测试
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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