1/*
2 * Copyright (C) 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 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
16const path = require('path');
17const async = require('async');
18const { test, runHvigor } = require('./main/cmd.js');
19const { prepareHostEnv } = require("./main/gitee_rest_api.js");
20const { readDir, deleteDir, renameDir } = require("./utils/file.js");
21const { generateHTML } = require("./main/collect_results_and_visualize.js");
22const { getDateTime } = require("./utils/date.js");
23const { getNodePIDs, deleteNodePIDs } = require("./utils/sys.js");
24const { parseJson } = require('./utils/json.js');
25const { readJson } = require("./utils/json");
26
27module.exports = { main };
28
29const args = process.argv.slice(2);
30const originUrl = args[0];
31const testFilePath = args[1];
32
33function Parameters(sdkPath, access_token, downloadPath, resultPath, casePath, devEcoPath, concurrentQuantity) {
34    this.sdkPath = sdkPath;
35    this.access_token = access_token;
36    this.downloadPath = downloadPath;
37    this.resultPath = resultPath;
38    this.casePath = casePath;
39    this.devEcoPath = devEcoPath;
40    this.concurrentQuantity = concurrentQuantity;
41}
42
43const createQueueWithHvigor = () => {
44    return async.queue(async (param, callback) => {
45        await runHvigor(param.sdkPath, param.testFile, param.resultPath, param.casePath, param.ohpmBat, param.nodePath
46            , param.hvigorPath);
47        callback();
48    }, 1);
49};
50
51const createQueueWithConcurrency = (concurrencyLimit) => {
52    return async.queue(async (param, callback) => {
53        await test(param.sdkPath, param.testFile, param.resultPath, param.casePath, param.ohpmBat, param.nodePath
54            , param.hvigorPath);
55        callback();
56    }, concurrencyLimit);
57};
58
59function TestParam(sdkPath, testFile, resultPath, casePath, ohpmBat, nodePath, hvigorPath) {
60    this.sdkPath = sdkPath;
61    this.testFile = testFile;
62    this.resultPath = resultPath;
63    this.casePath = casePath;
64    this.ohpmBat = ohpmBat;
65    this.nodePath = nodePath;
66    this.hvigorPath = hvigorPath;
67}
68
69async function run(url, htmlName, testFiles, downloadPath, resultFolder, sdkPath, casePath,
70    concurrentQuantity, datetime, ohpmBat, nodePath, hvigorPath) {
71    let startTime = new Date().getTime();
72    let downloadResultPath = path.join(downloadPath, "downloadResult");
73    await prepareHostEnv(url, downloadResultPath, sdkPath)
74        .catch(error => {
75            throw error;
76        });
77    let originPIDs = await getNodePIDs();
78    let projectName = "";
79    const queueHvigor = createQueueWithHvigor();
80    for (let i = 0; i < testFiles.length; i++) {
81        const resultPath = path.join(resultFolder, datetime, testFiles[i][0]);
82        let testFile = testFiles[i];
83        if (projectName !== testFile[0]) {
84            queueHvigor.push(new TestParam(sdkPath, testFile, resultPath, casePath, ohpmBat, nodePath, hvigorPath));
85            projectName = testFile[0];
86        }
87    }
88    queueHvigor.drain(() => {
89        const queue = createQueueWithConcurrency(concurrentQuantity);
90        for (let i = 0; i < testFiles.length; i++) {
91            const resultPath = path.join(resultFolder, datetime, testFiles[i][0]);
92            let testFile = testFiles[i];
93            queue.push(new TestParam(sdkPath, testFile, resultPath, casePath, ohpmBat, nodePath, hvigorPath));
94        }
95        queue.drain(async () => {
96            const htmlPath = path.join(resultFolder, datetime);
97            readDir(htmlPath)
98                .then((file, err) => {
99                    if (err) {
100                        console.error(err);
101                    }
102                    if (file.length > 0) {
103                        generateHTML(htmlPath, htmlName, startTime);
104                    } else {
105                        console.error('resultPath directory is empty.');
106                    }
107                });
108            getNodePIDs()
109                .then((pIds, err) => {
110                    if (err) {
111                        console.error(err);
112                    }
113                    let runOverPIDs = [...pIds];
114                    for (let i = 0; i < originPIDs.length; i++) {
115                        for (let j = 0; j < runOverPIDs.length; j++) {
116                            if (originPIDs[i] === runOverPIDs[j]) {
117                                runOverPIDs.splice(j, 1);
118                            }
119                        }
120                    }
121                    deleteNodePIDs(runOverPIDs)
122                        .then((code, err) => {
123                            if (err) {
124                                console.error(err);
125                            }
126                        }).catch((error) => {
127                            console.error(error);
128                        });
129                });
130            await deleteDir(sdkPath);
131            await renameDir(`${sdkPath}-backup`, sdkPath);
132        })
133    });
134}
135
136async function main() {
137    const testFiles = await parseJson(testFilePath);
138    const datetime = getDateTime();
139    let prNumber = originUrl.split("/")[originUrl.split("/").length - 1];
140    const htmlName = `${datetime}_${prNumber}.html`;
141    let jsonData = parseJson('param.json');
142    let param = new Parameters(jsonData.sdkPath, jsonData.access_token, jsonData.downloadPath, jsonData.resultPath,
143        jsonData.casePath, jsonData.devEcoPath, jsonData.concurrentQuantity);
144    let ohpmBat = `${param.devEcoPath}\\tools\\ohpm\\bin\\ohpm.bat`;
145    let nodePath = `${param.devEcoPath}\\tools\\node\\node.exe`;
146    let hvigorPath = `${param.devEcoPath}\\tools\\hvigor\\bin\\hvigorw.js`;
147    try {
148        const evolveUrl = originUrl.slice(18);
149        let requestUrl =
150            `https://gitee.com/api/v5/repos/${evolveUrl}/comments?access_token=${param.access_token}` +
151            `&page=1&per_page=50&direction=desc`;
152        await run(requestUrl, htmlName, testFiles, param.downloadPath, param.resultPath, param.sdkPath,
153            param.casePath, jsonData.concurrentQuantity, datetime, ohpmBat, nodePath, hvigorPath)
154            .catch(err => {
155                throw err;
156            });
157    } catch (err) {
158        process.exit(1);
159        throw err;
160    }
161}
162
163main();