Skip to content

Commit

Permalink
Add node 16 in supported runtime matrix (microsoft#902)
Browse files Browse the repository at this point in the history
* Validate compatibility with oher versions of node.js runtime

* Test

* Test

* Update versions

* Add node 16 in supported matrix
  • Loading branch information
hectorhdzg authored Mar 1, 2022
1 parent f0262a1 commit 67b1859
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 127 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: Node.js CI
on:
push:
branches: [ develop, master ]
pull_request:
branches: [ develop, master ]

jobs:
build:
Expand All @@ -14,15 +12,15 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
node-version: [8.x, 10.x, 12.x, 14.x]
node-version: [8, 10, 12, 14, 15, 16, 17]

steps:
- uses: actions/checkout@v2
- name: (${{ matrix.os }}) on Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm install
- run: npm run build --if-present
- run: if [[ ${{ matrix.node-version }} == 14 ]]; then npm run lint; fi;
- run: npm test
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Node.js runtime CI

on:
pull_request:
branches: [ develop, master ]
jobs:
build:

runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest]
node-version: [10, 12, 14, 16]

steps:
- uses: actions/checkout@v2
- name: (${{ matrix.os }}) on Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
- run: npm test
12 changes: 0 additions & 12 deletions AutoCollection/NativePerformance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,6 @@ export class AutoCollectNativePerformance {
this._client = client;
}

/**
* Reports if NativePerformance is able to run in this environment
*/
public static isNodeVersionCompatible() {
var nodeVer = process.versions.node.split(".");
return parseInt(nodeVer[0]) >= 6;
}

