Skip to content
This repository was archived by the owner on Aug 15, 2019. It is now read-only.

Commit ab6b88d

Browse files
WenheLIdsmilkov
authored andcommitted
Add Karma and node test for webworker (#1841)
DEV
1 parent 7704743 commit ab6b88d

8 files changed

+153
-3
lines changed

karma.conf.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ const devConfig = {
3535
frameworks: ['jasmine', 'karma-typescript'],
3636
files: ['src/setup_test.ts', {pattern: 'src/**/*.ts'}],
3737
exclude: [
38+
'src/worker_node_test.ts',
39+
'src/worker_test.ts',
3840
'src/test_node.ts',
39-
'src/test_async_backends.ts',
41+
'src/test_async_backends.ts'
4042
],
4143
preprocessors: {'**/*.ts': ['karma-typescript']},
4244
karmaTypescriptConfig,
@@ -47,8 +49,10 @@ const browserstackConfig = {
4749
frameworks: ['browserify', 'jasmine'],
4850
files: ['dist/setup_test.js', {pattern: 'dist/**/*_test.js'}],
4951
exclude: [
52+
'dist/worker_node_test.js',
53+
'dist/worker_test.js',
5054
'dist/test_node.js',
51-
'dist/test_async_backends.js',
55+
'dist/test_async_backends.js'
5256
],
5357
preprocessors: {'dist/**/*_test.js': ['browserify']},
5458
browserify: {debug: false},
@@ -57,6 +61,18 @@ const browserstackConfig = {
5761
hostname: 'bs-local.com',
5862
};
5963

64+
const webworkerConfig = {
65+
...browserstackConfig,
66+
files: [
67+
'dist/setup_test.js',
68+
'dist/worker_test.js',
69+
// Serve dist/tf-core.js as a static resource, but do not include in the test runner
70+
{pattern: 'dist/tf-core.js', included: false}
71+
],
72+
exclude: [],
73+
port: 12345
74+
};
75+
6076
module.exports = function(config) {
6177
const args = [];
6278
// If no test environment is set unit tests will run against all registered
@@ -70,7 +86,18 @@ module.exports = function(config) {
7086
if (config.flags) {
7187
args.push('--flags', config.flags);
7288
}
73-
const extraConfig = config.browserstack ? browserstackConfig : devConfig;
89+
90+
91+
let extraConfig = null;
92+
93+
if (config.worker) {
94+
extraConfig = webworkerConfig;
95+
} else if (config.browserstack) {
96+
extraConfig = browserstackConfig;
97+
} else {
98+
extraConfig = devConfig;
99+
}
100+
74101

75102
config.set({
76103
...extraConfig,

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"lint": "tslint -p . -t verbose",
6464
"coverage": "KARMA_COVERAGE=1 karma start --browsers='Chrome' --singleRun",
6565
"test": "karma start",
66+
"test-webworker": "karma start --worker",
6667
"run-browserstack": "karma start --browserstack",
6768
"test-bundle-size": "./scripts/test-bundle-size.js",
6869
"test-node": "rimraf dist/ && tsc && node dist/test_node.js",

scripts/test-ci.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,8 @@ npm-run-all -p -c --aggregate-output \
3535
"run-browserstack --browsers=bs_chrome_mac" \
3636
"run-browserstack --browsers=bs_chrome_mac --testEnv webgl2 --flags '{\"WEBGL_CPU_FORWARD\": true}'" \
3737
"run-browserstack --browsers=bs_chrome_mac --testEnv webgl2 --flags '{\"WEBGL_CPU_FORWARD\": false}'"
38+
39+
# Build dist/tf-core.js which is used by the webworker test
40+
yarn build-npm
41+
# Run under webworker environment
42+
yarn test-webworker --browsers=bs_safari_mac

src/jasmine_util.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ export const SYNC_BACKEND_ENVS: Constraints = {
3939
predicate: (testEnv: TestEnv) => testEnv.isDataSync === true
4040
};
4141

42+
export const HAS_WORKER = {
43+
predicate: () => typeof(Worker) !== 'undefined'
44+
&& typeof(Blob) !== 'undefined' && typeof(URL) !== 'undefined'
45+
};
46+
47+
export const HAS_NODE_WORKER = {
48+
predicate: () => {
49+
let hasWorker = true;
50+
try {
51+
require.resolve('worker_threads');
52+
} catch {
53+
hasWorker = false;
54+
}
55+
return typeof(process) !== 'undefined' && hasWorker;
56+
}
57+
};
58+
4259
export const ALL_ENVS: Constraints = {};
4360

4461
// Tests whether the current environment satisfies the set of constraints.

src/test_async_backends.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,6 @@ setTestEnvs([{
7474
}]);
7575

7676
const runner = new jasmine();
77+
7778
runner.loadConfig({spec_files: ['dist/**/**_test.js'], random: false});
7879
runner.execute();

src/tests.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,5 @@ import './types_test';
107107
import './util_test';
108108
import './variable_test';
109109
import './version_test';
110+
import './worker_node_test';
111+
import './worker_test';

src/worker_node_test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google Inc. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
* =============================================================================
16+
*/
17+
18+
import {HAS_NODE_WORKER, describeWithFlags} from './jasmine_util';
19+
import {expectArraysClose} from './test_util';
20+
21+
const fn2String = (fn: Function): string => {
22+
const funcStr = '('+fn.toString()+')()';
23+
return funcStr;
24+
};
25+
26+
// The source code of a web worker.
27+
const workerTestNode = () => {
28+
const tf = require(`${process.cwd()}/dist/tf-core.js`);
29+
// tslint:disable-next-line:no-require-imports
30+
const {parentPort} = require('worker_threads');
31+
let a = tf.tensor1d([1, 2, 3]);
32+
const b = tf.tensor1d([3, 2, 1]);
33+
a = a.add(b);
34+
parentPort.postMessage({data: a.dataSync()});
35+
};
36+
37+
describeWithFlags('computation in worker (node env)', HAS_NODE_WORKER, () => {
38+
it('tensor in worker', (done) => {
39+
// tslint:disable-next-line:no-require-imports
40+
const {Worker} = require('worker_threads');
41+
const worker = new Worker(fn2String(workerTestNode), {eval: true});
42+
// tslint:disable-next-line:no-any
43+
worker.on('message', (msg: any) => {
44+
const data = msg.data;
45+
expectArraysClose(data, [4, 4, 4]);
46+
done();
47+
});
48+
});
49+
});

src/worker_test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google Inc. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
* =============================================================================
16+
*/
17+
18+
import {HAS_WORKER, describeWithFlags} from './jasmine_util';
19+
import {expectArraysClose} from './test_util';
20+
import * as tf from './index';
21+
22+
const fn2workerURL = (fn: Function): string => {
23+
const blob =
24+
new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'});
25+
return URL.createObjectURL(blob);
26+
};
27+
28+
// The source code of a web worker.
29+
const workerTest = () => {
30+
//@ts-ignore
31+
importScripts('http://bs-local.com:12345/base/dist/tf-core.js');
32+
let a = tf.tensor1d([1, 2, 3]);
33+
const b = tf.tensor1d([3, 2, 1]);
34+
a = a.add(b);
35+
//@ts-ignore
36+
self.postMessage({data: a.dataSync()});
37+
};
38+
39+
describeWithFlags('computation in worker', HAS_WORKER, () => {
40+
it('tensor in worker', (done) => {
41+
const worker = new Worker(fn2workerURL(workerTest));
42+
worker.onmessage = (msg) => {
43+
const data = msg.data.data;
44+
expectArraysClose(data, [4, 4, 4]);
45+
done();
46+
};
47+
});
48+
});

0 commit comments

Comments
 (0)