1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License") 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import Core from './src/core'; 17import { DEFAULT, TestType, Size, Level, TAG, PrintTag } from './src/Constant'; 18import DataDriver from './src/module/config/DataDriver'; 19import ExpectExtend from './src/module/assert/ExpectExtend'; 20import OhReport from './src/module/report/OhReport'; 21import SysTestKit from './src/module/kit/SysTestKit'; 22import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect, beforeItSpecified, afterItSpecified, xdescribe, xit } from './src/interface'; 23import { MockKit, when } from './src/module/mock/MockKit'; 24import ArgumentMatchers from './src/module/mock/ArgumentMatchers'; 25import worker from '@ohos.worker'; 26 27class Hypium { 28 static context = new Map(); 29 static setData(data) { 30 const core = Core.getInstance(); 31 const dataDriver = new DataDriver({ data }); 32 core.addService('dataDriver', dataDriver); 33 } 34 35 static setTimeConfig(systemTime) { 36 SysTestKit.systemTime = systemTime; 37 } 38 39 static set(key, value) { 40 Hypium.context.set(key, value); 41 } 42 43 static get(key) { 44 return Hypium.context.get(key); 45 } 46 47 static hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) { 48 const core = Core.getInstance(); 49 const expectExtend = new ExpectExtend({ 50 'id': 'extend' 51 }); 52 core.addService('expect', expectExtend); 53 const ohReport = new OhReport({ 54 'delegator': abilityDelegator, 55 'abilityDelegatorArguments': abilityDelegatorArguments 56 }); 57 SysTestKit.delegator = abilityDelegator; 58 core.addService('report', ohReport); 59 core.init(); 60 core.subscribeEvent('spec', ohReport); 61 core.subscribeEvent('suite', ohReport); 62 core.subscribeEvent('task', ohReport); 63 const configService = core.getDefaultService('config'); 64 if (abilityDelegatorArguments !== null) { 65 let testParameters = configService.translateParams(abilityDelegatorArguments.parameters); 66 console.info(`${TAG}parameters:${JSON.stringify(testParameters)}`); 67 configService.setConfig(testParameters); 68 } 69 testsuite(); 70 core.execute(abilityDelegator); 71 } 72 static async hypiumInitWorkers(abilityDelegator, scriptURL, workerNum = 8, params) { 73 console.info(`${TAG}, hypiumInitWorkers call,${scriptURL}`); 74 let workerPromiseArray = []; 75 76 // 开始统计时间 77 let startTime = await SysTestKit.getRealTime(); 78 for (let i = 0; i < workerNum; i++) { 79 // 创建worker线程 80 const workerPromise = Hypium.createWorkerPromise(scriptURL, i, params); 81 workerPromiseArray.push(workerPromise); 82 } 83 const ret = {total: 0, failure: 0, error: 0, pass: 0, ignore: 0, duration: 0}; 84 Promise.all(workerPromiseArray).then(async (items) => { 85 console.info(`${TAG}, all result from workers, ${JSON.stringify(items)}`); 86 let allItemList = new Array(); 87 // 统计执行结果 88 Hypium.handleWorkerTestResult(ret, allItemList, items); 89 console.info(`${TAG}, all it result, ${JSON.stringify(allItemList)}`); 90 // 统计用例执行结果 91 const retResult = {total: 0, failure: 0, error: 0, pass: 0, ignore: 0, duration: 0}; 92 // 标记用例执行结果 93 Hypium.configWorkerItTestResult(retResult, allItemList); 94 // 打印用例结果 95 Hypium.printWorkerTestResult(abilityDelegator, allItemList); 96 // 用例执行完成统计时间 97 let endTime = await SysTestKit.getRealTime(); 98 const taskConsuming = endTime - startTime; 99 const message = 100 `\n${PrintTag.OHOS_REPORT_ALL_RESULT}: stream=Test run: runTimes: ${ret.total},total: ${retResult.total}, Failure: ${retResult.failure}, Error: ${retResult.error}, Pass: ${retResult.pass}, Ignore: ${retResult.ignore}` + 101 `\n${PrintTag.OHOS_REPORT_ALL_CODE}: ${retResult.failure > 0 || retResult.error > 0 ? -1 : 0}` + 102 `\n${PrintTag.OHOS_REPORT_ALL_STATUS}: taskconsuming=${taskConsuming > 0 ? taskConsuming : ret.duration}`; 103 abilityDelegator.printSync(message); 104 console.info(`${TAG}, [end] you worker test`); 105 abilityDelegator.finishTest('you worker test finished!!!', 0, () => {}); 106 }).catch((e) => { 107 console.info(`${TAG}, [end] error you worker test, ${JSON.stringify(e)}`); 108 abilityDelegator.finishTest('you worker test error finished!!!', 0, () => {}); 109 }).finally(() => { 110 console.info(`${TAG}, all promise finally end`); 111 }); 112 } 113 // 创建worker线程 114 static createWorkerPromise(scriptURL, i, params) { 115 console.info(`${TAG}, createWorkerPromiser, ${scriptURL}, ${i}`); 116 const workerPromise = new Promise((resolve, reject) => { 117 const workerInstance = new worker.ThreadWorker(scriptURL, {name: `worker_${i}`}); 118 console.info(`${TAG}, send data to worker`); 119 // 发送数据到worker线程中 120 workerInstance.postMessage(params); 121 workerInstance.onmessage = function (e) { 122 let currentThreadName = e.data?.currentThreadName; 123 console.info(`${TAG}, receview data from ${currentThreadName}, ${JSON.stringify(e.data)}`); 124 // 125 resolve(e.data?.summary); 126 console.info(`${TAG}, ${currentThreadName} finish`); 127 workerInstance.terminate(); 128 }; 129 workerInstance.onerror = function (e) { 130 console.info(`${TAG}, worker error, ${JSON.stringify(e)}`); 131 reject(e); 132 workerInstance.terminate(); 133 }; 134 workerInstance.onmessageerror = function (e) { 135 console.info(`${TAG}, worker message error, ${JSON.stringify(e)}`); 136 reject(e); 137 workerInstance.terminate(); 138 }; 139 }); 140 return workerPromise; 141 } 142 static handleWorkerTestResult(ret, allItemList, items) { 143 console.info(`${TAG}, handleWorkerTestResult, ${JSON.stringify(items)}`); 144 for (const {total, failure, error, pass, ignore, duration, itItemList} of items) { 145 ret.total += total; 146 ret.failure += failure; 147 ret.error += error; 148 ret.pass += pass; 149 ret.ignore += ignore; 150 ret.duration += duration; 151 Hypium.handleItResult(allItemList, itItemList); 152 } 153 } 154 static handleItResult(allItemList, itItemList) { 155 // 遍历所有的用例结果统计最终结果 156 for (const {currentThreadName, description, result} of itItemList) { 157 let item = allItemList.find((it) => it.description === description); 158 if (item) { 159 let itResult = item.result; 160 // 当在worker中出现一次failure就标记为failure, 出现一次error就标记为error, 所有线程都pass才标记为pass 161 if (itResult === 0) { 162 item.result = result; 163 item.currentThreadName = currentThreadName; 164 } 165 } else { 166 let it = { 167 description: description, 168 currentThreadName: currentThreadName, 169 result: result 170 }; 171 allItemList.push(it); 172 } 173 } 174 } 175 static configWorkerItTestResult(retResult, allItemList) { 176 console.info(`${TAG}, configWorkerItTestResult, ${JSON.stringify(allItemList)}`); 177 for (const {currentThreadName, description, result} of allItemList) { 178 console.info(`${TAG}, description, ${description}, result,${result}`); 179 retResult.total ++; 180 if (result === 0) { 181 retResult.pass ++; 182 } else if (result === -1) { 183 retResult.error ++; 184 } else if (result === -2) { 185 retResult.failure ++; 186 } else { 187 retResult.ignore ++; 188 } 189 } 190 } 191 static printWorkerTestResult(abilityDelegator, allItemList) { 192 console.info(`${TAG}, printWorkerTestResult, ${JSON.stringify(allItemList)}`); 193 let index = 1; 194 for (const {currentThreadName, description, result} of allItemList) { 195 console.info(`${TAG}, description print, ${description}, result,${result}`); 196 let itArray = description.split('#'); 197 let des; 198 let itName; 199 if (itArray.length > 1) { 200 des = itArray[0]; 201 itName = itArray[1]; 202 } else if (itArray.length > 1) { 203 des = itArray[0]; 204 itName = itArray[0]; 205 } else { 206 des = 'undefined'; 207 itName = 'undefined'; 208 } 209 210 let msg = `\n${PrintTag.OHOS_REPORT_WORKER_STATUS}: class=${des}`; 211 msg += `\n${PrintTag.OHOS_REPORT_WORKER_STATUS}: test=${itName}`; 212 msg += `\n${PrintTag.OHOS_REPORT_WORKER_STATUS}: current=${index}`; 213 msg += `\n${PrintTag.OHOS_REPORT_WORKER_STATUS}: CODE=${result}`; 214 abilityDelegator.printSync(msg); 215 index ++; 216 } 217 } 218 static hypiumWorkerTest(abilityDelegator, abilityDelegatorArguments, testsuite, workerPort) { 219 console.info(`${TAG}, hypiumWorkerTest call`); 220 SysTestKit.workerPort = workerPort; 221 let currentWorkerName = workerPort.name; 222 console.info(`${TAG}, hypiumWorkerTest_currentWorkerName: ${currentWorkerName}`); 223 Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite); 224 225 } 226 227 static registerAssert(customAssertion) { 228 const core = Core.getInstance(); 229 const expectService = core.getDefaultService('expect'); 230 let matchers = {}; 231 matchers[customAssertion.name] = customAssertion; 232 expectService.addMatchers(matchers); 233 expectService.customMatchers.push(customAssertion.name); 234 console.info(`${TAG}success to register the ${customAssertion.name}`); 235 } 236 237 static unregisterAssert(customAssertion) { 238 const core = Core.getInstance(); 239 const expectService = core.getDefaultService('expect'); 240 let customAssertionName = typeof customAssertion === 'function' ? customAssertion.name : customAssertion; 241 expectService.removeMatchers(customAssertionName); 242 console.info(`${TAG}success to unregister the ${customAssertionName}`); 243 } 244 245} 246 247export { 248 Hypium, 249 Core, 250 DEFAULT, 251 TestType, 252 Size, 253 Level, 254 DataDriver, 255 ExpectExtend, 256 OhReport, 257 SysTestKit, 258 describe, beforeAll, beforeEach, afterEach, afterAll, it, expect, beforeItSpecified, afterItSpecified, xdescribe, xit, 259 MockKit, when, 260 ArgumentMatchers 261};