Skip to content

Commit

Permalink
test(otlp-exporter-base): test config functions
Browse files Browse the repository at this point in the history
  • Loading branch information
pichlermarc committed Sep 10, 2024
1 parent 6fcd93a commit af05548
Show file tree
Hide file tree
Showing 7 changed files with 647 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ function getHeadersFromEnv(signalIdentifier: string) {
return undefined;
}

// headers are combined instead, with the non-specific headers taking precedence over the more specific ones.
// headers are combined instead of overwritten, with the non-specific headers taking precedence over
// the more specific ones.
return Object.assign(
{},
baggageUtils.parseKeyPairsIntoRecord(envNonSignalSpecificHeaders),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,20 @@
* limitations under the License.
*/

import { diag } from '@opentelemetry/api';

/**
* Configuration shared across all OTLP exporters
*
* Implementation note: anything added here MUST be
* - platform-agnostic
* - signal-agnostic
* - transport-agnostic
*/
export interface OtlpSharedConfiguration {
// Implementation note: anything added here MUST be
// - platform-agnostic
// - signal-agnostic
// - transport-agnostic
timeoutMillis: number;
concurrencyLimit: number;
compression: 'gzip' | 'none';
}

export function parseTimeout(timeoutEnvVar: string): number | undefined {
const envTimeout = process.env[timeoutEnvVar];
if (envTimeout != null && envTimeout !== '') {
const definedTimeout = Number(envTimeout);
if (
!Number.isNaN(definedTimeout) &&
Number.isFinite(definedTimeout) &&
definedTimeout > 0
) {
return definedTimeout;
}
diag.warn(
`Configuration: ${timeoutEnvVar} is invalid, expected number greater than 0 (actual: ${envTimeout})`
);
}
return undefined;
}

export function validateTimeoutMillis(timeoutMillis: number) {
if (
!Number.isNaN(timeoutMillis) &&
Expand All @@ -60,20 +41,6 @@ export function validateTimeoutMillis(timeoutMillis: number) {
);
}

export function parseCompression(
compressionEnvVar: string
): 'none' | 'gzip' | undefined {
const compression = process.env[compressionEnvVar];

if (compression == null || compression === 'none' || compression === 'gzip') {
return compression;
}
diag.warn(
`Configuration: ${compressionEnvVar} is invalid, expected 'none' or 'gzip' (actual: '${compression}')`
);
return undefined;
}

/**
* @param userProvidedConfiguration Configuration options provided by the user in code.
* @param fallbackConfiguration Fallback to use when the {@link userProvidedConfiguration} does not specify an option.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
OtlpSharedConfiguration,
parseCompression,
parseTimeout,
} from './shared-configuration';
import { OtlpSharedConfiguration } from './shared-configuration';
import { diag } from '@opentelemetry/api';

function parseTimeout(timeoutEnvVar: string): number | undefined {
const envTimeout = process.env[timeoutEnvVar];
if (envTimeout != null && envTimeout !== '') {
const definedTimeout = Number(envTimeout);
if (
!Number.isNaN(definedTimeout) &&
Number.isFinite(definedTimeout) &&
definedTimeout > 0
) {
return definedTimeout;
}
diag.warn(
`Configuration: ${timeoutEnvVar} is invalid, expected number greater than 0 (actual: ${envTimeout})`
);
}
return undefined;
}

function determineTimeout(signalIdentifier: string) {
const specificTimeout = parseTimeout(
Expand All @@ -28,6 +43,20 @@ function determineTimeout(signalIdentifier: string) {
return specificTimeout ?? nonSpecificTimeout;
}

function parseCompression(
compressionEnvVar: string
): 'none' | 'gzip' | undefined {
const compression = process.env[compressionEnvVar];

if (compression == null || compression === 'none' || compression === 'gzip') {
return compression;
}
diag.warn(
`Configuration: ${compressionEnvVar} is invalid, expected 'none' or 'gzip' (actual: '${compression}')`
);
return undefined;
}

function determineCompression(
signalIdentifier: string
): 'none' | 'gzip' | undefined {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* 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 {
mergeOtlpHttpConfigurationWithDefaults,
OtlpHttpConfiguration,
} from '../../../src/configuration/otlp-http-configuration';
import * as assert from 'assert';
import { testSharedConfigBehavior } from './shared-configuration.test';

describe('mergeOtlpHttpConfigurationWithDefaults', function () {
const testDefaults: OtlpHttpConfiguration = {
url: 'default-url',
timeoutMillis: 1,
compression: 'none',
concurrencyLimit: 2,
headers: { 'User-Agent': 'default-user-agent' },
};

describe('headers', function () {
it('merges headers instead of overriding', function () {
const config = mergeOtlpHttpConfigurationWithDefaults(
{
headers: { foo: 'user' },
},
{
headers: { foo: 'fallback', bar: 'fallback' },
},
testDefaults
);
assert.deepEqual(config.headers, {
'User-Agent': 'default-user-agent',
foo: 'user',
bar: 'fallback',
});
});
it('does not override default (required) header', function () {
const config = mergeOtlpHttpConfigurationWithDefaults(
{
headers: { 'User-Agent': 'custom' },
},
{
headers: { 'User-Agent': 'custom-fallback' },
},
{
url: 'default-url',
timeoutMillis: 1,
compression: 'none',
concurrencyLimit: 2,
headers: { 'User-Agent': 'default-user-agent' },
}
);
assert.deepEqual(config.headers, {
'User-Agent': 'default-user-agent',
});
});
});

describe('url', function () {
it('uses user provided url over fallback', () => {
const config = mergeOtlpHttpConfigurationWithDefaults(
{
url: 'https://example.com/user-provided',
},
{
url: 'https://example.com/fallback',
},
testDefaults
);
assert.deepEqual(config.url, 'https://example.com/user-provided');
});
it('uses fallback url over default', () => {
const config = mergeOtlpHttpConfigurationWithDefaults(
{},
{
url: 'https://example.com/fallback',
},
testDefaults
);
assert.deepEqual(config.url, 'https://example.com/fallback');
});
it('uses default if none other are specified', () => {
const config = mergeOtlpHttpConfigurationWithDefaults(
{},
{},
testDefaults
);
assert.deepEqual(config.url, testDefaults.url);
});
});

testSharedConfigBehavior(
mergeOtlpHttpConfigurationWithDefaults,
testDefaults
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* 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 {
mergeOtlpSharedConfigurationWithDefaults,
OtlpSharedConfiguration,
} from '../../../src';

export function testSharedConfigBehavior<T extends OtlpSharedConfiguration>(
sut: (
userProvidedConfiguration: Partial<OtlpSharedConfiguration>,
fallbackConfiguration: Partial<OtlpSharedConfiguration>,
defaultConfiguration: T
) => OtlpSharedConfiguration,
defaults: T
): void {
// copy so that we don't modify the original and pollute other tests.
const testDefaults = Object.assign({}, defaults);

testDefaults.timeoutMillis = 1;
testDefaults.compression = 'none';
testDefaults.concurrencyLimit = 2;

describe('timeout', function () {
it('uses user provided timeout over fallback', () => {
const config = sut(
{
timeoutMillis: 222,
},
{
timeoutMillis: 333,
},
testDefaults
);
assert.deepEqual(config.timeoutMillis, 222);
});
it('uses fallback timeout over default', () => {
const config = sut(
{},
{
timeoutMillis: 444,
},
testDefaults
);
assert.deepEqual(config.timeoutMillis, 444);
});
it('uses default if none other are specified', () => {
const config = sut({}, {}, testDefaults);
assert.deepEqual(config.timeoutMillis, testDefaults.timeoutMillis);
});

it('throws when value is negative', function () {
assert.throws(() => sut({ timeoutMillis: -1 }, {}, testDefaults));
});
});

describe('compression', function () {
it('uses user provided compression over fallback', () => {
const config = sut(
{
compression: 'gzip',
},
{
compression: 'none',
},
testDefaults
);
assert.deepEqual(config.compression, 'gzip');
});
it('uses fallback compression over default', () => {
const config = sut(
{},
{
compression: 'gzip',
},
testDefaults
);
assert.deepEqual(config.compression, 'gzip');
});
it('uses default if none other are specified', () => {
const config = sut({}, {}, testDefaults);
assert.deepEqual(config.compression, testDefaults.compression);
});
});

describe('concurrency limit', function () {
it('uses user provided limit over fallback', () => {
const config = sut(
{
concurrencyLimit: 20,
},
{
concurrencyLimit: 40,
},
testDefaults
);
assert.deepEqual(config.concurrencyLimit, 20);
});
it('uses fallback limit over default', () => {
const config = sut(
{},
{
concurrencyLimit: 50,
},
testDefaults
);
assert.deepEqual(config.concurrencyLimit, 50);
});
it('uses default if none other are specified', () => {
const config = sut({}, {}, testDefaults);
assert.deepEqual(config.concurrencyLimit, testDefaults.concurrencyLimit);
});
});
}

describe('mergeOtlpSharedConfigurationWithDefaults', function () {
testSharedConfigBehavior(mergeOtlpSharedConfigurationWithDefaults, {
timeoutMillis: 1,
compression: 'none',
concurrencyLimit: 2,
});
});
Loading

0 comments on commit af05548

Please sign in to comment.