From fbf1f44f6e3d6667a2484438fa60e561a4074e4d Mon Sep 17 00:00:00 2001 From: Dominic Kramer Date: Wed, 26 Apr 2017 10:54:43 -0700 Subject: [PATCH] System tests no longer use nested describe blocks --- .../system-test/testAuthClient.js | 607 +++++++++--------- 1 file changed, 300 insertions(+), 307 deletions(-) diff --git a/packages/error-reporting/system-test/testAuthClient.js b/packages/error-reporting/system-test/testAuthClient.js index 4aa5e01ce09..7e01b258ce5 100644 --- a/packages/error-reporting/system-test/testAuthClient.js +++ b/packages/error-reporting/system-test/testAuthClient.js @@ -15,6 +15,7 @@ */ 'use strict'; + var assert = require('assert'); var nock = require('nock'); var RequestHandler = require('../src/google-apis/auth-client.js'); @@ -29,338 +30,330 @@ var forEach = require('lodash.foreach'); var assign = require('lodash.assign'); var pick = require('lodash.pick'); var omitBy = require('lodash.omitby'); + const ERR_TOKEN = '_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'; -const env = (function(injectedEnv) { - const envKeys = ['GOOGLE_APPLICATION_CREDENTIALS', 'GCLOUD_PROJECT', + +const envKeys = ['GOOGLE_APPLICATION_CREDENTIALS', 'GCLOUD_PROJECT', 'NODE_ENV']; - class InstancedEnv { - constructor() { - assign(this, injectedEnv); - this._originalEnv = this._captureProcessProperties(); - } - _captureProcessProperties() { - return omitBy(pick(process.env, envKeys), value => !isString(value)); - } - sterilizeProcess() { - forEach(envKeys, (v, k) => delete process.env[k]); - return this; - } - setProjectId() { - assign(process.env, { - GCLOUD_PROJECT: injectedEnv.projectId - }); - return this; - } - setProjectNumber() { - assign(process.env, { - GCLOUD_PROJECT: injectedEnv.projectNumber - }); - return this; - } - setKeyFilename() { - assign(process.env, { - GOOGLE_APPLICATION_CREDENTIALS: injectedEnv.keyFilename - }); - return this; - } - setProduction() { - assign(process.env, { - NODE_ENV: 'production' - }); - return this; - } - restoreProcessToOriginalState() { - assign(process.env, this._originalEnv); - return this; - } - injected() { - return assign({}, injectedEnv); - } + +class InstancedEnv { + constructor(injectedEnv) { + assign(this, injectedEnv); + this.injectedEnv = injectedEnv; + this._originalEnv = this._captureProcessProperties(); } - return new InstancedEnv(); -}(require('../../../system-test/env.js'))); -const SHOULD_RUN = (function() { + + _captureProcessProperties() { + return omitBy(pick(process.env, envKeys), value => !isString(value)); + } + + sterilizeProcess() { + forEach(envKeys, (v, k) => delete process.env[k]); + return this; + } + + setProjectId() { + assign(process.env, { + GCLOUD_PROJECT: this.injectedEnv.projectId + }); + return this; + } + + setProjectNumber() { + assign(process.env, { + GCLOUD_PROJECT: this.injectedEnv.projectNumber + }); + return this; + } + + setKeyFilename() { + assign(process.env, { + GOOGLE_APPLICATION_CREDENTIALS: this.injectedEnv.keyFilename + }); + return this; + } + + setProduction() { + assign(process.env, { + NODE_ENV: 'production' + }); + return this; + } + + restoreProcessToOriginalState() { + assign(process.env, this._originalEnv); + return this; + } + + injected() { + return assign({}, this.injectedEnv); + } +} + +const env = new InstancedEnv(require('../../../system-test/env.js')); + +function shouldRun() { + var shouldRun = true; if (!isString(env.injected().projectId)) { - return new Error('The project id (projectId) was not set in the env'); + console.log('The project id (projectId) was not set in the env'); + shouldRun = false; } + if (!isString(env.injected().apiKey)) { - return new Error('The api key (apiKey) was not set as an env variable'); + console.log('The api key (apiKey) was not set as an env variable'); + shouldRun = false; } + if (!isString(env.injected().projectNumber)) { - return new Error( - 'The project number (projectNumber) was not set in the env'); + console.log('The project number (projectNumber) was not set in the env'); + shouldRun = false; } + if (!isString(env.injected().keyFilename)) { - return new Error( - 'The key filename (keyFilename) was not set in the env'); + console.log('The key filename (keyFilename) was not set in the env'); + shouldRun = false; } - return true; -}()); -const TEST_RUNNER = (function() { - if (SHOULD_RUN instanceof Error) { - console.log('Skipping error-reporting system tests:'); - console.log(' ' + SHOULD_RUN.message); - return describe.skip; - } - return describe; -}()); - -(TEST_RUNNER)('Errors system tests', function() { - describe('Request/Response lifecycle mocking', function() { - var sampleError = new Error(ERR_TOKEN); - var errorMessage = new ErrorMessage().setMessage(sampleError); - var fakeService, client, logger; - before(() => env.sterilizeProcess()); - beforeEach(function() { - env.setProjectId().setKeyFilename().setProduction(); - fakeService = nock( - 'https://clouderrorreporting.googleapis.com./v1beta1/projects/' + - process.env.GCLOUD_PROJECT - ).persist().post('/events:report'); - logger = createLogger({logLevel: 5}); - client = new RequestHandler( - new Configuration({ignoreEnvironmentCheck: true}, logger), logger); + + return shouldRun; +} + +if (!shouldRun()) { + console.log('Skipping error-reporting system tests'); + process.exit(1); +} + +describe('Request/Response lifecycle mocking', function() { + var sampleError = new Error(ERR_TOKEN); + var errorMessage = new ErrorMessage().setMessage(sampleError); + var fakeService, client, logger; + before(function() { + env.sterilizeProcess(); + }); + + beforeEach(function() { + env.setProjectId().setKeyFilename().setProduction(); + fakeService = nock( + 'https://clouderrorreporting.googleapis.com./v1beta1/projects/' + + process.env.GCLOUD_PROJECT + ).persist().post('/events:report'); + logger = createLogger({logLevel: 5}); + client = new RequestHandler( + new Configuration({ignoreEnvironmentCheck: true}, logger), logger); + }); + + afterEach(function() { + env.sterilizeProcess(); + nock.cleanAll(); + }); + + after(function() { + env.restoreProcessToOriginalState(); + }); + + it('Should fail when receiving non-retryable errors', function(done) { + this.timeout(5000); + client.sendError({}, function(err, response, + /* jshint unused:false */ body) { + assert(err instanceof Error); + assert.strictEqual(err.message.toLowerCase(), + 'message cannot be empty.'); + assert(isObject(response)); + assert.strictEqual(response.statusCode, 400); + done(); }); - afterEach(function() { - env.sterilizeProcess(); - nock.cleanAll(); + }); + + it('Should retry when receiving retryable errors', function(done) { + this.timeout(25000); + var tries = 0; + var intendedTries = 4; + fakeService.reply(429, function() { + tries += 1; + console.log('Mock Server Received Request:', tries + '/' + + intendedTries); + return {error: 'Please try again later'}; }); - after(() => env.restoreProcessToOriginalState()); - describe('Receiving non-retryable errors', function() { - it('Should fail', function(done) { - this.timeout(5000); - client.sendError({}, function(err, response, - /* jshint unused:false */ body) { - assert(err instanceof Error); - assert.strictEqual(err.message.toLowerCase(), - 'message cannot be empty.'); - assert(isObject(response)); - assert.strictEqual(response.statusCode, 400); - done(); - }); + client.sendError(errorMessage, function(err, response, + /* jshint unused:false */ body) { + assert.strictEqual(tries, intendedTries); + done(); + }); + }); + + it('Should provide the key as a query string on outgoing requests when ' + + 'using an API key', function(done) { + env.sterilizeProcess().setProjectId().setProduction(); + var key = env.apiKey; + var client = new RequestHandler(new Configuration( + {key: key, ignoreEnvironmentCheck: true}, + createLogger({logLevel: 5}))); + fakeService.query({key: key}).reply(200, function(uri) { + assert(uri.indexOf('key=' + key) > -1); + return {}; + }); + client.sendError(errorMessage, function() { + done(); }); + } + ); + + it('Should still execute the request with a callback-less invocation', + function(done) { + fakeService.reply(200, function() { + done(); }); - describe('Receiving retryable errors', function() { - it('Should retry', function(done) { - this.timeout(25000); - var tries = 0; - var intendedTries = 4; - fakeService.reply(429, function() { - tries += 1; - console.log('Mock Server Received Request:', tries + '/' + - intendedTries); - return {error: 'Please try again later'}; - }); - client.sendError(errorMessage, function(err, response, - /* jshint unused:false */ body) { - assert.strictEqual(tries, intendedTries); + client.sendError(errorMessage); + }); +}); + +describe('Client creation', function() { + var sampleError = new Error(ERR_TOKEN); + var errorMessage = new ErrorMessage().setMessage(sampleError.stack); + after(function() { + env.sterilizeProcess(); + }); + + it('Should not throw on initialization when using only project id as a ' + + 'runtime argument', function(done) { + env.sterilizeProcess().setKeyFilename(); + var logger = createLogger({logLevel: 5}); + var cfg = new Configuration({projectId: env.injected().projectId, + ignoreEnvironmentCheck: true}, logger); + this.timeout(10000); + assert.doesNotThrow(function() { + (new RequestHandler(cfg, logger)).sendError(errorMessage, + function(err, response, body) { + assert.strictEqual(err, null); + assert.strictEqual(response.statusCode, 200); + assert(isObject(body) && isEmpty(body)); done(); - }); - }); + } + ); + }); + }); + + it('Should not throw on initialization when using only project id as an ' + + 'env variable', function(done) { + env.sterilizeProcess().setProjectId().setKeyFilename(); + var logger = createLogger({logLevel: 5}); + var cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); + this.timeout(10000); + assert.doesNotThrow(function() { + (new RequestHandler(cfg, logger)).sendError(errorMessage, + function(err, response, body) { + assert.strictEqual(err, null); + assert.strictEqual(response.statusCode, 200); + assert(isObject(body) && isEmpty(body)); + done(); + } + ); }); - describe('Using an API key', function() { - it('Should provide the key as a query string on outgoing requests', - function(done) { - env.sterilizeProcess().setProjectId().setProduction(); - var key = env.apiKey; - var client = new RequestHandler(new Configuration( - {key: key, ignoreEnvironmentCheck: true}, - createLogger({logLevel: 5}))); - fakeService.query({key: key}).reply(200, function(uri) { - assert(uri.indexOf('key=' + key) > -1); - return {}; - }); - client.sendError(errorMessage, function() { - done(); - }); + }); + + it('Should not throw on initialization when using only project number as ' + + 'a runtime argument', function(done) { + env.sterilizeProcess().setKeyFilename(); + var logger = createLogger({logLevel: 5}); + var cfg = new Configuration({ + projectId: parseInt(env.injected().projectNumber), + ignoreEnvironmentCheck: true + }, logger); + this.timeout(10000); + assert.doesNotThrow(function() { + (new RequestHandler(cfg, logger)).sendError(errorMessage, + function(err, response, body) { + assert.strictEqual(err, null); + assert.strictEqual(response.statusCode, 200); + assert(isObject(body) && isEmpty(body)); + done(); } ); }); - describe('Callback-less invocation', function() { - it('Should still execute the request', function(done) { - fakeService.reply(200, function() { + }); + + it('Should not throw on initialization when using only project number as ' + + 'an env variable', function(done) { + env.sterilizeProcess().setKeyFilename().setProjectNumber(); + var logger = createLogger({logLevel: 5}); + var cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); + this.timeout(10000); + assert.doesNotThrow(function() { + (new RequestHandler(cfg, logger)).sendError(errorMessage, + function(err, response, body) { + assert.strictEqual(err, null); + assert.strictEqual(response.statusCode, 200); + assert(isObject(body) && isEmpty(body)); done(); - }); - client.sendError(errorMessage); - }); + } + ); }); }); - describe('System-live integration testing', function() { - var sampleError = new Error(ERR_TOKEN); - var errorMessage = new ErrorMessage().setMessage(sampleError.stack); - describe('Client creation', function() { - describe('Using only project id', function() { - describe('As a runtime argument', function() { - var cfg, logger; - before(function() { - env.sterilizeProcess().setKeyFilename(); - logger = createLogger({logLevel: 5}); - cfg = new Configuration({projectId: env.injected().projectId, - ignoreEnvironmentCheck: true}, logger); - }); - after(() => env.sterilizeProcess()); - it('Should not throw on initialization', function(done) { - this.timeout(10000); - assert.doesNotThrow(function() { - (new RequestHandler(cfg, logger)).sendError(errorMessage, - function(err, response, body) { - assert.strictEqual(err, null); - assert.strictEqual(response.statusCode, 200); - assert(isObject(body) && isEmpty(body)); - done(); - } - ); - }); - }); - }); - describe('As an env variable', function() { - var cfg, logger; - before(function() { - env.sterilizeProcess().setProjectId().setKeyFilename(); - logger = createLogger({logLevel: 5}); - cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); - }); - after(() => env.sterilizeProcess()); - it('Should not throw on initialization', function(done) { - this.timeout(10000); - assert.doesNotThrow(function() { - (new RequestHandler(cfg, logger)).sendError(errorMessage, - function(err, response, body) { - assert.strictEqual(err, null); - assert.strictEqual(response.statusCode, 200); - assert(isObject(body) && isEmpty(body)); - done(); - } - ); - }); - }); - }); - }); - describe('Using only project number', function() { - describe('As a runtime argument', function() { - var cfg, logger; - before(function() { - env.sterilizeProcess().setKeyFilename(); - logger = createLogger({logLevel: 5}); - cfg = new Configuration({ - projectId: parseInt(env.injected().projectNumber), - ignoreEnvironmentCheck: true - }, logger); - }); - after(() => env.sterilizeProcess()); - it('Should not throw on initialization', function(done) { - this.timeout(10000); - assert.doesNotThrow(function() { - (new RequestHandler(cfg, logger)).sendError(errorMessage, - function(err, response, body) { - assert.strictEqual(err, null); - assert.strictEqual(response.statusCode, 200); - assert(isObject(body) && isEmpty(body)); - done(); - } - ); - }); - }); - }); - describe('As an env variable', function() { - var cfg, logger; - before(function() { - env.sterilizeProcess().setKeyFilename().setProjectNumber(); - logger = createLogger({logLevel: 5}); - cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); - }); - after(() => env.sterilizeProcess()); - it('Should not throw on initialization', function(done) { - this.timeout(10000); - assert.doesNotThrow(function() { - (new RequestHandler(cfg, logger)).sendError(errorMessage, - function(err, response, body) { - assert.strictEqual(err, null); - assert.strictEqual(response.statusCode, 200); - assert(isObject(body) && isEmpty(body)); - done(); - } - ); - }); - }); - }); - }); +}); + +describe('Expected Behavior', function() { + var ERROR_STRING = [ + 'Stackdriver error reporting client has not been configured to send', + 'errors, please check the NODE_ENV environment variable and make', + 'sure it is set to "production" or set the ignoreEnvironmentCheck', + 'property to true in the runtime configuration object' + ].join(' '); + + var er = new Error(ERR_TOKEN); + var em = new ErrorMessage().setMessage(er.stack); + + after(function() { + env.sterilizeProcess(); + }); + + it('Should callback with an error with a configuration to not report errors', + function(done) { + env.sterilizeProcess().setKeyFilename().setProjectId(); + process.env.NODE_ENV = 'null'; + var logger = createLogger({logLevel: 5}); + var client = new RequestHandler(new Configuration(undefined, logger), + logger); + client.sendError({}, function(err, response, + /* jshint unused:false */ body) { + assert(err instanceof Error); + assert.strictEqual(err.message, ERROR_STRING); + assert.strictEqual(response, null); + done(); }); - describe('Error behvaiour', function() { - describe('With a configuration to not report errors', function() { - var ERROR_STRING = [ - 'Stackdriver error reporting client has not been configured to send', - 'errors, please check the NODE_ENV environment variable and make', - 'sure it is set to "production" or set the ignoreEnvironmentCheck', - 'property to true in the runtime configuration object' - ].join(' '); - var logger, client; - before(function() { - env.sterilizeProcess().setKeyFilename().setProjectId(); - process.env.NODE_ENV = 'null'; - logger = createLogger({logLevel: 5}); - client = new RequestHandler(new Configuration(undefined, logger), - logger); - }); - after(() => env.sterilizeProcess()); - it('Should callback with an error', function(done) { - client.sendError({}, function(err, response, - /* jshint unused:false */ body) { - assert(err instanceof Error); - assert.strictEqual(err.message, ERROR_STRING); - assert.strictEqual(response, null); - done(); - }); - }); - }); + }); + + it('Should succeed in its request given a valid project id', function(done) { + env.sterilizeProcess(); + var logger = createLogger({logLevel: 5}); + var cfg = new Configuration({ + projectId: env.injected().projectId, + ignoreEnvironmentCheck: true + }, logger); + var client = new RequestHandler(cfg, logger); + + client.sendError(em, function(err, response, body) { + assert.strictEqual(err, null); + assert(isObject(body)); + assert(isEmpty(body)); + assert.strictEqual(response.statusCode, 200); + done(); }); - describe('Success behaviour', function() { - var er = new Error(ERR_TOKEN); - var em = new ErrorMessage().setMessage(er.stack); - describe('Given a valid project id', function() { - var logger, client, cfg; - before(function() { - env.sterilizeProcess(); - logger = createLogger({logLevel: 5}); - cfg = new Configuration({ - projectId: env.injected().projectId, - ignoreEnvironmentCheck: true - }, logger); - client = new RequestHandler(cfg, logger); - }); - after(() => env.sterilizeProcess()); - it('Should succeed in its request', function(done) { - client.sendError(em, function(err, response, body) { - assert.strictEqual(err, null); - assert(isObject(body)); - assert(isEmpty(body)); - assert.strictEqual(response.statusCode, 200); - done(); - }); - }); - }); - describe('Given a valid project number', function() { - var logger, client, cfg; - before(function() { - env.sterilizeProcess(); - logger = createLogger({logLevel: 5}); - cfg = new Configuration({ - projectId: parseInt(env.injected().projectNumber), - ignoreEnvironmentCheck: true - }, logger); - client = new RequestHandler(cfg, logger); - }); - after(() => env.sterilizeProcess()); - it('Should succeed in its request', function(done) { - client.sendError(em, function(err, response, body) { - assert.strictEqual(err, null); - assert(isObject(body)); - assert(isEmpty(body)); - assert.strictEqual(response.statusCode, 200); - done(); - }); - }); - }); + }); + + it('Should succeed in its request given a valid project number', + function(done) { + env.sterilizeProcess(); + var logger = createLogger({logLevel: 5}); + var cfg = new Configuration({ + projectId: parseInt(env.injected().projectNumber), + ignoreEnvironmentCheck: true + }, logger); + var client = new RequestHandler(cfg, logger); + client.sendError(em, function(err, response, body) { + assert.strictEqual(err, null); + assert(isObject(body)); + assert(isEmpty(body)); + assert.strictEqual(response.statusCode, 200); + done(); }); }); });