/**
* Start instance of native metrics agent.
*
Expand All @@ -53,10 +45,6 @@ export class AutoCollectNativePerformance {
* @memberof AutoCollectNativePerformance
*/
public enable(isEnabled: boolean, disabledMetrics: IDisabledExtendedMetrics = {}, collectionInterval = 60000): void {
if (!AutoCollectNativePerformance.isNodeVersionCompatible()) {
return;
}

if (AutoCollectNativePerformance._metricsAvailable == undefined && isEnabled && !this._isInitialized) {
// Try to require in the native-metrics library. If it's found initialize it, else do nothing and never try again.
try {
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Application Insights for Node.js

[![npm version](https://badge.fury.io/js/applicationinsights.svg)](http://badge.fury.io/js/applicationinsights)
[![Build Status](https://travis-ci.org/Microsoft/ApplicationInsights-node.js.svg?branch=master)](https://travis-ci.org/Microsoft/ApplicationInsights-node.js)
![Integration Tests CI](https://github.com/microsoft/ApplicationInsights-node.js/workflows/Integration%20Tests%20CI/badge.svg)
![Node.js CI](https://github.com/microsoft/ApplicationInsights-node.js/workflows/Node.js%20CI/badge.svg)
![Back Compatability CI](https://github.com/microsoft/ApplicationInsights-node.js/workflows/Back%20Compatability%20CI/badge.svg)
Expand Down Expand Up @@ -29,6 +28,7 @@ You can manually track more aspects of your app and system using the API describ

| Platform Version | Supported |
|------------------|-------------------------------------------------|
| Node.JS `v16` ||
| Node.JS `v15` ||
| Node.JS `v14` ||
| Node.JS `v12` ||
Expand Down
188 changes: 95 additions & 93 deletions Tests/AutoCollection/NativePerformance.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,119 +21,121 @@ describe("AutoCollection/NativePerformance", () => {
sandbox.restore();
});

if (AutoCollectNativePerformance.isNodeVersionCompatible()) {
describe("#init and #dispose()", () => {
it("init should enable and dispose should stop autocollection interval", () => {
var setIntervalSpy = sandbox.spy(global, "setInterval");
var clearIntervalSpy = sandbox.spy(global, "clearInterval");

AppInsights.setup("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333")
.setAutoCollectHeartbeat(false)
.setAutoCollectPerformance(false, true)
.setAutoCollectPreAggregatedMetrics(false)
.start();
if (AutoCollectNativePerformance["_metricsAvailable"]) {
assert.equal(setIntervalSpy.callCount, 3, "setInteval should be called three times as part of NativePerformance initialization as well as Statsbeat");
AppInsights.dispose();
assert.equal(clearIntervalSpy.callCount, 1, "clearInterval should be called once as part of NativePerformance shutdown");
} else {
assert.equal(setIntervalSpy.callCount, 2, "setInterval should not be called if NativePerformance package is not available, Statsbeat will be called");
AppInsights.dispose();
assert.equal(clearIntervalSpy.callCount, 0, "clearInterval should not be called if NativePerformance package is not available");
}
});

it("constructor should be safe to call multiple times", () => {
var client = new TelemetryClient("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333");
var native = new AutoCollectNativePerformance(client);
var sinonSpy = sandbox.spy(AutoCollectNativePerformance.INSTANCE, "dispose");

assert.ok(native);
assert.ok(sinonSpy.notCalled);

assert.doesNotThrow(() => { native = new AutoCollectNativePerformance(client) }, "NativePerformance can be constructed more than once");
assert.ok(sinonSpy.calledOnce, "dispose is called when second instance is constructed");
});

it("Calling enable multiple times shoud not create multiple timers", () => {
var client = new TelemetryClient("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333");
var sinonSpy = sandbox.spy(global, "setInterval");
var native = new AutoCollectNativePerformance(client);

assert.ok(native);
assert.doesNotThrow(() => native.enable(true), "Does not throw when trying to enable");
assert.doesNotThrow(() => native.enable(true), "Does not throw when trying to enable");
describe("#init and #dispose()", () => {
it("init should enable and dispose should stop autocollection interval", () => {
var setIntervalSpy = sandbox.spy(global, "setInterval");
var clearIntervalSpy = sandbox.spy(global, "clearInterval");

AppInsights.setup("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333")
.setAutoCollectHeartbeat(false)
.setAutoCollectPerformance(false, true)
.setAutoCollectPreAggregatedMetrics(false)
.start();
if (AutoCollectNativePerformance["_metricsAvailable"]) {
assert.equal(setIntervalSpy.callCount, 3, "setInteval should be called three times as part of NativePerformance initialization as well as Statsbeat");
AppInsights.dispose();
assert.equal(clearIntervalSpy.callCount, 1, "clearInterval should be called once as part of NativePerformance shutdown");
} else {
assert.equal(setIntervalSpy.callCount, 2, "setInterval should not be called if NativePerformance package is not available, Statsbeat will be called");
AppInsights.dispose();
assert.equal(clearIntervalSpy.callCount, 0, "clearInterval should not be called if NativePerformance package is not available");
}
});

it("constructor should be safe to call multiple times", () => {
var client = new TelemetryClient("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333");
var native = new AutoCollectNativePerformance(client);
var sinonSpy = sandbox.spy(AutoCollectNativePerformance.INSTANCE, "dispose");

assert.ok(native);
assert.ok(sinonSpy.notCalled);

assert.doesNotThrow(() => { native = new AutoCollectNativePerformance(client) }, "NativePerformance can be constructed more than once");
assert.ok(sinonSpy.calledOnce, "dispose is called when second instance is constructed");
});

it("Calling enable multiple times should not create multiple timers", () => {
var client = new TelemetryClient("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333");
var sinonSpy = sandbox.spy(global, "setInterval");
var native = new AutoCollectNativePerformance(client);
assert.ok(native);
assert.doesNotThrow(() => native.enable(true), "Does not throw when trying to enable");
assert.doesNotThrow(() => native.enable(true), "Does not throw when trying to enable");
if (AutoCollectNativePerformance["_metricsAvailable"]) {
assert.equal(sinonSpy.callCount, 1, "setInterval should be singleton");
});
}
else{
assert.equal(sinonSpy.callCount, 0, "setInterval should not be called if native metrics package is not installed");
}
});

it("Calling enable when metrics are not available should fail gracefully", () => {
var client = new TelemetryClient("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333");
var native = new AutoCollectNativePerformance(client);
it("Calling enable when metrics are not available should fail gracefully", () => {
var client = new TelemetryClient("1aa11111-bbbb-1ccc-8ddd-eeeeffff3333");
var native = new AutoCollectNativePerformance(client);

AutoCollectNativePerformance["_metricsAvailable"] = false;
assert.ok(!(<any>native)["_emitter"]);
AutoCollectNativePerformance["_metricsAvailable"] = false;
assert.ok(!(<any>native)["_emitter"]);

assert.doesNotThrow(() => native.enable(true), "Does not throw when native metrics are not available and trying to enable");
assert.doesNotThrow(() => native.enable(false), "Does not throw when native metrics are not available and trying to disable");
});
assert.doesNotThrow(() => native.enable(true), "Does not throw when native metrics are not available and trying to enable");
assert.doesNotThrow(() => native.enable(false), "Does not throw when native metrics are not available and trying to disable");
});
});

describe("#_parseEnabled", () => {
it("should return equal input arg if no env vars are set", () => {
const _customConfig = JsonConfig.getInstance();
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(true, _customConfig), { isEnabled: true, disabledMetrics: {} });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(false, _customConfig), { isEnabled: false, disabledMetrics: {} });
describe("#_parseEnabled", () => {
it("should return equal input arg if no env vars are set", () => {
const _customConfig = JsonConfig.getInstance();
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(true, _customConfig), { isEnabled: true, disabledMetrics: {} });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(false, _customConfig), { isEnabled: false, disabledMetrics: {} });

const config = { gc: true, heap: true };
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(config, _customConfig), { isEnabled: true, disabledMetrics: config });
});
const config = { gc: true, heap: true };
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(config, _customConfig), { isEnabled: true, disabledMetrics: config });
});

it("should overwrite input arg if disable all extended metrics env var is set", () => {
const env = <{ [id: string]: string }>{};
const originalEnv = process.env;
it("should overwrite input arg if disable all extended metrics env var is set", () => {
const env = <{ [id: string]: string }>{};
const originalEnv = process.env;

env[ENV_nativeMetricsDisableAll] = "set";
process.env = env;
env[ENV_nativeMetricsDisableAll] = "set";
process.env = env;

const _customConfig = JsonConfig.getInstance();
const _customConfig = JsonConfig.getInstance();

assert.deepEqual(AutoCollectNativePerformance.parseEnabled(true, _customConfig), { isEnabled: false, disabledMetrics: {} });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled({}, _customConfig), { isEnabled: false, disabledMetrics: {} });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled({ gc: true }, _customConfig), { isEnabled: false, disabledMetrics: {} });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(true, _customConfig), { isEnabled: false, disabledMetrics: {} });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled({}, _customConfig), { isEnabled: false, disabledMetrics: {} });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled({ gc: true }, _customConfig), { isEnabled: false, disabledMetrics: {} });

process.env = originalEnv;
});
process.env = originalEnv;
});

it("should overwrite input arg if individual env vars are set", () => {
const expectation = { gc: true, heap: true };
const env = <{ [id: string]: string }>{};
const originalEnv = process.env;
it("should overwrite input arg if individual env vars are set", () => {
const expectation = { gc: true, heap: true };
const env = <{ [id: string]: string }>{};
const originalEnv = process.env;

env[ENV_nativeMetricsDisablers] = "gc,heap";
process.env = env;
env[ENV_nativeMetricsDisablers] = "gc,heap";
process.env = env;

const _customConfig = JsonConfig.getInstance();
const _customConfig = JsonConfig.getInstance();

let inConfig;
let inConfig;

inConfig = false;
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: false, disabledMetrics: expectation });
inConfig = false;
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: false, disabledMetrics: expectation });

inConfig = true;
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: expectation });
inConfig = true;
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: expectation });

inConfig = {};
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: expectation });
inConfig = { gc: true };
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: expectation });
inConfig = { loop: true };
inConfig = {};
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: expectation });
inConfig = { gc: true };
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: expectation });
inConfig = { loop: true };

assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: { ...inConfig, ...expectation } });
inConfig = { gc: false, loop: true, heap: 'abc', something: 'else' };
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(<any>inConfig, _customConfig), { isEnabled: true, disabledMetrics: { ...inConfig, ...expectation } });
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(inConfig, _customConfig), { isEnabled: true, disabledMetrics: { ...inConfig, ...expectation } });
inConfig = { gc: false, loop: true, heap: 'abc', something: 'else' };
assert.deepEqual(AutoCollectNativePerformance.parseEnabled(<any>inConfig, _customConfig), { isEnabled: true, disabledMetrics: { ...inConfig, ...expectation } });

process.env = originalEnv;
});
process.env = originalEnv;
});
}
});
});
17 changes: 0 additions & 17 deletions Tests/js/endToEnd.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,6 @@ describe('module', function () {
});
});

describe('rejected promises', function () {
it('should not crash on rejected promises containing no callstack', function () {
var appInsights = require('../../');
appInsights.setup('1aa11111-bbbb-1ccc-8ddd-eeeeffff3333');
appInsights.defaultClient.config.httpsAgent = new https.Agent({ keepAlive: false });
appInsights.start();
assert.ok(appInsights.defaultClient);
assert.doesNotThrow(function () {
if (typeof Promise !== 'undefined') {
Promise.reject();
}
});
appInsights.defaultClient.flush();
appInsights.dispose();
});
});

describe('uncaught exceptions', function () {
var UNCAUGHT_EXCEPTION = 'uncaughtException';
var UNCAUGHT_EXCEPTION_MONITOR = 'uncaughtExceptionMonitor';
Expand Down

0 comments on commit 67b1859

Please sign in to comment.