Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(breaking!): support API endpoint override #509

Merged
merged 4 commits into from
Jun 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@google-cloud/common": "^1.0.0",
"@google-cloud/common": "^2.0.0",
"@types/console-log-level": "^1.4.0",
"@types/semver": "^6.0.0",
"console-log-level": "^1.4.0",
Expand Down
14 changes: 8 additions & 6 deletions ts/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ const parseDuration: (str: string) => number = require('parse-duration');

// Configuration for Profiler.
export interface Config extends GoogleAuthOptions {
/**
* The API endpoint of the service used to make requests.
* Defaults to `cloudprofiler.googleapis.com`.
*/
apiEndpoint?: string;

// Cloud Console projectId to associate profiles with instead of one read
// from VM metadata server.
projectId?: string;
Expand Down Expand Up @@ -107,10 +113,6 @@ export interface Config extends GoogleAuthOptions {
// https://nodejs.org/dist/latest-v9.x/docs/api/timers.html#timers_settimeout_callback_delay_args.
serverBackoffCapMillis?: number;

// Allows user to specify API URL other than
// https://cloudprofiler.googleapis.com/v2.
baseApiUrl?: string;

// Time between profile collection.
// For testing with startLocal() only.
localProfilingPeriodMillis?: number;
Expand Down Expand Up @@ -148,6 +150,7 @@ export interface Config extends GoogleAuthOptions {

// Interface for an initialized config.
export interface ProfilerConfig extends GoogleAuthOptions {
apiEndpoint: string;
projectId?: string;
logLevel: number;
serviceContext: {service: string; version?: string};
Expand All @@ -163,7 +166,6 @@ export interface ProfilerConfig extends GoogleAuthOptions {
backoffCapMillis: number;
backoffMultiplier: number;
serverBackoffCapMillis: number;
baseApiUrl: string;
localProfilingPeriodMillis: number;
localLogPeriodMillis: number;
localTimeDurationMillis: number;
Expand All @@ -184,7 +186,7 @@ export const defaultConfig = {
initialBackoffMillis: 60 * 1000, // 1 minute
backoffCapMillis: parseDuration('1h'),
backoffMultiplier: 1.3,
baseApiUrl: 'https://cloudprofiler.googleapis.com/v2',
apiEndpoint: 'cloudprofiler.googleapis.com',

// This is the largest duration for setTimeout which does not cause it to
// run immediately.
Expand Down
6 changes: 3 additions & 3 deletions ts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,17 @@ export function nodeVersionOkay(version: string | SemVer): boolean {
* needed. Returns a profiler if creation is successful. Otherwise, returns
* rejected promise.
*/
export async function createProfiler(config: Config): Promise<Profiler> {
export async function createProfiler(config: Config = {}): Promise<Profiler> {
if (!nodeVersionOkay(process.version)) {
throw new Error(
`Could not start profiler: node version ${process.version}` +
` does not satisfies "${pjson.engines.node}"` +
'\nSee https://github.com/GoogleCloudPlatform/cloud-profiler-nodejs#prerequisites' +
'\nSee https://github.com/googleapis/cloud-profiler-nodejs#prerequisites' +
' for details.'
);
}

let profilerConfig: ProfilerConfig = initConfigLocal(config);
let profilerConfig = initConfigLocal(config);

// Start the heap profiler if profiler config does not indicate heap profiling
// is disabled. This must be done before any asynchronous calls are made so
Expand Down
8 changes: 6 additions & 2 deletions ts/src/profiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,17 @@ export class Profiler extends ServiceObject {
private profileTypes: string[];
private retryer: Retryer;
private sourceMapper: SourceMapper | undefined;
private baseApiUrl: string;

// Public for testing.
config: ProfilerConfig;

constructor(config: ProfilerConfig) {
config = config || ({} as ProfilerConfig);
const baseApiUrl = `https://${config.apiEndpoint}/v2`;
const serviceConfig: ServiceConfig = {
baseUrl: config.baseApiUrl,
apiEndpoint: config.apiEndpoint,
baseUrl: baseApiUrl,
scopes: [SCOPE],
packageJson: pjson,
};
Expand All @@ -296,6 +299,7 @@ export class Profiler extends ServiceObject {
baseUrl: '/',
});
this.config = config;
this.baseApiUrl = baseApiUrl;

this.logger = createLogger(this.config.logLevel);

Expand Down Expand Up @@ -471,7 +475,7 @@ export class Profiler extends ServiceObject {
}
const options = {
method: 'PATCH',
uri: this.config.baseApiUrl + '/' + prof.name,
uri: this.baseApiUrl + '/' + prof.name,
body: prof,
json: true,
};
Expand Down
10 changes: 5 additions & 5 deletions ts/test/test-init-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ describe('createProfiler', () => {
localProfilingPeriodMillis: 1000,
localTimeDurationMillis: 1000,
localLogPeriodMillis: 10000,
baseApiUrl: 'https://cloudprofiler.googleapis.com/v2',
apiEndpoint: 'cloudprofiler.googleapis.com',
};
const sourceMapSearchPath: string[] = [];

const disableSourceMapParams = {
sourceMapSearchPath: ['path'],
disableSourceMaps: true,
Expand Down Expand Up @@ -342,14 +342,14 @@ describe('createProfiler', () => {
}
});

it('should set baseApiUrl to non-default value', async () => {
it('should set apiEndpoint to non-default value', async () => {
metadataStub = sinon.stub(gcpMetadata, 'instance');
metadataStub.throwsException('cannot access metadata');

const config = Object.assign(
{
apiEndpoint: 'test-cloudprofiler.sandbox.googleapis.com',
serviceContext: {version: '', service: 'fake-service'},
baseApiUrl: 'https://test-cloudprofiler.sandbox.googleapis.com/v2',
},
disableSourceMapParams
);
Expand All @@ -358,7 +358,7 @@ describe('createProfiler', () => {
disableHeap: false,
disableTime: false,
logLevel: 2,
baseApiUrl: 'https://test-cloudprofiler.sandbox.googleapis.com/v2',
apiEndpoint: 'test-cloudprofiler.sandbox.googleapis.com',
};
const expConfig = Object.assign(
{},
Expand Down
27 changes: 15 additions & 12 deletions ts/test/test-profiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ const parseDuration: (str: string) => number = require('parse-duration');

const fakeCredentials = require('../../ts/test/fixtures/gcloud-credentials.json');

const API = 'https://cloudprofiler.googleapis.com/v2';
const TEST_API = 'https://test-cloudprofiler.sandbox.googleapis.com/v2';
const API = 'cloudprofiler.googleapis.com';
const TEST_API = 'test-cloudprofiler.sandbox.googleapis.com';

const FULL_API = `https://${API}/v2`;
const FULL_TEST_API = `https://${TEST_API}/v2`;

const testConfig: ProfilerConfig = {
projectId: 'test-projectId',
Expand All @@ -62,12 +65,12 @@ const testConfig: ProfilerConfig = {
backoffCapMillis: parseDuration('1h'),
backoffMultiplier: 1.3,
serverBackoffCapMillis: parseDuration('7d'),
baseApiUrl: API,
localProfilingPeriodMillis: 1000,
localTimeDurationMillis: 1000,
localLogPeriodMillis: 1000,
sourceMapSearchPath: [],
disableSourceMaps: true,
apiEndpoint: API,
};

nock.disableNetConnect();
Expand Down Expand Up @@ -391,7 +394,7 @@ describe('Profiler', () => {
labels: {instance: 'test-instance'},
};
nockOauth2();
const apiMock = nock(API)
const apiMock = nock(FULL_API)
.patch('/' + requestProf.name)
.once()
.reply(200);
Expand All @@ -407,12 +410,12 @@ describe('Profiler', () => {
labels: {instance: 'test-instance'},
};
nockOauth2();
const apiMock = nock(TEST_API)
const apiMock = nock(FULL_TEST_API)
.patch('/' + requestProf.name)
.once()
.reply(200);
const config = extend(true, {}, testConfig);
config.baseApiUrl = TEST_API;
config.apiEndpoint = TEST_API;
const profiler = new Profiler(config);
await profiler.profileAndUpload(requestProf);
assert.strictEqual(apiMock.isDone(), true, 'completed call to test API');
Expand Down Expand Up @@ -442,7 +445,7 @@ describe('Profiler', () => {
labels: {version: config.serviceContext.version},
};
nockOauth2();
const requestProfileMock = nock(API)
const requestProfileMock = nock(FULL_API)
.post('/projects/' + testConfig.projectId + '/profiles')
.once()
.reply(200, response);
Expand All @@ -454,7 +457,7 @@ describe('Profiler', () => {
it('should successfully create profile using non-default api', async () => {
const config = extend(true, {}, testConfig);
config.disableHeap = true;
config.baseApiUrl = TEST_API;
config.apiEndpoint = TEST_API;
const response = {
name: 'projects/12345678901/test-projectId',
profileType: 'WALL',
Expand All @@ -467,7 +470,7 @@ describe('Profiler', () => {
labels: {version: config.serviceContext.version},
};
nockOauth2();
const requestProfileMock = nock(TEST_API)
const requestProfileMock = nock(FULL_TEST_API)
.post('/projects/' + config.projectId + '/profiles')
.once()
.reply(200, response);
Expand All @@ -490,7 +493,7 @@ describe('Profiler', () => {
labels: {version: config.serviceContext.version},
};
nockOauth2();
const requestProfileMock = nock(API)
const requestProfileMock = nock(FULL_API)
.post('/projects/' + testConfig.projectId + '/profiles')
.once()
.reply(200, response);
Expand All @@ -504,7 +507,7 @@ describe('Profiler', () => {
config.disableHeap = true;
const response = {name: 'projects/12345678901/test-projectId'};
nockOauth2();
const requestProfileMock = nock(API)
const requestProfileMock = nock(FULL_API)
.post('/projects/' + testConfig.projectId + '/profiles')
.once()
.reply(200, response);
Expand Down Expand Up @@ -597,7 +600,7 @@ describe('Profiler', () => {
additionalField: 'additionalField',
};
nockOauth2();
const requestProfileMock = nock(API)
const requestProfileMock = nock(FULL_API)
.post('/projects/' + testConfig.projectId + '/profiles')
.once()
.reply(200, response);
Expand Down