Skip to content

Commit 767e74e

Browse files
authored
Make module context-aware (#30)
Fixes microsoft/vscode#120570
1 parent 623f757 commit 767e74e

File tree

6 files changed

+1252
-66
lines changed

6 files changed

+1252
-66
lines changed

appveyor.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
environment:
22
matrix:
33
# node.js
4-
- nodejs_version: "7"
5-
- nodejs_version: "8"
6-
- nodejs_version: "9"
7-
- nodejs_version: "10"
8-
- nodejs_version: "11"
94
- nodejs_version: "12"
5+
- nodejs_version: "14"
106

117
install:
128
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version)

lib/test.ts

Lines changed: 134 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
import * as assert from 'assert';
77
import * as child_process from 'child_process';
8+
import * as path from 'path';
89
import { getProcessTree, getProcessList, getProcessCpuUsage, ProcessDataFlag, buildProcessTree, filterProcessList } from './index';
9-
10+
import { Worker, isMainThread } from 'worker_threads';
1011
const native = require('../build/Release/windows_process_tree.node');
1112

1213
function pollUntil(makePromise: () => Promise<boolean>, cb: () => void, interval: number, timeout: number): void {
@@ -39,15 +40,15 @@ describe('getRawProcessList', () => {
3940

4041
it('should return a list containing this process', (done) => {
4142
native.getProcessList((list) => {
42-
assert.notEqual(list.find(p => p.pid === process.pid), undefined);
43+
assert.notStrictEqual(list.find(p => p.pid === process.pid), undefined);
4344
done();
4445
}, 0);
4546
});
4647

4748
it('should handle multiple calls gracefully', (done) => {
4849
let counter = 0;
4950
const callback = (list) => {
50-
assert.notEqual(list.find(p => p.pid === process.pid), undefined);
51+
assert.notStrictEqual(list.find(p => p.pid === process.pid), undefined);
5152
if (++counter === 2) {
5253
done();
5354
}
@@ -59,11 +60,11 @@ describe('getRawProcessList', () => {
5960
it('should return memory information only when the flag is set', (done) => {
6061
// Memory should be undefined when flag is not set
6162
native.getProcessList((list) => {
62-
assert.equal(list.every(p => p.memory === undefined), true);
63+
assert.strictEqual(list.every(p => p.memory === undefined), true);
6364

6465
// Memory should be a number when flag is set
6566
native.getProcessList((list) => {
66-
assert.equal(list.some(p => p.memory > 0), true);
67+
assert.strictEqual(list.some(p => p.memory > 0), true);
6768
done();
6869
}, ProcessDataFlag.Memory);
6970
}, ProcessDataFlag.None);
@@ -72,11 +73,11 @@ describe('getRawProcessList', () => {
7273
it('should return command line information only when the flag is set', (done) => {
7374
// commandLine should be undefined when flag is not set
7475
native.getProcessList((list) => {
75-
assert.equal(list.every(p => p.commandLine === undefined), true);
76+
assert.strictEqual(list.every(p => p.commandLine === undefined), true);
7677

7778
// commandLine should be a string when flag is set
7879
native.getProcessList((list) => {
79-
assert.equal(list.every(p => typeof p.commandLine === 'string'), true);
80+
assert.strictEqual(list.every(p => typeof p.commandLine === 'string'), true);
8081
done();
8182
}, ProcessDataFlag.CommandLine);
8283
}, ProcessDataFlag.None);
@@ -98,34 +99,34 @@ describe('getProcessList', () => {
9899

99100
it('should return a list containing this process', (done) => {
100101
getProcessList(process.pid, (list) => {
101-
assert.equal(list.length, 1);
102-
assert.equal(list[0].name, 'node.exe');
103-
assert.equal(list[0].pid, process.pid);
104-
assert.equal(list[0].memory, undefined);
105-
assert.equal(list[0].commandLine, undefined);
102+
assert.strictEqual(list.length, 1);
103+
assert.strictEqual(list[0].name, 'node.exe');
104+
assert.strictEqual(list[0].pid, process.pid);
105+
assert.strictEqual(list[0].memory, undefined);
106+
assert.strictEqual(list[0].commandLine, undefined);
106107
done();
107108
});
108109
});
109110

110111
it('should return a list containing this process\'s memory if the flag is set', done => {
111112
getProcessList(process.pid, (list) => {
112-
assert.equal(list.length, 1);
113-
assert.equal(list[0].name, 'node.exe');
114-
assert.equal(list[0].pid, process.pid);
115-
assert.equal(typeof list[0].memory, 'number');
113+
assert.strictEqual(list.length, 1);
114+
assert.strictEqual(list[0].name, 'node.exe');
115+
assert.strictEqual(list[0].pid, process.pid);
116+
assert.strictEqual(typeof list[0].memory, 'number');
116117
done();
117118
}, ProcessDataFlag.Memory);
118119
});
119120

120121
it('should return command line information only if the flag is set', (done) => {
121122
getProcessList(process.pid, (list) => {
122-
assert.equal(list.length, 1);
123-
assert.equal(list[0].name, 'node.exe');
124-
assert.equal(list[0].pid, process.pid);
125-
assert.equal(typeof list[0].commandLine, 'string');
123+
assert.strictEqual(list.length, 1);
124+
assert.strictEqual(list[0].name, 'node.exe');
125+
assert.strictEqual(list[0].pid, process.pid);
126+
assert.strictEqual(typeof list[0].commandLine, 'string');
126127
// CommandLine is "<path to node> <path to mocha> lib/test.js"
127-
assert.equal(list[0].commandLine.indexOf('mocha') > 0, true);
128-
assert.equal(list[0].commandLine.indexOf('lib/test.js') > 0, true);
128+
assert.strictEqual(list[0].commandLine.indexOf('mocha') > 0, true);
129+
assert.strictEqual(list[0].commandLine.indexOf('lib/test.js') > 0, true);
129130
done();
130131
}, ProcessDataFlag.CommandLine);
131132
});
@@ -146,22 +147,22 @@ describe('getProcessCpuUsage', () => {
146147

147148
it('should get process cpu usage', (done) => {
148149
getProcessCpuUsage([{ pid: process.pid, ppid: process.ppid, name: 'node.exe' }], (annotatedList) => {
149-
assert.equal(annotatedList.length, 1);
150-
assert.equal(annotatedList[0].name, 'node.exe');
151-
assert.equal(annotatedList[0].pid, process.pid);
152-
assert.equal(annotatedList[0].memory, undefined);
153-
assert.equal(typeof annotatedList[0].cpu, 'number');
154-
assert.equal(0 <= annotatedList[0].cpu && annotatedList[0].cpu <= 100, true);
150+
assert.strictEqual(annotatedList.length, 1);
151+
assert.strictEqual(annotatedList[0].name, 'node.exe');
152+
assert.strictEqual(annotatedList[0].pid, process.pid);
153+
assert.strictEqual(annotatedList[0].memory, undefined);
154+
assert.strictEqual(typeof annotatedList[0].cpu, 'number');
155+
assert.strictEqual(0 <= annotatedList[0].cpu && annotatedList[0].cpu <= 100, true);
155156
done();
156157
});
157158
});
158159

159-
it('should handle multiple calls gracefully', function (done: MochaDone): void {
160+
it('should handle multiple calls gracefully', function (done: Mocha.Done): void {
160161
this.timeout(3000);
161162

162163
let counter = 0;
163164
const callback = (list) => {
164-
assert.notEqual(list.find(p => p.pid === process.pid), undefined);
165+
assert.notStrictEqual(list.find(p => p.pid === process.pid), undefined);
165166
if (++counter === 2) {
166167
done();
167168
}
@@ -186,31 +187,31 @@ describe('getProcessTree', () => {
186187

187188
it('should return a tree containing this process', done => {
188189
getProcessTree(process.pid, (tree) => {
189-
assert.equal(tree.name, 'node.exe');
190-
assert.equal(tree.pid, process.pid);
191-
assert.equal(tree.memory, undefined);
192-
assert.equal(tree.commandLine, undefined);
193-
assert.equal(tree.children.length, 0);
190+
assert.strictEqual(tree.name, 'node.exe');
191+
assert.strictEqual(tree.pid, process.pid);
192+
assert.strictEqual(tree.memory, undefined);
193+
assert.strictEqual(tree.commandLine, undefined);
194+
assert.strictEqual(tree.children.length, 0);
194195
done();
195196
});
196197
});
197198

198199
it('should return a tree containing this process\'s memory if the flag is set', done => {
199200
getProcessTree(process.pid, (tree) => {
200-
assert.equal(tree.name, 'node.exe');
201-
assert.equal(tree.pid, process.pid);
202-
assert.notEqual(tree.memory, undefined);
203-
assert.equal(tree.children.length, 0);
201+
assert.strictEqual(tree.name, 'node.exe');
202+
assert.strictEqual(tree.pid, process.pid);
203+
assert.notStrictEqual(tree.memory, undefined);
204+
assert.strictEqual(tree.children.length, 0);
204205
done();
205206
}, ProcessDataFlag.Memory);
206207
});
207208

208209
it('should return a tree containing this process\'s command line if the flag is set', done => {
209210
getProcessTree(process.pid, (tree) => {
210-
assert.equal(tree.name, 'node.exe');
211-
assert.equal(tree.pid, process.pid);
212-
assert.equal(typeof tree.commandLine, 'string');
213-
assert.equal(tree.children.length, 0);
211+
assert.strictEqual(tree.name, 'node.exe');
212+
assert.strictEqual(tree.pid, process.pid);
213+
assert.strictEqual(typeof tree.commandLine, 'string');
214+
assert.strictEqual(tree.children.length, 0);
214215
done();
215216
}, ProcessDataFlag.CommandLine);
216217
});
@@ -250,14 +251,14 @@ describe('buildProcessTree', () => {
250251
const tree = buildProcessTree(0, [
251252
{ pid: 0, ppid: 0, name: '0' }
252253
], 3);
253-
assert.equal(tree.pid, 0);
254-
assert.equal(tree.children.length, 1);
255-
assert.equal(tree.children[0].pid, 0);
256-
assert.equal(tree.children[0].children.length, 1);
257-
assert.equal(tree.children[0].children[0].pid, 0);
258-
assert.equal(tree.children[0].children[0].children.length, 1);
259-
assert.equal(tree.children[0].children[0].children[0].pid, 0);
260-
assert.equal(tree.children[0].children[0].children[0].children.length, 0);
254+
assert.strictEqual(tree.pid, 0);
255+
assert.strictEqual(tree.children.length, 1);
256+
assert.strictEqual(tree.children[0].pid, 0);
257+
assert.strictEqual(tree.children[0].children.length, 1);
258+
assert.strictEqual(tree.children[0].children[0].pid, 0);
259+
assert.strictEqual(tree.children[0].children[0].children.length, 1);
260+
assert.strictEqual(tree.children[0].children[0].children[0].pid, 0);
261+
assert.strictEqual(tree.children[0].children[0].children[0].children.length, 0);
261262
});
262263
});
263264

@@ -266,10 +267,87 @@ describe('filterProcessList', () => {
266267
const list = filterProcessList(0, [
267268
{ pid: 0, ppid: 0, name: '0' }
268269
], 3);
269-
assert.equal(list.length, 4);
270-
assert.equal(list[0].pid, 0);
271-
assert.equal(list[1].pid, 0);
272-
assert.equal(list[2].pid, 0);
273-
assert.equal(list[3].pid, 0);
270+
assert.strictEqual(list.length, 4);
271+
assert.strictEqual(list[0].pid, 0);
272+
assert.strictEqual(list[1].pid, 0);
273+
assert.strictEqual(list[2].pid, 0);
274+
assert.strictEqual(list[3].pid, 0);
275+
});
276+
});
277+
278+
describe('contextAware', () => {
279+
it('should be context aware get process list', async () => {
280+
if (isMainThread) {
281+
const workerPromise: Promise<boolean> = new Promise(resolve => {
282+
const workerDir = path.join(__dirname, './testWorker.js');
283+
const worker = new Worker(workerDir);
284+
worker.on('message', (message: string) => {
285+
assert.strictEqual(message, 'done');
286+
});
287+
worker.on('error', () => {
288+
resolve(false);
289+
});
290+
worker.on('exit', (code) => {
291+
resolve(code === 0);
292+
});
293+
});
294+
const processListPromise: Promise<boolean> = new Promise(resolve => {
295+
getProcessList(process.pid, (list) => {
296+
assert.strictEqual(list.length >= 1, true);
297+
assert.strictEqual(list[0].name, 'node.exe');
298+
assert.strictEqual(list[0].pid, process.pid);
299+
assert.strictEqual(list[0].memory, undefined);
300+
assert.strictEqual(list[0].commandLine, undefined);
301+
resolve(true);
302+
});
303+
});
304+
const combinedResult = await Promise.all([workerPromise, processListPromise]).then(results => {
305+
return results.every(result => result);
306+
}, () => {
307+
return false;
308+
});
309+
assert.strictEqual(combinedResult, true);
310+
}
311+
});
312+
313+
it('should be context aware multiple workers', async () => {
314+
if (isMainThread) {
315+
const makeWorkerPromise = (): Promise<boolean> => {
316+
return new Promise(resolve => {
317+
const workerDir = path.join(__dirname, './testWorker.js');
318+
const worker = new Worker(workerDir);
319+
worker.on('message', (message: string) => {
320+
assert.strictEqual(message, 'done');
321+
});
322+
worker.on('error', () => {
323+
resolve(false);
324+
});
325+
worker.on('exit', (code) => {
326+
resolve(code === 0);
327+
});
328+
});
329+
};
330+
const workerPromises = [];
331+
for (let i = 0; i < 50; i++) {
332+
workerPromises.push(makeWorkerPromise());
333+
}
334+
const processListPromise: Promise<boolean> = new Promise(resolve => {
335+
getProcessList(process.pid, (list) => {
336+
assert.strictEqual(list.length >= 1, true);
337+
assert.strictEqual(list[0].name, 'node.exe');
338+
assert.strictEqual(list[0].pid, process.pid);
339+
assert.strictEqual(list[0].memory, undefined);
340+
assert.strictEqual(list[0].commandLine, undefined);
341+
resolve(true);
342+
});
343+
});
344+
const allPromises = [...workerPromises, processListPromise];
345+
const workerResult = await Promise.all(allPromises).then(results => {
346+
return results.every(result => result);
347+
}, () => {
348+
return false;
349+
});
350+
assert.strictEqual(workerResult, true);
351+
}
274352
});
275353
});

lib/testWorker.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as assert from 'assert';
2+
import { isMainThread, parentPort } from 'worker_threads';
3+
import { getProcessList } from './index';
4+
5+
if (!isMainThread) {
6+
new Promise(resolve => {
7+
getProcessList(process.pid, (list) => {
8+
assert.strictEqual(list.length >= 1, true);
9+
assert.strictEqual(list[0].name, 'node.exe');
10+
assert.strictEqual(list[0].pid, process.pid);
11+
assert.strictEqual(list[0].memory, undefined);
12+
assert.strictEqual(list[0].commandLine, undefined);
13+
resolve(true);
14+
});
15+
}).then((res) => {
16+
assert.strictEqual(res, true);
17+
parentPort.postMessage('done');
18+
}, () => {
19+
parentPort.postMessage('fail');
20+
});
21+
}

0 commit comments

Comments
 (0)