You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2021/05/10 06:37:40 UTC

[echarts] 02/02: test(visual): fix url loading error may block. add threads in cli

This is an automated email from the ASF dual-hosted git repository.

shenyi pushed a commit to branch enhance-visual-regression-test
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 568bf0085732ba326b9508a3b47723affa3f5b4d
Author: pissang <bm...@gmail.com>
AuthorDate: Mon May 10 14:36:16 2021 +0800

    test(visual): fix url loading error may block. add threads in cli
---
 test/dataZoom-action.html      |  4 +--
 test/lib/simpleRequire.js      | 18 +++++++++--
 test/runTest/cli.js            | 49 +++++++++++++++-------------
 test/runTest/task.js           | 72 ++++++++++++++++++++++++++++++++++++++++++
 test/scatter-stream-large.html |  4 +--
 5 files changed, 118 insertions(+), 29 deletions(-)

diff --git a/test/dataZoom-action.html b/test/dataZoom-action.html
index 48e24f7..d9be2d1 100644
--- a/test/dataZoom-action.html
+++ b/test/dataZoom-action.html
@@ -22,12 +22,12 @@ under the License.
     <head>
         <meta charset="utf-8">
         <meta name="viewport" content="width=device-width, initial-scale=1" />
-        <script src="lib/simpleRequire.js"></script>
-        <script src="lib/config.js"></script>
         <script src="../dist/echarts.js"></script>
         <script src="lib/testHelper.js"></script>
         <script src="lib/facePrint.js"></script>
         <script src="lib/jquery.min.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/simpleRequire.js"></script>
         <link rel="stylesheet" href="lib/reset.css" />
     </head>
     <body>
diff --git a/test/lib/simpleRequire.js b/test/lib/simpleRequire.js
index a82f2ca..004c9d3 100644
--- a/test/lib/simpleRequire.js
+++ b/test/lib/simpleRequire.js
@@ -58,6 +58,18 @@
     // Promise to get modules exports.
     var mods = {};
 
+    function handleLoadError(url, resolve, reject) {
+        var errMsg = 'require: failed to load ' + url;
+        if (typeof __VRT_LOAD_ERROR__ !== 'undefined') {
+            // Not block the visual regression testing.
+            __VRT_LOAD_ERROR__(errMsg);
+            resolve();
+        }
+        else {
+            reject(errMsg);
+        }
+    }
+
     function loadText(url) {
         return new Promise(function (resolve, reject) {
             var xhr = new XMLHttpRequest();
@@ -66,11 +78,11 @@
                     resolve(xhr.responseText);
                 }
                 else {
-                    reject('require: failed to load ' + url);
+                    handleLoadError(url, resolve, reject);
                 }
             }
             xhr.onerror = function (e) {
-                reject('require: failed to load ' + url);
+                handleLoadError(url, resolve, reject);
             }
             xhr.open('GET', url);
             xhr.send();
@@ -91,7 +103,7 @@
                 resolve();
             }
             script.onerror = function () {
-                reject('require: failed to load ' + url);
+                handleLoadError(url, resolve, reject);
             }
             script.src = url;
             document.head.appendChild(script);
