opentelemetry-js/packages/opentelemetry-plugin-https/test/functionals/https-package.test.ts

140 lines
4.9 KiB
TypeScript

/*!
* Copyright 2019, 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 { NoopLogger } from '@opentelemetry/core';
import { SpanKind, Span } from '@opentelemetry/types';
import * as assert from 'assert';
import * as https from 'https';
import * as http from 'http';
import * as nock from 'nock';
import { plugin } from '../../src/https';
import { assertSpan } from '../utils/assertSpan';
import { DummyPropagation } from '../utils/DummyPropagation';
import * as url from 'url';
import axios, { AxiosResponse } from 'axios';
import * as superagent from 'superagent';
import * as got from 'got';
import * as request from 'request-promise-native';
import * as path from 'path';
import { NodeTracer } from '@opentelemetry/node-sdk';
import {
InMemorySpanExporter,
SimpleSpanProcessor,
} from '@opentelemetry/tracer-basic';
import { Http } from '@opentelemetry/plugin-http';
const memoryExporter = new InMemorySpanExporter();
export const customAttributeFunction = (span: Span): void => {
span.setAttribute('span kind', SpanKind.CLIENT);
};
describe('Packages', () => {
describe('get', () => {
const httpTextFormat = new DummyPropagation();
const logger = new NoopLogger();
const tracer = new NodeTracer({
logger,
httpTextFormat,
});
tracer.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
beforeEach(() => {
memoryExporter.reset();
});
before(() => {
plugin.enable((https as unknown) as Http, tracer, tracer.logger);
});
after(() => {
// back to normal
nock.cleanAll();
nock.enableNetConnect();
});
let resHeaders: http.IncomingHttpHeaders;
[
{ name: 'axios', httpPackage: axios }, //keep first
{ name: 'superagent', httpPackage: superagent },
{ name: 'got', httpPackage: { get: (url: string) => got(url) } },
{
name: 'request',
httpPackage: { get: (url: string) => request(url) },
},
].forEach(({ name, httpPackage }) => {
it(`should create a span for GET requests and add propagation headers by using ${name} package`, async () => {
if (process.versions.node.startsWith('12') && name === 'got') {
// got complains with nock and node version 12+
// > RequestError: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type function
// so let's make a real call
nock.cleanAll();
nock.enableNetConnect();
} else {
nock.load(path.join(__dirname, '../', '/fixtures/google.json'));
}
const urlparsed = url.parse(
name === 'got' && process.versions.node.startsWith('12')
? // there is an issue with got 9.6 version and node 12 when redirecting so url above will not work
// https://github.com/nock/nock/pull/1551
// https://github.com/sindresorhus/got/commit/bf1aa5492ae2bc78cbbec6b7d764906fb156e6c2#diff-707a4781d57c42085155dcb27edb9ccbR258
// TODO: check if this is still the case when new version
'https://www.google.com'
: `https://www.google.com/search?q=axios&oq=axios&aqs=chrome.0.69i59l2j0l3j69i60.811j0j7&sourceid=chrome&ie=UTF-8`
);
const result = await httpPackage.get(urlparsed.href!);
if (!resHeaders) {
const res = result as AxiosResponse<{}>;
resHeaders = res.headers;
}
const spans = memoryExporter.getFinishedSpans();
const span = spans[0];
const validations = {
hostname: urlparsed.hostname!,
httpStatusCode: 200,
httpMethod: 'GET',
pathname: urlparsed.pathname!,
path: urlparsed.path,
resHeaders,
component: plugin.component,
};
assert.strictEqual(spans.length, 1);
assert.ok(span.name.indexOf(`GET ${urlparsed.pathname}`) >= 0);
switch (name) {
case 'axios':
assert.ok(
result.request._headers[DummyPropagation.TRACE_CONTEXT_KEY]
);
assert.ok(
result.request._headers[DummyPropagation.SPAN_CONTEXT_KEY]
);
break;
case 'got':
case 'superagent':
break;
default:
break;
}
assert.strictEqual(span.attributes['span kind'], SpanKind.CLIENT);
assertSpan(span, SpanKind.CLIENT, validations);
});
});
});
});