From 206a1c3c1a2d20aa40abb3484b907e995cb3ef24 Mon Sep 17 00:00:00 2001 From: legendecas Date: Wed, 19 Jan 2022 00:04:21 +0800 Subject: [PATCH] test(sdk-metrics): browser compatibility tests (#2709) --- .../karma.conf.js | 24 ++++++++++ .../package.json | 8 ++++ .../PeriodicExportingMetricReader.test.ts | 27 +++++------ .../test/index-webpack.ts | 21 +++++++++ .../test/test-utils.ts | 45 +++++++++++++++++++ .../opentelemetry-core/test/test-utils.ts | 17 +++++-- 6 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 experimental/packages/opentelemetry-sdk-metrics-base/karma.conf.js create mode 100644 experimental/packages/opentelemetry-sdk-metrics-base/test/index-webpack.ts create mode 100644 experimental/packages/opentelemetry-sdk-metrics-base/test/test-utils.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/karma.conf.js b/experimental/packages/opentelemetry-sdk-metrics-base/karma.conf.js new file mode 100644 index 0000000000..6174839d65 --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-metrics-base/karma.conf.js @@ -0,0 +1,24 @@ +/*! + * Copyright The OpenTelemetry Authors + * + * Licensed 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. + */ + +const karmaWebpackConfig = require('../../../karma.webpack'); +const karmaBaseConfig = require('../../../karma.base'); + +module.exports = (config) => { + config.set(Object.assign({}, karmaBaseConfig, { + webpack: karmaWebpackConfig + })) +}; diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/package.json b/experimental/packages/opentelemetry-sdk-metrics-base/package.json index ce653a0f4c..9f3105d4c1 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/package.json +++ b/experimental/packages/opentelemetry-sdk-metrics-base/package.json @@ -12,7 +12,9 @@ "compile": "tsc --build tsconfig.all.json", "clean": "tsc --build --clean tsconfig.all.json", "test": "nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'", + "test:browser": "nyc karma start --single-run", "tdd": "npm run test -- --watch-extensions ts --watch", + "tdd:browser": "karma start", "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", @@ -57,6 +59,12 @@ "@types/node": "14.17.33", "@types/sinon": "10.0.6", "codecov": "3.8.3", + "karma": "6.3.8", + "karma-chrome-launcher": "3.1.0", + "karma-coverage-istanbul-reporter": "3.0.3", + "karma-mocha": "2.0.1", + "karma-spec-reporter": "0.0.32", + "karma-webpack": "4.0.2", "mocha": "7.2.0", "nyc": "15.1.0", "rimraf": "3.0.2", diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/export/PeriodicExportingMetricReader.test.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/export/PeriodicExportingMetricReader.test.ts index 90962c8ca2..4950f1cadc 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/test/export/PeriodicExportingMetricReader.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/export/PeriodicExportingMetricReader.test.ts @@ -22,6 +22,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { MetricProducer } from '../../src/export/MetricProducer'; import { TimeoutError } from '../../src/utils'; +import { assertRejects } from '../test-utils'; const MAX_32_BIT_INT = 2 ** 31 - 1; @@ -102,7 +103,7 @@ describe('PeriodicExportingMetricReader', () => { exporter: exporter, exportIntervalMillis: 0, exportTimeoutMillis: 0 - }), new Error('exportIntervalMillis must be greater than 0')); + }), /exportIntervalMillis must be greater than 0/); }); it('should throw when timeout less or equal to 0', () => { @@ -111,7 +112,7 @@ describe('PeriodicExportingMetricReader', () => { exporter: exporter, exportIntervalMillis: 1, exportTimeoutMillis: 0 - }), new Error('exportTimeoutMillis must be greater than 0')); + }), /exportTimeoutMillis must be greater than 0/); }); it('should throw when timeout less or equal to interval', () => { @@ -120,7 +121,7 @@ describe('PeriodicExportingMetricReader', () => { exporter: exporter, exportIntervalMillis: 100, exportTimeoutMillis: 200 - }), new Error('exportIntervalMillis must be greater than or equal to exportTimeoutMillis')); + }), /exportIntervalMillis must be greater than or equal to exportTimeoutMillis/); }); it('should not start exporting', async () => { @@ -151,7 +152,7 @@ describe('PeriodicExportingMetricReader', () => { reader.setMetricProducer(new TestMetricProducer()); const result = await exporter.waitForNumberOfExports(2); - assert.deepEqual(result, [[], []]); + assert.deepStrictEqual(result, [[], []]); await reader.shutdown(); }); }); @@ -169,7 +170,7 @@ describe('PeriodicExportingMetricReader', () => { reader.setMetricProducer(new TestMetricProducer()); const result = await exporter.waitForNumberOfExports(2); - assert.deepEqual(result, [[], []]); + assert.deepStrictEqual(result, [[], []]); exporter.throwException = false; await reader.shutdown(); @@ -188,7 +189,7 @@ describe('PeriodicExportingMetricReader', () => { reader.setMetricProducer(new TestMetricProducer()); const result = await exporter.waitForNumberOfExports(2); - assert.deepEqual(result, [[], []]); + assert.deepStrictEqual(result, [[], []]); exporter.throwException = false; await reader.shutdown(); @@ -227,7 +228,7 @@ describe('PeriodicExportingMetricReader', () => { }); reader.setMetricProducer(new TestMetricProducer()); - await assert.rejects(() => reader.forceFlush({ timeoutMillis: 20 }), + await assertRejects(() => reader.forceFlush({ timeoutMillis: 20 }), TimeoutError); await reader.shutdown(); }); @@ -241,7 +242,7 @@ describe('PeriodicExportingMetricReader', () => { exportTimeoutMillis: 80, }); - await assert.rejects(() => reader.forceFlush()); + await assertRejects(() => reader.forceFlush(), /Error during forceFlush/); }); it('should not forceFlush exporter after shutdown', async () => { @@ -294,7 +295,7 @@ describe('PeriodicExportingMetricReader', () => { }); reader.setMetricProducer(new TestMetricProducer()); - await assert.rejects(() => reader.shutdown({ timeoutMillis: 20 }), + await assertRejects(() => reader.shutdown({ timeoutMillis: 20 }), TimeoutError); }); @@ -326,7 +327,7 @@ describe('PeriodicExportingMetricReader', () => { exportTimeoutMillis: 80, }); - await assert.rejects(() => reader.shutdown()); + await assertRejects(() => reader.shutdown(), /Error during forceFlush/); }); }) ; @@ -340,7 +341,7 @@ describe('PeriodicExportingMetricReader', () => { exportTimeoutMillis: 80, }); - await assert.rejects(() => reader.collect()); + await assertRejects(() => reader.collect(), /MetricReader is not bound to a MetricProducer/); }); it('should return empty on shut-down instance', async () => { @@ -354,7 +355,7 @@ describe('PeriodicExportingMetricReader', () => { reader.setMetricProducer(new TestMetricProducer()); await reader.shutdown(); - assert.deepEqual([], await reader.collect()); + assert.deepStrictEqual([], await reader.collect()); }); it('should time out when timeoutMillis is set', async () => { @@ -368,7 +369,7 @@ describe('PeriodicExportingMetricReader', () => { producer.collectionTime = 40; reader.setMetricProducer(producer); - await assert.rejects( + await assertRejects( () => reader.collect({ timeoutMillis: 20 }), TimeoutError ); diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/index-webpack.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/index-webpack.ts new file mode 100644 index 0000000000..9cfc10baa1 --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/index-webpack.ts @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed 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 + * + * https://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. + */ + +const testsContext = require.context('.', true, /test$/); +testsContext.keys().forEach(testsContext); + +const srcContext = require.context('.', true, /src$/); +srcContext.keys().forEach(srcContext); diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/test-utils.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/test-utils.ts new file mode 100644 index 0000000000..82533608cd --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/test-utils.ts @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed 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 + * + * https://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. + */ + +/** + * Changes to this file should be applied to opentelemetry-core/test/test-utils.ts too. + */ + +import * as assert from 'assert'; + +interface ErrorLikeConstructor { + new(): Error; +} + +/** + * Node.js v8.x and browser compatible `assert.rejects`. + */ +export async function assertRejects(actual: any, expected: RegExp | ErrorLikeConstructor) { + let rejected; + try { + if (typeof actual === 'function') { + await actual(); + } else { + await actual; + } + } catch (err) { + rejected = true; + assert.throws(() => { + throw err; + }, expected); + } + assert(rejected, 'Promise not rejected'); +} diff --git a/packages/opentelemetry-core/test/test-utils.ts b/packages/opentelemetry-core/test/test-utils.ts index 72ec427730..002945691d 100644 --- a/packages/opentelemetry-core/test/test-utils.ts +++ b/packages/opentelemetry-core/test/test-utils.ts @@ -16,15 +16,26 @@ import * as assert from 'assert'; +interface ErrorLikeConstructor { + new(): Error; +} + /** * Node.js v8.x and browser compatible `assert.rejects`. */ -export async function assertRejects(promise: any, expect: any) { +export async function assertRejects(actual: any, expected: RegExp | ErrorLikeConstructor) { + let rejected; try { - await promise; + if (typeof actual === 'function') { + await actual(); + } else { + await actual; + } } catch (err) { + rejected = true; assert.throws(() => { throw err; - }, expect); + }, expected); } + assert(rejected, 'Promise not rejected'); }