diff --git a/test/runTest/cli.js b/test/runTest/cli.js
index 432cd46..676b7e4 100644
--- a/test/runTest/cli.js
+++ b/test/runTest/cli.js
@@ -30,6 +30,7 @@ const {testNameFromFile, fileNameFromTest, getVersionDir, buildRuntimeCode, getE
 const {origin} = require('./config');
 const cwebpBin = require('cwebp-bin');
 const { execFile } = require('child_process');
+const {runTasks} = require('./task');
 
 // Handling input arguments.
 program
@@ -39,6 +40,7 @@ program
     .option('--expected <expected>', 'Expected version')
     .option('--actual <actual>', 'Actual version')
     .option('--renderer <renderer>', 'svg/canvas renderer')
+    .option('--threads', 'How many threads to run concurrently')
     .option('--no-save', 'Don\'t save result')
     .option('--dir <dir>', 'Out dir');
 
@@ -46,6 +48,7 @@ program.parse(process.argv);
 
 program.speed = +program.speed || 1;
 program.actual = program.actual || 'local';
+program.threads = +program.threads || 1;
 program.renderer = (program.renderer || 'canvas').toLowerCase();
 program.dir = program.dir || (__dirname + '/tmp');
 
@@ -194,6 +197,9 @@ async function runTestPage(browser, testOpt, version, runtimeCode, isExpected) {
     await page.exposeFunction('__VRT_MOUSE_UP__', async () =>  {
         await page.mouse.up();
     });
+    await page.exposeFunction('__VRT_LOAD_ERROR__', async (err) =>  {
+        errors.push(err);
+    });
     // await page.exposeFunction('__VRT_WAIT_FOR_NETWORK_IDLE__', async () =>  {
     //     await waitForNetworkIdle();
     // });
@@ -272,7 +278,7 @@ async function runTestPage(browser, testOpt, version, runtimeCode, isExpected) {
 
         let actions = [];
         try {
-            let actContent = fs.readFileSync(path.join(__dirname, 'actions', testOpt.name + '.json'));
+            let actContent = await fse.readFile(path.join(__dirname, 'actions', testOpt.name + '.json'));
             actions = JSON.parse(actContent);
         }
         catch (e) {}
@@ -347,9 +353,11 @@ async function runTest(browser, testOpt, runtimeCode, expectedVersion, actualVer
 
                 // Remove png files
                 try {
-                    fs.unlinkSync(actual.rawScreenshotPath);
-                    fs.unlinkSync(expected.rawScreenshotPath);
-                    fs.unlinkSync(diffPath);
+                    await Promise.all([
+                        fse.unlink(actual.rawScreenshotPath),
+                        fse.unlink(expected.rawScreenshotPath),
+                        fse.unlink(diffPath)
+                    ]);
                 }
                 catch (e) {}
             }
@@ -393,26 +401,23 @@ async function runTests(pendingTests) {
         browser.close();
     });
 
-    try {
-        for (let testOpt of pendingTests) {
-            console.log(`Running test: ${testOpt.name}, renderer: ${program.renderer}`);
-            try {
-                await runTest(browser, testOpt, runtimeCode, program.expected, program.actual);
-            }
-            catch (e) {
-                // Restore status
-                testOpt.status = 'unsettled';
-                console.log(e);
-            }
+    console.log('Running threads: ', program.threads);
 
-            if (program.save) {
-                process.send(testOpt);
-            }
+    await runTasks(pendingTests, async (testOpt) => {
+        console.log(`Running test: ${testOpt.name}, renderer: ${program.renderer}`);
+        try {
+            await runTest(browser, testOpt, runtimeCode, program.expected, program.actual);
         }
-    }
-    catch(e) {
-        console.log(e);
-    }
+        catch (e) {
+            // Restore status
+            testOpt.status = 'unsettled';
+            console.log(e);
+        }
+
+        if (program.save) {
+            process.send(testOpt);
+        }
+    }, program.threads);
 
     await browser.close();
 }
diff --git a/test/runTest/task.js b/test/runTest/task.js
new file mode 100644
index 0000000..44d50dc
--- /dev/null
+++ b/test/runTest/task.js
@@ -0,0 +1,72 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+function runTasks(
+    taskParamsLists,
+    createTask,
+    concurrency
+) {
+    concurrency = Math.min(taskParamsLists.length, concurrency);
+    return new Promise((resolve, reject) => {
+        let runningTaskCount = 0;
+        let cursor = 0;
+        let rets = [];
+
+        function finishTask(res, idx) {
+            rets[idx] = res;
+            processNext();
+        }
+
+        function failTask(e) {
+            console.error(e);
+            processNext();
+        }
+
+        function processNext() {
+            runningTaskCount--;
+            addTask();
+
+            if (runningTaskCount === 0) {
+                resolve(rets);
+            }
+        }
+
+        function addTask() {
+            const param = taskParamsLists[cursor];
+            if (param) {
+                const currentTaskIdx = cursor;
+                runningTaskCount++;
+                createTask(param)
+                    .then((res) => finishTask(res, currentTaskIdx))
+                    .catch(failTask);
+                cursor++;
+            }
+        }
+
+        for (let i = 0; i < concurrency; i++) {
+            addTask();
+        }
+
+        if (!runningTaskCount) {
+            resolve(rets);
+        }
+    });
+}
+
+module.exports.runTasks = runTasks;
\ No newline at end of file
diff --git a/test/scatter-stream-large.html b/test/scatter-stream-large.html
index f1cf83e..2d87659 100644
--- a/test/scatter-stream-large.html
+++ b/test/scatter-stream-large.html
@@ -44,8 +44,8 @@ under the License.
 
         require([
             'echarts',
-            'echarts/map/js/world'
-    ], function (echarts) {
+            'map/js/world'
+        ], function (echarts) {
             var count = 35663;
             var lngCount = 1000;
             var chart;

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org