Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ environment:
- nodejs_version: "10"
- nodejs_version: "11"
Copy link
Member

@Tyriar Tyriar Apr 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove 10 and 11, they're pretty old at this point.

- nodejs_version: "12"
- nodejs_version: "14"

install:
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version)
Expand Down
179 changes: 123 additions & 56 deletions lib/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

import * as assert from 'assert';
import * as child_process from 'child_process';
import * as path from 'path';
import { getProcessTree, getProcessList, getProcessCpuUsage, ProcessDataFlag, buildProcessTree, filterProcessList } from './index';

import { Worker, isMainThread } from 'worker_threads';
const native = require('../build/Release/windows_process_tree.node');

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

it('should return a list containing this process', (done) => {
native.getProcessList((list) => {
assert.notEqual(list.find(p => p.pid === process.pid), undefined);
assert.notStrictEqual(list.find(p => p.pid === process.pid), undefined);
done();
}, 0);
});

it('should handle multiple calls gracefully', (done) => {
let counter = 0;
const callback = (list) => {
assert.notEqual(list.find(p => p.pid === process.pid), undefined);
assert.notStrictEqual(list.find(p => p.pid === process.pid), undefined);
if (++counter === 2) {
done();
}
Expand All @@ -59,11 +60,11 @@ describe('getRawProcessList', () => {
it('should return memory information only when the flag is set', (done) => {
// Memory should be undefined when flag is not set
native.getProcessList((list) => {
assert.equal(list.every(p => p.memory === undefined), true);
assert.strictEqual(list.every(p => p.memory === undefined), true);

// Memory should be a number when flag is set
native.getProcessList((list) => {
assert.equal(list.some(p => p.memory > 0), true);
assert.strictEqual(list.some(p => p.memory > 0), true);
done();
}, ProcessDataFlag.Memory);
}, ProcessDataFlag.None);
Expand All @@ -72,11 +73,11 @@ describe('getRawProcessList', () => {
it('should return command line information only when the flag is set', (done) => {
// commandLine should be undefined when flag is not set
native.getProcessList((list) => {
assert.equal(list.every(p => p.commandLine === undefined), true);
assert.strictEqual(list.every(p => p.commandLine === undefined), true);

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

it('should return a list containing this process', (done) => {
getProcessList(process.pid, (list) => {
assert.equal(list.length, 1);
assert.equal(list[0].name, 'node.exe');
assert.equal(list[0].pid, process.pid);
assert.equal(list[0].memory, undefined);
assert.equal(list[0].commandLine, undefined);
assert.strictEqual(list.length, 1);
assert.strictEqual(list[0].name, 'node.exe');
assert.strictEqual(list[0].pid, process.pid);
assert.strictEqual(list[0].memory, undefined);
assert.strictEqual(list[0].commandLine, undefined);
done();
});
});

it('should return a list containing this process\'s memory if the flag is set', done => {
getProcessList(process.pid, (list) => {
assert.equal(list.length, 1);
assert.equal(list[0].name, 'node.exe');
assert.equal(list[0].pid, process.pid);
assert.equal(typeof list[0].memory, 'number');
assert.strictEqual(list.length, 1);
assert.strictEqual(list[0].name, 'node.exe');
assert.strictEqual(list[0].pid, process.pid);
assert.strictEqual(typeof list[0].memory, 'number');
done();
}, ProcessDataFlag.Memory);
});

it('should return command line information only if the flag is set', (done) => {
getProcessList(process.pid, (list) => {
assert.equal(list.length, 1);
assert.equal(list[0].name, 'node.exe');
assert.equal(list[0].pid, process.pid);
assert.equal(typeof list[0].commandLine, 'string');
assert.strictEqual(list.length, 1);
assert.strictEqual(list[0].name, 'node.exe');
assert.strictEqual(list[0].pid, process.pid);
assert.strictEqual(typeof list[0].commandLine, 'string');
// CommandLine is "<path to node> <path to mocha> lib/test.js"
assert.equal(list[0].commandLine.indexOf('mocha') > 0, true);
assert.equal(list[0].commandLine.indexOf('lib/test.js') > 0, true);
assert.strictEqual(list[0].commandLine.indexOf('mocha') > 0, true);
assert.strictEqual(list[0].commandLine.indexOf('lib/test.js') > 0, true);
done();
}, ProcessDataFlag.CommandLine);
});
Expand All @@ -146,22 +147,22 @@ describe('getProcessCpuUsage', () => {

it('should get process cpu usage', (done) => {
getProcessCpuUsage([{ pid: process.pid, ppid: process.ppid, name: 'node.exe' }], (annotatedList) => {
assert.equal(annotatedList.length, 1);
assert.equal(annotatedList[0].name, 'node.exe');
assert.equal(annotatedList[0].pid, process.pid);
assert.equal(annotatedList[0].memory, undefined);
assert.equal(typeof annotatedList[0].cpu, 'number');
assert.equal(0 <= annotatedList[0].cpu && annotatedList[0].cpu <= 100, true);
assert.strictEqual(annotatedList.length, 1);
assert.strictEqual(annotatedList[0].name, 'node.exe');
assert.strictEqual(annotatedList[0].pid, process.pid);
assert.strictEqual(annotatedList[0].memory, undefined);
assert.strictEqual(typeof annotatedList[0].cpu, 'number');
assert.strictEqual(0 <= annotatedList[0].cpu && annotatedList[0].cpu <= 100, true);
done();
});
});

it('should handle multiple calls gracefully', function (done: MochaDone): void {
it('should handle multiple calls gracefully', function (done): void {
this.timeout(3000);

let counter = 0;
const callback = (list) => {
assert.notEqual(list.find(p => p.pid === process.pid), undefined);
assert.notStrictEqual(list.find(p => p.pid === process.pid), undefined);
if (++counter === 2) {
done();
}
Expand All @@ -186,31 +187,31 @@ describe('getProcessTree', () => {

it('should return a tree containing this process', done => {
getProcessTree(process.pid, (tree) => {
assert.equal(tree.name, 'node.exe');
assert.equal(tree.pid, process.pid);
assert.equal(tree.memory, undefined);
assert.equal(tree.commandLine, undefined);
assert.equal(tree.children.length, 0);
assert.strictEqual(tree.name, 'node.exe');
assert.strictEqual(tree.pid, process.pid);
assert.strictEqual(tree.memory, undefined);
assert.strictEqual(tree.commandLine, undefined);
assert.strictEqual(tree.children.length, 0);
done();
});
});

it('should return a tree containing this process\'s memory if the flag is set', done => {
getProcessTree(process.pid, (tree) => {
assert.equal(tree.name, 'node.exe');
assert.equal(tree.pid, process.pid);
assert.notEqual(tree.memory, undefined);
assert.equal(tree.children.length, 0);
assert.strictEqual(tree.name, 'node.exe');
assert.strictEqual(tree.pid, process.pid);
assert.notStrictEqual(tree.memory, undefined);
assert.strictEqual(tree.children.length, 0);
done();
}, ProcessDataFlag.Memory);
});

it('should return a tree containing this process\'s command line if the flag is set', done => {
getProcessTree(process.pid, (tree) => {
assert.equal(tree.name, 'node.exe');
assert.equal(tree.pid, process.pid);
assert.equal(typeof tree.commandLine, 'string');
assert.equal(tree.children.length, 0);
assert.strictEqual(tree.name, 'node.exe');
assert.strictEqual(tree.pid, process.pid);
assert.strictEqual(typeof tree.commandLine, 'string');
assert.strictEqual(tree.children.length, 0);
done();
}, ProcessDataFlag.CommandLine);
});
Expand Down Expand Up @@ -250,14 +251,14 @@ describe('buildProcessTree', () => {
const tree = buildProcessTree(0, [
{ pid: 0, ppid: 0, name: '0' }
], 3);
assert.equal(tree.pid, 0);
assert.equal(tree.children.length, 1);
assert.equal(tree.children[0].pid, 0);
assert.equal(tree.children[0].children.length, 1);
assert.equal(tree.children[0].children[0].pid, 0);
assert.equal(tree.children[0].children[0].children.length, 1);
assert.equal(tree.children[0].children[0].children[0].pid, 0);
assert.equal(tree.children[0].children[0].children[0].children.length, 0);
assert.strictEqual(tree.pid, 0);
assert.strictEqual(tree.children.length, 1);
assert.strictEqual(tree.children[0].pid, 0);
assert.strictEqual(tree.children[0].children.length, 1);
assert.strictEqual(tree.children[0].children[0].pid, 0);
assert.strictEqual(tree.children[0].children[0].children.length, 1);
assert.strictEqual(tree.children[0].children[0].children[0].pid, 0);
assert.strictEqual(tree.children[0].children[0].children[0].children.length, 0);
});
});

Expand All @@ -266,10 +267,76 @@ describe('filterProcessList', () => {
const list = filterProcessList(0, [
{ pid: 0, ppid: 0, name: '0' }
], 3);
assert.equal(list.length, 4);
assert.equal(list[0].pid, 0);
assert.equal(list[1].pid, 0);
assert.equal(list[2].pid, 0);
assert.equal(list[3].pid, 0);
assert.strictEqual(list.length, 4);
assert.strictEqual(list[0].pid, 0);
assert.strictEqual(list[1].pid, 0);
assert.strictEqual(list[2].pid, 0);
assert.strictEqual(list[3].pid, 0);
});
});

describe('contextAware', () => {
it('should be context aware filter process list', async () => {
if (isMainThread) {
const workerPromise: Promise<boolean> = new Promise(resolve => {
const workerDir = path.join(__dirname, "./testWorker.js");
const worker = new Worker(workerDir);
worker.on('message', (message: string) => {
assert.strictEqual(message, 'done');
});
worker.on('error', () => {
resolve(false);
});
worker.on('exit', (code) => {
resolve(code === 0);
});
});
const list = filterProcessList(0, [
{ pid: 0, ppid: 0, name: '0' }
], 3);
assert.strictEqual(list.length, 4);
assert.strictEqual(list[0].pid, 0);
assert.strictEqual(list[1].pid, 0);
assert.strictEqual(list[2].pid, 0);
assert.strictEqual(list[3].pid, 0);
const workerResult = await workerPromise;
assert.strictEqual(workerResult, true);
}
});

it('should be context aware multiple workers', async () => {
if (isMainThread) {
const makeWorkerPromise = (): Promise<boolean> => {
return new Promise(resolve => {
const workerDir = path.join(__dirname, "./testWorker.js");
const worker = new Worker(workerDir);
worker.on('message', (message: string) => {
assert.strictEqual(message, 'done');
});
worker.on('error', () => {
resolve(false);
});
worker.on('exit', (code) => {
resolve(code === 0);
});
});
}
const workerPromises = [makeWorkerPromise(), makeWorkerPromise(), makeWorkerPromise()];
const processListPromise: Promise<boolean> = new Promise(resolve => {
getProcessList(process.pid, (list) => {
assert.strictEqual(list.length, 1);
assert.strictEqual(list[0].name, 'node.exe');
assert.strictEqual(list[0].pid, process.pid);
assert.strictEqual(list[0].memory, undefined);
assert.strictEqual(list[0].commandLine, undefined);
resolve(true);
});
});
const allPromises = [...workerPromises, processListPromise];
const workerResult = await Promise.all(allPromises).then(results => {
return results.every(result => result);
});
assert.strictEqual(workerResult, true);
}
});
});
15 changes: 15 additions & 0 deletions lib/testWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as assert from 'assert';
import { isMainThread, parentPort } from 'worker_threads';
import { filterProcessList } from './index';

if (!isMainThread) {
const list = filterProcessList(0, [
{ pid: 0, ppid: 0, name: '0' }
], 3);
assert.strictEqual(list.length, 4);
assert.strictEqual(list[0].pid, 0);
assert.strictEqual(list[1].pid, 0);
assert.strictEqual(list[2].pid, 0);
assert.strictEqual(list[3].pid, 0);
parentPort.postMessage('done');
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"scripts": {
"test": "mocha lib/test.js",
"prepublish": "tsc",
"compile": "tsc",
"watch": "tsc -w",
"lint": "tslint lib/*.ts typings/*.ts *.ts"
},
Expand All @@ -25,9 +26,9 @@
},
"devDependencies": {
"mocha": "^3.5.0",
"typescript": "2.7.2",
"typescript": "^4.0.0",
"tslint": "5.9.1",
"@types/node": "9.4.7",
"@types/node": "^14.14.0",
"@types/mocha": "2.2.48"
},
"os": [
Expand Down
2 changes: 1 addition & 1 deletion src/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ void Init(v8::Local<v8::Object> exports) {
Nan::Export(exports, "getProcessCpuUsage", GetProcessCpuUsage);
}

NODE_MODULE(hello, Init)
NAN_MODULE_WORKER_ENABLED(hello, Init)
Loading