sandbox/base_test.js
Star f9dcf07ba4 first version
supported macOS、linux
2026-03-23 00:35:27 +08:00

118 lines
3.9 KiB
JavaScript

// base_test.js v1.0 测试基础功能(低代码框架测试入口)
import sandbox from 'apigo.cc/gojs/sandbox'
import co from 'apigo.cc/gojs/console'
import file from 'apigo.cc/gojs/file'
import rt from 'apigo.cc/gojs/runtime'
import u from 'apigo.cc/gojs/util'
import tt from 'testTool'
function runTest(codefile) {
let baseConfig = {
projectDir: "data",
}
let user_config = "{}"
if (codefile.endsWith('.py')) {
baseConfig.runtime = { language: "python", venv: "test", version: "3.12" }
baseConfig.startArgs = ["-c", file.read(codefile)]
file.write('data/requirements.txt', 'cowsay')
user_config = file.read(codefile).match(/"""\s*TEST_CONFIG\s*([\s\S]*?)\s*"""/)[1]
} else if (codefile.endsWith('.js')) {
file.write('data/package.json', '{"dependencies":{"cowsay":"*"}}')
baseConfig.runtime = { language: "nodejs", version: "24" }
baseConfig.startArgs = ["-e", file.read(codefile)]
user_config = file.read(codefile).match(/\/\*\s*TEST_CONFIG\s*([\s\S]*?)\s*\*\//)[1]
}
let config = { ...baseConfig, ...u.unJson(user_config) }
if (rt.os() === 'darwin') {
// Mac 系统清除不支持的配置
config.limits = {}
}
const name = config.name || codefile
try {
file.remove('data/stdout.log')
file.remove('data/stderr.log')
const sb = sandbox.start(config)
if (err = getLastError()) throw new Error(`sandbox test ${name} start failed: ` + err)
let st = sb.status()
if (st.status !== 'running') throw new Error(`sandbox test ${name} status is not running: ` + st.status)
sb.wait(10000)
if (err = getLastError()) throw new Error(`sandbox test ${name} wait failed: ` + err)
st = sb.status()
if (st.status !== 'exited') throw new Error(`sandbox test ${name} status is not exited: ` + st.status)
co.info(`sandbox test ${name} finished uptime ${st.uptime}`)
er = file.read('data/stderr.log')
if (er) throw new Error(er)
r = file.load('data/stdout.log')
if (!r || !r.testSuccess) throw new Error(`sandbox test ${name} failed`)
co.info(r)
return true
} catch (e) {
co.info(co.red(e.message), co.magenta(file.read('data/stderr.log')))
co.println(co.bCyan('stdout'), co.cyan(file.read('data/stdout.log')))
co.println(co.bMagenta('stderr'), co.magenta(file.read('data/stderr.log')))
return false
}
}
const TEST_COUNT_PER_TEST = 100
const TEST_COUNT = 10
function main() {
if (!runTest('testcase/base_allow.py')) return false
if (!runTest('testcase/base_deny.py')) return false
if (!runTest('testcase/secret.py')) return false
if (!runTest('testcase/base_allow.js')) return false
// 压力测试
let tasks = []
for (let i = 0; i < TEST_COUNT_PER_TEST; i++) {
tasks.push([`
import sandbox from 'apigo.cc/gojs/sandbox'
import u from 'apigo.cc/gojs/util'
import co from 'apigo.cc/gojs/console'
const sb = sandbox.start({
noLog: true,
startArgs: ["-c", "import time\\nprint(int(time.time() * 1000))"],
runtime: { language: "python", venv: "test", version: "3.12" },
})
u.len({ a: 1, b: 2 })
if (err = getLastError()) throw new Error(err)
return sb.wait(10000)
`])
}
let totalOkNum = 0
let totalFailNum = 0
let totalTotalTime = 0
for (let j = 0; j < TEST_COUNT; j++) {
co.info(`Dispatching ${tasks.length} tasks...`)
const startTime = Date.now()
// 执行并发任务
let results = tt.runAll(tasks)
const totalTime = Date.now() - startTime
let countTotalTime = 0
let okNum = 0
let failNum = 0
for (let i = 0; i < results.length; i++) {
const [data, err] = results[i]
if (!err) {
countTotalTime += Number(data.trim()) - startTime
okNum++
} else {
failNum++
co.info(co.red(`Task ${i} failed: ${err}`))
}
}
totalOkNum += okNum
totalFailNum += failNum
totalTotalTime += countTotalTime
co.info(`All tasks finished in ${totalTime}ms, avg ${countTotalTime / okNum}ms, ${okNum} ok, ${failNum} fail`)
file.remove('/tmp/sandbox_tests')
}
co.info(`Total: ${totalOkNum} ok, ${totalFailNum} fail, avg ${totalTotalTime / totalOkNum}ms`)
return totalFailNum === 0
}