From 556eecf0f9d6b6728ad46d17cc2d689f496498f5 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 26 Nov 2024 09:43:23 +0100 Subject: [PATCH 01/10] chore(otlp-exporter-*-proto): clean up tests (#5199) Co-authored-by: Trent Mick --- experimental/CHANGELOG.md | 2 + .../test/browser/OTLPLogExporter.test.ts | 90 ++++- .../test/logHelper.ts | 190 ---------- .../test/node/OTLPLogExporter.test.ts | 332 ++---------------- .../browser/CollectorTraceExporter.test.ts | 38 -- .../test/browser/OTLPTraceExporter.test.ts | 93 +++++ .../test/node/OTLPTraceExporter.test.ts | 318 ++--------------- .../test/traceHelper.ts | 283 --------------- .../test/OTLPMetricExporter.test.ts | 275 ++------------- .../test/metricsHelper.ts | 242 ------------- 10 files changed, 254 insertions(+), 1609 deletions(-) delete mode 100644 experimental/packages/exporter-logs-otlp-proto/test/logHelper.ts delete mode 100644 experimental/packages/exporter-trace-otlp-proto/test/browser/CollectorTraceExporter.test.ts create mode 100644 experimental/packages/exporter-trace-otlp-proto/test/browser/OTLPTraceExporter.test.ts delete mode 100644 experimental/packages/exporter-trace-otlp-proto/test/traceHelper.ts delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 7edb7aa07e..2fca9156dc 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -32,6 +32,8 @@ All notable changes to experimental packages in this project will be documented ### :house: (Internal) +* chore(otlp-exporter-\*-proto): clean up tests [#5196](https://github.com/open-telemetry/opentelemetry-js/pull/5199) @pichlermarc + ## 0.55.0 ### :boom: Breaking Change diff --git a/experimental/packages/exporter-logs-otlp-proto/test/browser/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-proto/test/browser/OTLPLogExporter.test.ts index 29ed48ff4a..dc6ffc2665 100644 --- a/experimental/packages/exporter-logs-otlp-proto/test/browser/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-proto/test/browser/OTLPLogExporter.test.ts @@ -13,26 +13,82 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import * as assert from 'assert'; import * as sinon from 'sinon'; -import { OTLPLogExporter } from '../../src/platform/browser/index'; - -describe('OTLPLogExporter - web', () => { - let collectorLogsExporter: OTLPLogExporter; - describe('constructor', () => { - beforeEach(() => { - const collectorExporterConfig = { - hostname: 'foo', - url: 'http://foo.bar.com', - }; - collectorLogsExporter = new OTLPLogExporter(collectorExporterConfig); - }); - afterEach(() => { - sinon.restore(); + +import { OTLPLogExporter } from '../../src/platform/browser'; +import { + LoggerProvider, + SimpleLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; + +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ + +describe('OTLPLogExporter', function () { + afterEach(() => { + sinon.restore(); + }); + + describe('export', function () { + describe('when sendBeacon is available', function () { + it('should successfully send data using sendBeacon', async function () { + // arrange + const stubBeacon = sinon.stub(navigator, 'sendBeacon'); + const loggerProvider = new LoggerProvider(); + loggerProvider.addLogRecordProcessor( + new SimpleLogRecordProcessor(new OTLPLogExporter()) + ); + + // act + loggerProvider.getLogger('test-logger').emit({ body: 'test-body' }); + await loggerProvider.shutdown(); + + // assert + const args = stubBeacon.args[0]; + const blob: Blob = args[1] as unknown as Blob; + const body = await blob.text(); + assert.throws( + () => JSON.parse(body), + 'expected requestBody to be in protobuf format, but parsing as JSON succeeded' + ); + }); }); - it('should create an instance', () => { - assert.ok(typeof collectorLogsExporter !== 'undefined'); + + describe('when sendBeacon is not available', function () { + beforeEach(function () { + // fake sendBeacon not being available + (window.navigator as any).sendBeacon = false; + }); + + it('should successfully send data using XMLHttpRequest', async function () { + // arrange + const server = sinon.fakeServer.create(); + const loggerProvider = new LoggerProvider(); + loggerProvider.addLogRecordProcessor( + new SimpleLogRecordProcessor(new OTLPLogExporter()) + ); + + // act + loggerProvider.getLogger('test-logger').emit({ body: 'test-body' }); + queueMicrotask(() => { + // simulate success response + server.requests[0].respond(200, {}, ''); + }); + await loggerProvider.shutdown(); + + // assert + const request = server.requests[0]; + const body = request.requestBody as unknown as Uint8Array; + assert.throws( + () => JSON.parse(new TextDecoder().decode(body)), + 'expected requestBody to be in protobuf format, but parsing as JSON succeeded' + ); + }); }); }); }); diff --git a/experimental/packages/exporter-logs-otlp-proto/test/logHelper.ts b/experimental/packages/exporter-logs-otlp-proto/test/logHelper.ts deleted file mode 100644 index c5a110ca1a..0000000000 --- a/experimental/packages/exporter-logs-otlp-proto/test/logHelper.ts +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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. - */ - -import { HrTime, TraceFlags } from '@opentelemetry/api'; -import { SeverityNumber } from '@opentelemetry/api-logs'; -import { Resource } from '@opentelemetry/resources'; -import * as assert from 'assert'; -import { VERSION } from '@opentelemetry/core'; -import { - IAnyValue, - IExportLogsServiceRequest, - IKeyValue, - ILogRecord, - IResource, -} from '@opentelemetry/otlp-transformer'; -import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; -import { Stream } from 'stream'; - -export const mockedReadableLogRecord: ReadableLogRecord = { - resource: Resource.default().merge( - new Resource({ - 'resource-attribute': 'some resource-attr value', - }) - ), - instrumentationScope: { - name: 'scope_name_1', - version: '0.1.0', - schemaUrl: 'http://url.to.schema', - }, - hrTime: [1680253513, 123241635] as HrTime, - hrTimeObserved: [1680253513, 123241635] as HrTime, - attributes: { - 'some-attribute': 'some attribute value', - }, - droppedAttributesCount: 0, - severityNumber: SeverityNumber.ERROR, - severityText: 'error', - body: 'some_log_body', - spanContext: { - traceFlags: TraceFlags.SAMPLED, - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '5e107261f64fa53e', - }, -}; -export function ensureExportedAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'some-attribute', - value: { - stringValue: 'some attribute value', - }, - }, - ], - 'exported attributes are incorrect' - ); -} - -export function ensureExportedBodyIsCorrect(body?: IAnyValue) { - assert.deepStrictEqual( - body, - { stringValue: 'some_log_body' }, - 'exported attributes are incorrect' - ); -} - -export function ensureExportedLogRecordIsCorrect(logRecord: ILogRecord) { - ensureExportedBodyIsCorrect(logRecord.body); - ensureExportedAttributesAreCorrect(logRecord.attributes); - assert.strictEqual( - logRecord.timeUnixNano, - '1680253513123241635', - 'timeUnixNano is wrong' - ); - assert.strictEqual( - logRecord.observedTimeUnixNano, - '1680253513123241635', - 'observedTimeUnixNano is wrong' - ); - assert.strictEqual( - logRecord.severityNumber, - 'SEVERITY_NUMBER_ERROR', - 'severityNumber is wrong' - ); - assert.strictEqual(logRecord.severityText, 'error', 'severityText is wrong'); - assert.strictEqual( - logRecord.droppedAttributesCount, - 0, - 'droppedAttributesCount is wrong' - ); - assert.strictEqual(logRecord.flags, TraceFlags.SAMPLED, 'flags is wrong'); -} - -export function ensureResourceIsCorrect(resource: IResource) { - assert.deepStrictEqual(resource, { - attributes: [ - { - key: 'service.name', - value: { - stringValue: `unknown_service:${process.argv0}`, - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.language', - value: { - stringValue: 'nodejs', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.name', - value: { - stringValue: 'opentelemetry', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.version', - value: { - stringValue: VERSION, - value: 'stringValue', - }, - }, - { - key: 'resource-attribute', - value: { - stringValue: 'some resource-attr value', - value: 'stringValue', - }, - }, - ], - droppedAttributesCount: 0, - }); -} - -export function ensureExportLogsServiceRequestIsSet( - json: IExportLogsServiceRequest -) { - const resourceLogs = json.resourceLogs; - assert.strictEqual(resourceLogs?.length, 1, 'resourceLogs is missing'); - - const resource = resourceLogs?.[0].resource; - assert.ok(resource, 'resource is missing'); - - const scopeLogs = resourceLogs?.[0].scopeLogs; - assert.strictEqual(scopeLogs?.length, 1, 'scopeLogs is missing'); - - const scope = scopeLogs?.[0].scope; - assert.ok(scope, 'scope is missing'); - - const logRecords = scopeLogs?.[0].logRecords; - assert.strictEqual(logRecords?.length, 1, 'logs are missing'); -} - -export class MockedResponse extends Stream { - constructor( - private _code: number, - private _msg?: string - ) { - super(); - } - - send(data: Uint8Array) { - this.emit('data', data); - this.emit('end'); - } - - get statusCode() { - return this._code; - } - - get statusMessage() { - return this._msg; - } -} diff --git a/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts index 475b00ad74..7bb6b9ee4e 100644 --- a/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-proto/test/node/OTLPLogExporter.test.ts @@ -14,333 +14,61 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; -import { ExportResultCode } from '@opentelemetry/core'; import * as assert from 'assert'; import * as http from 'http'; import * as sinon from 'sinon'; -import { Stream, PassThrough } from 'stream'; -import * as zlib from 'zlib'; -import { OTLPLogExporter } from '../../src'; -import { - ensureExportLogsServiceRequestIsSet, - ensureExportedLogRecordIsCorrect, - mockedReadableLogRecord, - MockedResponse, -} from '../logHelper'; -import { - CompressionAlgorithm, - OTLPExporterNodeConfigBase, - OTLPExporterError, -} from '@opentelemetry/otlp-exporter-base'; -import { IExportLogsServiceRequest } from '@opentelemetry/otlp-transformer'; -import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; -import { Root } from 'protobufjs'; -import * as path from 'path'; - -let fakeRequest: PassThrough; -const dir = path.resolve(__dirname, '../../../otlp-transformer/protos'); -const root = new Root(); -root.resolvePath = function (origin, target) { - return `${dir}/${target}`; -}; -const proto = root.loadSync([ - 'opentelemetry/proto/common/v1/common.proto', - 'opentelemetry/proto/resource/v1/resource.proto', - 'opentelemetry/proto/logs/v1/logs.proto', - 'opentelemetry/proto/collector/logs/v1/logs_service.proto', -]); -const exportRequestServiceProto = proto?.lookupType('ExportLogsServiceRequest'); - -describe('OTLPLogExporter - node with proto over http', () => { - let collectorExporter: OTLPLogExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let logs: ReadableLogRecord[]; +import { OTLPLogExporter } from '../../src/platform/node'; +import { + LoggerProvider, + SimpleLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; +import { Stream } from 'stream'; - afterEach(() => { - fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - sinon.restore(); - }); +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ +describe('OTLPLogExporter', () => { describe('export', () => { - beforeEach(() => { - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - httpAgentOptions: { keepAliveMsecs: 2000 }, - }; - collectorExporter = new OTLPLogExporter(collectorExporterConfig); - logs = []; - logs.push(Object.assign({}, mockedReadableLogRecord)); - }); afterEach(() => { sinon.restore(); }); - it('should open the connection', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.hostname, 'foo.bar.com'); - assert.strictEqual(options.method, 'POST'); - assert.strictEqual(options.path, '/'); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - collectorExporter.export(logs, () => {}); - }); - - it('should set custom headers', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.headers['foo'], 'bar'); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - collectorExporter.export(logs, () => {}); - }); - - it('should have keep alive and keepAliveMsecs option set', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.agent.keepAlive, true); - assert.strictEqual(options.agent.options.keepAliveMsecs, 2000); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - collectorExporter.export(logs, () => {}); - }); - - it('should successfully send the logs', done => { + it('successfully exports data', done => { const fakeRequest = new Stream.PassThrough(); Object.defineProperty(fakeRequest, 'setTimeout', { value: function (_timeout: number) {}, }); - sinon.stub(http, 'request').returns(fakeRequest as any); - - let buff = Buffer.from(''); - fakeRequest.on('end', () => { - const data = exportRequestServiceProto.decode(buff); - const json = data?.toJSON() as IExportLogsServiceRequest; - const log1 = json.resourceLogs?.[0].scopeLogs?.[0].logRecords?.[0]; - assert.ok(typeof log1 !== 'undefined', "log doesn't exist"); - ensureExportedLogRecordIsCorrect(log1); - - ensureExportLogsServiceRequestIsSet(json); - - done(); - }); - fakeRequest.on('data', chunk => { - buff = Buffer.concat([buff, chunk]); - }); - - const clock = sinon.useFakeTimers(); - collectorExporter.export(logs, () => {}); - clock.tick(200); - clock.restore(); - }); - - it('should log the successful message', done => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - const spyLoggerError = sinon.stub(diag, 'error'); - - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - }); - return fakeRequest as any; - }); - - collectorExporter.export(logs, result => { - assert.strictEqual(result.code, ExportResultCode.SUCCESS); - assert.strictEqual(spyLoggerError.args.length, 0); - done(); - }); - }); - - it('should log the error message', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(400); - cb(mockRes); - mockRes.send(Buffer.from('failure')); - }); - - return fakeRequest as any; - }); - - collectorExporter.export(logs, result => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - // @ts-expect-error verify error code - assert.strictEqual(result.error.code, 400); - done(); - }); - }); - }); - describe('export - with compression', () => { - beforeEach(() => { - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - compression: CompressionAlgorithm.GZIP, - httpAgentOptions: { keepAliveMsecs: 2000 }, - }; - collectorExporter = new OTLPLogExporter(collectorExporterConfig); - logs = []; - logs.push(Object.assign({}, mockedReadableLogRecord)); - }); - afterEach(() => { - sinon.restore(); - }); - - it('should successfully send the logs', done => { - const fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); sinon.stub(http, 'request').returns(fakeRequest as any); - const spySetHeader = sinon.spy(); - (fakeRequest as any).setHeader = spySetHeader; - let buff = Buffer.from(''); - fakeRequest.on('end', () => { - const unzippedBuff = zlib.gunzipSync(buff); - const data = exportRequestServiceProto.decode(unzippedBuff); - const json = data?.toJSON() as IExportLogsServiceRequest; - const log1 = json.resourceLogs?.[0].scopeLogs?.[0].logRecords?.[0]; - assert.ok(typeof log1 !== 'undefined', "log doesn't exist"); - ensureExportedLogRecordIsCorrect(log1); - - ensureExportLogsServiceRequestIsSet(json); - assert.ok(spySetHeader.calledWith('Content-Encoding', 'gzip')); - - done(); + fakeRequest.on('finish', () => { + try { + const requestBody = buff.toString(); + assert.throws(() => { + JSON.parse(requestBody); + }, 'expected requestBody to be in protobuf format, but parsing as JSON succeeded'); + done(); + } catch (e) { + done(e); + } }); fakeRequest.on('data', chunk => { buff = Buffer.concat([buff, chunk]); }); - const clock = sinon.useFakeTimers(); - collectorExporter.export(logs, () => {}); - clock.tick(200); - clock.restore(); - }); - }); -}); - -describe('export - real http request destroyed before response received', () => { - let collectorExporter: OTLPLogExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let logs: ReadableLogRecord[]; - const server = http.createServer((_, res) => { - setTimeout(() => { - res.statusCode = 200; - res.end(); - }, 1000); - }); - before(done => { - server.listen(8082, done); - }); - after(done => { - server.close(done); - }); - it('should log the timeout request error message when timeout is 1', done => { - collectorExporterConfig = { - url: 'http://localhost:8082', - timeoutMillis: 1, - }; - collectorExporter = new OTLPLogExporter(collectorExporterConfig); - logs = []; - logs.push(Object.assign({}, mockedReadableLogRecord)); - - collectorExporter.export(logs, result => { - try { - assert.strictEqual(result.code, ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'Request Timeout'); - done(); - } catch (e) { - done(e); - } - }); - }); - it('should log the timeout request error message when timeout is 100', done => { - collectorExporterConfig = { - url: 'http://localhost:8082', - timeoutMillis: 100, - }; - collectorExporter = new OTLPLogExporter(collectorExporterConfig); - logs = []; - logs.push(Object.assign({}, mockedReadableLogRecord)); - - collectorExporter.export(logs, result => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'Request Timeout'); - done(); - }); - }); -}); - -describe('export - real http request destroyed after response received', () => { - let collectorExporter: OTLPLogExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let logs: ReadableLogRecord[]; - - const server = http.createServer((_, res) => { - res.write('writing something'); - }); - before(done => { - server.listen(8082, done); - }); - after(done => { - server.close(done); - }); - it('should log the timeout request error message', done => { - collectorExporterConfig = { - url: 'http://localhost:8082', - timeoutMillis: 300, - }; - collectorExporter = new OTLPLogExporter(collectorExporterConfig); - logs = []; - logs.push(Object.assign({}, mockedReadableLogRecord)); + const loggerProvider = new LoggerProvider(); + loggerProvider.addLogRecordProcessor( + new SimpleLogRecordProcessor(new OTLPLogExporter()) + ); - collectorExporter.export(logs, result => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'Request Timeout'); - done(); + loggerProvider.getLogger('test-logger').emit({ body: 'test-body' }); + loggerProvider.shutdown(); }); }); }); diff --git a/experimental/packages/exporter-trace-otlp-proto/test/browser/CollectorTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-proto/test/browser/CollectorTraceExporter.test.ts deleted file mode 100644 index 264d0051f5..0000000000 --- a/experimental/packages/exporter-trace-otlp-proto/test/browser/CollectorTraceExporter.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - */ - -import * as assert from 'assert'; -import * as sinon from 'sinon'; -import { OTLPTraceExporter } from '../../src/platform/browser/index'; - -describe('OTLPTraceExporter - web', () => { - let collectorTraceExporter: OTLPTraceExporter; - describe('constructor', () => { - beforeEach(() => { - const collectorExporterConfig = { - hostname: 'foo', - url: 'http://foo.bar.com', - }; - collectorTraceExporter = new OTLPTraceExporter(collectorExporterConfig); - }); - afterEach(() => { - sinon.restore(); - }); - it('should create an instance', () => { - assert.ok(typeof collectorTraceExporter !== 'undefined'); - }); - }); -}); diff --git a/experimental/packages/exporter-trace-otlp-proto/test/browser/OTLPTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-proto/test/browser/OTLPTraceExporter.test.ts new file mode 100644 index 0000000000..24e517c8b7 --- /dev/null +++ b/experimental/packages/exporter-trace-otlp-proto/test/browser/OTLPTraceExporter.test.ts @@ -0,0 +1,93 @@ +/* + * 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. + */ + +import { + BasicTracerProvider, + SimpleSpanProcessor, +} from '@opentelemetry/sdk-trace-base'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import { OTLPTraceExporter } from '../../src/platform/browser/index'; + +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...) + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + * - `@opentelemetry/otlp-grpc-exporter-base`: gRPC transport + */ + +describe('OTLPTraceExporter', () => { + afterEach(() => { + sinon.restore(); + }); + + describe('export', function () { + describe('when sendBeacon is available', function () { + it('should successfully send data using sendBeacon', async function () { + // arrange + const stubBeacon = sinon.stub(navigator, 'sendBeacon'); + const tracerProvider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())], + }); + + // act + tracerProvider.getTracer('test-tracer').startSpan('test-span').end(); + await tracerProvider.shutdown(); + + // assert + const args = stubBeacon.args[0]; + const blob: Blob = args[1] as unknown as Blob; + const body = await blob.text(); + assert.throws( + () => JSON.parse(body), + 'expected requestBody to be in protobuf format, but parsing as JSON succeeded' + ); + }); + }); + + describe('when sendBeacon is not available', function () { + beforeEach(function () { + // fake sendBeacon not being available + (window.navigator as any).sendBeacon = false; + }); + + it('should successfully send data using XMLHttpRequest', async function () { + // arrange + const server = sinon.fakeServer.create(); + const tracerProvider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())], + }); + + // act + tracerProvider.getTracer('test-tracer').startSpan('test-span').end(); + queueMicrotask(() => { + // simulate success response + server.requests[0].respond(200, {}, ''); + }); + await tracerProvider.shutdown(); + + // assert + const request = server.requests[0]; + const body = request.requestBody as unknown as Uint8Array; + assert.throws( + () => JSON.parse(new TextDecoder().decode(body)), + 'expected requestBody to be in protobuf format, but parsing as JSON succeeded' + ); + }); + }); + }); +}); diff --git a/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts index 355dacac21..c4eeb56d59 100644 --- a/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts +++ b/experimental/packages/exporter-trace-otlp-proto/test/node/OTLPTraceExporter.test.ts @@ -14,328 +14,60 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; -import { ExportResultCode } from '@opentelemetry/core'; -import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import * as assert from 'assert'; import * as http from 'http'; import * as sinon from 'sinon'; -import { Stream, PassThrough } from 'stream'; -import * as zlib from 'zlib'; -import { OTLPTraceExporter } from '../../src'; -import { - ensureExportTraceServiceRequestIsSet, - ensureProtoSpanIsCorrect, - mockedReadableSpan, - MockedResponse, -} from '../traceHelper'; -import { - CompressionAlgorithm, - OTLPExporterNodeConfigBase, - OTLPExporterError, -} from '@opentelemetry/otlp-exporter-base'; -import { IExportTraceServiceRequest } from '@opentelemetry/otlp-transformer'; -import { Root } from 'protobufjs'; -import * as path from 'path'; - -const dir = path.resolve(__dirname, '../../../otlp-transformer/protos'); -const root = new Root(); -root.resolvePath = function (origin, target) { - return `${dir}/${target}`; -}; -const proto = root.loadSync([ - 'opentelemetry/proto/common/v1/common.proto', - 'opentelemetry/proto/resource/v1/resource.proto', - 'opentelemetry/proto/trace/v1/trace.proto', - 'opentelemetry/proto/collector/trace/v1/trace_service.proto', -]); -const exportRequestServiceProto = proto?.lookupType( - 'ExportTraceServiceRequest' -); +import { Stream } from 'stream'; -let fakeRequest: PassThrough; - -describe('OTLPTraceExporter - node with proto over http', () => { - let collectorExporter: OTLPTraceExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let spans: ReadableSpan[]; +import { + BasicTracerProvider, + SimpleSpanProcessor, +} from '@opentelemetry/sdk-trace-base'; +import { OTLPTraceExporter } from '../../src/platform/node'; - afterEach(() => { - fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - sinon.restore(); - }); +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ +describe('OTLPTraceExporter', () => { describe('export', () => { - beforeEach(() => { - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - httpAgentOptions: { keepAliveMsecs: 2000 }, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - }); afterEach(() => { sinon.restore(); }); - it('should open the connection', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - try { - assert.strictEqual(options.hostname, 'foo.bar.com'); - assert.strictEqual(options.method, 'POST'); - assert.strictEqual(options.path, '/'); - } catch (e) { - done(e); - } - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - - collectorExporter.export(spans, () => {}); - }); - - it('should set custom headers', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.headers['foo'], 'bar'); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - - return fakeRequest as any; - }); - - collectorExporter.export(spans, () => {}); - }); - - it('should have keep alive and keepAliveMsecs option set', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.agent.keepAlive, true); - assert.strictEqual(options.agent.options.keepAliveMsecs, 2000); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - - return fakeRequest as any; - }); - - collectorExporter.export(spans, () => {}); - }); - - it('should successfully send the spans', done => { + it('successfully exports data', done => { const fakeRequest = new Stream.PassThrough(); Object.defineProperty(fakeRequest, 'setTimeout', { value: function (_timeout: number) {}, }); - sinon.stub(http, 'request').returns(fakeRequest as any); + sinon.stub(http, 'request').returns(fakeRequest as any); let buff = Buffer.from(''); fakeRequest.on('finish', () => { - const data = exportRequestServiceProto.decode(buff); - const json = data?.toJSON() as IExportTraceServiceRequest; - const span1 = json.resourceSpans?.[0].scopeSpans?.[0].spans?.[0]; - assert.ok(typeof span1 !== 'undefined', "span doesn't exist"); - ensureProtoSpanIsCorrect(span1); - - ensureExportTraceServiceRequestIsSet(json); - - done(); - }); - - fakeRequest.on('data', chunk => { - buff = Buffer.concat([buff, chunk]); - }); - - const clock = sinon.useFakeTimers(); - collectorExporter.export(spans, () => {}); - clock.tick(200); - clock.restore(); - }); - - it('should log the successful message', done => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - const spyLoggerError = sinon.stub(diag, 'error'); - - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - }); - - return fakeRequest as any; - }); - - collectorExporter.export(spans, result => { try { - assert.strictEqual(result.code, ExportResultCode.SUCCESS); - assert.strictEqual(spyLoggerError.args.length, 0); + const requestBody = buff.toString(); + assert.throws(() => { + JSON.parse(requestBody); + }, 'expected requestBody to be in protobuf format, but parsing as JSON succeeded'); done(); } catch (e) { done(e); } }); - }); - - it('should log the error message', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(400); - cb(mockRes); - mockRes.send(Buffer.from('failure')); - }); - - return fakeRequest as any; - }); - - collectorExporter.export(spans, result => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - // @ts-expect-error verify error code - assert.strictEqual(result.error.code, 400); - done(); - }); - }); - }); - describe('export - with compression', () => { - beforeEach(() => { - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - compression: CompressionAlgorithm.GZIP, - httpAgentOptions: { keepAliveMsecs: 2000 }, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - }); - afterEach(() => { - sinon.restore(); - }); - - it('should successfully send the spans', done => { - const fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - sinon.stub(http, 'request').returns(fakeRequest as any); - const spySetHeader = sinon.spy(); - (fakeRequest as any).setHeader = spySetHeader; - - let buff = Buffer.from(''); - fakeRequest.on('finish', () => { - const unzippedBuff = zlib.gunzipSync(buff); - const data = exportRequestServiceProto.decode(unzippedBuff); - const json = data?.toJSON() as IExportTraceServiceRequest; - const span1 = json.resourceSpans?.[0].scopeSpans?.[0].spans?.[0]; - assert.ok(typeof span1 !== 'undefined', "span doesn't exist"); - ensureProtoSpanIsCorrect(span1); - - ensureExportTraceServiceRequestIsSet(json); - assert.ok(spySetHeader.calledWith('Content-Encoding', 'gzip')); - - done(); - }); fakeRequest.on('data', chunk => { buff = Buffer.concat([buff, chunk]); }); - const clock = sinon.useFakeTimers(); - collectorExporter.export(spans, () => {}); - clock.tick(200); - clock.restore(); - }); - }); -}); - -describe('export - real http request destroyed before response received', () => { - let collectorExporter: OTLPTraceExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let spans: ReadableSpan[]; - const server = http.createServer((_, res) => { - setTimeout(() => { - res.statusCode = 200; - res.end(); - }, 1000); - }); - before(done => { - server.listen(8080, done); - }); - after(done => { - server.close(done); - }); - it('should log the timeout request error message when timeout is 100', done => { - collectorExporterConfig = { - url: 'http://localhost:8080', - timeoutMillis: 100, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - collectorExporter.export(spans, result => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'Request Timeout'); - done(); - }); - }); -}); - -describe('export - real http request destroyed after response received', () => { - let collectorExporter: OTLPTraceExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let spans: ReadableSpan[]; - - const server = http.createServer((_, res) => { - res.write('writing something'); - }); - before(done => { - server.listen(8080, done); - }); - after(done => { - server.close(done); - }); - it('should log the timeout request error message', done => { - collectorExporterConfig = { - url: 'http://localhost:8080', - timeoutMillis: 300, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - collectorExporter.export(spans, result => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'Request Timeout'); - done(); + new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())], + }) + .getTracer('test-tracer') + .startSpan('test-span') + .end(); }); }); }); diff --git a/experimental/packages/exporter-trace-otlp-proto/test/traceHelper.ts b/experimental/packages/exporter-trace-otlp-proto/test/traceHelper.ts deleted file mode 100644 index efbdc03283..0000000000 --- a/experimental/packages/exporter-trace-otlp-proto/test/traceHelper.ts +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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. - */ - -import { SpanStatusCode, TraceFlags } from '@opentelemetry/api'; -import { hexToBase64 } from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; -import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import * as assert from 'assert'; -import { Stream } from 'stream'; -import { - IEvent, - IExportTraceServiceRequest, - IKeyValue, - ILink, - ISpan, -} from '@opentelemetry/otlp-transformer'; - -const traceIdHex = '1f1008dc8e270e85c40a0d7c3939b278'; -const spanIdHex = '5e107261f64fa53e'; -const parentIdHex = '78a8915098864388'; - -export const mockedReadableSpan: ReadableSpan = { - name: 'documentFetch', - kind: 0, - spanContext: () => { - return { - traceId: traceIdHex, - spanId: spanIdHex, - traceFlags: TraceFlags.SAMPLED, - }; - }, - parentSpanId: parentIdHex, - startTime: [1574120165, 429803070], - endTime: [1574120165, 438688070], - ended: true, - status: { code: SpanStatusCode.OK }, - attributes: { component: 'document-load' }, - links: [ - { - context: { - traceId: traceIdHex, - spanId: parentIdHex, - traceFlags: TraceFlags.SAMPLED, - }, - attributes: { component: 'document-load' }, - }, - ], - events: [ - { - name: 'fetchStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupEnd', - time: [1574120165, 429803070], - }, - { - name: 'connectStart', - time: [1574120165, 429803070], - }, - { - name: 'connectEnd', - time: [1574120165, 429803070], - }, - { - name: 'requestStart', - time: [1574120165, 435513070], - }, - { - name: 'responseStart', - time: [1574120165, 436923070], - }, - { - name: 'responseEnd', - time: [1574120165, 438688070], - }, - ], - duration: [0, 8885000], - resource: new Resource({ - service: 'ui', - version: 1, - cost: 112.12, - }), - instrumentationLibrary: { name: 'default', version: '0.0.1' }, - droppedAttributesCount: 0, - droppedEventsCount: 0, - droppedLinksCount: 0, -}; - -export function ensureProtoEventsAreCorrect(events: IEvent[]) { - assert.deepStrictEqual( - events, - [ - { - timeUnixNano: '1574120165429803070', - name: 'fetchStart', - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'domainLookupStart', - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'domainLookupEnd', - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'connectStart', - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'connectEnd', - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165435513070', - name: 'requestStart', - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165436923070', - name: 'responseStart', - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165438688070', - name: 'responseEnd', - droppedAttributesCount: 0, - }, - ], - 'events are incorrect' - ); -} - -export function ensureProtoAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'component', - value: { - stringValue: 'document-load', - }, - }, - ], - 'attributes are incorrect' - ); -} - -export function ensureProtoLinksAreCorrect(attributes: ILink[]) { - assert.deepStrictEqual( - attributes, - [ - { - traceId: hexToBase64(traceIdHex), - spanId: hexToBase64(parentIdHex), - attributes: [ - { - key: 'component', - value: { - stringValue: 'document-load', - }, - }, - ], - droppedAttributesCount: 0, - }, - ], - 'links are incorrect' - ); -} - -export function ensureProtoSpanIsCorrect(span: ISpan) { - if (span.attributes) { - ensureProtoAttributesAreCorrect(span.attributes); - } - if (span.events) { - ensureProtoEventsAreCorrect(span.events); - } - if (span.links) { - ensureProtoLinksAreCorrect(span.links); - } - assert.deepStrictEqual( - span.traceId, - hexToBase64(traceIdHex), - 'traceId is' + ' wrong' - ); - assert.deepStrictEqual( - span.spanId, - hexToBase64(spanIdHex), - 'spanId is' + ' wrong' - ); - assert.deepStrictEqual( - span.parentSpanId, - hexToBase64(parentIdHex), - 'parentIdArr is wrong' - ); - assert.strictEqual(span.name, 'documentFetch', 'name is wrong'); - assert.strictEqual(span.kind, 'SPAN_KIND_INTERNAL', 'kind is wrong'); - assert.strictEqual( - span.startTimeUnixNano, - '1574120165429803070', - 'startTimeUnixNano is wrong' - ); - assert.strictEqual( - span.endTimeUnixNano, - '1574120165438688070', - 'endTimeUnixNano is wrong' - ); - assert.strictEqual( - span.droppedAttributesCount, - 0, - 'droppedAttributesCount is wrong' - ); - assert.strictEqual(span.droppedEventsCount, 0, 'droppedEventsCount is wrong'); - assert.strictEqual(span.droppedLinksCount, 0, 'droppedLinksCount is wrong'); - assert.deepStrictEqual( - span.status, - { code: 'STATUS_CODE_OK' }, - 'status is wrong' - ); -} - -export function ensureExportTraceServiceRequestIsSet( - json: IExportTraceServiceRequest -) { - const resourceSpans = json.resourceSpans; - assert.strictEqual(resourceSpans?.length, 1, 'resourceSpans is missing'); - - const resource = resourceSpans?.[0].resource; - assert.ok(resource, 'resource is missing'); - - const scopeSpans = resourceSpans?.[0].scopeSpans; - assert.strictEqual(scopeSpans?.length, 1, 'scopeSpans is missing'); - - const scope = scopeSpans?.[0].scope; - assert.ok(scope, 'scope is missing'); - - const spans = scopeSpans?.[0].spans; - assert.strictEqual(spans?.length, 1, 'spans are missing'); -} - -export class MockedResponse extends Stream { - constructor( - private _code: number, - private _msg?: string - ) { - super(); - } - - send(data: Uint8Array) { - this.emit('data', data); - this.emit('end'); - } - - get statusCode() { - return this._code; - } - - get statusMessage() { - return this._msg; - } -} diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts index d8dcdc72b6..aeb7e14ecb 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts @@ -14,222 +14,46 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; -import { ExportResultCode } from '@opentelemetry/core'; import * as assert from 'assert'; import * as http from 'http'; import * as sinon from 'sinon'; -import { OTLPMetricExporter } from '../src'; +import { OTLPMetricExporter } from '../src/'; import { - ensureExportedCounterIsCorrect, - ensureExportedObservableGaugeIsCorrect, - ensureExportedHistogramIsCorrect, - ensureExportMetricsServiceRequestIsSet, - mockCounter, - MockedResponse, - mockObservableGauge, - mockHistogram, - collect, - setUp, - shutdown, -} from './metricsHelper'; -import { ResourceMetrics } from '@opentelemetry/sdk-metrics'; -import { - AggregationTemporalityPreference, - OTLPMetricExporterOptions, -} from '@opentelemetry/exporter-metrics-otlp-http'; -import { Stream, PassThrough } from 'stream'; -import { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'; -import { Root } from 'protobufjs'; -import * as path from 'path'; - -let fakeRequest: PassThrough; - -const dir = path.resolve(__dirname, '../../otlp-transformer/protos'); -const root = new Root(); -root.resolvePath = function (origin, target) { - return `${dir}/${target}`; -}; -const proto = root.loadSync([ - 'opentelemetry/proto/common/v1/common.proto', - 'opentelemetry/proto/resource/v1/resource.proto', - 'opentelemetry/proto/metrics/v1/metrics.proto', - 'opentelemetry/proto/collector/metrics/v1/metrics_service.proto', -]); -const exportRequestServiceProto = proto?.lookupType( - 'ExportMetricsServiceRequest' -); - -describe('OTLPMetricExporter - node with proto over http', () => { - let collectorExporter: OTLPMetricExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase & - OTLPMetricExporterOptions; - let metrics: ResourceMetrics; + MeterProvider, + PeriodicExportingMetricReader, +} from '@opentelemetry/sdk-metrics'; +import { Stream } from 'stream'; - afterEach(() => { - fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - sinon.restore(); - }); +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ +describe('OTLPMetricExporter', () => { describe('export', () => { - beforeEach(async () => { - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - httpAgentOptions: { keepAliveMsecs: 2000 }, - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }; - collectorExporter = new OTLPMetricExporter(collectorExporterConfig); - setUp(); - - const counter = mockCounter(); - mockObservableGauge(observableResult => { - observableResult.observe(3, {}); - observableResult.observe(6, {}); - }); - const histogram = mockHistogram(); - - counter.add(1); - histogram.record(7); - histogram.record(14); - - const { resourceMetrics, errors } = await collect(); - assert.strictEqual(errors.length, 0); - metrics = resourceMetrics; - }); - - afterEach(async () => { - await shutdown(); + afterEach(() => { sinon.restore(); }); - it('should open the connection', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.hostname, 'foo.bar.com'); - assert.strictEqual(options.method, 'POST'); - assert.strictEqual(options.path, '/'); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - - collectorExporter.export(metrics, () => {}); - }); - - it('should set custom headers', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.headers['foo'], 'bar'); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - - collectorExporter.export(metrics, () => {}); - }); - - it('should have keep alive and keepAliveMsecs option set', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - try { - assert.strictEqual(options.agent.keepAlive, true); - assert.strictEqual(options.agent.options.keepAliveMsecs, 2000); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - } catch (e) { - done(e); - } - return fakeRequest as any; - }); - - collectorExporter.export(metrics, () => {}); - }); - - it('should successfully send metrics', done => { + it('successfully exports data', function (done) { + // arrange const fakeRequest = new Stream.PassThrough(); Object.defineProperty(fakeRequest, 'setTimeout', { value: function (_timeout: number) {}, }); - sinon.stub(http, 'request').returns(fakeRequest as any); + sinon.stub(http, 'request').returns(fakeRequest as any); let buff = Buffer.from(''); - fakeRequest.on('finish', () => { try { - const data = exportRequestServiceProto.decode(buff); - const json = data?.toJSON() as any; - - // The order of the metrics is not guaranteed. - const counterIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-counter' - ); - const observableIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'double-observable-gauge' - ); - const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-histogram' - ); - - const metric1 = - json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; - const metric2 = - json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; - const metric3 = - json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; - - assert.ok(typeof metric1 !== 'undefined', "counter doesn't exist"); - ensureExportedCounterIsCorrect( - metric1, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].endTime, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0] - .startTime - ); - assert.ok( - typeof metric2 !== 'undefined', - "observable gauge doesn't exist" - ); - ensureExportedObservableGaugeIsCorrect( - metric2, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .startTime - ); - assert.ok( - typeof metric3 !== 'undefined', - "value recorder doesn't exist" - ); - ensureExportedHistogramIsCorrect( - metric3, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .startTime, - [0, 100], - ['0', '2', '0'] - ); - - ensureExportMetricsServiceRequestIsSet(json); + // assert + const requestBody = buff.toString(); + assert.throws(() => { + JSON.parse(requestBody); + }, 'expected requestBody to be in protobuf format, but parsing as JSON succeeded'); done(); } catch (e) { done(e); @@ -240,55 +64,18 @@ describe('OTLPMetricExporter - node with proto over http', () => { buff = Buffer.concat([buff, chunk]); }); - try { - collectorExporter.export(metrics, () => {}); - } catch (error) { - done(error); - } - }); - - it('should log the successful message', done => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - const spyLoggerError = sinon.stub(diag, 'error'); - - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - }); - - return fakeRequest as any; - }); - - collectorExporter.export(metrics, result => { - assert.strictEqual(result.code, ExportResultCode.SUCCESS); - sinon.assert.notCalled(spyLoggerError); - done(); - }); - }); - - it('should return the error code message', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(400); - cb(mockRes); - mockRes.send(Buffer.from('failure')); - }); - - return fakeRequest as any; + const meterProvider = new MeterProvider({ + readers: [ + new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter(), + }), + ], }); + meterProvider.getMeter('test-meter').createCounter('test-counter').add(1); - collectorExporter.export(metrics, result => { - try { - assert.strictEqual(result.code, ExportResultCode.FAILED); - // @ts-expect-error verify error code - assert.strictEqual(result.error.code, 400); - done(); - } catch (e) { - done(e); - } - }); + // act + meterProvider.forceFlush(); + meterProvider.shutdown(); }); }); }); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts deleted file mode 100644 index effc732b37..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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. - */ - -import { - Counter, - ObservableResult, - Histogram, - ValueType, - ObservableGauge, - HrTime, -} from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; -import * as assert from 'assert'; -import { - ExplicitBucketHistogramAggregation, - MeterProvider, - MetricReader, - View, -} from '@opentelemetry/sdk-metrics'; -import { - encodeAsString, - IExportMetricsServiceRequest, - IKeyValue, - IMetric, -} from '@opentelemetry/otlp-transformer'; -import { Stream } from 'stream'; - -export class TestMetricReader extends MetricReader { - protected onForceFlush(): Promise { - return Promise.resolve(undefined); - } - - protected onShutdown(): Promise { - return Promise.resolve(undefined); - } -} - -const testResource = new Resource({ - service: 'ui', - version: 1, - cost: 112.12, -}); - -let reader = new TestMetricReader(); -let meterProvider = new MeterProvider({ - resource: testResource, - readers: [reader], -}); - -let meter = meterProvider.getMeter('default', '0.0.1'); - -export async function collect() { - return (await reader.collect())!; -} - -export function setUp() { - reader = new TestMetricReader(); - meterProvider = new MeterProvider({ - resource: testResource, - views: [ - new View({ - aggregation: new ExplicitBucketHistogramAggregation([0, 100]), - instrumentName: 'int-histogram', - }), - ], - readers: [reader], - }); - meter = meterProvider.getMeter('default', '0.0.1'); -} - -export async function shutdown() { - await meterProvider.shutdown(); -} - -export function mockCounter(): Counter { - const name = 'int-counter'; - return meter.createCounter(name, { - description: 'sample counter description', - valueType: ValueType.INT, - }); -} - -export function mockObservableGauge( - callback: (observableResult: ObservableResult) => void -): ObservableGauge { - const name = 'double-observable-gauge'; - const observableGauge = meter.createObservableGauge(name, { - description: 'sample observable gauge description', - valueType: ValueType.DOUBLE, - }); - observableGauge.addCallback(callback); - - return observableGauge; -} - -export function mockHistogram(): Histogram { - const name = 'int-histogram'; - - return meter.createHistogram(name, { - description: 'sample histogram description', - valueType: ValueType.INT, - }); -} - -export function ensureProtoAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'component', - value: { - stringValue: 'document-load', - }, - }, - ], - 'attributes are incorrect' - ); -} - -export function ensureExportedCounterIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime -) { - assert.strictEqual(metric.name, 'int-counter'); - assert.strictEqual(metric.description, 'sample counter description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.sum?.dataPoints.length, 1); - assert.strictEqual(metric.sum?.isMonotonic, true); - assert.strictEqual( - metric.sum?.aggregationTemporality, - 'AGGREGATION_TEMPORALITY_CUMULATIVE' - ); - - const [dp] = metric.sum.dataPoints; - assert.strictEqual(dp.asInt, '1'); - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); -} - -export function ensureExportedObservableGaugeIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime -) { - assert.strictEqual(metric.name, 'double-observable-gauge'); - assert.strictEqual(metric.description, 'sample observable gauge description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.gauge?.dataPoints.length, 1); - - const [dp] = metric.gauge.dataPoints; - assert.strictEqual(dp.asDouble, 6); - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); -} - -export function ensureExportedHistogramIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime, - explicitBounds: number[] = [Infinity], - bucketCounts: string[] = ['2', '0'] -) { - assert.strictEqual(metric.name, 'int-histogram'); - assert.strictEqual(metric.description, 'sample histogram description'); - assert.strictEqual(metric.unit, ''); - - assert.strictEqual(metric.histogram?.dataPoints.length, 1); - assert.strictEqual( - metric.histogram.aggregationTemporality, - 'AGGREGATION_TEMPORALITY_CUMULATIVE' - ); - - const [dp] = metric.histogram.dataPoints; - - assert.strictEqual(dp.sum, 21); - assert.strictEqual(dp.count, '2'); - assert.strictEqual(dp.min, 7); - assert.strictEqual(dp.max, 14); - assert.deepStrictEqual(dp.explicitBounds, explicitBounds); - assert.deepStrictEqual(dp.bucketCounts, bucketCounts); - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); -} - -export function ensureExportMetricsServiceRequestIsSet( - json: IExportMetricsServiceRequest -) { - const resourceMetrics = json.resourceMetrics; - assert.strictEqual( - resourceMetrics.length, - 1, - 'resourceMetrics has incorrect length' - ); - - const resource = resourceMetrics[0].resource; - assert.ok(resource, 'resource is missing'); - - const scopeMetrics = resourceMetrics[0].scopeMetrics; - assert.strictEqual(scopeMetrics?.length, 1, 'scopeMetrics is missing'); - - const scope = scopeMetrics[0].scope; - assert.ok(scope, 'scope is missing'); - - const metrics = resourceMetrics[0].scopeMetrics[0].metrics; - assert.strictEqual(metrics.length, 3, 'Metrics are missing'); -} - -export class MockedResponse extends Stream { - constructor( - private _code: number, - private _msg?: string - ) { - super(); - } - - send(data: Uint8Array) { - this.emit('data', data); - this.emit('end'); - } - - get statusCode() { - return this._code; - } - - get statusMessage() { - return this._msg; - } -} From e35f3d659ea19fd1094655375a2ffe13c4367941 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 26 Nov 2024 10:13:48 +0100 Subject: [PATCH 02/10] chore(exporter-otlp-*-http): clean up tests (#5198) --- experimental/CHANGELOG.md | 1 + .../test/browser/OTLPLogExporter.test.ts | 72 ++- .../exporter-logs-otlp-http/test/logHelper.ts | 167 ------ .../test/node/OTLPLogExporter.test.ts | 193 +----- .../browser/CollectorTraceExporter.test.ts | 560 ------------------ .../test/browser/OTLPTraceExporter.test.ts | 93 +++ .../test/node/CollectorTraceExporter.test.ts | 442 -------------- .../test/node/OTLPTraceExporter.test.ts | 73 +++ .../test/node/nodeHelpers.ts | 39 -- .../test/traceHelper.ts | 443 -------------- .../browser/CollectorMetricExporter.test.ts | 435 -------------- .../test/browser/OTLPMetricExporter.test.ts | 108 ++++ .../test/metricsHelper.ts | 341 ----------- .../test/node/CollectorMetricExporter.test.ts | 462 --------------- .../test/node/OTLPMetricExporter.test.ts | 221 +++++++ .../test/node/nodeHelpers.ts | 39 -- 16 files changed, 589 insertions(+), 3100 deletions(-) delete mode 100644 experimental/packages/exporter-logs-otlp-http/test/logHelper.ts delete mode 100644 experimental/packages/exporter-trace-otlp-http/test/browser/CollectorTraceExporter.test.ts create mode 100644 experimental/packages/exporter-trace-otlp-http/test/browser/OTLPTraceExporter.test.ts delete mode 100644 experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts create mode 100644 experimental/packages/exporter-trace-otlp-http/test/node/OTLPTraceExporter.test.ts delete mode 100644 experimental/packages/exporter-trace-otlp-http/test/node/nodeHelpers.ts delete mode 100644 experimental/packages/exporter-trace-otlp-http/test/traceHelper.ts delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts create mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/OTLPMetricExporter.test.ts delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts create mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/OTLPMetricExporter.test.ts delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/nodeHelpers.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 2fca9156dc..3363d30f8d 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to experimental packages in this project will be documented ### :house: (Internal) +* chore(otlp-exporter-\*-http): clean up tests [#5196](https://github.com/open-telemetry/opentelemetry-js/pull/5198) @pichlermarc * chore(otlp-exporter-\*-proto): clean up tests [#5196](https://github.com/open-telemetry/opentelemetry-js/pull/5199) @pichlermarc ## 0.55.0 diff --git a/experimental/packages/exporter-logs-otlp-http/test/browser/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-http/test/browser/OTLPLogExporter.test.ts index b02e56f069..4870b6681c 100644 --- a/experimental/packages/exporter-logs-otlp-http/test/browser/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-http/test/browser/OTLPLogExporter.test.ts @@ -17,16 +17,78 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { OTLPLogExporter } from '../../src/platform/browser'; +import { + LoggerProvider, + SimpleLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; -describe('OTLPLogExporter', () => { +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ + +describe('OTLPLogExporter', function () { afterEach(() => { sinon.restore(); }); - describe('constructor', () => { - it('should create an instance', () => { - const exporter = new OTLPLogExporter(); - assert.ok(exporter instanceof OTLPLogExporter); + describe('export', function () { + describe('when sendBeacon is available', function () { + it('should successfully send data using sendBeacon', async function () { + // arrange + const stubBeacon = sinon.stub(navigator, 'sendBeacon'); + const loggerProvider = new LoggerProvider(); + loggerProvider.addLogRecordProcessor( + new SimpleLogRecordProcessor(new OTLPLogExporter()) + ); + + // act + loggerProvider.getLogger('test-logger').emit({ body: 'test-body' }); + await loggerProvider.shutdown(); + + // assert + const args = stubBeacon.args[0]; + const blob: Blob = args[1] as unknown as Blob; + const body = await blob.text(); + assert.doesNotThrow( + () => JSON.parse(body), + 'expected requestBody to be in JSON format, but parsing failed' + ); + }); + }); + + describe('when sendBeacon is not available', function () { + beforeEach(function () { + // fake sendBeacon not being available + (window.navigator as any).sendBeacon = false; + }); + + it('should successfully send data using XMLHttpRequest', async function () { + // arrange + const server = sinon.fakeServer.create(); + const loggerProvider = new LoggerProvider(); + loggerProvider.addLogRecordProcessor( + new SimpleLogRecordProcessor(new OTLPLogExporter()) + ); + + // act + loggerProvider.getLogger('test-logger').emit({ body: 'test-body' }); + queueMicrotask(() => { + // simulate success response + server.requests[0].respond(200, {}, ''); + }); + await loggerProvider.shutdown(); + + // assert + const request = server.requests[0]; + const body = request.requestBody as unknown as Uint8Array; + assert.doesNotThrow( + () => JSON.parse(new TextDecoder().decode(body)), + 'expected requestBody to be in JSON format, but parsing failed' + ); + }); }); }); }); diff --git a/experimental/packages/exporter-logs-otlp-http/test/logHelper.ts b/experimental/packages/exporter-logs-otlp-http/test/logHelper.ts deleted file mode 100644 index 11facc4402..0000000000 --- a/experimental/packages/exporter-logs-otlp-http/test/logHelper.ts +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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. - */ - -import { HrTime, TraceFlags } from '@opentelemetry/api'; -import { SeverityNumber } from '@opentelemetry/api-logs'; -import { Resource } from '@opentelemetry/resources'; -import * as assert from 'assert'; -import { VERSION } from '@opentelemetry/core'; -import { - IAnyValue, - IExportLogsServiceRequest, - IKeyValue, - ILogRecord, - IResource, -} from '@opentelemetry/otlp-transformer'; -import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; - -export const mockedReadableLogRecord: ReadableLogRecord = { - resource: Resource.default().merge( - new Resource({ - 'resource-attribute': 'some resource-attr value', - }) - ), - instrumentationScope: { - name: 'scope_name_1', - version: '0.1.0', - schemaUrl: 'http://url.to.schema', - }, - hrTime: [1680253513, 123241635] as HrTime, - hrTimeObserved: [1680253513, 123241635] as HrTime, - attributes: { - 'some-attribute': 'some attribute value', - }, - droppedAttributesCount: 0, - severityNumber: SeverityNumber.ERROR, - severityText: 'error', - body: 'some_log_body', - spanContext: { - traceFlags: TraceFlags.SAMPLED, - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '5e107261f64fa53e', - }, -}; -export function ensureExportedAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'some-attribute', - value: { - stringValue: 'some attribute value', - }, - }, - ], - 'exported attributes are incorrect' - ); -} - -export function ensureExportedBodyIsCorrect(body?: IAnyValue) { - assert.deepStrictEqual( - body, - { stringValue: 'some_log_body' }, - 'exported attributes are incorrect' - ); -} - -export function ensureExportedLogRecordIsCorrect(logRecord: ILogRecord) { - ensureExportedBodyIsCorrect(logRecord.body); - ensureExportedAttributesAreCorrect(logRecord.attributes); - assert.deepStrictEqual( - logRecord.timeUnixNano, - '1680253513123241635', - 'timeUnixNano is wrong' - ); - assert.deepStrictEqual( - logRecord.observedTimeUnixNano, - '1680253513123241635', - 'observedTimeUnixNano is wrong' - ); - assert.strictEqual( - logRecord.severityNumber, - SeverityNumber.ERROR, - 'severityNumber is wrong' - ); - assert.strictEqual(logRecord.severityText, 'error', 'severityText is wrong'); - assert.strictEqual( - logRecord.droppedAttributesCount, - 0, - 'droppedAttributesCount is wrong' - ); - assert.strictEqual(logRecord.flags, TraceFlags.SAMPLED, 'flags is wrong'); -} - -export function ensureResourceIsCorrect(resource: IResource) { - assert.deepStrictEqual(resource, { - attributes: [ - { - key: 'service.name', - value: { - stringValue: `unknown_service:${process.argv0}`, - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.language', - value: { - stringValue: 'nodejs', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.name', - value: { - stringValue: 'opentelemetry', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.version', - value: { - stringValue: VERSION, - value: 'stringValue', - }, - }, - { - key: 'resource-attribute', - value: { - stringValue: 'some resource-attr value', - value: 'stringValue', - }, - }, - ], - droppedAttributesCount: 0, - }); -} - -export function ensureExportLogsServiceRequestIsSet( - json: IExportLogsServiceRequest -) { - const resourceLogs = json.resourceLogs; - assert.strictEqual(resourceLogs?.length, 1, 'resourceLogs is missing'); - - const resource = resourceLogs?.[0].resource; - assert.ok(resource, 'resource is missing'); - - const scopeLogs = resourceLogs?.[0].scopeLogs; - assert.strictEqual(scopeLogs?.length, 1, 'scopeLogs is missing'); - - const scope = scopeLogs?.[0].scope; - assert.ok(scope, 'scope is missing'); - - const logRecords = scopeLogs?.[0].logRecords; - assert.strictEqual(logRecords?.length, 1, 'logs are missing'); -} diff --git a/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts index dd31888e14..b746f83db2 100644 --- a/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-http/test/node/OTLPLogExporter.test.ts @@ -14,136 +14,31 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; import * as assert from 'assert'; import * as http from 'http'; import * as sinon from 'sinon'; import { OTLPLogExporter } from '../../src/platform/node'; -import { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'; -import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; import { - ensureExportLogsServiceRequestIsSet, - ensureExportedLogRecordIsCorrect, - mockedReadableLogRecord, -} from '../logHelper'; -import { PassThrough, Stream } from 'stream'; -import { IExportLogsServiceRequest } from '@opentelemetry/otlp-transformer'; -import { ExportResultCode } from '@opentelemetry/core'; + LoggerProvider, + SimpleLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; +import { Stream } from 'stream'; -let fakeRequest: PassThrough; - -class MockedResponse extends Stream { - constructor( - private _code: number, - private _msg?: string - ) { - super(); - } - - send(data: Uint8Array) { - this.emit('data', data); - this.emit('end'); - } - - get statusCode() { - return this._code; - } - - get statusMessage() { - return this._msg; - } -} +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ describe('OTLPLogExporter', () => { - let collectorExporter: OTLPLogExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let logs: ReadableLogRecord[]; - - afterEach(() => { - fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - sinon.restore(); - }); - - describe('constructor', () => { - it('should create an instance', () => { - const exporter = new OTLPLogExporter(); - assert.ok(exporter instanceof OTLPLogExporter); - }); - }); - describe('export', () => { - beforeEach(() => { - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - httpAgentOptions: { keepAliveMsecs: 2000 }, - }; - collectorExporter = new OTLPLogExporter(collectorExporterConfig); - logs = []; - logs.push(Object.assign({}, mockedReadableLogRecord)); - }); afterEach(() => { sinon.restore(); }); - it('should open the connection', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.hostname, 'foo.bar.com'); - assert.strictEqual(options.method, 'POST'); - assert.strictEqual(options.path, '/'); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - collectorExporter.export(logs, () => {}); - }); - - it('should set custom headers', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.headers['foo'], 'bar'); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - - collectorExporter.export(logs, () => {}); - }); - - it('should have keep alive and keepAliveMsecs option set', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - assert.strictEqual(options.agent.keepAlive, true); - assert.strictEqual(options.agent.options.keepAliveMsecs, 2000); - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - done(); - }); - return fakeRequest as any; - }); - - collectorExporter.export(logs, () => {}); - }); - - it('should successfully send the logs', done => { + it('successfully exports data', done => { const fakeRequest = new Stream.PassThrough(); Object.defineProperty(fakeRequest, 'setTimeout', { value: function (_timeout: number) {}, @@ -152,64 +47,28 @@ describe('OTLPLogExporter', () => { sinon.stub(http, 'request').returns(fakeRequest as any); let buff = Buffer.from(''); fakeRequest.on('finish', () => { - const responseBody = buff.toString(); - const json = JSON.parse(responseBody) as IExportLogsServiceRequest; - const log1 = json.resourceLogs?.[0].scopeLogs?.[0].logRecords?.[0]; - assert.ok(typeof log1 !== 'undefined', "log doesn't exist"); - ensureExportedLogRecordIsCorrect(log1); - - ensureExportLogsServiceRequestIsSet(json); - - done(); + try { + const requestBody = buff.toString(); + assert.doesNotThrow(() => { + JSON.parse(requestBody); + }, 'expected requestBody to be in JSON format, but parsing failed'); + done(); + } catch (e) { + done(e); + } }); fakeRequest.on('data', chunk => { buff = Buffer.concat([buff, chunk]); }); - const clock = sinon.useFakeTimers(); - collectorExporter.export(logs, () => {}); - clock.tick(200); - clock.restore(); - }); - - it('should log the successful message', done => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - const spyLoggerError = sinon.stub(diag, 'error'); - - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - cb(mockRes); - mockRes.send(Buffer.from('success')); - }); - return fakeRequest as any; - }); + const loggerProvider = new LoggerProvider(); + loggerProvider.addLogRecordProcessor( + new SimpleLogRecordProcessor(new OTLPLogExporter()) + ); - collectorExporter.export(logs, result => { - assert.strictEqual(result.code, ExportResultCode.SUCCESS); - assert.strictEqual(spyLoggerError.args.length, 0); - done(); - }); - }); - - it('should log the error message', done => { - sinon.stub(http, 'request').callsFake((options: any, cb: any) => { - queueMicrotask(() => { - const mockRes = new MockedResponse(400); - cb(mockRes); - mockRes.send(Buffer.from('failure')); - }); - - return fakeRequest as any; - }); - - collectorExporter.export(logs, result => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - // @ts-expect-error verify error code - assert.strictEqual(result.error.code, 400); - done(); - }); + loggerProvider.getLogger('test-logger').emit({ body: 'test-body' }); + loggerProvider.shutdown(); }); }); }); diff --git a/experimental/packages/exporter-trace-otlp-http/test/browser/CollectorTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-http/test/browser/CollectorTraceExporter.test.ts deleted file mode 100644 index 1de1e9485b..0000000000 --- a/experimental/packages/exporter-trace-otlp-http/test/browser/CollectorTraceExporter.test.ts +++ /dev/null @@ -1,560 +0,0 @@ -/* - * 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. - */ - -import * as core from '@opentelemetry/core'; -import { diag, DiagLogger, DiagLogLevel } from '@opentelemetry/api'; -import { ExportResultCode } from '@opentelemetry/core'; -import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import * as assert from 'assert'; -import * as sinon from 'sinon'; -import { OTLPTraceExporter } from '../../src/platform/browser/index'; -import { - ensureSpanIsCorrect, - ensureExportTraceServiceRequestIsSet, - ensureWebResourceIsCorrect, - ensureHeadersContain, - mockedReadableSpan, -} from '../traceHelper'; -import { - OTLPExporterConfigBase, - OTLPExporterError, -} from '@opentelemetry/otlp-exporter-base'; -import { IExportTraceServiceRequest } from '@opentelemetry/otlp-transformer'; - -describe('OTLPTraceExporter - web', () => { - let collectorTraceExporter: OTLPTraceExporter; - let collectorExporterConfig: OTLPExporterConfigBase; - let stubOpen: sinon.SinonStub; - let stubBeacon: sinon.SinonStub; - let spans: ReadableSpan[]; - - beforeEach(() => { - stubOpen = sinon.stub(XMLHttpRequest.prototype, 'open'); - sinon.stub(XMLHttpRequest.prototype, 'send'); - stubBeacon = sinon.stub(navigator, 'sendBeacon'); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - }); - - afterEach(() => { - sinon.restore(); - }); - - describe('constructor', () => { - beforeEach(() => { - collectorExporterConfig = { - url: 'http://foo.bar.com', - }; - collectorTraceExporter = new OTLPTraceExporter(collectorExporterConfig); - }); - - it('should create an instance', () => { - assert.ok(typeof collectorTraceExporter !== 'undefined'); - }); - }); - - describe('export', () => { - beforeEach(() => { - collectorExporterConfig = { - url: 'http://foo.bar.com', - }; - }); - - describe('when "sendBeacon" is available', () => { - beforeEach(() => { - collectorTraceExporter = new OTLPTraceExporter(collectorExporterConfig); - }); - - it('should successfully send the spans using sendBeacon', done => { - collectorTraceExporter.export(spans, () => {}); - - setTimeout(async () => { - try { - const args = stubBeacon.args[0]; - const url = args[0]; - const blob: Blob = args[1]; - const body = await blob.text(); - const json = JSON.parse(body) as IExportTraceServiceRequest; - const span1 = json.resourceSpans?.[0].scopeSpans?.[0].spans?.[0]; - - assert.ok(typeof span1 !== 'undefined', "span doesn't exist"); - ensureSpanIsCorrect(span1); - - const resource = json.resourceSpans?.[0].resource; - assert.ok( - typeof resource !== 'undefined', - "resource doesn't exist" - ); - ensureWebResourceIsCorrect(resource); - - assert.strictEqual(url, 'http://foo.bar.com'); - assert.strictEqual(stubBeacon.callCount, 1); - - assert.strictEqual(stubOpen.callCount, 0); - - ensureExportTraceServiceRequestIsSet(json); - done(); - } catch (err) { - done(err); - } - }); - }); - - it('should log the successful message', done => { - const spyLoggerDebug = sinon.stub(); - const spyLoggerError = sinon.stub(); - const nop = () => {}; - const diagLogger: DiagLogger = { - debug: spyLoggerDebug, - error: spyLoggerError, - info: nop, - verbose: nop, - warn: nop, - }; - - diag.setLogger(diagLogger, DiagLogLevel.ALL); - - stubBeacon.returns(true); - - collectorTraceExporter.export(spans, () => {}); - - queueMicrotask(() => { - try { - sinon.assert.calledWith(spyLoggerDebug, 'SendBeacon success'); - sinon.assert.notCalled(spyLoggerError); - - done(); - } catch (e) { - done(e); - } - }); - }); - - it('should log the error message', done => { - stubBeacon.returns(false); - - collectorTraceExporter.export(spans, result => { - try { - assert.deepStrictEqual(result.code, ExportResultCode.FAILED); - assert.ok( - result.error, - 'Expected Error, but no Error was present on the result' - ); - assert.match(result.error?.message, /SendBeacon failed/); - done(); - } catch (e) { - done(e); - } - }); - }); - }); - - describe('when "sendBeacon" is NOT available', () => { - let server: any; - let clock: sinon.SinonFakeTimers; - beforeEach(() => { - // fakeTimers is used to replace the next setTimeout which is - // located in sendWithXhr function called by the export method - clock = sinon.useFakeTimers(); - - (window.navigator as any).sendBeacon = false; - server = sinon.fakeServer.create(); - collectorTraceExporter = new OTLPTraceExporter(collectorExporterConfig); - }); - afterEach(() => { - server.restore(); - }); - - it('should successfully send the spans using XMLHttpRequest', done => { - collectorTraceExporter.export(spans, () => {}); - - queueMicrotask(async () => { - try { - const request = server.requests[0]; - assert.strictEqual(request.method, 'POST'); - assert.strictEqual(request.url, 'http://foo.bar.com'); - - const body = request.requestBody as Uint8Array; - const json = JSON.parse( - new TextDecoder().decode(body) - ) as IExportTraceServiceRequest; - const span1 = json.resourceSpans?.[0].scopeSpans?.[0].spans?.[0]; - - assert.ok(typeof span1 !== 'undefined', "span doesn't exist"); - ensureSpanIsCorrect(span1); - - const resource = json.resourceSpans?.[0].resource; - assert.ok( - typeof resource !== 'undefined', - "resource doesn't exist" - ); - ensureWebResourceIsCorrect(resource); - - assert.strictEqual(stubBeacon.callCount, 0); - ensureExportTraceServiceRequestIsSet(json); - - clock.restore(); - done(); - } catch (e) { - done(e); - } - }); - }); - - it('should log the successful message', done => { - const spyLoggerDebug = sinon.stub(); - const spyLoggerError = sinon.stub(); - const nop = () => {}; - const diagLogger: DiagLogger = { - debug: spyLoggerDebug, - error: spyLoggerError, - info: nop, - verbose: nop, - warn: nop, - }; - - diag.setLogger(diagLogger, DiagLogLevel.ALL); - - collectorTraceExporter.export(spans, () => {}); - - queueMicrotask(() => { - const request = server.requests[0]; - request.respond(200); - try { - const response: any = spyLoggerDebug.args[2][0]; - assert.strictEqual(response, 'XHR success'); - assert.strictEqual(spyLoggerError.args.length, 0); - assert.strictEqual(stubBeacon.callCount, 0); - clock.restore(); - done(); - } catch (e) { - done(e); - } - }); - }); - - it('should log the error message', done => { - collectorTraceExporter.export(spans, result => { - try { - assert.deepStrictEqual(result.code, ExportResultCode.FAILED); - assert.deepStrictEqual( - result.error?.message, - 'XHR request failed with non-retryable status' - ); - } catch (e) { - done(e); - } - done(); - }); - - queueMicrotask(() => { - const request = server.requests[0]; - request.respond(400); - }); - }); - - it('should send custom headers', done => { - collectorTraceExporter.export(spans, () => {}); - - queueMicrotask(() => { - const request = server.requests[0]; - request.respond(200); - - assert.strictEqual(stubBeacon.callCount, 0); - clock.restore(); - done(); - }); - }); - }); - }); - - describe('export with custom headers', () => { - let server: any; - const customHeaders = { - foo: 'bar', - bar: 'baz', - }; - - beforeEach(() => { - collectorExporterConfig = { - headers: customHeaders, - }; - server = sinon.fakeServer.create(); - }); - - afterEach(() => { - server.restore(); - }); - - describe('when "sendBeacon" is available', () => { - let clock: sinon.SinonFakeTimers; - beforeEach(() => { - // fakeTimers is used to replace the next setTimeout which is - // located in sendWithXhr function called by the export method - clock = sinon.useFakeTimers(); - - collectorTraceExporter = new OTLPTraceExporter(collectorExporterConfig); - }); - it('should successfully send custom headers using XMLHTTPRequest', done => { - collectorTraceExporter.export(spans, () => {}); - - queueMicrotask(() => { - const [{ requestHeaders }] = server.requests; - - ensureHeadersContain(requestHeaders, customHeaders); - assert.strictEqual(stubBeacon.callCount, 0); - assert.strictEqual(stubOpen.callCount, 0); - - clock.restore(); - done(); - }); - }); - }); - - describe('when "sendBeacon" is NOT available', () => { - let clock: sinon.SinonFakeTimers; - beforeEach(() => { - // fakeTimers is used to replace the next setTimeout which is - // located in sendWithXhr function called by the export method - clock = sinon.useFakeTimers(); - - (window.navigator as any).sendBeacon = false; - collectorTraceExporter = new OTLPTraceExporter(collectorExporterConfig); - }); - - it('should successfully send spans using XMLHttpRequest', done => { - collectorTraceExporter.export(spans, () => {}); - - queueMicrotask(() => { - try { - const [{ requestHeaders: requestHeaders }] = server.requests; - - ensureHeadersContain(requestHeaders, customHeaders); - assert.strictEqual(stubBeacon.callCount, 0); - assert.strictEqual(stubOpen.callCount, 0); - done(); - } catch (e) { - done(e); - } finally { - clock.restore(); - } - }); - }); - it('should log the timeout request error message', done => { - const responseSpy = sinon.spy(); - collectorTraceExporter.export(spans, responseSpy); - clock.tick(20000); - clock.restore(); - - setTimeout(() => { - try { - const result = responseSpy.args[0][0] as core.ExportResult; - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'XHR request timed out'); - done(); - } catch (e) { - done(e); - } - }); - }); - }); - }); - - describe('export - concurrency limit', () => { - it('should error if too many concurrent exports are queued', done => { - const collectorExporterWithConcurrencyLimit = new OTLPTraceExporter({ - ...collectorExporterConfig, - concurrencyLimit: 3, - }); - const spans: ReadableSpan[] = [{ ...mockedReadableSpan }]; - const callbackSpy = sinon.spy(); - for (let i = 0; i < 7; i++) { - collectorExporterWithConcurrencyLimit.export(spans, callbackSpy); - } - - const failures = callbackSpy.args.filter( - ([result]) => result.code === ExportResultCode.FAILED - ); - - setTimeout(() => { - // Expect 4 failures - try { - assert.strictEqual(failures.length, 4); - failures.forEach(([result]) => { - assert.strictEqual(result.code, ExportResultCode.FAILED); - assert.strictEqual( - result.error!.message, - 'Concurrent export limit reached' - ); - }); - done(); - } catch (e) { - done(e); - } - }); - }); - }); -}); - -describe('export with retry - real http request destroyed', () => { - let server: any; - let collectorTraceExporter: OTLPTraceExporter; - let collectorExporterConfig: OTLPExporterConfigBase; - let spans: ReadableSpan[]; - - beforeEach(() => { - server = sinon.fakeServer.create({ - autoRespond: true, - }); - collectorExporterConfig = { - timeoutMillis: 1500, - }; - }); - - afterEach(() => { - server.restore(); - }); - - describe('when "sendBeacon" is NOT available', () => { - beforeEach(() => { - (window.navigator as any).sendBeacon = false; - collectorTraceExporter = new OTLPTraceExporter(collectorExporterConfig); - }); - it('should log the retryable request error message when retrying with exponential backoff with jitter', done => { - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - let calls = 0; - server.respondWith( - 'http://localhost:4318/v1/traces', - function (xhr: any) { - calls++; - xhr.respond(503); - } - ); - - collectorTraceExporter.export(spans, result => { - try { - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual( - error.message, - 'Export failed with retryable status' - ); - assert.strictEqual(calls, 2); - done(); - } catch (e) { - done(e); - } - }); - }).timeout(3000); - - it('should log the timeout request error message when retry-after header is set to 3 seconds', done => { - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - let calls = 0; - server.respondWith( - 'http://localhost:4318/v1/traces', - function (xhr: any) { - calls++; - xhr.respond(503, { 'Retry-After': 0.1 }); - } - ); - - collectorTraceExporter.export(spans, result => { - try { - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual( - error.message, - 'Export failed with retryable status' - ); - assert.strictEqual(calls, 6); - done(); - } catch (e) { - done(e); - } - }); - }).timeout(3000); - it('should log the timeout request error message when retry-after header is a date', done => { - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - let retry = 0; - server.respondWith( - 'http://localhost:4318/v1/traces', - function (xhr: any) { - retry++; - const d = new Date(); - d.setSeconds(d.getSeconds() + 0.1); - xhr.respond(503, { 'Retry-After': d }); - } - ); - - collectorTraceExporter.export(spans, result => { - try { - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual( - error.message, - 'Export failed with retryable status' - ); - assert.strictEqual(retry, 6); - done(); - } catch (e) { - done(e); - } - }); - }).timeout(3000); - it('should log the timeout request error message when retry-after header is a date with long delay', done => { - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - let retry = 0; - server.respondWith( - 'http://localhost:4318/v1/traces', - function (xhr: any) { - retry++; - const d = new Date(); - d.setSeconds(d.getSeconds() + 120); - xhr.respond(503, { 'Retry-After': d }); - } - ); - - collectorTraceExporter.export(spans, result => { - try { - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual( - error.message, - 'Export failed with retryable status' - ); - assert.strictEqual(retry, 1); - done(); - } catch (e) { - done(e); - } - }); - }).timeout(3000); - }); -}); diff --git a/experimental/packages/exporter-trace-otlp-http/test/browser/OTLPTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-http/test/browser/OTLPTraceExporter.test.ts new file mode 100644 index 0000000000..a5ef3ad002 --- /dev/null +++ b/experimental/packages/exporter-trace-otlp-http/test/browser/OTLPTraceExporter.test.ts @@ -0,0 +1,93 @@ +/* + * 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. + */ + +import { + BasicTracerProvider, + SimpleSpanProcessor, +} from '@opentelemetry/sdk-trace-base'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import { OTLPTraceExporter } from '../../src/platform/browser/index'; + +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...) + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + * - `@opentelemetry/otlp-grpc-exporter-base`: gRPC transport + */ + +describe('OTLPTraceExporter', () => { + afterEach(() => { + sinon.restore(); + }); + + describe('export', function () { + describe('when sendBeacon is available', function () { + it('should successfully send data using sendBeacon', async function () { + // arrange + const stubBeacon = sinon.stub(navigator, 'sendBeacon'); + const tracerProvider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())], + }); + + // act + tracerProvider.getTracer('test-tracer').startSpan('test-span').end(); + await tracerProvider.shutdown(); + + // assert + const args = stubBeacon.args[0]; + const blob: Blob = args[1] as unknown as Blob; + const body = await blob.text(); + assert.doesNotThrow( + () => JSON.parse(body), + 'expected requestBody to be in JSON format, but parsing failed' + ); + }); + }); + + describe('when sendBeacon is not available', function () { + beforeEach(function () { + // fake sendBeacon not being available + (window.navigator as any).sendBeacon = false; + }); + + it('should successfully send data using XMLHttpRequest', async function () { + // arrange + const server = sinon.fakeServer.create(); + const tracerProvider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())], + }); + + // act + tracerProvider.getTracer('test-tracer').startSpan('test-span').end(); + queueMicrotask(() => { + // simulate success response + server.requests[0].respond(200, {}, ''); + }); + await tracerProvider.shutdown(); + + // assert + const request = server.requests[0]; + const body = request.requestBody as unknown as Uint8Array; + assert.doesNotThrow( + () => JSON.parse(new TextDecoder().decode(body)), + 'expected requestBody to be in JSON format, but parsing failed' + ); + }); + }); + }); +}); diff --git a/experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts deleted file mode 100644 index 38e1bf5c2b..0000000000 --- a/experimental/packages/exporter-trace-otlp-http/test/node/CollectorTraceExporter.test.ts +++ /dev/null @@ -1,442 +0,0 @@ -/* - * 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. - */ - -import * as assert from 'assert'; -import * as http from 'http'; -import * as sinon from 'sinon'; -import * as zlib from 'zlib'; -import { PassThrough, Stream } from 'stream'; - -import { diag } from '@opentelemetry/api'; -import { - CompressionAlgorithm, - OTLPExporterError, - OTLPExporterNodeConfigBase, -} from '@opentelemetry/otlp-exporter-base'; -import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import * as core from '@opentelemetry/core'; -import { IExportTraceServiceRequest } from '@opentelemetry/otlp-transformer'; - -import { MockedResponse } from './nodeHelpers'; -import { OTLPTraceExporter } from '../../src/platform/node'; -import { - ensureExportTraceServiceRequestIsSet, - ensureSpanIsCorrect, - mockedReadableSpan, -} from '../traceHelper'; - -let fakeRequest: PassThrough; - -const address = 'localhost:1501'; - -describe('OTLPTraceExporter - node with json over http', function () { - let collectorExporter: OTLPTraceExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let stubRequest: sinon.SinonStub; - let spySetHeader: sinon.SinonSpy; - let spans: ReadableSpan[]; - - afterEach(function () { - fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - sinon.restore(); - }); - - describe('instance', function () { - it('should warn about metadata when using json', () => { - const metadata = 'foo'; - const warnLoggerSpy = sinon.stub(diag, 'warn'); - - collectorExporter = new OTLPTraceExporter({ - metadata, - url: address, - } as any); - sinon.assert.calledOnce(warnLoggerSpy); - sinon.assert.calledOnceWithExactly( - warnLoggerSpy, - 'Metadata cannot be set when using http' - ); - }); - }); - - describe('export', () => { - beforeEach(() => { - stubRequest = sinon.stub(http, 'request').returns(fakeRequest as any); - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - httpAgentOptions: { keepAliveMsecs: 2000 }, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - }); - - it('should open the connection', done => { - collectorExporter.export(spans, () => {}); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - const options = args[0]; - - assert.strictEqual(options.hostname, 'foo.bar.com'); - assert.strictEqual(options.method, 'POST'); - assert.strictEqual(options.path, '/'); - done(); - }); - }); - - it('should set custom headers', done => { - collectorExporter.export(spans, () => {}); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - const options = args[0]; - assert.strictEqual(options.headers['foo'], 'bar'); - done(); - }); - }); - - it('should not have Content-Encoding header', done => { - collectorExporter.export(spans, () => {}); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - const options = args[0]; - assert.strictEqual(options.headers['Content-Encoding'], undefined); - done(); - }); - }); - - it('should have keep alive and keepAliveMsecs option set', done => { - collectorExporter.export(spans, () => {}); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - const options = args[0]; - const agent = options.agent; - assert.strictEqual(agent.keepAlive, true); - assert.strictEqual(agent.options.keepAliveMsecs, 2000); - done(); - }); - }); - - it('different http export requests should use the same agent', done => { - const clock = sinon.useFakeTimers(); - collectorExporter.export(spans, () => {}); - - const args = stubRequest.args[0]; - const callback = args[1]; - const mockRes = new MockedResponse(200); - - queueMicrotask(() => { - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - clock.restore(); - - queueMicrotask(() => { - const clock = sinon.useFakeTimers(); - collectorExporter.export(spans, () => {}); - - const mockRes2 = new MockedResponse(200); - const args2 = stubRequest.args[1]; - const callback2 = args2[1]; - - callback2(mockRes); - mockRes2.send(Buffer.from('success')); - - const [firstExportAgent, secondExportAgent] = stubRequest.args.map( - a => a[0].agent - ); - - assert.strictEqual(firstExportAgent, secondExportAgent); - clock.restore(); - done(); - }); - }); - - it('should successfully send the spans', done => { - let buff = Buffer.from(''); - - fakeRequest.on('finish', () => { - const responseBody = buff.toString(); - const json = JSON.parse(responseBody) as IExportTraceServiceRequest; - const span1 = json.resourceSpans?.[0].scopeSpans?.[0].spans?.[0]; - assert.ok(typeof span1 !== 'undefined', "span doesn't exist"); - ensureSpanIsCorrect(span1); - - ensureExportTraceServiceRequestIsSet(json); - - done(); - }); - - fakeRequest.on('data', chunk => { - buff = Buffer.concat([buff, chunk]); - }); - - collectorExporter.export(spans, () => {}); - - const mockRes = new MockedResponse(200); - const args = stubRequest.args[0]; - const callback = args[1]; - - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - it('should log the successful message', done => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - const stubLoggerError = sinon.stub(diag, 'error'); - const responseSpy = sinon.spy(); - collectorExporter.export(spans, responseSpy); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - setTimeout(() => { - assert.strictEqual(stubLoggerError.args.length, 0); - assert.strictEqual( - responseSpy.args[0][0].code, - core.ExportResultCode.SUCCESS - ); - done(); - }); - }); - }); - - it('should log the error message', done => { - const responseSpy = sinon.spy(); - collectorExporter.export(spans, responseSpy); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - - queueMicrotask(() => { - const mockRes = new MockedResponse(400); - callback(mockRes); - mockRes.send(Buffer.from('failure')); - }); - - setTimeout(() => { - const result = responseSpy.args[0][0] as core.ExportResult; - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.code, 400); - done(); - }); - }); - }); - }); - - describe('export - with compression', () => { - beforeEach(() => { - stubRequest = sinon.stub(http, 'request').returns(fakeRequest as any); - spySetHeader = sinon.spy(); - (fakeRequest as any).setHeader = spySetHeader; - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - compression: CompressionAlgorithm.GZIP, - httpAgentOptions: { keepAliveMsecs: 2000 }, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - }); - - it('should successfully send the spans', done => { - let buff = Buffer.from(''); - - fakeRequest.on('finish', () => { - const responseBody = zlib.gunzipSync(buff).toString(); - - const json = JSON.parse(responseBody) as IExportTraceServiceRequest; - const span1 = json.resourceSpans?.[0].scopeSpans?.[0].spans?.[0]; - assert.ok(typeof span1 !== 'undefined', "span doesn't exist"); - ensureSpanIsCorrect(span1); - - ensureExportTraceServiceRequestIsSet(json); - assert.ok(spySetHeader.calledWith('Content-Encoding', 'gzip')); - done(); - }); - - fakeRequest.on('data', chunk => { - buff = Buffer.concat([buff, chunk]); - }); - - collectorExporter.export(spans, () => {}); - - const mockRes = new MockedResponse(200); - const args = stubRequest.args[0]; - const callback = args[1]; - - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - }); - - describe('export - with timeout', () => { - beforeEach(() => { - fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - stubRequest = sinon.stub(http, 'request').returns(fakeRequest as any); - spySetHeader = sinon.spy(); - (fakeRequest as any).setHeader = spySetHeader; - (fakeRequest as any).abort = sinon.spy(); - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - httpAgentOptions: { keepAliveMsecs: 2000 }, - timeoutMillis: 100, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - }); - - it('should log the timeout request error message', done => { - const responseSpy = sinon.spy(); - collectorExporter.export(spans, responseSpy); - - setTimeout(() => { - fakeRequest.emit('error', { code: 'ECONNRESET' }); - - setTimeout(() => { - const result = responseSpy.args[0][0] as core.ExportResult; - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.deepEqual(error, { code: 'ECONNRESET' }); - - done(); - }); - }, 300); - }); - }); -}); - -describe('export - real http request destroyed before response received', () => { - let collectorExporter: OTLPTraceExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase; - let spans: ReadableSpan[]; - - const server = http.createServer((_, res) => { - setTimeout(() => { - res.statusCode = 200; - res.end(); - }, 200); - }); - before(done => { - server.listen(8081, done); - }); - after(done => { - server.close(done); - }); - it('should log the timeout request error message when timeout is 1', done => { - collectorExporterConfig = { - url: 'http://localhost:8081', - timeoutMillis: 1, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - setTimeout(() => { - collectorExporter.export(spans, result => { - try { - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'Request Timeout'); - } catch (e) { - done(e); - } - done(); - }); - }, 0); - }); - it('should log the timeout request error message when timeout is 100', done => { - collectorExporterConfig = { - url: 'http://localhost:8081', - timeoutMillis: 100, - }; - collectorExporter = new OTLPTraceExporter(collectorExporterConfig); - spans = []; - spans.push(Object.assign({}, mockedReadableSpan)); - - setTimeout(() => { - collectorExporter.export(spans, result => { - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.message, 'Request Timeout'); - done(); - }); - }, 0); - }); -}); diff --git a/experimental/packages/exporter-trace-otlp-http/test/node/OTLPTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-http/test/node/OTLPTraceExporter.test.ts new file mode 100644 index 0000000000..d4ee19ca85 --- /dev/null +++ b/experimental/packages/exporter-trace-otlp-http/test/node/OTLPTraceExporter.test.ts @@ -0,0 +1,73 @@ +/* + * 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. + */ + +import * as assert from 'assert'; +import * as http from 'http'; +import * as sinon from 'sinon'; +import { Stream } from 'stream'; + +import { + BasicTracerProvider, + SimpleSpanProcessor, +} from '@opentelemetry/sdk-trace-base'; +import { OTLPTraceExporter } from '../../src/platform/node'; + +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ + +describe('OTLPTraceExporter', () => { + describe('export', () => { + afterEach(() => { + sinon.restore(); + }); + + it('successfully exports data', done => { + const fakeRequest = new Stream.PassThrough(); + Object.defineProperty(fakeRequest, 'setTimeout', { + value: function (_timeout: number) {}, + }); + + sinon.stub(http, 'request').returns(fakeRequest as any); + let buff = Buffer.from(''); + fakeRequest.on('finish', () => { + try { + const requestBody = buff.toString(); + assert.doesNotThrow(() => { + JSON.parse(requestBody); + }, 'expected requestBody to be in JSON format, but parsing failed'); + done(); + } catch (e) { + done(e); + } + }); + + fakeRequest.on('data', chunk => { + buff = Buffer.concat([buff, chunk]); + }); + + new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())], + }) + .getTracer('test-tracer') + .startSpan('test-span') + .end(); + }); + }); +}); diff --git a/experimental/packages/exporter-trace-otlp-http/test/node/nodeHelpers.ts b/experimental/packages/exporter-trace-otlp-http/test/node/nodeHelpers.ts deleted file mode 100644 index e63d21b17c..0000000000 --- a/experimental/packages/exporter-trace-otlp-http/test/node/nodeHelpers.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -import { Stream } from 'stream'; - -export class MockedResponse extends Stream { - constructor( - private _code: number, - private _msg?: string - ) { - super(); - } - - send(data: Uint8Array) { - this.emit('data', data); - this.emit('end'); - } - - get statusCode() { - return this._code; - } - - get statusMessage() { - return this._msg; - } -} diff --git a/experimental/packages/exporter-trace-otlp-http/test/traceHelper.ts b/experimental/packages/exporter-trace-otlp-http/test/traceHelper.ts deleted file mode 100644 index e89062c924..0000000000 --- a/experimental/packages/exporter-trace-otlp-http/test/traceHelper.ts +++ /dev/null @@ -1,443 +0,0 @@ -/* - * 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. - */ - -import { SpanStatusCode, TraceFlags } from '@opentelemetry/api'; -import { - hexToBase64, - InstrumentationLibrary, - VERSION, -} from '@opentelemetry/core'; -import { Resource } from '@opentelemetry/resources'; -import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import * as assert from 'assert'; -import { - ESpanKind, - IEvent, - IExportTraceServiceRequest, - IKeyValue, - ILink, - IResource, - ISpan, -} from '@opentelemetry/otlp-transformer'; - -if (typeof Buffer === 'undefined') { - (window as any).Buffer = { - from: function (arr: []) { - return new Uint8Array(arr); - }, - }; -} - -const traceIdHex = '1f1008dc8e270e85c40a0d7c3939b278'; -const spanIdHex = '5e107261f64fa53e'; -const parentIdHex = '78a8915098864388'; - -export const mockedReadableSpan: ReadableSpan = { - name: 'documentFetch', - kind: 0, - spanContext: () => { - return { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '5e107261f64fa53e', - traceFlags: TraceFlags.SAMPLED, - }; - }, - parentSpanId: '78a8915098864388', - startTime: [1574120165, 429803070], - endTime: [1574120165, 438688070], - ended: true, - status: { code: SpanStatusCode.OK }, - attributes: { component: 'document-load' }, - links: [ - { - context: { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '78a8915098864388', - traceFlags: TraceFlags.SAMPLED, - }, - attributes: { component: 'document-load' }, - }, - ], - events: [ - { - name: 'fetchStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupEnd', - time: [1574120165, 429803070], - }, - { - name: 'connectStart', - time: [1574120165, 429803070], - }, - { - name: 'connectEnd', - time: [1574120165, 429803070], - }, - { - name: 'requestStart', - time: [1574120165, 435513070], - }, - { - name: 'responseStart', - time: [1574120165, 436923070], - }, - { - name: 'responseEnd', - time: [1574120165, 438688070], - }, - ], - duration: [0, 8885000], - resource: Resource.default().merge( - new Resource({ - service: 'ui', - version: 1, - cost: 112.12, - }) - ), - instrumentationLibrary: { name: 'default', version: '0.0.1' }, - droppedAttributesCount: 0, - droppedEventsCount: 0, - droppedLinksCount: 0, -}; - -export const mockedResources: Resource[] = [ - new Resource({ name: 'resource 1' }), - new Resource({ name: 'resource 2' }), -]; - -export const mockedInstrumentationLibraries: InstrumentationLibrary[] = [ - { - name: 'lib1', - version: '0.0.1', - }, - { - name: 'lib2', - version: '0.0.2', - }, -]; - -export const basicTrace: ReadableSpan[] = [ - { - name: 'span1', - kind: 0, - spanContext: () => { - return { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '5e107261f64fa53e', - traceFlags: TraceFlags.SAMPLED, - }; - }, - parentSpanId: '78a8915098864388', - startTime: [1574120165, 429803070], - endTime: [1574120165, 438688070], - ended: true, - status: { code: SpanStatusCode.OK }, - attributes: {}, - links: [], - events: [], - duration: [0, 8885000], - resource: mockedResources[0], - instrumentationLibrary: mockedInstrumentationLibraries[0], - droppedAttributesCount: 0, - droppedEventsCount: 0, - droppedLinksCount: 0, - }, - { - name: 'span2', - kind: 0, - spanContext: () => { - return { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: 'f64fa53e5e107261', - traceFlags: TraceFlags.SAMPLED, - }; - }, - parentSpanId: '78a8915098864388', - startTime: [1575120165, 439803070], - endTime: [1575120165, 448688070], - ended: true, - status: { code: SpanStatusCode.OK }, - attributes: {}, - links: [], - events: [], - duration: [0, 8775000], - resource: mockedResources[0], - instrumentationLibrary: mockedInstrumentationLibraries[0], - droppedAttributesCount: 0, - droppedEventsCount: 0, - droppedLinksCount: 0, - }, - { - name: 'span3', - kind: 0, - spanContext: () => { - return { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '07261f64fa53e5e1', - traceFlags: TraceFlags.SAMPLED, - }; - }, - parentSpanId: 'a891578098864388', - startTime: [1575120165, 439803070], - endTime: [1575120165, 448688070], - ended: true, - status: { code: SpanStatusCode.OK }, - attributes: {}, - links: [], - events: [], - duration: [0, 8775000], - resource: mockedResources[0], - instrumentationLibrary: mockedInstrumentationLibraries[0], - droppedAttributesCount: 0, - droppedEventsCount: 0, - droppedLinksCount: 0, - }, -]; - -export const multiResourceTrace: ReadableSpan[] = [ - { - ...basicTrace[0], - resource: mockedResources[0], - }, - { - ...basicTrace[1], - resource: mockedResources[1], - }, - { - ...basicTrace[2], - resource: mockedResources[1], - }, -]; - -export const multiInstrumentationLibraryTrace: ReadableSpan[] = [ - { - ...basicTrace[0], - instrumentationLibrary: mockedInstrumentationLibraries[0], - }, - { - ...basicTrace[1], - instrumentationLibrary: mockedInstrumentationLibraries[0], - }, - { - ...basicTrace[2], - instrumentationLibrary: mockedInstrumentationLibraries[1], - }, -]; - -export function ensureEventsAreCorrect(events: IEvent[]) { - assert.deepStrictEqual( - events, - [ - { - timeUnixNano: '1574120165429803070', - name: 'fetchStart', - attributes: [], - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'domainLookupStart', - attributes: [], - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'domainLookupEnd', - attributes: [], - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'connectStart', - attributes: [], - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165429803070', - name: 'connectEnd', - attributes: [], - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165435513070', - name: 'requestStart', - attributes: [], - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165436923070', - name: 'responseStart', - attributes: [], - droppedAttributesCount: 0, - }, - { - timeUnixNano: '1574120165438688070', - name: 'responseEnd', - attributes: [], - droppedAttributesCount: 0, - }, - ], - 'events are incorrect' - ); -} - -export function ensureAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'component', - value: { - stringValue: 'document-load', - }, - }, - ], - 'attributes are incorrect' - ); -} - -export function ensureLinksAreCorrect(attributes: ILink[], useHex?: boolean) { - assert.deepStrictEqual( - attributes, - [ - { - traceId: useHex ? traceIdHex : hexToBase64(traceIdHex), - spanId: useHex ? parentIdHex : hexToBase64(parentIdHex), - attributes: [ - { - key: 'component', - value: { - stringValue: 'document-load', - }, - }, - ], - droppedAttributesCount: 0, - }, - ], - 'links are incorrect' - ); -} - -export function ensureSpanIsCorrect(span: ISpan, useHex = true) { - if (span.attributes) { - ensureAttributesAreCorrect(span.attributes); - } - if (span.events) { - ensureEventsAreCorrect(span.events); - } - if (span.links) { - ensureLinksAreCorrect(span.links, useHex); - } - assert.deepStrictEqual( - span.traceId, - useHex ? traceIdHex : hexToBase64(traceIdHex), - 'traceId is' + ' wrong' - ); - assert.deepStrictEqual( - span.spanId, - useHex ? spanIdHex : hexToBase64(spanIdHex), - 'spanId is' + ' wrong' - ); - assert.deepStrictEqual( - span.parentSpanId, - useHex ? parentIdHex : hexToBase64(parentIdHex), - 'parentIdArr is wrong' - ); - assert.strictEqual(span.name, 'documentFetch', 'name is wrong'); - assert.strictEqual(span.kind, ESpanKind.SPAN_KIND_INTERNAL, 'kind is wrong'); - assert.deepStrictEqual( - span.startTimeUnixNano, - '1574120165429803070', - 'startTimeUnixNano is wrong' - ); - assert.deepStrictEqual( - span.endTimeUnixNano, - '1574120165438688070', - 'endTimeUnixNano is wrong' - ); - assert.strictEqual( - span.droppedAttributesCount, - 0, - 'droppedAttributesCount is wrong' - ); - assert.strictEqual(span.droppedEventsCount, 0, 'droppedEventsCount is wrong'); - assert.strictEqual(span.droppedLinksCount, 0, 'droppedLinksCount is wrong'); - assert.deepStrictEqual( - span.status, - { code: SpanStatusCode.OK }, - 'status is wrong' - ); -} - -export function ensureWebResourceIsCorrect(resource: IResource) { - assert.strictEqual(resource.attributes.length, 7); - assert.strictEqual(resource.attributes[0].key, 'service.name'); - assert.strictEqual( - resource.attributes[0].value.stringValue, - 'unknown_service' - ); - assert.strictEqual(resource.attributes[1].key, 'telemetry.sdk.language'); - assert.strictEqual(resource.attributes[1].value.stringValue, 'webjs'); - assert.strictEqual(resource.attributes[2].key, 'telemetry.sdk.name'); - assert.strictEqual(resource.attributes[2].value.stringValue, 'opentelemetry'); - assert.strictEqual(resource.attributes[3].key, 'telemetry.sdk.version'); - assert.strictEqual(resource.attributes[3].value.stringValue, VERSION); - assert.strictEqual(resource.attributes[4].key, 'service'); - assert.strictEqual(resource.attributes[4].value.stringValue, 'ui'); - assert.strictEqual(resource.attributes[5].key, 'version'); - assert.strictEqual(resource.attributes[5].value.intValue, 1); - assert.strictEqual(resource.attributes[6].key, 'cost'); - assert.strictEqual(resource.attributes[6].value.doubleValue, 112.12); - assert.strictEqual(resource.droppedAttributesCount, 0); -} - -export function ensureExportTraceServiceRequestIsSet( - json: IExportTraceServiceRequest -) { - const resourceSpans = json.resourceSpans; - assert.strictEqual(resourceSpans?.length, 1, 'resourceSpans is missing'); - - const resource = resourceSpans?.[0].resource; - assert.ok(resource, 'resource is missing'); - - const scopeSpans = resourceSpans?.[0].scopeSpans; - assert.strictEqual(scopeSpans?.length, 1, 'scopeSpans is missing'); - - const scope = scopeSpans?.[0].scope; - assert.ok(scope, 'scope is missing'); - - const spans = scopeSpans?.[0].spans; - assert.strictEqual(spans?.length, 1, 'spans are missing'); -} - -export function ensureHeadersContain( - actual: { [key: string]: string }, - expected: { [key: string]: string } -) { - Object.entries(expected).forEach(([k, v]) => { - assert.strictEqual( - v, - actual[k], - `Expected ${actual} to contain ${k}: ${v}` - ); - }); -} diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts deleted file mode 100644 index 55dd0a8049..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts +++ /dev/null @@ -1,435 +0,0 @@ -/* - * 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. - */ - -import { - diag, - DiagLogger, - DiagLogLevel, - Counter, - Histogram, -} from '@opentelemetry/api'; -import { ExportResultCode } from '@opentelemetry/core'; -import { ResourceMetrics } from '@opentelemetry/sdk-metrics'; -import * as assert from 'assert'; -import * as sinon from 'sinon'; -import { OTLPMetricExporter } from '../../src/platform/browser'; -import { - collect, - ensureCounterIsCorrect, - ensureExportMetricsServiceRequestIsSet, - ensureHeadersContain, - ensureHistogramIsCorrect, - ensureObservableGaugeIsCorrect, - ensureWebResourceIsCorrect, - HISTOGRAM_AGGREGATION_VIEW, - mockCounter, - mockHistogram, - mockObservableGauge, - setUp, - shutdown, -} from '../metricsHelper'; -import { - AggregationTemporalityPreference, - OTLPMetricExporterOptions, -} from '../../src'; -import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base'; -import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; - -describe('OTLPMetricExporter - web', () => { - let collectorExporter: OTLPMetricExporter; - let stubOpen: sinon.SinonStub; - let stubBeacon: sinon.SinonStub; - let metrics: ResourceMetrics; - let debugStub: sinon.SinonStub; - let errorStub: sinon.SinonStub; - - beforeEach(async () => { - setUp([HISTOGRAM_AGGREGATION_VIEW]); - stubOpen = sinon.stub(XMLHttpRequest.prototype, 'open'); - sinon.stub(XMLHttpRequest.prototype, 'send'); - stubBeacon = sinon.stub(navigator, 'sendBeacon'); - - const counter: Counter = mockCounter(); - mockObservableGauge(observableResult => { - observableResult.observe(3, {}); - observableResult.observe(6, {}); - }, 'double-observable-gauge2'); - const histogram: Histogram = mockHistogram(); - - counter.add(1); - histogram.record(7); - histogram.record(14); - - const { resourceMetrics, errors } = await collect(); - assert.strictEqual(errors.length, 0); - metrics = resourceMetrics; - - // Need to stub/spy on the underlying logger as the "diag" instance is global - debugStub = sinon.stub(); - errorStub = sinon.stub(); - const nop = () => {}; - const diagLogger: DiagLogger = { - debug: debugStub, - error: errorStub, - info: nop, - verbose: nop, - warn: nop, - }; - diag.setLogger(diagLogger, DiagLogLevel.DEBUG); - }); - - afterEach(async () => { - await shutdown(); - sinon.restore(); - diag.disable(); - }); - - describe('export', () => { - describe('when "sendBeacon" is available', () => { - beforeEach(() => { - collectorExporter = new OTLPMetricExporter({ - url: 'http://foo.bar.com', - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }); - }); - - it('should successfully send metrics using sendBeacon', done => { - collectorExporter.export(metrics, () => {}); - - setTimeout(async () => { - const args = stubBeacon.args[0]; - const url = args[0]; - const blob: Blob = args[1]; - const body = await blob.text(); - const json = JSON.parse(body) as IExportMetricsServiceRequest; - - // The order of the metrics is not guaranteed. - const counterIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-counter' - ); - const observableIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'double-observable-gauge2' - ); - const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-histogram' - ); - - const metric1 = - json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; - const metric2 = - json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; - const metric3 = - json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; - - assert.ok(typeof metric1 !== 'undefined', "metric doesn't exist"); - - ensureCounterIsCorrect( - metric1, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].endTime, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0] - .startTime - ); - - assert.ok( - typeof metric2 !== 'undefined', - "second metric doesn't exist" - ); - ensureObservableGaugeIsCorrect( - metric2, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .startTime, - 6, - 'double-observable-gauge2' - ); - - assert.ok( - typeof metric3 !== 'undefined', - "third metric doesn't exist" - ); - ensureHistogramIsCorrect( - metric3, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .startTime, - [0, 100], - [0, 2, 0] - ); - - const resource = json.resourceMetrics[0].resource; - assert.ok(typeof resource !== 'undefined', "resource doesn't exist"); - ensureWebResourceIsCorrect(resource); - - assert.strictEqual(url, 'http://foo.bar.com'); - - assert.strictEqual(stubBeacon.callCount, 1); - assert.strictEqual(stubOpen.callCount, 0); - - ensureExportMetricsServiceRequestIsSet(json); - - done(); - }); - }); - - it('should log the successful message', done => { - stubBeacon.returns(true); - - collectorExporter.export(metrics, () => {}); - - queueMicrotask(() => { - sinon.assert.calledWith(debugStub, 'SendBeacon success'); - sinon.assert.notCalled(errorStub); - - done(); - }); - }); - - it('should log the error message', done => { - stubBeacon.returns(false); - - collectorExporter.export(metrics, result => { - try { - assert.deepStrictEqual(result.code, ExportResultCode.FAILED); - assert.ok( - result.error, - 'Expected Error, but no Error was present on the result' - ); - assert.match(result.error?.message, /SendBeacon failed/); - done(); - } catch (e) { - done(e); - } - }); - }); - }); - - describe('when "sendBeacon" is NOT available', () => { - let server: any; - beforeEach(() => { - (window.navigator as any).sendBeacon = false; - collectorExporter = new OTLPMetricExporter({ - url: 'http://foo.bar.com', - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }); - // Overwrites the start time to make tests consistent - Object.defineProperty(collectorExporter, '_startTime', { - value: 1592602232694000000, - }); - server = sinon.fakeServer.create(); - }); - afterEach(() => { - server.restore(); - }); - - it('should successfully send the metrics using XMLHttpRequest', done => { - collectorExporter.export(metrics, () => {}); - - queueMicrotask(async () => { - try { - const request = server.requests[0]; - assert.strictEqual(request.method, 'POST'); - assert.strictEqual(request.url, 'http://foo.bar.com'); - - const body = request.requestBody; - const json = JSON.parse( - new TextDecoder().decode(body) - ) as IExportMetricsServiceRequest; - // The order of the metrics is not guaranteed. - const counterIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-counter' - ); - const observableIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'double-observable-gauge2' - ); - const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-histogram' - ); - - const metric1 = - json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; - const metric2 = - json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; - const metric3 = - json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; - - assert.ok(typeof metric1 !== 'undefined', "metric doesn't exist"); - ensureCounterIsCorrect( - metric1, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0] - .startTime - ); - - assert.ok( - typeof metric2 !== 'undefined', - "second metric doesn't exist" - ); - ensureObservableGaugeIsCorrect( - metric2, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .startTime, - 6, - 'double-observable-gauge2' - ); - - assert.ok( - typeof metric3 !== 'undefined', - "third metric doesn't exist" - ); - ensureHistogramIsCorrect( - metric3, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .startTime, - [0, 100], - [0, 2, 0] - ); - - const resource = json.resourceMetrics[0].resource; - assert.ok( - typeof resource !== 'undefined', - "resource doesn't exist" - ); - ensureWebResourceIsCorrect(resource); - - assert.strictEqual(stubBeacon.callCount, 0); - ensureExportMetricsServiceRequestIsSet(json); - - done(); - } catch (e) { - done(e); - } - }); - }); - - it('should log the successful message', done => { - collectorExporter.export(metrics, () => {}); - - queueMicrotask(() => { - const request = server.requests[0]; - request.respond(200); - - const response: any = debugStub.args[2][0]; - assert.strictEqual(response, 'XHR success'); - assert.strictEqual(errorStub.args.length, 0); - - assert.strictEqual(stubBeacon.callCount, 0); - done(); - }); - }); - - it('should log the error message', done => { - collectorExporter.export(metrics, result => { - try { - assert.deepStrictEqual(result.code, ExportResultCode.FAILED); - assert.deepStrictEqual( - result.error?.message, - 'XHR request failed with non-retryable status' - ); - } catch (e) { - done(e); - } - done(); - }); - - queueMicrotask(() => { - const request = server.requests[0]; - request.respond(400); - }); - }); - it('should send custom headers', done => { - collectorExporter.export(metrics, () => {}); - - queueMicrotask(() => { - const request = server.requests[0]; - request.respond(200); - - assert.strictEqual(stubBeacon.callCount, 0); - done(); - }); - }); - }); - }); - - describe('export with custom headers', () => { - let server: any; - const customHeaders = { - foo: 'bar', - bar: 'baz', - }; - let collectorExporterConfig: - | (OTLPExporterConfigBase & OTLPMetricExporterOptions) - | undefined; - - beforeEach(() => { - collectorExporterConfig = { - headers: customHeaders, - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }; - server = sinon.fakeServer.create(); - }); - - afterEach(() => { - server.restore(); - }); - - describe('when "sendBeacon" is available', () => { - beforeEach(() => { - collectorExporter = new OTLPMetricExporter(collectorExporterConfig); - }); - it('should successfully send custom headers using XMLHTTPRequest', done => { - collectorExporter.export(metrics, () => {}); - - setTimeout(() => { - const [{ requestHeaders }] = server.requests; - - ensureHeadersContain(requestHeaders, customHeaders); - assert.strictEqual(stubBeacon.callCount, 0); - assert.strictEqual(stubOpen.callCount, 0); - - done(); - }); - }); - }); - - describe('when "sendBeacon" is NOT available', () => { - beforeEach(() => { - (window.navigator as any).sendBeacon = false; - collectorExporter = new OTLPMetricExporter(collectorExporterConfig); - }); - - it('should successfully send metrics using XMLHttpRequest', done => { - collectorExporter.export(metrics, () => {}); - - setTimeout(() => { - const [{ requestHeaders }] = server.requests; - - ensureHeadersContain(requestHeaders, customHeaders); - assert.strictEqual(stubBeacon.callCount, 0); - assert.strictEqual(stubOpen.callCount, 0); - - done(); - }); - }); - }); - }); -}); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/OTLPMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/OTLPMetricExporter.test.ts new file mode 100644 index 0000000000..cd6d80d8ea --- /dev/null +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/OTLPMetricExporter.test.ts @@ -0,0 +1,108 @@ +/* + * 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. + */ + +import { + MeterProvider, + PeriodicExportingMetricReader, +} from '@opentelemetry/sdk-metrics'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import { OTLPMetricExporter } from '../../src/platform/browser'; + +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ + +describe('OTLPMetricExporter', function () { + afterEach(() => { + sinon.restore(); + }); + + describe('export', function () { + describe('when sendBeacon is available', function () { + it('should successfully send data using sendBeacon', async function () { + // arrange + const stubBeacon = sinon.stub(navigator, 'sendBeacon'); + const meterProvider = new MeterProvider({ + readers: [ + new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter(), + }), + ], + }); + + // act + meterProvider + .getMeter('test-meter') + .createCounter('test-counter') + .add(1); + await meterProvider.forceFlush(); + await meterProvider.shutdown(); + + // assert + const args = stubBeacon.args[0]; + const blob: Blob = args[1] as unknown as Blob; + const body = await blob.text(); + assert.doesNotThrow( + () => JSON.parse(body), + 'expected requestBody to be in JSON format, but parsing failed' + ); + }); + }); + + describe('when sendBeacon is not available', function () { + beforeEach(function () { + // fake sendBeacon not being available + (window.navigator as any).sendBeacon = false; + }); + + it('should successfully send data using XMLHttpRequest', async function () { + // arrange + const server = sinon.fakeServer.create(); + server.respondWith('OK'); + server.respondImmediately = true; + server.autoRespond = true; + const meterProvider = new MeterProvider({ + readers: [ + new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter(), + }), + ], + }); + + // act + meterProvider + .getMeter('test-meter') + .createCounter('test-counter') + .add(1); + + await meterProvider.forceFlush(); + await meterProvider.shutdown(); + + // assert + const request = server.requests[0]; + const body = request.requestBody as unknown as Uint8Array; + assert.doesNotThrow( + () => JSON.parse(new TextDecoder().decode(body)), + 'expected requestBody to be in JSON format, but parsing failed' + ); + }); + }); + }); +}); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts deleted file mode 100644 index 850cdae4d0..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts +++ /dev/null @@ -1,341 +0,0 @@ -/* - * 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. - */ - -import { - Counter, - ObservableResult, - Histogram, - ValueType, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - HrTime, -} from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; -import * as assert from 'assert'; -import { InstrumentationScope, VERSION } from '@opentelemetry/core'; -import { - ExplicitBucketHistogramAggregation, - MeterProvider, - MetricReader, - View, -} from '@opentelemetry/sdk-metrics'; -import { - encodeAsString, - IExportMetricsServiceRequest, - IKeyValue, - IMetric, - IResource, -} from '@opentelemetry/otlp-transformer'; - -if (typeof Buffer === 'undefined') { - (window as any).Buffer = { - from: function (arr: []) { - return new Uint8Array(arr); - }, - }; -} - -class TestMetricReader extends MetricReader { - protected onForceFlush(): Promise { - return Promise.resolve(undefined); - } - - protected onShutdown(): Promise { - return Promise.resolve(undefined); - } -} - -export const HISTOGRAM_AGGREGATION_VIEW = new View({ - aggregation: new ExplicitBucketHistogramAggregation([0, 100]), - instrumentName: 'int-histogram', -}); - -const defaultResource = Resource.default().merge( - new Resource({ - service: 'ui', - version: 1, - cost: 112.12, - }) -); - -let reader = new TestMetricReader(); -let meterProvider = new MeterProvider({ - resource: defaultResource, - readers: [reader], -}); -let meter = meterProvider.getMeter('default', '0.0.1'); - -export async function collect() { - return (await reader.collect())!; -} - -export function setUp(views?: View[]) { - reader = new TestMetricReader(); - meterProvider = new MeterProvider({ - resource: defaultResource, - views, - readers: [reader], - }); - meter = meterProvider.getMeter('default', '0.0.1'); -} - -export async function shutdown() { - await meterProvider.shutdown(); -} - -export function mockCounter(): Counter { - const name = 'int-counter'; - return meter.createCounter(name, { - description: 'sample counter description', - valueType: ValueType.INT, - }); -} - -export function mockObservableGauge( - callback: (observableResult: ObservableResult) => void, - name = 'double-observable-gauge' -): ObservableGauge { - const observableGauge = meter.createObservableGauge(name, { - description: 'sample observable gauge description', - valueType: ValueType.DOUBLE, - }); - observableGauge.addCallback(callback); - - return observableGauge; -} - -export function mockDoubleCounter(): Counter { - const name = 'double-counter'; - return meter.createCounter(name, { - description: 'sample counter description', - valueType: ValueType.DOUBLE, - }); -} - -export function mockObservableCounter( - callback: (observableResult: ObservableResult) => void, - name = 'double-observable-counter' -): ObservableCounter { - const observableCounter = meter.createObservableCounter(name, { - description: 'sample observable counter description', - valueType: ValueType.DOUBLE, - }); - observableCounter.addCallback(callback); - - return observableCounter; -} - -export function mockObservableUpDownCounter( - callback: (observableResult: ObservableResult) => void, - name = 'double-up-down-observable-counter' -): ObservableUpDownCounter { - const observableUpDownCounter = meter.createObservableUpDownCounter(name, { - description: 'sample observable up down counter description', - valueType: ValueType.DOUBLE, - }); - observableUpDownCounter.addCallback(callback); - - return observableUpDownCounter; -} - -export function mockHistogram(): Histogram { - return meter.createHistogram('int-histogram', { - description: 'sample histogram description', - valueType: ValueType.INT, - }); -} - -export const mockedResources: Resource[] = [ - new Resource({ name: 'resource 1' }), - new Resource({ name: 'resource 2' }), -]; - -export const mockedInstrumentationLibraries: InstrumentationScope[] = [ - { - name: 'lib1', - version: '0.0.1', - }, - { - name: 'lib2', - version: '0.0.2', - }, -]; - -export function ensureAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'component', - value: { - stringValue: 'document-load', - }, - }, - ], - 'attributes are incorrect' - ); -} - -export function ensureWebResourceIsCorrect(resource: IResource) { - assert.strictEqual(resource.attributes.length, 7); - assert.strictEqual(resource.attributes[0].key, 'service.name'); - assert.strictEqual( - resource.attributes[0].value.stringValue, - 'unknown_service' - ); - assert.strictEqual(resource.attributes[1].key, 'telemetry.sdk.language'); - assert.strictEqual(resource.attributes[1].value.stringValue, 'webjs'); - assert.strictEqual(resource.attributes[2].key, 'telemetry.sdk.name'); - assert.strictEqual(resource.attributes[2].value.stringValue, 'opentelemetry'); - assert.strictEqual(resource.attributes[3].key, 'telemetry.sdk.version'); - assert.strictEqual(resource.attributes[3].value.stringValue, VERSION); - assert.strictEqual(resource.attributes[4].key, 'service'); - assert.strictEqual(resource.attributes[4].value.stringValue, 'ui'); - assert.strictEqual(resource.attributes[5].key, 'version'); - assert.strictEqual(resource.attributes[5].value.intValue, 1); - assert.strictEqual(resource.attributes[6].key, 'cost'); - assert.strictEqual(resource.attributes[6].value.doubleValue, 112.12); - assert.strictEqual(resource.droppedAttributesCount, 0); -} - -export function ensureCounterIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime -) { - assert.strictEqual(metric.name, 'int-counter'); - assert.strictEqual(metric.description, 'sample counter description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.sum?.dataPoints.length, 1); - assert.strictEqual(metric.sum?.isMonotonic, true); - assert.strictEqual(metric.sum?.aggregationTemporality, 2); - - const [dp] = metric.sum.dataPoints; - - assert.deepStrictEqual(dp.attributes, []); - assert.strictEqual(dp.asInt, 1); - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); -} - -export function ensureDoubleCounterIsCorrect( - metric: IMetric, - time: number, - endTime: number -) { - assert.deepStrictEqual(metric, { - name: 'double-counter', - description: 'sample counter description', - unit: '', - doubleSum: { - dataPoints: [ - { - labels: [], - value: 8, - startTimeUnixNano: endTime, - timeUnixNano: time, - }, - ], - isMonotonic: true, - aggregationTemporality: 2, - }, - }); -} - -export function ensureObservableGaugeIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime, - value: number, - name = 'double-observable-gauge' -) { - assert.strictEqual(metric.name, name); - assert.strictEqual(metric.description, 'sample observable gauge description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.gauge?.dataPoints.length, 1); - - const [dp] = metric.gauge.dataPoints; - - assert.deepStrictEqual(dp.attributes, []); - assert.strictEqual(dp.asDouble, value); - - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); -} - -export function ensureHistogramIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime, - explicitBounds: (number | null)[] = [Infinity], - bucketCounts: number[] = [2, 0] -) { - assert.strictEqual(metric.name, 'int-histogram'); - assert.strictEqual(metric.description, 'sample histogram description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.histogram?.dataPoints.length, 1); - assert.strictEqual(metric.histogram?.aggregationTemporality, 2); - - const [dp] = metric.histogram.dataPoints; - - assert.deepStrictEqual(dp.attributes, []); - assert.strictEqual(dp.sum, 21); - assert.strictEqual(dp.count, 2); - assert.strictEqual(dp.min, 7); - assert.strictEqual(dp.max, 14); - assert.deepStrictEqual(dp.bucketCounts, bucketCounts); - assert.deepStrictEqual(dp.explicitBounds, explicitBounds); - - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); -} - -export function ensureExportMetricsServiceRequestIsSet( - json: IExportMetricsServiceRequest -) { - const resourceMetrics = json.resourceMetrics; - assert.strictEqual( - resourceMetrics.length, - 1, - 'resourceMetrics has incorrect length' - ); - - const resource = resourceMetrics[0].resource; - assert.ok(resource, 'resource is missing'); - - const scopeMetrics = resourceMetrics[0].scopeMetrics; - assert.strictEqual(scopeMetrics?.length, 1, 'scopeMetrics is missing'); - - const scope = scopeMetrics[0].scope; - assert.ok(scope, 'scope is missing'); - - const metrics = resourceMetrics[0].scopeMetrics[0].metrics; - assert.strictEqual(metrics.length, 3, 'Metrics are missing'); -} - -export function ensureHeadersContain( - actual: { [key: string]: string }, - expected: { [key: string]: string } -) { - Object.entries(expected).forEach(([k, v]) => { - assert.strictEqual( - v, - actual[k], - `Expected ${actual} to contain ${k}: ${v}` - ); - }); -} diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts deleted file mode 100644 index 4b11c946cc..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts +++ /dev/null @@ -1,462 +0,0 @@ -/* - * 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. - */ - -import { diag, DiagLogger } from '@opentelemetry/api'; -import * as core from '@opentelemetry/core'; -import * as assert from 'assert'; -import * as http from 'http'; -import * as sinon from 'sinon'; -import { - AggregationTemporalityPreference, - OTLPMetricExporterOptions, -} from '../../src'; - -import { OTLPMetricExporter } from '../../src/platform/node'; -import { - collect, - ensureCounterIsCorrect, - ensureExportMetricsServiceRequestIsSet, - ensureHistogramIsCorrect, - ensureObservableGaugeIsCorrect, - HISTOGRAM_AGGREGATION_VIEW, - mockCounter, - mockHistogram, - mockObservableGauge, - setUp, - shutdown, -} from '../metricsHelper'; -import { MockedResponse } from './nodeHelpers'; -import { - Aggregation, - AggregationTemporality, - ExplicitBucketHistogramAggregation, - InstrumentType, - ResourceMetrics, -} from '@opentelemetry/sdk-metrics'; -import { PassThrough, Stream } from 'stream'; -import { - OTLPExporterError, - OTLPExporterNodeConfigBase, -} from '@opentelemetry/otlp-exporter-base'; -import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; - -let fakeRequest: PassThrough; - -const address = 'localhost:1501'; - -describe('OTLPMetricExporter - node with json over http', () => { - let collectorExporter: OTLPMetricExporter; - let collectorExporterConfig: OTLPExporterNodeConfigBase & - OTLPMetricExporterOptions; - let stubRequest: sinon.SinonStub; - let metrics: ResourceMetrics; - - beforeEach(async () => { - setUp([HISTOGRAM_AGGREGATION_VIEW]); - }); - - afterEach(async () => { - fakeRequest = new Stream.PassThrough(); - Object.defineProperty(fakeRequest, 'setTimeout', { - value: function (_timeout: number) {}, - }); - await shutdown(); - sinon.restore(); - }); - - describe('instance', () => { - let warnStub: sinon.SinonStub; - - beforeEach(() => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - warnStub = sinon.stub(); - const nop = () => {}; - const diagLogger: DiagLogger = { - debug: nop, - error: nop, - info: nop, - verbose: nop, - warn: warnStub, - }; - diag.setLogger(diagLogger); - }); - - afterEach(() => { - diag.disable(); - }); - - it('should warn about metadata when using json', () => { - const metadata = 'foo'; - collectorExporter = new OTLPMetricExporter({ - url: address, - metadata, - } as any); - const args = warnStub.args[0]; - assert.strictEqual(args[0], 'Metadata cannot be set when using http'); - }); - }); - - describe('temporality', () => { - it('should use the right temporality when Cumulative preference is selected', () => { - const exporter = new OTLPMetricExporter({ - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }); - - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.COUNTER), - AggregationTemporality.CUMULATIVE, - 'Counter' - ); - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.HISTOGRAM), - AggregationTemporality.CUMULATIVE, - 'Histogram' - ); - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.UP_DOWN_COUNTER), - AggregationTemporality.CUMULATIVE, - 'UpDownCounter' - ); - assert.equal( - exporter.selectAggregationTemporality( - InstrumentType.OBSERVABLE_COUNTER - ), - AggregationTemporality.CUMULATIVE, - 'Asynchronous Counter' - ); - assert.equal( - exporter.selectAggregationTemporality( - InstrumentType.OBSERVABLE_UP_DOWN_COUNTER - ), - AggregationTemporality.CUMULATIVE, - 'Asynchronous UpDownCounter' - ); - }); - - it('should use the right temporality when Delta preference is selected', () => { - const exporter = new OTLPMetricExporter({ - temporalityPreference: AggregationTemporalityPreference.DELTA, - }); - - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.COUNTER), - AggregationTemporality.DELTA, - 'Counter' - ); - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.HISTOGRAM), - AggregationTemporality.DELTA, - 'Histogram' - ); - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.UP_DOWN_COUNTER), - AggregationTemporality.CUMULATIVE, - 'UpDownCounter' - ); - assert.equal( - exporter.selectAggregationTemporality( - InstrumentType.OBSERVABLE_COUNTER - ), - AggregationTemporality.DELTA, - 'Asynchronous Counter' - ); - assert.equal( - exporter.selectAggregationTemporality( - InstrumentType.OBSERVABLE_UP_DOWN_COUNTER - ), - AggregationTemporality.CUMULATIVE, - 'Asynchronous UpDownCounter' - ); - }); - - it('should use the right temporality when LowMemory preference is selected', () => { - const exporter = new OTLPMetricExporter({ - temporalityPreference: AggregationTemporalityPreference.LOWMEMORY, - }); - - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.COUNTER), - AggregationTemporality.DELTA, - 'Counter' - ); - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.HISTOGRAM), - AggregationTemporality.DELTA, - 'Histogram' - ); - assert.equal( - exporter.selectAggregationTemporality(InstrumentType.UP_DOWN_COUNTER), - AggregationTemporality.CUMULATIVE, - 'UpDownCounter' - ); - assert.equal( - exporter.selectAggregationTemporality( - InstrumentType.OBSERVABLE_COUNTER - ), - AggregationTemporality.CUMULATIVE, - 'Asynchronous Counter' - ); - assert.equal( - exporter.selectAggregationTemporality( - InstrumentType.OBSERVABLE_UP_DOWN_COUNTER - ), - AggregationTemporality.CUMULATIVE, - 'Asynchronous UpDownCounter' - ); - }); - }); - - describe('aggregation', () => { - it('aggregationSelector calls the selector supplied to the constructor', () => { - const aggregation = new ExplicitBucketHistogramAggregation([ - 0, 100, 100000, - ]); - const exporter = new OTLPMetricExporter({ - aggregationPreference: _instrumentType => aggregation, - }); - assert.equal( - exporter.selectAggregation(InstrumentType.COUNTER), - aggregation - ); - }); - - it('aggregationSelector returns the default aggregation preference when nothing is supplied', () => { - const exporter = new OTLPMetricExporter({ - aggregationPreference: _instrumentType => Aggregation.Default(), - }); - assert.equal( - exporter.selectAggregation(InstrumentType.COUNTER), - Aggregation.Default() - ); - }); - }); - - describe('export', () => { - beforeEach(async () => { - stubRequest = sinon.stub(http, 'request').returns(fakeRequest as any); - collectorExporterConfig = { - headers: { - foo: 'bar', - }, - url: 'http://foo.bar.com', - keepAlive: true, - httpAgentOptions: { keepAliveMsecs: 2000 }, - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }; - - collectorExporter = new OTLPMetricExporter(collectorExporterConfig); - - const counter = mockCounter(); - mockObservableGauge(observableResult => { - observableResult.observe(6, {}); - }, 'double-observable-gauge2'); - const histogram = mockHistogram(); - counter.add(1); - histogram.record(7); - histogram.record(14); - - const { resourceMetrics, errors } = await collect(); - assert.strictEqual(errors.length, 0); - metrics = resourceMetrics; - }); - - it('should open the connection', done => { - collectorExporter.export(metrics, () => {}); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - const options = args[0]; - - assert.strictEqual(options.hostname, 'foo.bar.com'); - assert.strictEqual(options.method, 'POST'); - assert.strictEqual(options.path, '/'); - done(); - }); - }); - - it('should set custom headers', done => { - collectorExporter.export(metrics, () => {}); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - const options = args[0]; - assert.strictEqual(options.headers['foo'], 'bar'); - done(); - }); - }); - - it('should have keep alive and keepAliveMsecs option set', done => { - collectorExporter.export(metrics, () => {}); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - const options = args[0]; - const agent = options.agent; - assert.strictEqual(agent.keepAlive, true); - assert.strictEqual(agent.options.keepAliveMsecs, 2000); - done(); - }); - }); - - it('should successfully send metrics', done => { - let buff = Buffer.from(''); - - collectorExporter.export(metrics, () => {}); - - fakeRequest.on('end', () => { - const responseBody = buff.toString(); - - const json = JSON.parse(responseBody) as IExportMetricsServiceRequest; - // The order of the metrics is not guaranteed. - const counterIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-counter' - ); - const observableIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'double-observable-gauge2' - ); - const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex( - it => it.descriptor.name === 'int-histogram' - ); - - const metric1 = - json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; - const metric2 = - json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; - const metric3 = - json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; - - assert.ok(typeof metric1 !== 'undefined', "counter doesn't exist"); - ensureCounterIsCorrect( - metric1, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].endTime, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].startTime - ); - assert.ok( - typeof metric2 !== 'undefined', - "observable gauge doesn't exist" - ); - ensureObservableGaugeIsCorrect( - metric2, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .startTime, - 6, - 'double-observable-gauge2' - ); - assert.ok(typeof metric3 !== 'undefined', "histogram doesn't exist"); - ensureHistogramIsCorrect( - metric3, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0].endTime, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .startTime, - [0, 100], - [0, 2, 0] - ); - - ensureExportMetricsServiceRequestIsSet(json); - - done(); - }); - - fakeRequest.on('data', chunk => { - buff = Buffer.concat([buff, chunk]); - }); - - const mockRes = new MockedResponse(200); - const args = stubRequest.args[0]; - const callback = args[1]; - - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - it('should log the successful message', done => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - const stubLoggerError = sinon.stub(diag, 'error'); - - const responseSpy = sinon.spy(); - collectorExporter.export(metrics, responseSpy); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - - queueMicrotask(() => { - const mockRes = new MockedResponse(200); - callback(mockRes); - mockRes.send(Buffer.from('success')); - }); - - setTimeout(() => { - assert.strictEqual(stubLoggerError.args.length, 0); - assert.strictEqual( - responseSpy.args[0][0].code, - core.ExportResultCode.SUCCESS - ); - done(); - }); - }); - }); - - it('should log the error message', done => { - const handler = core.loggingErrorHandler(); - core.setGlobalErrorHandler(handler); - - const responseSpy = sinon.spy(); - collectorExporter.export(metrics, responseSpy); - - setTimeout(() => { - const args = stubRequest.args[0]; - const callback = args[1]; - queueMicrotask(() => { - const mockRes = new MockedResponse(400); - callback(mockRes); - mockRes.send(Buffer.from('failure')); - }); - - setTimeout(() => { - const result = responseSpy.args[0][0] as core.ExportResult; - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - const error = result.error as OTLPExporterError; - assert.ok(error !== undefined); - assert.strictEqual(error.code, 400); - done(); - }); - }); - }); - }); -}); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/OTLPMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/OTLPMetricExporter.test.ts new file mode 100644 index 0000000000..87569f327a --- /dev/null +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/OTLPMetricExporter.test.ts @@ -0,0 +1,221 @@ +/* + * 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. + */ + +import * as assert from 'assert'; +import * as http from 'http'; +import * as sinon from 'sinon'; +import { AggregationTemporalityPreference } from '../../src'; + +import { OTLPMetricExporter } from '../../src/platform/node'; +import { + Aggregation, + AggregationTemporality, + ExplicitBucketHistogramAggregation, + InstrumentType, + MeterProvider, + PeriodicExportingMetricReader, +} from '@opentelemetry/sdk-metrics'; +import { Stream } from 'stream'; + +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...), HTTP transport code + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + */ + +describe('OTLPMetricExporter', () => { + describe('temporality', () => { + it('should use the right temporality when Cumulative preference is selected', () => { + const exporter = new OTLPMetricExporter({ + temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, + }); + + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.COUNTER), + AggregationTemporality.CUMULATIVE, + 'Counter' + ); + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.HISTOGRAM), + AggregationTemporality.CUMULATIVE, + 'Histogram' + ); + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.UP_DOWN_COUNTER), + AggregationTemporality.CUMULATIVE, + 'UpDownCounter' + ); + assert.equal( + exporter.selectAggregationTemporality( + InstrumentType.OBSERVABLE_COUNTER + ), + AggregationTemporality.CUMULATIVE, + 'Asynchronous Counter' + ); + assert.equal( + exporter.selectAggregationTemporality( + InstrumentType.OBSERVABLE_UP_DOWN_COUNTER + ), + AggregationTemporality.CUMULATIVE, + 'Asynchronous UpDownCounter' + ); + }); + + it('should use the right temporality when Delta preference is selected', () => { + const exporter = new OTLPMetricExporter({ + temporalityPreference: AggregationTemporalityPreference.DELTA, + }); + + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.COUNTER), + AggregationTemporality.DELTA, + 'Counter' + ); + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.HISTOGRAM), + AggregationTemporality.DELTA, + 'Histogram' + ); + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.UP_DOWN_COUNTER), + AggregationTemporality.CUMULATIVE, + 'UpDownCounter' + ); + assert.equal( + exporter.selectAggregationTemporality( + InstrumentType.OBSERVABLE_COUNTER + ), + AggregationTemporality.DELTA, + 'Asynchronous Counter' + ); + assert.equal( + exporter.selectAggregationTemporality( + InstrumentType.OBSERVABLE_UP_DOWN_COUNTER + ), + AggregationTemporality.CUMULATIVE, + 'Asynchronous UpDownCounter' + ); + }); + + it('should use the right temporality when LowMemory preference is selected', () => { + const exporter = new OTLPMetricExporter({ + temporalityPreference: AggregationTemporalityPreference.LOWMEMORY, + }); + + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.COUNTER), + AggregationTemporality.DELTA, + 'Counter' + ); + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.HISTOGRAM), + AggregationTemporality.DELTA, + 'Histogram' + ); + assert.equal( + exporter.selectAggregationTemporality(InstrumentType.UP_DOWN_COUNTER), + AggregationTemporality.CUMULATIVE, + 'UpDownCounter' + ); + assert.equal( + exporter.selectAggregationTemporality( + InstrumentType.OBSERVABLE_COUNTER + ), + AggregationTemporality.CUMULATIVE, + 'Asynchronous Counter' + ); + assert.equal( + exporter.selectAggregationTemporality( + InstrumentType.OBSERVABLE_UP_DOWN_COUNTER + ), + AggregationTemporality.CUMULATIVE, + 'Asynchronous UpDownCounter' + ); + }); + }); + + describe('aggregation', () => { + it('aggregationSelector calls the selector supplied to the constructor', () => { + const aggregation = new ExplicitBucketHistogramAggregation([ + 0, 100, 100000, + ]); + const exporter = new OTLPMetricExporter({ + aggregationPreference: _instrumentType => aggregation, + }); + assert.equal( + exporter.selectAggregation(InstrumentType.COUNTER), + aggregation + ); + }); + + it('aggregationSelector returns the default aggregation preference when nothing is supplied', () => { + const exporter = new OTLPMetricExporter({ + aggregationPreference: _instrumentType => Aggregation.Default(), + }); + assert.equal( + exporter.selectAggregation(InstrumentType.COUNTER), + Aggregation.Default() + ); + }); + }); + + describe('export', () => { + afterEach(() => { + sinon.restore(); + }); + + it('successfully exports data', function (done) { + // arrange + const fakeRequest = new Stream.PassThrough(); + Object.defineProperty(fakeRequest, 'setTimeout', { + value: function (_timeout: number) {}, + }); + + sinon.stub(http, 'request').returns(fakeRequest as any); + let buff = Buffer.from(''); + fakeRequest.on('finish', () => { + try { + // assert + const requestBody = buff.toString(); + assert.doesNotThrow(() => { + JSON.parse(requestBody); + }, 'expected requestBody to be in JSON format, but parsing failed'); + done(); + } catch (e) { + done(e); + } + }); + + fakeRequest.on('data', chunk => { + buff = Buffer.concat([buff, chunk]); + }); + + const meterProvider = new MeterProvider({ + readers: [ + new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter(), + }), + ], + }); + meterProvider.getMeter('test-meter').createCounter('test-counter').add(1); + + // act + meterProvider.forceFlush(); + meterProvider.shutdown(); + }); + }); +}); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/nodeHelpers.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/nodeHelpers.ts deleted file mode 100644 index e63d21b17c..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/nodeHelpers.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -import { Stream } from 'stream'; - -export class MockedResponse extends Stream { - constructor( - private _code: number, - private _msg?: string - ) { - super(); - } - - send(data: Uint8Array) { - this.emit('data', data); - this.emit('end'); - } - - get statusCode() { - return this._code; - } - - get statusMessage() { - return this._msg; - } -} From c9fa209bf961fc11c2490c739c2be58f6e386506 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 26 Nov 2024 10:58:23 +0100 Subject: [PATCH 03/10] chore(otlp-exporter-*-grpc): clean up tests (#5196) --- experimental/CHANGELOG.md | 1 + .../exporter-logs-otlp-grpc/package.json | 3 +- .../test/OTLPLogExporter.test.ts | 348 ++++------------- .../exporter-logs-otlp-grpc/test/certs/ca.crt | 33 -- .../exporter-logs-otlp-grpc/test/certs/ca.key | 52 --- .../test/certs/client.crt | 32 -- .../test/certs/client.csr | 28 -- .../test/certs/client.key | 52 --- .../test/certs/regenerate.sh | 21 -- .../test/certs/server.crt | 32 -- .../test/certs/server.csr | 28 -- .../test/certs/server.key | 52 --- .../test/logsHelper.ts | 175 --------- .../exporter-logs-otlp-grpc/test/utils.ts | 72 ++++ .../exporter-trace-otlp-grpc/package.json | 3 +- .../test/OTLPTraceExporter.test.ts | 348 ++++------------- .../test/certs/ca.crt | 33 -- .../test/certs/ca.key | 52 --- .../test/certs/client.crt | 32 -- .../test/certs/client.csr | 28 -- .../test/certs/client.key | 52 --- .../test/certs/regenerate.sh | 21 -- .../test/certs/server.crt | 32 -- .../test/certs/server.csr | 28 -- .../test/certs/server.key | 52 --- .../test/traceHelper.ts | 328 ---------------- .../exporter-trace-otlp-grpc/test/utils.ts | 72 ++++ .../package.json | 3 +- .../test/OTLPMetricExporter.test.ts | 350 ++++-------------- .../test/certs/ca.crt | 33 -- .../test/certs/ca.key | 52 --- .../test/certs/client.crt | 32 -- .../test/certs/client.csr | 28 -- .../test/certs/client.key | 52 --- .../test/certs/regenerate.sh | 21 -- .../test/certs/server.crt | 32 -- .../test/certs/server.csr | 28 -- .../test/certs/server.key | 52 --- .../test/metricsHelper.ts | 277 -------------- .../test/utils.ts | 72 ++++ .../test/grpc-exporter-transport.test.ts | 323 ++++++++++------ .../test/traceHelper.ts | 329 ---------------- 42 files changed, 635 insertions(+), 3059 deletions(-) delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.crt delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.key delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/client.crt delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/client.csr delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/client.key delete mode 100755 experimental/packages/exporter-logs-otlp-grpc/test/certs/regenerate.sh delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/server.crt delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/server.csr delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/certs/server.key delete mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts create mode 100644 experimental/packages/exporter-logs-otlp-grpc/test/utils.ts delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.crt delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.key delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/client.crt delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/client.csr delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/client.key delete mode 100755 experimental/packages/exporter-trace-otlp-grpc/test/certs/regenerate.sh delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/server.crt delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/server.csr delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/certs/server.key delete mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/traceHelper.ts create mode 100644 experimental/packages/exporter-trace-otlp-grpc/test/utils.ts delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.crt delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.key delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.crt delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.csr delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.key delete mode 100755 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/regenerate.sh delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.crt delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.csr delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.key delete mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts create mode 100644 experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/utils.ts delete mode 100644 experimental/packages/otlp-grpc-exporter-base/test/traceHelper.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 3363d30f8d..9127b7bd71 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to experimental packages in this project will be documented ### :house: (Internal) +* chore(otlp-exporter-\*-grpc): clean up tests [#5196](https://github.com/open-telemetry/opentelemetry-js/pull/5196) @pichlermarc * chore(otlp-exporter-\*-http): clean up tests [#5196](https://github.com/open-telemetry/opentelemetry-js/pull/5198) @pichlermarc * chore(otlp-exporter-\*-proto): clean up tests [#5196](https://github.com/open-telemetry/opentelemetry-js/pull/5199) @pichlermarc diff --git a/experimental/packages/exporter-logs-otlp-grpc/package.json b/experimental/packages/exporter-logs-otlp-grpc/package.json index 2dc7564ac6..42c2e56657 100644 --- a/experimental/packages/exporter-logs-otlp-grpc/package.json +++ b/experimental/packages/exporter-logs-otlp-grpc/package.json @@ -18,8 +18,7 @@ "precompile": "cross-var lerna run version --scope $npm_package_name --include-dependencies", "prewatch": "npm run precompile", "peer-api-check": "node ../../../scripts/peer-api-check.js", - "align-api-deps": "node ../../../scripts/align-api-deps.js", - "maint:regenerate-test-certs": "cd test/certs && ./regenerate.sh" + "align-api-deps": "node ../../../scripts/align-api-deps.js" }, "keywords": [ "opentelemetry", diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts b/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts index 996b5180ac..6218f75036 100644 --- a/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts +++ b/experimental/packages/exporter-logs-otlp-grpc/test/OTLPLogExporter.test.ts @@ -14,290 +14,86 @@ * limitations under the License. */ -import * as protoLoader from '@grpc/proto-loader'; -import { diag } from '@opentelemetry/api'; - -import * as assert from 'assert'; -import * as crypto from 'crypto'; -import * as fs from 'fs'; -import * as grpc from '@grpc/grpc-js'; -import * as path from 'path'; -import * as sinon from 'sinon'; -import { OTLPLogExporter } from '../src'; - -import { - ensureExportedLogRecordIsCorrect, - ensureMetadataIsCorrect, - ensureResourceIsCorrect, - mockedReadableLogRecord, -} from './logsHelper'; -import * as core from '@opentelemetry/core'; -import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base'; import { - IExportLogsServiceRequest, - IResourceLogs, -} from '@opentelemetry/otlp-transformer'; - -const logsServiceProtoPath = - 'opentelemetry/proto/collector/logs/v1/logs_service.proto'; -const includeDirs = [path.resolve(__dirname, '../../otlp-transformer/protos')]; - -const httpAddr = 'https://localhost:1503'; -const udsAddr = 'unix:///tmp/otlp-logs.sock'; + LoggerProvider, + SimpleLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; +import { OTLPLogExporter } from '../src'; +import { ServerTestContext, startServer } from './utils'; +import * as assert from 'assert'; -type TestParams = { - address?: string; - useTLS?: boolean; - metadata?: grpc.Metadata; +const testServiceDefinition = { + export: { + path: '/opentelemetry.proto.collector.logs.v1.LogsService/Export', + requestStream: false, + responseStream: false, + requestSerialize: (arg: Buffer) => { + return arg; + }, + requestDeserialize: (arg: Buffer) => { + return arg; + }, + responseSerialize: (arg: Buffer) => { + return arg; + }, + responseDeserialize: (arg: Buffer) => { + return arg; + }, + }, }; -const metadata = new grpc.Metadata(); -metadata.set('k', 'v'); - -const testCollectorExporter = (params: TestParams) => { - const { address = httpAddr, useTLS, metadata } = params; - return describe(`OTLPLogExporter - node ${useTLS ? 'with' : 'without'} TLS, ${ - metadata ? 'with' : 'without' - } metadata, target ${address}`, () => { - let collectorExporter: OTLPLogExporter; - let server: grpc.Server; - let exportedData: IResourceLogs | undefined; - let reqMetadata: grpc.Metadata | undefined; - - before(done => { - server = new grpc.Server(); - protoLoader - .load(logsServiceProtoPath, { - keepCase: false, - longs: String, - enums: String, - defaults: true, - oneofs: true, - includeDirs, - }) - .then((packageDefinition: protoLoader.PackageDefinition) => { - const packageObject: any = - grpc.loadPackageDefinition(packageDefinition); - server.addService( - packageObject.opentelemetry.proto.collector.logs.v1.LogsService - .service, - { - Export: (data: { - request: IExportLogsServiceRequest; - metadata: grpc.Metadata; - }) => { - if (data.request.resourceLogs != null) { - exportedData = data.request.resourceLogs[0]; - } - reqMetadata = data.metadata; - }, - } - ); - const credentials = useTLS - ? grpc.ServerCredentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - [ - { - cert_chain: fs.readFileSync('./test/certs/server.crt'), - private_key: fs.readFileSync('./test/certs/server.key'), - }, - ] - ) - : grpc.ServerCredentials.createInsecure(); - const serverAddr = new URL(address); - server.bindAsync( - serverAddr.protocol === 'https:' ? serverAddr.host : address, - credentials, - err => { - if (err) { - done(err); - } else { - server.start(); - done(); - } - } - ); - }) - .catch(done); - }); - - after(() => { - server.forceShutdown(); - }); - - beforeEach(done => { - const credentials = useTLS - ? grpc.credentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - fs.readFileSync('./test/certs/client.key'), - fs.readFileSync('./test/certs/client.crt') - ) - : grpc.credentials.createInsecure(); - collectorExporter = new OTLPLogExporter({ - url: address, - credentials, - metadata: metadata, - }); - done(); - }); - - afterEach(() => { - exportedData = undefined; - reqMetadata = undefined; - sinon.restore(); - }); - - if (useTLS && crypto.X509Certificate) { - it('test certs are valid', () => { - const certPaths = [ - './test/certs/ca.crt', - './test/certs/client.crt', - './test/certs/server.crt', - ]; - certPaths.forEach(certPath => { - const cert = new crypto.X509Certificate(fs.readFileSync(certPath)); - const now = new Date(); - assert.ok( - new Date(cert.validTo) > now, - `TLS cert "${certPath}" is still valid: cert.validTo="${cert.validTo}" (if this fails use 'npm run maint:regenerate-test-certs')` - ); - }); - }); - } - - describe('instance', () => { - it('should warn about headers when using grpc', () => { - // Need to stub/spy on the underlying logger as the 'diag' instance is global - const spyLoggerWarn = sinon.stub(diag, 'warn'); - collectorExporter = new OTLPLogExporter({ - url: address, - headers: { - foo: 'bar', - }, - }); - const args = spyLoggerWarn.args[0]; - assert.strictEqual(args[0], 'Headers cannot be set when using grpc'); - }); - it('should warn about path in url', () => { - if (new URL(address).protocol === 'unix:') { - // Skip this test for UDS - return; - } - const spyLoggerWarn = sinon.stub(diag, 'warn'); - collectorExporter = new OTLPLogExporter({ - url: `${address}/v1/logs`, - }); - const args = spyLoggerWarn.args[0]; - assert.strictEqual( - args[0], - 'URL path should not be set when using grpc, the path part of the URL will be ignored.' - ); - }); - }); - - describe('export', () => { - it('should export log records', done => { - const responseSpy = sinon.spy(); - const logRecords = [Object.assign({}, mockedReadableLogRecord)]; - collectorExporter.export(logRecords, responseSpy); - setTimeout(() => { - assert.ok( - typeof exportedData !== 'undefined', - 'resource' + " doesn't exist" - ); - - const logs = exportedData.scopeLogs[0].logRecords; - const resource = exportedData.resource; - - assert.ok(typeof logs !== 'undefined', 'log records do not exist'); - - ensureExportedLogRecordIsCorrect(logs[0]); - - assert.ok(typeof resource !== 'undefined', "resource doesn't exist"); - - ensureResourceIsCorrect(resource); - - ensureMetadataIsCorrect(reqMetadata, params?.metadata); +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...) + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + * - `@opentelemetry/otlp-grpc-exporter-base`: gRPC transport + */ +describe('OTLPLogExporter', function () { + let shutdownHandle: () => void | undefined; + const serverTestContext: ServerTestContext = { + requests: [], + serverResponseProvider: () => { + return { error: null, buffer: Buffer.from([]) }; + }, + }; + + beforeEach(async function () { + shutdownHandle = await startServer( + 'localhost:1503', + testServiceDefinition, + serverTestContext + ); + }); - done(); - }, 500); - }); - it('should log deadline exceeded error', done => { - const credentials = useTLS - ? grpc.credentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - fs.readFileSync('./test/certs/client.key'), - fs.readFileSync('./test/certs/client.crt') - ) - : grpc.credentials.createInsecure(); + afterEach(function () { + shutdownHandle(); - const collectorExporterWithTimeout = new OTLPLogExporter({ - url: address, - credentials, - metadata: metadata, - timeoutMillis: 100, - }); + // clear context + serverTestContext.requests = []; + serverTestContext.serverResponseProvider = () => { + return { error: null, buffer: Buffer.from([]) }; + }; + }); - const responseSpy = sinon.spy(); - const logRecords = [Object.assign({}, mockedReadableLogRecord)]; - collectorExporterWithTimeout.export(logRecords, responseSpy); + it('successfully exports data', async () => { + // arrange + const loggerProvider = new LoggerProvider(); + loggerProvider.addLogRecordProcessor( + new SimpleLogRecordProcessor( + new OTLPLogExporter({ + url: 'http://localhost:1503', + }) + ) + ); - setTimeout(() => { - const result = responseSpy.args[0][0] as core.ExportResult; - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - assert.match( - responseSpy.args[0][0].error.details, - /Deadline exceeded.*/ - ); - done(); - }, 300); - }); + // act + loggerProvider.getLogger('test-logger').emit({ + body: 'test-body', }); - describe('export - with gzip compression', () => { - beforeEach(() => { - const credentials = useTLS - ? grpc.credentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - fs.readFileSync('./test/certs/client.key'), - fs.readFileSync('./test/certs/client.crt') - ) - : grpc.credentials.createInsecure(); - collectorExporter = new OTLPLogExporter({ - url: address, - credentials, - metadata: metadata, - compression: CompressionAlgorithm.GZIP, - }); - }); - it('should successfully send the log records', done => { - const responseSpy = sinon.spy(); - const logRecords = [Object.assign({}, mockedReadableLogRecord)]; - collectorExporter.export(logRecords, responseSpy); - setTimeout(() => { - assert.ok( - typeof exportedData !== 'undefined', - 'resource' + " doesn't exist" - ); - const logs = exportedData.scopeLogs[0].logRecords; - const resource = exportedData.resource; - - assert.ok(typeof logs !== 'undefined', 'log records do not exist'); - ensureExportedLogRecordIsCorrect(logs[0]); + await loggerProvider.shutdown(); - assert.ok(typeof resource !== 'undefined', "resource doesn't exist"); - ensureResourceIsCorrect(resource); - - ensureMetadataIsCorrect(reqMetadata, metadata); - - done(); - }, 500); - }); - }); + // assert + assert.strictEqual(serverTestContext.requests.length, 1); }); -}; - -testCollectorExporter({ useTLS: true }); -testCollectorExporter({ useTLS: false }); -testCollectorExporter({ metadata }); -// skip UDS tests on windows -process.platform !== 'win32' && testCollectorExporter({ address: udsAddr }); +}); diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.crt b/experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.crt deleted file mode 100644 index 62270748a6..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFozCCA4ugAwIBAgIUAlsD9Gz58PTwA00z7LcmYLcREgswDQYJKoZIhvcNAQEL -BQAwYTELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQHDBFPcGVuVGVs -ZW1ldHJ5VGVzdDENMAsGA1UECgwEUm9vdDENMAsGA1UECwwEVGVzdDELMAkGA1UE -AwwCY2EwHhcNMjQwNjA4MTkxODQ4WhcNMjUwNjA4MTkxODQ4WjBhMQswCQYDVQQG -EwJDTDELMAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0w -CwYDVQQKDARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMv6RFj5bgfSnj27LJMUwceaVI8Rz6Ks -BKRyJlM/cE3MQg+58BjoelLxfRsCxHFLvwuo/S6l0leRYAvzCexsnFnqd5Ie0tMi -1pB6YMPcmzUwbJCywLUGBin85TDFpEd1L1cSxKvi4DoC6EDYdBge0yp3T1my3mlu -8LaMVYr22RQvofwaTqFwmOQSqxK3wR9LRWTMDoUioMdolkIv7y1lpQ59ORWlASfP -SMUhh4KAYmDCtH9M40iY7kwCMv8ZwB2DIiw1qZxkk3MFJoyI5HZuvb586Pp5GfHI -Wry2KaTZskGCDB/8mURhMyFQnsO+kN9moYLm+NVk+8jzTTus4DUI6sEnpSgF05hU -O9lIL+HAFl/6N5d/W5wbSfOulPwJCd+c49ylIAUu38ZmNmRpmGPalBlluDYu8Exw -d/uoXBmt5vyeE9d14uTYYt+xef942s66Qnoq9wLFJymSsMb1v41Pv/zjeV53NIRE -xJ1sSH+5xcRaAdvjdmN2q5zuKddkD/2FyIl0NkWwNYefKaFdLEy9MfdbBgKBHOkh -neTWIZwI8Kkff6v5MTW022MK7v3nis1wUjrvEn0CyI8USCh/wcNBmiJsrEPltN+S -CsriZLwT1x4mce+43+bibxinL+RZogWxZ/Q+TkeUsluBNjn8hwWy5n/750HKgRAa -D+KxGkn92B9tAgMBAAGjUzBRMB0GA1UdDgQWBBQjlis82orRLmms4w1dbJFf9NDO -6zAfBgNVHSMEGDAWgBQjlis82orRLmms4w1dbJFf9NDO6zAPBgNVHRMBAf8EBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQARxfWyzqU9aUrSt50daVayVezg3gJQh4XI -V0p+LGEF6rlGVlX3lnhyf1g/nd1jdiBxMGnROXTFotdw4h1yQjlNrPp5Gh7ZJets -NPvo0xYfCckEmwUFX1+ikwteSciOmBKypAsEYlPjUuGxhMm7WT18WyogjUZOz8k9 -Q3DSAsf3KR516uYeK+U/RTOiYc6HzCPxBy5fG80aI4rxcdJkA60RxHEM2ZqdhlYY -+DkE6843xEbrF4TjmoDeOq471D4Zl3DqLg9v7YbOARV2G8MYUsBkeSTcSz+DWEXA -MSoQMgv2Z6G7ToUeYhRXOLHHILHmu5Hc2ldVvLmbhkfDICjYnNqsiuSnKkZ2WqBn -1GXTjTEPl+FNt0Gwy/+ygiG4Z2S5Cc2ULPLMs9E9N2Iiq+LNjmgw3dUy8pwOTfDo -heluT4NeGmHxh4sFQpg96z0K1JCZZpzJCsSAJRXxLdSl7VVFXTGbmRjD8BrBWn4k -9euT4UHgWj+xSYkJWpIkuTMJ6M4+B/JQQNVwKok/xqTHadOJ2f4V6j4cy517hMu6 -oFo/XF6zG3N0sGfkFTlcE7xsruRbir7utAEQwuUGQsy1SeGRrLCwBcvhetq1jVR8 -mjXEADzaP1a9+nMG+LFD+PeHcpYbuxaOwAinFbA1SwwGmAwWFhXudSiFpIM2btrE -f9n1KYObAw== ------END CERTIFICATE----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.key b/experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.key deleted file mode 100644 index 6d444ffdab..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/ca.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -Z4y6eNlrPgWPTUHp+YTgMmZ/c1kwHGo= ------END PRIVATE KEY----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.crt b/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.crt deleted file mode 100644 index ff9555042c..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJDTDEL -MAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0wCwYDVQQK -DARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTAeFw0yNDA2MDgxOTE4 -NDlaFw0yNTA2MDgxOTE4NDlaMGoxCzAJBgNVBAYTAkNMMQswCQYDVQQIDAJSTTEa -MBgGA1UEBwwRT3BlblRlbGVtZXRyeVRlc3QxDTALBgNVBAoMBFRlc3QxDzANBgNV -BAsMBkNsaWVudDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEAwmlAXHz7CE3EQ7XEMNwYymj193+C3Mo6V210X2BKjCuZ -SRdq0c/VpAWeFy5f1SHzFEkvpmfXKjePrnQL9fT5bFwUusx1pepI1c+9eHMxiSxc -rpO5SPfEPfZPHOhZBUYEYI2MRektn0UaE/a9qiQpBh5fFtyMedLkyNkfJ2OAbwCJ -XRwmUpt5pWAFORXDecVLWtTSVMQsWsOI/2gae6dgbTbJdXaLUV/UFsBOlp6m1mwb -PsHiQDawxM5aks2AjRA79aBSF1IxwO9Duqv3ZjqFd8C1nXr7oqVyEujQFtjIAvNJ -I1aP9Mu5Pybcp928VkQT8PdRcaLDt8iuOyggI86CITxVFOur8GxASHF1EF4ymkfG -jS5jCLh8BLqAGqNERQpoNyD879yTlq8ho/k/F0in9WyaEjbuEKo6wPhJUgZ1JV0q -CpqxmTlGgcWBg1Mnl8RdmHkq68zsmTpLbPzpuXlv51KmJCahc31jWHJjN1ORPGPg -hLrKkbcylW/6HTpI5i2kkn+k5owUAkst7K0njRH5TF4p7iYuC4zwSnTgxlvio9E5 -Ci6BinMgkDOjwNovXy60mR+RnKP9yxlpuJ/jbZvR9a2SYpMbu1CrBFyZ4JkTLCEC -A6rh6arjXVW6rTwEjKpMoqhZXg7CNux7gxq/czo9S6Ja0xVOnomTRCHLTgCoAOcC -AwEAAaNCMEAwHQYDVR0OBBYEFMI7y2a70iF6O+SLnWA2FXbjIlhkMB8GA1UdIwQY -MBaAFCOWKzzaitEuaazjDV1skV/00M7rMA0GCSqGSIb3DQEBCwUAA4ICAQADNVle -3YVLZs/MULoWXTwVWgriM/o5/j0iYQ4xAWlTkaT38gLov16EmwOZJbXSfDVyom1p -M818j1IwqUKdMNJyCAiXE3IriBLLSjtk6tpi4sQ2Es/QnyINGoMcAugfoymjJPhA -Pr0fJK06fs/8BDcPhlbZl3DfMF4heXh/6wlgGfjwRoXmRwtzw1Iavw9ThbolhJTm -RiE4WE2Grh0AGtqe4EJHVDslhq2oe0UHU55BbwBPWvpUYb7VWR5dd3B04TgnOnR2 -ESzUgb4suQmNEIQsO/k2O7aIQj9jJzPCULzkmcUppAP9ig9lipmi/Fa0+1nFVJrT -lAnlDm8EW5g/S+XdFTEd22mSaWM5hjTQqDlGi2Ni6R4jDcPE7uyFS0FwTk6e72YE -CP+wLIDd8s8Q8Bp5jP5JgJm3f1MCXGDtoGVR4fgMF+N36eKVGFIeFN/jQaLAE4pO -3qaVCEpQCPC4NoCW+lIOLtYQ+nTg6RVCHf26uZqkuHKqh/gGP9MCSEkg9b78iC8D -ciKxp4gz7CUUV+cmDMcDJxqAaBZnA+V0brVqDcYtul1UyanPN4WsJbBRG5s705vy -m7Fk4k2GWdfyEiOjrRd2EuezmemeSD4S9aIgtAGhggcIMtkJaSdS6zfjo/nuu2kO -A0+Bw3OOUbvnnJ0MlmLHeCSMPBCu4xVaKda8Lw== ------END CERTIFICATE----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.csr b/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.csr deleted file mode 100644 index 1fe2d47932..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.csr +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIErzCCApcCAQAwajELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQH -DBFPcGVuVGVsZW1ldHJ5VGVzdDENMAsGA1UECgwEVGVzdDEPMA0GA1UECwwGQ2xp -ZW50MRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDCaUBcfPsITcRDtcQw3BjKaPX3f4LcyjpXbXRfYEqMK5lJF2rRz9Wk -BZ4XLl/VIfMUSS+mZ9cqN4+udAv19PlsXBS6zHWl6kjVz714czGJLFyuk7lI98Q9 -9k8c6FkFRgRgjYxF6S2fRRoT9r2qJCkGHl8W3Ix50uTI2R8nY4BvAIldHCZSm3ml -YAU5FcN5xUta1NJUxCxaw4j/aBp7p2BtNsl1dotRX9QWwE6WnqbWbBs+weJANrDE -zlqSzYCNEDv1oFIXUjHA70O6q/dmOoV3wLWdevuipXIS6NAW2MgC80kjVo/0y7k/ -Jtyn3bxWRBPw91FxosO3yK47KCAjzoIhPFUU66vwbEBIcXUQXjKaR8aNLmMIuHwE -uoAao0RFCmg3IPzv3JOWryGj+T8XSKf1bJoSNu4QqjrA+ElSBnUlXSoKmrGZOUaB -xYGDUyeXxF2YeSrrzOyZOkts/Om5eW/nUqYkJqFzfWNYcmM3U5E8Y+CEusqRtzKV -b/odOkjmLaSSf6TmjBQCSy3srSeNEflMXinuJi4LjPBKdODGW+Kj0TkKLoGKcyCQ -M6PA2i9fLrSZH5Gco/3LGWm4n+Ntm9H1rZJikxu7UKsEXJngmRMsIQIDquHpquNd -VbqtPASMqkyiqFleDsI27HuDGr9zOj1LolrTFU6eiZNEIctOAKgA5wIDAQABoAAw -DQYJKoZIhvcNAQELBQADggIBAHfjpZwmJgizjCW89+pYI0vhYH9LH22YhN7qzV6y -smS9JNRe/N3jCOadpKgsmx7W52+RZHkdst69dvg775cMJjQ6qNouXALydUHTloXj -2k562BeUCfDBFlBR06dRGdGNkAuntAEdn/uV7+wU2SyptPGpXW8HP5xHyYoqdIlA -tEqcb/Ue9WqG7oiP4X6FI56/4HjVt9PiFtCWZS1uU06eJSRufMDSzKzS12jNfm6C -TGHD0vnzzJdW2YkaGwAUa2Iluzm7lo3eD0QJOaa9RvquxPCjbIKnzJQuzOpcI6Lm -m/fd3fGxyAl6T8kCMnItzjFTgux7NuPps3oF/FKaiNqeL/HZXWLRRI74agzlvUP7 -10HqmUvw+diVka4+ve/8zmStn7pUb5IHd8C0OGbU/N2Y+UX++jYlI5W6vXGpjo76 -R2FMaG+crPAlOKZ9/7t9+NeoqYM5iW8zLiGTXX1Zx0UKMV2om3b8CXVsGrB3y7WG -j3ZYs/4apg9sNqsIs8+udOPkfx8a3a+ZvBlrCl3XavYCaUHoNH5+dThQWvMpaFAQ -Z2wKwuSkD9kTQqeTJUj684ztf2kDopM+nt9j54ZhrkfsDiGMUtz8Xk4SPYTdN/Yc -KKVBOnm/4Hr1bASAukkQmF7AEUyUG6eJVGrEP/5MWuWc6ddONFj+eiwyAd2OzVq7 -3tvv ------END CERTIFICATE REQUEST----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.key b/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.key deleted file mode 100644 index 4cfd6bcdb3..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/client.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -GCjn3ccqyYWia5VCpKUwdjE0k/SMU8/D ------END PRIVATE KEY----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/regenerate.sh b/experimental/packages/exporter-logs-otlp-grpc/test/certs/regenerate.sh deleted file mode 100755 index cc052a4eff..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/regenerate.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env sh -# -# Regenerate certificates that are used for tests using TLS. -# Certs are generated with a one year expiry, so periodic regen is required. -# -# Usage: npm run maint:regenerate-test-certs - -rm ca.crt ca.key client.crt client.csr client.key server.crt server.csr server.key - -openssl genrsa -out ca.key 4096 -openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Root/OU=Test/CN=ca" - -openssl genrsa -out server.key 4096 -openssl req -new -key server.key -out server.csr -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Test/OU=Server/CN=localhost" -openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -openssl rsa -in server.key -out server.key - -openssl genrsa -out client.key 4096 -openssl req -new -key client.key -out client.csr -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Test/OU=Client/CN=localhost" -openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt -openssl rsa -in client.key -out client.key diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.crt b/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.crt deleted file mode 100644 index 99877d7759..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJDTDEL -MAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0wCwYDVQQK -DARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTAeFw0yNDA2MDgxOTE4 -NDhaFw0yNTA2MDgxOTE4NDhaMGoxCzAJBgNVBAYTAkNMMQswCQYDVQQIDAJSTTEa -MBgGA1UEBwwRT3BlblRlbGVtZXRyeVRlc3QxDTALBgNVBAoMBFRlc3QxDzANBgNV -BAsMBlNlcnZlcjESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEAs4sfkgZBkGLNdsv1i2tcfrMOfqm/7xfGHTC05mBDatv3 -3k0RL+9KhR7xblAR3VadAN8HhdtmzlB+kdVYsSZHeZDJFjOnwXoxMRFxoNWxc4t/ -RTyj7JfWtYVL+2AXqOvXeMBCY5N3otS6i/6evoeBf4rEKs4h2bBoRTzEhBKlF7zR -HkqnhBrTR/vjOJYvasUte8KRFbsJeoxAsn5oCLQHA5+DBggBfFX8pO/JIGRYbdpr -oZ7AU0l9hdTMP7iakL1pZIuddROwk6kF5mc22T2Jey/sQp5OqxqT9mtbyZqDdQsF -V/jmuMs6H/fBfOkeJaAPyNeJ+Pa23WsuODzefWzCMDTCEwGsHddi5vWCbJaFWqu1 -9C9uy6iSP5aAnmW+RTi/bVv/KZavl+NGF8RFMaOr8hCtkvh8JqW19D9SmtU8Ky45 -qHSqz2q7awfbWLy8xMM8IYM6L5jCB27g2XeA/SjCb2ryab0OP6a8LSezXMBzQuml -f1C3kNnm2pSFFfLNimPs7A01zqo6eowGm3yneRBlTTyHgTFOFzuP7sEtY6p/GI6F -+jKBtSXUiKqAAwpObcMXS9a5td8wpAs87IEKKAb58BcSkzslU1fuY28At9kEUIWR -z1dyQRBPxiu4NaSxcIpI9cEBvHYSAf454noTuehlZvL6tCaAobZZMqsXSfvnVvkC -AwEAAaNCMEAwHQYDVR0OBBYEFFRmQkQkZmb8ER1Cx/6FOWmKXKlXMB8GA1UdIwQY -MBaAFCOWKzzaitEuaazjDV1skV/00M7rMA0GCSqGSIb3DQEBCwUAA4ICAQAYQHvf -s1hrdDUDzn6LQiAMbDh3VwEVOg3O/8uomn6+J/TCBkTAD6avMO3hZH28Kc5H4c8P -9db7rBkmqyOzOo7JG8xJz7vg90oh0sqo5+G73h9PQb7G8f6wCGJTD9IbRDcgCspW -Z8zIBZGxpeHHitdB2Jik1DxUkqViwxlBzBkiNpqixDde5U5EqxbecTBIuMqJkkxG -7JV61Mbb6r8xCNPqd1qYDQ6fggV1MFb6yf9TEuLmV2mKn1ypo/MzMBoTMGgKoHS8 -RgiN0bztRayaEqnmMZ5TQOYkmuGbW1oBwXeA7lorOu7/Yi4/IP0/H0rt/mSUhh5K -ubtZkWrsZV3xPeERYL9UiuOdEJ58tI3u3yDFvnULczH8bzapZisxQIfaMasq9aHg -LO8lqMk4+Kyb09vz+DPuMGdDkl4hchHlySUCrhmMmrCJTgQHmEmQMF+1TBP1cFXe -B9grn4zr+sVsqKNMArnQoUff42cFi1E5pZq7Z4DfGltcv81ay51OgTVxMJYOUB9Q -1PJcO0hkLrV66kSbTd5//6uyYuAOy5ZVXOFHOO/tDBlKlgOqYXe5tj90uZQh0AnJ -NeH73pwS3x9dF0JZBcviaH/yTK2ggi9lmzJ0EkwqUXyfYfJZGBgnLVDnNpXSUUha -v1h7xzhfZgYbWEgwV+AWiXlHTrZCXSmY3sM2QA== ------END CERTIFICATE----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.csr b/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.csr deleted file mode 100644 index b459ff45ff..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.csr +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIErzCCApcCAQAwajELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQH -DBFPcGVuVGVsZW1ldHJ5VGVzdDENMAsGA1UECgwEVGVzdDEPMA0GA1UECwwGU2Vy -dmVyMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQCzix+SBkGQYs12y/WLa1x+sw5+qb/vF8YdMLTmYENq2/feTREv70qF -HvFuUBHdVp0A3weF22bOUH6R1VixJkd5kMkWM6fBejExEXGg1bFzi39FPKPsl9a1 -hUv7YBeo69d4wEJjk3ei1LqL/p6+h4F/isQqziHZsGhFPMSEEqUXvNEeSqeEGtNH -++M4li9qxS17wpEVuwl6jECyfmgItAcDn4MGCAF8Vfyk78kgZFht2muhnsBTSX2F -1Mw/uJqQvWlki511E7CTqQXmZzbZPYl7L+xCnk6rGpP2a1vJmoN1CwVX+Oa4yzof -98F86R4loA/I14n49rbday44PN59bMIwNMITAawd12Lm9YJsloVaq7X0L27LqJI/ -loCeZb5FOL9tW/8plq+X40YXxEUxo6vyEK2S+HwmpbX0P1Ka1TwrLjmodKrPartr -B9tYvLzEwzwhgzovmMIHbuDZd4D9KMJvavJpvQ4/prwtJ7NcwHNC6aV/ULeQ2eba -lIUV8s2KY+zsDTXOqjp6jAabfKd5EGVNPIeBMU4XO4/uwS1jqn8YjoX6MoG1JdSI -qoADCk5twxdL1rm13zCkCzzsgQooBvnwFxKTOyVTV+5jbwC32QRQhZHPV3JBEE/G -K7g1pLFwikj1wQG8dhIB/jniehO56GVm8vq0JoChtlkyqxdJ++dW+QIDAQABoAAw -DQYJKoZIhvcNAQELBQADggIBAB5lc1i6TI58ZkV8dxlqw2OJaTuj2064GzQvwekc -iRSg8QaeVaGhA+jnet/UvBCDBqFAh4nMY/THKWB7721agRbSJS3RtyiZbBFNBDQt -dLPXO6HY6HGM1Z2ov71HNeDBQnqYSmOld3RkO9Co9nGhjOLkBtvoiAWmMHS3pnpq -o2ssCd2GmbMmiAdSJspgWJnCJUQneV0hW+l7b79oW8E0j4aZLQ7g0B3y2iTg2Ngk -0R301hh3Fs9B5PYa/TlOJsd4icgxvMjCvsIxHaihKjvNLDu3GhYRyHlxyAnZVvaG -GAqHn2WyvLeg2bMswy7FV9J6qI5PQVaApLb2g5TPbG6y52XgLMCl06fM25UbTaym -GCAEeylvXwIClPNlmnvLnytABHA5tLkfHt+E7UPJmPv8BuOeRTYtlp3UB/aI6rKG -HOMZnhUNZTVCnxid6gLEI7xMxdAKP6N1sWdcDD8bkcVEk8IjOJrpQzuYUchQwzZ+ -hZIact21gTuN5xhxq1f1gvEN0th1vUSjfZ0K67M9mgqNdza8fXOaUNc3XwRUxhfB -1kpXxDuH2dzjsy3CGeobry8nHmUB/P2KEy8u7ue7Ra3J4stFCPDRJqroRM3V8xNK -1+I2KBM8UeybFzYya9xqT9q0FNe/ukS2ohV5C1YjnxrMQ2Mx+CqJOVqpA/nP55ZE -cuZ8 ------END CERTIFICATE REQUEST----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.key b/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.key deleted file mode 100644 index 8af97da4a7..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/certs/server.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -LPnexONaL/II1DilmyNT5mZMXCXP ------END PRIVATE KEY----- diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts b/experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts deleted file mode 100644 index 21e151d227..0000000000 --- a/experimental/packages/exporter-logs-otlp-grpc/test/logsHelper.ts +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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. - */ - -import { HrTime, TraceFlags } from '@opentelemetry/api'; -import { SeverityNumber } from '@opentelemetry/api-logs'; -import { Resource } from '@opentelemetry/resources'; -import * as assert from 'assert'; -import * as grpc from '@grpc/grpc-js'; -import { VERSION } from '@opentelemetry/core'; -import { - IAnyValue, - IKeyValue, - ILogRecord, - IResource, -} from '@opentelemetry/otlp-transformer'; -import { ReadableLogRecord } from '@opentelemetry/sdk-logs'; - -const traceIdArr = [ - 31, 16, 8, 220, 142, 39, 14, 133, 196, 10, 13, 124, 57, 57, 178, 120, -]; -const spanIdArr = [94, 16, 114, 97, 246, 79, 165, 62]; - -export const mockedReadableLogRecord: ReadableLogRecord = { - resource: Resource.default().merge( - new Resource({ - 'resource-attribute': 'some resource-attr value', - }) - ), - instrumentationScope: { - name: 'scope_name_1', - version: '0.1.0', - schemaUrl: 'http://url.to.schema', - }, - hrTime: [1680253513, 123241635] as HrTime, - hrTimeObserved: [1683526948, 965142784] as HrTime, - attributes: { - 'some-attribute': 'some attribute value', - }, - droppedAttributesCount: 0, - severityNumber: SeverityNumber.ERROR, - severityText: 'error', - body: 'some_log_body', - spanContext: { - traceFlags: TraceFlags.SAMPLED, - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '5e107261f64fa53e', - }, -}; - -export function ensureExportedAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'some-attribute', - value: { - stringValue: 'some attribute value', - value: 'stringValue', - }, - }, - ], - 'exported attributes are incorrect' - ); -} - -export function ensureExportedBodyIsCorrect(body?: IAnyValue) { - assert.deepStrictEqual( - body, - { stringValue: 'some_log_body', value: 'stringValue' }, - 'exported attributes are incorrect' - ); -} - -export function ensureExportedLogRecordIsCorrect(logRecord: ILogRecord) { - ensureExportedBodyIsCorrect(logRecord.body); - ensureExportedAttributesAreCorrect(logRecord.attributes); - assert.strictEqual( - logRecord.timeUnixNano, - '1680253513123241635', - 'timeUnixNano is wrong' - ); - assert.strictEqual( - logRecord.observedTimeUnixNano, - '1683526948965142784', - 'observedTimeUnixNano is wrong' - ); - assert.strictEqual( - logRecord.severityNumber, - 'SEVERITY_NUMBER_ERROR', - 'severityNumber is wrong' - ); - assert.strictEqual(logRecord.severityText, 'error', 'severityText is wrong'); - assert.strictEqual( - logRecord.droppedAttributesCount, - 0, - 'droppedAttributesCount is wrong' - ); - assert.strictEqual(logRecord.flags, TraceFlags.SAMPLED, 'flags is wrong'); - assert.deepStrictEqual( - logRecord.traceId, - Buffer.from(traceIdArr), - 'traceId is wrong' - ); - assert.deepStrictEqual( - logRecord.spanId, - Buffer.from(spanIdArr), - 'spanId is wrong' - ); -} - -export function ensureResourceIsCorrect(resource: IResource) { - assert.deepStrictEqual(resource, { - attributes: [ - { - key: 'service.name', - value: { - stringValue: `unknown_service:${process.argv0}`, - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.language', - value: { - stringValue: 'nodejs', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.name', - value: { - stringValue: 'opentelemetry', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.version', - value: { - stringValue: VERSION, - value: 'stringValue', - }, - }, - { - key: 'resource-attribute', - value: { - stringValue: 'some resource-attr value', - value: 'stringValue', - }, - }, - ], - droppedAttributesCount: 0, - }); -} - -export function ensureMetadataIsCorrect( - actual?: grpc.Metadata, - expected?: grpc.Metadata -) { - //ignore user agent - expected?.remove('user-agent'); - actual?.remove('user-agent'); - assert.deepStrictEqual(actual?.getMap(), expected?.getMap() ?? {}); -} diff --git a/experimental/packages/exporter-logs-otlp-grpc/test/utils.ts b/experimental/packages/exporter-logs-otlp-grpc/test/utils.ts new file mode 100644 index 0000000000..8dc6ae14e0 --- /dev/null +++ b/experimental/packages/exporter-logs-otlp-grpc/test/utils.ts @@ -0,0 +1,72 @@ +/* + * 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. + */ + +import { + Metadata, + Server, + ServerCredentials, + ServiceDefinition, +} from '@grpc/grpc-js'; + +export interface ExportedData { + request: Buffer; + metadata: Metadata; +} + +export interface ServerTestContext { + requests: ExportedData[]; + serverResponseProvider: () => { error: Error | null; buffer?: Buffer }; +} + +/** + * Starts a customizable server that saves all responses to context.responses + * Returns data as defined in context.ServerResponseProvider + * + * @return shutdown handle, needs to be called to ensure that mocha exits + * @param address address to bind to + * @param service service to start + * @param context context for storing responses and to define server behavior. + */ +export function startServer( + address: string, + service: ServiceDefinition, + context: ServerTestContext +): Promise<() => void> { + const server = new Server(); + server.addService(service, { + export: (data: ExportedData, callback: any) => { + context.requests.push(data); + const response = context.serverResponseProvider(); + callback(response.error, response.buffer); + }, + }); + + return new Promise<() => void>((resolve, reject) => { + server.bindAsync( + address, + ServerCredentials.createInsecure(), + (error, port) => { + server.start(); + if (error != null) { + reject(error); + } + resolve(() => { + server.forceShutdown(); + }); + } + ); + }); +} diff --git a/experimental/packages/exporter-trace-otlp-grpc/package.json b/experimental/packages/exporter-trace-otlp-grpc/package.json index 84b83dd55d..efa366d787 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/package.json +++ b/experimental/packages/exporter-trace-otlp-grpc/package.json @@ -18,8 +18,7 @@ "precompile": "cross-var lerna run version --scope $npm_package_name --include-dependencies", "prewatch": "npm run precompile", "peer-api-check": "node ../../../scripts/peer-api-check.js", - "align-api-deps": "node ../../../scripts/align-api-deps.js", - "maint:regenerate-test-certs": "cd test/certs && ./regenerate.sh" + "align-api-deps": "node ../../../scripts/align-api-deps.js" }, "keywords": [ "opentelemetry", diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/OTLPTraceExporter.test.ts b/experimental/packages/exporter-trace-otlp-grpc/test/OTLPTraceExporter.test.ts index 801f85a36b..85b6725c5e 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/test/OTLPTraceExporter.test.ts +++ b/experimental/packages/exporter-trace-otlp-grpc/test/OTLPTraceExporter.test.ts @@ -14,295 +14,85 @@ * limitations under the License. */ -import * as protoLoader from '@grpc/proto-loader'; -import { diag } from '@opentelemetry/api'; +import { OTLPTraceExporter } from '../src'; +import { ServerTestContext, startServer } from './utils'; +import * as assert from 'assert'; import { - BasicTracerProvider, SimpleSpanProcessor, + BasicTracerProvider, } from '@opentelemetry/sdk-trace-base'; -import * as assert from 'assert'; -import * as crypto from 'crypto'; -import * as fs from 'fs'; -import * as grpc from '@grpc/grpc-js'; -import * as path from 'path'; -import * as sinon from 'sinon'; -import { OTLPTraceExporter } from '../src'; - -import { - ensureExportedSpanIsCorrect, - ensureMetadataIsCorrect, - ensureResourceIsCorrect, - mockedReadableSpan, -} from './traceHelper'; -import * as core from '@opentelemetry/core'; -import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base'; -import { - IExportTraceServiceRequest, - IResourceSpans, -} from '@opentelemetry/otlp-transformer'; - -const traceServiceProtoPath = - 'opentelemetry/proto/collector/trace/v1/trace_service.proto'; -const includeDirs = [path.resolve(__dirname, '../../otlp-transformer/protos')]; - -const httpAddr = 'https://localhost:1501'; -const udsAddr = 'unix:///tmp/otlp-traces.sock'; - -type TestParams = { - address?: string; - useTLS?: boolean; - metadata?: grpc.Metadata; +const testServiceDefinition = { + export: { + path: '/opentelemetry.proto.collector.trace.v1.TraceService/Export', + requestStream: false, + responseStream: false, + requestSerialize: (arg: Buffer) => { + return arg; + }, + requestDeserialize: (arg: Buffer) => { + return arg; + }, + responseSerialize: (arg: Buffer) => { + return arg; + }, + responseDeserialize: (arg: Buffer) => { + return arg; + }, + }, }; -const metadata = new grpc.Metadata(); -metadata.set('k', 'v'); - -const testCollectorExporter = (params: TestParams) => { - const { address = httpAddr, useTLS, metadata } = params; - return describe(`OTLPTraceExporter - node ${ - useTLS ? 'with' : 'without' - } TLS, ${metadata ? 'with' : 'without'} metadata, target ${address}`, () => { - let collectorExporter: OTLPTraceExporter; - let server: grpc.Server; - let exportedData: IResourceSpans | undefined; - let reqMetadata: grpc.Metadata | undefined; - - before(done => { - server = new grpc.Server(); - protoLoader - .load(traceServiceProtoPath, { - keepCase: false, - longs: String, - enums: String, - defaults: true, - oneofs: true, - includeDirs, - }) - .then((packageDefinition: protoLoader.PackageDefinition) => { - const packageObject: any = - grpc.loadPackageDefinition(packageDefinition); - server.addService( - packageObject.opentelemetry.proto.collector.trace.v1.TraceService - .service, - { - Export: (data: { - request: IExportTraceServiceRequest; - metadata: grpc.Metadata; - }) => { - if (data.request.resourceSpans != null) { - exportedData = data.request.resourceSpans[0]; - } - reqMetadata = data.metadata; - }, - } - ); - const credentials = useTLS - ? grpc.ServerCredentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - [ - { - cert_chain: fs.readFileSync('./test/certs/server.crt'), - private_key: fs.readFileSync('./test/certs/server.key'), - }, - ] - ) - : grpc.ServerCredentials.createInsecure(); - const serverAddr = new URL(address); - server.bindAsync( - serverAddr.protocol === 'https:' ? serverAddr.host : address, - credentials, - () => { - server.start(); - done(); - } - ); - }); - }); - - after(() => { - server.forceShutdown(); - }); - - beforeEach(done => { - const credentials = useTLS - ? grpc.credentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - fs.readFileSync('./test/certs/client.key'), - fs.readFileSync('./test/certs/client.crt') - ) - : grpc.credentials.createInsecure(); - collectorExporter = new OTLPTraceExporter({ - url: address, - credentials, - metadata: metadata, - }); - - const provider = new BasicTracerProvider(); - provider.addSpanProcessor(new SimpleSpanProcessor(collectorExporter)); - done(); - }); - - afterEach(() => { - exportedData = undefined; - reqMetadata = undefined; - sinon.restore(); - }); - - if (useTLS && crypto.X509Certificate) { - it('test certs are valid', () => { - const certPaths = [ - './test/certs/ca.crt', - './test/certs/client.crt', - './test/certs/server.crt', - ]; - certPaths.forEach(certPath => { - const cert = new crypto.X509Certificate(fs.readFileSync(certPath)); - const now = new Date(); - assert.ok( - new Date(cert.validTo) > now, - `TLS cert "${certPath}" is still valid: cert.validTo="${cert.validTo}" (if this fails use 'npm run maint:regenerate-test-certs')` - ); - }); - }); - } - - describe('instance', () => { - it('should warn about headers when using grpc', () => { - // Need to stub/spy on the underlying logger as the 'diag' instance is global - const spyLoggerWarn = sinon.stub(diag, 'warn'); - collectorExporter = new OTLPTraceExporter({ - url: address, - headers: { - foo: 'bar', - }, - }); - const args = spyLoggerWarn.args[0]; - assert.strictEqual(args[0], 'Headers cannot be set when using grpc'); - }); - it('should warn about path in url', () => { - if (new URL(address).protocol === 'unix:') { - // Skip this test for UDS - return; - } - const spyLoggerWarn = sinon.stub(diag, 'warn'); - collectorExporter = new OTLPTraceExporter({ - url: `${address}/v1/trace`, - }); - const args = spyLoggerWarn.args[0]; - assert.strictEqual( - args[0], - 'URL path should not be set when using grpc, the path part of the URL will be ignored.' - ); - }); - }); - - describe('export', () => { - it('should export spans', done => { - const responseSpy = sinon.spy(); - const spans = [Object.assign({}, mockedReadableSpan)]; - collectorExporter.export(spans, responseSpy); - setTimeout(() => { - assert.ok( - typeof exportedData !== 'undefined', - 'resource' + " doesn't exist" - ); - - const spans = exportedData.scopeSpans[0].spans; - const resource = exportedData.resource; - - assert.ok(typeof spans !== 'undefined', 'spans do not exist'); - - ensureExportedSpanIsCorrect(spans[0]); - - assert.ok(typeof resource !== 'undefined', "resource doesn't exist"); - - ensureResourceIsCorrect(resource); - - ensureMetadataIsCorrect(reqMetadata, params?.metadata); - - done(); - }, 500); - }); - it('should log deadline exceeded error', done => { - const credentials = useTLS - ? grpc.credentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - fs.readFileSync('./test/certs/client.key'), - fs.readFileSync('./test/certs/client.crt') - ) - : grpc.credentials.createInsecure(); +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...) + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + * - `@opentelemetry/otlp-grpc-exporter-base`: gRPC transport + */ +describe('OTLPTraceExporter', function () { + let shutdownHandle: () => void | undefined; + const serverTestContext: ServerTestContext = { + requests: [], + serverResponseProvider: () => { + return { error: null, buffer: Buffer.from([]) }; + }, + }; + + beforeEach(async function () { + shutdownHandle = await startServer( + 'localhost:1501', + testServiceDefinition, + serverTestContext + ); + }); - const collectorExporterWithTimeout = new OTLPTraceExporter({ - url: address, - credentials, - metadata: metadata, - timeoutMillis: 100, - }); + afterEach(function () { + shutdownHandle(); - const responseSpy = sinon.spy(); - const spans = [Object.assign({}, mockedReadableSpan)]; - collectorExporterWithTimeout.export(spans, responseSpy); + // clear context + serverTestContext.requests = []; + serverTestContext.serverResponseProvider = () => { + return { error: null, buffer: Buffer.from([]) }; + }; + }); - setTimeout(() => { - const result = responseSpy.args[0][0] as core.ExportResult; - assert.strictEqual(result.code, core.ExportResultCode.FAILED); - assert.match( - responseSpy.args[0][0].error.details, - /Deadline exceeded.*/ - ); - done(); - }, 300); - }); + it('successfully exports data', async () => { + // arrange + const tracerProvider = new BasicTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor( + new OTLPTraceExporter({ + url: 'http://localhost:1501', + }) + ), + ], }); - describe('export - with gzip compression', () => { - beforeEach(() => { - const credentials = useTLS - ? grpc.credentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - fs.readFileSync('./test/certs/client.key'), - fs.readFileSync('./test/certs/client.crt') - ) - : grpc.credentials.createInsecure(); - collectorExporter = new OTLPTraceExporter({ - url: address, - credentials, - metadata: metadata, - compression: CompressionAlgorithm.GZIP, - }); - - const provider = new BasicTracerProvider(); - provider.addSpanProcessor(new SimpleSpanProcessor(collectorExporter)); - }); - it('should successfully send the spans', done => { - const responseSpy = sinon.spy(); - const spans = [Object.assign({}, mockedReadableSpan)]; - collectorExporter.export(spans, responseSpy); - setTimeout(() => { - assert.ok( - typeof exportedData !== 'undefined', - 'resource' + " doesn't exist" - ); - const spans = exportedData.scopeSpans[0].spans; - const resource = exportedData.resource; - assert.ok(typeof spans !== 'undefined', 'spans do not exist'); - ensureExportedSpanIsCorrect(spans[0]); + // act + tracerProvider.getTracer('test-tracer').startSpan('test-span').end(); + await tracerProvider.shutdown(); - assert.ok(typeof resource !== 'undefined', "resource doesn't exist"); - ensureResourceIsCorrect(resource); - - ensureMetadataIsCorrect(reqMetadata, metadata); - - done(); - }, 500); - }); - }); + // assert + assert.strictEqual(serverTestContext.requests.length, 1); }); -}; - -testCollectorExporter({ useTLS: true }); -testCollectorExporter({ useTLS: false }); -testCollectorExporter({ metadata }); -// skip UDS tests on windows -process.platform !== 'win32' && testCollectorExporter({ address: udsAddr }); +}); diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.crt b/experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.crt deleted file mode 100644 index 08075df43b..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFozCCA4ugAwIBAgIUFk1cYj0iRoo2KlsL519xVhA3k/gwDQYJKoZIhvcNAQEL -BQAwYTELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQHDBFPcGVuVGVs -ZW1ldHJ5VGVzdDENMAsGA1UECgwEUm9vdDENMAsGA1UECwwEVGVzdDELMAkGA1UE -AwwCY2EwHhcNMjQwNjA4MTkxODUwWhcNMjUwNjA4MTkxODUwWjBhMQswCQYDVQQG -EwJDTDELMAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0w -CwYDVQQKDARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL0NqK2IeL6fBwdEyHewWEdpBjCf1QxH -S8ejgJTXcI8mUCijn/Q4Wox3ZNiVAad/y2ETYNRWExo4Z0LUq/KFRrdz4oBcxU0L -lifw5Kbpw4HZk6WzvGw1FhOaOOuCbaBRYJLnVy42AprYfmknvJ1b/iAoOLmYrlJU -JOhtSiOc3rZDq/A301TwLJ96vOVnoJohGf9aqYoP6EVEYSILpaPvRN5dN8HfPbrE -WFElLw1heMEivXajxQ4wEdH3j50lU50NcmUC81629Ca+Dia9yLN+leYjZWhelhv2 -le4k/pqC14CfZ91Xbbb/WfVTnzgSmXdjCDpXKzV6YdGKa3t3uYAcvx2RylMdeco3 -JK9y86dFb2pH/5rAjnKxyE7Hgvs2m9+kD8qP2GT2idcwb7/6jbQm7ivxY8LvGvN6 -G5MhhoSecLFcyLatDhGcsNFAV81GQVZQzj+8riz681zEl7zNmCQEQcyyFaHfYMBm -eD5lzeDUsKXJTwg/toT9ZTSQadjMy4KMFZqsoVpFdf/rpYM8HGuRRJiZwsLAGnNf -Azlua4ctFMJftS4TJrBzEEf6W9nGRdfslLKI56dssULfC5wwtDgYOg1PrQdYrw7m -xa8uBGBDpI5czZfnn8Z3MdMng7yP43f/SyplTk87VuZImGO9nDE9OKdcLj7W2UHH -pD6PfHMR3D4DAgMBAAGjUzBRMB0GA1UdDgQWBBQWSFyaQ5G8Zr9jvMcByugHxZ27 -BjAfBgNVHSMEGDAWgBQWSFyaQ5G8Zr9jvMcByugHxZ27BjAPBgNVHRMBAf8EBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBQxq6vBqs+Hoie4syroOc11JeFZYqKpWsA -BxTmjFSVs3RCVk1sf4VW6znX2G5CeBeQHhjnC9j7L45hjeWjbTtx6MT5lPUhRz6D -OU1e+mTl2uAiH+bFV9QGU6UtQmSMmWfSL11wtnGVJnkQyzGc0kTLiDLZpVTYs9eO -9upTexE+C8DsCd7uJ37zp9Od6Oh0MthfB98ab7Hkdts9cc7edZuYdWfWaqwkP6Vp -Icx4asgi8rdG4bdRU1EL87J1ReXheXf+jRLu/bWbNBWC/o6C21abK7DZHrpKv8xf -WeCNw3wczbdQrAQ96FgJwxloIvCjOZKWNI3vAAcB9aEYMTxcCO2iV0Q+ihIIAg7M -kTbkjoKbVWAFDbtdwSDvOVv+G/tfb8E7k5rZrBDvsKCbdaR238LIZITgZ8mtLvS7 -DeWlDL9GlFKxNkz64dgSSxpYTOdZKO2/Dty/0LydmlsSz85GeSYXIPlzAp5Zcg+x -Rs1/zkrWGlnaos9uQj7xKj8B0ltrDLkI0mrX5TFuc9/lbGaJMT3n5jMlcfMUOwgV -3jCo3i2plrxhLE22tK9M26a0NywkCrygRGiu2fgrunQgLTAbC4EyK1crZYoFXyhI -Tq//oOEjNgGF8yvDUDh2R2CndsH+w3+P+Z0IrM3xRCqSWFOEvyOJ7pBfiesUwSbI -nkERQqdGug== ------END CERTIFICATE----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.key b/experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.key deleted file mode 100644 index fa1f66e65f..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/ca.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -MKrxFkhV1ynkDphHDFz5xXbumyvCNw== ------END PRIVATE KEY----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.crt b/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.crt deleted file mode 100644 index 80f6c147e7..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJDTDEL -MAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0wCwYDVQQK -DARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTAeFw0yNDA2MDgxOTE4 -NTBaFw0yNTA2MDgxOTE4NTBaMGoxCzAJBgNVBAYTAkNMMQswCQYDVQQIDAJSTTEa -MBgGA1UEBwwRT3BlblRlbGVtZXRyeVRlc3QxDTALBgNVBAoMBFRlc3QxDzANBgNV -BAsMBkNsaWVudDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEAp8Llrbwz9XLaS2vrbo8vQB/Ks/kYE7Efh4x3hZFD1IVj -/7scNhBJJTsO3KGmfuKHcJqhCp7zgGeEaF/ciB2V3JmF1+PcmjOGZyWm8etioS3u -qfTkS376b6aZ0Vyl4J10gCYEaiacmYPxXbKTz3T1/iD9cNmATNyiJFiVRHP2ERTW -ROCUnVVguyrHCJVoXEACa7c7lVGfvjMJa56w3X+Ot/JtG1oobhynG33UO9/3S/mJ -qierFt7Q7bvxvn5paBktUO59qTEvDsTmL28Buj4EHjBEpEJvrr5IDGp7Z30/PXxW -Y62l6nifMEa/QX/ExxYtzHl6xLk4Ob38oA8i/rz4N6gJFnVq2dY/lip6L4aKfg9+ -inUkqydrG0188EJbQ8/vd0K4wfdeOITNGSL3IGBNABvJsX0sOx9qJxSTFdNz+PZs -p0reZVcT7AN1yYzYSamvtoI9Sg23ZCVnXTYiUUaLOAoqLxghKLE8sTu3AcNNAuZv -TDoQdMcvyYvvoyYpJNxeY9nPqDrGE5vMGMS3jYzvCtTGtFR0g23/LLC+2B5STjxx -ixMdmGERUz9c5uJjGWw/6oooK85KaQg2ly5QW36xnz84oAiw6ZI9Pw9AnnbC+Uix -+WKjxDn0ZcUtlutxQpn663gkaHnEbS9wfR7sTkMOO94Wb0cLnNdXvbkbgnQQ5oEC -AwEAAaNCMEAwHQYDVR0OBBYEFAJfQgFDvpBqDPTL1enA7y9DQv/UMB8GA1UdIwQY -MBaAFBZIXJpDkbxmv2O8xwHK6AfFnbsGMA0GCSqGSIb3DQEBCwUAA4ICAQA/e4xK -wNft7yqDiY3CXjnyaL2n4m6J736UoM0ijmkJlBYiv1CGmn+CE97CWSoIz3gxPWJs -fe8crVlQXflOm3fvWFzLXqK2026v/Ql1s6GcoG2YCBJLvJYtSrMRUecP48K1qkAA -m0b7nxM5nKx2pvMYMN+TqBEhjOCCAKgRqCZbhO+oN36n1LcGUpjWy2aCg9N3QBq/ -jlZrOC019eiB97HZOmM27hGKmLflIqLklDBG28ANBSk18Nh7AvH9PZ4QWAZBcAmB -RJ5/DncdFooHeQVJYyH28lkdvAruFA8YONWgP4rmwBLGBmaKKw3ZxkghV1XKDfCj -tAlxSLj+WutnKo1E5EML7PAVLhhTfHKx+C7JLjjonyJhr+vozdNSWaYWcaTHMN2l -s+Hadsi1AmLaYbL/9lVVV1+v+IiPlisMAm+T5PBxnxuiuwARBh3UCeFEkSWmpmA4 -EE9RQ3/JKhqGZRMyRg2tlodgOvSyAlXe+h6MbUF8IRgdvXfgrlGEDYVbLOqW6D8K -KNO+1hqNdXKC7am7nDH41JlU5CUxSQISOgRV92IJ3jeGMUF35lfYERlR4E9K2TrT -NXsvLp3Vf7nqfQNhSji3r/hsEEs/ni7fo1SbuaZjX1bGyAGZnMSQMJWyBCeucxsd -WRHY+ANKPbPWedOdaMn3uGBXndUHFMPu6cyk6w== ------END CERTIFICATE----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.csr b/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.csr deleted file mode 100644 index cee04b8bd6..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.csr +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIErzCCApcCAQAwajELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQH -DBFPcGVuVGVsZW1ldHJ5VGVzdDENMAsGA1UECgwEVGVzdDEPMA0GA1UECwwGQ2xp -ZW50MRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQCnwuWtvDP1ctpLa+tujy9AH8qz+RgTsR+HjHeFkUPUhWP/uxw2EEkl -Ow7coaZ+4odwmqEKnvOAZ4RoX9yIHZXcmYXX49yaM4ZnJabx62KhLe6p9ORLfvpv -ppnRXKXgnXSAJgRqJpyZg/FdspPPdPX+IP1w2YBM3KIkWJVEc/YRFNZE4JSdVWC7 -KscIlWhcQAJrtzuVUZ++MwlrnrDdf4638m0bWihuHKcbfdQ73/dL+YmqJ6sW3tDt -u/G+fmloGS1Q7n2pMS8OxOYvbwG6PgQeMESkQm+uvkgMantnfT89fFZjraXqeJ8w -Rr9Bf8THFi3MeXrEuTg5vfygDyL+vPg3qAkWdWrZ1j+WKnovhop+D36KdSSrJ2sb -TXzwQltDz+93QrjB9144hM0ZIvcgYE0AG8mxfSw7H2onFJMV03P49mynSt5lVxPs -A3XJjNhJqa+2gj1KDbdkJWddNiJRRos4CiovGCEosTyxO7cBw00C5m9MOhB0xy/J -i++jJikk3F5j2c+oOsYTm8wYxLeNjO8K1Ma0VHSDbf8ssL7YHlJOPHGLEx2YYRFT -P1zm4mMZbD/qiigrzkppCDaXLlBbfrGfPzigCLDpkj0/D0CedsL5SLH5YqPEOfRl -xS2W63FCmfrreCRoecRtL3B9HuxOQw473hZvRwuc11e9uRuCdBDmgQIDAQABoAAw -DQYJKoZIhvcNAQELBQADggIBAIfdI8Jw6v7jkdfyelY4NCq00cSryok0m4AqRcOx -9oYclU7+vYsqiUU7IWGaU4POfPTJEj4iRK76fR2uoTSxrggRuXlKw7BWHZAL2O2r -14/e6M4dZuGTGoEJX6K+N4OBA0BhB8NreQZ90uGXmD/tp0wutSHVizpiP+JStUhY -UzMt7jv/iRiCeOMBXecU7KgymCyfIcTxdYo2yXZUnnveBGIobFTWHB1N27rO5iao -69RJWIM16btOISmIRdy6kpTNuYRentmas+6oFZnrIN7EOjhZL1NnUsUkv+6URADS -Z+z+8Xac2M10GLNXJaqoOHXN/zks0LPX2ewEEUaeTVajs93urMGw+w9waeIU5YpE -Smp3KGehthb7Mpu7/CeaowVSekeOTR4xcAvCeLJ1pf+UJscXnCYSPkajzCxAXMzR -76Aruzoigk4DGVAYfPQuTdD+Ap397LUI8MbhoZQ6UEfvslubblOAoHzTqLxJ3WWt -/QhuDBQVWoHtIArkPP9kI6PFstwUw+HW5nctO7HQeCBQ7FKHlFEgCUSFedbZNy9A -daGXHM53IqDA2jpnkujLoGOxLQV3IsymoKGTyFOxP2AJMeAiKYG+xTUxHYCp4Z99 -cM/bPRQJKCYECb+ZQ13dLT9uBJdjIH2lve1UYXdyUC9Y8dNwV5Bvht5P87rDZChX -8IR+ ------END CERTIFICATE REQUEST----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.key b/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.key deleted file mode 100644 index 7681e0a5e7..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/client.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -oZy6rwoqrtLFacr41Jy5fq4MvMmkxwo= ------END PRIVATE KEY----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/regenerate.sh b/experimental/packages/exporter-trace-otlp-grpc/test/certs/regenerate.sh deleted file mode 100755 index cc052a4eff..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/regenerate.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env sh -# -# Regenerate certificates that are used for tests using TLS. -# Certs are generated with a one year expiry, so periodic regen is required. -# -# Usage: npm run maint:regenerate-test-certs - -rm ca.crt ca.key client.crt client.csr client.key server.crt server.csr server.key - -openssl genrsa -out ca.key 4096 -openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Root/OU=Test/CN=ca" - -openssl genrsa -out server.key 4096 -openssl req -new -key server.key -out server.csr -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Test/OU=Server/CN=localhost" -openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -openssl rsa -in server.key -out server.key - -openssl genrsa -out client.key 4096 -openssl req -new -key client.key -out client.csr -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Test/OU=Client/CN=localhost" -openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt -openssl rsa -in client.key -out client.key diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.crt b/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.crt deleted file mode 100644 index db941affc4..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJDTDEL -MAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0wCwYDVQQK -DARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTAeFw0yNDA2MDgxOTE4 -NTBaFw0yNTA2MDgxOTE4NTBaMGoxCzAJBgNVBAYTAkNMMQswCQYDVQQIDAJSTTEa -MBgGA1UEBwwRT3BlblRlbGVtZXRyeVRlc3QxDTALBgNVBAoMBFRlc3QxDzANBgNV -BAsMBlNlcnZlcjESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEAho9Odc3xj0yN5rlGePl4NG5FAhLeoG4zsPm8Wq/F8tYV -RGNuBv4FbfIwscWc21vN5vxIazlNe+wR9gs+JPXQqetJNBzoKyCnY5JWbUxhD69o -5CqYUifWBML2+9fJlfPDRyLjZ63PaXw1lM+25F46qLC5VYaXcR8+OUf7SIOJnS6n -1ZT1s5038tJdHw3pkep/hwaFuMAXEkAgemL/OOYJw4RSGAIGjXdsbDhTzIHovIwu -LmyAAOivF/FPdTFoMdy08au7t21GMQKSa/eoJ6luMfy67DsqJ5FRFc570ZTjejOq -VeLrxjjEGOHndZy550nIB50+ukmjGwdgEyQZ4Gie2nLckQMfgAPG6LsxixBoAg1B -fm2nRDeEA87+5VWPCBxAJ4WrD24HjxTS0P7gXnAnYC8CxBolw6eGhYE4zrAoC0GQ -tyU5iLdb3J9jbvV/OjHmNcMAbQrOtF+LC+O0YR6TScFyMUQy1DzCPNSjB6LA+bor -Qwu+ixyFlSAWTbd0CbBep1kzBKGbw4WP7oqU06FAibg5TDizZIey6peq3ia+0gaJ -08Y9BiJs0IClDP1zhTtXanjRsIfios9ucYzZiB2yfEKZhblBq8eq/z77ssL/4qDf -czbFm9wcq22Pvsn/sY60UqNkxgfZvUDzhDdXd5EBouUd67KEEW3v6AOy2AG/YYkC -AwEAAaNCMEAwHQYDVR0OBBYEFLqPQPHvLHjqNkPF9ol0NmzXvNqjMB8GA1UdIwQY -MBaAFBZIXJpDkbxmv2O8xwHK6AfFnbsGMA0GCSqGSIb3DQEBCwUAA4ICAQB/E9UK -vxQ6QSjjvwevEAwXcxkGbWNuFhOZGBey+IA9HrZvsvJJa65MMAcuarFbAu9NRVHK -B+xQcEoZaumTv1ehtp/wRcaPQeixnr9ikwrreHho9bWbcLNc1r9zGAV94Mswq8XY -Vu3ZNPYGrrI/m7GBu0piMtgK/PiVcn6CnzfQXrBJmP5zgrJNQjiMVbTXYrD3d521 -Pn0ptnvThWEFJhNlFHZ6arYZslU/rLAiWUiWkEiuTKAPiBNSNrQjqnljVBQA7Q/+ -CguQvSWt174tdMgeesvIHnDSvoC6Esk6P97uFi5fEafTE8fhhkOZeoRfKubj6Pwa -WqU4iRQMEU8NR8BMdHsTweCKL2Rs2mwJFP9fXBW2pKQpfortAIPwO7mW9WUSm92g -KoYG0rh/zkgYpH9KnnZa6yyauD1V2+lx/7y937puiMkUIqHeXVvTv0brDYmg21j/ -oRwO0BIVqwVItL1E9Ir+uas38bq6ij3Nylkn1cqUfuof+FXTj8BIHpvWwA3RRfzC -YZQQu3yd3p2GvSmjHtkP3cDdci8OyxXMcCedYWB0Xnw63XaG2li6RRzGfY0kfxrH -yRGbvxLgpTD3rgFTR2mTDz2Q6UODWriQ7cgmQ8OV+t61v92Di0OnXWVRUCNI+/P9 -xmNKrMU+gfM7amKc4N3oMKZgVtQexHNm7+Geng== ------END CERTIFICATE----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.csr b/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.csr deleted file mode 100644 index 6ac87e971b..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.csr +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIErzCCApcCAQAwajELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQH -DBFPcGVuVGVsZW1ldHJ5VGVzdDENMAsGA1UECgwEVGVzdDEPMA0GA1UECwwGU2Vy -dmVyMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQCGj051zfGPTI3muUZ4+Xg0bkUCEt6gbjOw+bxar8Xy1hVEY24G/gVt -8jCxxZzbW83m/EhrOU177BH2Cz4k9dCp60k0HOgrIKdjklZtTGEPr2jkKphSJ9YE -wvb718mV88NHIuNnrc9pfDWUz7bkXjqosLlVhpdxHz45R/tIg4mdLqfVlPWznTfy -0l0fDemR6n+HBoW4wBcSQCB6Yv845gnDhFIYAgaNd2xsOFPMgei8jC4ubIAA6K8X -8U91MWgx3LTxq7u3bUYxApJr96gnqW4x/LrsOyonkVEVznvRlON6M6pV4uvGOMQY -4ed1nLnnScgHnT66SaMbB2ATJBngaJ7actyRAx+AA8bouzGLEGgCDUF+badEN4QD -zv7lVY8IHEAnhasPbgePFNLQ/uBecCdgLwLEGiXDp4aFgTjOsCgLQZC3JTmIt1vc -n2Nu9X86MeY1wwBtCs60X4sL47RhHpNJwXIxRDLUPMI81KMHosD5uitDC76LHIWV -IBZNt3QJsF6nWTMEoZvDhY/uipTToUCJuDlMOLNkh7Lql6reJr7SBonTxj0GImzQ -gKUM/XOFO1dqeNGwh+Kiz25xjNmIHbJ8QpmFuUGrx6r/Pvuywv/ioN9zNsWb3Byr -bY++yf+xjrRSo2TGB9m9QPOEN1d3kQGi5R3rsoQRbe/oA7LYAb9hiQIDAQABoAAw -DQYJKoZIhvcNAQELBQADggIBAA6azFPc6LFR3wm8VkPXwQuAEMk8MwTWdSL/7NGf -tW1AwlXaTVfzD+Q+lDqFCIBeDz783jC8CUzlLwToncQFIKJINE4Df16uX/UDe4Ez -yyKeuyBKGiPPktmgtYKGnzQNXoJmJ4QjWUyZNxR1qojyj/niVc11WJbKjF1xOl9H -RAf0W6HGLwjov68ZcHeaShE7utMPLTxa13LQh66bUGkIW9mtu20y9YRjRf9j3Y3n -56qfRk0f8e/qqnG8EZr+KITm8W3abfDG2onozVYFTWZQ8dJhlYrKmBBoMjnpmG/7 -1DP59Ar+59ikpAtvtbdohhunlcMAcYKfZ/AIb4YcUdjbdMxPgfTEwMso4NL2p1at -B/B26xqjolUz92oqByYn6G+t6MH9O5jDFvgazg1vVRIDXScxWj26VS37JE5qs7o6 -L5mWCc9XJpMocEX3goeFPERvFs6Ar6RH+j+wQQrHB7mIMBoLbxMQz+ZM6xbkwkv9 -JpRTCbbDUNZSC7FzNRDhlj22x4FnDhNOIwsUu8jH+Hm6c4Nudj+uxowdPvjFkF32 -0o4INWpBLY01SNKhkHuzsbbPvSzx3wx7fB2zHZFvQ558bRBc8j8SrxGegOtEiBkF -tMTNObLaMHUAQ0y7izjcqFe2DBq8knc/kY9/QCkD5/0Zb/hYz8VnSvdmY2VrXcOn -bdO+ ------END CERTIFICATE REQUEST----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.key b/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.key deleted file mode 100644 index 66969c7f7c..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/certs/server.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -nwltH7Jc/hdFyg6QG3p7/28gMdP+oxE= ------END PRIVATE KEY----- diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/traceHelper.ts b/experimental/packages/exporter-trace-otlp-grpc/test/traceHelper.ts deleted file mode 100644 index 62157741a8..0000000000 --- a/experimental/packages/exporter-trace-otlp-grpc/test/traceHelper.ts +++ /dev/null @@ -1,328 +0,0 @@ -/* - * 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. - */ - -import { SpanStatusCode, TraceFlags } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; -import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import * as assert from 'assert'; -import * as grpc from '@grpc/grpc-js'; -import { VERSION } from '@opentelemetry/core'; -import { - IEvent, - IKeyValue, - ILink, - IResource, - ISpan, -} from '@opentelemetry/otlp-transformer'; - -const traceIdArr = [ - 31, 16, 8, 220, 142, 39, 14, 133, 196, 10, 13, 124, 57, 57, 178, 120, -]; -const spanIdArr = [94, 16, 114, 97, 246, 79, 165, 62]; -const parentIdArr = [120, 168, 145, 80, 152, 134, 67, 136]; - -export const mockedReadableSpan: ReadableSpan = { - name: 'documentFetch', - kind: 0, - spanContext: () => { - return { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '5e107261f64fa53e', - traceFlags: TraceFlags.SAMPLED, - }; - }, - parentSpanId: '78a8915098864388', - startTime: [1574120165, 429803070], - endTime: [1574120165, 438688070], - ended: true, - status: { code: SpanStatusCode.OK }, - attributes: { component: 'document-load' }, - links: [ - { - context: { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '78a8915098864388', - traceFlags: TraceFlags.SAMPLED, - }, - attributes: { component: 'document-load' }, - }, - ], - events: [ - { - name: 'fetchStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupEnd', - time: [1574120165, 429803070], - }, - { - name: 'connectStart', - time: [1574120165, 429803070], - }, - { - name: 'connectEnd', - time: [1574120165, 429803070], - }, - { - name: 'requestStart', - time: [1574120165, 435513070], - }, - { - name: 'responseStart', - time: [1574120165, 436923070], - }, - { - name: 'responseEnd', - time: [1574120165, 438688070], - }, - ], - duration: [0, 8885000], - resource: Resource.default().merge( - new Resource({ - service: 'ui', - version: 1, - cost: 112.12, - }) - ), - instrumentationLibrary: { name: 'default', version: '0.0.1' }, - droppedAttributesCount: 0, - droppedEventsCount: 0, - droppedLinksCount: 0, -}; - -export function ensureExportedEventsAreCorrect(events: IEvent[]) { - assert.deepStrictEqual( - events, - [ - { - attributes: [], - timeUnixNano: '1574120165429803070', - name: 'fetchStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803070', - name: 'domainLookupStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803070', - name: 'domainLookupEnd', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803070', - name: 'connectStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803070', - name: 'connectEnd', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165435513070', - name: 'requestStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165436923070', - name: 'responseStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165438688070', - name: 'responseEnd', - droppedAttributesCount: 0, - }, - ], - 'exported events are incorrect' - ); -} - -export function ensureExportedAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'component', - value: { - stringValue: 'document-load', - value: 'stringValue', - }, - }, - ], - 'exported attributes are incorrect' - ); -} - -export function ensureExportedLinksAreCorrect(attributes: ILink[]) { - assert.deepStrictEqual( - attributes, - [ - { - attributes: [ - { - key: 'component', - value: { - stringValue: 'document-load', - value: 'stringValue', - }, - }, - ], - traceId: Buffer.from(traceIdArr), - spanId: Buffer.from(parentIdArr), - traceState: '', - droppedAttributesCount: 0, - }, - ], - 'exported links are incorrect' - ); -} - -export function ensureExportedSpanIsCorrect(span: ISpan) { - if (span.attributes) { - ensureExportedAttributesAreCorrect(span.attributes); - } - if (span.events) { - ensureExportedEventsAreCorrect(span.events); - } - if (span.links) { - ensureExportedLinksAreCorrect(span.links); - } - assert.deepStrictEqual( - span.traceId, - Buffer.from(traceIdArr), - 'traceId is wrong' - ); - assert.deepStrictEqual( - span.spanId, - Buffer.from(spanIdArr), - 'spanId is wrong' - ); - assert.strictEqual(span.traceState, '', 'traceState is wrong'); - assert.deepStrictEqual( - span.parentSpanId, - Buffer.from(parentIdArr), - 'parentIdArr is wrong' - ); - assert.strictEqual(span.name, 'documentFetch', 'name is wrong'); - assert.strictEqual(span.kind, 'SPAN_KIND_INTERNAL', 'kind is wrong'); - assert.strictEqual( - span.startTimeUnixNano, - '1574120165429803070', - 'startTimeUnixNano is wrong' - ); - assert.strictEqual( - span.endTimeUnixNano, - '1574120165438688070', - 'endTimeUnixNano is wrong' - ); - assert.strictEqual( - span.droppedAttributesCount, - 0, - 'droppedAttributesCount is wrong' - ); - assert.strictEqual(span.droppedEventsCount, 0, 'droppedEventsCount is wrong'); - assert.strictEqual(span.droppedLinksCount, 0, 'droppedLinksCount is wrong'); - assert.deepStrictEqual( - span.status, - { - code: 'STATUS_CODE_OK', - message: '', - }, - 'status is wrong' - ); -} - -export function ensureResourceIsCorrect(resource: IResource) { - assert.deepStrictEqual(resource, { - attributes: [ - { - key: 'service.name', - value: { - stringValue: `unknown_service:${process.argv0}`, - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.language', - value: { - stringValue: 'nodejs', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.name', - value: { - stringValue: 'opentelemetry', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.version', - value: { - stringValue: VERSION, - value: 'stringValue', - }, - }, - { - key: 'service', - value: { - stringValue: 'ui', - value: 'stringValue', - }, - }, - { - key: 'version', - value: { - intValue: '1', - value: 'intValue', - }, - }, - { - key: 'cost', - value: { - doubleValue: 112.12, - value: 'doubleValue', - }, - }, - ], - droppedAttributesCount: 0, - }); -} - -export function ensureMetadataIsCorrect( - actual?: grpc.Metadata, - expected?: grpc.Metadata -) { - //ignore user agent - expected?.remove('user-agent'); - actual?.remove('user-agent'); - assert.deepStrictEqual(actual?.getMap(), expected?.getMap() ?? {}); -} diff --git a/experimental/packages/exporter-trace-otlp-grpc/test/utils.ts b/experimental/packages/exporter-trace-otlp-grpc/test/utils.ts new file mode 100644 index 0000000000..8dc6ae14e0 --- /dev/null +++ b/experimental/packages/exporter-trace-otlp-grpc/test/utils.ts @@ -0,0 +1,72 @@ +/* + * 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. + */ + +import { + Metadata, + Server, + ServerCredentials, + ServiceDefinition, +} from '@grpc/grpc-js'; + +export interface ExportedData { + request: Buffer; + metadata: Metadata; +} + +export interface ServerTestContext { + requests: ExportedData[]; + serverResponseProvider: () => { error: Error | null; buffer?: Buffer }; +} + +/** + * Starts a customizable server that saves all responses to context.responses + * Returns data as defined in context.ServerResponseProvider + * + * @return shutdown handle, needs to be called to ensure that mocha exits + * @param address address to bind to + * @param service service to start + * @param context context for storing responses and to define server behavior. + */ +export function startServer( + address: string, + service: ServiceDefinition, + context: ServerTestContext +): Promise<() => void> { + const server = new Server(); + server.addService(service, { + export: (data: ExportedData, callback: any) => { + context.requests.push(data); + const response = context.serverResponseProvider(); + callback(response.error, response.buffer); + }, + }); + + return new Promise<() => void>((resolve, reject) => { + server.bindAsync( + address, + ServerCredentials.createInsecure(), + (error, port) => { + server.start(); + if (error != null) { + reject(error); + } + resolve(() => { + server.forceShutdown(); + }); + } + ); + }); +} diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json index c81b4201b7..40760ce73c 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json @@ -18,8 +18,7 @@ "precompile": "cross-var lerna run version --scope $npm_package_name --include-dependencies", "prewatch": "npm run precompile", "peer-api-check": "node ../../../scripts/peer-api-check.js", - "align-api-deps": "node ../../../scripts/align-api-deps.js", - "maint:regenerate-test-certs": "cd test/certs && ./regenerate.sh" + "align-api-deps": "node ../../../scripts/align-api-deps.js" }, "keywords": [ "opentelemetry", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts index 833fa2ba7d..ac84344ba4 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts @@ -14,295 +14,83 @@ * limitations under the License. */ -import * as protoLoader from '@grpc/proto-loader'; -import { diag, DiagLogger } from '@opentelemetry/api'; -import * as assert from 'assert'; -import * as crypto from 'crypto'; -import * as fs from 'fs'; -import * as grpc from '@grpc/grpc-js'; -import * as path from 'path'; -import * as sinon from 'sinon'; import { OTLPMetricExporter } from '../src'; +import { ServerTestContext, startServer } from './utils'; +import * as assert from 'assert'; import { - collect, - ensureExportedCounterIsCorrect, - ensureExportedHistogramIsCorrect, - ensureExportedObservableGaugeIsCorrect, - ensureMetadataIsCorrect, - ensureResourceIsCorrect, - mockCounter, - mockHistogram, - mockObservableGauge, - setUp, - shutdown, -} from './metricsHelper'; -import { ResourceMetrics } from '@opentelemetry/sdk-metrics'; -import { - IExportMetricsServiceRequest, - IResourceMetrics, -} from '@opentelemetry/otlp-transformer'; -import { AggregationTemporalityPreference } from '@opentelemetry/exporter-metrics-otlp-http'; - -const metricsServiceProtoPath = - 'opentelemetry/proto/collector/metrics/v1/metrics_service.proto'; -const includeDirs = [path.resolve(__dirname, '../../otlp-transformer/protos')]; - -const httpAddr = 'https://localhost:1502'; -const udsAddr = 'unix:///tmp/otlp-metrics.sock'; - -type TestParams = { - address?: string; - useTLS?: boolean; - metadata?: grpc.Metadata; + MeterProvider, + PeriodicExportingMetricReader, +} from '@opentelemetry/sdk-metrics'; + +const testServiceDefinition = { + export: { + path: '/opentelemetry.proto.collector.metrics.v1.MetricsService/Export', + requestStream: false, + responseStream: false, + requestSerialize: (arg: Buffer) => { + return arg; + }, + requestDeserialize: (arg: Buffer) => { + return arg; + }, + responseSerialize: (arg: Buffer) => { + return arg; + }, + responseDeserialize: (arg: Buffer) => { + return arg; + }, + }, }; -const metadata = new grpc.Metadata(); -metadata.set('k', 'v'); - -const testOTLPMetricExporter = (params: TestParams) => { - const { address = httpAddr, useTLS, metadata } = params; - return describe(`OTLPMetricExporter - node ${ - useTLS ? 'with' : 'without' - } TLS, ${metadata ? 'with' : 'without'} metadata, target ${address}`, () => { - let collectorExporter: OTLPMetricExporter; - let server: grpc.Server; - let exportedData: IResourceMetrics[] | undefined; - let metrics: ResourceMetrics; - let reqMetadata: grpc.Metadata | undefined; - - before(done => { - server = new grpc.Server(); - protoLoader - .load(metricsServiceProtoPath, { - keepCase: false, - longs: String, - enums: String, - defaults: true, - oneofs: true, - includeDirs, - }) - .then((packageDefinition: protoLoader.PackageDefinition) => { - const packageObject: any = - grpc.loadPackageDefinition(packageDefinition); - server.addService( - packageObject.opentelemetry.proto.collector.metrics.v1 - .MetricsService.service, - { - Export: (data: { - request: IExportMetricsServiceRequest; - metadata: grpc.Metadata; - }) => { - try { - exportedData = data.request.resourceMetrics; - reqMetadata = data.metadata; - } catch (e) { - exportedData = undefined; - } - }, - } - ); - const credentials = useTLS - ? grpc.ServerCredentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - [ - { - cert_chain: fs.readFileSync('./test/certs/server.crt'), - private_key: fs.readFileSync('./test/certs/server.key'), - }, - ] - ) - : grpc.ServerCredentials.createInsecure(); - const serverAddr = new URL(address); - server.bindAsync( - serverAddr.protocol === 'https:' ? serverAddr.host : address, - credentials, - () => { - server.start(); - done(); - } - ); - }); - }); - - after(() => { - server.forceShutdown(); - }); - - beforeEach(async () => { - const credentials = useTLS - ? grpc.credentials.createSsl( - fs.readFileSync('./test/certs/ca.crt'), - fs.readFileSync('./test/certs/client.key'), - fs.readFileSync('./test/certs/client.crt') - ) - : grpc.credentials.createInsecure(); - collectorExporter = new OTLPMetricExporter({ - url: address, - credentials, - metadata: metadata, - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }); - - setUp(); - - const counter = mockCounter(); - mockObservableGauge(observableResult => { - observableResult.observe(3, {}); - observableResult.observe(6, {}); - }); - const histogram = mockHistogram(); - - counter.add(1); - histogram.record(7); - histogram.record(14); - - const { resourceMetrics, errors } = await collect(); - assert.strictEqual(errors.length, 0); - metrics = resourceMetrics; - }); - - afterEach(async () => { - await shutdown(); - exportedData = undefined; - reqMetadata = undefined; - sinon.restore(); - }); - - if (useTLS && crypto.X509Certificate) { - it('test certs are valid', () => { - const certPaths = [ - './test/certs/ca.crt', - './test/certs/client.crt', - './test/certs/server.crt', - ]; - certPaths.forEach(certPath => { - const cert = new crypto.X509Certificate(fs.readFileSync(certPath)); - const now = new Date(); - assert.ok( - new Date(cert.validTo) > now, - `TLS cert "${certPath}" is still valid: cert.validTo="${cert.validTo}" (if this fails use 'npm run maint:regenerate-test-certs')` - ); - }); - }); - } - - describe('instance', () => { - let warnStub: sinon.SinonStub; +/* + * NOTE: Tests here are not intended to test the underlying components directly. They are intended as a quick + * check if the correct components are used. Use the following packages to test details: + * - `@opentelemetry/oltp-exporter-base`: OTLP common exporter logic (handling of concurrent exports, ...) + * - `@opentelemetry/otlp-transformer`: Everything regarding serialization and transforming internal representations to OTLP + * - `@opentelemetry/otlp-grpc-exporter-base`: gRPC transport + */ +describe('OTLPMetricsExporter', function () { + let shutdownHandle: () => void | undefined; + const serverTestContext: ServerTestContext = { + requests: [], + serverResponseProvider: () => { + return { error: null, buffer: Buffer.from([]) }; + }, + }; + + beforeEach(async function () { + shutdownHandle = await startServer( + 'localhost:1502', + testServiceDefinition, + serverTestContext + ); + }); - beforeEach(() => { - // Need to stub/spy on the underlying logger as the "diag" instance is global - warnStub = sinon.stub(); - const nop = () => {}; - const diagLogger: DiagLogger = { - debug: nop, - error: nop, - info: nop, - verbose: nop, - warn: warnStub, - }; - diag.setLogger(diagLogger); - }); + afterEach(function () { + shutdownHandle(); - afterEach(() => { - diag.disable(); - }); + // clear context + serverTestContext.requests = []; + serverTestContext.serverResponseProvider = () => { + return { error: null, buffer: Buffer.from([]) }; + }; + }); - it('should warn about headers', () => { - collectorExporter = new OTLPMetricExporter({ - url: address, - headers: { - foo: 'bar', - }, - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }); - const args = warnStub.args[0]; - assert.strictEqual(args[0], 'Headers cannot be set when using grpc'); - }); - it('should warn about path in url', () => { - if (new URL(address).protocol === 'unix:') { - // Skip this test for UDS - return; - } - collectorExporter = new OTLPMetricExporter({ - url: `${address}/v1/metrics`, - temporalityPreference: AggregationTemporalityPreference.CUMULATIVE, - }); - const args = warnStub.args[0]; - assert.strictEqual( - args[0], - 'URL path should not be set when using grpc, the path part of the URL will be ignored.' - ); - }); + it('successfully exports data', async () => { + // arrange + const meterProvider = new MeterProvider({ + readers: [ + new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter({ url: 'http://localhost:1502' }), + }), + ], }); - describe('export', () => { - it('should export metrics', done => { - const responseSpy = sinon.spy(); - collectorExporter.export(metrics, responseSpy); - setTimeout(() => { - assert.ok( - typeof exportedData !== 'undefined', - 'resource does not exist' - ); - - assert.ok(exportedData, 'exportedData does not exist'); - - // The order of the metrics is not guaranteed. - const counterIndex = - exportedData[0].scopeMetrics[0].metrics.findIndex( - it => it.name === 'int-counter' - ); - const observableIndex = - exportedData[0].scopeMetrics[0].metrics.findIndex( - it => it.name === 'double-observable-gauge' - ); - const histogramIndex = - exportedData[0].scopeMetrics[0].metrics.findIndex( - it => it.name === 'int-histogram' - ); - - const resource = exportedData[0].resource; - const counter = exportedData[0].scopeMetrics[0].metrics[counterIndex]; - const observableGauge = - exportedData[0].scopeMetrics[0].metrics[observableIndex]; - const histogram = - exportedData[0].scopeMetrics[0].metrics[histogramIndex]; - ensureExportedCounterIsCorrect( - counter, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].endTime, - metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0] - .startTime - ); - ensureExportedObservableGaugeIsCorrect( - observableGauge, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0] - .startTime - ); - ensureExportedHistogramIsCorrect( - histogram, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .endTime, - metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0] - .startTime, - [0, 100], - ['0', '2', '0'] - ); - assert.ok(typeof resource !== 'undefined', "resource doesn't exist"); - ensureResourceIsCorrect(resource); + // act + meterProvider.getMeter('test-meter').createCounter('test-counter').add(1); + await meterProvider.forceFlush(); - ensureMetadataIsCorrect(reqMetadata, metadata); - - done(); - }, 500); - }); - }); + // assert + assert.strictEqual(serverTestContext.requests.length, 1); }); -}; - -testOTLPMetricExporter({ useTLS: true }); -testOTLPMetricExporter({ useTLS: false }); -testOTLPMetricExporter({ metadata }); -// skip UDS tests on windows -process.platform !== 'win32' && testOTLPMetricExporter({ address: udsAddr }); +}); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.crt b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.crt deleted file mode 100644 index 57decab97a..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFozCCA4ugAwIBAgIUB0Ij1wY1Y97b9f57vy3qxdY3eyMwDQYJKoZIhvcNAQEL -BQAwYTELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQHDBFPcGVuVGVs -ZW1ldHJ5VGVzdDENMAsGA1UECgwEUm9vdDENMAsGA1UECwwEVGVzdDELMAkGA1UE -AwwCY2EwHhcNMjQwNjA4MTkxODUwWhcNMjUwNjA4MTkxODUwWjBhMQswCQYDVQQG -EwJDTDELMAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0w -CwYDVQQKDARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL5sOaALnaMG5LvsyTRf77a0iQj5A1QP -N11tcWPQ5DvRtD6rKh3ISuKCPOX0BOeY0VdwqWP3dVP0qQgek48iGQw4Wl7SBQxO -vX3+cmaIy17ZHPu4RZIbjbGbS61OHU2iM4Ek1styhccWTv8dDN9V1LGr9mOnqVkv -4SZrmrGYAKyF5JLImafzAUUGttc5aeBpqWmjObk3GLFDWEvObkrI5sUqabJ3U4LS -KVPAX4sXoEPmlmnqIe6/5edmYNbeK0Kr8gZLDqJXThIDsgbRNIOTYWohPR3/JlDy -xnIH31GXygSWlGmDUxHynm7rvzY70Dm4G8JHI8F8hClRZ29XVYjyBMlS8qBHLa72 -mLU79WfsCbvdU/1AWg9g1FopSdf3G3z0Y4ZI8nTCMAbSJ0zQm3nIT9pNVPa9nk0e -iOo1462+TZ40X3/E+t7G7PkGgIHyYrL3o6bMsp3B2pKbJHIybwwGNxiuyRKvzIyc -Xcz7jbEzyL7rmcsxiNNuukk8ilpMexeCDu/Y+ndmvnNVWAsNf6HSbHlkip3Efi+p -6pK0pWgNprkoQvigiEeSqep5u2v/ogTRflLwih1UDB9krJ3dzoE6TB5kDrgvmn/s -Iohh/LWC7HipuQji1b+/ejFuQNy3mwDR2G09vrqk5PZXvfHRX+CCfTUZSFY8uEHr -TAhfgiKEPaf5AgMBAAGjUzBRMB0GA1UdDgQWBBQJ4qWJUnKN4XrWuGJ8TN4YIN7R -sjAfBgNVHSMEGDAWgBQJ4qWJUnKN4XrWuGJ8TN4YIN7RsjAPBgNVHRMBAf8EBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAYAu4AjPtl3Ji0n5u/p1mlp7DfmT4JpzZa -nczi7M1ae9ILx58i037zXVB9Fk7Yk5CG3buVqf7hzRT6KERKpTyUsc4wiy+vaAw9 -euGnp4qmG3mj4GRDAqDruOHFrv8Dfq541aF4N+V1OOdCbG3B3wXBQ9LkBpWCgHSk -M2h5jiLbbvwIbd4WoztLUOJtx89L+5TVM10fBTxekdJM/cVXOMzJgFzukc87sTAL -dSj3dz9J3TH6R24NzWijSch8Zh9ymAfSCKthBOl1mWIfd8h4ygUjnouGj5MGIIpl -q9ATAk0cka6VvjSzQ5OucZtrYkWIlLlqiUisYD7bJSn2zij4j3K2TQu+PTxM4/Oh -Xzz3W8LuAp+mdcgtPt4GvmtML2LtIJi6EgNRMkUzYtaERxubrgPuJOh1/10kp1ww -W8wdnweYid1I4nJXjGDhIvKk6ntzhBg6zV+5OSJf6o2RJKRsdxAz8o3wKbIXXGXh -u4B1TQJEivUTAcaZJX4iOJI2VhLaSP5lzdihAaLiPpSMk/cTTs5OYHCvb4XxkT5L -KH3UqSlvQBTQ2NfMfM5S4kLGtcCarOzcPYn++fjAOg24//TyZ2RAGbSCwjok/nKN -62MwO+Npr0sSkBGvYG2xzTS7R00L14cWOA9L26v7EqjZbpFd2B6vE0sUWLvVlbNc -wwZok4pFbw== ------END CERTIFICATE----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.key b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.key deleted file mode 100644 index b9f12f4f35..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/ca.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -+pFcbZ4RROHkC2Vg2eaQxFXb0mnv ------END PRIVATE KEY----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.crt b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.crt deleted file mode 100644 index b85e18dffa..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJDTDEL -MAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0wCwYDVQQK -DARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTAeFw0yNDA2MDgxOTE4 -NTFaFw0yNTA2MDgxOTE4NTFaMGoxCzAJBgNVBAYTAkNMMQswCQYDVQQIDAJSTTEa -MBgGA1UEBwwRT3BlblRlbGVtZXRyeVRlc3QxDTALBgNVBAoMBFRlc3QxDzANBgNV -BAsMBkNsaWVudDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEAjTQGK0mcpE04z7FRBz2mYOeoIh7SToyII0cR8+6T3YEK -R6SzZOLRXZ73/EucsQs0WxYEqXLgSlnxOBDQVttEwIi4VBxQnTc3T1itbZJeGnvf -t108ntOX5czbFJMuey/4D5WPRFBFJfSgqRPq4h5zu9rm1eUXOCB6l6B+OK5Ev5/8 -OLHAXY/QqUNFPLYggUMom7OhnWqA0Z1HR504J4GkeEsIwI/asEclo1gS6WrV6VBh -ZZFS7u//C52vw+jSZ+VAXLcgJ+9m6CPRdrhBh+yQ9hX2ZLb+TrUaPAsgtxrj6oB0 -uV62MYE7zNhNnrks6zwT8GDOu/rMSbII0bpF3L/M/fD57vpcbSu0t3TLgP2ZgV6L -pwKesQmcl3m7G6mvhx1R9M5xlKkcOjcoxCMmCttkzyh49x7bVYZEm+mFV+WPkgoe -CBg5eEbBxsVsIHkpU2GjnzIFMJlPpnwtDdgKKY/feQ88CLRlEF7+juJnjUS2tXmJ -2tcGteugIi459PHw3ZcFaXPsheEXUa8zPkyPCbFYXLpYLpXZN8wIwzxlgtw62Owk -ri6DA29F0rZy2N1Nf5R/mkVqN69ulZPxX9UYt5bCPYn4z2VKT46JpxsBTMV8TLbf -RO8xOfLj3PARCGWHV4KmBC9fakLQmVsMKjlcoWN3m2oVLNAORlYdmo+I81JryasC -AwEAAaNCMEAwHQYDVR0OBBYEFJUvzuLa8rgkuSbFYmQvj89kpe2QMB8GA1UdIwQY -MBaAFAnipYlSco3heta4YnxM3hgg3tGyMA0GCSqGSIb3DQEBCwUAA4ICAQCIMXBi -c0pTL0YAurUQUPtmU9GPLOxA2e0Uj4TjLY1hn4gUOHXcdxWsvL0B18z9AP74b/d6 -e57l944BDUXZsb0A9HqDR3HqVsCU9cEFmFEXcdx7kMCZzptRSWdUz/WRGChtjVIS -0YhX6JNmAR6luNGarzt1brCNQi5BBJEo3OhH/WcuKXcWnCIcNCL7dTybXbu2d5aO -d9wrAtZzmTtetlRAAia0jMmM/nAPYhN8cq5qkUdOsfnUyq09sfFh6JwmLAm9jT8T -HLFY+44BpMB+4H4PluY22nSKg2DzlerxYsbcnGklEAG4bglNlVTiJ+d7hi0Vn1sx -WxNzammg3b7RSEr7F2HXHztpx32QQO93igTHGXpb55yM2jt3eCivl3xynnPQMPhS -ZZPv61zVeVXaqjJHX12AMP41PEjFvBlIB0PqsORDZv4+X5MOchRf5VepM4hd01LW -9lTrX7oBSc0uzjDA5OyOZaqNDP06YfgezO0uF049cVbuGQ4NA+Iby6+nFILFgjcS -50p29zV2mP2KJ4dLnFf3/6CPNUSGrY7SXh2rcTefs7oxvlBu6Jt+b+2XYIWl9+Iz -Z/3dm5l5cEt9B4eogUb6HpFCfm3yba89wqUZK9o4O5WS/amx7MxPcQ4NPw5e+6EE -If4hv5PmFbUJtzKCwwvtjg1eWRW0th/Il3ixgQ== ------END CERTIFICATE----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.csr b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.csr deleted file mode 100644 index 190eb372ce..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.csr +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIErzCCApcCAQAwajELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQH -DBFPcGVuVGVsZW1ldHJ5VGVzdDENMAsGA1UECgwEVGVzdDEPMA0GA1UECwwGQ2xp -ZW50MRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQCNNAYrSZykTTjPsVEHPaZg56giHtJOjIgjRxHz7pPdgQpHpLNk4tFd -nvf8S5yxCzRbFgSpcuBKWfE4ENBW20TAiLhUHFCdNzdPWK1tkl4ae9+3XTye05fl -zNsUky57L/gPlY9EUEUl9KCpE+riHnO72ubV5Rc4IHqXoH44rkS/n/w4scBdj9Cp -Q0U8tiCBQyibs6GdaoDRnUdHnTgngaR4SwjAj9qwRyWjWBLpatXpUGFlkVLu7/8L -na/D6NJn5UBctyAn72boI9F2uEGH7JD2FfZktv5OtRo8CyC3GuPqgHS5XrYxgTvM -2E2euSzrPBPwYM67+sxJsgjRukXcv8z98Pnu+lxtK7S3dMuA/ZmBXounAp6xCZyX -ebsbqa+HHVH0znGUqRw6NyjEIyYK22TPKHj3HttVhkSb6YVX5Y+SCh4IGDl4RsHG -xWwgeSlTYaOfMgUwmU+mfC0N2Aopj995DzwItGUQXv6O4meNRLa1eYna1wa166Ai -Ljn08fDdlwVpc+yF4RdRrzM+TI8JsVhculguldk3zAjDPGWC3DrY7CSuLoMDb0XS -tnLY3U1/lH+aRWo3r26Vk/Ff1Ri3lsI9ifjPZUpPjomnGwFMxXxMtt9E7zE58uPc -8BEIZYdXgqYEL19qQtCZWwwqOVyhY3ebahUs0A5GVh2aj4jzUmvJqwIDAQABoAAw -DQYJKoZIhvcNAQELBQADggIBAGU0GhLOUGDMEnHNMebVO7hXewW2wc8pfMO/QwgV -/KyqDe7FxZgmfGIw6lN8QMowSL5ZJx7S/lu5lHg3W+OgbRmXm8KocelLkVNXekRW -qhgzPuWsrCBO+EoGvN5R3ZTW9uxWiI2XmfZmlBkWpl2ozPSjPL3muleU04nSza4k -rUio6Qn3nwPEjjVrfeglO3B15wwkiEzyvA5sUdnJ2rHz5VvPjCUNQiGVwqZLLDP9 -9XLfImregy4/NKBN/M5RwF1HihdPOH5yeqBW+CF3WPvjatwlVwpduGdlhe2Kymu0 -wpys3mv/Y6cE6G9UmbUB14axhFhZ1DqrDLl7RvOOeezH94tCM8bG97nYgfJvkq9t -Z1chPweaNugOBe/GAle0P8sxSMvVh2k3exeSCVyFguZKzmt6THciJ7ney3vkJP9w -cnw5armWglVALEljMSZf5pNqBzvnXGxs0mHlH4KuJl01+fH/GMt6P/XMJ9vBVje/ -IqHexFtd9s8U7k885jkVCu+hTtEaOU71m5kGbfHX15Xbo5JSlX5L89PeZb4Xr5ts -sSJ31F/RmNCbrNQbhXJ2Q/tS/ndxKU1F+rCXIxGMGRcJDjBJ7PB613URZN5Nl0TV -NU356jMzURcAhRfdmN6GhTjM0cPz365hqywkHWryv20xrdLgGuYjxkNsU8DeQ7/R -ZDny ------END CERTIFICATE REQUEST----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.key b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.key deleted file mode 100644 index 4ea34697a3..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/client.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -rUDy/i3nw+6XSyDDV2kEJRodu+fA8Q== ------END PRIVATE KEY----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/regenerate.sh b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/regenerate.sh deleted file mode 100755 index cc052a4eff..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/regenerate.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env sh -# -# Regenerate certificates that are used for tests using TLS. -# Certs are generated with a one year expiry, so periodic regen is required. -# -# Usage: npm run maint:regenerate-test-certs - -rm ca.crt ca.key client.crt client.csr client.key server.crt server.csr server.key - -openssl genrsa -out ca.key 4096 -openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Root/OU=Test/CN=ca" - -openssl genrsa -out server.key 4096 -openssl req -new -key server.key -out server.csr -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Test/OU=Server/CN=localhost" -openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -openssl rsa -in server.key -out server.key - -openssl genrsa -out client.key 4096 -openssl req -new -key client.key -out client.csr -subj "/C=CL/ST=RM/L=OpenTelemetryTest/O=Test/OU=Client/CN=localhost" -openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt -openssl rsa -in client.key -out client.key diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.crt b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.crt deleted file mode 100644 index e4e85c42df..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJDTDEL -MAkGA1UECAwCUk0xGjAYBgNVBAcMEU9wZW5UZWxlbWV0cnlUZXN0MQ0wCwYDVQQK -DARSb290MQ0wCwYDVQQLDARUZXN0MQswCQYDVQQDDAJjYTAeFw0yNDA2MDgxOTE4 -NTFaFw0yNTA2MDgxOTE4NTFaMGoxCzAJBgNVBAYTAkNMMQswCQYDVQQIDAJSTTEa -MBgGA1UEBwwRT3BlblRlbGVtZXRyeVRlc3QxDTALBgNVBAoMBFRlc3QxDzANBgNV -BAsMBlNlcnZlcjESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEAsrgR40g2ius4P7h5mO6/2r9uD903m672EHRkYXKKKViV -wMS/7kgNo8vbenmmO0Ra3Rk3J80M4HhWJsI5bWvjLtbLkG6CkiK0yCpSbsK+F13B -oDvCeVEYaLz2IV2e/61l5y73Q5s6Iu2OTckIvGZr/jsCBJ+9457uuMd4Mvzi1jLo -PmVYJZYG/8I2dIjrtxqm/gAiBjbrZ5Nmm702GArvm85VWL8o3b0C+9YXI8PHHGT9 -CYqBjKobDdM0lrZdBiy5JEwSI1L0MCGzcmEVCJIuHe9b66GUVWrAsvOKrBMkziSm -BKjvAzDIsiRIS0Z2jiXpRwUhjpAphJDtsePGXvbSzvt4mUNUvSsnS4ImKURkDLVB -BndzJMUX0/fJG2fh0cVmT0V6+otqpPTrf89i3dsSG9gBHVlp4u1p7krQ8KgZ0Fpw -wbo+p41KrChQ8iwE4eEgcI2joQrC2ccpQzxyn/quH604gadtBTEw+NrCu8NB5hso -hMGJV1jMJ0wENkRY0WjD51y87ieUhMQwUnM7Yi7CLq3SJA9N0KHbtg4U+42d63pH -HmMwUw2cG7tVKJR/quZxwibqkA7mkUYp/pyILt6m1IOAwK5SgomMGCsstXSFXisR -fCCNTEkQMvuylC3TsV6THPb6zJvhntIkLGbSFzxfLeGP5x0KhqWt76W//BnKfXsC -AwEAAaNCMEAwHQYDVR0OBBYEFLNHcwOHiVPwk8X3kZnMBz/rezOiMB8GA1UdIwQY -MBaAFAnipYlSco3heta4YnxM3hgg3tGyMA0GCSqGSIb3DQEBCwUAA4ICAQCqWBJL -+hOWGK4IUXXUodvHcctiXU6ktUP4ki8Ml0c1UWnRZECuBU/tlCiasgQlGc0eld/H -q9h0zK3gUDoLXYb6uPuFUmhtJYY6ydIBR7XqCCTgBMfJ6gwxH2ybC/BTyp1cE9o1 -hMkaD+/r3JRGX0G5FPYRhfF5JDSGVAiWWFD1udPH4+UidjFAXTyi0bn5BsY5Aze9 -xVWvOMYNLxiaZEklfTGGgY7xbTECow+XR7ThguzL1Wg9GBJEAYWvfbdb+RKB5bqs -ggKRTg21VWapTeSbfnjhvyrRN2FamGxeW1lqb8Ts1yyKiqtkj/cy2tIheEGAPt/a -wWgFKAuSRN0YtSW8D8oOmY+4+ULDl0um/dhJ31/nF0qOgopHUozJXDj71GsNrokh -3TmYYnuyZdAAyVFwNffXWingfqNOs2ozf/efBTLLAb094QOnpdit9pYPqE5ar72Y -JdGACna1Mxz5PDa6Z7eQB7s7h/Q47JFXIOI4TdguKGYiDT0XXfEq6lKbvVYkheQ/ -kutiMFQQCwwv/LxRhjTeeFEnASyWgRhhvuTg0ndOqpCtgUJ8mEZ4c9RB+QA7XeOe -FKx9QMLJRAOMNE2WoSPhgaJrf6glSKOvR6CuH/v1ekE3pJpVZGk+3GOs3H8k92Vv -pV9S89yNX95tLzlOR/nKWLrX6n27fjE2BBXeBg== ------END CERTIFICATE----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.csr b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.csr deleted file mode 100644 index 642fbae3c4..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.csr +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIErzCCApcCAQAwajELMAkGA1UEBhMCQ0wxCzAJBgNVBAgMAlJNMRowGAYDVQQH -DBFPcGVuVGVsZW1ldHJ5VGVzdDENMAsGA1UECgwEVGVzdDEPMA0GA1UECwwGU2Vy -dmVyMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQCyuBHjSDaK6zg/uHmY7r/av24P3TebrvYQdGRhcoopWJXAxL/uSA2j -y9t6eaY7RFrdGTcnzQzgeFYmwjlta+Mu1suQboKSIrTIKlJuwr4XXcGgO8J5URho -vPYhXZ7/rWXnLvdDmzoi7Y5NyQi8Zmv+OwIEn73jnu64x3gy/OLWMug+ZVgllgb/ -wjZ0iOu3Gqb+ACIGNutnk2abvTYYCu+bzlVYvyjdvQL71hcjw8ccZP0JioGMqhsN -0zSWtl0GLLkkTBIjUvQwIbNyYRUIki4d71vroZRVasCy84qsEyTOJKYEqO8DMMiy -JEhLRnaOJelHBSGOkCmEkO2x48Ze9tLO+3iZQ1S9KydLgiYpRGQMtUEGd3MkxRfT -98kbZ+HRxWZPRXr6i2qk9Ot/z2Ld2xIb2AEdWWni7WnuStDwqBnQWnDBuj6njUqs -KFDyLATh4SBwjaOhCsLZxylDPHKf+q4frTiBp20FMTD42sK7w0HmGyiEwYlXWMwn -TAQ2RFjRaMPnXLzuJ5SExDBScztiLsIurdIkD03Qodu2DhT7jZ3rekceYzBTDZwb -u1UolH+q5nHCJuqQDuaRRin+nIgu3qbUg4DArlKCiYwYKyy1dIVeKxF8II1MSRAy -+7KULdOxXpMc9vrMm+Ge0iQsZtIXPF8t4Y/nHQqGpa3vpb/8Gcp9ewIDAQABoAAw -DQYJKoZIhvcNAQELBQADggIBAAvxaoCgCOM5mVOAFeLQoKGTORIWoT73yKeebLu8 -Ie26lrOZyItFneYCnyFocYb20mriC+C30lUgNM66mHWLW0QSDPhI0VeBMDRHYPMo -S5EWkQNy0VQ1HZV/DITXqEBld0WdmBl71D7gOlZvDHHnrb5emOKOVP/7poitywC1 -NA/Ry0TJYAz1z9uu5GLmMNJwfkRAPVYJnzMTMQ6G8z2tUKTTDKbJvkkJ1tmjBToD -/8JeXmxH0a0NuwC7QLDzR1Jl4XWj3uIAHUtcsHMFjOc3nAin3L7FGD7CaXTyz/Hw -J7GkeIMGSYs+i+09l9dMLSrlIsh2sphV768dKajqA11C6nGOeEkJFziY+l9KNy9B -MkW74Vj2SyN0l8Cn2X282UakAxQ0kCwpBQYSO+M6q2gVLhwTwmDUCpfuo03dOGrn -kHPDYQUahTLfKNEe6seXHomGUxTpMnr5p3ftMOrc4uCWY1DkhEviw9Jea666gG/e -5yiYcN4vSmru4GpmOV5N28GNC8oAgm7rPpPgXeiVET+p3wms8cZ8/Htpkxn2nTcc -3tBvAYt8qql9Wt/2R4ewo39bzg4dPzl9AUWeQRpA6O0n6ZhtHhCzDSik5Tam9fh8 -lxTldG69Enm4+amCLja/YYRmaEE9KYM3jxSi6k+Xh2L+vI8WlwbkZKnYs9suDW22 -eoJ+ ------END CERTIFICATE REQUEST----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.key b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.key deleted file mode 100644 index 1801be4022..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/certs/server.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -HvjeIanEQir29p2epOg8Epxewjc9 ------END PRIVATE KEY----- diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts deleted file mode 100644 index 7c9fbfd99c..0000000000 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts +++ /dev/null @@ -1,277 +0,0 @@ -/* - * 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. - */ - -import { - Counter, - Histogram, - HrTime, - ObservableGauge, - ObservableResult, - ValueType, -} from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; -import * as assert from 'assert'; -import * as grpc from '@grpc/grpc-js'; -import { VERSION } from '@opentelemetry/core'; -import { - ExplicitBucketHistogramAggregation, - MeterProvider, - MetricReader, - View, -} from '@opentelemetry/sdk-metrics'; -import { - encodeAsString, - IKeyValue, - IMetric, - IResource, -} from '@opentelemetry/otlp-transformer'; - -class TestMetricReader extends MetricReader { - protected onForceFlush(): Promise { - return Promise.resolve(undefined); - } - - protected onShutdown(): Promise { - return Promise.resolve(undefined); - } -} - -const testResource = new Resource({ - service: 'ui', - version: 1, - cost: 112.12, -}); - -let reader = new TestMetricReader(); -let meterProvider = new MeterProvider({ - resource: testResource, - readers: [reader], -}); - -let meter = meterProvider.getMeter('default', '0.0.1'); - -export async function collect() { - return (await reader.collect())!; -} - -export function setUp() { - reader = new TestMetricReader(); - meterProvider = new MeterProvider({ - resource: testResource, - views: [ - new View({ - aggregation: new ExplicitBucketHistogramAggregation([0, 100]), - instrumentName: 'int-histogram', - }), - ], - readers: [reader], - }); - meter = meterProvider.getMeter('default', '0.0.1'); -} - -export async function shutdown() { - await meterProvider.shutdown(); -} - -export function mockCounter(): Counter { - const name = 'int-counter'; - return meter.createCounter(name, { - description: 'sample counter description', - valueType: ValueType.INT, - }); -} - -export function mockObservableGauge( - callback: (observableResult: ObservableResult) => void -): ObservableGauge { - const name = 'double-observable-gauge'; - const observableGauge = meter.createObservableGauge(name, { - description: 'sample observable gauge description', - valueType: ValueType.DOUBLE, - }); - observableGauge.addCallback(callback); - - return observableGauge; -} - -export function mockHistogram(): Histogram { - return meter.createHistogram('int-histogram', { - description: 'sample histogram description', - valueType: ValueType.INT, - }); -} - -export function ensureExportedAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'component', - value: { - stringValue: 'document-load', - value: 'stringValue', - }, - }, - ], - 'exported attributes are incorrect' - ); -} - -export function ensureExportedCounterIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime -) { - assert.strictEqual(metric.name, 'int-counter'); - assert.strictEqual(metric.description, 'sample counter description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.sum?.dataPoints.length, 1); - assert.strictEqual( - metric.sum?.aggregationTemporality, - 'AGGREGATION_TEMPORALITY_CUMULATIVE' - ); - assert.strictEqual(metric.sum?.isMonotonic, true); - - const [dp] = metric.sum.dataPoints; - - assert.deepStrictEqual(dp.attributes, []); - assert.deepStrictEqual(dp.exemplars, []); - assert.strictEqual(dp.asInt, '1'); - assert.strictEqual(dp.flags, 0); - - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano as string, encodeAsString(time)); -} - -export function ensureExportedObservableGaugeIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime -) { - assert.strictEqual(metric.name, 'double-observable-gauge'); - assert.strictEqual(metric.description, 'sample observable gauge description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.gauge?.dataPoints.length, 1); - - const [dp] = metric.gauge.dataPoints; - - assert.deepStrictEqual(dp.attributes, []); - assert.deepStrictEqual(dp.exemplars, []); - assert.strictEqual(dp.asDouble, 6); - assert.strictEqual(dp.flags, 0); - - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); -} - -export function ensureExportedHistogramIsCorrect( - metric: IMetric, - time: HrTime, - startTime: HrTime, - explicitBounds: number[] = [Infinity], - bucketCounts: string[] = ['2', '0'] -) { - assert.strictEqual(metric.name, 'int-histogram'); - assert.strictEqual(metric.description, 'sample histogram description'); - assert.strictEqual(metric.unit, ''); - assert.strictEqual(metric.histogram?.dataPoints.length, 1); - assert.strictEqual( - metric.histogram?.aggregationTemporality, - 'AGGREGATION_TEMPORALITY_CUMULATIVE' - ); - - const [dp] = metric.histogram.dataPoints; - - assert.deepStrictEqual(dp.attributes, []); - assert.deepStrictEqual(dp.exemplars, []); - assert.strictEqual(dp.flags, 0); - assert.strictEqual(dp.sum, 21); - assert.strictEqual(dp.count, '2'); - assert.strictEqual(dp.min, 7); - assert.strictEqual(dp.max, 14); - - assert.deepStrictEqual(dp.startTimeUnixNano, encodeAsString(startTime)); - assert.deepStrictEqual(dp.timeUnixNano, encodeAsString(time)); - assert.deepStrictEqual(dp.bucketCounts, bucketCounts); - assert.deepStrictEqual(dp.explicitBounds, explicitBounds); -} - -export function ensureResourceIsCorrect(resource: IResource) { - assert.deepStrictEqual(resource, { - attributes: [ - { - key: 'service.name', - value: { - stringValue: `unknown_service:${process.argv0}`, - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.language', - value: { - stringValue: 'nodejs', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.name', - value: { - stringValue: 'opentelemetry', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.version', - value: { - stringValue: VERSION, - value: 'stringValue', - }, - }, - { - key: 'service', - value: { - stringValue: 'ui', - value: 'stringValue', - }, - }, - { - key: 'version', - value: { - intValue: '1', - value: 'intValue', - }, - }, - { - key: 'cost', - value: { - doubleValue: 112.12, - value: 'doubleValue', - }, - }, - ], - droppedAttributesCount: 0, - }); -} - -export function ensureMetadataIsCorrect( - actual?: grpc.Metadata, - expected?: grpc.Metadata -) { - //ignore user agent - expected?.remove('user-agent'); - actual?.remove('user-agent'); - assert.deepStrictEqual(actual?.getMap(), expected?.getMap() ?? {}); -} diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/utils.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/utils.ts new file mode 100644 index 0000000000..8dc6ae14e0 --- /dev/null +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/utils.ts @@ -0,0 +1,72 @@ +/* + * 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. + */ + +import { + Metadata, + Server, + ServerCredentials, + ServiceDefinition, +} from '@grpc/grpc-js'; + +export interface ExportedData { + request: Buffer; + metadata: Metadata; +} + +export interface ServerTestContext { + requests: ExportedData[]; + serverResponseProvider: () => { error: Error | null; buffer?: Buffer }; +} + +/** + * Starts a customizable server that saves all responses to context.responses + * Returns data as defined in context.ServerResponseProvider + * + * @return shutdown handle, needs to be called to ensure that mocha exits + * @param address address to bind to + * @param service service to start + * @param context context for storing responses and to define server behavior. + */ +export function startServer( + address: string, + service: ServiceDefinition, + context: ServerTestContext +): Promise<() => void> { + const server = new Server(); + server.addService(service, { + export: (data: ExportedData, callback: any) => { + context.requests.push(data); + const response = context.serverResponseProvider(); + callback(response.error, response.buffer); + }, + }); + + return new Promise<() => void>((resolve, reject) => { + server.bindAsync( + address, + ServerCredentials.createInsecure(), + (error, port) => { + server.start(); + if (error != null) { + reject(error); + } + resolve(() => { + server.forceShutdown(); + }); + } + ); + }); +} diff --git a/experimental/packages/otlp-grpc-exporter-base/test/grpc-exporter-transport.test.ts b/experimental/packages/otlp-grpc-exporter-base/test/grpc-exporter-transport.test.ts index c74b401342..69b906e895 100644 --- a/experimental/packages/otlp-grpc-exporter-base/test/grpc-exporter-transport.test.ts +++ b/experimental/packages/otlp-grpc-exporter-base/test/grpc-exporter-transport.test.ts @@ -111,6 +111,40 @@ function startServer(context: ServerTestContext): Promise<() => void> { }); } +/** + * Starts a customizable server that saves all responses to context.responses + * Returns data as defined in context.ServerResponseProvider + * + * @return shutdown handle, needs to be called to ensure that mocha exits + * @param context context for storing responses and to define server behavior. + */ +function startUdsServer(context: ServerTestContext): Promise<() => void> { + const server = new Server(); + server.addService(testServiceDefinition, { + export: (data: ExportedData, callback: any) => { + context.requests.push(data); + const response = context.serverResponseProvider(); + callback(response.error, response.buffer); + }, + }); + + return new Promise<() => void>((resolve, reject) => { + server.bindAsync( + 'unix:///tmp/otlp-test.sock', + ServerCredentials.createInsecure(), + (error, port) => { + server.start(); + if (error != null) { + reject(error); + } + resolve(() => { + server.forceShutdown(); + }); + } + ); + }); +} + describe('GrpcExporterTransport', function () { describe('utilities', function () { describe('createEmptyMetadata', function () { @@ -199,149 +233,202 @@ describe('GrpcExporterTransport', function () { }); }); describe('send', function () { - let shutdownHandle: () => void | undefined; - const serverTestContext: ServerTestContext = { - requests: [], - serverResponseProvider: () => { - return { error: null, buffer: Buffer.from([]) }; - }, - }; + describe('http2', function () { + let shutdownHandle: () => void | undefined; + const serverTestContext: ServerTestContext = { + requests: [], + serverResponseProvider: () => { + return { error: null, buffer: Buffer.from([]) }; + }, + }; - beforeEach(async function () { - shutdownHandle = await startServer(serverTestContext); - }); + beforeEach(async function () { + shutdownHandle = await startServer(serverTestContext); + }); - afterEach(function () { - shutdownHandle(); + afterEach(function () { + shutdownHandle(); - // clear context - serverTestContext.requests = []; - serverTestContext.serverResponseProvider = () => { - return { error: null, buffer: Buffer.from([]) }; - }; - }); + // clear context + serverTestContext.requests = []; + serverTestContext.serverResponseProvider = () => { + return { error: null, buffer: Buffer.from([]) }; + }; + }); - it('sends data', async function () { - const transport = createOtlpGrpcExporterTransport(simpleClientConfig); + it('sends data', async function () { + const transport = createOtlpGrpcExporterTransport(simpleClientConfig); - const result = (await transport.send( - Buffer.from([1, 2, 3]), - timeoutMillis - )) as ExportResponseSuccess; - - assert.strictEqual(result.status, 'success'); - assert.deepEqual(result.data, Buffer.from([])); - assert.strictEqual(serverTestContext.requests.length, 1); - assert.deepEqual( - serverTestContext.requests[0].request, - Buffer.from([1, 2, 3]) - ); - assert.deepEqual( - serverTestContext.requests[0].metadata.get('foo'), - simpleClientConfig.metadata().get('foo') - ); - }); + const result = (await transport.send( + Buffer.from([1, 2, 3]), + timeoutMillis + )) as ExportResponseSuccess; - it('forwards response', async function () { - const expectedResponseData = Buffer.from([1, 2, 3]); - serverTestContext.serverResponseProvider = () => { - return { - buffer: expectedResponseData, - error: null, + assert.strictEqual(result.status, 'success'); + assert.deepEqual(result.data, Buffer.from([])); + assert.strictEqual(serverTestContext.requests.length, 1); + assert.deepEqual( + serverTestContext.requests[0].request, + Buffer.from([1, 2, 3]) + ); + assert.deepEqual( + serverTestContext.requests[0].metadata.get('foo'), + simpleClientConfig.metadata().get('foo') + ); + }); + + it('forwards response', async function () { + const expectedResponseData = Buffer.from([1, 2, 3]); + serverTestContext.serverResponseProvider = () => { + return { + buffer: expectedResponseData, + error: null, + }; }; - }; - const transport = createOtlpGrpcExporterTransport(simpleClientConfig); + const transport = createOtlpGrpcExporterTransport(simpleClientConfig); - const result = (await transport.send( - Buffer.from([]), - timeoutMillis - )) as ExportResponseSuccess; + const result = (await transport.send( + Buffer.from([]), + timeoutMillis + )) as ExportResponseSuccess; - assert.strictEqual(result.status, 'success'); - assert.deepEqual(result.data, expectedResponseData); - }); + assert.strictEqual(result.status, 'success'); + assert.deepEqual(result.data, expectedResponseData); + }); - it('forwards handled server error as failure', async function () { - serverTestContext.serverResponseProvider = () => { - return { - buffer: Buffer.from([]), - error: new Error('handled server error'), + it('forwards handled server error as failure', async function () { + serverTestContext.serverResponseProvider = () => { + return { + buffer: Buffer.from([]), + error: new Error('handled server error'), + }; }; - }; - const transport = createOtlpGrpcExporterTransport(simpleClientConfig); + const transport = createOtlpGrpcExporterTransport(simpleClientConfig); - const result = (await transport.send( - Buffer.from([]), - timeoutMillis - )) as ExportResponseFailure; + const result = (await transport.send( + Buffer.from([]), + timeoutMillis + )) as ExportResponseFailure; - assert.strictEqual(result.status, 'failure'); - assert.ok(types.isNativeError(result.error)); - }); + assert.strictEqual(result.status, 'failure'); + assert.ok(types.isNativeError(result.error)); + }); - it('forwards unhandled server error as failure', async function () { - serverTestContext.serverResponseProvider = () => { - throw new Error('unhandled server error'); - }; - const transport = createOtlpGrpcExporterTransport(simpleClientConfig); + it('forwards unhandled server error as failure', async function () { + serverTestContext.serverResponseProvider = () => { + throw new Error('unhandled server error'); + }; + const transport = createOtlpGrpcExporterTransport(simpleClientConfig); + + const result = (await transport.send( + Buffer.from([]), + timeoutMillis + )) as ExportResponseFailure; + assert.strictEqual(result.status, 'failure'); + assert.ok(types.isNativeError(result.error)); + }); - const result = (await transport.send( - Buffer.from([]), - timeoutMillis - )) as ExportResponseFailure; - assert.strictEqual(result.status, 'failure'); - assert.ok(types.isNativeError(result.error)); - }); + it('forwards metadataProvider error as failure', async function () { + const expectedError = new Error('metadata provider error'); + const config = Object.assign({}, simpleClientConfig); + config.metadata = () => { + throw expectedError; + }; - it('forwards metadataProvider error as failure', async function () { - const expectedError = new Error('metadata provider error'); - const config = Object.assign({}, simpleClientConfig); - config.metadata = () => { - throw expectedError; - }; + const transport = createOtlpGrpcExporterTransport(config); - const transport = createOtlpGrpcExporterTransport(config); + const result = (await transport.send( + Buffer.from([]), + timeoutMillis + )) as ExportResponseFailure; + assert.strictEqual(result.status, 'failure'); + assert.strictEqual(result.error, expectedError); + }); - const result = (await transport.send( - Buffer.from([]), - timeoutMillis - )) as ExportResponseFailure; - assert.strictEqual(result.status, 'failure'); - assert.strictEqual(result.error, expectedError); - }); + it('forwards metadataProvider returns null value as failure', async function () { + const expectedError = new Error('metadata was null'); + const config = Object.assign({}, simpleClientConfig); + config.metadata = () => { + return null as unknown as Metadata; + }; - it('forwards metadataProvider returns null value as failure', async function () { - const expectedError = new Error('metadata was null'); - const config = Object.assign({}, simpleClientConfig); - config.metadata = () => { - return null as unknown as Metadata; - }; + const transport = createOtlpGrpcExporterTransport(config); - const transport = createOtlpGrpcExporterTransport(config); + const result = (await transport.send( + Buffer.from([]), + timeoutMillis + )) as ExportResponseFailure; + assert.strictEqual(result.status, 'failure'); + assert.deepEqual(result.error, expectedError); + }); - const result = (await transport.send( - Buffer.from([]), - timeoutMillis - )) as ExportResponseFailure; - assert.strictEqual(result.status, 'failure'); - assert.deepEqual(result.error, expectedError); - }); + it('forwards credential error as failure', async function () { + const expectedError = new Error('credential provider error'); + const config = Object.assign({}, simpleClientConfig); + config.credentials = () => { + throw expectedError; + }; + + const transport = createOtlpGrpcExporterTransport(config); - it('forwards credential error as failure', async function () { - const expectedError = new Error('credential provider error'); - const config = Object.assign({}, simpleClientConfig); - config.credentials = () => { - throw expectedError; + const result = (await transport.send( + Buffer.from([]), + timeoutMillis + )) as ExportResponseFailure; + assert.strictEqual(result.status, 'failure'); + assert.strictEqual(result.error, expectedError); + }); + }); + describe('uds', function () { + let shutdownHandle: (() => void) | undefined; + const serverTestContext: ServerTestContext = { + requests: [], + serverResponseProvider: () => { + return { error: null, buffer: Buffer.from([]) }; + }, }; - const transport = createOtlpGrpcExporterTransport(config); + beforeEach(async function () { + // skip uds tests on windows + if (process.platform === 'win32') { + this.skip(); + } + shutdownHandle = await startUdsServer(serverTestContext); + }); + + afterEach(function () { + shutdownHandle?.(); + + // clear context + serverTestContext.requests = []; + serverTestContext.serverResponseProvider = () => { + return { error: null, buffer: Buffer.from([]) }; + }; + }); + + it('sends data', async function () { + const transport = createOtlpGrpcExporterTransport({ + ...simpleClientConfig, + address: 'unix:///tmp/otlp-test.sock', + }); - const result = (await transport.send( - Buffer.from([]), - timeoutMillis - )) as ExportResponseFailure; - assert.strictEqual(result.status, 'failure'); - assert.strictEqual(result.error, expectedError); + const result = (await transport.send( + Buffer.from([1, 2, 3]), + timeoutMillis + )) as ExportResponseSuccess; + + assert.strictEqual(result.status, 'success'); + assert.deepEqual(result.data, Buffer.from([])); + assert.strictEqual(serverTestContext.requests.length, 1); + assert.deepEqual( + serverTestContext.requests[0].request, + Buffer.from([1, 2, 3]) + ); + assert.deepEqual( + serverTestContext.requests[0].metadata.get('foo'), + simpleClientConfig.metadata().get('foo') + ); + }); }); }); }); diff --git a/experimental/packages/otlp-grpc-exporter-base/test/traceHelper.ts b/experimental/packages/otlp-grpc-exporter-base/test/traceHelper.ts deleted file mode 100644 index 13103b405b..0000000000 --- a/experimental/packages/otlp-grpc-exporter-base/test/traceHelper.ts +++ /dev/null @@ -1,329 +0,0 @@ -/* - * 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. - */ - -import { SpanStatusCode, TraceFlags } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; -import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import * as assert from 'assert'; -import * as grpc from '@grpc/grpc-js'; -import { VERSION } from '@opentelemetry/core'; -import { - IEvent, - IKeyValue, - ILink, - IResource, - ISpan, -} from '@opentelemetry/otlp-transformer'; - -const traceIdArr = [ - 31, 16, 8, 220, 142, 39, 14, 133, 196, 10, 13, 124, 57, 57, 178, 120, -]; -const spanIdArr = [94, 16, 114, 97, 246, 79, 165, 62]; -const parentIdArr = [120, 168, 145, 80, 152, 134, 67, 136]; - -export const mockedReadableSpan: ReadableSpan = { - name: 'documentFetch', - kind: 0, - spanContext: () => { - return { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '5e107261f64fa53e', - traceFlags: TraceFlags.SAMPLED, - }; - }, - parentSpanId: '78a8915098864388', - startTime: [1574120165, 429803070], - endTime: [1574120165, 438688070], - ended: true, - status: { code: SpanStatusCode.OK }, - attributes: { component: 'document-load' }, - links: [ - { - context: { - traceId: '1f1008dc8e270e85c40a0d7c3939b278', - spanId: '78a8915098864388', - traceFlags: TraceFlags.SAMPLED, - }, - attributes: { component: 'document-load' }, - }, - ], - events: [ - { - name: 'fetchStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupStart', - time: [1574120165, 429803070], - }, - { - name: 'domainLookupEnd', - time: [1574120165, 429803070], - }, - { - name: 'connectStart', - time: [1574120165, 429803070], - }, - { - name: 'connectEnd', - time: [1574120165, 429803070], - }, - { - name: 'requestStart', - time: [1574120165, 435513070], - }, - { - name: 'responseStart', - time: [1574120165, 436923070], - }, - { - name: 'responseEnd', - time: [1574120165, 438688070], - }, - ], - duration: [0, 8885000], - resource: Resource.default().merge( - new Resource({ - service: 'ui', - version: 1, - cost: 112.12, - }) - ), - instrumentationLibrary: { name: 'default', version: '0.0.1' }, - droppedAttributesCount: 0, - droppedEventsCount: 0, - droppedLinksCount: 0, -}; - -export function ensureExportedEventsAreCorrect(events: IEvent[]) { - assert.deepStrictEqual( - events, - [ - { - attributes: [], - timeUnixNano: '1574120165429803008', - name: 'fetchStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803008', - name: 'domainLookupStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803008', - name: 'domainLookupEnd', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803008', - name: 'connectStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165429803008', - name: 'connectEnd', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165435513088', - name: 'requestStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165436923136', - name: 'responseStart', - droppedAttributesCount: 0, - }, - { - attributes: [], - timeUnixNano: '1574120165438688000', - name: 'responseEnd', - droppedAttributesCount: 0, - }, - ], - 'exported events are incorrect' - ); -} - -export function ensureExportedAttributesAreCorrect(attributes: IKeyValue[]) { - assert.deepStrictEqual( - attributes, - [ - { - key: 'component', - value: { - stringValue: 'document-load', - value: 'stringValue', - }, - }, - ], - 'exported attributes are incorrect' - ); -} - -export function ensureExportedLinksAreCorrect(attributes: ILink[]) { - assert.deepStrictEqual( - attributes, - [ - { - attributes: [ - { - key: 'component', - value: { - stringValue: 'document-load', - value: 'stringValue', - }, - }, - ], - traceId: Buffer.from(traceIdArr), - spanId: Buffer.from(parentIdArr), - traceState: '', - droppedAttributesCount: 0, - }, - ], - 'exported links are incorrect' - ); -} - -export function ensureExportedSpanIsCorrect(span: ISpan) { - if (span.attributes) { - ensureExportedAttributesAreCorrect(span.attributes); - } - if (span.events) { - ensureExportedEventsAreCorrect(span.events); - } - if (span.links) { - ensureExportedLinksAreCorrect(span.links); - } - assert.deepStrictEqual( - span.traceId, - Buffer.from(traceIdArr), - 'traceId is wrong' - ); - assert.deepStrictEqual( - span.spanId, - Buffer.from(spanIdArr), - 'spanId is wrong' - ); - assert.strictEqual(span.traceState, '', 'traceState is wrong'); - assert.deepStrictEqual( - span.parentSpanId, - Buffer.from(parentIdArr), - 'parentIdArr is wrong' - ); - assert.strictEqual(span.name, 'documentFetch', 'name is wrong'); - assert.strictEqual(span.kind, 'SPAN_KIND_INTERNAL', 'kind is wrong'); - assert.strictEqual( - span.startTimeUnixNano, - '1574120165429803008', - 'startTimeUnixNano is wrong' - ); - assert.strictEqual( - span.endTimeUnixNano, - '1574120165438688000', - 'endTimeUnixNano is wrong' - ); - assert.strictEqual( - span.droppedAttributesCount, - 0, - 'droppedAttributesCount is wrong' - ); - assert.strictEqual(span.droppedEventsCount, 0, 'droppedEventsCount is wrong'); - assert.strictEqual(span.droppedLinksCount, 0, 'droppedLinksCount is wrong'); - assert.deepStrictEqual( - span.status, - { - code: 'STATUS_CODE_OK', - deprecatedCode: 'DEPRECATED_STATUS_CODE_OK', - message: '', - }, - 'status is wrong' - ); -} - -export function ensureResourceIsCorrect(resource: IResource) { - assert.deepStrictEqual(resource, { - attributes: [ - { - key: 'service.name', - value: { - stringValue: `unknown_service:${process.argv0}`, - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.language', - value: { - stringValue: 'nodejs', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.name', - value: { - stringValue: 'opentelemetry', - value: 'stringValue', - }, - }, - { - key: 'telemetry.sdk.version', - value: { - stringValue: VERSION, - value: 'stringValue', - }, - }, - { - key: 'service', - value: { - stringValue: 'ui', - value: 'stringValue', - }, - }, - { - key: 'version', - value: { - intValue: '1', - value: 'intValue', - }, - }, - { - key: 'cost', - value: { - doubleValue: 112.12, - value: 'doubleValue', - }, - }, - ], - droppedAttributesCount: 0, - }); -} - -export function ensureMetadataIsCorrect( - actual: grpc.Metadata, - expected: grpc.Metadata -) { - //ignore user agent - expected.remove('user-agent'); - actual.remove('user-agent'); - assert.deepStrictEqual(actual.getMap(), expected.getMap()); -} From e80879e093638e97c3df81bd331d28a52dbfb6ce Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 26 Nov 2024 12:06:05 +0100 Subject: [PATCH 04/10] fix(deps): update dependency axios to v1.7.8 (#5202) --- .../package.json | 2 +- .../package.json | 2 +- package-lock.json | 68 +++---------------- 3 files changed, 12 insertions(+), 60 deletions(-) diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index 2c9907ac61..04a2229a51 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -59,7 +59,7 @@ "@types/semver": "7.5.8", "@types/sinon": "17.0.3", "@types/superagent": "8.1.9", - "axios": "1.7.4", + "axios": "1.7.8", "cross-var": "1.1.0", "lerna": "6.6.2", "mocha": "10.8.2", diff --git a/integration-tests/propagation-validation-server/package.json b/integration-tests/propagation-validation-server/package.json index 1ec0f124ff..b5be318ddb 100644 --- a/integration-tests/propagation-validation-server/package.json +++ b/integration-tests/propagation-validation-server/package.json @@ -15,7 +15,7 @@ "@opentelemetry/context-async-hooks": "1.28.0", "@opentelemetry/core": "1.28.0", "@opentelemetry/sdk-trace-base": "1.28.0", - "axios": "1.7.4", + "axios": "1.7.8", "body-parser": "1.20.3", "express": "4.20.0" }, diff --git a/package-lock.json b/package-lock.json index 18f13d04ea..8dae41dcac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -972,7 +972,7 @@ "@types/semver": "7.5.8", "@types/sinon": "17.0.3", "@types/superagent": "8.1.9", - "axios": "1.7.4", + "axios": "1.7.8", "cross-var": "1.1.0", "lerna": "6.6.2", "mocha": "10.8.2", @@ -991,17 +991,6 @@ "@opentelemetry/api": "^1.3.0" } }, - "experimental/packages/opentelemetry-instrumentation-http/node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "experimental/packages/opentelemetry-instrumentation-xml-http-request": { "name": "@opentelemetry/instrumentation-xml-http-request", "version": "0.55.0", @@ -1542,7 +1531,7 @@ "@opentelemetry/context-async-hooks": "1.28.0", "@opentelemetry/core": "1.28.0", "@opentelemetry/sdk-trace-base": "1.28.0", - "axios": "1.7.4", + "axios": "1.7.8", "body-parser": "1.20.3", "express": "4.20.0" }, @@ -1553,16 +1542,6 @@ "node": ">=14" } }, - "integration-tests/propagation-validation-server/node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -7878,10 +7857,9 @@ } }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "dev": true, + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -32120,7 +32098,7 @@ "@types/semver": "7.5.8", "@types/sinon": "17.0.3", "@types/superagent": "8.1.9", - "axios": "1.7.4", + "axios": "1.7.8", "cross-var": "1.1.0", "forwarded-parse": "2.1.2", "lerna": "6.6.2", @@ -32133,19 +32111,6 @@ "sinon": "15.1.2", "superagent": "10.0.2", "typescript": "4.4.4" - }, - "dependencies": { - "axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "dev": true, - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - } } }, "@opentelemetry/instrumentation-xml-http-request": { @@ -34788,10 +34753,9 @@ "dev": true }, "axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "dev": true, + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", "requires": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -45776,22 +45740,10 @@ "@opentelemetry/context-async-hooks": "1.28.0", "@opentelemetry/core": "1.28.0", "@opentelemetry/sdk-trace-base": "1.28.0", - "axios": "1.7.4", + "axios": "1.7.8", "body-parser": "1.20.3", "express": "4.20.0", "typescript": "4.4.4" - }, - "dependencies": { - "axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - } } }, "proto-list": { From 561f8ad3a3b50c61f643d13a42bcd9c2006a6b57 Mon Sep 17 00:00:00 2001 From: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Date: Wed, 27 Nov 2024 01:14:23 -0800 Subject: [PATCH 05/10] fix(docs): broken link for community contribution lifecycle and processes (#5206) --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- CONTRIBUTING.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 554b4ebfee..485c1a48aa 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,7 +7,7 @@ Before creating a pull request, please make sure: - You have read the guide for contributing - See https://github.com/open-telemetry/opentelemetry-js/blob/main/CONTRIBUTING.md - You signed all your commits (otherwise we won't be able to merge the PR) - - See https://github.com/open-telemetry/community/blob/master/CONTRIBUTING.md#sign-the-cla + - See https://github.com/open-telemetry/community/blob/main/guides/contributor#sign-the-cla - You added unit tests for the new functionality - You mention in the PR description which issue it is addressing, e.g. "Fixes #xxx". This will auto-close the issue that your PR fixes (if such) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7c4c6fc0e4..a0b040337d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,7 +79,7 @@ Reporting bugs is an important contribution. Please make sure to include: ### Before you start Please read project contribution -[guide](https://github.com/open-telemetry/community/blob/master/CONTRIBUTING.md) +[guide](https://github.com/open-telemetry/community/blob/main/guides/contributor) for general practices for OpenTelemetry project. #### Conventional commit @@ -145,7 +145,7 @@ git merge upstream/main Remember to always work in a branch of your local copy, as you might otherwise have to contend with conflicts in main. -Please also see [GitHub workflow](https://github.com/open-telemetry/community/blob/master/CONTRIBUTING.md#github-workflow) section of general project contributing guide. +Please also see [GitHub workflow](https://github.com/open-telemetry/community/blob/main/guides/contributor/processes.md#github-workflow) section of general project contributing guide. ## Development From 3bf12847d166db34967355a6de8cee5b4b70fab3 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Wed, 27 Nov 2024 10:14:59 +0100 Subject: [PATCH 06/10] feat(otlp-exporter-base): add http response body to exporter error (#5204) --- experimental/CHANGELOG.md | 1 + .../src/transport/http-transport-utils.ts | 6 +++++- .../test/node/http-exporter-transport.test.ts | 11 ++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 9127b7bd71..eebd013262 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -25,6 +25,7 @@ All notable changes to experimental packages in this project will be documented * feat(otlp-exporter-base): internally accept a http header provider function only [#5179](https://github.com/open-telemetry/opentelemetry-js/pull/5179) @pichlermarc * refactor(otlp-exporter-base): don't create blob before sending xhr [#5193](https://github.com/open-telemetry/opentelemetry-js/pull/5193) @pichlermarc * improves compatibility with some unsupported runtimes +* feat(otlp-exporter-base): add http response body to exporter error [#5204](https://github.com/open-telemetry/opentelemetry-js/pull/5204) @pichlermarc ### :bug: (Bug Fix) diff --git a/experimental/packages/otlp-exporter-base/src/transport/http-transport-utils.ts b/experimental/packages/otlp-exporter-base/src/transport/http-transport-utils.ts index 99c55b0872..5dab9670b5 100644 --- a/experimental/packages/otlp-exporter-base/src/transport/http-transport-utils.ts +++ b/experimental/packages/otlp-exporter-base/src/transport/http-transport-utils.ts @@ -72,7 +72,11 @@ export function sendWithHttp( retryInMillis: parseRetryAfterToMills(res.headers['retry-after']), }); } else { - const error = new OTLPExporterError(res.statusMessage, res.statusCode); + const error = new OTLPExporterError( + res.statusMessage, + res.statusCode, + Buffer.concat(responseData).toString() + ); onDone({ status: 'failure', error, diff --git a/experimental/packages/otlp-exporter-base/test/node/http-exporter-transport.test.ts b/experimental/packages/otlp-exporter-base/test/node/http-exporter-transport.test.ts index d4c9230ae1..2e511893ed 100644 --- a/experimental/packages/otlp-exporter-base/test/node/http-exporter-transport.test.ts +++ b/experimental/packages/otlp-exporter-base/test/node/http-exporter-transport.test.ts @@ -22,6 +22,7 @@ import { ExportResponseRetryable, ExportResponseFailure, ExportResponseSuccess, + OTLPExporterError, } from '../../src'; import * as zlib from 'zlib'; @@ -123,7 +124,7 @@ describe('HttpExporterTransport', function () { // arrange server = http.createServer((_, res) => { res.statusCode = 404; - res.end(); + res.end('response-body'); }); server.listen(8080); @@ -143,6 +144,14 @@ describe('HttpExporterTransport', function () { (result as ExportResponseFailure).error.message, 'Not Found' ); + assert.strictEqual( + ((result as ExportResponseFailure).error as OTLPExporterError).data, + 'response-body' + ); + assert.strictEqual( + ((result as ExportResponseFailure).error as OTLPExporterError).code, + 404 + ); }); it('returns failure when request times out', function (done) { From 5ad0aa544b680556be5c58ed05d2cea191c6e542 Mon Sep 17 00:00:00 2001 From: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:10:35 -0800 Subject: [PATCH 07/10] chore: replace deprecated String.prototype.substr() with substring() (#5209) --- packages/opentelemetry-core/src/common/time.ts | 2 +- packages/opentelemetry-sdk-trace-base/src/Span.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/opentelemetry-core/src/common/time.ts b/packages/opentelemetry-core/src/common/time.ts index 8d3051b00c..89f5bfd3f6 100644 --- a/packages/opentelemetry-core/src/common/time.ts +++ b/packages/opentelemetry-core/src/common/time.ts @@ -111,7 +111,7 @@ export function hrTimeDuration( export function hrTimeToTimeStamp(time: api.HrTime): string { const precision = NANOSECOND_DIGITS; const tmp = `${'0'.repeat(precision)}${time[1]}Z`; - const nanoString = tmp.substr(tmp.length - precision - 1); + const nanoString = tmp.substring(tmp.length - precision - 1); const date = new Date(time[0] * 1000).toISOString(); return date.replace('000Z', nanoString); } diff --git a/packages/opentelemetry-sdk-trace-base/src/Span.ts b/packages/opentelemetry-sdk-trace-base/src/Span.ts index b5f3b75b4b..39a8b30308 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Span.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Span.ts @@ -377,7 +377,7 @@ export class Span implements APISpan, ReadableSpan { if (value.length <= limit) { return value; } - return value.substr(0, limit); + return value.substring(0, limit); } /** From 1249e34591d79407c488466ebd4340e84a6b0e9f Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Wed, 27 Nov 2024 19:34:07 +0100 Subject: [PATCH 08/10] refactor(otlp-exporter-base): remove exports that were meant to be internal (#5212) --- experimental/packages/otlp-exporter-base/src/index.ts | 6 +----- .../common/bounded-queue-export-promise-handler.test.ts | 2 +- .../test/common/otlp-export-delegate.test.ts | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/experimental/packages/otlp-exporter-base/src/index.ts b/experimental/packages/otlp-exporter-base/src/index.ts index 2d1860d391..7950fa70f6 100644 --- a/experimental/packages/otlp-exporter-base/src/index.ts +++ b/experimental/packages/otlp-exporter-base/src/index.ts @@ -37,9 +37,5 @@ export { CompressionAlgorithm, } from './configuration/legacy-node-configuration'; export { OTLPExporterConfigBase } from './configuration/legacy-base-configuration'; -export { - createOtlpExportDelegate, - IOtlpExportDelegate, -} from './otlp-export-delegate'; -export { createBoundedQueueExportPromiseHandler } from './bounded-queue-export-promise-handler'; +export { IOtlpExportDelegate } from './otlp-export-delegate'; export { createOtlpNetworkExportDelegate } from './otlp-network-export-delegate'; diff --git a/experimental/packages/otlp-exporter-base/test/common/bounded-queue-export-promise-handler.test.ts b/experimental/packages/otlp-exporter-base/test/common/bounded-queue-export-promise-handler.test.ts index 57cd86a4d2..d3bcccd9e0 100644 --- a/experimental/packages/otlp-exporter-base/test/common/bounded-queue-export-promise-handler.test.ts +++ b/experimental/packages/otlp-exporter-base/test/common/bounded-queue-export-promise-handler.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createBoundedQueueExportPromiseHandler } from '../../src'; +import { createBoundedQueueExportPromiseHandler } from '../../src/bounded-queue-export-promise-handler'; import * as assert from 'assert'; describe('BoundedQueueExportPromiseHandler', function () { diff --git a/experimental/packages/otlp-exporter-base/test/common/otlp-export-delegate.test.ts b/experimental/packages/otlp-exporter-base/test/common/otlp-export-delegate.test.ts index 1953ceea94..96a636c707 100644 --- a/experimental/packages/otlp-exporter-base/test/common/otlp-export-delegate.test.ts +++ b/experimental/packages/otlp-exporter-base/test/common/otlp-export-delegate.test.ts @@ -18,7 +18,7 @@ import * as sinon from 'sinon'; import * as assert from 'assert'; import { IExporterTransport } from '../../src'; import { ExportResultCode } from '@opentelemetry/core'; -import { createOtlpExportDelegate } from '../../src'; +import { createOtlpExportDelegate } from '../../src/otlp-export-delegate'; import { ExportResponse } from '../../src'; import { ISerializer } from '@opentelemetry/otlp-transformer'; import { IExportPromiseHandler } from '../../src/bounded-queue-export-promise-handler'; From 17bf0d9a344e7e4dd391d070c4d318f0783529e7 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 27 Nov 2024 19:35:08 +0100 Subject: [PATCH 09/10] chore(deps): update dependency @bufbuild/buf to v1.47.2 (#5210) --- .../package.json | 2 +- package-lock.json | 137 +++++++++++------- 2 files changed, 82 insertions(+), 57 deletions(-) diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index f375396c36..17bbe27838 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -46,7 +46,7 @@ "access": "public" }, "devDependencies": { - "@bufbuild/buf": "1.21.0-1", + "@bufbuild/buf": "1.47.2", "@grpc/grpc-js": "^1.7.1", "@grpc/proto-loader": "^0.7.10", "@opentelemetry/api": "1.9.0", diff --git a/package-lock.json b/package-lock.json index 8dae41dcac..45bd18b7bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -919,7 +919,7 @@ "@opentelemetry/semantic-conventions": "1.28.0" }, "devDependencies": { - "@bufbuild/buf": "1.21.0-1", + "@bufbuild/buf": "1.47.2", "@grpc/grpc-js": "^1.7.1", "@grpc/proto-loader": "^0.7.10", "@opentelemetry/api": "1.9.0", @@ -3128,9 +3128,9 @@ } }, "node_modules/@bufbuild/buf": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.21.0-1.tgz", - "integrity": "sha512-WPO0dAc3eUr1gsaB0s9MdMrlqFVg8O8peMulSt7j2akPycI9CSHao0JD4qiM89+2xnexgEJ0iZeCHl8QchIQNQ==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.47.2.tgz", + "integrity": "sha512-glY5kCAoO4+a7HvDb+BLOdoHSdCk4mdXdkp53H8JFz7maOnkxCiHHXgRX+taFyEu25N8ybn7NjZFrZSdRwq2sA==", "dev": true, "hasInstallScript": true, "bin": { @@ -3142,18 +3142,19 @@ "node": ">=12" }, "optionalDependencies": { - "@bufbuild/buf-darwin-arm64": "1.21.0-1", - "@bufbuild/buf-darwin-x64": "1.21.0-1", - "@bufbuild/buf-linux-aarch64": "1.21.0-1", - "@bufbuild/buf-linux-x64": "1.21.0-1", - "@bufbuild/buf-win32-arm64": "1.21.0-1", - "@bufbuild/buf-win32-x64": "1.21.0-1" + "@bufbuild/buf-darwin-arm64": "1.47.2", + "@bufbuild/buf-darwin-x64": "1.47.2", + "@bufbuild/buf-linux-aarch64": "1.47.2", + "@bufbuild/buf-linux-armv7": "1.47.2", + "@bufbuild/buf-linux-x64": "1.47.2", + "@bufbuild/buf-win32-arm64": "1.47.2", + "@bufbuild/buf-win32-x64": "1.47.2" } }, "node_modules/@bufbuild/buf-darwin-arm64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.21.0-1.tgz", - "integrity": "sha512-/JTmxQIIElZLPYMd7hPmglRMBUnhUYaeZvkAoHXKiLF9JJ2G6LNL0XTzM88lqwdqU4mc53VMZz3heSlmK3gpcA==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.47.2.tgz", + "integrity": "sha512-74WerFn06y+azgVfsnzhfbI5wla/OLPDnIvaNJBWHaqya/3bfascJkDylW2GVNHmwG1K/cscpmcc/RJPaO7ntQ==", "cpu": [ "arm64" ], @@ -3167,9 +3168,9 @@ } }, "node_modules/@bufbuild/buf-darwin-x64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.21.0-1.tgz", - "integrity": "sha512-lyQ+qret2es8Vt7GEUZ1KmF1ke5/lTQmhJMQFdCLGCPrJunEmpcAZvBKHVpaxvtspv6JdYdGI2nD2LYb3Qv41A==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.47.2.tgz", + "integrity": "sha512-adAiOacOQe8Ym/YXPCEiq9mrPeKRmDtF2TgqPWTcDy6mF7TqR7hMJINkEEuMd1EeACmXnzMOnXlm9ICtvdYgPg==", "cpu": [ "x64" ], @@ -3183,9 +3184,9 @@ } }, "node_modules/@bufbuild/buf-linux-aarch64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.21.0-1.tgz", - "integrity": "sha512-0ERNu3FHpqf4xKNtqGPUPXsGP3QGcnQfwnsqIMQOUMQ9YOUIHwk+wp2OyebwGOhyGfZe37s0Ji1ed4pbsXAgWg==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.47.2.tgz", + "integrity": "sha512-52vY+Owffr5diw2PyfQJqH+Fld6zW6NhNZak4zojvc2MjZKubWM0TfNyM9jXz2YrwyB+cyxkabE60nBI80m37w==", "cpu": [ "arm64" ], @@ -3198,10 +3199,26 @@ "node": ">=12" } }, + "node_modules/@bufbuild/buf-linux-armv7": { + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-armv7/-/buf-linux-armv7-1.47.2.tgz", + "integrity": "sha512-g9KtpObDeHZ/VG/0b5ZCieOao7L/WYZ0fPqFSs4N07D3APgEDhJG6vLyUcDgJMDgyLcgkNjNz0+XdYQb/tXyQw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@bufbuild/buf-linux-x64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.21.0-1.tgz", - "integrity": "sha512-x8CzB1Ta3XvyOVmBh6TyVLPOIoFsxtdVJQStpmXrxRj7bFLwR9MbZLL/Mq0ypoXS90LVi+EKk1dXjGXMcUaR7A==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.47.2.tgz", + "integrity": "sha512-MODCK2BzD1Mgoyr+5Sp8xA8qMNdytj8hYheyhA5NnCGTkQf8sfqAjpBSAAmKk6Zar8HOlVXML6tzE/ioDFFGwQ==", "cpu": [ "x64" ], @@ -3215,9 +3232,9 @@ } }, "node_modules/@bufbuild/buf-win32-arm64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.21.0-1.tgz", - "integrity": "sha512-41tllK/+Yv+ivRavB+5op37cQV2QFkT3m18jgfO27QtO1WIajLjOcl3sevP19xAib+eEF9Y/SP3c3m1qBS0/XQ==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.47.2.tgz", + "integrity": "sha512-563YKYWJl3LrCY3G3+zuhb8HwOs6DzWslwGPFkKV2hwHyWyvd1DR1JjiLvw9zX64IKNctQ0HempSqc3kcboaqQ==", "cpu": [ "arm64" ], @@ -3231,9 +3248,9 @@ } }, "node_modules/@bufbuild/buf-win32-x64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.21.0-1.tgz", - "integrity": "sha512-cA0f3Bnv3m4ciirtg1uUeF0kq6HBS0ZxY4uNDAW+E7V6xvVSQpjMO+d0Jr9wp7XNhdLmjd1q+u+pnA/L9H1/1A==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.47.2.tgz", + "integrity": "sha512-Sqcdv7La2xBDh3bTdEYb2f4UTMMqCcYe/D0RELhvQ5wDn6I35V3/2YT1OF5fRuf0BZLCo0OdO37S9L47uHSz2g==", "cpu": [ "x64" ], @@ -29742,58 +29759,66 @@ } }, "@bufbuild/buf": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.21.0-1.tgz", - "integrity": "sha512-WPO0dAc3eUr1gsaB0s9MdMrlqFVg8O8peMulSt7j2akPycI9CSHao0JD4qiM89+2xnexgEJ0iZeCHl8QchIQNQ==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.47.2.tgz", + "integrity": "sha512-glY5kCAoO4+a7HvDb+BLOdoHSdCk4mdXdkp53H8JFz7maOnkxCiHHXgRX+taFyEu25N8ybn7NjZFrZSdRwq2sA==", "dev": true, "requires": { - "@bufbuild/buf-darwin-arm64": "1.21.0-1", - "@bufbuild/buf-darwin-x64": "1.21.0-1", - "@bufbuild/buf-linux-aarch64": "1.21.0-1", - "@bufbuild/buf-linux-x64": "1.21.0-1", - "@bufbuild/buf-win32-arm64": "1.21.0-1", - "@bufbuild/buf-win32-x64": "1.21.0-1" + "@bufbuild/buf-darwin-arm64": "1.47.2", + "@bufbuild/buf-darwin-x64": "1.47.2", + "@bufbuild/buf-linux-aarch64": "1.47.2", + "@bufbuild/buf-linux-armv7": "1.47.2", + "@bufbuild/buf-linux-x64": "1.47.2", + "@bufbuild/buf-win32-arm64": "1.47.2", + "@bufbuild/buf-win32-x64": "1.47.2" } }, "@bufbuild/buf-darwin-arm64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.21.0-1.tgz", - "integrity": "sha512-/JTmxQIIElZLPYMd7hPmglRMBUnhUYaeZvkAoHXKiLF9JJ2G6LNL0XTzM88lqwdqU4mc53VMZz3heSlmK3gpcA==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.47.2.tgz", + "integrity": "sha512-74WerFn06y+azgVfsnzhfbI5wla/OLPDnIvaNJBWHaqya/3bfascJkDylW2GVNHmwG1K/cscpmcc/RJPaO7ntQ==", "dev": true, "optional": true }, "@bufbuild/buf-darwin-x64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.21.0-1.tgz", - "integrity": "sha512-lyQ+qret2es8Vt7GEUZ1KmF1ke5/lTQmhJMQFdCLGCPrJunEmpcAZvBKHVpaxvtspv6JdYdGI2nD2LYb3Qv41A==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.47.2.tgz", + "integrity": "sha512-adAiOacOQe8Ym/YXPCEiq9mrPeKRmDtF2TgqPWTcDy6mF7TqR7hMJINkEEuMd1EeACmXnzMOnXlm9ICtvdYgPg==", "dev": true, "optional": true }, "@bufbuild/buf-linux-aarch64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.21.0-1.tgz", - "integrity": "sha512-0ERNu3FHpqf4xKNtqGPUPXsGP3QGcnQfwnsqIMQOUMQ9YOUIHwk+wp2OyebwGOhyGfZe37s0Ji1ed4pbsXAgWg==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.47.2.tgz", + "integrity": "sha512-52vY+Owffr5diw2PyfQJqH+Fld6zW6NhNZak4zojvc2MjZKubWM0TfNyM9jXz2YrwyB+cyxkabE60nBI80m37w==", + "dev": true, + "optional": true + }, + "@bufbuild/buf-linux-armv7": { + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-armv7/-/buf-linux-armv7-1.47.2.tgz", + "integrity": "sha512-g9KtpObDeHZ/VG/0b5ZCieOao7L/WYZ0fPqFSs4N07D3APgEDhJG6vLyUcDgJMDgyLcgkNjNz0+XdYQb/tXyQw==", "dev": true, "optional": true }, "@bufbuild/buf-linux-x64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.21.0-1.tgz", - "integrity": "sha512-x8CzB1Ta3XvyOVmBh6TyVLPOIoFsxtdVJQStpmXrxRj7bFLwR9MbZLL/Mq0ypoXS90LVi+EKk1dXjGXMcUaR7A==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.47.2.tgz", + "integrity": "sha512-MODCK2BzD1Mgoyr+5Sp8xA8qMNdytj8hYheyhA5NnCGTkQf8sfqAjpBSAAmKk6Zar8HOlVXML6tzE/ioDFFGwQ==", "dev": true, "optional": true }, "@bufbuild/buf-win32-arm64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.21.0-1.tgz", - "integrity": "sha512-41tllK/+Yv+ivRavB+5op37cQV2QFkT3m18jgfO27QtO1WIajLjOcl3sevP19xAib+eEF9Y/SP3c3m1qBS0/XQ==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.47.2.tgz", + "integrity": "sha512-563YKYWJl3LrCY3G3+zuhb8HwOs6DzWslwGPFkKV2hwHyWyvd1DR1JjiLvw9zX64IKNctQ0HempSqc3kcboaqQ==", "dev": true, "optional": true }, "@bufbuild/buf-win32-x64": { - "version": "1.21.0-1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.21.0-1.tgz", - "integrity": "sha512-cA0f3Bnv3m4ciirtg1uUeF0kq6HBS0ZxY4uNDAW+E7V6xvVSQpjMO+d0Jr9wp7XNhdLmjd1q+u+pnA/L9H1/1A==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.47.2.tgz", + "integrity": "sha512-Sqcdv7La2xBDh3bTdEYb2f4UTMMqCcYe/D0RELhvQ5wDn6I35V3/2YT1OF5fRuf0BZLCo0OdO37S9L47uHSz2g==", "dev": true, "optional": true }, @@ -32055,7 +32080,7 @@ "@opentelemetry/instrumentation-grpc": { "version": "file:experimental/packages/opentelemetry-instrumentation-grpc", "requires": { - "@bufbuild/buf": "1.21.0-1", + "@bufbuild/buf": "1.47.2", "@grpc/grpc-js": "^1.7.1", "@grpc/proto-loader": "^0.7.10", "@opentelemetry/api": "1.9.0", From fd7f2d951b4b760c6b957ca42f4a0f6b5fa600bd Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 27 Nov 2024 19:43:54 +0100 Subject: [PATCH 10/10] fix(deps): update dependency zone.js to v0.15.0 (#5213) --- package-lock.json | 46 ++++++------------- .../package.json | 4 +- .../opentelemetry-context-zone/package.json | 2 +- selenium-tests/package.json | 2 +- 4 files changed, 17 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45bd18b7bb..386118cee5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27916,9 +27916,9 @@ } }, "node_modules/zone.js": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.10.tgz", - "integrity": "sha512-YGAhaO7J5ywOXW6InXNlLmfU194F8lVgu7bRntUF3TiG8Y3nBK0x1UJJuHUP/e8IyihkjCYqhCScpSwnlaSRkQ==" + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==" }, "packages/opentelemetry-context-async-hooks": { "name": "@opentelemetry/context-async-hooks", @@ -27947,7 +27947,7 @@ "license": "Apache-2.0", "dependencies": { "@opentelemetry/context-zone-peer-dep": "1.28.0", - "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" + "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" }, "devDependencies": { "cross-var": "1.1.0", @@ -27988,23 +27988,14 @@ "typescript": "4.4.4", "webpack": "5.96.1", "webpack-cli": "5.1.4", - "zone.js": "0.13.3" + "zone.js": "0.15.0" }, "engines": { "node": ">=14" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0", - "zone.js": "^0.10.2 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" - } - }, - "packages/opentelemetry-context-zone-peer-dep/node_modules/zone.js": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz", - "integrity": "sha512-MKPbmZie6fASC/ps4dkmIhaT5eonHkEt6eAy80K42tAm0G2W+AahLJjbfi6X9NPdciOE9GRFTTM8u2IiF6O3ww==", - "dev": true, - "dependencies": { - "tslib": "^2.3.0" + "zone.js": "^0.10.2 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" } }, "packages/opentelemetry-core": { @@ -28490,7 +28481,7 @@ "@opentelemetry/sdk-metrics": "1.28.0", "@opentelemetry/sdk-trace-base": "1.28.0", "@opentelemetry/sdk-trace-web": "1.28.0", - "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" + "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" }, "devDependencies": { "@babel/core": "7.26.0", @@ -31585,7 +31576,7 @@ "cross-var": "1.1.0", "lerna": "6.6.2", "typescript": "4.4.4", - "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" + "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" } }, "@opentelemetry/context-zone-peer-dep": { @@ -31616,18 +31607,7 @@ "typescript": "4.4.4", "webpack": "5.96.1", "webpack-cli": "5.1.4", - "zone.js": "0.13.3" - }, - "dependencies": { - "zone.js": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz", - "integrity": "sha512-MKPbmZie6fASC/ps4dkmIhaT5eonHkEt6eAy80K42tAm0G2W+AahLJjbfi6X9NPdciOE9GRFTTM8u2IiF6O3ww==", - "dev": true, - "requires": { - "tslib": "^2.3.0" - } - } + "zone.js": "0.15.0" } }, "@opentelemetry/core": { @@ -32750,7 +32730,7 @@ "webpack-cli": "5.1.4", "webpack-dev-server": "4.5.0", "webpack-merge": "5.10.0", - "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" + "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" }, "dependencies": { "ansi-regex": { @@ -50488,9 +50468,9 @@ "dev": true }, "zone.js": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.10.tgz", - "integrity": "sha512-YGAhaO7J5ywOXW6InXNlLmfU194F8lVgu7bRntUF3TiG8Y3nBK0x1UJJuHUP/e8IyihkjCYqhCScpSwnlaSRkQ==" + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==" } } } diff --git a/packages/opentelemetry-context-zone-peer-dep/package.json b/packages/opentelemetry-context-zone-peer-dep/package.json index b2c0412c78..626624e399 100644 --- a/packages/opentelemetry-context-zone-peer-dep/package.json +++ b/packages/opentelemetry-context-zone-peer-dep/package.json @@ -78,11 +78,11 @@ "typescript": "4.4.4", "webpack": "5.96.1", "webpack-cli": "5.1.4", - "zone.js": "0.13.3" + "zone.js": "0.15.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0", - "zone.js": "^0.10.2 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" + "zone.js": "^0.10.2 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" }, "sideEffects": false, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-zone-peer-dep" diff --git a/packages/opentelemetry-context-zone/package.json b/packages/opentelemetry-context-zone/package.json index 9bd77a8850..1c0ce514f5 100644 --- a/packages/opentelemetry-context-zone/package.json +++ b/packages/opentelemetry-context-zone/package.json @@ -57,7 +57,7 @@ }, "dependencies": { "@opentelemetry/context-zone-peer-dep": "1.28.0", - "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" + "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" }, "sideEffects": true, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-zone" diff --git a/selenium-tests/package.json b/selenium-tests/package.json index 4bbf2499fe..8f750d1f38 100644 --- a/selenium-tests/package.json +++ b/selenium-tests/package.json @@ -67,6 +67,6 @@ "@opentelemetry/sdk-metrics": "1.28.0", "@opentelemetry/sdk-trace-base": "1.28.0", "@opentelemetry/sdk-trace-web": "1.28.0", - "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0" + "zone.js": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" } }