Skip to content

Commit 48bae14

Browse files
committed
add unit tests
1 parent ceb3d62 commit 48bae14

File tree

6 files changed

+178
-3
lines changed

6 files changed

+178
-3
lines changed

aws-distro-opentelemetry-node-autoinstrumentation/src/exporter/otlp/aws/common/aws-authenticator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class AwsAuthenticator {
3737
if (dependenciesLoaded) {
3838
const url = new URL(endpoint);
3939

40-
if (serializedData == undefined) {
40+
if (serializedData === undefined) {
4141
diag.error('Given serialized data is undefined. Not authenticating.');
4242
return headers;
4343
}

aws-distro-opentelemetry-node-autoinstrumentation/src/exporter/otlp/aws/logs/otlp-aws-log-exporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { ExportResult } from '@opentelemetry/core';
1919
export class OTLPAwsLogExporter extends OTLPProtoLogExporter {
2020
private endpoint: string;
2121
private region: string;
22-
private authenticator;
22+
private authenticator: AwsAuthenticator;
2323

2424
constructor(endpoint: string, config?: OTLPExporterNodeConfigBase) {
2525
super(changeUrlConfig(endpoint, config));

aws-distro-opentelemetry-node-autoinstrumentation/src/exporter/otlp/aws/traces/otlp-aws-span-exporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { changeUrlConfig } from '../common/utils';
1919
export class OTLPAwsSpanExporter extends OTLPProtoTraceExporter {
2020
private endpoint: string;
2121
private region: string;
22-
private authenticator;
22+
private authenticator: AwsAuthenticator;
2323

2424
constructor(endpoint: string, config?: OTLPExporterNodeConfigBase) {
2525
super(changeUrlConfig(endpoint, config));
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
export const AWS_AUTH_PATH = '../../../../../src/exporter/otlp/aws/common/aws-authenticator';
4+
export const AWS_SPAN_EXPORTER_PATH = '../../../../../src/exporter/otlp/aws/traces/otlp-aws-span-exporter';
5+
export const AWS_LOG_EXPORTER_PATH = '../../../../../src/exporter/otlp/aws/logs/otlp-aws-log-exporter';
6+
7+
export const SIGNATURE_V4_MODULE = '@smithy/signature-v4';
8+
export const CREDENTIAL_PROVIDER_MODULE = '@aws-sdk/credential-provider-node';
9+
export const SHA_256_MODULE = '@aws-crypto/sha256-js';
10+
export const AWS_HTTP_MODULE = '@smithy/protocol-http';
11+
12+
export const AWS_OTLP_TRACES_ENDPOINT = 'https://xray.us-east-1.amazonaws.com';
13+
export const AWS_OTLP_TRACES_ENDPOINT_PATH = '/v1/traces';
14+
15+
export const AWS_OTLP_LOGS_ENDPOINT = 'https://logs.us-east-1.amazonaws.com';
16+
export const AWS_OTLP_LOGS_ENDPOINT_PATH = '/v1/logs';
17+
18+
export const AUTHORIZATION_HEADER = 'authorization';
19+
export const X_AMZ_DATE_HEADER = 'x-amz-date';
20+
export const X_AMZ_SECURITY_TOKEN_HEADER = 'x-amz-security-token';
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import expect from 'expect';
5+
import {
6+
AWS_OTLP_LOGS_ENDPOINT,
7+
AWS_OTLP_LOGS_ENDPOINT_PATH,
8+
AUTHORIZATION_HEADER,
9+
X_AMZ_DATE_HEADER,
10+
X_AMZ_SECURITY_TOKEN_HEADER,
11+
AWS_LOG_EXPORTER_PATH,
12+
} from '../common/test-utils.test';
13+
import * as sinon from 'sinon';
14+
import * as proxyquire from 'proxyquire';
15+
import * as nock from 'nock';
16+
17+
const EXPECTED_AUTH_HEADER = 'AWS4-HMAC-SHA256 Credential=test_key/some_date/us-east-1/xray/aws4_request';
18+
const EXPECTED_AUTH_X_AMZ_DATE = 'some_date';
19+
const EXPECTED_AUTH_SECURITY_TOKEN = 'test_token';
20+
21+
describe('OTLPAwsLogExporter', () => {
22+
let sandbox: sinon.SinonSandbox;
23+
let scope: nock.Scope;
24+
let mockModule: any;
25+
26+
beforeEach(() => {
27+
sandbox = sinon.createSandbox();
28+
29+
scope = nock(AWS_OTLP_LOGS_ENDPOINT)
30+
.post(AWS_OTLP_LOGS_ENDPOINT_PATH)
31+
.reply((uri: any, requestBody: any) => {
32+
return [200, ''];
33+
});
34+
35+
mockModule = proxyquire(AWS_LOG_EXPORTER_PATH, {
36+
'../common/aws-authenticator': {
37+
AwsAuthenticator: class MockAwsAuthenticator {
38+
constructor() {}
39+
async authenticate(endpoint: string, headers: Record<string, string>) {
40+
return {
41+
...headers,
42+
[AUTHORIZATION_HEADER]: EXPECTED_AUTH_HEADER,
43+
[X_AMZ_DATE_HEADER]: EXPECTED_AUTH_X_AMZ_DATE,
44+
[X_AMZ_SECURITY_TOKEN_HEADER]: EXPECTED_AUTH_SECURITY_TOKEN,
45+
};
46+
}
47+
},
48+
},
49+
});
50+
});
51+
52+
afterEach(() => {
53+
sandbox.restore();
54+
});
55+
56+
it('Should inject SigV4 Headers successfully', done => {
57+
const exporter = new mockModule.OTLPAwsLogExporter(AWS_OTLP_LOGS_ENDPOINT + AWS_OTLP_LOGS_ENDPOINT_PATH);
58+
59+
exporter
60+
.export([], () => {})
61+
.then(() => {
62+
scope.on('request', (req, interceptor, body) => {
63+
const headers = req.headers;
64+
expect(headers).toHaveProperty(AUTHORIZATION_HEADER.toLowerCase());
65+
expect(headers).toHaveProperty(X_AMZ_SECURITY_TOKEN_HEADER.toLowerCase());
66+
expect(headers).toHaveProperty(X_AMZ_DATE_HEADER.toLowerCase());
67+
68+
expect(headers[AUTHORIZATION_HEADER.toLowerCase()]).toBe(EXPECTED_AUTH_HEADER);
69+
expect(headers[X_AMZ_SECURITY_TOKEN_HEADER.toLowerCase()]).toBe(EXPECTED_AUTH_SECURITY_TOKEN);
70+
expect(headers[X_AMZ_DATE_HEADER.toLowerCase()]).toBe(EXPECTED_AUTH_X_AMZ_DATE);
71+
72+
expect(headers['content-type']).toBe('application/x-protobuf');
73+
expect(headers['user-agent']).toMatch(/^OTel-OTLP-Exporter-JavaScript\/\d+\.\d+\.\d+$/);
74+
done();
75+
});
76+
});
77+
});
78+
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import expect from 'expect';
4+
import {
5+
AWS_OTLP_TRACES_ENDPOINT,
6+
AUTHORIZATION_HEADER,
7+
X_AMZ_DATE_HEADER,
8+
X_AMZ_SECURITY_TOKEN_HEADER,
9+
AWS_OTLP_TRACES_ENDPOINT_PATH,
10+
AWS_SPAN_EXPORTER_PATH,
11+
} from '../common/test-utils.test';
12+
import * as sinon from 'sinon';
13+
import * as proxyquire from 'proxyquire';
14+
import * as nock from 'nock';
15+
16+
const EXPECTED_AUTH_HEADER = 'AWS4-HMAC-SHA256 Credential=test_key/some_date/us-east-1/xray/aws4_request';
17+
const EXPECTED_AUTH_X_AMZ_DATE = 'some_date';
18+
const EXPECTED_AUTH_SECURITY_TOKEN = 'test_token';
19+
20+
describe('OTLPAwsSpanExporter', () => {
21+
let sandbox: sinon.SinonSandbox;
22+
let scope: nock.Scope;
23+
let mockModule: any;
24+
25+
beforeEach(() => {
26+
sandbox = sinon.createSandbox();
27+
28+
scope = nock(AWS_OTLP_TRACES_ENDPOINT)
29+
.post(AWS_OTLP_TRACES_ENDPOINT_PATH)
30+
.reply((uri: any, requestBody: any) => {
31+
return [200, ''];
32+
});
33+
34+
mockModule = proxyquire(AWS_SPAN_EXPORTER_PATH, {
35+
'../common/aws-authenticator': {
36+
AwsAuthenticator: class MockAwsAuthenticator {
37+
constructor() {}
38+
async authenticate(endpoint: string, headers: Record<string, string>) {
39+
return {
40+
...headers,
41+
[AUTHORIZATION_HEADER]: EXPECTED_AUTH_HEADER,
42+
[X_AMZ_DATE_HEADER]: EXPECTED_AUTH_X_AMZ_DATE,
43+
[X_AMZ_SECURITY_TOKEN_HEADER]: EXPECTED_AUTH_SECURITY_TOKEN,
44+
};
45+
}
46+
},
47+
},
48+
});
49+
});
50+
51+
afterEach(() => {
52+
sandbox.restore();
53+
});
54+
55+
it('Should inject SigV4 Headers successfully', done => {
56+
const exporter = new mockModule.OTLPAwsSpanExporter(AWS_OTLP_TRACES_ENDPOINT + AWS_OTLP_TRACES_ENDPOINT_PATH);
57+
58+
exporter
59+
.export([], () => {})
60+
.then(() => {
61+
scope.on('request', (req, interceptor, body) => {
62+
const headers = req.headers;
63+
expect(headers).toHaveProperty(AUTHORIZATION_HEADER.toLowerCase());
64+
expect(headers).toHaveProperty(X_AMZ_SECURITY_TOKEN_HEADER.toLowerCase());
65+
expect(headers).toHaveProperty(X_AMZ_DATE_HEADER.toLowerCase());
66+
67+
expect(headers[AUTHORIZATION_HEADER.toLowerCase()]).toBe(EXPECTED_AUTH_HEADER);
68+
expect(headers[X_AMZ_SECURITY_TOKEN_HEADER.toLowerCase()]).toBe(EXPECTED_AUTH_SECURITY_TOKEN);
69+
expect(headers[X_AMZ_DATE_HEADER.toLowerCase()]).toBe(EXPECTED_AUTH_X_AMZ_DATE);
70+
71+
expect(headers['content-type']).toBe('application/x-protobuf');
72+
expect(headers['user-agent']).toMatch(/^OTel-OTLP-Exporter-JavaScript\/\d+\.\d+\.\d+$/);
73+
done();
74+
});
75+
});
76+
});
77+
});

0 commit comments

Comments
 (0)