From 1e7b3b0dadb74a68fe77df1a23a277f31d910467 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Thu, 23 Feb 2017 11:51:14 -0800 Subject: [PATCH 01/29] Stage errors for repo integration TODOS (ongoing): - [x] Refactor test directory to follow repo conventions - [x] Unit and system tests pass --- packages/error-reporting/.clang-format.yaml | 2 + packages/error-reporting/.gitignore | 9 + packages/error-reporting/.jshintignore | 4 + packages/error-reporting/.jshintrc | 28 + packages/error-reporting/.npmignore | 5 + packages/error-reporting/.travis.yml | 9 + packages/error-reporting/CHANGELOG.md | 29 + packages/error-reporting/CONTRIBUTING.md | 20 + packages/error-reporting/LICENSE | 202 ++++++ packages/error-reporting/README.md | 285 ++++++++ packages/error-reporting/bin/test.sh | 80 +++ packages/error-reporting/config.tar.enc | Bin 0 -> 9232 bytes packages/error-reporting/index.js | 108 +++ packages/error-reporting/package.json | 52 ++ .../src/classes/custom-stack-trace.js | 117 +++ .../src/classes/error-message.js | 291 ++++++++ .../classes/request-information-container.js | 130 ++++ packages/error-reporting/src/configuration.js | 481 +++++++++++++ .../src/error-extractors/error.js | 49 ++ .../src/error-extractors/object.js | 80 +++ .../src/error-handlers/error.js | 46 ++ .../src/error-handlers/number.js | 45 ++ .../src/error-handlers/object.js | 45 ++ .../src/error-handlers/string.js | 47 ++ .../src/error-handlers/unknown.js | 37 + packages/error-reporting/src/error-router.js | 63 ++ .../src/google-apis/auth-client.js | 155 ++++ .../error-reporting/src/interfaces/express.js | 81 +++ .../error-reporting/src/interfaces/hapi.js | 127 ++++ .../error-reporting/src/interfaces/koa.js | 68 ++ .../error-reporting/src/interfaces/manual.js | 103 +++ .../src/interfaces/message-builder.js | 44 ++ .../error-reporting/src/interfaces/restify.js | 159 ++++ .../src/interfaces/uncaught.js | 67 ++ packages/error-reporting/src/logger.js | 44 ++ .../src/request-extractors/express.js | 76 ++ .../src/request-extractors/hapi.js | 102 +++ .../src/request-extractors/koa.js | 55 ++ .../src/request-extractors/manual.js | 85 +++ .../test/fixtures/configuration.js | 25 + .../test/fixtures/gcloud-credentials.json | 6 + .../test/fixtures/uncaughtExitBehaviour.js | 93 +++ .../test/system-test/testAuthClient.js | 350 +++++++++ .../test-servers/express_scaffold_server.js | 138 ++++ .../test/test-servers/hapi_scaffold_server.js | 69 ++ .../test/test-servers/koa_scaffold_server.js | 51 ++ .../test-servers/manual_scaffold_server.js | 34 + .../test-servers/restify_scaffold_server.js | 32 + .../test/unit/testConfigCredentials.js | 182 +++++ .../test/unit/testConfiguration.js | 377 ++++++++++ .../test/unit/testCustomStackTrace.js | 69 ++ .../test/unit/testErrorMessage.js | 680 ++++++++++++++++++ .../test/unit/testExpressInterface.js | 90 +++ .../testExpressRequestInformationExtractor.js | 155 ++++ .../test/unit/testExtractFromErrorClass.js | 105 +++ .../test/unit/testExtractFromObject.js | 106 +++ .../test/unit/testHandleErrorClassError.js | 54 ++ .../test/unit/testHandleNumberAsError.js | 42 ++ .../test/unit/testHandleObjectAsError.js | 42 ++ .../test/unit/testHandleStringAsError.js | 42 ++ .../test/unit/testHandleUnknownAsError.js | 45 ++ .../test/unit/testHapiInterface.js | 145 ++++ .../testHapiRequestInformationExtractor.js | 124 ++++ .../testKoaRequestInformationExtractor.js | 67 ++ .../error-reporting/test/unit/testLogger.js | 68 ++ .../test/unit/testManualHandler.js | 183 +++++ .../testManualRequestInformationExtractor.js | 110 +++ .../unit/testRequestInformationContainer.js | 93 +++ .../test/unit/testRestifyInterface.js | 134 ++++ .../test/unit/testServiceConfiguration.js | 498 +++++++++++++ .../error-reporting/test/unit/testUncaught.js | 94 +++ packages/error-reporting/utils/fuzzer.js | 313 ++++++++ 72 files changed, 8046 insertions(+) create mode 100644 packages/error-reporting/.clang-format.yaml create mode 100644 packages/error-reporting/.gitignore create mode 100644 packages/error-reporting/.jshintignore create mode 100644 packages/error-reporting/.jshintrc create mode 100644 packages/error-reporting/.npmignore create mode 100644 packages/error-reporting/.travis.yml create mode 100644 packages/error-reporting/CHANGELOG.md create mode 100644 packages/error-reporting/CONTRIBUTING.md create mode 100644 packages/error-reporting/LICENSE create mode 100644 packages/error-reporting/README.md create mode 100755 packages/error-reporting/bin/test.sh create mode 100644 packages/error-reporting/config.tar.enc create mode 100644 packages/error-reporting/index.js create mode 100644 packages/error-reporting/package.json create mode 100644 packages/error-reporting/src/classes/custom-stack-trace.js create mode 100644 packages/error-reporting/src/classes/error-message.js create mode 100644 packages/error-reporting/src/classes/request-information-container.js create mode 100644 packages/error-reporting/src/configuration.js create mode 100644 packages/error-reporting/src/error-extractors/error.js create mode 100644 packages/error-reporting/src/error-extractors/object.js create mode 100644 packages/error-reporting/src/error-handlers/error.js create mode 100644 packages/error-reporting/src/error-handlers/number.js create mode 100644 packages/error-reporting/src/error-handlers/object.js create mode 100644 packages/error-reporting/src/error-handlers/string.js create mode 100644 packages/error-reporting/src/error-handlers/unknown.js create mode 100644 packages/error-reporting/src/error-router.js create mode 100644 packages/error-reporting/src/google-apis/auth-client.js create mode 100644 packages/error-reporting/src/interfaces/express.js create mode 100644 packages/error-reporting/src/interfaces/hapi.js create mode 100644 packages/error-reporting/src/interfaces/koa.js create mode 100644 packages/error-reporting/src/interfaces/manual.js create mode 100644 packages/error-reporting/src/interfaces/message-builder.js create mode 100644 packages/error-reporting/src/interfaces/restify.js create mode 100644 packages/error-reporting/src/interfaces/uncaught.js create mode 100644 packages/error-reporting/src/logger.js create mode 100644 packages/error-reporting/src/request-extractors/express.js create mode 100644 packages/error-reporting/src/request-extractors/hapi.js create mode 100644 packages/error-reporting/src/request-extractors/koa.js create mode 100644 packages/error-reporting/src/request-extractors/manual.js create mode 100644 packages/error-reporting/test/fixtures/configuration.js create mode 100644 packages/error-reporting/test/fixtures/gcloud-credentials.json create mode 100644 packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js create mode 100644 packages/error-reporting/test/system-test/testAuthClient.js create mode 100644 packages/error-reporting/test/test-servers/express_scaffold_server.js create mode 100644 packages/error-reporting/test/test-servers/hapi_scaffold_server.js create mode 100644 packages/error-reporting/test/test-servers/koa_scaffold_server.js create mode 100644 packages/error-reporting/test/test-servers/manual_scaffold_server.js create mode 100644 packages/error-reporting/test/test-servers/restify_scaffold_server.js create mode 100644 packages/error-reporting/test/unit/testConfigCredentials.js create mode 100644 packages/error-reporting/test/unit/testConfiguration.js create mode 100644 packages/error-reporting/test/unit/testCustomStackTrace.js create mode 100644 packages/error-reporting/test/unit/testErrorMessage.js create mode 100644 packages/error-reporting/test/unit/testExpressInterface.js create mode 100644 packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js create mode 100644 packages/error-reporting/test/unit/testExtractFromErrorClass.js create mode 100644 packages/error-reporting/test/unit/testExtractFromObject.js create mode 100644 packages/error-reporting/test/unit/testHandleErrorClassError.js create mode 100644 packages/error-reporting/test/unit/testHandleNumberAsError.js create mode 100644 packages/error-reporting/test/unit/testHandleObjectAsError.js create mode 100644 packages/error-reporting/test/unit/testHandleStringAsError.js create mode 100644 packages/error-reporting/test/unit/testHandleUnknownAsError.js create mode 100644 packages/error-reporting/test/unit/testHapiInterface.js create mode 100644 packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js create mode 100644 packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js create mode 100644 packages/error-reporting/test/unit/testLogger.js create mode 100644 packages/error-reporting/test/unit/testManualHandler.js create mode 100644 packages/error-reporting/test/unit/testManualRequestInformationExtractor.js create mode 100644 packages/error-reporting/test/unit/testRequestInformationContainer.js create mode 100644 packages/error-reporting/test/unit/testRestifyInterface.js create mode 100644 packages/error-reporting/test/unit/testServiceConfiguration.js create mode 100644 packages/error-reporting/test/unit/testUncaught.js create mode 100644 packages/error-reporting/utils/fuzzer.js diff --git a/packages/error-reporting/.clang-format.yaml b/packages/error-reporting/.clang-format.yaml new file mode 100644 index 00000000000..e1a95210184 --- /dev/null +++ b/packages/error-reporting/.clang-format.yaml @@ -0,0 +1,2 @@ +BasedOnStyle: Google +Language: Javascript diff --git a/packages/error-reporting/.gitignore b/packages/error-reporting/.gitignore new file mode 100644 index 00000000000..43e232a9716 --- /dev/null +++ b/packages/error-reporting/.gitignore @@ -0,0 +1,9 @@ +node_modules +coverage +npm-debug.log +.DS_Store +.eslintrc.js +docs +tests/configuration +.nyc_output +*.patch diff --git a/packages/error-reporting/.jshintignore b/packages/error-reporting/.jshintignore new file mode 100644 index 00000000000..db20f1d7121 --- /dev/null +++ b/packages/error-reporting/.jshintignore @@ -0,0 +1,4 @@ +node_modules +test/e2e/node_modules +test/fixtures +coverage diff --git a/packages/error-reporting/.jshintrc b/packages/error-reporting/.jshintrc new file mode 100644 index 00000000000..bf58ca099dd --- /dev/null +++ b/packages/error-reporting/.jshintrc @@ -0,0 +1,28 @@ +{ + "bitwise": true, + "curly": true, + "eqeqeq": true, + "esnext": true, + "freeze": true, + "immed": true, + "indent": 2, + "latedef": "nofunc", + "maxlen": 100, + "newcap": true, + "node": true, + "noarg": true, + "quotmark": "single", + "strict": true, + "trailing": true, + "undef": true, + "unused": "vars", + "globals": { + /* Mocha-provided globals */ + "describe": false, + "it": false, + "before": false, + "beforeEach": false, + "after": false, + "afterEach": false + } +} diff --git a/packages/error-reporting/.npmignore b/packages/error-reporting/.npmignore new file mode 100644 index 00000000000..8c2961713d8 --- /dev/null +++ b/packages/error-reporting/.npmignore @@ -0,0 +1,5 @@ +/bin +/coverage +/doc +/test +*.enc diff --git a/packages/error-reporting/.travis.yml b/packages/error-reporting/.travis.yml new file mode 100644 index 00000000000..1aefc8a9b21 --- /dev/null +++ b/packages/error-reporting/.travis.yml @@ -0,0 +1,9 @@ +sudo: false +language: node_js +node_js: +- '0.12' +- '4' +- '6' +- '7' +script: +- npm run-script test diff --git a/packages/error-reporting/CHANGELOG.md b/packages/error-reporting/CHANGELOG.md new file mode 100644 index 00000000000..c1d3b6c082d --- /dev/null +++ b/packages/error-reporting/CHANGELOG.md @@ -0,0 +1,29 @@ +# Node.js Agent for Google Cloud Errors ChangeLog + +## 2016-10-03, Version 0.1.0 (Experimental), @matthewloring + +### Notable changes + +**configuration**: + + * [[`4d25c759cd`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/4d25c759cd)] - Update uncaught handler to terminate on timeout #35 (#50) (Cristian Cavalli) + * [[`82b78614f5`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/82b78614f5)] - Remove anonymous function invocation on import and create start method (#44) (Cristian Cavalli) + +### Commits + +* [[`16e15a08bc`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/16e15a08bc)] - Update diagnostics common (#60) (Matthew Loring) [#60](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/pull/60) +* [[`bc03aebd78`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/bc03aebd78)] - Add tests for restify interface (#58) (Cristian Cavalli) +* [[`22fa09a2e0`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/22fa09a2e0)] - Update testUncaught.js with env detection (#57) (Cristian Cavalli) +* [[`be4b47b385`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/be4b47b385)] - Add log-level option to runtime configuration #51 (#54) (Cristian Cavalli) +* [[`6b113f3db7`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/6b113f3db7)] - Update defaults for service context on Error Message #52 (#53) (Cristian Cavalli) +* [[`4d25c759cd`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/4d25c759cd)] - Update uncaught handler to terminate on timeout #35 (#50) (Cristian Cavalli) +* [[`e3c527a03c`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/e3c527a03c)] - Add the Common Diagnostics Logger to Errors (#43) (Cristian Cavalli) +* [[`53b7b5225c`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/53b7b5225c)] - Remove keyfile option from configuration (#49) (Cristian Cavalli) +* [[`82b78614f5`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/82b78614f5)] - Remove anonymous function invocation on import and create start method (#44) (Cristian Cavalli) +* [[`31b24f7580`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/31b24f7580)] - New configuration flow (#36) (Cristian Cavalli) +* [[`04b1c8367a`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/04b1c8367a)] - add tests and fix arguments for manual report (#47) (Ali Ijaz Sheikh) +* [[`4a3896d05a`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/4a3896d05a)] - Avoid using bind in various handlers (#46) (Ali Ijaz Sheikh) +* [[`be6576f90d`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/be6576f90d)] - Minor README and package.json fixes (#45) (Ali Ijaz Sheikh) +* [[`6ae1f38821`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/6ae1f38821)] - Update example text (#42) (Cristian Cavalli) +* [[`cba91ddea9`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/cba91ddea9)] - Fix test quickstart instructions in README (Steren) +* [[`404c72bbf4`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/404c72bbf4)] - README update reportUncaughtExceptions (Steren) diff --git a/packages/error-reporting/CONTRIBUTING.md b/packages/error-reporting/CONTRIBUTING.md new file mode 100644 index 00000000000..718ada1164b --- /dev/null +++ b/packages/error-reporting/CONTRIBUTING.md @@ -0,0 +1,20 @@ +# How to become a contributor and submit your own code + +## Contributor License Agreements + +We'd love to accept your patches! Before we can take them, we have to jump a couple of legal hurdles. + +Please fill out either the individual or corporate Contributor License Agreement (CLA). + + * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html). + * If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html). + +Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests. + +## Contributing A Patch + +1. Submit an issue describing your proposed change to the repo in question. +1. The repo owner will respond to your issue promptly. +1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). +1. Fork the desired repo, develop and test your code changes. +1. Submit a pull request. \ No newline at end of file diff --git a/packages/error-reporting/LICENSE b/packages/error-reporting/LICENSE new file mode 100644 index 00000000000..25dd99930e2 --- /dev/null +++ b/packages/error-reporting/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 Google Inc. + + 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 + + http://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. diff --git a/packages/error-reporting/README.md b/packages/error-reporting/README.md new file mode 100644 index 00000000000..6aa747d6048 --- /dev/null +++ b/packages/error-reporting/README.md @@ -0,0 +1,285 @@ +# Node.js module for Stackdriver Error Reporting + +[![NPM Version][npm-image]][npm-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] +[![Dependency Status][david-image]][david-url] +[![devDependency Status][david-dev-image]][david-dev-url] +[![Known Vulnerabilities][snyk-image]][snyk-url] + +> **This is not an official Google product.** This module is experimental and may not be ready for use. +> This module uses APIs that may be undocumented and are subject to change without notice. + +This modules provides Stackdriver Error Reporting support for Node.js applications. +[Stackdriver Error Reporting](https://cloud.google.com/error-reporting/) is a feature of +Google Cloud Platform that allows in-depth monitoring and viewing of errors reported by +applications running in almost any environment. Here's an introductory video: + +[![Learn about Error Reporting in Stackdriver](https://img.youtube.com/vi/cVpWVD75Hs8/0.jpg)](https://www.youtube.com/watch?v=cVpWVD75Hs8) + +## Prerequisites + +1. Your application needs to use Node.js version 0.12 or greater. +1. You need a [Google Cloud project](https://console.cloud.google.com). Your application can run anywhere, but errors are reported to a particular project. +1. [Enable the Stackdriver Error Reporting API](https://console.cloud.google.com/apis/api/clouderrorreporting.googleapis.com/overview) for your project. +1. The module will only send errors when the `NODE_ENV` environment variable is +set to `production` or the `ignoreEnvironmentCheck` property given in the +runtime configuration object is set to `true`. + +## Quick Start + +1. **Install the module:** + + In your project, on the command line: + + ```shell + # Install through npm while saving to the local 'package.json' + npm install --save @google/cloud-errors + ``` +1. **Instrument your application:** + + ```JS + // Require the library and initialize the error handler + var errors = require('@google/cloud-errors')({ + serviceContext: {service: 'my-service'} // not needed on Google App Engine + }); + + // Report an error to the Stackdriver Error Reporting API + errors.report(new Error('Something broke!')); + ``` + +1. **View reported errors:** + + Open Stackdriver Error Reporting at https://console.cloud.google.com/errors to view the reported errors. + +## Running on Google Cloud Platform + +### Google App Engine flexible environment + +If you are using [Google App Engine flexible environment](https://cloud.google.com/appengine/docs/flexible/), you do not have to do any additional configuration. + +### Google Compute Engine + +Your VM instances need to be created with the `https://www.googleapis.com/auth/cloud-platform` scope if created via the [gcloud](https://cloud.google.com/sdk) CLI or the Google Cloud Platform API, or by enabling at least one of the Stackdriver APIs if created through the browser-based console. + +If you already have VMs that were created without API access and do not wish to recreate it, you can follow the instructions for using a service account under [running elsewhere](#running-elsewhere). + +### Google Container Engine + +Container Engine nodes need to also be created with the `https://www.googleapis.com/auth/cloud-platform` scope, which is configurable during cluster creation. Alternatively, you can follow the instructions for using a service account under [running elsewhere](#running-elsewhere). It's recommended that you store the service account credentials as [Kubernetes Secret](http://kubernetes.io/v1.1/docs/user-guide/secrets.html). + +## Running elsewhere + +If your application is running outside of Google Cloud Platform, such as locally, on-premise, or on another cloud provider, you can still use Stackdriver Errors. + +1. You will need to specify your project ID when starting the errors agent. + + GCLOUD_PROJECT=particular-future-12345 node myapp.js + +1. You need to provide service account credentials to your application. + * The recommended way is via [Application Default Credentials][app-default-credentials]. + 1. [Create a new JSON service account key][service-account]. + 1. Copy the key somewhere your application can access it. Be sure not to expose the key publicly. + 1. Set the environment variable `GOOGLE_APPLICATION_CREDENTIALS` to the full path to the key. The trace agent will automatically look for this environment variable. + * If you are running your application on a development machine or test environment where you are using the [`gcloud` command line tools][gcloud-sdk], and are logged using `gcloud beta auth application-default login`, you already have sufficient credentials, and a service account key is not required. + * Alternatively, you may set the `keyFilename` or `credentials` configuration field to the full path or contents to the key file, respectively. Setting either of these fields will override either setting `GOOGLE_APPLICATION_CREDENTIALS` or logging in using `gcloud`. For example: + + ```JS + // Require and start the agent with configuration options + var errors = require('@google/cloud-errors')({ + // The path to your key file: + keyFilename: '/path/to/keyfile.json', + + // Or the contents of the key file: + credentials: require('./path/to/keyfile.json') + }); + ``` + +On Google App Engine, these environment variables are already set. + +## Configuration + +The following code snippet lists all available configuration options. All configuration options are optional. + +```js +var errors = require('@google/cloud-errors')({ + projectId: 'my-project-id', + keyFilename: '/path/to/keyfile.json', + credentials: require('./path/to/keyfile.json'), + // if true library will attempt to report errors to the service regardless + // of the value of NODE_ENV + // defaults to false + ignoreEnvironmentCheck: false, + // determines if the library will attempt to report uncaught exceptions + // defaults to true + reportUncaughtExceptions: true, + // determines the logging level internal to the library; levels range 0-5 + // defaults to 2 (warnings) + logLevel: 2, + serviceContext: { + service: 'my-service', + version: 'my-service-version' + } +}); +``` + +## Examples + +### Reporting Manually + +```JS +var errors = require('@google/cloud-errors').start(); +// Use the error message builder to custom set all message fields +var errorEvt = errors.event() + .setMessage('My error message') + .setUser('root@nexus'); +errors.report(errorEvt, () => console.log('done!')); +// Or just use a regular error +errors.report(new Error('My error message'), () => console.log('done!')); +// One can even just use a string +errors.report('My error message'); +``` + +### Using Express + +```JS +var express = require('express'); +var app = express(); +// Will create a errors instance based off env variables +var errors = require('@google/cloud-errors')(); + +app.get('/error', function ( req, res, next ) { + res.send('Something broke!'); + next(new Error('Custom error message')); +}); + +app.get('/exception', function () { + JSON.parse('{\"malformedJson\": true'); +}); + +app.use(errors.express); + +app.listen(3000); +``` + +### Using Hapi + +```JS +var hapi = require('hapi'); +var errors = require('@google/cloud-errors')(); + +var server = new hapi.Server(); +server.connection({ port: 3000 }); +server.start(); + +server.route({ + method: 'GET', + path: '/error', + handler: function ( request, reply ) { + throw new Error('Custom error message'); + reply('Something broke!'); + } +}); + +server.register({ register: errors.hapi }); +``` + +### Using Koa + +**Note**: Koa is not supported in Node.js v0.12 unless the `--harmony` flag is enabled. + +```JS +var errors = require('@google/cloud-errors')(); +var koa = require('koa'); +var app = koa(); + +app.use(errors.koa); + +app.use(function *(next) { + //This will set status and message + this.throw('Error Message', 500); +}); + +// response +app.use(function *(){ + this.body = 'Hello World'; +}); + +app.listen(3000); +``` + +### Using Restify + +```JS +function respond(req, res, next) { + next(new Error('this is a restify error')); +} + +var restify = require('restify'); +var errors = require('@google/cloud-errors')(); + +var server = restify.createServer(); + +server.use(errors.restify(server)); +server.get('/hello/:name', respond); +server.head('/hello/:name', respond); + +server.listen(8080); +``` + +## Contributing changes + +Install the dependencies: + +```bash +npm install +``` + +Add your unit tests to: + +``` +tests/unit/ +``` + +Run the test suite: + +```bash +npm test +``` + +Run the coverage suite (will also run the test suite): + +```bash +npm run-script coverage +``` + +Run the style checking suite: + +```bash +npm run-script style +``` + +Pre-commit, run the Pre-commit hook to run Clang Formatter *(Must have Clang + Formatter installed prior to use)* + +```bash +git commit +``` + +*Then commit your changes and make a pull-request* + +[gcloud-sdk]: https://cloud.google.com/sdk/gcloud/ +[app-default-credentials]: https://developers.google.com/identity/protocols/application-default-credentials +[service-account]: https://console.developers.google.com/apis/credentials/serviceaccountkey +[npm-image]: https://badge.fury.io/js/%40google%2Fcloud-errors.svg +[npm-url]: https://npmjs.org/package/@google/cloud-errors +[travis-image]: https://travis-ci.org/GoogleCloudPlatform/cloud-errors-nodejs.svg?branch=master +[travis-url]: https://travis-ci.org/GoogleCloudPlatform/cloud-errors-nodejs +[coveralls-image]: https://coveralls.io/repos/GoogleCloudPlatform/cloud-errors-nodejs/badge.svg?branch=master&service=github +[coveralls-url]: https://coveralls.io/github/GoogleCloudPlatform/cloud-errors-nodejs?branch=master +[david-image]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs.svg +[david-url]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs +[david-dev-image]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs/dev-status.svg +[david-dev-url]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs?type=dev +[snyk-image]: https://snyk.io/test/github/GoogleCloudPlatform/cloud-errors-nodejs/badge.svg +[snyk-url]: https://snyk.io/test/github/GoogleCloudPlatform/cloud-errors-nodejs diff --git a/packages/error-reporting/bin/test.sh b/packages/error-reporting/bin/test.sh new file mode 100755 index 00000000000..58c11ad4a02 --- /dev/null +++ b/packages/error-reporting/bin/test.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +IS_TESTING_LOCALLY=false + +function basicSetup { + export NODE_ENV=production + if [ -d ./test/configuration ]; then + # Remove the old configuration + rm -rf ./test/configuration + fi + mkdir ./test/configuration +} + +function basicTeardown { + unset NODE_ENV + rm -rf ./test/configuration +} + +function trustedSetup { + export GCLOUD_PROJECT=`cat ./test/configuration/stub_project_id.txt` + export STUBBED_API_KEY=`cat ./test/configuration/stub_api_key.txt` + export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/test/configuration/stub_default_credentials.json +} + +function trustedTeardown { + unset GCLOUD_PROJECT + unset STUBBED_API_KEY + unset GOOGLE_APPLICATION_CREDENTIALS +} + +function decryptAcceptanceCredentials { + openssl aes-256-cbc -K $encrypted_7e22a7c28f69_key \ + -iv $encrypted_7e22a7c28f69_iv -in config.tar.enc \ + -out ./test/configuration/config.tar -d \ + && tar xvf ./test/configuration/config.tar +} + +function runFullSuite { + $(npm bin)/nyc report --reporter=text-lcov \ + $(npm bin)/mocha ./test/system-test/*.js ./test/unit/*.js \ + ./test/fixtures/*.js | \ + $(npm bin)/coveralls coveralls && rm -rf ./coverage +} + +function runUnitSuite { + $(npm bin)/nyc report --reporter=text-lcov \ + $(npm bin)/mocha ./test/unit/*.js | \ + $(npm bin)/coveralls && rm -rf ./coverage +} + +function run { + basicSetup + if [ "$IS_TESTING_LOCALLY" = "true" ] + then + echo "Running integration and unit suites in local development mode" + runFullSuite + elif [ "$TRAVIS_TRUSTED_INTERNAL_MERGE" = "true" ] + then + echo "Running integration and unit suites in container mode" + decryptAcceptanceCredentials + trustedSetup + runFullSuite + trustedTeardown + else + echo "Running unit suite" + runUnitSuite + fi + basicTeardown +} + +while getopts "l" opt +do + case $opt in + l) + IS_TESTING_LOCALLY=true + ;; + esac +done + +run \ No newline at end of file diff --git a/packages/error-reporting/config.tar.enc b/packages/error-reporting/config.tar.enc new file mode 100644 index 0000000000000000000000000000000000000000..ed17326de570eff6820ab5ed1b0d8009476e7fc4 GIT binary patch literal 9232 zcmV+rB=6hr0IYH{j!loT!9hObHJy7}mrQpR&908QnM$XKuhfFOpx#x9%n~Ik80EXj zHwG2S41-?H?=R;G)LD-c&Zv{DRQ-(SJynpf4e3R)d; z#uda4I5U8;PjwGFNmD{Zdtv&Wa+S#L7%Wml9+35zs*qz~5g8?O-Cq+U`=dTuXW z&ZPvf$2J;fPmh~Lw+HZ+sc2$VT27ZcMwF@WL@uf6(Up%J^_f%|P@K`_8upHpJ6ZR`PU;+LDPG>nDBGTObaWG5A z)ed9Afh7S8V`8m&|E7Bt2Ui<5QW|Gm6tt`C%#j1WF8kxyV7^9?$3b3s=f4D5^^^kgS+TUTqD*xOGiP6;@iqTQ??>#5^1CIgQvsEaKX;Qd!^`TtOWst3;rK|2eP_3fasAf|vm*@+O zT(HcaYWMm|xiOpa!a9W>ZG9sm@RjbQTTDV@Bj=PFthN9`03F_`KYV}g zPtpEL{Qz}jG&RT;3lzqRV0H>J{O!;_=bt-Xx#r--VwFJ0qopwR4F9o+OJR)Cw`20s z3g2RXc}?PG6k_evg{)V&YJO^o#Sn&62h5-dq`*tf0Dr_1K@08S0r?@R(x$4kPR^r0 z|B7W|(yW)_7e!qxpcSL!^Kw#(#8pSg$O11tX&MTG$OKo^#MmdMNpyc}Uu-zfKo{W^q{2Q_ zxA0a)?$H)Z{#Z&Up(4_Fu*dVBiO#gWv`cKq9>EHjSFJ67pl~thMcr>ZsOO_Z78Tzu zt90%Lt$$ z0coT%5c%o@e>ax7pj0`vP6?dd_nw*I?~hLp1F@X3c&l;4I?C9{6}>PWIgwAA=kzij zH}H$n!k7$mwL^d5Le`h6nYBfsfP&5dqwvxt?3_KUY2D(ckul*?p>u*|)+?{A+u zsh09PL@cRi>w7b~_dr~mh`T0?ZxJ`g7ZquHG@Bgff&ZOyie0*A9zok*@tFkxph(9B zyX&BqT;Z#+pKO^|NJ_YW zuJm^JU6KPQp5y zWj8t9B}0`tC_0>*_^GOu4(n_x#G&?L5h3%yYB24-dM-=Pc2{nPCl;&MR~V#4T}tt5+kI(%bBO(SZ9x`BeZ_ZqVj!7ZD*yGLo|pVk=p6q8|vn`G~cn!Hi zDOIRqDiF4H5Vc9Q#j-H4HZ8S0x)k2;S{ zW}?CARjg|ik<*>JB)i8j69#2%7SXUad?V`NSF4`X)8V{h{*E-%3Bqr){#Y3*Am}+N z=XazjGyWeML8V#b$W|YcJn9Q^A)0&}hipGzhaNYm<69zO-vuliTqbvPP!JMV(DIm!RhLlkD6`K zE1cr@5%MvjK|A@*$Br8qd^?A6WS**K&#yH(uo?$rOW@p=t|;`k&%~d!ZJv=hFHNd_ zwIo*({!Ip7&nJB>Q00;Lm?4|kZqk;qADKHe_Dvjq_NBo4H3eK_adjCmhf zD2>Vhm~8n3#lEcaS)JcXHdjaO1cw%?XzQo-%^@mo+9}hLQd{8|`2;`f0;S?L%y79) z@M2MknOmyTM*7#6T;_Gc{qx3Nh;QsaCRXQ!z91FY`X09>i}CmDhb7{JXQh%;E^ILJLbkMxI7PPz4SDh~K2Z8C!(e~*S#0=ocrkhy#U(E{V z%pX1|^SShgbIaIa(7tv>=A4?9ovmT%CFz7a6W=;`ef_KZ1k70myVP5+6a0O@^27^p zmLIzR0=06)f!Db5yf;8U8=~0Hm$CW&)XKitG|(Kg?d7Lr)nar|gecy=m|1fjO%sa% z`~{ZVo0-wpMyQN!pE+t3fhM4sK*h>3%0k+5XN-&bNFiCO)6On)QpCf{7;P5x+;bUk z&CsSYK6Bd4L~4B{Fd*%xrLR;=biiOcs>3*a4>KEDQj*T2hML29I-Xe&Cxt0%7TM#FKmWmUU zzEhJD@@{hdsZ!elV)Tc{aC>}bi zDk7Gxy8>y&)Lzv+e1cwJ%ayICj^EFy10)||2GprW>{O0UoRjY~l@jpEMShGE!@&)* z4>FKvGSQ)h-FzLXkLAr3oiGmYXi+%T zE;^YDXK6ihn@}6C@D@3{<5Jhnn2tBLbwBvmwSm2;m*lXX{ny3c3B#oQ%6a8f50k`8ATf<0I1H=FttC-0;m?AiOh)R(GJl zWnclQ;b%f6)dhOy%bBPba%f50I9S|X;!FtN7Sgaq_vBIQnp3C#Vn7hlkK4hUjYu-- zk!$OR-0gGv17!t*gjCb3%{@KjmXuC|Kf&!N@M;N>AIDh)ssk18T-3B;SUnhaTQ4S% z*6LjiJp3u_(!9FIh{)g;%msf0YaM5W4iYE3N8nwPw(3Dy>L{+$F$HP>K8s^{I#mMo z?77PesT~Nl z{!7n<&xQuj`MPPUvnlv5q<)po2$ZBdL9O6xuQdYu`HiEp=BZy(MJA%~Mx@v_FsF`|yjtba%ocex>|ivUvgxA2J6bf9N9(L! z8uv_krTcr|T{N=w`LqgJDMu4fNQ1AXRgprAPPvN0(t4*r5D=Lv0naa*bm-ewsV{#f ziZGPf>^5v+Go8^$k+|o?luX>7%-S01c9#P-shD+DSP$F4OW^4r8w*^~#7dqKL2l*H z@dY>Uzt)X~e%F>@$bi?QrudF#%%S$H`gg^2`jxju9~KKp)1^x9MTD?bzE$8e zAjd&BWlz5&N8$;b0A*T)fBOf7$>b80dP7-F!+ z?Vc&_U?0Pl$msmxYp#9cSwoHNugN>T{=f=qa0}bk>1*h(Gc#WQKr?4nGKjATp8vA( zo_^4&`b1iA9MLQ0L9#Qg5EwUNIU~W|X~vWE9U}nb&7n76(2hV>M8udR4cAj$g8XLP zRxQ%mJMX@-nbBZuLhpIrXmK&pXsq}#g_9pf^~cH zT{i$fuvrv_ZbGP2(q%s!8hgr&c3)NNMSUA^9DQH(GT z;)@^3Z51QSu6fUFThmSkeMvd)G$M=F|h{76@N9XE=oK5GU)4w7e}j`v_>-(7iVZix?;ro~0X0F7V=tcVMnu)35b*T2MhK&j9%&yj zPOpG=9jsj{H*JyN z>tGC^k#pW(jxfZZBh+_1R2fKBh_`5(dsDjanrH_1{*&wpTavV_Z)2@_=5X|iSX%|$ z-;CQ#AQ^_4lAPEodp-DyWzhK;g1ON|LlJ%k$;KW#^HgwX9krtmEv|A}X~{zuwE>&3 z7Q?FlfqIYEuE&C_lJ9Jv!>46$A1VOeke_9@8fPNGT9wEW~Pg^#Yq6Vp;E z+j;32a&ZSUE$dkzM}&RWHON|IhA?ZSOANEqpeZxy-g`7Sg}dFw<^iCwxT;k@sJ3on zDt1Y~0@G0g2g>sr9(fA&Ob>IKGlz!v1A3qX|84Q6AAz1iE&%#Ep#mB7w^9z}`66=@ z(oE=rEUcckIcsV1HW2_@+dyJ&QtKhhq#Mq0QMe+D?j5->G5WM6r84B?I0%>k&~luR zKx!O3B&$bH(M6ETpYDqh;rUt+<-2o>{fzU2UKZ`*V*r`h|Vr=%0=gvvuDGDrjD~r=%t@(s#LsMn5{5Ci9VOX)M2oalQ2NsLd zA!)r=o#Xrp&RX{)s6vIlqHZdAa-26h>p+l0J3k&%KCWxNuB#7Q-t7wX_F5>G92IuHvNQ9P5Jn^m?$5n$i)*xA9=CCE}+g(i3l) zrqmAC*KdRbXvGJYL^M#b32_MM)u|(UO}ggM1JFgl)uwg;A?o){>H=u8qB9A9S#|B7 z4OeVW()6^WLQ{pHYtTzcOU!hPL?}N@uF+WsBO`roO@&>nMWX(p#4!*d+CYzkiq+mK;HdWMscR=_#H#Kj8~6ks zF{3F;Ax&!6{E#=yBN$x;0&QtAhwkGSm+NWz%sI$?`X=tu`2k}gafXBomm^}a(h(Ek zFrIeRZKPTkn=-{NqhZP;#<2K7Baa`xymlaRdX`K&OT3(a`hKdo$SJ8J3%xlqK~jRG z%+x6%K;jC`&1l~KFIp85Aohe8GuAHbVS?jlOK{tW2<0`q{&`yM`*LOmVH6Q%U zBd@q7DVcr{o}ihy9V91a$q(P_D4_Qc=M#ul$;bDk+=rI097eHA52xZBA#gI`LpRlf zxh@RnWT@H#wrjPecq@u`pxRZqUE6W|kKW)CZ%X)-kwoE^iG{3tnG$OZ7z#n;!)F$& zUWUuM3$OPBmqR+UW~pBNMB!$J%24um-0xSb^AuUUg~wwUMQ@Wwnb7u71YC$w`mc%R z3qT}Gb2Ft8HpLXfzD|?j89hCfrrT100|jDqQS_XQJ!&Ra|ce zT@XHVA}ZjJ9_;n23L>>?+&VCRA&iv1tcZBXCbaPN<}8LiJku;3eHUa+X>Zm_-|flc znV#i!)SLY?HZi=*gH19hMaY@jdlA4E!+}aHyvZScOZ+-w8TAh|LRs`O~B9{4f>pJSX2AF46w(LFg+uJ9~pa_~Cyg~&MTqy`${=ZbEIYD~A#8~T6 zRT@f5YfTz>yW*0?aSOoVY3dUP@GPBbSqsib{p;m}y)3ub9Vw&CbUWz70awi=B@UPo z3J69F6WLg2rQb0%_x1%xGhW^{0lRI!GcUc(lQxB?OWc$yfo!1Zeri`4En5 zp-o6BK|e}Q#+il4{xnK+XxC&{z%deL$Iu=M@b|Z+WC*a2jpEfYkGz3f;p{k{QmcGQ zzxaW03X1v3_oC`D96K=0v6npg=2_wCCDg=^UjN34GM7g~(ISReKNKL4&cMX~j=}Ti z8Pca2Q=fXCju|*&OMOa1T~;ob3HSP=J2}nMLP$a~chE#Nsq6qkg5NjY5e*qT5H?6O zIpj{Rn6pe53G#K3YoGKa?D3z8=(w{piieeFR!&5p+Kh8C;%WhoqvSdO@v%wE3~ebT zPNWc#;cy8Ktg~mpos*$vhw4mWAK@ZPATeI?v;5~Ya4lDZw)SjLZA!Q?rWb)@*P38L zVm4%AgDn_vMWl#rwnzB>o{fXE$`pHhM*81}lCI>6STSoBy{h)jZhVowyF8&5lO|!| z65xjN+caF_==`c~^7GVPt3S%#JdJ?^tL>Q9D1kjeHK=4{=tozHjJyKP{}SkT(wCO? z3_lE1Bi6^H(37f?`*x96<)=S}ZvhDL&j2>*(o!W^5V(f?2I(tA+-U4{uOeaBNHBnP z>lLv>%4(lp8?QH{RE#|-jw@!EC$cN}&Jr<^$F26P{$neq<@Tn8RbALGh*{w3Y4tTW z%6`6>ZOc}RqV2L}k^LAf9dyW8LT87C!8ye9U@xX}Qm{Nr0!YGljx;!5^x~`PuD9w- z(&yNH9Ckd;^QX!OA~?8ZE40%<%4QvA?N)L-VkrWYO^V>q3Sm7Vz6Pbd$0l#p56 z>%6V|Qw#sLoJy+2&iT9I2k8)^0Up+2#xAhBpHjB{uAs&qhW)Xy*hyz^q>dF^w}VWX zwCOns5g0JV4sB9xD$k0q$nYqBbloFQPxaAqbxUrpK)rD6-|FcT4S{n9 zoi&XWymj8wFsdp0>U8eDxNS+xH*blOy(9X14h5IBHTO{0lYy_%^;4HKQq_bE{rzHC z`UMh$CP%ZkKV~Hx=YS#g#O*jjX00($dMwzS`6k{yTTX*y%0@CxDS((#Vp6dsh-Ekc zf(HvaR0#&s=f{vIKjuNg?}jJ$!_>cE{hPPwb}aj24PJ=u!`Nj_U#c)$*c4Et+BA;< zl9L;?Lt0J}9!1>LqG$@-fAH}az|>X2EAdLR%lP7VC=s6<75RTr0Fsi8eVdZ-rw5QE zd;iu{SOs(O(q2dG$+AIce$PiQielywwB)~ItaPKJe37v7ed-~ZZuGy6_>B*X5AUkJ zy?#mze6K;M3S@C|*G!;p;dXkcdQwk1(Fi+hukYu-&tuvkBF_M~nBX9df5`Z+~&VIV48&DPLaMEDfTB4qh+3kqvM~KaS6RA14Ka!4~G21+9T58J7y}5v`OK zE1uu6X%WY<9Ze&C(nS-5OIl(}zO*lIpK_;zt&|&hXRyyJ1|dsDuFBX7IGC5d<^m$p zlV_k2*YtBJ0idX56$Pkp_LoOlJ_C!w+xjOf{V-W!yv%Lflfr@j$BmTFidpw&>+qU1MhmboLWfnS!q;6ZX+7#?ukhP&6bOpd<1E-uBmU;Kx|(cz_%)*RYu z2}qO~97QB3;_&wQwvWpji&fg1-glr@5eLdhLh>P*9rwi!pRI9#nrFgEM$NM1hYe%7 zMe0pm8Oy>EF@gilmAJvy+)1s%^C+n2<-_uV;o^)ZYgR1icF1H_)+61b*O;g$bQgv< zZSiRc*4$xPf3}-q)fDj%juUzGH3L$gR7?kbDVWLrq2Krf*>uxyuflfC!)oYJ-c~0= zwB6)XXzn%0C{Ve}96w!;U2?jQwBwU@F!@ybq*Ecj+@+abn+eW%7a>zkg@b|Y`S-(f zg&g1mkD{(l8B*;DYFJ=+li8a6asr1U*b(XX&C9 zO#}EvB6%o2Y43lqFWh}VNF61*hIt*2D$b_9$H4K^-hI{+c|OFL+u`v7ixqu&r{Fyr z71#?;VEZ7^`SL<+k3R1y`Cn^r@L7_xy^WxR?udu?|7Y|-O^v}MuBKknHt1mX1H%yF=R}l6(}MV45H@78`W4mUUA;Nx6|<% zl1GFY#X@Sr$NQ}1)!okBAH-XiDt@PaI&fal^^d_{Ie8^$b{4Yo5b_(|9on;{6l8D} zOEkY%L0U_7w|lxnFV%A%J0PdK2HPe`RqW=5=Q1m1{i0Upv&gVasF*fZBz;3S~5E#^E`Z**eR1c&hv5yL10p63^nXQcy+kOG*6Mmf^gus-#fl z7K~BlM#<3<=W-VI0Eo_!qJSiICC7`vdV;pnv#$QESuPM#%a*3^C0lrj(Nm!seU&}V zhcCPAt`@v9wc&iMrbSlMS9%e8hQJ;t~zS@lA1`mgTI zZeN0CddHTcNFOT|pMd4vLww+uyu|uvkB?9FLeHcgQLv^#ZsOd^W%V?zDAF z#;q&} list of scopes needed to work with the errors api. */ +var SCOPES = ['https://www.googleapis.com/auth/cloud-platform']; + +/* @const {String} Base Error Reporting API */ +var API = 'https://clouderrorreporting.googleapis.com/v1beta1/projects'; + +/** + * The RequestHandler constructor initializes several properties on the + * RequestHandler instance and create a new request factory for requesting + * against the Error Reporting API. + * @param {Configuration} config - The configuration instance + * @param {Object} logger - the logger instance + * @class RequestHandler + * @classdesc The RequestHandler class provides a centralized way of managing a + * pool of ongoing requests and routing there callback execution to the right + * handlers. The RequestHandler relies on the diag-common request factory + * and therefore only manages the routing of execution to the proper callback + * and does not do any queueing/batching. The RequestHandler instance has + * several properties: the projectId property is used to create a correct url + * for interacting with the API and key property can be optionally provided a + * value which can be used in place of default application authentication. The + * shouldReportErrors property will dictate whether or not the handler instance + * will attempt to send payloads to the API. If it is false the handler will + * immediately call back to the completion callback with a constant error value. + * @property {Function} _request - a npm.im/request style request function that + * provides the transport layer for requesting against the Error Reporting API. + * It includes retry and authorization logic. + * @property {String} _projectId - the project id used to uniquely identify and + * address the correct project in the Error Reporting API + * @property {Object} _logger - the instance-cached logger instance + */ +function RequestHandler(config, logger) { + this._request = commonDiag.utils.authorizedRequestFactory(SCOPES, { + keyFile: config.getKeyFilename(), + credentials: config.getCredentials() + }); + this._config = config; + this._logger = logger; +} + +/** + * Compute the URL that errors should be reported to given the projectId and + * optional key. + * @param {String} projectId - the project id of the application. + * @param {String|Null} [key] - the API key used to authenticate against the + * service in place of application default credentials. + * @returns {String} computed URL that the errors should be reported to. + * @private + */ +function getErrorReportURL(projectId, key) { + var url = [API, projectId, 'events:report'].join('/'); + if (isString(key)) { + url += '?key=' + key; + } + return url; +} + +/** + * Creates a request options object given the value of the error message and + * will callback to the user supplied callback if given one. If a callback is + * not given then the request will execute and silently dissipate. + * @function sendError + * @param {ErrorMessage} payload - the ErrorMessage instance to JSON.stringify + * for submission to the service + * @param {RequestHandler~requestCallback} [userCb] - function called when the + * request has succeeded or failed. + * @returns {Undefined} - does not return anything + */ +RequestHandler.prototype.sendError = function(errorMessage, userCb) { + var self = this; + var cb = isFunction(userCb) ? userCb : function() {}; + if (self._config.getShouldReportErrorsToAPI()) { + self._config.getProjectId(function (err, id) { + if (err) { + setImmediate(function () { cb(err, null, null); }); + self._logger.error([ + 'Unable to retrieve a project id from the Google Metadata Service or', + 'the local environment. Client will not be able to communicate with', + 'the Stackdriver Error Reporting API without a valid project id', + 'Please make sure to supply a project id either through the', + 'GCLOUD_PROJECT environmental variable or through the configuration', + 'object given to this library on startup if not running on Google', + 'Cloud Platform.' + ].join(' ')); + return; + } + self._request({ + url: getErrorReportURL(id, self._config.getKey()), + method: 'POST', + json: errorMessage + }, function (err, response, body) { + if (err) { + self._logger.error([ + 'Encountered an error while attempting to transmit an error to the', + 'Stackdriver Error Reporting API.' + ].join(' '), err); + } + cb(err, response, body); + }); + }); + } else { + cb(new Error([ + '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(' ')), null, null); + } +}; +/** + * The requestCallback callback function is called on completion of an API + * request whether that completion is success or failure. The request can either + * fail by reaching the max number of retries or encountering an unrecoverable + * response from the API. The first parameter to any invocation of the + * requestCallback function type will be the applicable error if one was + * generated during the request-response transaction. If an error was not + * generated during the transaction then the first parameter will be of type + * Null. The second parameter is the entire response from the transaction, this + * is an object that as well as containing the body of the response from the + * transaction will also include transaction information. The third parameter is + * the body of the response, this can be an object, a string or any type given + * by the response object. + * @callback RequestHandler~requestCallback cb - The function that will be + * invoked once the transaction has completed + * @param {Error|Null} err - The error, if applicable, generated during the + * transaction + * @param {Object|Undefined|Null} response - The response, if applicable, received + * during the transaction + * @param {Any} body - The response body if applicable + */ + +module.exports = RequestHandler; diff --git a/packages/error-reporting/src/interfaces/express.js b/packages/error-reporting/src/interfaces/express.js new file mode 100644 index 00000000000..332549aa2b9 --- /dev/null +++ b/packages/error-reporting/src/interfaces/express.js @@ -0,0 +1,81 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var is = require('is'); +var isObject = is.object; +var isFunction = is.fn; +var ErrorMessage = require('../classes/error-message.js'); +var expressRequestInformationExtractor = + require('../request-extractors/express.js'); +var errorHandlerRouter = require('../error-router.js'); + +/** + * Returns a function that can be used as an express error handling middleware. + * @function makeExpressHandler + * @param {AuthClient} client - an inited Auth Client instance + * @param {NormalizedConfigurationVariables} config - the environmental + * configuration + * @returns {expressErrorHandler} - a function that can be used as an express + * error handling middleware. + */ +function makeExpressHandler(client, config) { + /** + * The Express Error Handler function is an interface for the error handler + * stack into the Express architecture. + * @function expressErrorHandler + * @param {Any} err - a error of some type propagated by the express plugin + * stack + * @param {Object} req - an Express request object + * @param {Object} res - an Express response object + * @param {Function} next - an Express continuation callback + * @returns {ErrorMessage} - Returns the ErrorMessage instance + */ + function expressErrorHandler(err, req, res, next) { + var ctxService = ''; + var ctxVersion = ''; + + if (config.lacksCredentials()) { + next(err); + } + + if (isObject(config)) { + ctxService = config.getServiceContext().service; + ctxVersion = config.getServiceContext().version; + } + + var em = new ErrorMessage() + .consumeRequestInformation( + expressRequestInformationExtractor(req, res)) + .setServiceContext(ctxService, ctxVersion); + + errorHandlerRouter(err, em); + + if (isObject(client) && isFunction(client.sendError)) { + client.sendError(em); + } + + if (isFunction(next)) { + next(err); + } + + return em; + } + + return expressErrorHandler; +} + +module.exports = makeExpressHandler; diff --git a/packages/error-reporting/src/interfaces/hapi.js b/packages/error-reporting/src/interfaces/hapi.js new file mode 100644 index 00000000000..28009a56091 --- /dev/null +++ b/packages/error-reporting/src/interfaces/hapi.js @@ -0,0 +1,127 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var is = require('is'); +var isObject = is.object; +var isFunction = is.fn; +var ErrorMessage = require('../classes/error-message.js'); +var hapiRequestInformationExtractor = require('../request-extractors/hapi.js'); +var errorHandlerRouter = require('../error-router.js'); + +/** + * The Hapi error handler function serves simply to create an error message + * and begin that error message on the path of correct population. + * @function hapiErrorHandler + * @param {Object} req - The Hapi request object + * @param {Any} err - The error input + * @param {Object} config - the env configuration + * @returns {ErrorMessage} - a partially or fully populated instance of + * ErrorMessage + */ +function hapiErrorHandler(req, err, config) { + var service = ''; + var version = ''; + + if (isObject(config)) { + service = config.getServiceContext().service; + version = config.getServiceContext().version; + } + + var em = new ErrorMessage() + .consumeRequestInformation(hapiRequestInformationExtractor(req)) + .setServiceContext(service, version); + + errorHandlerRouter(err, em); + + return em; +} + + +/** + * Creates a Hapi plugin object which can be used to handle errors in Hapi. + * @param {AuthClient} client - an inited auth client instance + * @param {NormalizedConfigurationVariables} config - the environmental + * configuration + * @returns {Object} - the actual Hapi plugin + */ +function makeHapiPlugin(client, config) { + + /** + * The register function serves to attach the hapiErrorHandler to specific + * points in the hapi request-response lifecycle. Namely: it attaches to the + * 'request-error' event in Hapi which is emitted when a plugin or receiver + * throws an error while executing and the 'onPreResponse' event to intercept + * error code carrying requests before they are sent back to the client so + * that the errors can be logged to the Error Reporting API. + * @function hapiRegisterFunction + * @param {Hapi.Server} server - A Hapi server instance + * @param {Object} options - The server configuration options object + * @param {Function} next - The Hapi callback to move execution to the next + * plugin + * @returns {Undefined} - returns the execution of the next callback + */ + function hapiRegisterFunction(server, options, next) { + if (isObject(server)) { + if (isFunction(server.on)) { + server.on('request-error', function(req, err) { + var em = hapiErrorHandler(req, err, config); + + if (!config.lacksCredentials()) { + client.sendError(em); + } + }); + } + + if (isFunction(server.ext)) { + server.ext('onPreResponse', function(request, reply) { + var em = null; + + if (isObject(request) && isObject(request.response) && + request.response.isBoom) { + em = hapiErrorHandler(request, new Error(request.response.message), + config); + + if (!config.lacksCredentials()) { + client.sendError(em); + } + } + + if (isObject(reply) && isFunction(reply.continue)) { + reply.continue(); + } + }); + } + } + + if (isFunction(next)) { + return next(); + } + } + + var hapiPlugin = {register : hapiRegisterFunction}; + var version = (isObject(config) && config.getVersion()) ? + config.getVersion() : '0.0.0'; + + hapiPlugin.register.attributes = { + name : '@google/cloud-errors', + version : version + }; + + return hapiPlugin; +} + +module.exports = makeHapiPlugin; diff --git a/packages/error-reporting/src/interfaces/koa.js b/packages/error-reporting/src/interfaces/koa.js new file mode 100644 index 00000000000..8e3768aa4b1 --- /dev/null +++ b/packages/error-reporting/src/interfaces/koa.js @@ -0,0 +1,68 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var ErrorMessage = require('../classes/error-message.js'); +var koaRequestInformationExtractor = require('../request-extractors/koa.js'); +var errorHandlerRouter = require('../error-router.js'); + +/** + * The koaErrorHandler should be placed at the beginning of the koa middleware + * stack and should catch the yield of the output of the request handling chain. + * The Koa error handler returns the actual error handler which will be used in + * the request chain handling and this function corresponds to the format given + * in: https://github.com/koajs/koa/wiki/Error-Handling. + * @function koaErrorHandler + * @param {AuthClient} - The API client instance to report errors to Stackdriver + * @param {NormalizedConfigurationVariables} - The application configuration + * @returns {Function} - The function used to catch errors yielded by downstream + * request handlers. + */ +function koaErrorHandler(client, config) { + + /** + * The actual error handler for the Koa plugin attempts to yield the results + * of downstream request handlers and will attempt to catch errors emitted by + * these handlers. + * @param {Function} next - the result of the request handlers to yield + * @returns {Undefined} does not return anything + */ + return function * (next) { + var em; + var svc = config.getServiceContext(); + + try { + + yield next; + } catch (err) { + if (config.lacksCredentials()) { + return; + } + + em = new ErrorMessage() + .consumeRequestInformation( + koaRequestInformationExtractor(this.request, this.response)) + .setServiceContext(svc.service, + svc.version); + + errorHandlerRouter(err, em); + + client.sendError(em); + } + }; +} + +module.exports = koaErrorHandler; diff --git a/packages/error-reporting/src/interfaces/manual.js b/packages/error-reporting/src/interfaces/manual.js new file mode 100644 index 00000000000..f2c7230158f --- /dev/null +++ b/packages/error-reporting/src/interfaces/manual.js @@ -0,0 +1,103 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var is = require('is'); +var isString = is.string; +var isObject = is.object; +var isFunction = is.fn; +var ErrorMessage = require('../classes/error-message.js'); +var manualRequestInformationExtractor = + require('../request-extractors/manual.js'); +var errorHandlerRouter = require('../error-router.js'); + +/** + * The handler setup function serves to produce a bound instance of the + * reportManualError function with no bound context, a bound first arugment + * which is intended to be an initialized instance of the API client and a bound + * second argument which is the environmental configuration. + * @function handlerSetup + * @param {AuthClient} client - an initialized API client + * @param {NormalizedConfigurationVariables} config - the environmental + * configuration + * @returns {reportManualError} - a bound version of the reportManualError + * function + */ +function handlerSetup(client, config) { + /** + * The interface for manually reporting errors to the Google Error API in + * application code. + * @param {Any|ErrorMessage} err - error information of any type or content. + * This can be of any type but by giving an instance of ErrorMessage as the + * error arugment one can manually provide values to all fields of the + * potential payload. + * @param {Object} [request] - an object containing request information. This + * is expected to be an object similar to the Node/Express request object. + * @param {String} [additionalMessage] - a string containing error message + * information to override the builtin message given by an Error/Exception + * @param {Function} [callback] - a callback to be invoked once the message + * has been successfully submitted to the error reporting API or has failed + * after four attempts with the success or error response. + * @returns {ErrorMessage} - returns the error message created through with + * the parameters given. + */ + function reportManualError(err, request, additionalMessage, callback) { + var em; + if (config.lacksCredentials()) { + return; + } + if (isString(request)) { + // no request given + callback = additionalMessage; + additionalMessage = request; + request = undefined; + } else if (isFunction(request)) { + // neither request nor additionalMessage given + callback = request; + request = undefined; + additionalMessage = undefined; + } + + if (isFunction(additionalMessage)) { + callback = additionalMessage; + additionalMessage = undefined; + } + + if (err instanceof ErrorMessage) { + em = err; + } else { + em = new ErrorMessage(); + em.setServiceContext(config.getServiceContext().service, + config.getServiceContext().version); + errorHandlerRouter(err, em); + } + + if (isObject(request)) { + em.consumeRequestInformation(manualRequestInformationExtractor(request)); + } + + if (isString(additionalMessage)) { + em.setMessage(additionalMessage); + } + + client.sendError(em, callback); + return em; + } + + return reportManualError; +} + +module.exports = handlerSetup; diff --git a/packages/error-reporting/src/interfaces/message-builder.js b/packages/error-reporting/src/interfaces/message-builder.js new file mode 100644 index 00000000000..c22f3c11cc0 --- /dev/null +++ b/packages/error-reporting/src/interfaces/message-builder.js @@ -0,0 +1,44 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var ErrorMessage = require('../classes/error-message.js'); + +/** + * The handler setup function serves to produce a bound instance of the + * of a factory for ErrorMessage class instances with configuration-supplied + * service contexts automatically set. + * @function handlerSetup + * @param {NormalizedConfigurationVariables} config - the environmental + * configuration + * @returns {ErrorMessage} - a new ErrorMessage instance + */ +function handlerSetup(config) { + /** + * The interface for creating new instances of the ErrorMessage class which + * can be used to send custom payloads to the Error reporting service. + * @returns {ErrorMessage} - returns a new instance of the ErrorMessage class + */ + function newMessage() { + return new ErrorMessage().setServiceContext( + config.getServiceContext().service, + config.getServiceContext().version); + } + + return newMessage; +} + +module.exports = handlerSetup; diff --git a/packages/error-reporting/src/interfaces/restify.js b/packages/error-reporting/src/interfaces/restify.js new file mode 100644 index 00000000000..df03996aae4 --- /dev/null +++ b/packages/error-reporting/src/interfaces/restify.js @@ -0,0 +1,159 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var is = require('is'); +var isObject = is.object; +var isFunction = is.function; +var ErrorMessage = require('../classes/error-message.js'); +var expressRequestInformationExtractor = + require('../request-extractors/express.js'); +var errorHandlerRouter = require('../error-router.js'); + +/** + * The restifyErrorHandler is responsible for taking the captured error, setting + * the serviceContext property on the corresponding ErrorMessage instance, + * routing the captured error to the right handler so that it can be correctly + * marshaled into the ErrorMessage instance and then attempting to send it to + * the Stackdriver API via the given API client instance. + * @function restifyErrorHandler + * @param {AuthClient} client - the API client + * @param {NormalizedConfigurationVariables} config - the application + * configuration + * @param {Any} err - the error being handled + * @param {ErrorMessage} - the error message instance container + * @returns {Undefined} - does not return anything + */ +function restifyErrorHandler(client, config, err, em) { + var svc = config.getServiceContext(); + em.setServiceContext(svc.service, svc.version); + + errorHandlerRouter(err, em); + + client.sendError(em); +} + +/** + * The restifyRequestFinishHandler will be called once the response has emitted + * the `finish` event and is now in its finalized state. This function will + * attempt to determine whether or not the body of response is an instance of + * the Error class or its status codes indicate that the response ended in an + * error state. If either of the preceding are true then the restifyErrorHandler + * will be called with the error to be routed to the Stackdriver service. + * @function restifyRequestFinishHandler + * @param {AuthClient} client - the API client + * @param {NormalizedConfigurationVariables} config - the application + * configuration + * @param {Object} req - the restify request + * @param {Object} res - the restify response + * @returns {Undefined} - does not return anything + */ +function restifyRequestFinishHandler(client, config, req, res) { + var em; + + if (res._body instanceof Error || + res.statusCode > 309 && res.statusCode < 512) { + em = new ErrorMessage().consumeRequestInformation( + expressRequestInformationExtractor(req, res)); + + restifyErrorHandler(client, config, res._body, em); + } +} + +/** + * The restifyRequestHandler attaches the restifyRequestFinishHandler to each + * responses 'finish' event wherein the callback function will determine + * whether or not the response is an error response or not. The finish event is + * used since the restify response object will not have any error information + * contained within it until the downstream request handlers have had the + * opportunity to deal with the request and create a contextually significant + * response. + * @function restifyRequestHandler + * @param {AuthClient} client - the API client + * @param {NormalizedConfigurationVariables} config - the application + * configuration + * @param {Object} req - the current request + * @param {Object} res - the current response + * @param {Function} next - the callback function to pass the request onto the + * downstream request handlers + * @returns {Any} - the result of the next function + */ +function restifyRequestHandler(client, config, req, res, next) { + var listener = {}; + + if (isObject(res) && isFunction(res.on) && isFunction(res.removeListener)) { + + listener = function() { + + restifyRequestFinishHandler(client, config, req, res); + res.removeListener('finish', listener); + }; + + res.on('finish', listener); + } + + return next(); +} + +/** + * The serverErrorHandler is the actual function used by the restify error + * handling stack and should be used as a bound instance with its first two + * arguments (client & config) bound to it. The serverErrorHandler function must + * be given the restify server instance as a parameter so that it can listen + * to the `uncaughtException` event in the restify request handling stack. This + * event is emitted when an uncaught error is thrown inside a restify request + * handler. This init function will return the actual request handler function + * which will attach to outgoing responses, determine if they are instances of + * errors and then attempt to send this information to the Stackdriver API. + * @function serverErrorHandler + * @param {AuthClient} client - the API client + * @param {NormalizedConfigurationVariables} config - the application + * configuration + * @param {Object} server - the restify server instance + * @returns {Function} - the actual request error handler + */ +function serverErrorHandler(client, config, server) { + + server.on('uncaughtException', function(req, res, reqConfig, err) { + if (config.lacksCredentials()) { + return; + } + var em = new ErrorMessage().consumeRequestInformation( + expressRequestInformationExtractor(req, res)); + + restifyErrorHandler(client, config, err, em); + }); + + return restifyRequestHandler.bind(null, client, config); +} + +/** + * The handler setup function serves to provide a simple interface to init the + * the restify server error handler by binding the needed client and config + * variables to the error-handling chain. + * @function handlerSetup + * @param {AuthClient} client - the API client + * @param {NormalizedConfigurationVariables} config - the application + * configuration + * @returns {Function} - returns the serverErrorHandler function for use in the + * restify middleware stack + */ +function handlerSetup(client, config) { + + return serverErrorHandler.bind(null, client, config); +} + +module.exports = handlerSetup; diff --git a/packages/error-reporting/src/interfaces/uncaught.js b/packages/error-reporting/src/interfaces/uncaught.js new file mode 100644 index 00000000000..e426e5d25e0 --- /dev/null +++ b/packages/error-reporting/src/interfaces/uncaught.js @@ -0,0 +1,67 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var errorHandlerRouter = require('../error-router.js'); +var ErrorMessage = require('../classes/error-message.js'); + +/** + * Exits the process with exit code `1` which indicates that an unhandled error + * occurred. !! Invocation of this function will terminate the process !! + * @function handleProcessExit + * @return {Undefined} - does not return a value + */ +function handleProcessExit() { process.exit(1); } + +/** + * If the configuraiton allows, install an uncaught exception handler that will + * report the uncaught error to the API and then terminate the process. + * @function handlerSetup + * @param {AuthClient} client - the API client for communication with the + * Stackdriver Error API + * @param {Configuration} config - the init configuration + * @returns {Null|process} - Returns null if the config demands ignoring + * uncaught + * exceptions, otherwise return the process instance + */ +function handlerSetup(client, config) { + /** + * The actual exception handler creates a new instance of `ErrorMessage`, + * extracts infomation from the propagated `Error` and marshals it into the + * `ErrorMessage` instance, attempts to send this `ErrorMessage` instance to + * the Stackdriver Error Reporting API. Subsequently the process is + * terminated. + * @function uncaughtExceptionHandler + * @listens module:process~event:uncaughtException + * @param {Error} err - The error that has been uncaught to this point + * @returns {Undefined} - does not return a value + */ + function uncaughtExceptionHandler(err) { + var em = new ErrorMessage(); + errorHandlerRouter(err, em); + client.sendError(em, handleProcessExit); + setTimeout(handleProcessExit, 2000); + } + + if (!config.getReportUncaughtExceptions() || config.lacksCredentials()) { + // Do not attach a listener to the process + return null; + } + + return process.on('uncaughtException', uncaughtExceptionHandler); +} + +module.exports = handlerSetup; diff --git a/packages/error-reporting/src/logger.js b/packages/error-reporting/src/logger.js new file mode 100644 index 00000000000..22951e31b0b --- /dev/null +++ b/packages/error-reporting/src/logger.js @@ -0,0 +1,44 @@ +var has = require('lodash.has'); +var is = require('is'); +var isObject = is.object; +var isString = is.string; +var isNumber = is.number; +var logger = require('@google/cloud-diagnostics-common').logger; +/** + * Creates an instance of the Google Cloud Diagnostics logger class. This + * instance will be configured to log at the level given by the environment or + * the runtime configuration property `logLevel`. If neither of these inputs are + * given or valid then the logger will default to logging at log level `WARN`. + * Order of precedence for logging level is: + * 1) Environmental variable `GCLOUD_ERRORS_LOGLEVEL` + * 2) Runtime configuration property `logLevel` + * 3) Default log level of `WARN` (2) + * @function createLogger + * @param {ConfigurationOptions} initConfiguration - the desired project/error + * reporting configuration. Will look for the `logLevel` property which, if + * supplied, must be a number or stringified decimal representation of a + * number between and including 1 through 5 + * @returns {Object} - returns an instance of the logger created with the given/ + * default options + */ +function createLogger (initConfiguration) { + // Default to log level: warn (2) + var level = logger.WARN; + if (has(process.env, 'GCLOUD_ERRORS_LOGLEVEL')) { + // Cast env string as integer + level = ~~process.env.GCLOUD_ERRORS_LOGLEVEL; + } else if (isObject(initConfiguration) && has(initConfiguration, 'logLevel')) { + if (isString(initConfiguration.logLevel)) { + // Cast string as integer + level = ~~initConfiguration.logLevel; + } else if (isNumber(initConfiguration.logLevel)) { + level = initConfiguration.logLevel; + } else { + throw new Error('config.logLevel must be a number or decimal ' + + 'representation of a number in string form'); + } + } + return logger.create(level, '@google/cloud-errors'); +} + +module.exports = createLogger; diff --git a/packages/error-reporting/src/request-extractors/express.js b/packages/error-reporting/src/request-extractors/express.js new file mode 100644 index 00000000000..3ebd034b88e --- /dev/null +++ b/packages/error-reporting/src/request-extractors/express.js @@ -0,0 +1,76 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +'use strict'; +var is = require('is'); +var isFunction = is.fn; +var isObject = is.object; +var RequestInformationContainer = + require('../classes/request-information-container.js'); + +/** + * This function checks for the presence of an `x-forwarded-for` header on the + * request to check for remote address forwards, if that is header is not + * present in the request then the function will attempt to extract the remote + * address from the express request object. + * @function extractRemoteAddressFromRequest + * @param {Object} req - the express request object + * @returns {String} - the remote address or, if one cannot be found, an empty + * string + */ +function extractRemoteAddressFromRequest(req) { + + if (typeof req.header('x-forwarded-for') !== 'undefined') { + + return req.header('x-forwarded-for'); + } else if (isObject(req.connection)) { + + return req.connection.remoteAddress; + } + + return ''; +} + +/** + * The expressRequestInformationExtractor is a function which is made to extract + * request information from a express request object. This function will do a + * basic check for type and method presence but will not check for the presence + * of properties on the request object. + * @function expressRequestInformationExtractor + * @param {Object} req - the express request object + * @param {Object} res - the express response object + * @returns {RequestInformationContainer} - an object containing the request + * information in a standardized format + */ +function expressRequestInformationExtractor(req, res) { + + var returnObject = new RequestInformationContainer(); + + if (!isObject(req) || !isFunction(req.header) || !isObject(res)) { + + return returnObject; + } + + returnObject.setMethod(req.method) + .setUrl(req.url) + .setUserAgent(req.header('user-agent')) + .setReferrer(req.header('referrer')) + .setStatusCode(res.statusCode) + .setRemoteAddress(extractRemoteAddressFromRequest(req)); + + return returnObject; +} + +module.exports = expressRequestInformationExtractor; diff --git a/packages/error-reporting/src/request-extractors/hapi.js b/packages/error-reporting/src/request-extractors/hapi.js new file mode 100644 index 00000000000..9751864e191 --- /dev/null +++ b/packages/error-reporting/src/request-extractors/hapi.js @@ -0,0 +1,102 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +'use strict'; +var has = require('lodash.has'); +var is = require('is'); +var isObject = is.object; +var isFunction = is.function; +var isArray = is.array; +var RequestInformationContainer = + require('../classes/request-information-container.js'); + +/** + * This function is used to check for a pending status code on the response + * or a set status code on the response.output object property. If neither of + * these properties can be found then -1 will be returned as the output. + * @function attemptToExtractStatusCode + * @param {Object} req - the request information object to extract from + * @returns {Number} - Either an HTTP status code or -1 in absence of an + * extractable status code. + */ +function attemptToExtractStatusCode(req) { + + if (has(req, 'response') && isObject(req.response) && + has(req.response, 'statusCode')) { + + return req.response.statusCode; + } else if (has(req, 'response') && isObject(req.response) && + isObject(req.response.output)) { + + return req.response.output.statusCode; + } + + return 0; +} + +/** + * This function is used to check for the x-forwarded-for header first to + * identify source IP connnections. If this header is not present, then the + * function will attempt to extract the remoteAddress from the request.info + * object property. If neither of these properties can be found then an empty + * string will be returned. + * @function extractRemoteAddressFromRequest + * @param {Object} req - the request information object to extract from + * @returns {String} - Either an empty string if the IP cannot be extracted or + * a string that represents the remote IP address + */ +function extractRemoteAddressFromRequest(req) { + + if (has(req.headers, 'x-forwarded-for')) { + + return req.headers['x-forwarded-for']; + } else if (isObject(req.info)) { + + return req.info.remoteAddress; + } + + return ''; +} + +/** + * This function is used to extract request information from a hapi request + * object. This function will not check for the presence of properties on the + * request object. + * @function hapiRequestInformationExtractor + * @param {Object} req - the hapi request object to extract from + * @returns {RequestInformationContainer} - an object containing the request + * information in a standardized format + */ +function hapiRequestInformationExtractor(req) { + + var returnObject = new RequestInformationContainer(); + + if (!isObject(req) || !isObject(req.headers) || isFunction(req) || + isArray(req)) { + + return returnObject; + } + + returnObject.setMethod(req.method) + .setUrl(req.url) + .setUserAgent(req.headers['user-agent']) + .setReferrer(req.headers.referrer) + .setStatusCode(attemptToExtractStatusCode(req)) + .setRemoteAddress(extractRemoteAddressFromRequest(req)); + + return returnObject; +} + +module.exports = hapiRequestInformationExtractor; diff --git a/packages/error-reporting/src/request-extractors/koa.js b/packages/error-reporting/src/request-extractors/koa.js new file mode 100644 index 00000000000..5dceb5aeec9 --- /dev/null +++ b/packages/error-reporting/src/request-extractors/koa.js @@ -0,0 +1,55 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var is = require('is'); +var isObject = is.object; +var isFunction = is.function; +var isArray = is.array; +var RequestInformationContainer = + require('../classes/request-information-container.js'); + +/** + * The koaRequestInformationExtractor attempts to extract information from a Koa + * request/reponse set and marshal it into a RequestInformationContainer + * instance. + * @function koaRequestInformationExtractor + * @param {Object} req - the Koa request object + * @param {Object} res - the Koa response object + * @returns {RequestInformationContainer} - returns a request information + * container instance that may be in its initial state + */ +function koaRequestInformationExtractor(req, res) { + + var returnObject = new RequestInformationContainer(); + + if (!isObject(req) || !isObject(res) || isFunction(req) || isFunction(res) || + isArray(req) || isArray(res) || !isObject(req.headers)) { + + return returnObject; + } + + returnObject.setMethod(req.method) + .setUrl(req.url) + .setUserAgent(req.headers['user-agent']) + .setReferrer(req.headers.referrer) + .setStatusCode(res.status) + .setRemoteAddress(req.ip); + + return returnObject; +} + +module.exports = koaRequestInformationExtractor; diff --git a/packages/error-reporting/src/request-extractors/manual.js b/packages/error-reporting/src/request-extractors/manual.js new file mode 100644 index 00000000000..706e8a0c88a --- /dev/null +++ b/packages/error-reporting/src/request-extractors/manual.js @@ -0,0 +1,85 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +'use strict'; +var has = require('lodash.has'); +var is = require('is'); +var isObject = is.object; +var isArray = is.array; +var isFunction = is.fn; +var RequestInformationContainer = + require('../classes/request-information-container.js'); + +/** + * The manualRequestInformationExtractor is meant to take a standard object + * and extract request information based on the inclusion of several properties. + * This function will check the presence of properties before attempting to + * access them on the object but it will not attempt to check for these + * properties types as this is allocated to the RequestInformationContainer. + * @function manualRequestInformationExtractor + * @param {Object} req - the request information object to extract from + * @param {String} [req.method] - the request method (ex GET, PUT, POST, DELETE) + * @param {String} [req.url] - the request url + * @param {String} [req.userAgent] - the requesters user-agent + * @param {String} [req.referrer] - the requesters referrer + * @param {Number} [req.statusCode] - the status code given in response to the + * request + * @param {String} [req.remoteAddress] - the remote address of the requester + * @returns {RequestInformationContainer} - an object containing the request + * information in a standardized format + */ +function manualRequestInformationExtractor(req) { + + var returnObject = new RequestInformationContainer(); + + if (!isObject(req) || isArray(req) || isFunction(req)) { + + return returnObject; + } + + if (has(req, 'method')) { + + returnObject.setMethod(req.method); + } + + if (has(req, 'url')) { + + returnObject.setUrl(req.url); + } + + if (has(req, 'userAgent')) { + + returnObject.setUserAgent(req.userAgent); + } + + if (has(req, 'referrer')) { + + returnObject.setReferrer(req.referrer); + } + + if (has(req, 'statusCode')) { + + returnObject.setStatusCode(req.statusCode); + } + + if (has(req, 'remoteAddress')) { + + returnObject.setRemoteAddress(req.remoteAddress); + } + + return returnObject; +} + +module.exports = manualRequestInformationExtractor; diff --git a/packages/error-reporting/test/fixtures/configuration.js b/packages/error-reporting/test/fixtures/configuration.js new file mode 100644 index 00000000000..cecfdd7da17 --- /dev/null +++ b/packages/error-reporting/test/fixtures/configuration.js @@ -0,0 +1,25 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var Configuration = require('../../src/configuration.js'); + +var FakeConfiguration = function(config) { + return Configuration.call(this, config, { warn: function () {} }); +}; + +FakeConfiguration.prototype = Object.create(Configuration.prototype); + +module.exports = FakeConfiguration; diff --git a/packages/error-reporting/test/fixtures/gcloud-credentials.json b/packages/error-reporting/test/fixtures/gcloud-credentials.json new file mode 100644 index 00000000000..3499fcc9c3d --- /dev/null +++ b/packages/error-reporting/test/fixtures/gcloud-credentials.json @@ -0,0 +1,6 @@ +{ + "client_id": "x", + "client_secret": "y", + "refresh_token": "z", + "type": "authorized_user" +} diff --git a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js new file mode 100644 index 00000000000..2995e147b34 --- /dev/null +++ b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js @@ -0,0 +1,93 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var uncaughtSetup = require('../../src/interfaces/uncaught.js'); +var assert = require('assert'); +var nock = require('nock'); +var createLogger = require('../../src/logger.js'); +var isString = require('is').string; +var Configuration = require('../fixtures/configuration.js'); +var RequestHandler = require('../../src/google-apis/auth-client.js'); +var originalHandlers = process.listeners('uncaughtException'); +var UNCAUGHT = 'uncaughtException'; +var client; + +function reattachOriginalListeners ( ) { + for (var i = 0; i < originalHandlers.length; i++) { + process.on(UNCAUGHT, originalHandlers[i]); + } +} +var env = { + NODE_ENV: process.env.NODE_ENV +}; +function setEnv () { + process.env.NODE_ENV = 'production'; +} +function restoreEnv () { + process.env.NODE_ENV = env.NODE_ENV; +} + +describe('Uncaught Exception exit behaviour', function () { + var metadataUrl + before(function () { + process.removeAllListeners(UNCAUGHT); + if (!isString(process.env.GCLOUD_PROJECT)) { + // The gcloud project id (GCLOUD_PROJECT) was not set as an env variable + this.skip(); + process.exit(1); + } else if (!isString(process.env.GOOGLE_APPLICATION_CREDENTIALS)) { + // The app credentials (GOOGLE_APPLICATION_CREDENTIALS) was not set as an env variable + this.skip(); + process.exit(1); + } + setEnv(); + }); + after(function () { + nock.cleanAll(); + nock.enableNetConnect(); + reattachOriginalListeners(); + restoreEnv(); + }); + it('Should attempt to report the uncaught exception', function (done) { + var id = 'xyz'; + var metadataId = nock( + 'http://metadata.google.internal/computeMetadata/v1/project' + ).get('/project-id').times(1).reply(200, id); + var metadataToken = nock('https://accounts.google.com:443/o/oauth2') + .post('/token').query(function () {return true}).reply(200, { + refresh_token: 'hello', + access_token: 'goodbye', + expiry_date: new Date(9999, 1, 1) + }); + this.timeout(2000); + var s = nock( + 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+id + ).post('/events:report').once().reply(200, function () { + done(); + return {success: true}; + }); + var cfg = new Configuration( + {reportUncaughtExceptions: true, projectId: 'xyz'}); + cfg.lacksCredentials = function () { + return false; + }; + client = new RequestHandler(cfg, createLogger({logLevel: 4})); + uncaughtSetup(client, cfg); + setTimeout(function () { + throw new Error('This error was supposed to be thrown'); + }, 10); + }); +}); diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js new file mode 100644 index 00000000000..ee4dc828373 --- /dev/null +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -0,0 +1,350 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var assert = require('assert'); +var nock = require('nock'); +var RequestHandler = require('../../src/google-apis/auth-client.js'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var Configuration = require('../fixtures/configuration.js'); +var createLogger = require('../../src/logger.js'); +var is = require('is'); +var isObject = is.object; +var isString = is.string; +var isEmpty = is.empty; +var forEach = require('lodash.foreach'); +var assign = require('lodash.assign'); +var client; + + +describe('Behvaiour acceptance testing', function () { + before(function () { + // Before starting the suite make sure we have the proper resources + if (!isString(process.env.GCLOUD_PROJECT)) { + console.error( + 'The gcloud project id (GCLOUD_PROJECT) was not set as an env variable'); + this.skip(); + } else if (!isString(process.env.STUBBED_API_KEY)) { + console.error( + 'The api key (STUBBED_API_KEY) was not set as an env variable'); + this.skip(); + } else if (!isString(process.env.STUBBED_PROJECT_NUM)) { + console.error( + 'The project number (STUBBED_PROJECT_NUM) was not set as an env variable'); + this.skip(); + } else if (process.env.NODE_ENV !== 'production') { + console.error( + 'The NODE_ENV is not set to production as an env variable. Please set '+ + 'NODE_ENV to production'); + this.skip(); + } + // In case we are running after unit mocks which were not destroyed properly + nock.cleanAll(); + }); + describe('Request/Response lifecycle mocking', function () { + var sampleError = new Error("_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__"); + var errorMessage = new ErrorMessage().setMessage(sampleError); + var fakeService, client, logger; + beforeEach(function () { + 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 () { + nock.cleanAll(); + }); + describe('Receiving non-retryable errors', function () { + it('Should fail', function (done) { + this.timeout(5000); + client.sendError({}, function (err, response, body) { + assert(err instanceof Error); + assert.strictEqual(err.message.toLowerCase(), + 'message cannot be empty.'); + assert.strictEqual(body, null); + assert(isObject(response)); + assert.strictEqual(response.statusCode, 400); + done(); + }); + }); + }); + describe('Receiving retryable errors', function () { + it('Should retry', function (done) { + this.timeout(25000); + var tries = 0; + var intendedTries = 5; + 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, body) { + assert.strictEqual(tries, intendedTries); + done(); + }); + }); + }); + describe('Using an API key', function () { + it('Should provide the key as a query string on outgoing requests', function (done) { + var key = process.env.STUBBED_API_KEY; + 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(); + }); + }); + }); + describe('Callback-less invocation', function () { + it('Should still execute the request', function (done) { + fakeService.reply(200, function () { + done(); + }); + client.sendError(errorMessage); + }); + }); + }); + describe('System-live integration testing', function () { + var sampleError = new Error("_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__"); + var errorMessage = new ErrorMessage().setMessage(sampleError.stack); + var oldEnv = { + GCLOUD_PROJECT: process.env.GCLOUD_PROJECT, + STUBBED_PROJECT_NUM: process.env.STUBBED_PROJECT_NUM, + NODE_ENV: process.env.NODE_ENV + }; + function sterilizeEnv () { + forEach(oldEnv, function (val, key) { + delete process.env[key]; + }); + } + function restoreEnv () { + assign(process.env, oldEnv); + } + describe('Client creation', function () { + describe('Using only project id', function () { + describe('As a runtime argument', function () { + var cfg, logger; + before(function () { + sterilizeEnv(); + logger = createLogger({logLevel: 5}); + cfg = new Configuration({projectId: oldEnv.GCLOUD_PROJECT, + ignoreEnvironmentCheck: true}, logger); + }); + after(restoreEnv); + 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 () { + sterilizeEnv(); + process.env.GCLOUD_PROJECT = oldEnv.GCLOUD_PROJECT; + logger = createLogger({logLevel: 5}); + cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); + }); + after(restoreEnv); + 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 () { + sterilizeEnv(); + logger = createLogger({logLevel: 5}); + cfg = new Configuration({projectId: parseInt(oldEnv.STUBBED_PROJECT_NUM), + ignoreEnvironmentCheck: true}, logger); + }); + after(restoreEnv); + 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 () { + sterilizeEnv(); + process.env.GCLOUD_PROJECT = oldEnv.STUBBED_PROJECT_NUM; + logger = createLogger({logLevel: 5}); + cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); + }); + after(restoreEnv); + 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('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 () { + delete process.env.NODE_ENV; + logger = createLogger({logLevel: 5}); + client = new RequestHandler(new Configuration(undefined, logger), + logger); + }); + after(function () { + process.env.NODE_ENV = oldEnv.NODE_ENV; + }); + it('Should callback with an error', function (done) { + client.sendError({}, function (err, response, body) { + assert(err instanceof Error); + assert.strictEqual(err.message, ERROR_STRING); + assert.strictEqual(body, null); + assert.strictEqual(response, null); + done(); + }); + }); + }); + describe('An invalid env configuration', function () { + var ERROR_STRING = [ + 'Unable to find the project Id for communication with the Stackdriver', + 'Error Reporting service. This app will be unable to send errors to', + 'the reporting service unless a valid project Id is supplied via', + 'runtime configuration or the GCLOUD_PROJECT environmental variable.' + ].join(' '); + var logger, client; + before(function () { + delete process.env.GCLOUD_PROJECT; + logger = createLogger({logLevel: 5}); + client = new RequestHandler(new Configuration( + {ignoreEnvironmentCheck: true}, logger), logger); + }); + after(function () { + process.env.GCLOUD_PROJECT = oldEnv.GCLOUD_PROJECT; + }); + it('Should callback with an error', function (done) { + client.sendError(errorMessage, function (err, response, body) { + assert(err instanceof Error); + assert.strictEqual(err.message, ERROR_STRING); + assert.strictEqual(response, null); + assert.strictEqual(body, null); + done(); + }); + }); + }); + }); + describe('Success behaviour', function () { + var er = new Error("_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__"); + var em = new ErrorMessage().setMessage(er.stack); + describe('Given a valid project id', function () { + var logger, client, cfg; + before(function () { + sterilizeEnv(); + logger = createLogger({logLevel: 5}); + cfg = new Configuration({ + projectId: oldEnv.GCLOUD_PROJECT, + ignoreEnvironmentCheck: true + }, logger); + client = new RequestHandler(cfg, logger); + }); + after(restoreEnv); + 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 () { + forEach(oldEnv, function (val, key) { + delete process.env[key]; + }); + logger = createLogger({logLevel: 5}); + cfg = new Configuration({ + projectId: parseInt(oldEnv.STUBBED_PROJECT_NUM), + ignoreEnvironmentCheck: true + }, logger); + client = new RequestHandler(cfg, logger); + }); + after(function () { + assign(process.env, oldEnv); + }); + 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(); + }); + }); + }); + }); + }); +}); diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js new file mode 100644 index 00000000000..ff8ff7c52a4 --- /dev/null +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -0,0 +1,138 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var WARNING_HEADER = "\n!! -WARNING-"; +var EXCLAMATION_LN = "\n!!"; +var has = require('lodash.has'); +var express = require('express'); +var app = express(); +var errorHandler = require('../../index.js')({ + onUncaughtException: 'report', + key: process.env.STUBBED_API_KEY, + projectId: process.env.STUBBED_PROJECT_NUM +}); +var bodyParser = require('body-parser'); + +app.use(bodyParser.json()); + +app.post( + '/testErrorHandling' + , function ( req, res, next ) { + + + if ( has(req.body, 'test') && req.body.test !== true ) { + + return next(new Error("Error on Express Regular Error POST Route")); + } else { + + res.send("Success"); + res.end(); + } + } +); + +app.get( + '/customError' + , function ( req, res, next ) { + + errorHandler.report( + "Error on Express Custom Error GET Route" + , function ( err, res ) { + + if ( err ) { + + console.log(WARNING_HEADER); + console.log("Error in sending custom get error to api"); + console.log(err); + console.log(EXCLAMATION_LN); + } else { + + console.log(EXCLAMATION_LN); + console.log("Successfully sent custom get error to api"); + console.log(EXCLAMATION_LN); + } + } + ); + + res.send("Success"); + res.end(); + + next(); + } +); + +app.get( + '/getError' + , function ( req, res, next ) { + + return next(new Error("Error on Express Regular Error GET Route")); + } +) + +app.use(errorHandler.express); + +function throwUncaughtError ( ) { + console.log("Throwing an uncaught error.."); + throw new Error('This is an uncaught error'); +} + +function reportManualError ( ) { + console.log("Reporting a manual error.."); + errorHandler.report( + new Error("This is a manually reported error") + , null + , null + , function ( err, res ) { + + if ( err ) { + + console.log(WARNING_HEADER); + console.log("Got an error in sending error information to the API"); + console.log(err); + console.log(EXCLAMATION_LN); + } else { + + console.log(EXCLAMATION_LN); + console.log("Successfully sent error information to the API"); + console.log(EXCLAMATION_LN); + } + + if ( process.env.THROW_ON_STARTUP ) { + throwUncaughtError(); + } + } + ); +} +console.log("reporting a manual error first"); +errorHandler.report( + new Error('This is a test'), + (err, res) => { + console.log("reported first manual error"); + if (err) { + console.log('Error was unable to be reported', err); + } else { + console.log('Error reported!'); + } + } +); + +app.listen( + 3000 + , function ( ) { + console.log('Scaffold Server has been started on port 3000'); + reportManualError(); + } +); diff --git a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js new file mode 100644 index 00000000000..355226589b7 --- /dev/null +++ b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js @@ -0,0 +1,69 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +var hapi = require('hapi'); +var errorHandler = require('../../index.js')(); + +var server = new hapi.Server(); +server.connection({ port: 3000 }); + +server.start( + ( err ) => { + + if ( err ) { + + throw err; + } + + console.log( + 'Server running at' + , server.info.uri + ); + } +); + +server.route({ + method: 'GET' + , path: '/get' + , handler: function ( request, reply ) { + + console.log("Got a GET"); + throw new Error("an error"); + reply('hello there!'); + } +}); + +server.route({ + method: 'POST' + , path: '/post' + , handler: function ( request, reply ) { + + console.log("Got a POST", request.payload); + throw new Error("An error on the hapi post route"); + reply('Got your post'); + } +}); + + +server.register( + { register: errorHandler.hapi } + , ( err ) => { + + if ( err ) { + + console.error("There was an error in registering the plugin", err); + } + } +); diff --git a/packages/error-reporting/test/test-servers/koa_scaffold_server.js b/packages/error-reporting/test/test-servers/koa_scaffold_server.js new file mode 100644 index 00000000000..4844b7324fd --- /dev/null +++ b/packages/error-reporting/test/test-servers/koa_scaffold_server.js @@ -0,0 +1,51 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +var errorHandler = require('../../index.js')({ + onUncaughtException: 'report' +}); +var koa = require('koa'); +var app = koa(); + +app.use(errorHandler.koa); + +app.use(function *(next) { + //This will set status and message + this.throw('Error Message', 500); +}); + + +app.use(function *(next){ + var start = new Date; + yield next; + var ms = new Date - start; + this.set('X-Response-Time', ms + 'ms'); +}); + +// logger + +app.use(function *(next){ + var start = new Date; + yield next; + var ms = new Date - start; + console.log('%s %s - %s', this.method, this.url, ms); +}); + +// response +app.use(function *(){ + this.body = 'Hello World'; +}); + +app.listen(3000); diff --git a/packages/error-reporting/test/test-servers/manual_scaffold_server.js b/packages/error-reporting/test/test-servers/manual_scaffold_server.js new file mode 100644 index 00000000000..08445139952 --- /dev/null +++ b/packages/error-reporting/test/test-servers/manual_scaffold_server.js @@ -0,0 +1,34 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +var errors = require('../../index.js')(); +var r = errors.report('Sample test string', (err, response, body) => { + console.log( + 'Callback from report:\n', + '\tError: ', err, '\n', + '\tResponse Body:', body + ); +}); + +var express = require('express'); +var app = express(); + +app.get('/', function (req, res) { + res.send('Hello World!'); +}); + +app.listen(3000, function () { + console.log('Example app listening on port 3000!'); +}); diff --git a/packages/error-reporting/test/test-servers/restify_scaffold_server.js b/packages/error-reporting/test/test-servers/restify_scaffold_server.js new file mode 100644 index 00000000000..8bc1dd138c2 --- /dev/null +++ b/packages/error-reporting/test/test-servers/restify_scaffold_server.js @@ -0,0 +1,32 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +function respond(req, res, next) { + next(new Error('this is a restify error')); +} + +var restify = require('restify'); +var errorHandler = require('../../index.js')(); + +var server = restify.createServer(); + +server.use(errorHandler.restify(server)); +server.get('/hello/:name', respond); +server.head('/hello/:name', respond); + +server.listen(8080, function() { + console.log('%s listening at %s', server.name, server.url); +}); diff --git a/packages/error-reporting/test/unit/testConfigCredentials.js b/packages/error-reporting/test/unit/testConfigCredentials.js new file mode 100644 index 00000000000..fd6cd7e42fd --- /dev/null +++ b/packages/error-reporting/test/unit/testConfigCredentials.js @@ -0,0 +1,182 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +'use strict'; + +var assert = require('assert'); +var path = require('path'); +var nock = require('nock'); +var http = require('http'); +var express = require('express'); +var Errors = require('../..'); + +var originalHandlers = process.listeners('uncaughtException'); + +function reattachOriginalListeners() { + for (var i = 0; i < originalHandlers.length; i++) { + process.on('uncaughtException', originalHandlers[i]); + } +} + +var oldg, olde; + +describe('Testing use of runtime configurations', function () { + before(function () { + nock.cleanAll(); + nock.disableNetConnect(); + process.removeAllListeners('uncaughtException'); + oldg = process.env.GCLOUD_PROJECT; + olde = process.env.NODE_ENV; + delete process.env.GCLOUD_PROJECT; + process.env.NODE_ENV = 'production'; + }); + after(function () { + nock.enableNetConnect(); + process.env.GCLOUD_PROJECT = oldg; + process.env.NODE_ENV = olde; + }); + afterEach(function () { + nock.cleanAll(); + process.removeAllListeners('uncaughtException'); + }); + it('Should use the keyFilename field of the config object', function (done) { + this.timeout(25000); + var credentials = require('../fixtures/gcloud-credentials.json'); + var config = { + keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json'), + reportUncaughtExceptions: false, + projectId: '0' + }; + var scope = nock('https://accounts.google.com/o/oauth2') + .post('/token', function(body) { + assert.strictEqual(body.client_id, credentials.client_id); + assert.strictEqual(body.client_secret, credentials.client_secret); + assert.strictEqual(body.refresh_token, credentials.refresh_token); + done(); + return true; + }).times(1).reply(200, { + refresh_token: 'hello', + access_token: 'goodbye', + expiry_date: new Date(9999, 1, 1) + }); + var agent = new Errors(config); + agent.report(new Error('a b c')); + }); + describe( + 'use of the credentials field of the config object', + function () { + before(function () { + process.env.GCLOUD_PROJECT = '0'; + }); + after(function () { + delete process.env.GCLOUD_PROJECT; + nock.cleanAll(); + }); + it('Should use the credentials field of the config object', function (done) { + var config = { + credentials: require('../fixtures/gcloud-credentials.json'), + reportUncaughtExceptions: false + }; + var agent = new Errors(config); + var app = express(); + app.use('/', function () { + throw '0'; + }); + app.use(agent.express); + var server = app.listen(3000, function() { + nock.enableNetConnect('localhost'); + var scope = nock('https://accounts.google.com/o/oauth2') + .intercept('/token', 'POST', function(body) { + assert.strictEqual(body.client_id, config.credentials.client_id); + assert.strictEqual(body.client_secret, config.credentials.client_secret); + assert.strictEqual(body.refresh_token, config.credentials.refresh_token); + return true; + }).reply(200, { + refresh_token: 'hello', + access_token: 'goodbye', + expiry_date: new Date(9999, 1, 1) + }); + + // Since we have to get an auth token, this always gets intercepted second + nock('https://clouderrorreporting.googleapis.com/v1beta1/projects/0') + .post('/events:report', function() { + assert(scope.isDone()); + nock.cleanAll(); + server.close(); + reattachOriginalListeners(); + done(); + return true; + }).reply(200); + + http.get({port: 3000, path: '/'}, function(res) {}); + }); + }); + } + ); + it('Should ignore credentials if keyFilename is provided', function (done) { + var correctCredentials = require('../fixtures/gcloud-credentials.json'); + var config = { + keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json'), + projectId: '0', + credentials: { + client_id: 'a', + client_secret: 'b', + refresh_token: 'c', + type: 'authorized_user' + }, + reportUncaughtExceptions: true + }; + ['client_id', 'client_secret', 'refresh_token'].forEach(function (field) { + assert(correctCredentials.hasOwnProperty(field)); + assert(config.credentials.hasOwnProperty(field)); + assert.notEqual(config.credentials[field], + correctCredentials[field]); + }); + var agent = new Errors(config); + var app = express(); + app.use('/', function () { + throw '0'; + }); + app.use(agent.express); + var server = app.listen(3000, function() { + nock.disableNetConnect(); + nock.enableNetConnect('localhost'); + var scope = nock('https://accounts.google.com/o/oauth2') + .intercept('/token', 'POST', function(body) { + assert.strictEqual(body.client_id, correctCredentials.client_id); + assert.strictEqual(body.client_secret, correctCredentials.client_secret); + assert.strictEqual(body.refresh_token, correctCredentials.refresh_token); + return true; + }).reply(200, { + refresh_token: 'hello', + access_token: 'goodbye', + expiry_date: new Date(9999, 1, 1) + }); + + // Since we have to get an auth token, this always gets intercepted second + nock('https://clouderrorreporting.googleapis.com/v1beta1/projects/0') + .post('/events:report', function() { + assert(scope.isDone()); + nock.cleanAll(); + server.close(); + reattachOriginalListeners(); + done(); + return true; + }).reply(200); + + http.get({port: 3000, path: '/'}, function(res) {}); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js new file mode 100644 index 00000000000..af90d20ab7e --- /dev/null +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -0,0 +1,377 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var assert = require('assert'); +var isNumber = require('is').number; +var merge = require('lodash.merge'); +var Configuration = require('../fixtures/configuration.js'); +var version = require('../../package.json').version; +var Fuzzer = require('../../utils/fuzzer.js'); +var level = process.env.GCLOUD_ERRORS_LOGLEVEL; +var logger = require('../../src/logger.js')({ + logLevel: isNumber(level) ? level : 4 +}); +var nock = require('nock'); + +var METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/project'; + +var originalHandlers = process.listeners('uncaughtException'); + +function reattachOriginalListeners() { + for (var i = 0; i < originalHandlers.length; i++) { + process.on('uncaughtException', originalHandlers[i]); + } +} + +process.removeAllListeners('uncaughtException'); +var env = { + NODE_ENV: process.env.NODE_ENV, + GCLOUD_PROJECT: process.env.GCLOUD_PROJECT, + GAE_MODULE_NAME: process.env.GAE_MODULE_NAME, + GAE_MODULE_VERSION: process.env.GAE_MODULE_VERSION +}; +function sterilizeEnv () { + delete process.env.NODE_ENV; + delete process.env.GCLOUD_PROJECT; + delete process.env.GAE_MODULE_NAME; + delete process.env.GAE_MODULE_VERSION; +} +function restoreEnv () { + process.env.NODE_ENV = env.NODE_ENV; + process.env.GCLOUD_PROJECT = env.GCLOUD_PROJECT; + process.env.GAE_MODULE_NAME = env.GAE_MODULE_NAME; + process.env.GAE_MODULE_VERSION = env.GAE_MODULE_VERSION; +} +function createDeadMetadataService () { + return nock(METADATA_URL).get('/project-id').times(1).reply(500); +} + +describe('Configuration class', function () { + before(function () {sterilizeEnv();}); + after(function () {restoreEnv();}); + describe( + 'Initialization', + function () { + var f = new Fuzzer(); + var stubConfig = {test: true}; + describe('fuzzing the constructor', function () { + it('Should return default values', function () { + var c; + f.fuzzFunctionForTypes( + function (givenConfigFuzz) { + c = new Configuration(givenConfigFuzz, logger); + assert.deepEqual(c._givenConfiguration, {}); + }, + ['object'] + ); + }); + }); + describe('valid config and default values', function () { + var c; + before(function () {process.env.NODE_ENV = 'development';}); + after(function () {sterilizeEnv();}); + it('Should not throw with a valid configuration', function () { + assert.doesNotThrow(function () { + c = new Configuration(stubConfig, logger); + }); + }); + it('Should have a property reflecting the config argument', function () { + assert.deepEqual(c._givenConfiguration, stubConfig); + }); + it('Should reportUncaughtExceptions', function () { + assert.strictEqual(c.getReportUncaughtExceptions(), true); + }); + it('Should not reportUncaughtExceptions', function () { + assert.strictEqual(c.getShouldReportErrorsToAPI(), false); + }); + it('Should not have a project id', function () { + assert.strictEqual(c._projectId, null); + }); + it('Should not have a key', function () { + assert.strictEqual(c.getKey(), null); + }); + it('Should have a default service context', function () { + assert.deepEqual(c.getServiceContext(), + {service: 'node', version: undefined}); + }); + it('Should have a version corresponding to package.json', function () { + assert.strictEqual(c.getVersion(), version); + }); + }); + describe('with ignoreEnvironmentCheck', function () { + var conf = merge({}, stubConfig, {ignoreEnvironmentCheck: true}); + var c = new Configuration(conf, logger); + it('Should reportErrorsToAPI', function () { + assert.strictEqual(c.getShouldReportErrorsToAPI(), true); + }); + }); + describe('without ignoreEnvironmentCheck', function () { + describe('Exception behvaiour without proper resources', function () { + var c; + before(function () { + sterilizeEnv(); + c = new Configuration(stubConfig, logger); + }); + after(function () {sterilizeEnv();}); + it('Should error without proper config resource', function (done) { + this.timeout(3500); + c.getProjectId(function (err, id) { + assert(err instanceof Error); + assert.strictEqual(id, null); + done(); + }); + }); + }); + describe('report behaviour with production env', function () { + var c; + before(function () { + sterilizeEnv(); + process.env.NODE_ENV = 'production'; + c = new Configuration(undefined, logger); + }); + after(function () {sterilizeEnv();}); + it('Should reportErrorsToAPI', function () { + assert.strictEqual(c.getShouldReportErrorsToAPI(), true); + }); + }); + describe('exception behaviour', function () { + it('Should throw if invalid type for reportUncaughtExceptions', function () { + assert.throws(function () { + new Configuration({reportUncaughtExceptions: 1}, logger); + }); + }); + it('Should throw if invalid type for key', function () { + assert.throws(function () { + new Configuration({key: null}, logger); + }); + }); + it('Should throw if invalid type for ignoreEnvironmentCheck', function () { + assert.throws(function () { + new Configuration({ignoreEnvironmentCheck: null}, logger); + }); + }); + it('Should throw if invalid type for serviceContext.service', function () { + assert.throws(function () { + new Configuration({serviceContext: {service: false}}, logger); + }); + }); + it('Should throw if invalid type for serviceContext.version', function () { + assert.throws(function () { + new Configuration({serviceContext: {version: true}}, logger); + }); + }); + it('Should not throw given an empty object for serviceContext', function () { + assert.doesNotThrow(function () { + new Configuration({serviceContext: {}}, logger); + }); + }); + }); + }); + } + ); + describe('Configuration resource aquisition', function () { + before(function () {sterilizeEnv();}); + describe('project id from configuration instance', function () { + var pi = 'test'; + var serve, c; + before(function () { + serve = createDeadMetadataService(); + c = new Configuration({projectId: pi}, logger); + }); + after(function () {nock.cleanAll();}); + it('Should return the project id', function (done) { + c.getProjectId(function (err, id) { + assert.strictEqual(err, null); + assert.strictEqual(id, pi); + done(); + }); + }); + }); + describe('project number from configuration instance', function () { + var pn = 1234; + var serve, c; + before(function () { + sterilizeEnv(); + serve = createDeadMetadataService(); + c = new Configuration({projectId: pn}, logger); + }); + after(function () {nock.cleanAll(); sterilizeEnv();}); + it('Should return the project number', function (done) { + c.getProjectId(function (err, id) { + assert.strictEqual(err, null); + assert.strictEqual(pn.toString(), id); + done(); + }); + }); + }); + }); + describe('Exception behaviour', function () { + describe('While lacking a project id', function () { + var serve, c; + before(function () { + sterilizeEnv(); + serve = createDeadMetadataService(); + c = new Configuration(undefined, logger); + }); + after(function () { + nock.cleanAll(); + sterilizeEnv(); + }); + it('Should error', function (done) { + c.getProjectId(function (err, id) { + assert(err instanceof Error); + assert.strictEqual(id, null); + done(); + }); + }); + }); + describe('Invalid type for projectId in runtime config', function () { + var serve, c; + before(function () { + sterilizeEnv(); + serve = createDeadMetadataService(); + c = new Configuration({projectId: null}, logger); + }); + after(function () { + nock.cleanAll(); + sterilizeEnv(); + }); + it('Should error', function (done) { + c.getProjectId(function (err, id) { + assert(err instanceof Error); + assert.strictEqual(id, null); + done(); + }); + }); + }); + }); + describe('Resource aquisition', function () { + after(function () { + /* + * !! IMPORTANT !! + * THE restoreEnv FUNCTION SHOULD BE CALLED LAST AS THIS TEST FILE EXITS + * AND SHOULD THEREFORE BE THE LAST THING TO EXECUTE FROM THIS FILE. + * !! IMPORTANT !! + */ + restoreEnv(); + }); + describe('via env', function () { + before(function() {sterilizeEnv();}) + afterEach(function () {sterilizeEnv();}); + describe('projectId', function () { + var c; + var projectId = 'test-xyz'; + before(function () { + process.env.GCLOUD_PROJECT = projectId; + c = new Configuration(undefined, logger); + }); + it('Should assign', function (done) { + c.getProjectId(function (err, id) { + assert.strictEqual(err, null); + assert.strictEqual(id, projectId); + done(); + }); + }); + }); + describe('serviceContext', function () { + var c; + var projectId = 'test-abc'; + var serviceContext = { + service: 'test', + version: '1.x' + }; + before(function () { + process.env.GCLOUD_PROJECT = projectId; + process.env.GAE_MODULE_NAME = serviceContext.service; + process.env.GAE_MODULE_VERSION = serviceContext.version; + c = new Configuration(undefined, logger); + }); + it('Should assign', function () { + assert.deepEqual(c.getServiceContext(), serviceContext); + }); + }); + }); + describe('via runtime configuration', function () { + before(function () {sterilizeEnv();}); + describe('serviceContext', function () { + var c; + var projectId = 'xyz123'; + var serviceContext = { + service: 'evaluation', + version: '2.x' + }; + before(function () { + c = new Configuration({ + projectId: projectId, + serviceContext: serviceContext + }); + }); + it('Should assign', function () { + assert.deepEqual(c.getServiceContext(), serviceContext); + }); + }); + describe('api key', function () { + var c; + var projectId = '987abc'; + var key = '1337-api-key'; + before(function () { + c = new Configuration({ + key: key, + projectId: projectId + }, logger); + }); + it('Should assign', function () { + assert.strictEqual(c.getKey(), key); + }); + }); + describe('reportUncaughtExceptions', function () { + var c; + var projectId = '123-xyz'; + var reportUncaughtExceptions = false; + before(function () { + c = new Configuration({ + projectId: projectId, + reportUncaughtExceptions: reportUncaughtExceptions + }); + }); + it('Should assign', function () { + assert.strictEqual(c.getReportUncaughtExceptions(), + reportUncaughtExceptions); + }); + }); + }); + describe('via the metadata service', function () { + before(function () {sterilizeEnv();}); + describe('project id', function () { + var serve, c; + var id = '6789'; + before(function () { + serve = nock(METADATA_URL).get('/project-id').times(1).reply(200, id); + c = new Configuration(undefined, logger); + }); + it('Should assign', function (done) { + c.getProjectId(function (err, projectId) { + assert.strictEqual(err, null); + assert.strictEqual(id, projectId); + assert(serve.isDone()); + done(); + }); + }); + }); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testCustomStackTrace.js b/packages/error-reporting/test/unit/testCustomStackTrace.js new file mode 100644 index 00000000000..2a2b2edb470 --- /dev/null +++ b/packages/error-reporting/test/unit/testCustomStackTrace.js @@ -0,0 +1,69 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var CustomStackTrace = require('../../src/classes/custom-stack-trace.js'); + +describe('Fuzzing the CustomStackTrace class', function () { + var testFunction = function testFunction () { + return ""; + }; + var cs; + beforeEach(function () { cs = new CustomStackTrace(); }); + it('Should accept value for file path', function () { + cs.setFilePath("test"); + assert( + cs.filePath === "test", + "Setting a valid string on the CustomStackTrace.filePath instance should result in assignment" + ); + }); + it('Should reject invalid type for file path', function () { + cs.setFilePath(null); + assert( + cs.filePath === "", + "Setting an invalid type on the CustomStackTrace.filePath instance should result in default value of an empty string" + ); + }); + it('Should accept value for line number', function () { + cs.setLineNumber(10); + assert( + cs.lineNumber === 10, + "Setting a valid number on the CustomStackTrace.lineNumber instance should result in assignment" + ); + }); + it('Should reject invalid type for line number', function () { + cs.setLineNumber("10"); + assert( + cs.lineNumber === 0, + "Setting an invalid type on the CustomStackTrace.lineNumber instance should result in default value of number 0" + ); + }); + it('Should accept value for call list', function () { + cs.setStringifyStructuredCallList(testFunction); + assert.strictEqual( + cs.stringifyStucturedCallList, + testFunction, + "Setting a valid function on the CustomStackTrace. setStringifyStructuredCallList should result in assignment" + ); + }); + it('Should reject incalid value for call list', function () { + cs.setStringifyStructuredCallList(null); + assert( + ((typeof cs.setStringifyStructuredCallList) === "function"), + "Setting an invalid setStringifyStructuredCallList on the CustomStackTrace. setStringifyStructuredCallList should result in a default value of a function" + ); + }) +}); diff --git a/packages/error-reporting/test/unit/testErrorMessage.js b/packages/error-reporting/test/unit/testErrorMessage.js new file mode 100644 index 00000000000..6047e1ec20c --- /dev/null +++ b/packages/error-reporting/test/unit/testErrorMessage.js @@ -0,0 +1,680 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var ErrorMessage = require('../../src/classes/error-message.js'); + +describe('Instantiating a new ErrorMessage', function () { + var em; + beforeEach(function () {em = new ErrorMessage();}); + + it('Should have a default service context', function () { + assert.deepEqual( + em.serviceContext, + { service: "node", version: undefined } + ); + }); + it('Should have a default message', function () { + assert.strictEqual(em.message, ''); + }); + it('Should have a default http context', function () { + assert.deepEqual( + em.context.httpRequest, + { + method: "" + , url: "" + , userAgent: "" + , referrer: "" + , responseStatusCode: 0 + , remoteIp: "" + } + ); + }); + it('Should have a default reportLocation', function () { + assert.deepEqual( + em.context.reportLocation, + { + filePath: '', + lineNumber: 0, + functionName: '' + } + ); + }) +}); + +describe('Calling against setEventTimeToNow', function () { + var em; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set the eventTime property', function () { + em.setEventTimeToNow(); + assert((typeof em.eventTime) === 'string'); + }); +}); + +describe('Fuzzing against setServiceContext', function () { + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var DEFAULT_TEST_VALUE = "DEFAULT"; + var DEFAULT_VERSION_VALUE = undefined; + var DEFAULT_SERVICE_VALUE = "node"; + var em; + beforeEach(function () {em = new ErrorMessage()}); + + it('Should set the value for service context', function () { + em.setServiceContext(AFFIRMATIVE_TEST_VALUE, AFFIRMATIVE_TEST_VALUE); + assert.deepEqual( + em.serviceContext + , { + service: AFFIRMATIVE_TEST_VALUE + , version: AFFIRMATIVE_TEST_VALUE + } + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should set the default values', function () { + em.setServiceContext(DEFAULT_TEST_VALUE, DEFAULT_TEST_VALUE); + assert.deepEqual( + em.serviceContext + , { + service: DEFAULT_TEST_VALUE + , version: DEFAULT_TEST_VALUE + } + , [ + "In resetting to default valid values the instance should reflect the" + , "value update" + ].join(" ") + ); + }); + it('Should still set version with affirmative value', function () { + em.setServiceContext(null, AFFIRMATIVE_TEST_VALUE); + assert.deepEqual( + em.serviceContext + , { + service: DEFAULT_SERVICE_VALUE + , version: AFFIRMATIVE_TEST_VALUE + } + , [ + "Providing only a valid value to the second argument of" + , "setServiceContext should set the service property as an empty string" + , "but set the version property to the affirmative value." + ].join(" ") + ); + }); + it('Should still set service with affirmative value', function () { + em.setServiceContext(AFFIRMATIVE_TEST_VALUE, null); + assert.deepEqual( + em.serviceContext + , { + service: AFFIRMATIVE_TEST_VALUE + , version: DEFAULT_VERSION_VALUE + } + , [ + "Providing only a valid value to the first argument of" + , "setServiceContext should set the version property as an empty string" + , "but set the service property to the affirmative value." + ].join(" ") + ); + }); + it('Should set default values on both', function () { + em.setServiceContext(null, null); + assert.deepEqual( + em.serviceContext + , { + service: DEFAULT_SERVICE_VALUE + , version: DEFAULT_VERSION_VALUE + } + , [ + "Providing null as the value to both arguments should set both" + , "properties as empty strings." + ].join(" ") + ); + }); + it('Should set default values on both', function () { + em.setServiceContext(2, 1.3); + assert.deepEqual( + em.serviceContext + , { + service: DEFAULT_SERVICE_VALUE + , version: DEFAULT_VERSION_VALUE + } + , [ + "Providing numbers as the value to both arguments should set both" + , "properties as empty strings." + ].join(" ") + ); + }); + it('Should set as default', function () { + em.setServiceContext({ test: "true" }, []); + assert.deepEqual( + em.serviceContext + , { + service: DEFAULT_SERVICE_VALUE + , version: DEFAULT_VERSION_VALUE + } + , [ + "Providing arrays or objects as the value to both arguments" + , "should set both properties as empty strings." + ].join(" ") + ); + }); + it('Should set as default', function () { + em.setServiceContext(); + assert.deepEqual( + em.serviceContext + , { + service: DEFAULT_SERVICE_VALUE + , version: DEFAULT_VERSION_VALUE + } + , "Providing no arguments should set both properties as empty strings" + ); + }) +}); + +describe( + 'Fuzzing against setMessage', + function () { + var em; + beforeEach(function () {em = new ErrorMessage()}); + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + + it('Should set the message', function () { + em.setMessage(AFFIRMATIVE_TEST_VALUE); + assert( + em.message === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setMessage(); + assert( + em.message === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setMessage the property" + , "message should be set to an empty string on the instance" + ].join(" ") + ); + }); + } +); + +describe( + 'Fuzzing against setHttpMethod', + function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set the method', function () { + em.setHttpMethod(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.httpRequest.method === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setHttpMethod(); + assert( + em.context.httpRequest.method === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setHttpMethod the property" + , "message should be set to an empty string on the instance" + ].join(" ") + ); + }); + } +); + +describe( + 'Fuzzing against setUrl', + function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set url', function () { + em.setUrl(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.httpRequest.url === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setUrl(); + assert( + em.context.httpRequest.url === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setUrl the property" + , "message should be set to an empty string on the instance" + ].join(" ") + ); + }); + } +); + + +describe( + 'Fuzzing against setUserAgent', + function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set userAgent', function () { + em.setUserAgent(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.httpRequest.userAgent === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setUserAgent(); + assert( + em.context.httpRequest.userAgent === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setUserAgent the property" + , "message should be set to an empty string on the instance" + ].join(" ") + ); + }); + } +); + +describe('Fuzzing against setReferrer', function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set referrer', function () { + em.setReferrer(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.httpRequest.referrer === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setReferrer(); + assert( + em.context.httpRequest.referrer === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setReferrer the property" + , "message should be set to an empty string on the instance" + ].join(" ") + ); + }); +}); + +describe('Fuzzing against setResponseStatusCode', function () { + var em; + var AFFIRMATIVE_TEST_VALUE = 200; + var NEGATIVE_TEST_VALUE = 0; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set responseStatusCode', function () { + em.setResponseStatusCode(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.httpRequest.responseStatusCode === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setResponseStatusCode(); + assert( + em.context.httpRequest.responseStatusCode === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setResponseStatusCode the property" + , "message should be set to an empty string on the instance" + ].join(" ") + ); + }); +}); + +describe('Fuzzing against setRemoteIp', function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set remoteIp', function () { + em.setRemoteIp(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.httpRequest.remoteIp === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setRemoteIp(); + assert( + em.context.httpRequest.remoteIp === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setRemoteIp the property" + , "message should be set to an empty string on the instance" + ].join(" ") + ); + }); +}); + +describe( + 'Fuzzing against setUser', + function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set user', function () { + em.setUser(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.user === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setUser(); + assert( + em.context.user === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setUser the property" + , "user should be set to an empty string on the instance" + ].join(" ") + ); + }); + } +); + +describe('Fuzzing against setFilePath', function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set filePath', function () { + em.setFilePath(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.reportLocation.filePath === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setFilePath(); + assert( + em.context.reportLocation.filePath === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setFilePath the property" + , "filePath should be set to an empty string on the instance" + ].join(" ") + ); + }); +}); + +describe('Fuzzing against setLineNumber', function () { + var em; + var AFFIRMATIVE_TEST_VALUE = 27; + var NEGATIVE_TEST_VALUE = 0; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set lineNumber', function () { + em.setLineNumber(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.reportLocation.lineNumber === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setLineNumber(); + assert( + em.context.reportLocation.lineNumber === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setLineNumber the property" + , "lineNumber should be set to an empty string on the instance" + ].join(" ") + ); + }); +}); + +describe('Fuzzing against setFunctionName', function () { + var em; + var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; + var NEGATIVE_TEST_VALUE = ""; + beforeEach(function () {em = new ErrorMessage()}); + it('Should set functionName', function () { + em.setFunctionName(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.reportLocation.functionName === AFFIRMATIVE_TEST_VALUE + , [ + "In the affirmative case the value should be settable to a valid string" + , "and by setting this value this should mutate the instance" + ].join(" ") + ); + }); + it('Should default', function () { + em.setFunctionName(); + assert( + em.context.reportLocation.functionName === NEGATIVE_TEST_VALUE + , [ + "By providing no argument (undefined) to setFunctionName the property" + , "functionName should be set to an empty string on the instance" + ].join(" ") + ); + }); +}); + +describe('Fuzzing against consumeRequestInformation', function () { + var em = new ErrorMessage(); + var A_VALID_STRING = "A_VALID_STRING"; + var A_VALID_NUMBER = 201; + var NEGATIVE_STRING_CASE = ""; + var NEGATIVE_NUMBER_CASE = 0; + + var AFFIRMATIVE_TEST_VALUE = { + method: A_VALID_STRING + , url: A_VALID_STRING + , userAgent: A_VALID_STRING + , referrer: A_VALID_STRING + , statusCode: A_VALID_NUMBER + , remoteAddress: A_VALID_STRING + }; + var NEGATIVE_TEST_VALUE = { + method: null + , url: A_VALID_NUMBER + , userAgent: {} + , referrer: [] + , statusCode: A_VALID_STRING + , remoteAddress: undefined + }; + it('Should consume the stubbed request object', function () { + em.consumeRequestInformation(AFFIRMATIVE_TEST_VALUE); + assert( + em.context.httpRequest.method === A_VALID_STRING + , [ + "The error messages method, given a valid string, should be" + , "set to that value" + ].join(" ") + ); + assert( + em.context.httpRequest.url === A_VALID_STRING + , [ + "The error messages url, given a valid string, should be" + , "set to that value" + ].join(" ") + ); + assert( + em.context.httpRequest.userAgent === A_VALID_STRING + , [ + "The error messages userAgent, given a valid string, should be" + , "set to that value" + ].join(" ") + ); + assert( + em.context.httpRequest.referrer === A_VALID_STRING + , [ + "The error messages referrer, given a valid string, should be" + , "set to that value" + ].join(" ") + ); + assert( + em.context.httpRequest.responseStatusCode === A_VALID_NUMBER + , [ + "The error messages responseStatusCode, given a valid number, should be" + , "set to that value" + ].join(" ") + ); + assert( + em.context.httpRequest.remoteIp === A_VALID_STRING + , [ + "The error messages remoteAddress, given a valid string, should be" + , "set to that value" + ].join(" ") + ); + }); + it('Should default when consuming a malformed request object', function () { + em.consumeRequestInformation(null); + assert( + em.context.httpRequest.method === A_VALID_STRING + , [ + "The error messages method, given an invalid type a the top-level" + , "should remain untouched" + ].join(" ") + ); + assert( + em.context.httpRequest.url === A_VALID_STRING + , [ + "The error messages url, given an invalid type a the top-level" + , "should remain untouched" + ].join(" ") + ); + assert( + em.context.httpRequest.userAgent === A_VALID_STRING + , [ + "The error messages userAgent, given an invalid type a the top-level" + , "should remain untouched" + ].join(" ") + ); + assert( + em.context.httpRequest.referrer === A_VALID_STRING + , [ + "The error messages referrer, given an invalid type a the top-level" + , "should remain untouched" + ].join(" ") + ); + assert( + em.context.httpRequest.responseStatusCode === A_VALID_NUMBER + , [ + "The error messages responseStatusCode, given an invalid type a the top-level" + , "should remain untouched" + ].join(" ") + ); + assert( + em.context.httpRequest.remoteIp === A_VALID_STRING + , [ + "The error messages remoteAddress, given an invalid type a the top-level" + , "should remain untouched" + ].join(" ") + ); + }); + it('Should default when consuming mistyped response object properties', + function () { + em.consumeRequestInformation(NEGATIVE_TEST_VALUE); + assert( + em.context.httpRequest.method === NEGATIVE_STRING_CASE + , [ + "The error messages method, given an invalid input should default to" + , "the negative value" + ].join(" ") + ); + assert( + em.context.httpRequest.url === NEGATIVE_STRING_CASE + , [ + "The error messages url, given an invalid input should default to" + , "the negative value" + ].join(" ") + ); + assert( + em.context.httpRequest.userAgent === NEGATIVE_STRING_CASE + , [ + "The error messages userAgent, ggiven an invalid input should default to" + , "the negative value" + ].join(" ") + ); + assert( + em.context.httpRequest.referrer === NEGATIVE_STRING_CASE + , [ + "The error messages referrer, given an invalid input should default to" + , "the negative value" + ].join(" ") + ); + assert( + em.context.httpRequest.responseStatusCode === NEGATIVE_NUMBER_CASE + , [ + "The error messages responseStatusCode, given an invalid input should default to" + , "the negative value" + ].join(" ") + ); + assert( + em.context.httpRequest.remoteIp === NEGATIVE_STRING_CASE + , [ + "The error messages remoteAddress, given an invalid input should default to" + , "the negative value" + ].join(" ") + ); + } + ); + it('Should return the instance on calling consumeRequestInformation', + function () { + assert( + em.consumeRequestInformation(AFFIRMATIVE_TEST_VALUE) instanceof ErrorMessage + , [ + "Calling consumeRequestInformation with valid input should return" + , "the ErrorMessage instance" + ].join(" ") + ); + assert( + em.consumeRequestInformation() instanceof ErrorMessage + , [ + "Calling consumeRequestInformation with invalid input should return" + , "the ErrorMessage instance" + ].join(" ") + ); + } + ); +}); diff --git a/packages/error-reporting/test/unit/testExpressInterface.js b/packages/error-reporting/test/unit/testExpressInterface.js new file mode 100644 index 00000000000..adaa47ee2bd --- /dev/null +++ b/packages/error-reporting/test/unit/testExpressInterface.js @@ -0,0 +1,90 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var merge = require('lodash.merge'); +var expressInterface = require('../../src/interfaces/express.js'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var Fuzzer = require('../../utils/fuzzer.js'); +var Configuration = require('../fixtures/configuration.js'); +var createLogger = require('../../src/logger.js'); + +describe('expressInterface', function () { + describe('Exception handling', function () { + describe('Given invalid input', function () { + it('Should not throw errors', function () { + var f = new Fuzzer(); + assert.doesNotThrow( + function () { + f.fuzzFunctionForTypes( + expressInterface + , ["object", "object"] + ); + return; + } + ); + }); + }); + }); + describe('Intended behaviour', function () { + var stubbedConfig = new Configuration({ + serviceContext: { + service: "a_test_service" + , version: "a_version" + } + }, createLogger({logLevel: 4})); + stubbedConfig.lacksCredentials = function () { + return false; + }; + var client = { + sendError: function () { + return; + } + }; + var testError = new Error("This is a test"); + var validBoundHandler = expressInterface(client, stubbedConfig); + it('Should return the error message', function () { + var res = validBoundHandler(testError, null, null, null); + assert.deepEqual( + res, + merge(new ErrorMessage().setMessage(testError.stack) + .setServiceContext( + stubbedConfig._serviceContext.service, + stubbedConfig._serviceContext.version), + {eventTime: res.eventTime} + ) + ); + }); + describe('Calling back to express builtins', function () { + it('Should callback to next', function (done) { + var nextCb = function () { + done(); + }; + validBoundHandler(testError, null, null, nextCb); + }); + it('Should callback to sendError', function (done) { + var sendError = function () { + done(); + }; + var client = { + sendError: sendError + }; + var handler = expressInterface(client, stubbedConfig); + handler(testError, null, null, function (){return;}); + }); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js new file mode 100644 index 00000000000..52c51d961fb --- /dev/null +++ b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js @@ -0,0 +1,155 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var expressRequestInformationExtractor = require('../../src/request-extractors/express.js'); + +var Fuzzer = require('../../utils/fuzzer.js'); +var extend = require('extend'); + +describe('Behaviour under varying input', + function () { + var f; + var DEFAULT_RETURN_VALUE = { + method: "" + , url: "" + , userAgent: "" + , referrer: "" + , statusCode: 0 + , remoteAddress: "" + }; + beforeEach(function () {f = new Fuzzer();}); + it('Should return a default value given invalid input', function () { + var cbFn = function (value) { + assert.deepEqual(value, DEFAULT_RETURN_VALUE); + } + f.fuzzFunctionForTypes(expressRequestInformationExtractor, + ['object', 'object'], cbFn); + }); + it('Should return valid request object given valid input', function () { + var FULL_REQ_DERIVATION_VALUE = { + method: "STUB_METHOD" + , url: "www.TEST-URL.com" + , 'user-agent': "Something like Mozilla" + , referrer: "www.ANOTHER-TEST.com" + , 'x-forwarded-for': '0.0.0.1' + , connection: { + remoteAddress: "0.0.0.0" + } + }; + var FULL_RES_DERIVATION_VALUE = { + 'statusCode': 200 + }; + var FULL_REQ_EXPECTED_VALUE = { + method: "STUB_METHOD" + , url: "www.TEST-URL.com" + , userAgent: "Something like Mozilla" + , referrer: "www.ANOTHER-TEST.com" + , remoteAddress: '0.0.0.1' + , statusCode: 200 + } + + var PARTIAL_REQ_DERIVATION_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , 'user-agent': "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + , connection: { + remoteAddress: "0.0.2.1" + } + }; + var PARTIAL_RES_DERIVATION_VALUE = { + statusCode: 201 + }; + var PARTIAL_REQ_EXPECTED_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , userAgent: "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + , remoteAddress: "0.0.2.1" + , statusCode: 201 + }; + + var ANOTHER_PARTIAL_REQ_DERIVATION_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , 'user-agent': "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + }; + var ANOTHER_PARTIAL_RES_DERIVATION_VALUE = { + statusCode: 201 + }; + var ANOTHER_PARTIAL_REQ_EXPECTED_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , userAgent: "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + , remoteAddress: "" + , statusCode: 201 + }; + var headerFactory = function (toDeriveFrom) { + var lrn = extend({}, toDeriveFrom); + lrn.header = function ( toRet ) { + if (lrn.hasOwnProperty(toRet)) { + return lrn[toRet]; + } + return undefined; + } + return lrn; + }; + var tmpOutput = expressRequestInformationExtractor( + headerFactory(FULL_REQ_DERIVATION_VALUE) + , FULL_RES_DERIVATION_VALUE + ); + assert.deepEqual(tmpOutput, FULL_REQ_EXPECTED_VALUE, + [ + 'Given a valid object input for the request parameter and an', + , '\'x-forwarded-for\' parameter the request extractor should return', + , 'the expected full req output and the \'x-forwarded-for\' value', + , 'as the value for the \'remoteAddress\' property.' + ].join(' ') + ); + tmpOutput = expressRequestInformationExtractor( + headerFactory(PARTIAL_REQ_DERIVATION_VALUE) + , PARTIAL_RES_DERIVATION_VALUE + ); + assert.deepEqual( + tmpOutput, + PARTIAL_REQ_EXPECTED_VALUE, + [ + "Given a valid object input for the request parameter but sans an", + "\'x-forwarded-for\' parameter the request extractor should return", + "the expected parital req output and the remoteAddress value", + "as the value for the \'remoteAddress\' property." + ].join(" ") + ); + tmpOutput = expressRequestInformationExtractor( + headerFactory(ANOTHER_PARTIAL_REQ_DERIVATION_VALUE) + , ANOTHER_PARTIAL_RES_DERIVATION_VALUE + ); + assert.deepEqual( + tmpOutput, + ANOTHER_PARTIAL_REQ_EXPECTED_VALUE, + [ + "Given a valid object input for the request parameter but sans an", + "\'x-forwarded-for\' parameter or a remoteAddress parameter", + "the request extractor should return an empty string", + "as the value for the \'remoteAddress\' property." + ].join(" ") + ); + } + ); +}); diff --git a/packages/error-reporting/test/unit/testExtractFromErrorClass.js b/packages/error-reporting/test/unit/testExtractFromErrorClass.js new file mode 100644 index 00000000000..2ffb82f9c03 --- /dev/null +++ b/packages/error-reporting/test/unit/testExtractFromErrorClass.js @@ -0,0 +1,105 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var extractFromErrorClass = require('../../src/error-extractors/error.js'); +var ErrorMessage = require('../../src/classes/error-message.js'); + + +describe('Writing and reading ErrorMessage properties', function () { + describe('Message field', function () { + it('Should set the message as the stack of the given error', function () { + var TEST_MESSAGE = "This is a test"; + var em = new ErrorMessage(); + var err = new Error(TEST_MESSAGE); + extractFromErrorClass(err, em); + assert.deepEqual(em.message, err.stack, 'Given a valid message the ' + + 'error message should absorb the error stack as the message' + ); + }); + }); + describe('User field', function () { + var em, err; + var TEST_USER_INVALID = 12; + beforeEach(function () { + em = new ErrorMessage(); + err = new Error(); + }); + it('Should set the user field if given valid input', function () { + var TEST_USER_VALID = "TEST_USER"; + err.user = TEST_USER_VALID; + extractFromErrorClass(err, em); + assert.strictEqual(em.context.user, TEST_USER_VALID); + }); + it('Should default the user field if given invalid input', function () { + err.user = TEST_USER_INVALID; + extractFromErrorClass(err, em); + assert.strictEqual(em.context.user, ''); + }); + }); + describe('Service field', function () { + var em, err; + var TEST_SERVICE_DEFAULT = {service: 'node', version: undefined}; + beforeEach(function () { + em = new ErrorMessage(); + err = new Error(); + }); + it('Should set the field if given valid input', function () { + var TEST_SERVICE_VALID = {service: 'test', version: 'test'}; + err.serviceContext = TEST_SERVICE_VALID; + extractFromErrorClass(err, em); + assert.deepEqual(err.serviceContext, TEST_SERVICE_VALID); + }); + it('Should default the field if given invalid input', function () { + var TEST_SERVICE_INVALID = 12; + err.serviceContext = TEST_SERVICE_INVALID; + extractFromErrorClass(err, em); + assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); + }); + it('Should default the field if not given input', function () { + extractFromErrorClass(err, em); + assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); + }); + }); + describe('Report location field', function () { + var em, err; + var TEST_STACK_DEFAULT = { + filePath: "" + , lineNumber: 0 + , functionName: "" + }; + beforeEach(function () { + em = new ErrorMessage(); + err = new Error(); + }) + it('Should default the field if given invalid input', function () { + var TEST_STACK_INVALID_CONTENTS = { + filePath: null + , lineNumber: "2" + , functionName: {} + }; + err.stack = TEST_STACK_INVALID_CONTENTS; + extractFromErrorClass(err, em); + assert.deepEqual(em.context.reportLocation, TEST_STACK_DEFAULT); + }); + it('Should default field if not given a valid type', function () { + var TEST_STACK_INVALID_TYPE = []; + err.stack = TEST_STACK_INVALID_TYPE; + extractFromErrorClass(err, em); + assert.deepEqual(em.context.reportLocation, TEST_STACK_DEFAULT); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testExtractFromObject.js b/packages/error-reporting/test/unit/testExtractFromObject.js new file mode 100644 index 00000000000..e0c7a06f650 --- /dev/null +++ b/packages/error-reporting/test/unit/testExtractFromObject.js @@ -0,0 +1,106 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var extractFromObject = require('../../src/error-extractors/object.js'); +var ErrorMessage = require('../../src/classes/error-message.js'); + +describe('Object value extraction as error message', function () { + var em, err; + beforeEach(function () { + em = new ErrorMessage(); + err = {}; + }); + describe('Message field', function () { + it('Should write to the field given valid input', function () { + var MESSAGE = 'test'; + err = {message: MESSAGE}; + extractFromObject(err, em); + assert.strictEqual(em.message, MESSAGE); + }); + it('Should default the field given lack-of input', function () { + extractFromObject(err, em); + assert.strictEqual(em.message, ''); + }); + }); + describe('User field', function () { + it('Should write to the field given valid input', function () { + var USER = 'test'; + err.user = USER; + extractFromObject(err, em); + assert.strictEqual(em.context.user, USER); + }); + it('Should default the field given lack-of input', function () { + extractFromObject(err, em); + assert.strictEqual(em.context.user, ''); + }); + }); + describe('filePath field', function () { + it('Should write to the field given valid input', function () { + var PATH = 'test'; + err.filePath = PATH; + extractFromObject(err, em); + assert.strictEqual(em.context.reportLocation.filePath, PATH); + }); + it('Should default the field given lack-of input', function () { + extractFromObject(err, em); + assert.strictEqual(em.context.reportLocation.filePath, ''); + }); + }); + describe('lineNumber field', function () { + it('Should write to the field given valid input', function () { + var LINE_NUMBER = 10; + err.lineNumber = LINE_NUMBER; + extractFromObject(err, em); + assert.strictEqual(em.context.reportLocation.lineNumber, LINE_NUMBER); + }); + it('Should default the field given lack-of input', function () { + extractFromObject(err, em); + assert.strictEqual(em.context.reportLocation.lineNumber, 0); + }); + }); + describe('functionName field', function () { + it('Should write to the field given valid input', function () { + var FUNCTION_NAME = 'test'; + err.functionName = FUNCTION_NAME; + extractFromObject(err, em); + assert.strictEqual(em.context.reportLocation.functionName, FUNCTION_NAME); + }); + it('Should default the field given lack-of input', function () { + extractFromObject(err, em); + assert.strictEqual(em.context.reportLocation.functionName, ''); + }); + }); + describe('serviceContext field', function () { + var TEST_SERVICE_DEFAULT = {service: 'node', version: undefined}; + it('Should write to the field given valid input', function () { + var TEST_SERVICE_VALID = {service: 'test', version: 'test'}; + err.serviceContext = TEST_SERVICE_VALID; + extractFromObject(err, em); + assert.deepEqual(em.serviceContext, TEST_SERVICE_VALID); + }); + it('Should default the field given invalid input', function () { + var TEST_SERVICE_INVALID = 12; + err.serviceContext = TEST_SERVICE_INVALID; + extractFromObject(err, em); + assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); + }); + it('Should default the field given lack-of input', function () { + extractFromObject(err, em); + assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testHandleErrorClassError.js b/packages/error-reporting/test/unit/testHandleErrorClassError.js new file mode 100644 index 00000000000..51903536acc --- /dev/null +++ b/packages/error-reporting/test/unit/testHandleErrorClassError.js @@ -0,0 +1,54 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var handleErrorClassError = require('../../src/error-handlers/error.js'); + +describe('Behaviour under various type inputs', function () { + var em; + var adversarialObjectInput = { + stack: {} + }; + var adversarialObjectInputTwo = { + stack: [] + }; + beforeEach(function () {em = new ErrorMessage()}); + it('Should not throw given undefined', function () { + assert.doesNotThrow(handleErrorClassError.bind(null, undefined, em)); + }); + it('Should not throw given null', function () { + assert.doesNotThrow(handleErrorClassError.bind(null, null, em)); + }); + it('Should not throw given a string', function () { + assert.doesNotThrow(handleErrorClassError.bind(null, 'string_test', em)); + }); + it('Should not throw given a number', function () { + assert.doesNotThrow(handleErrorClassError.bind(null, 1.2, em)); + }); + it('Should not throw given an array', function () { + assert.doesNotThrow(handleErrorClassError.bind(null, [], em)); + }); + it('Should not throw given an object of invalid form', function () { + assert.doesNotThrow( + handleErrorClassError.bind(null, adversarialObjectInput, em)); + assert.doesNotThrow( + handleErrorClassError.bind(null, adversarialObjectInputTwo, em)); + }); + it('Should not throw given valid input', function () { + assert.doesNotThrow(handleErrorClassError.bind(null, new Error(), em)); + }); +}); diff --git a/packages/error-reporting/test/unit/testHandleNumberAsError.js b/packages/error-reporting/test/unit/testHandleNumberAsError.js new file mode 100644 index 00000000000..48134ac640c --- /dev/null +++ b/packages/error-reporting/test/unit/testHandleNumberAsError.js @@ -0,0 +1,42 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var handleNumberAsError = require('../../src/error-handlers/number.js'); + +describe('handleNumberAsError behaviour under varying input', function () { + var em; + beforeEach(function () {em = new ErrorMessage();}); + it('Should not throw given undefined', function () { + assert.doesNotThrow(handleNumberAsError.bind(null, undefined, em)); + }); + it('Should not throw given null', function () { + assert.doesNotThrow(handleNumberAsError.bind(null, null, em)); + }); + it('Should not throw given a string', function () { + assert.doesNotThrow(handleNumberAsError.bind(null, 'test', em)); + }); + it('Should not throw given an instance of Error', function () { + assert.doesNotThrow(handleNumberAsError.bind(null, new Error(), em)); + }); + it('Should not throw given an object', function () { + assert.doesNotThrow(handleNumberAsError.bind(null, {}, em)); + }); + it('Should not throw given valid input', function () { + assert.doesNotThrow(handleNumberAsError.bind(null, 1.3, em)); + }); +}); diff --git a/packages/error-reporting/test/unit/testHandleObjectAsError.js b/packages/error-reporting/test/unit/testHandleObjectAsError.js new file mode 100644 index 00000000000..bcc9b594d41 --- /dev/null +++ b/packages/error-reporting/test/unit/testHandleObjectAsError.js @@ -0,0 +1,42 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var handleObjectAsError = require('../../src/error-handlers/object.js'); + +describe('handleObjectAsError behaviour under varying inputs', function () { + var em; + beforeEach(function () {em = new ErrorMessage();}); + it('Should not throw given undefined', function () { + assert.doesNotThrow(handleObjectAsError.bind(null, undefined, em)); + }); + it('Should not throw given null', function () { + assert.doesNotThrow(handleObjectAsError.bind(null, null, em)); + }); + it('Should not throw given a string', function () { + assert.doesNotThrow(handleObjectAsError.bind(null, 'msg', em)); + }); + it('Should not throw given an instance of Error', function () { + assert.doesNotThrow(handleObjectAsError.bind(null, new Error(), em)); + }); + it('Should not throw given a number', function () { + assert.doesNotThrow(handleObjectAsError.bind(null, 1.3, em)); + }); + it('Should not throw given valid input', function () { + assert.doesNotThrow(handleObjectAsError.bind(null, {}, em)); + }); +}); diff --git a/packages/error-reporting/test/unit/testHandleStringAsError.js b/packages/error-reporting/test/unit/testHandleStringAsError.js new file mode 100644 index 00000000000..09b7cb99929 --- /dev/null +++ b/packages/error-reporting/test/unit/testHandleStringAsError.js @@ -0,0 +1,42 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var handleStringAsError = require('../../src/error-handlers/string.js'); + +describe('handleStringAsError behaviour under varying inputs', function () { + var em; + beforeEach(function () {em = new ErrorMessage();}); + it('Should not throw given undefined', function () { + assert.doesNotThrow(handleStringAsError.bind(null, undefined, em)); + }); + it('Should not throw given null', function () { + assert.doesNotThrow(handleStringAsError.bind(null, null, em)); + }); + it('Should not throw given an object', function () { + assert.doesNotThrow(handleStringAsError.bind(null, {}, em)); + }); + it('Should not throw given an array', function () { + assert.doesNotThrow(handleStringAsError.bind(null, [], em)); + }); + it('Should not throw given an instance of Error', function () { + assert.doesNotThrow(handleStringAsError.bind(null, 1.3, em)); + }); + it('Should not throw given valid input', function () { + assert.doesNotThrow(handleStringAsError.bind(null, 'test', em)); + }); +}); diff --git a/packages/error-reporting/test/unit/testHandleUnknownAsError.js b/packages/error-reporting/test/unit/testHandleUnknownAsError.js new file mode 100644 index 00000000000..2d6f745e3cd --- /dev/null +++ b/packages/error-reporting/test/unit/testHandleUnknownAsError.js @@ -0,0 +1,45 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var handleUnknownAsError = require('../../src/error-handlers/unknown.js'); + +describe('handleUnknownAsError behvaiour under varying input', function () { + var em; + beforeEach(function () {em = new ErrorMessage();}); + it('Should not throw given undefined', function () { + assert.doesNotThrow(handleUnknownAsError.bind(null, undefined, em)); + }); + it('Should not throw given null', function () { + assert.doesNotThrow(handleUnknownAsError.bind(null, null, em)); + }); + it('Should not throw given an object', function () { + assert.doesNotThrow(handleUnknownAsError.bind(null, {}, em)); + }); + it('Should not throw given an array', function () { + assert.doesNotThrow(handleUnknownAsError.bind(null, [], em)); + }); + it('Should not throw given an instance of Error', function () { + assert.doesNotThrow(handleUnknownAsError.bind(null, new Error(), em)); + }); + it('Should not throw given a number', function () { + assert.doesNotThrow(handleUnknownAsError.bind(null, 1.3, em)); + }); + it('Should not throw given a string', function () { + assert.doesNotThrow(handleUnknownAsError.bind(null, 'msg', em)); + }); +}); diff --git a/packages/error-reporting/test/unit/testHapiInterface.js b/packages/error-reporting/test/unit/testHapiInterface.js new file mode 100644 index 00000000000..512e8c099af --- /dev/null +++ b/packages/error-reporting/test/unit/testHapiInterface.js @@ -0,0 +1,145 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var has = require('lodash.has'); +var is = require('is'); +var isFunction = is.fn; +var isObject = is.object; +var assert = require('assert'); +var hapiInterface = require('../../src/interfaces/hapi.js'); +var ErrorMessage = require('../../src/classes/error-message.js'); +var Fuzzer = require('../../utils/fuzzer.js'); +var EventEmitter = require('events').EventEmitter; +var Configuration = require('../fixtures/configuration.js'); +var createLogger = require('../../src/logger.js'); + +describe('Hapi interface', function () { + describe('Fuzzing the setup handler', function () { + it('Should not throw when fuzzed with invalid types', function () { + var f = new Fuzzer(); + assert.doesNotThrow(function () { + f.fuzzFunctionForTypes(hapiInterface, ['object', 'object']); + return; + }); + }); + }); + describe('Providing valid input to the setup handler', function () { + var givenConfig = {getVersion: function () {return '1';}}; + var plugin; + beforeEach(function () {plugin = hapiInterface(null, givenConfig)}); + it('should have plain object as plugin', function () { + assert(isObject(plugin)); + }); + it('plugin should have a register function property', function () { + assert(has(plugin, 'register') && isFunction(plugin.register)); + }); + it('the plugin\'s register property should have an attributes property', + function () { + assert(has(plugin.register, 'attributes') && + isObject(plugin.register.attributes)); + } + ); + it('the plugin\'s attribute property should have a name property', + function () { + assert(has(plugin.register.attributes, 'name')); + assert.strictEqual(plugin.register.attributes.name, + '@google/cloud-errors'); + } + ); + it('the plugin\'s attribute property should have a version property', + function () { + assert(has(plugin.register.attributes, 'version')); + } + ); + }); + describe('hapiRegisterFunction behaviour', function () { + var fakeServer; + beforeEach(function () {fakeServer = new EventEmitter();}); + it('Should call sendError when the request-error event is emitted', function () { + var fakeClient = { + sendError: function ( errMsg ) { + assert(errMsg instanceof ErrorMessage, + 'The value given to sendError should be an instance of Error message'); + } + }; + var plugin = hapiInterface(fakeClient, { + lacksCredentials: function () { + return false; + }, + getVersion: function () { + return '1'; + }, + getServiceContext: function () { + return {service: 'node'} + } + }); + plugin.register(fakeServer, null, null, null); + fakeServer.emit('request-error'); + }); + }); + describe('Behaviour around the request/response lifecycle', function () { + var EVENT = 'onPreResponse'; + var fakeServer, config, plugin, fakeClient = {sendError: function () {}}; + before(function () { + config = new Configuration({ + projectId: 'xyz', + serviceContext: { + service: 'x', + version: '1.x' + } + }); + config.lacksCredentials = function () {return false;}; + plugin = hapiInterface(fakeClient, config); + }); + beforeEach(function () { + fakeServer = new EventEmitter(); + fakeServer.ext = fakeServer.on; + }); + afterEach(function () { + fakeServer.removeAllListeners(); + }); + it('Should call continue when a boom preResponse is emitted', function (done) { + plugin.register(fakeServer, null, function () {}); + fakeServer.emit(EVENT, {response: {isBoom: true}}, + { + continue: function () { + // The continue function should be called + done(); + } + } + ); + }); + it('Should call sendError when a boom response is received', function (done) { + var fakeClient = { + sendError: function (err) { + assert(err instanceof ErrorMessage); + done(); + } + }; + var plugin = hapiInterface(fakeClient, config); + plugin.register(fakeServer, null, function () {}); + fakeServer.emit('onPreResponse', {response:{isBoom: true}}); + }); + it('Should call next when completing a request', function (done) { + plugin.register(fakeServer, null, function (err) { + // The next function should be called + done(); + }); + fakeServer.emit(EVENT, {response: {isBoom: true}}, + {continue: function () {}}); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js new file mode 100644 index 00000000000..bd79db92b70 --- /dev/null +++ b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js @@ -0,0 +1,124 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var hapiRequestInformationExtractor = require('../../src/request-extractors/hapi.js'); +var Fuzzer = require('../../utils/fuzzer.js'); + +describe('hapiRequestInformationExtractor behaviour', function () { + describe('behaviour given invalid input', function () { + it('Should produce the default value', function () { + var DEFAULT_RETURN_VALUE = { + method: "", + url: "", + userAgent: "", + referrer: "", + statusCode: 0, + remoteAddress: "" + }; + var f = new Fuzzer(); + var cbFn = function (value) { + assert.deepEqual(value, DEFAULT_RETURN_VALUE); + }; + f.fuzzFunctionForTypes( + hapiRequestInformationExtractor + , ["object"] + , cbFn + ); + }); + }); + describe('behaviour given valid input', function () { + var FULL_REQ_DERIVATION_VALUE = { + method: "STUB_METHOD" + , url: "www.TEST-URL.com" + , info: { + remoteAddress: "0.0.0.0" + } + , headers: { + 'x-forwarded-for': '0.0.0.1' + , 'user-agent': "Something like Mozilla" + , referrer: "www.ANOTHER-TEST.com" + } + , response: { + statusCode: 200 + } + }; + var FULL_REQ_EXPECTED_VALUE = { + method: "STUB_METHOD" + , url: "www.TEST-URL.com" + , userAgent: "Something like Mozilla" + , referrer: "www.ANOTHER-TEST.com" + , remoteAddress: '0.0.0.1' + , statusCode: 200 + }; + var PARTIAL_REQ_DERIVATION_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , info: { + remoteAddress: "0.0.2.1" + } + , headers: { + 'user-agent': "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + } + , response: { + output: { + statusCode: 201 + } + } + }; + var PARTIAL_REQ_EXPECTED_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , userAgent: "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + , remoteAddress: "0.0.2.1" + , statusCode: 201 + }; + var ANOTHER_PARTIAL_REQ_DERIVATION_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , headers: { + 'user-agent': "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + } + }; + var ANOTHER_PARTIAL_REQ_EXPECTED_VALUE = { + method: "STUB_METHOD_#2" + , url: "www.SUPER-TEST.com" + , userAgent: "Something like Gecko" + , referrer: "www.SUPER-ANOTHER-TEST.com" + , remoteAddress: "" + , statusCode: 0 + }; + it('Should produce the full request input', function () { + assert.deepEqual( + hapiRequestInformationExtractor(FULL_REQ_DERIVATION_VALUE), + FULL_REQ_EXPECTED_VALUE); + }); + it('Should produce the partial request input', function () { + assert.deepEqual( + hapiRequestInformationExtractor(PARTIAL_REQ_DERIVATION_VALUE), + PARTIAL_REQ_EXPECTED_VALUE); + }); + it('Should produce the second partial request input', function () { + assert.deepEqual( + hapiRequestInformationExtractor(ANOTHER_PARTIAL_REQ_DERIVATION_VALUE), + ANOTHER_PARTIAL_REQ_EXPECTED_VALUE + ); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js new file mode 100644 index 00000000000..7255d57c36b --- /dev/null +++ b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js @@ -0,0 +1,67 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var koaRequestInformationExtractor = require('../../src/request-extractors/koa.js'); +var Fuzzer = require('../../utils/fuzzer.js'); + +describe('koaRequestInformationExtractor', function () { + describe('Behaviour under invalid input', function () { + it('Should produce a default value', function () { + var DEFAULT_RETURN_VALUE = { + method: '', + url: '', + userAgent: '', + referrer: '', + statusCode: 0, + remoteAddress: '' + }; + var f = new Fuzzer(); + var cbFn = function (value) { + assert.deepEqual(value, DEFAULT_RETURN_VALUE); + }; + f.fuzzFunctionForTypes(koaRequestInformationExtractor, + ['object', 'object'], cbFn); + }); + }); + describe('Behaviour under valid input', function () { + it('Should produce the expected value', function () { + var FULL_REQ_DERIVATION_VALUE = { + method: 'STUB_METHOD', + url: 'www.TEST-URL.com', + headers: { + 'user-agent': 'Something like Mozilla', + referrer: 'www.ANOTHER-TEST.com' + }, + ip: '0.0.0.0' + }; + var FULL_RES_DERIVATION_VALUE = { + 'status': 200 + }; + var FULL_REQ_EXPECTED_VALUE = { + method: 'STUB_METHOD', + url: 'www.TEST-URL.com', + userAgent: 'Something like Mozilla', + referrer: 'www.ANOTHER-TEST.com', + remoteAddress: '0.0.0.0', + statusCode: 200 + }; + assert.deepEqual( + koaRequestInformationExtractor(FULL_REQ_DERIVATION_VALUE, FULL_RES_DERIVATION_VALUE), + FULL_REQ_EXPECTED_VALUE); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testLogger.js b/packages/error-reporting/test/unit/testLogger.js new file mode 100644 index 00000000000..32f33e54647 --- /dev/null +++ b/packages/error-reporting/test/unit/testLogger.js @@ -0,0 +1,68 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var assert = require('assert'); +var createLogger = require('../../src/logger.js'); + +describe('logger', function () { + describe('Initialization', function () { + var oldEnv; + before(function () { + oldEnv = process.env.GCLOUD_ERRORS_LOGLEVEL; + delete process.env.GCLOUD_ERRORS_LOGLEVEL; + }); + after(function () {process.env.GCLOUD_ERRORS_LOGLEVEL = oldEnv;}); + describe('Exception handling', function () { + it('Should not throw given undefined', function () { + assert.doesNotThrow(createLogger, createLogger()); + }); + it('Should not throw given an empty object', function () { + assert.doesNotThrow(createLogger.bind(null, {}), createLogger()); + }); + it('Should not throw given logLevel as a number', function () { + assert.doesNotThrow(createLogger.bind(null, {logLevel: 3}), + createLogger({logLevel: 3})); + }); + it('Should not throw given logLevel as a string', function () { + assert.doesNotThrow(createLogger.bind(null, {logLevel: '3'}), + createLogger({logLevel: 3})); + }); + it('Should not throw given an env variable to use', function () { + process.env.GCLOUD_ERRORS_LOGLEVEL = 4; + assert.doesNotThrow(createLogger, createLogger({logLevel: 4})); + delete process.env.GCLOUD_ERRORS_LOGLEVEL; + }); + it('Should thow given logLevel as null', function () { + assert.throws(createLogger.bind(null, {logLevel: null}), + undefined); + }); + }); + describe('Default log level', function () { + it('Should be WARN', function () { + var buf = []; + var orig = console._stdout.write; + console._stdout.write = function () { + buf.push(arguments[0]); + orig.apply(this, arguments); + }; + var logger = createLogger({}); + logger.warn('test warning message'); + assert(buf.pop().match(/test warning message/)); + }); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testManualHandler.js b/packages/error-reporting/test/unit/testManualHandler.js new file mode 100644 index 00000000000..8c3eb794c46 --- /dev/null +++ b/packages/error-reporting/test/unit/testManualHandler.js @@ -0,0 +1,183 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var manual = require('../../src/interfaces/manual.js'); +var Configuration = require('../fixtures/configuration.js'); +var config = new Configuration({}); +config.lacksCredentials = function () { + return false; +}; +var ErrorMessage = require('../../src/classes/error-message.js'); +// var nock = require('nock'); + +describe('Manual handler', function () { + // nock.disableNetConnect(); + // Mocked client + var client = { + sendError: function(e, cb) { + // immediately callback + if (cb) { + setImmediate(cb); + } + } + }; + var report = manual(client, config); + describe('Report invocation behaviour', function () { + it('Should allow argument-less invocation', function () { + var r = report(); + assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); + }); + it('Should allow single string', function () { + var r = report('doohickey'); + assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); + assert(r.message.match(/doohickey/), 'string error should propagate'); + }); + it('Should allow single instance of Error', function () { + var r = report(new Error('hokeypokey')); + assert(r.message.match(/hokeypokey/)); + }); + it('Should allow a single function as a malformed error input', function (done) { + this.timeout(2000); + var r = report(function(err, res) { + assert(false, 'callback should not be called'); + done(); + }); + assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); + setTimeout(function() { + done(); + }, 1000); + }); + it('Should callback to the supplied function', function (done) { + var r = report('malarkey', function(err, res) { + done(); + }); + assert(r.message.match(/malarkey/), 'string error should propagate'); + }); + it('Should replace the error string with the additional message', function (done) { + var r = report('monkey', 'wrench', function(err, res) { + done(); + }); + assert.strictEqual(r.message, 'wrench', 'additional message should replace'); + }); + it('Should allow a full array of optional arguments', function (done) { + var r = report('donkey', { method: 'FETCH' }, 'cart', function(err, res) { + done(); + }); + assert.strictEqual(r.message, 'cart', 'additional message should replace'); + assert.strictEqual(r.context.httpRequest.method, 'FETCH'); + }); + it('Should allow all optional arguments except the callback', function () { + var r = report('whiskey', { method: 'SIP' }, 'sour'); + assert.strictEqual(r.message, 'sour', 'additional message should replace'); + assert.strictEqual(r.context.httpRequest.method, 'SIP'); + }); + it('Should allow a lack of additional message', function (done) { + var r = report('ticky', { method: 'TACKEY' }, function(err, res) { + done(); + }); + assert(r.message.match(/ticky/) && !r.message.match(/TACKEY/), + 'original message should be preserved'); + assert.strictEqual(r.context.httpRequest.method, 'TACKEY'); + }); + it('Should ignore arguments after callback value placement', function (done) { + var r = report('hockey', function(err, res) { + done(); + }, 'field'); + assert(r.message.match('hockey') && !r.message.match('field'), + 'string after callback should be ignored'); + }); + it('Should ignore arguments after callback value placement', function (done) { + var r = report('passkey', function(err, res) { + done(); + }, { method: 'HONK'}); + assert.notEqual(r.context.httpRequest.method, 'HONK'); + }); + it('Should allow null arguments as placeholders', function (done) { + var r = report('pokey', null, null, function(err, res) { + done(); + }); + assert(r.message.match(/pokey/), 'string error should propagate'); + }); + it('Should allow explicit undefined arguments as placeholders', function (done) { + var r = report('Turkey', undefined, undefined, function(err, res) { + done(); + }); + assert(r.message.match(/Turkey/), 'string error should propagate'); + }); + it('Should allow request to be supplied as undefined', function (done) { + var r = report('turnkey', undefined, 'solution', function(err, res) { + done(); + }); + assert.strictEqual(r.message, 'solution', 'string error should propagate'); + }); + it('Should allow additional message to be supplied as undefined', function (done) { + var r = report('Mickey', { method: 'SNIFF'}, undefined, function(err, res) { + done(); + }); + assert(r.message.match(/Mickey/) && !r.message.match(/SNIFF/), + 'string error should propagate'); + assert.strictEqual(r.context.httpRequest.method, 'SNIFF'); + }); + }); + + describe('Custom Payload Builder', function () { + it('Should accept builder instance as only argument', function () { + var msg = 'test'; + var r = report(new ErrorMessage().setMessage(msg)); + assert.strictEqual(r.message, msg, + 'string message should propagate from error message instance'); + }); + it('Should accept builder and request as arguments', function () { + var msg = 'test'; + var oldReq = {method: 'GET'}; + var newReq = {method: 'POST'}; + var r = report( + new ErrorMessage().setMessage(msg).consumeRequestInformation(oldReq), + newReq + ); + assert.strictEqual(r.message, msg, + 'string message should propagate from error message instance'); + assert.strictEqual(r.context.httpRequest.method, newReq.method, + [ + 'request argument supplied at report invocation should propagte and, if', + 'supplied, should overwrite any prexisting data in the field.' + ].join('\n') + ); + }); + it('Should accept message and additional message params as arguments', function () { + var oldMsg = 'test'; + var newMsg = 'analysis'; + var r = report( + new ErrorMessage().setMessage(oldMsg), + newMsg + ); + assert.strictEqual(r.message, newMsg, + [ + 'message argument supplied at report invocation should propagte and, if', + 'supplied, should overwrite any prexisting data in the message field.' + ].join('\n')); + }); + it('Should accept message and callback function as arguments', function (done) { + var oldMsg = 'test'; + var newMsg = 'analysis'; + var r = report( + new ErrorMessage().setMessage(oldMsg), + function () { done(); } + ); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js new file mode 100644 index 00000000000..efcf225c356 --- /dev/null +++ b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js @@ -0,0 +1,110 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var omit = require('lodash.omit'); +var extend = require('extend'); +var manualRequestInformationExtractor = require('../../src/request-extractors/manual.js'); +var Fuzzer = require('../../utils/fuzzer.js'); + +describe('manualRequestInformationExtractor', function () { + describe('Behaviour given invalid input', function () { + it('Should return default values', function () { + var DEFAULT_RETURN_VALUE = { + method: '', + url: '', + userAgent: '', + referrer: '', + statusCode: 0, + remoteAddress: '' + }; + var f = new Fuzzer(); + var cbFn = function (value) { + assert.deepEqual(value, DEFAULT_RETURN_VALUE); + }; + f.fuzzFunctionForTypes(manualRequestInformationExtractor, ["object"], + cbFn); + }); + }); + describe('Behaviour given valid input', function () { + var FULL_VALID_INPUT = { + method: 'GET', + url: 'http://0.0.0.0/myTestRoute', + userAgent: 'Something like Gecko', + referrer: 'www.example.com', + statusCode: 500, + remoteAddress: '0.0.0.1' + }; + it('Should return expected output', function () { + assert.deepEqual( + manualRequestInformationExtractor(FULL_VALID_INPUT), + FULL_VALID_INPUT, + [ + "Given a full valid input object these values should be reflected by" + , "the output of the request extraction" + ].join(" ") + ); + assert.deepEqual( + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "method")), + extend({}, FULL_VALID_INPUT, {method: ""}), + [ + "Given a full valid input object sans the method property these values" + , "should be reflected by the output of the request extraction" + ].join(" ") + ); + assert.deepEqual( + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "url")), + extend({}, FULL_VALID_INPUT, {url: ""}), + [ + "Given a full valid input sans the url property these values should be" + , "reflected by the output of the request extraction" + ] + ); + assert.deepEqual( + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "userAgent")), + extend({}, FULL_VALID_INPUT, {"userAgent": ""}), + [ + "Given a full valid input sans the userAgent property these values" + , "should be reflected by the output of the request extraction" + ] + ); + assert.deepEqual( + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "referrer")), + extend({}, FULL_VALID_INPUT, {referrer: ""}), + [ + "Given a full valid input sans the referrer property these values" + , "should be reflected by the output of the request extraction" + ] + ); + assert.deepEqual( + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "statusCode")), + extend({}, FULL_VALID_INPUT, {statusCode: 0}), + [ + "Given a full valid input sans the statusCode property these values" + , "should be reflected by the output of the request extraction" + ] + ); + assert.deepEqual( + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "remoteAddress")), + extend({}, FULL_VALID_INPUT, {remoteAddress: ""}), + [ + "Given a full valid input sans the remoteAddress property these values" + , "should be reflected by the output of the request extraction" + ] + ); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testRequestInformationContainer.js b/packages/error-reporting/test/unit/testRequestInformationContainer.js new file mode 100644 index 00000000000..c66e48ed14b --- /dev/null +++ b/packages/error-reporting/test/unit/testRequestInformationContainer.js @@ -0,0 +1,93 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var RequestInformationContainer = require('../../src/classes/request-information-container.js'); +var Fuzzer = require('../../utils/fuzzer.js'); + +describe('RequestInformationContainer', function () { + var f = new Fuzzer(); + var cbFn, ric; + beforeEach(function () {ric = new RequestInformationContainer();}); + describe('Fuzzing against RequestInformationContainer for negative cases', function () { + it('Should return the RequestInformationContainer.url propertym as an empty string', + function () { + cbFn = function () { + assert.deepEqual(ric.url, ''); + }; + f.fuzzFunctionForTypes(ric.setUrl, ["string"], cbFn, ric); + } + ); + it('Should return the method property as an empty string', function () { + cbFn = function ( returnValue ) { + assert.deepEqual(ric.method, ''); + }; + f.fuzzFunctionForTypes(ric.setMethod, ["string"], cbFn, ric); + }); + it('Should return the referrer property as an empty string', function () { + cbFn = function ( returnValue ) { + assert.deepEqual(ric.referrer, ''); + }; + f.fuzzFunctionForTypes(ric.setReferrer, ["string"], cbFn, ric); + }); + it('Should return the userAgent property as an empty string', function () { + cbFn = function ( returnValue ) { + assert.deepEqual(ric.userAgent, ''); + }; + f.fuzzFunctionForTypes(ric.setUserAgent, ["string"], cbFn, ric); + }); + it('Should return the remoteAddress property as an empty string', function () { + cbFn = function ( returnValue ) { + assert.deepEqual(ric.remoteAddress, ''); + }; + f.fuzzFunctionForTypes(ric.setRemoteAddress, ["string"], cbFn, ric); + }); + it('Should return the default value for statusCode', function () { + cbFn = function ( returnValue ) { + assert.strictEqual(ric.statusCode, 0); + }; + f.fuzzFunctionForTypes(ric.setStatusCode, ["number"], cbFn, ric); + }); + }); + describe('Fuzzing against RequestInformationContainer for positive cases', function () { + var VALID_STRING_INPUT = 'valid'; + var VALID_NUMBER_INPUT = 500; + it('Should assign the value to the url property', function () { + ric.setUrl(VALID_STRING_INPUT); + assert.deepEqual(ric.url, VALID_STRING_INPUT); + }); + it('Should assign the value to the method property', function () { + ric.setMethod(VALID_STRING_INPUT); + assert.deepEqual(ric.method, VALID_STRING_INPUT); + }); + it('Should assign the value to the referrer property', function () { + ric.setReferrer(VALID_STRING_INPUT); + assert.deepEqual(ric.referrer, VALID_STRING_INPUT); + }); + it('Should assign the value to the userAgent property', function () { + ric.setUserAgent(VALID_STRING_INPUT); + assert.deepEqual(ric.userAgent, VALID_STRING_INPUT); + }); + it('Should assign the value to remoteAddress property', function () { + ric.setRemoteAddress(VALID_STRING_INPUT); + assert.deepEqual(ric.remoteAddress, VALID_STRING_INPUT); + }); + it('Should assign the value to statusCode property', function () { + ric.setStatusCode(VALID_NUMBER_INPUT); + assert.deepEqual(ric.statusCode, VALID_NUMBER_INPUT); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testRestifyInterface.js b/packages/error-reporting/test/unit/testRestifyInterface.js new file mode 100644 index 00000000000..46870464afc --- /dev/null +++ b/packages/error-reporting/test/unit/testRestifyInterface.js @@ -0,0 +1,134 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var EventEmitter = require('events').EventEmitter; +var assert = require('assert'); +var restifyInterface = require('../../src/interfaces/restify.js'); + +// node v0.12 compatibility +if (!EventEmitter.prototype.listenerCount) { + EventEmitter.prototype.listenerCount = function(eventName) { + return EventEmitter.listenerCount(this, eventName); + } +} + +describe('restifyInterface', function () { + var UNCAUGHT_EVENT = 'uncaughtException'; + var FINISH = 'finish'; + var noOp = function () {return;}; + describe('Attachment to the uncaughtException event', function () { + it('Should attach one listener after instantiation', function () { + var ee = new EventEmitter; + assert.strictEqual(ee.listenerCount(UNCAUGHT_EVENT), 0, + 'Listeners on event should be zero'); + // return the bound function which the user will actually interface with + var errorHandlerInstance = restifyInterface(null, null); + // execute the handler the user will use with the stubbed server instance + errorHandlerInstance(ee); + assert.strictEqual(ee.listenerCount(UNCAUGHT_EVENT), 1, + 'Listeners on event should now be one'); + }); + }); + describe('Request handler lifecycle events', function () { + var ee = new EventEmitter; + var errorHandlerInstance = restifyInterface(null, null); + var requestHandlerInstance = errorHandlerInstance(ee); + describe('default path on invalid input', function () { + it('Should not throw', function () { + assert.doesNotThrow(function () { + requestHandlerInstance(null, null, noOp); + }); + }); + }); + describe('default path without req/res error', function () { + ee.removeAllListeners(); + var req = new EventEmitter; + var res = new EventEmitter; + res.statusCode = 200; + it('Should have 0 listeners on the finish event', function () { + assert.strictEqual(res.listenerCount(FINISH), 0); + }); + it('Should not throw while handling the req/res objects', function () { + assert.doesNotThrow(function () { + requestHandlerInstance(req, res, noOp); + }); + }); + it('Should have 1 listener on the finish event after handling req/res', function () { + assert.strictEqual(res.listenerCount(FINISH), 1); + }); + it('Should not throw when emitting the finish event', function () { + assert.doesNotThrow(function () { + res.emit(FINISH); + }); + }); + }); + describe('default path with req/res error', function (done) { + ee.removeAllListeners(); + var client = { + sendError: function () { + assert(true, 'sendError should be called'); + } + }; + var config = { + getServiceContext: function ( ) { + assert(true, 'getServiceContext should be called'); + return { + service: 'stub-service', + version: 'stub-version' + } + }, + lacksCredentials: function () { + return false; + }, + getVersion: function () { + return '1'; + } + }; + var errorHandlerInstance = restifyInterface(client, config); + var requestHandlerInstance = errorHandlerInstance(ee); + var req = new EventEmitter; + var res = new EventEmitter; + res.statusCode = 500; + it('Should have 0 Listeners on the finish event', function () { + assert.strictEqual(res.listenerCount(FINISH), 0); + }); + it('Should not throw on instantiation', function () { + assert.doesNotThrow(function () { + requestHandlerInstance(req, res, noOp); + }); + }); + it('Should have 1 listener on the finish event after instantiation', function () { + assert.strictEqual(res.listenerCount(FINISH), 1); + }); + it('Should not throw on emission of the finish event', function () { + assert.doesNotThrow(function () { + res.emit(FINISH); + }); + }); + describe('Exercise the uncaughtException event path', function () { + it('Should call the sendError function property on the client', function (done) { + client.sendError = function () { + assert(true, 'sendError should be called'); + done(); + }; + assert.doesNotThrow(function () { + ee.emit(UNCAUGHT_EVENT); + }); + }); + }); + }); + }); +}); diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js new file mode 100644 index 00000000000..26d5f06e93d --- /dev/null +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -0,0 +1,498 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var assert = require('assert'); +var is = require('is'); +var isNull = is.null; +var isString = is.string; +var isNumber = is.number; +var forEach = require('lodash.foreach'); +var assign = require('lodash.assign'); +var omitBy = require('lodash.omitby'); +var Configuration = require('../fixtures/configuration.js'); +var level = process.env.GCLOUD_ERRORS_LOGLEVEL; +var logger = require('../../src/logger.js')({ + logLevel: isNumber(level) ? level : 4 +}); +var env = { + GAE_SERVICE: process.env.GAE_SERVICE, + GAE_VERSION: process.env.GAE_VERSION, + GAE_MODULE_VERSION: process.env.GAE_MODULE_VERSION, + FUNCTION_NAME: process.env.FUNCTION_NAME, + GAE_MODULE_NAME: process.env.GAE_MODULE_NAME +}; +function sterilizeEnv () { + forEach(env, function (val, key) { + delete process.env[key]; + }); +} +function setEnv (serviceName, serviceVersion, moduleName, moduleVersion, functionName) { + assign(process.env, omitBy({ + GAE_SERVICE: serviceName, + GAE_VERSION: serviceVersion, + GAE_MODULE_NAME: moduleName, + GAE_MODULE_VERSION: moduleVersion, + FUNCTION_NAME: functionName + }, function (val) {return !isString(val)})); +} +function restoreEnv () { + assign(process.env, env); +} + +describe('Testing service configuration', function () { + beforeEach(function () {sterilizeEnv();}); + after(function () {restoreEnv();}); + it( + 'A Configuration uses the function name as the service name on GCF ' + + 'if the service name is not given in the given config', + function () { + setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', + 'someFunction'); + var c = new Configuration({}, logger); + assert.deepEqual(c.getServiceContext().service, 'someFunction'); + // FUNCTION_NAME is set and the user didn't specify a version, and so + // the version should not be defined + assert.deepEqual(c.getServiceContext().version, undefined); + } + ); + it( + 'A Configuration uses the function name as the service name on GCF ' + + 'if the service name is not given in the given config ' + + 'even if the GAE_SERVICE was not set', + function () { + setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); + var c = new Configuration({}, logger); + assert.deepEqual(c.getServiceContext().service, 'someFunction'); + // The user didn't specify a version and FUNCTION_NAME is defined, and + // so the version should not be defined + assert.deepEqual(c.getServiceContext().version, undefined); + } + ); + it( + 'A Configuration uses the GAE_SERVICE env value as the service name ' + + 'if the FUNCTION_NAME env variable is not set and the given config ' + + 'does not specify the service name', + function () { + setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); + var c = new Configuration({}, logger); + assert.deepEqual(c.getServiceContext().service, 'someModuleName'); + // The user didn't specify a version, and FUNCTION_NAME is not defined, + // and so use the GAE_MODULE_VERSION + assert.deepEqual(c.getServiceContext().version, '1.0'); + } + ); + it( + 'A Configuration uses the service name in the given config if it ' + + 'was specified and both the GAE_SERVICE and FUNCTION_NAME ' + + 'env vars are set', + function () { + setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', + 'someFunction'); + var c = new Configuration({ + serviceContext: { + service: 'customService' + } + }, logger); + assert.deepEqual(c.getServiceContext().service, 'customService'); + // The user didn't specify a version, but FUNCTION_NAME is defined, and + // so the version should not be defined + assert.deepEqual(c.getServiceContext().version, undefined); + } + ); + it( + 'A Configuration uses the service name and version in the given config if ' + + 'they were both specified and both the GAE_SERVICE and FUNCTION_NAME ' + + 'env vars are set', + function () { + setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', + 'someFunction'); + var c = new Configuration({ + serviceContext: { + service: 'customService', + version: '2.0' + } + }, logger); + assert.deepEqual(c.getServiceContext().service, 'customService'); + // The user specified version should be used + assert.deepEqual(c.getServiceContext().version, '2.0'); + } + ); + it( + 'A Configuration uses the service name in the given config if it ' + + 'was specified and only the GAE_SERVICE env var is set', + function () { + setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); + var c = new Configuration({ + serviceContext: { + service: 'customService' + } + }, logger); + assert.deepEqual(c.getServiceContext().service, 'customService'); + // The user didn't specify a version and FUNCTION_NAME is not defined + // and so the GAE_MODULE_VERSION should be used + assert.deepEqual(c.getServiceContext().version, '1.0'); + } + ); + it( + 'A Configuration uses the service name and version in the given config if ' + + 'they were both specified and only the GAE_SERVICE env var is set', + function () { + setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); + var c = new Configuration({ + serviceContext: { + service: 'customService', + version: '2.0' + } + }, logger); + assert.deepEqual(c.getServiceContext().service, 'customService'); + // The user specified version should be used + assert.deepEqual(c.getServiceContext().version, '2.0'); + } + ); + it( + 'A Configuration uses the service name in the given config if it ' + + 'was specified and only the FUNCTION_NAME env var is set', + function () { + setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); + var c = new Configuration({ + serviceContext: { + service: 'customService' + } + }, logger); + assert.deepEqual(c.getServiceContext().service, 'customService'); + // The user didn't specify a version and thus because FUNCTION_NAME is + // defined the version should not be defined + assert.deepEqual(c.getServiceContext().version, undefined); + } + ); + it( + 'A Configuration uses the service name and version in the given config if ' + + 'they were both specified and only the FUNCTION_NAME env var is set', + function () { + setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); + var c = new Configuration({ + serviceContext: { + service: 'customService', + version: '2.0' + } + }, logger); + assert.strictEqual(c.getServiceContext().service, 'customService'); + // The user specified version should be used + assert.strictEqual(c.getServiceContext().version, '2.0'); + } + ); + it( + 'A Configuration uses the service name "node" and no version if ' + + 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ + 'not specified a service name or version', + function () { + var c = new Configuration({}, logger); + assert.strictEqual(c.getServiceContext().service, 'node'); + assert.strictEqual(c.getServiceContext().version, undefined); + } + ); + it( + 'A Configuration uses the service name "node" and no version if ' + + 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ + 'not specified a service name or version even if GAE_VERSION has ' + + 'been set', + function () { + setEnv(null, 'InvalidVersion', null, 'InvalidVersion', null); + var c = new Configuration({}, logger); + assert.strictEqual(c.getServiceContext().service, 'node'); + assert.strictEqual(c.getServiceContext().version, undefined); + } + ); + it( + 'A Configuration uses the service name "node" and the user specified ' + + 'version if GAE_SERVICE is not set, FUNCTION_NAME is not set, and the ' + + 'user has not specified a service name but has specified a version', + function () { + var c = new Configuration({ + serviceContext: { + version: '2.0' + } + }, logger); + assert.deepEqual(c.getServiceContext().service, 'node'); + assert.deepEqual(c.getServiceContext().version, '2.0'); + } + ); + + // it( + // 'A Configuration uses the service name "node" and the user specified ' + + // 'version if GAE_SERVICE is not set, FUNCTION_NAME is not set, and the ' + + // 'user has not specified a service name but has specified a version even ' + + // 'if GAE_VERSION has been set', + // makeTest(null, 'InvalidVersion', + // null, 'InvalidVersion', + // null, + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // version: '2.0' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'node'); + // assert.deepEqual(c.getServiceContext().version, '2.0'); + + // done(); + // }) + // ); + + // // The following tests always have GAE_SERVICE and GAE_VERSION not set + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the function name as the service name on GCF ' + + // 'if the service name is not given in the given config', + // makeTest(null, null, 'someModuleName', '1.0', 'someFunction', + // function(done) { + // var c = new Configuration({}, logger); + // assert.deepEqual(c.getServiceContext().service, 'someFunction'); + // // FUNCTION_NAME is set and the user didn't specify a version, and so + // // the version should not be defined + // assert.deepEqual(c.getServiceContext().version, undefined); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the function name as the service name on GCF ' + + // 'if the service name is not given in the given config ' + + // 'even if the GAE_MODULE_NAME was not set', + // makeTest(null, null, null, '1.0', 'someFunction', + // function(done) { + // var c = new Configuration({}, logger); + // assert.deepEqual(c.getServiceContext().service, 'someFunction'); + // // The user didn't specify a version and FUNCTION_NAME is defined, and + // // so the version should not be defined + // assert.deepEqual(c.getServiceContext().version, undefined); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the GAE_MODULE_NAME env value as the service name ' + + // 'if the FUNCTION_NAME env variable is not set and the given config ' + + // 'does not specify the service name', + // makeTest(null, null, 'someModuleName', '1.0', null, + // function(done) { + // var c = new Configuration({}, logger); + // assert.deepEqual(c.getServiceContext().service, 'someModuleName'); + // // The user didn't specify a version, and FUNCTION_NAME is not defined, + // // and so use the GAE_MODULE_VERSION + // assert.deepEqual(c.getServiceContext().version, '1.0'); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name in the given config if it ' + + // 'was specified and both the GAE_MODULE_NAME and FUNCTION_NAME ' + + // 'env vars are set', + // makeTest(null, null, 'someModuleName', '1.0', 'someFunction', + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // service: 'customService' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'customService'); + // // The user didn't specify a version, but FUNCTION_NAME is defined, and + // // so the version should not be defined + // assert.deepEqual(c.getServiceContext().version, undefined); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name and version in the given config if ' + + // 'they were both specified and both the GAE_MODULE_NAME and FUNCTION_NAME ' + + // 'env vars are set', + // makeTest(null, null, 'someModuleName', '1.0', 'someFunction', + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // service: 'customService', + // version: '2.0' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'customService'); + // // The user specified version should be used + // assert.deepEqual(c.getServiceContext().version, '2.0'); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name in the given config if it ' + + // 'was specified and only the GAE_MODULE_NAME env var is set', + // makeTest(null, null, 'someModuleName', '1.0', null, + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // service: 'customService' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'customService'); + // // The user didn't specify a version and FUNCTION_NAME is not defined + // // and so the GAE_MODULE_VERSION should be used + // assert.deepEqual(c.getServiceContext().version, '1.0'); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name and version in the given config if ' + + // 'they were both specified and only the GAE_MODULE_NAME env var is set', + // makeTest(null, null, 'someModuleName', '1.0', null, + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // service: 'customService', + // version: '2.0' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'customService'); + // // The user specified version should be used + // assert.deepEqual(c.getServiceContext().version, '2.0'); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name in the given config if it ' + + // 'was specified and only the FUNCTION_NAME env var is set', + // makeTest(null, null, null, '1.0', 'someFunction', + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // service: 'customService' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'customService'); + // // The user didn't specify a version and thus because FUNCTION_NAME is + // // defined the version should not be defined + // assert.deepEqual(c.getServiceContext().version, undefined); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name and version in the given config if ' + + // 'they were both specified and only the FUNCTION_NAME env var is set', + // makeTest(null, null, null, '1.0', 'someFunction', + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // service: 'customService', + // version: '2.0' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'customService'); + // // The user specified version should be used + // assert.deepEqual(c.getServiceContext().version, '2.0'); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name "node" and no version if ' + + // 'GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the user has '+ + // 'not specified a service name or version', + // makeTest(null, null, null, null, null, + // function(done) { + // var c = new Configuration({}, logger); + // assert.deepEqual(c.getServiceContext().service, 'node'); + // assert.deepEqual(c.getServiceContext().version, undefined); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name "node" and no version if ' + + // 'GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the user has '+ + // 'not specified a service name or version even if GAE_MODULE_VERSION has ' + + // 'been set', + // makeTest(null, null, null, '1.0', null, + // function(done) { + // var c = new Configuration({}, logger); + // assert.deepEqual(c.getServiceContext().service, 'node'); + // assert.deepEqual(c.getServiceContext().version, undefined); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name "node" and the user specified ' + + // 'version if GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the ' + + // 'user has not specified a service name but has specified a version', + // makeTest(null, null, null, null, null, + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // version: '2.0' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'node'); + // assert.deepEqual(c.getServiceContext().version, '2.0'); + + // done(); + // }) + // ); + + // it( + // 'With GAE_SERVICE and GAE_VERSION not set: ' + + // 'A Configuration uses the service name "node" and the user specified ' + + // 'version if GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the ' + + // 'user has not specified a service name but has specified a version even ' + + // 'if GAE_MODULE_VERSION has been set', + // makeTest(null, null, null, '1.0', null, + // function(done) { + // var c = new Configuration({ + // serviceContext: { + // version: '2.0' + // } + // }, logger); + // assert.deepEqual(c.getServiceContext().service, 'node'); + // assert.deepEqual(c.getServiceContext().version, '2.0'); + + // done(); + // }) + // ); +}); diff --git a/packages/error-reporting/test/unit/testUncaught.js b/packages/error-reporting/test/unit/testUncaught.js new file mode 100644 index 00000000000..756193c7c3f --- /dev/null +++ b/packages/error-reporting/test/unit/testUncaught.js @@ -0,0 +1,94 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +var assert = require('assert'); +var isString = require('is').string; +var uncaughtSetup = require('../../src/interfaces/uncaught.js'); +var Configuration = require('../fixtures/configuration.js'); +var createLogger = require('../../src/logger.js'); +var originalHandlers = process.listeners('uncaughtException'); +var spawn = require('child_process').spawn; + +function reattachOriginalListeners ( ) { + for (var i = 0; i < originalHandlers.length; i++) { + process.on('uncaughtException', originalHandlers[i]); + } +} + +// Returns a Configuration object with given value for reportUncaughtExceptions, +// and dummy logger +function getConfig(reportUncaughtExceptions) { + var c = new Configuration({ + reportUncaughtExceptions: reportUncaughtExceptions + }, createLogger({logLevel: 4})); + c.lacksCredentials = function () { + return false; + }; + return c; +} + +describe('Uncaught exception handler behvaiour', function () { + var UNCAUGHT = 'uncaughtException'; + describe('Instantiation', function () { + beforeEach(function () {process.removeAllListeners(UNCAUGHT);}); + it('Should throw without a configuration', function () { + assert.throws(uncaughtSetup); + }); + it('Should not throw given a valid configuration', function () { + assert.doesNotThrow(uncaughtSetup.bind(null, {}, getConfig(false))); + assert.doesNotThrow(uncaughtSetup.bind(null, {}, getConfig(true))); + }); + it('Should return the process object after instantiation', function () { + assert.strictEqual(process, uncaughtSetup({}, getConfig(true))); + }); + it('Should not attach a listener to the uncaughtException event if ' + + 'reportUncaughtExceptions is false', function () { + uncaughtSetup({}, getConfig(false)); + assert.strictEqual(process.listeners(UNCAUGHT).length, 0); + }); + it('Should attach a listener to the uncaughtException event if ' + + 'reportUncaughtExceptions is true', function () { + uncaughtSetup({}, getConfig(true)); + assert.strictEqual(process.listeners(UNCAUGHT).length, 1); + }); + }); + describe('Uncaught exception handling shutdown behaviour', function () { + before(function () { + if (!isString(process.env.GOOGLE_APPLICATION_CREDENTIALS) + || !isString(process.env.GCLOUD_PROJECT)) { + this.skip(); + return; + } + }); + after(function () { + reattachOriginalListeners(); + }) + it('Should terminate before 2500ms', function (done) { + var TERMINATE_MSG = 'Should terminate before 2500ms'; + this.timeout(3500); + var isolate = spawn('./node_modules/mocha/bin/mocha', + ['../../test/fixtures/uncaughtExitBehaviour.js'], {env: process.env}); + isolate.on('close', function () { + done(); + }); + isolate.on('error', function () { + console.log('Test isolate encountered error:', '\n', arguments); + assert(false, TERMINATE_MSG); + done(); + }); + }); + }); +}); diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js new file mode 100644 index 00000000000..91b67767104 --- /dev/null +++ b/packages/error-reporting/utils/fuzzer.js @@ -0,0 +1,313 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ + +'use strict'; +var indexOf = require('lodash.indexof'); +var without = require('lodash.without'); +var maxBy = require('lodash.maxby'); +var random = require('lodash.random'); +var is = require('is'); +var isNumber = is.number; +var isObject = is.object; +var isString = is.string; +var isArray = is.array; +var isNull = is.null; +var isFunction = is.function; + +function Fuzzer ( ) { } + +Fuzzer.prototype.generate = {}; + +Fuzzer.prototype.generate.types = function ( ) { + return [ + "object", + "array", + "string", + "number", + "null", + "undefined", + "function", + "boolean" + ]; +} + +Fuzzer.prototype.generate.string = function ( len ) { + var lenChecked = isNumber(len) ? len : 10; + var chars = []; + + for ( var i = 0; i < lenChecked; i++ ) { + + chars.push(String.fromCharCode(random(32, 126))); + } + + return chars.join(""); +}; + +Fuzzer.prototype.generate.boolean = function ( ) { + + return !!random(0, 1); +} + +Fuzzer.prototype.generate.alphaNumericString = function ( len ) { + var lenChecked = isNumber(len) ? len : 10; + var chars = []; + var thisRange = []; + var ranges = [[48, 57], [65, 90], [97, 122]]; + + for ( var i = 0; i < lenChecked; i++ ) { + + thisRange = ranges[random(0, 2)]; + chars.push( + String.fromCharCode( + random( + thisRange[0] + , thisRange[1] + ) + ) + ); + } + + return chars.join(""); +} + +Fuzzer.prototype.generate.function = function ( ) { + + var availableTypes = without(this.types(), "function"); + var typeToGen = this.types()[random(0, availableTypes.length-1)]; + var fnToCall = this[typeToGen]; + + return function ( ) { + + return fnToCall(); + }; +} + +Fuzzer.prototype.generate.number = function ( lower, upper ) { + + var lowerChecked = isNumber(lower) ? lower : 0; + var upperChecked = isNumber(upper) ? upper : 100; + + return random(lowerChecked, upperChecked); +} + +Fuzzer.prototype.generate.null = function ( ) { + + return null; +} + +Fuzzer.prototype.generate.undefined = function ( ) { + + return undefined; +} + +Fuzzer.prototype.generate.array = function ( len, ofOneType, currentDepth, allowedDepth ) { + + var lenChecked = isNumber(len) ? len : random(1, 10); + var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType] : this.types(); + var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; + var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth : 3; + var arr = []; + var currentTypeBeingGenerated = ""; + currentDepthChecked += 1; + + // Deny the ability to nest more objects + if ( currentDepthChecked >= allowedDepthChecked ) { + + availableTypes = without(this.types(), "object", "array"); + } + + for ( var i = 0; i < lenChecked; i++ ) { + currentTypeBeingGenerated = availableTypes[random(0, availableTypes.length-1)]; + + if ( currentTypeBeingGenerated === "object" ) { + + arr.push( + this[currentTypeBeingGenerated]( + null + , currentDepthChecked + , allowedDepthChecked + ) + ); + } else if ( currentTypeBeingGenerated === "array" ) { + + arr.push( + this[currentTypeBeingGenerated]( + null + , ofOneType + , currentDepthChecked + , allowedDepthChecked + ) + ); + } else { + + arr.push(this[currentTypeBeingGenerated]()); + } + } + + return arr; +} + +Fuzzer.prototype.generate.object = function ( numProperties, currentDepth, allowedDepth ) { + + var numPropertiesChecked = isNumber(numProperties) ? numProperties : random(1, 10); + var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; + var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth : 3; + var obj = {}; + currentDepthChecked += 1; + + var availableTypes = this.types() + + // Deny the ability to nest more objects + if ( currentDepth >= allowedDepth ) { + availableTypes = without(availableTypes, "object", "array"); + } + + var currentTypeBeingGenerated = 0; + var currentKey = ""; + + for ( var i = 0; i < numPropertiesChecked; i++ ) { + + currentTypeBeingGenerated = availableTypes[random(0, availableTypes.length-1)]; + currentKey = this.alphaNumericString(random(1, 10)); + + if ( currentTypeBeingGenerated === "object" ) { + + obj[currentKey] = this[currentTypeBeingGenerated](null, currentDepthChecked, allowedDepthChecked); + } else if ( currentTypeBeingGenerated === "array" ) { + + obj[currentKey] = this[currentTypeBeingGenerated](null, null, currentDepthChecked, allowedDepthChecked); + } else { + + obj[currentKey] = this[currentTypeBeingGenerated](); + } + } + + return obj; +} + +Fuzzer.prototype._backFillUnevenTypesArrays = function ( argsTypesArray ) { + + var largestIndex = 0; + var largestLength = (maxBy( + argsTypesArray + , function ( o ) { return o.length } + )).length; + + for ( var i = 0; i < argsTypesArray.length; i++ ) { + if ( argsTypesArray[i].length !== largestLength ) { + + while ( argsTypesArray[i].length < largestLength ) { + argsTypesArray[i].push( + argsTypesArray[i][random(0, argsTypesArray[i].length-1)] + ); + } + } + } + + return argsTypesArray; +} + +Fuzzer.prototype._normalizeTypesArrayLengths = function ( argsTypesArray ) { + + var allAreTheSameLength = true; + var lastLength = argsTypesArray[0].length; + + for ( var i = 1; i < argsTypesArray.length; i++ ) { + + if ( argsTypesArray[i].length !== lastLength ) { + + allAreTheSameLength = false; + break; + } + } + + if ( allAreTheSameLength ) { + + return argsTypesArray; + } + + return this._backFillUnevenTypesArrays( argsTypesArray ); +} + +Fuzzer.prototype._generateTypesToFuzzWith = function ( expectsArgTypes ) { + var argsTypesArray = []; + var tmpArray = this.generate.types(); + + for ( var i = 0; i < expectsArgTypes.length; i++ ) { + + if ( !isArray(expectsArgTypes[i]) ) { + argsTypesArray.push( + without( + this.generate.types() + , expectsArgTypes[i] + ) + ); + } else { + + for ( var j = 0; j < expectsArgTypes[i].length; j++ ) { + + tmpArray = without( + tmpArray + , expectsArgTypes[i][j] + ); + } + + argsTypesArray.push([].concat(tmpArray)); + tmpArray = this.generate.types(); + } + } + + argsTypesArray = this._normalizeTypesArrayLengths(argsTypesArray); + return argsTypesArray; +} + +Fuzzer.prototype._generateValuesForFuzzTyping = function ( typesToFuzzOnEach, index ) { + var args = []; + var typeToGen = ""; + + for ( var i = 0; i < typesToFuzzOnEach.length; i++ ) { + typeToGen = typesToFuzzOnEach[i][index]; + + args.push(this.generate[typeToGen]()); + } + + return args; +} + +Fuzzer.prototype.fuzzFunctionForTypes = function ( fnToFuzz, expectsArgTypes, cb, withContext ) { + var expectsArgTypesChecked = isArray(expectsArgTypes) ? expectsArgTypes : []; + var typesToFuzzOnEach = this._generateTypesToFuzzWith( expectsArgTypesChecked ); + var withContextChecked = (withContext !== undefined) ? withContext : null; + + var returnValue = undefined; + + for ( var i = 0; i < typesToFuzzOnEach[0].length; i++ ) { + + returnValue = fnToFuzz.apply( + withContext + , this._generateValuesForFuzzTyping(typesToFuzzOnEach, i) + ); + + if ( isFunction(cb) ) { + + cb(returnValue); + } + } + + return true; +} + +module.exports = Fuzzer; From 33255b1d145205de2c02f10096cd4245619c1d53 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Tue, 28 Feb 2017 13:31:32 -0800 Subject: [PATCH 02/29] bring syntax into repo linting pattern --- packages/error-reporting/src/configuration.js | 4 +- .../src/google-apis/auth-client.js | 1 + packages/error-reporting/src/logger.js | 18 + .../test/fixtures/configuration.js | 2 + .../test/fixtures/uncaughtExitBehaviour.js | 11 +- .../test/system-test/testAuthClient.js | 7 +- .../test-servers/express_scaffold_server.js | 58 ++- .../test/test-servers/hapi_scaffold_server.js | 40 +- .../test/test-servers/koa_scaffold_server.js | 16 +- .../test-servers/manual_scaffold_server.js | 6 +- .../test-servers/restify_scaffold_server.js | 1 + .../test/unit/testConfigCredentials.js | 2 +- .../test/unit/testConfiguration.js | 10 +- .../test/unit/testCustomStackTrace.js | 38 +- .../test/unit/testErrorMessage.js | 368 +++++++++--------- .../test/unit/testExpressInterface.js | 14 +- .../testExpressRequestInformationExtractor.js | 132 +++---- .../test/unit/testExtractFromErrorClass.js | 24 +- .../test/unit/testExtractFromObject.js | 2 + .../test/unit/testHandleErrorClassError.js | 4 +- .../test/unit/testHandleNumberAsError.js | 2 + .../test/unit/testHandleObjectAsError.js | 2 + .../test/unit/testHandleStringAsError.js | 2 + .../test/unit/testHandleUnknownAsError.js | 2 + .../test/unit/testHapiInterface.js | 7 +- .../testHapiRequestInformationExtractor.js | 110 +++--- .../testKoaRequestInformationExtractor.js | 2 + .../test/unit/testManualHandler.js | 5 +- .../testManualRequestInformationExtractor.js | 62 +-- .../unit/testRequestInformationContainer.js | 18 +- .../test/unit/testRestifyInterface.js | 18 +- .../test/unit/testServiceConfiguration.js | 3 +- .../error-reporting/test/unit/testUncaught.js | 11 +- packages/error-reporting/utils/fuzzer.js | 2 + 34 files changed, 522 insertions(+), 482 deletions(-) diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index 36ce94d3f68..f71c35bf1de 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -266,8 +266,8 @@ Configuration.prototype._checkLocalServiceContext = function() { Configuration.prototype._gatherLocalConfiguration = function() { if (this._givenConfiguration.ignoreEnvironmentCheck === true) { this._shouldReportErrorsToAPI = true; - } else if (has(this._givenConfiguration, 'ignoreEnvironmentCheck') - && !isBoolean(this._givenConfiguration.ignoreEnvironmentCheck)) { + } else if (has(this._givenConfiguration, 'ignoreEnvironmentCheck') && + !isBoolean(this._givenConfiguration.ignoreEnvironmentCheck)) { throw new Error('config.ignoreEnvironmentCheck must be a boolean'); } else { this._shouldReportErrorsToAPI = env.NODE_ENV === 'production'; diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index c29b72364b8..4ccb2f71514 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/*jshint unused:false*/ 'use strict'; var commonDiag = require('@google/cloud-diagnostics-common'); diff --git a/packages/error-reporting/src/logger.js b/packages/error-reporting/src/logger.js index 22951e31b0b..aa5cd0d6747 100644 --- a/packages/error-reporting/src/logger.js +++ b/packages/error-reporting/src/logger.js @@ -1,3 +1,21 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 + * + * http://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. + */ +/*jshint bitwise: false*/ + +'use strict'; var has = require('lodash.has'); var is = require('is'); var isObject = is.object; diff --git a/packages/error-reporting/test/fixtures/configuration.js b/packages/error-reporting/test/fixtures/configuration.js index cecfdd7da17..2f89b554536 100644 --- a/packages/error-reporting/test/fixtures/configuration.js +++ b/packages/error-reporting/test/fixtures/configuration.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var Configuration = require('../../src/configuration.js'); var FakeConfiguration = function(config) { diff --git a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js index 2995e147b34..d3a7e8f1c1e 100644 --- a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js +++ b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js @@ -14,8 +14,8 @@ * limitations under the License. */ +'use strict'; var uncaughtSetup = require('../../src/interfaces/uncaught.js'); -var assert = require('assert'); var nock = require('nock'); var createLogger = require('../../src/logger.js'); var isString = require('is').string; @@ -41,7 +41,6 @@ function restoreEnv () { } describe('Uncaught Exception exit behaviour', function () { - var metadataUrl before(function () { process.removeAllListeners(UNCAUGHT); if (!isString(process.env.GCLOUD_PROJECT)) { @@ -63,17 +62,17 @@ describe('Uncaught Exception exit behaviour', function () { }); it('Should attempt to report the uncaught exception', function (done) { var id = 'xyz'; - var metadataId = nock( + nock( 'http://metadata.google.internal/computeMetadata/v1/project' ).get('/project-id').times(1).reply(200, id); - var metadataToken = nock('https://accounts.google.com:443/o/oauth2') - .post('/token').query(function () {return true}).reply(200, { + nock('https://accounts.google.com:443/o/oauth2') + .post('/token').query(function () {return true;}).reply(200, { refresh_token: 'hello', access_token: 'goodbye', expiry_date: new Date(9999, 1, 1) }); this.timeout(2000); - var s = nock( + nock( 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+id ).post('/events:report').once().reply(200, function () { done(); diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index ee4dc828373..324fdba47cd 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -27,7 +27,6 @@ var isString = is.string; var isEmpty = is.empty; var forEach = require('lodash.foreach'); var assign = require('lodash.assign'); -var client; describe('Behvaiour acceptance testing', function () { @@ -55,7 +54,7 @@ describe('Behvaiour acceptance testing', function () { nock.cleanAll(); }); describe('Request/Response lifecycle mocking', function () { - var sampleError = new Error("_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__"); + var sampleError = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); var errorMessage = new ErrorMessage().setMessage(sampleError); var fakeService, client, logger; beforeEach(function () { @@ -125,7 +124,7 @@ describe('Behvaiour acceptance testing', function () { }); }); describe('System-live integration testing', function () { - var sampleError = new Error("_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__"); + var sampleError = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); var errorMessage = new ErrorMessage().setMessage(sampleError.stack); var oldEnv = { GCLOUD_PROJECT: process.env.GCLOUD_PROJECT, @@ -295,7 +294,7 @@ describe('Behvaiour acceptance testing', function () { }); }); describe('Success behaviour', function () { - var er = new Error("_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__"); + var er = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); var em = new ErrorMessage().setMessage(er.stack); describe('Given a valid project id', function () { var logger, client, cfg; diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js index ff8ff7c52a4..13c24014dc6 100644 --- a/packages/error-reporting/test/test-servers/express_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -1,21 +1,23 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ -var WARNING_HEADER = "\n!! -WARNING-"; -var EXCLAMATION_LN = "\n!!"; +'use strict'; + +var WARNING_HEADER = '\n!! -WARNING-'; +var EXCLAMATION_LN = '\n!!'; var has = require('lodash.has'); var express = require('express'); var app = express(); @@ -28,46 +30,42 @@ var bodyParser = require('body-parser'); app.use(bodyParser.json()); -app.post( - '/testErrorHandling' - , function ( req, res, next ) { +app.post('/testErrorHandling', function ( req, res, next ) { if ( has(req.body, 'test') && req.body.test !== true ) { - return next(new Error("Error on Express Regular Error POST Route")); + return next(new Error('Error on Express Regular Error POST Route')); } else { - res.send("Success"); + res.send('Success'); res.end(); } } ); app.get( - '/customError' - , function ( req, res, next ) { + '/customError', function ( req, res, next ) { errorHandler.report( - "Error on Express Custom Error GET Route" - , function ( err, res ) { + 'Error on Express Custom Error GET Route', function ( err, res ) { if ( err ) { console.log(WARNING_HEADER); - console.log("Error in sending custom get error to api"); + console.log('Error in sending custom get error to api'); console.log(err); console.log(EXCLAMATION_LN); } else { console.log(EXCLAMATION_LN); - console.log("Successfully sent custom get error to api"); + console.log('Successfully sent custom get error to api'); console.log(EXCLAMATION_LN); } } ); - res.send("Success"); + res.send('Success'); res.end(); next(); @@ -75,38 +73,34 @@ app.get( ); app.get( - '/getError' - , function ( req, res, next ) { + '/getError', function ( req, res, next ) { - return next(new Error("Error on Express Regular Error GET Route")); + return next(new Error('Error on Express Regular Error GET Route')); } -) +); app.use(errorHandler.express); function throwUncaughtError ( ) { - console.log("Throwing an uncaught error.."); + console.log('Throwing an uncaught error..'); throw new Error('This is an uncaught error'); } function reportManualError ( ) { - console.log("Reporting a manual error.."); + console.log('Reporting a manual error..'); errorHandler.report( - new Error("This is a manually reported error") - , null - , null - , function ( err, res ) { + new Error('This is a manually reported error'), null, null, function ( err, res ) { if ( err ) { console.log(WARNING_HEADER); - console.log("Got an error in sending error information to the API"); + console.log('Got an error in sending error information to the API'); console.log(err); console.log(EXCLAMATION_LN); } else { console.log(EXCLAMATION_LN); - console.log("Successfully sent error information to the API"); + console.log('Successfully sent error information to the API'); console.log(EXCLAMATION_LN); } @@ -116,11 +110,11 @@ function reportManualError ( ) { } ); } -console.log("reporting a manual error first"); +console.log('reporting a manual error first'); errorHandler.report( new Error('This is a test'), (err, res) => { - console.log("reported first manual error"); + console.log('reported first manual error'); if (err) { console.log('Error was unable to be reported', err); } else { @@ -130,8 +124,8 @@ errorHandler.report( ); app.listen( - 3000 - , function ( ) { + 3000, + function ( ) { console.log('Scaffold Server has been started on port 3000'); reportManualError(); } diff --git a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js index 355226589b7..6019e4baed6 100644 --- a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js @@ -1,18 +1,20 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; + var hapi = require('hapi'); var errorHandler = require('../../index.js')(); @@ -21,49 +23,33 @@ server.connection({ port: 3000 }); server.start( ( err ) => { - if ( err ) { - throw err; } - console.log( - 'Server running at' - , server.info.uri - ); + 'Server running at', server.info.uri); } ); server.route({ - method: 'GET' - , path: '/get' - , handler: function ( request, reply ) { - - console.log("Got a GET"); - throw new Error("an error"); - reply('hello there!'); + method: 'GET', path: '/get', handler: function ( request, reply ) { + console.log('Got a GET'); + throw new Error('an error'); } }); server.route({ - method: 'POST' - , path: '/post' - , handler: function ( request, reply ) { - - console.log("Got a POST", request.payload); - throw new Error("An error on the hapi post route"); - reply('Got your post'); + method: 'POST', path: '/post', handler: function ( request, reply ) { + console.log('Got a POST', request.payload); + throw new Error('An error on the hapi post route'); } }); server.register( - { register: errorHandler.hapi } - , ( err ) => { - + { register: errorHandler.hapi }, ( err ) => { if ( err ) { - - console.error("There was an error in registering the plugin", err); + console.error('There was an error in registering the plugin', err); } } ); diff --git a/packages/error-reporting/test/test-servers/koa_scaffold_server.js b/packages/error-reporting/test/test-servers/koa_scaffold_server.js index 4844b7324fd..37388f8c41e 100644 --- a/packages/error-reporting/test/test-servers/koa_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/koa_scaffold_server.js @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +// jscs doesn't understand koa.. +// jscs:disable +'use strict'; + var errorHandler = require('../../index.js')({ onUncaughtException: 'report' }); @@ -24,28 +28,30 @@ app.use(errorHandler.koa); app.use(function *(next) { //This will set status and message this.throw('Error Message', 500); + yield next; }); app.use(function *(next){ - var start = new Date; + var start = new Date(); yield next; - var ms = new Date - start; + var ms = new Date() - start; this.set('X-Response-Time', ms + 'ms'); }); // logger app.use(function *(next){ - var start = new Date; + var start = new Date(); yield next; - var ms = new Date - start; + var ms = new Date() - start; console.log('%s %s - %s', this.method, this.url, ms); }); // response -app.use(function *(){ +app.use(function *(next){ this.body = 'Hello World'; + yield next; }); app.listen(3000); diff --git a/packages/error-reporting/test/test-servers/manual_scaffold_server.js b/packages/error-reporting/test/test-servers/manual_scaffold_server.js index 08445139952..9c6f20b961e 100644 --- a/packages/error-reporting/test/test-servers/manual_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/manual_scaffold_server.js @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var errors = require('../../index.js')(); -var r = errors.report('Sample test string', (err, response, body) => { +'use strict'; + +const errors = require('../../index.js')(); +errors.report('Sample test string', (err, response, body) => { console.log( 'Callback from report:\n', '\tError: ', err, '\n', diff --git a/packages/error-reporting/test/test-servers/restify_scaffold_server.js b/packages/error-reporting/test/test-servers/restify_scaffold_server.js index 8bc1dd138c2..19c40c5aa92 100644 --- a/packages/error-reporting/test/test-servers/restify_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/restify_scaffold_server.js @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use strict'; function respond(req, res, next) { next(new Error('this is a restify error')); diff --git a/packages/error-reporting/test/unit/testConfigCredentials.js b/packages/error-reporting/test/unit/testConfigCredentials.js index fd6cd7e42fd..3d4d1814da4 100644 --- a/packages/error-reporting/test/unit/testConfigCredentials.js +++ b/packages/error-reporting/test/unit/testConfigCredentials.js @@ -59,7 +59,7 @@ describe('Testing use of runtime configurations', function () { reportUncaughtExceptions: false, projectId: '0' }; - var scope = nock('https://accounts.google.com/o/oauth2') + nock('https://accounts.google.com/o/oauth2') .post('/token', function(body) { assert.strictEqual(body.client_id, credentials.client_id); assert.strictEqual(body.client_secret, credentials.client_secret); diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index af90d20ab7e..6b62628467b 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -29,14 +29,6 @@ var nock = require('nock'); var METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/project'; -var originalHandlers = process.listeners('uncaughtException'); - -function reattachOriginalListeners() { - for (var i = 0; i < originalHandlers.length; i++) { - process.on('uncaughtException', originalHandlers[i]); - } -} - process.removeAllListeners('uncaughtException'); var env = { NODE_ENV: process.env.NODE_ENV, @@ -270,7 +262,7 @@ describe('Configuration class', function () { restoreEnv(); }); describe('via env', function () { - before(function() {sterilizeEnv();}) + before(function() {sterilizeEnv();}); afterEach(function () {sterilizeEnv();}); describe('projectId', function () { var c; diff --git a/packages/error-reporting/test/unit/testCustomStackTrace.js b/packages/error-reporting/test/unit/testCustomStackTrace.js index 2a2b2edb470..f7cc818c33d 100644 --- a/packages/error-reporting/test/unit/testCustomStackTrace.js +++ b/packages/error-reporting/test/unit/testCustomStackTrace.js @@ -1,54 +1,59 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; var assert = require('assert'); var CustomStackTrace = require('../../src/classes/custom-stack-trace.js'); describe('Fuzzing the CustomStackTrace class', function () { var testFunction = function testFunction () { - return ""; + return ''; }; var cs; beforeEach(function () { cs = new CustomStackTrace(); }); it('Should accept value for file path', function () { - cs.setFilePath("test"); + cs.setFilePath('test'); assert( - cs.filePath === "test", - "Setting a valid string on the CustomStackTrace.filePath instance should result in assignment" + cs.filePath === 'test', + 'Setting a valid string on the CustomStackTrace.filePath instance ' + + 'should result in assignment' ); }); it('Should reject invalid type for file path', function () { cs.setFilePath(null); assert( - cs.filePath === "", - "Setting an invalid type on the CustomStackTrace.filePath instance should result in default value of an empty string" + cs.filePath === '', + 'Setting an invalid type on the CustomStackTrace.filePath instance ' + + 'should result in default value of an empty string' ); }); it('Should accept value for line number', function () { cs.setLineNumber(10); assert( cs.lineNumber === 10, - "Setting a valid number on the CustomStackTrace.lineNumber instance should result in assignment" + 'Setting a valid number on the CustomStackTrace.lineNumber instance ' + + 'should result in assignment' ); }); it('Should reject invalid type for line number', function () { - cs.setLineNumber("10"); + cs.setLineNumber('10'); assert( cs.lineNumber === 0, - "Setting an invalid type on the CustomStackTrace.lineNumber instance should result in default value of number 0" + 'Setting an invalid type on the CustomStackTrace.lineNumber instance ' + + 'should result in default value of number 0' ); }); it('Should accept value for call list', function () { @@ -56,14 +61,17 @@ describe('Fuzzing the CustomStackTrace class', function () { assert.strictEqual( cs.stringifyStucturedCallList, testFunction, - "Setting a valid function on the CustomStackTrace. setStringifyStructuredCallList should result in assignment" + 'Setting a valid function on the CustomStackTrace. ' + + 'setStringifyStructuredCallList should result in assignment' ); }); it('Should reject incalid value for call list', function () { cs.setStringifyStructuredCallList(null); assert( - ((typeof cs.setStringifyStructuredCallList) === "function"), - "Setting an invalid setStringifyStructuredCallList on the CustomStackTrace. setStringifyStructuredCallList should result in a default value of a function" + ((typeof cs.setStringifyStructuredCallList) === 'function'), + 'Setting an invalid setStringifyStructuredCallList on the ' + + 'CustomStackTrace. setStringifyStructuredCallList should result in a ' + + 'default value of a function' ); - }) + }); }); diff --git a/packages/error-reporting/test/unit/testErrorMessage.js b/packages/error-reporting/test/unit/testErrorMessage.js index 6047e1ec20c..2f9f1bc76cc 100644 --- a/packages/error-reporting/test/unit/testErrorMessage.js +++ b/packages/error-reporting/test/unit/testErrorMessage.js @@ -1,18 +1,20 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +// jscs:disable +// jshint ignore: start var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); @@ -24,7 +26,7 @@ describe('Instantiating a new ErrorMessage', function () { it('Should have a default service context', function () { assert.deepEqual( em.serviceContext, - { service: "node", version: undefined } + { service: 'node', version: undefined } ); }); it('Should have a default message', function () { @@ -34,12 +36,12 @@ describe('Instantiating a new ErrorMessage', function () { assert.deepEqual( em.context.httpRequest, { - method: "" - , url: "" - , userAgent: "" - , referrer: "" - , responseStatusCode: 0 - , remoteIp: "" + method: '', + url: '', + userAgent: '', + referrer: '', + responseStatusCode: 0, + remoteIp: '' } ); }); @@ -65,10 +67,10 @@ describe('Calling against setEventTimeToNow', function () { }); describe('Fuzzing against setServiceContext', function () { - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var DEFAULT_TEST_VALUE = "DEFAULT"; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var DEFAULT_TEST_VALUE = 'DEFAULT'; var DEFAULT_VERSION_VALUE = undefined; - var DEFAULT_SERVICE_VALUE = "node"; + var DEFAULT_SERVICE_VALUE = 'node'; var em; beforeEach(function () {em = new ErrorMessage()}); @@ -81,9 +83,9 @@ describe('Fuzzing against setServiceContext', function () { , version: AFFIRMATIVE_TEST_VALUE } , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should set the default values', function () { @@ -95,9 +97,9 @@ describe('Fuzzing against setServiceContext', function () { , version: DEFAULT_TEST_VALUE } , [ - "In resetting to default valid values the instance should reflect the" - , "value update" - ].join(" ") + 'In resetting to default valid values the instance should reflect the' + , 'value update' + ].join(' ') ); }); it('Should still set version with affirmative value', function () { @@ -109,10 +111,10 @@ describe('Fuzzing against setServiceContext', function () { , version: AFFIRMATIVE_TEST_VALUE } , [ - "Providing only a valid value to the second argument of" - , "setServiceContext should set the service property as an empty string" - , "but set the version property to the affirmative value." - ].join(" ") + 'Providing only a valid value to the second argument of' + , 'setServiceContext should set the service property as an empty string' + , 'but set the version property to the affirmative value.' + ].join(' ') ); }); it('Should still set service with affirmative value', function () { @@ -124,10 +126,10 @@ describe('Fuzzing against setServiceContext', function () { , version: DEFAULT_VERSION_VALUE } , [ - "Providing only a valid value to the first argument of" - , "setServiceContext should set the version property as an empty string" - , "but set the service property to the affirmative value." - ].join(" ") + 'Providing only a valid value to the first argument of' + , 'setServiceContext should set the version property as an empty string' + , 'but set the service property to the affirmative value.' + ].join(' ') ); }); it('Should set default values on both', function () { @@ -139,9 +141,9 @@ describe('Fuzzing against setServiceContext', function () { , version: DEFAULT_VERSION_VALUE } , [ - "Providing null as the value to both arguments should set both" - , "properties as empty strings." - ].join(" ") + 'Providing null as the value to both arguments should set both' + , 'properties as empty strings.' + ].join(' ') ); }); it('Should set default values on both', function () { @@ -153,13 +155,13 @@ describe('Fuzzing against setServiceContext', function () { , version: DEFAULT_VERSION_VALUE } , [ - "Providing numbers as the value to both arguments should set both" - , "properties as empty strings." - ].join(" ") + 'Providing numbers as the value to both arguments should set both' + , 'properties as empty strings.' + ].join(' ') ); }); it('Should set as default', function () { - em.setServiceContext({ test: "true" }, []); + em.setServiceContext({ test: 'true' }, []); assert.deepEqual( em.serviceContext , { @@ -167,9 +169,9 @@ describe('Fuzzing against setServiceContext', function () { , version: DEFAULT_VERSION_VALUE } , [ - "Providing arrays or objects as the value to both arguments" - , "should set both properties as empty strings." - ].join(" ") + 'Providing arrays or objects as the value to both arguments' + , 'should set both properties as empty strings.' + ].join(' ') ); }); it('Should set as default', function () { @@ -180,7 +182,7 @@ describe('Fuzzing against setServiceContext', function () { service: DEFAULT_SERVICE_VALUE , version: DEFAULT_VERSION_VALUE } - , "Providing no arguments should set both properties as empty strings" + , 'Providing no arguments should set both properties as empty strings' ); }) }); @@ -190,17 +192,17 @@ describe( function () { var em; beforeEach(function () {em = new ErrorMessage()}); - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; it('Should set the message', function () { em.setMessage(AFFIRMATIVE_TEST_VALUE); assert( em.message === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -208,9 +210,9 @@ describe( assert( em.message === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setMessage the property" - , "message should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setMessage the property' + , 'message should be set to an empty string on the instance' + ].join(' ') ); }); } @@ -220,17 +222,17 @@ describe( 'Fuzzing against setHttpMethod', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set the method', function () { em.setHttpMethod(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.method === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -238,9 +240,9 @@ describe( assert( em.context.httpRequest.method === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setHttpMethod the property" - , "message should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setHttpMethod the property' + , 'message should be set to an empty string on the instance' + ].join(' ') ); }); } @@ -250,17 +252,17 @@ describe( 'Fuzzing against setUrl', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set url', function () { em.setUrl(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.url === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -268,9 +270,9 @@ describe( assert( em.context.httpRequest.url === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setUrl the property" - , "message should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setUrl the property' + , 'message should be set to an empty string on the instance' + ].join(' ') ); }); } @@ -281,17 +283,17 @@ describe( 'Fuzzing against setUserAgent', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set userAgent', function () { em.setUserAgent(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.userAgent === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -299,9 +301,9 @@ describe( assert( em.context.httpRequest.userAgent === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setUserAgent the property" - , "message should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setUserAgent the property' + , 'message should be set to an empty string on the instance' + ].join(' ') ); }); } @@ -309,17 +311,17 @@ describe( describe('Fuzzing against setReferrer', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set referrer', function () { em.setReferrer(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.referrer === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -327,9 +329,9 @@ describe('Fuzzing against setReferrer', function () { assert( em.context.httpRequest.referrer === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setReferrer the property" - , "message should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setReferrer the property' + , 'message should be set to an empty string on the instance' + ].join(' ') ); }); }); @@ -344,9 +346,9 @@ describe('Fuzzing against setResponseStatusCode', function () { assert( em.context.httpRequest.responseStatusCode === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -354,26 +356,26 @@ describe('Fuzzing against setResponseStatusCode', function () { assert( em.context.httpRequest.responseStatusCode === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setResponseStatusCode the property" - , "message should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setResponseStatusCode the property' + , 'message should be set to an empty string on the instance' + ].join(' ') ); }); }); describe('Fuzzing against setRemoteIp', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set remoteIp', function () { em.setRemoteIp(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.remoteIp === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -381,9 +383,9 @@ describe('Fuzzing against setRemoteIp', function () { assert( em.context.httpRequest.remoteIp === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setRemoteIp the property" - , "message should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setRemoteIp the property' + , 'message should be set to an empty string on the instance' + ].join(' ') ); }); }); @@ -392,17 +394,17 @@ describe( 'Fuzzing against setUser', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set user', function () { em.setUser(AFFIRMATIVE_TEST_VALUE); assert( em.context.user === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -410,9 +412,9 @@ describe( assert( em.context.user === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setUser the property" - , "user should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setUser the property' + , 'user should be set to an empty string on the instance' + ].join(' ') ); }); } @@ -420,17 +422,17 @@ describe( describe('Fuzzing against setFilePath', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set filePath', function () { em.setFilePath(AFFIRMATIVE_TEST_VALUE); assert( em.context.reportLocation.filePath === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -438,9 +440,9 @@ describe('Fuzzing against setFilePath', function () { assert( em.context.reportLocation.filePath === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setFilePath the property" - , "filePath should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setFilePath the property' + , 'filePath should be set to an empty string on the instance' + ].join(' ') ); }); }); @@ -455,9 +457,9 @@ describe('Fuzzing against setLineNumber', function () { assert( em.context.reportLocation.lineNumber === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -465,26 +467,26 @@ describe('Fuzzing against setLineNumber', function () { assert( em.context.reportLocation.lineNumber === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setLineNumber the property" - , "lineNumber should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setLineNumber the property' + , 'lineNumber should be set to an empty string on the instance' + ].join(' ') ); }); }); describe('Fuzzing against setFunctionName', function () { var em; - var AFFIRMATIVE_TEST_VALUE = "VALID_INPUT_AND_TYPE"; - var NEGATIVE_TEST_VALUE = ""; + var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; + var NEGATIVE_TEST_VALUE = ''; beforeEach(function () {em = new ErrorMessage()}); it('Should set functionName', function () { em.setFunctionName(AFFIRMATIVE_TEST_VALUE); assert( em.context.reportLocation.functionName === AFFIRMATIVE_TEST_VALUE , [ - "In the affirmative case the value should be settable to a valid string" - , "and by setting this value this should mutate the instance" - ].join(" ") + 'In the affirmative case the value should be settable to a valid string' + , 'and by setting this value this should mutate the instance' + ].join(' ') ); }); it('Should default', function () { @@ -492,18 +494,18 @@ describe('Fuzzing against setFunctionName', function () { assert( em.context.reportLocation.functionName === NEGATIVE_TEST_VALUE , [ - "By providing no argument (undefined) to setFunctionName the property" - , "functionName should be set to an empty string on the instance" - ].join(" ") + 'By providing no argument (undefined) to setFunctionName the property' + , 'functionName should be set to an empty string on the instance' + ].join(' ') ); }); }); describe('Fuzzing against consumeRequestInformation', function () { var em = new ErrorMessage(); - var A_VALID_STRING = "A_VALID_STRING"; + var A_VALID_STRING = 'A_VALID_STRING'; var A_VALID_NUMBER = 201; - var NEGATIVE_STRING_CASE = ""; + var NEGATIVE_STRING_CASE = ''; var NEGATIVE_NUMBER_CASE = 0; var AFFIRMATIVE_TEST_VALUE = { @@ -527,44 +529,44 @@ describe('Fuzzing against consumeRequestInformation', function () { assert( em.context.httpRequest.method === A_VALID_STRING , [ - "The error messages method, given a valid string, should be" - , "set to that value" - ].join(" ") + 'The error messages method, given a valid string, should be' + , 'set to that value' + ].join(' ') ); assert( em.context.httpRequest.url === A_VALID_STRING , [ - "The error messages url, given a valid string, should be" - , "set to that value" - ].join(" ") + 'The error messages url, given a valid string, should be' + , 'set to that value' + ].join(' ') ); assert( em.context.httpRequest.userAgent === A_VALID_STRING , [ - "The error messages userAgent, given a valid string, should be" - , "set to that value" - ].join(" ") + 'The error messages userAgent, given a valid string, should be' + , 'set to that value' + ].join(' ') ); assert( em.context.httpRequest.referrer === A_VALID_STRING , [ - "The error messages referrer, given a valid string, should be" - , "set to that value" - ].join(" ") + 'The error messages referrer, given a valid string, should be' + , 'set to that value' + ].join(' ') ); assert( em.context.httpRequest.responseStatusCode === A_VALID_NUMBER , [ - "The error messages responseStatusCode, given a valid number, should be" - , "set to that value" - ].join(" ") + 'The error messages responseStatusCode, given a valid number, should be' + , 'set to that value' + ].join(' ') ); assert( em.context.httpRequest.remoteIp === A_VALID_STRING , [ - "The error messages remoteAddress, given a valid string, should be" - , "set to that value" - ].join(" ") + 'The error messages remoteAddress, given a valid string, should be' + , 'set to that value' + ].join(' ') ); }); it('Should default when consuming a malformed request object', function () { @@ -572,44 +574,44 @@ describe('Fuzzing against consumeRequestInformation', function () { assert( em.context.httpRequest.method === A_VALID_STRING , [ - "The error messages method, given an invalid type a the top-level" - , "should remain untouched" - ].join(" ") + 'The error messages method, given an invalid type a the top-level' + , 'should remain untouched' + ].join(' ') ); assert( em.context.httpRequest.url === A_VALID_STRING , [ - "The error messages url, given an invalid type a the top-level" - , "should remain untouched" - ].join(" ") + 'The error messages url, given an invalid type a the top-level' + , 'should remain untouched' + ].join(' ') ); assert( em.context.httpRequest.userAgent === A_VALID_STRING , [ - "The error messages userAgent, given an invalid type a the top-level" - , "should remain untouched" - ].join(" ") + 'The error messages userAgent, given an invalid type a the top-level' + , 'should remain untouched' + ].join(' ') ); assert( em.context.httpRequest.referrer === A_VALID_STRING , [ - "The error messages referrer, given an invalid type a the top-level" - , "should remain untouched" - ].join(" ") + 'The error messages referrer, given an invalid type a the top-level' + , 'should remain untouched' + ].join(' ') ); assert( em.context.httpRequest.responseStatusCode === A_VALID_NUMBER , [ - "The error messages responseStatusCode, given an invalid type a the top-level" - , "should remain untouched" - ].join(" ") + 'The error messages responseStatusCode, given an invalid type a the top-level' + , 'should remain untouched' + ].join(' ') ); assert( em.context.httpRequest.remoteIp === A_VALID_STRING , [ - "The error messages remoteAddress, given an invalid type a the top-level" - , "should remain untouched" - ].join(" ") + 'The error messages remoteAddress, given an invalid type a the top-level' + , 'should remain untouched' + ].join(' ') ); }); it('Should default when consuming mistyped response object properties', @@ -618,44 +620,44 @@ describe('Fuzzing against consumeRequestInformation', function () { assert( em.context.httpRequest.method === NEGATIVE_STRING_CASE , [ - "The error messages method, given an invalid input should default to" - , "the negative value" - ].join(" ") + 'The error messages method, given an invalid input should default to' + , 'the negative value' + ].join(' ') ); assert( em.context.httpRequest.url === NEGATIVE_STRING_CASE , [ - "The error messages url, given an invalid input should default to" - , "the negative value" - ].join(" ") + 'The error messages url, given an invalid input should default to' + , 'the negative value' + ].join(' ') ); assert( em.context.httpRequest.userAgent === NEGATIVE_STRING_CASE , [ - "The error messages userAgent, ggiven an invalid input should default to" - , "the negative value" - ].join(" ") + 'The error messages userAgent, ggiven an invalid input should default to' + , 'the negative value' + ].join(' ') ); assert( em.context.httpRequest.referrer === NEGATIVE_STRING_CASE , [ - "The error messages referrer, given an invalid input should default to" - , "the negative value" - ].join(" ") + 'The error messages referrer, given an invalid input should default to' + , 'the negative value' + ].join(' ') ); assert( em.context.httpRequest.responseStatusCode === NEGATIVE_NUMBER_CASE , [ - "The error messages responseStatusCode, given an invalid input should default to" - , "the negative value" - ].join(" ") + 'The error messages responseStatusCode, given an invalid input should default to' + , 'the negative value' + ].join(' ') ); assert( em.context.httpRequest.remoteIp === NEGATIVE_STRING_CASE , [ - "The error messages remoteAddress, given an invalid input should default to" - , "the negative value" - ].join(" ") + 'The error messages remoteAddress, given an invalid input should default to' + , 'the negative value' + ].join(' ') ); } ); @@ -664,16 +666,16 @@ describe('Fuzzing against consumeRequestInformation', function () { assert( em.consumeRequestInformation(AFFIRMATIVE_TEST_VALUE) instanceof ErrorMessage , [ - "Calling consumeRequestInformation with valid input should return" - , "the ErrorMessage instance" - ].join(" ") + 'Calling consumeRequestInformation with valid input should return' + , 'the ErrorMessage instance' + ].join(' ') ); assert( em.consumeRequestInformation() instanceof ErrorMessage , [ - "Calling consumeRequestInformation with invalid input should return" - , "the ErrorMessage instance" - ].join(" ") + 'Calling consumeRequestInformation with invalid input should return' + , 'the ErrorMessage instance' + ].join(' ') ); } ); diff --git a/packages/error-reporting/test/unit/testExpressInterface.js b/packages/error-reporting/test/unit/testExpressInterface.js index adaa47ee2bd..3e4f2955d32 100644 --- a/packages/error-reporting/test/unit/testExpressInterface.js +++ b/packages/error-reporting/test/unit/testExpressInterface.js @@ -1,19 +1,21 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; + var assert = require('assert'); var merge = require('lodash.merge'); var expressInterface = require('../../src/interfaces/express.js'); @@ -30,8 +32,7 @@ describe('expressInterface', function () { assert.doesNotThrow( function () { f.fuzzFunctionForTypes( - expressInterface - , ["object", "object"] + expressInterface, ['object', 'object'] ); return; } @@ -42,8 +43,7 @@ describe('expressInterface', function () { describe('Intended behaviour', function () { var stubbedConfig = new Configuration({ serviceContext: { - service: "a_test_service" - , version: "a_version" + service: 'a_test_service', version: 'a_version' } }, createLogger({logLevel: 4})); stubbedConfig.lacksCredentials = function () { @@ -54,7 +54,7 @@ describe('expressInterface', function () { return; } }; - var testError = new Error("This is a test"); + var testError = new Error('This is a test'); var validBoundHandler = expressInterface(client, stubbedConfig); it('Should return the error message', function () { var res = validBoundHandler(testError, null, null, null); diff --git a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js index 52c51d961fb..e49c70582e3 100644 --- a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js @@ -1,19 +1,21 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; + var assert = require('assert'); var expressRequestInformationExtractor = require('../../src/request-extractors/express.js'); @@ -24,81 +26,81 @@ describe('Behaviour under varying input', function () { var f; var DEFAULT_RETURN_VALUE = { - method: "" - , url: "" - , userAgent: "" - , referrer: "" - , statusCode: 0 - , remoteAddress: "" + method: '', + url: '', + userAgent: '', + referrer: '', + statusCode: 0, + remoteAddress: '' }; beforeEach(function () {f = new Fuzzer();}); it('Should return a default value given invalid input', function () { var cbFn = function (value) { assert.deepEqual(value, DEFAULT_RETURN_VALUE); - } + }; f.fuzzFunctionForTypes(expressRequestInformationExtractor, ['object', 'object'], cbFn); }); it('Should return valid request object given valid input', function () { var FULL_REQ_DERIVATION_VALUE = { - method: "STUB_METHOD" - , url: "www.TEST-URL.com" - , 'user-agent': "Something like Mozilla" - , referrer: "www.ANOTHER-TEST.com" - , 'x-forwarded-for': '0.0.0.1' - , connection: { - remoteAddress: "0.0.0.0" + method: 'STUB_METHOD', + url: 'www.TEST-URL.com', + 'user-agent': 'Something like Mozilla', + referrer: 'www.ANOTHER-TEST.com', + 'x-forwarded-for': '0.0.0.1', + connection: { + remoteAddress: '0.0.0.0' } }; var FULL_RES_DERIVATION_VALUE = { 'statusCode': 200 }; var FULL_REQ_EXPECTED_VALUE = { - method: "STUB_METHOD" - , url: "www.TEST-URL.com" - , userAgent: "Something like Mozilla" - , referrer: "www.ANOTHER-TEST.com" - , remoteAddress: '0.0.0.1' - , statusCode: 200 - } + method: 'STUB_METHOD', + url: 'www.TEST-URL.com', + userAgent: 'Something like Mozilla', + referrer: 'www.ANOTHER-TEST.com', + remoteAddress: '0.0.0.1', + statusCode: 200 + }; var PARTIAL_REQ_DERIVATION_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , 'user-agent': "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" - , connection: { - remoteAddress: "0.0.2.1" + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + 'user-agent': 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com', + connection: { + remoteAddress: '0.0.2.1' } }; var PARTIAL_RES_DERIVATION_VALUE = { statusCode: 201 }; var PARTIAL_REQ_EXPECTED_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , userAgent: "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" - , remoteAddress: "0.0.2.1" - , statusCode: 201 + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + userAgent: 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com', + remoteAddress: '0.0.2.1', + statusCode: 201 }; var ANOTHER_PARTIAL_REQ_DERIVATION_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , 'user-agent': "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + 'user-agent': 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com' }; var ANOTHER_PARTIAL_RES_DERIVATION_VALUE = { statusCode: 201 }; var ANOTHER_PARTIAL_REQ_EXPECTED_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , userAgent: "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" - , remoteAddress: "" - , statusCode: 201 + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + userAgent: 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com', + remoteAddress: '', + statusCode: 201 }; var headerFactory = function (toDeriveFrom) { var lrn = extend({}, toDeriveFrom); @@ -107,48 +109,48 @@ describe('Behaviour under varying input', return lrn[toRet]; } return undefined; - } + }; return lrn; }; var tmpOutput = expressRequestInformationExtractor( - headerFactory(FULL_REQ_DERIVATION_VALUE) - , FULL_RES_DERIVATION_VALUE + headerFactory(FULL_REQ_DERIVATION_VALUE), + FULL_RES_DERIVATION_VALUE ); assert.deepEqual(tmpOutput, FULL_REQ_EXPECTED_VALUE, [ 'Given a valid object input for the request parameter and an', - , '\'x-forwarded-for\' parameter the request extractor should return', - , 'the expected full req output and the \'x-forwarded-for\' value', - , 'as the value for the \'remoteAddress\' property.' + '\'x-forwarded-for\' parameter the request extractor should return', + 'the expected full req output and the \'x-forwarded-for\' value', + 'as the value for the \'remoteAddress\' property.' ].join(' ') ); tmpOutput = expressRequestInformationExtractor( - headerFactory(PARTIAL_REQ_DERIVATION_VALUE) - , PARTIAL_RES_DERIVATION_VALUE + headerFactory(PARTIAL_REQ_DERIVATION_VALUE), + PARTIAL_RES_DERIVATION_VALUE ); assert.deepEqual( tmpOutput, PARTIAL_REQ_EXPECTED_VALUE, [ - "Given a valid object input for the request parameter but sans an", - "\'x-forwarded-for\' parameter the request extractor should return", - "the expected parital req output and the remoteAddress value", - "as the value for the \'remoteAddress\' property." - ].join(" ") + 'Given a valid object input for the request parameter but sans an', + '\'x-forwarded-for\' parameter the request extractor should return', + 'the expected parital req output and the remoteAddress value', + 'as the value for the \'remoteAddress\' property.' + ].join(' ') ); tmpOutput = expressRequestInformationExtractor( - headerFactory(ANOTHER_PARTIAL_REQ_DERIVATION_VALUE) - , ANOTHER_PARTIAL_RES_DERIVATION_VALUE + headerFactory(ANOTHER_PARTIAL_REQ_DERIVATION_VALUE), + ANOTHER_PARTIAL_RES_DERIVATION_VALUE ); assert.deepEqual( tmpOutput, ANOTHER_PARTIAL_REQ_EXPECTED_VALUE, [ - "Given a valid object input for the request parameter but sans an", - "\'x-forwarded-for\' parameter or a remoteAddress parameter", - "the request extractor should return an empty string", - "as the value for the \'remoteAddress\' property." - ].join(" ") + 'Given a valid object input for the request parameter but sans an', + '\'x-forwarded-for\' parameter or a remoteAddress parameter', + 'the request extractor should return an empty string', + 'as the value for the \'remoteAddress\' property.' + ].join(' ') ); } ); diff --git a/packages/error-reporting/test/unit/testExtractFromErrorClass.js b/packages/error-reporting/test/unit/testExtractFromErrorClass.js index 2ffb82f9c03..a2454ac7bdb 100644 --- a/packages/error-reporting/test/unit/testExtractFromErrorClass.js +++ b/packages/error-reporting/test/unit/testExtractFromErrorClass.js @@ -1,19 +1,21 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; + var assert = require('assert'); var extractFromErrorClass = require('../../src/error-extractors/error.js'); var ErrorMessage = require('../../src/classes/error-message.js'); @@ -22,7 +24,7 @@ var ErrorMessage = require('../../src/classes/error-message.js'); describe('Writing and reading ErrorMessage properties', function () { describe('Message field', function () { it('Should set the message as the stack of the given error', function () { - var TEST_MESSAGE = "This is a test"; + var TEST_MESSAGE = 'This is a test'; var em = new ErrorMessage(); var err = new Error(TEST_MESSAGE); extractFromErrorClass(err, em); @@ -39,7 +41,7 @@ describe('Writing and reading ErrorMessage properties', function () { err = new Error(); }); it('Should set the user field if given valid input', function () { - var TEST_USER_VALID = "TEST_USER"; + var TEST_USER_VALID = 'TEST_USER'; err.user = TEST_USER_VALID; extractFromErrorClass(err, em); assert.strictEqual(em.context.user, TEST_USER_VALID); @@ -77,19 +79,19 @@ describe('Writing and reading ErrorMessage properties', function () { describe('Report location field', function () { var em, err; var TEST_STACK_DEFAULT = { - filePath: "" - , lineNumber: 0 - , functionName: "" + filePath: '', + lineNumber: 0, + functionName: '' }; beforeEach(function () { em = new ErrorMessage(); err = new Error(); - }) + }); it('Should default the field if given invalid input', function () { var TEST_STACK_INVALID_CONTENTS = { - filePath: null - , lineNumber: "2" - , functionName: {} + filePath: null, + lineNumber: '2', + functionName: {} }; err.stack = TEST_STACK_INVALID_CONTENTS; extractFromErrorClass(err, em); diff --git a/packages/error-reporting/test/unit/testExtractFromObject.js b/packages/error-reporting/test/unit/testExtractFromObject.js index e0c7a06f650..c2cb546c4d6 100644 --- a/packages/error-reporting/test/unit/testExtractFromObject.js +++ b/packages/error-reporting/test/unit/testExtractFromObject.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var extractFromObject = require('../../src/error-extractors/object.js'); var ErrorMessage = require('../../src/classes/error-message.js'); diff --git a/packages/error-reporting/test/unit/testHandleErrorClassError.js b/packages/error-reporting/test/unit/testHandleErrorClassError.js index 51903536acc..2e304af3975 100644 --- a/packages/error-reporting/test/unit/testHandleErrorClassError.js +++ b/packages/error-reporting/test/unit/testHandleErrorClassError.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleErrorClassError = require('../../src/error-handlers/error.js'); @@ -26,7 +28,7 @@ describe('Behaviour under various type inputs', function () { var adversarialObjectInputTwo = { stack: [] }; - beforeEach(function () {em = new ErrorMessage()}); + beforeEach(function () {em = new ErrorMessage();}); it('Should not throw given undefined', function () { assert.doesNotThrow(handleErrorClassError.bind(null, undefined, em)); }); diff --git a/packages/error-reporting/test/unit/testHandleNumberAsError.js b/packages/error-reporting/test/unit/testHandleNumberAsError.js index 48134ac640c..a3bfbe52368 100644 --- a/packages/error-reporting/test/unit/testHandleNumberAsError.js +++ b/packages/error-reporting/test/unit/testHandleNumberAsError.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleNumberAsError = require('../../src/error-handlers/number.js'); diff --git a/packages/error-reporting/test/unit/testHandleObjectAsError.js b/packages/error-reporting/test/unit/testHandleObjectAsError.js index bcc9b594d41..7dd3983734e 100644 --- a/packages/error-reporting/test/unit/testHandleObjectAsError.js +++ b/packages/error-reporting/test/unit/testHandleObjectAsError.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleObjectAsError = require('../../src/error-handlers/object.js'); diff --git a/packages/error-reporting/test/unit/testHandleStringAsError.js b/packages/error-reporting/test/unit/testHandleStringAsError.js index 09b7cb99929..e690ac3e8df 100644 --- a/packages/error-reporting/test/unit/testHandleStringAsError.js +++ b/packages/error-reporting/test/unit/testHandleStringAsError.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleStringAsError = require('../../src/error-handlers/string.js'); diff --git a/packages/error-reporting/test/unit/testHandleUnknownAsError.js b/packages/error-reporting/test/unit/testHandleUnknownAsError.js index 2d6f745e3cd..d3e86da353a 100644 --- a/packages/error-reporting/test/unit/testHandleUnknownAsError.js +++ b/packages/error-reporting/test/unit/testHandleUnknownAsError.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleUnknownAsError = require('../../src/error-handlers/unknown.js'); diff --git a/packages/error-reporting/test/unit/testHapiInterface.js b/packages/error-reporting/test/unit/testHapiInterface.js index 512e8c099af..5afb34f5f2b 100644 --- a/packages/error-reporting/test/unit/testHapiInterface.js +++ b/packages/error-reporting/test/unit/testHapiInterface.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var has = require('lodash.has'); var is = require('is'); var isFunction = is.fn; @@ -24,7 +26,6 @@ var ErrorMessage = require('../../src/classes/error-message.js'); var Fuzzer = require('../../utils/fuzzer.js'); var EventEmitter = require('events').EventEmitter; var Configuration = require('../fixtures/configuration.js'); -var createLogger = require('../../src/logger.js'); describe('Hapi interface', function () { describe('Fuzzing the setup handler', function () { @@ -39,7 +40,7 @@ describe('Hapi interface', function () { describe('Providing valid input to the setup handler', function () { var givenConfig = {getVersion: function () {return '1';}}; var plugin; - beforeEach(function () {plugin = hapiInterface(null, givenConfig)}); + beforeEach(function () {plugin = hapiInterface(null, givenConfig);}); it('should have plain object as plugin', function () { assert(isObject(plugin)); }); @@ -83,7 +84,7 @@ describe('Hapi interface', function () { return '1'; }, getServiceContext: function () { - return {service: 'node'} + return {service: 'node'}; } }); plugin.register(fakeServer, null, null, null); diff --git a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js index bd79db92b70..aec4b569217 100644 --- a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js @@ -1,19 +1,21 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; + var assert = require('assert'); var hapiRequestInformationExtractor = require('../../src/request-extractors/hapi.js'); var Fuzzer = require('../../utils/fuzzer.js'); @@ -22,87 +24,87 @@ describe('hapiRequestInformationExtractor behaviour', function () { describe('behaviour given invalid input', function () { it('Should produce the default value', function () { var DEFAULT_RETURN_VALUE = { - method: "", - url: "", - userAgent: "", - referrer: "", + method: '', + url: '', + userAgent: '', + referrer: '', statusCode: 0, - remoteAddress: "" + remoteAddress: '' }; var f = new Fuzzer(); var cbFn = function (value) { assert.deepEqual(value, DEFAULT_RETURN_VALUE); }; f.fuzzFunctionForTypes( - hapiRequestInformationExtractor - , ["object"] - , cbFn + hapiRequestInformationExtractor, + ['object'], + cbFn ); }); }); describe('behaviour given valid input', function () { var FULL_REQ_DERIVATION_VALUE = { - method: "STUB_METHOD" - , url: "www.TEST-URL.com" - , info: { - remoteAddress: "0.0.0.0" - } - , headers: { - 'x-forwarded-for': '0.0.0.1' - , 'user-agent': "Something like Mozilla" - , referrer: "www.ANOTHER-TEST.com" - } - , response: { + method: 'STUB_METHOD', + url: 'www.TEST-URL.com', + info: { + remoteAddress: '0.0.0.0' + }, + headers: { + 'x-forwarded-for': '0.0.0.1', + 'user-agent': 'Something like Mozilla', + referrer: 'www.ANOTHER-TEST.com' + }, + response: { statusCode: 200 } }; var FULL_REQ_EXPECTED_VALUE = { - method: "STUB_METHOD" - , url: "www.TEST-URL.com" - , userAgent: "Something like Mozilla" - , referrer: "www.ANOTHER-TEST.com" - , remoteAddress: '0.0.0.1' - , statusCode: 200 + method: 'STUB_METHOD', + url: 'www.TEST-URL.com', + userAgent: 'Something like Mozilla', + referrer: 'www.ANOTHER-TEST.com', + remoteAddress: '0.0.0.1', + statusCode: 200 }; var PARTIAL_REQ_DERIVATION_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , info: { - remoteAddress: "0.0.2.1" - } - , headers: { - 'user-agent': "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" - } - , response: { + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + info: { + remoteAddress: '0.0.2.1' + }, + headers: { + 'user-agent': 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com' + }, + response: { output: { statusCode: 201 } } }; var PARTIAL_REQ_EXPECTED_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , userAgent: "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" - , remoteAddress: "0.0.2.1" - , statusCode: 201 + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + userAgent: 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com', + remoteAddress: '0.0.2.1', + statusCode: 201 }; var ANOTHER_PARTIAL_REQ_DERIVATION_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , headers: { - 'user-agent': "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + headers: { + 'user-agent': 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com' } }; var ANOTHER_PARTIAL_REQ_EXPECTED_VALUE = { - method: "STUB_METHOD_#2" - , url: "www.SUPER-TEST.com" - , userAgent: "Something like Gecko" - , referrer: "www.SUPER-ANOTHER-TEST.com" - , remoteAddress: "" - , statusCode: 0 + method: 'STUB_METHOD_#2', + url: 'www.SUPER-TEST.com', + userAgent: 'Something like Gecko', + referrer: 'www.SUPER-ANOTHER-TEST.com', + remoteAddress: '', + statusCode: 0 }; it('Should produce the full request input', function () { assert.deepEqual( diff --git a/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js index 7255d57c36b..fa7c8347e68 100644 --- a/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var koaRequestInformationExtractor = require('../../src/request-extractors/koa.js'); var Fuzzer = require('../../utils/fuzzer.js'); diff --git a/packages/error-reporting/test/unit/testManualHandler.js b/packages/error-reporting/test/unit/testManualHandler.js index 8c3eb794c46..4ac4e6347bb 100644 --- a/packages/error-reporting/test/unit/testManualHandler.js +++ b/packages/error-reporting/test/unit/testManualHandler.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var manual = require('../../src/interfaces/manual.js'); var Configuration = require('../fixtures/configuration.js'); @@ -173,8 +175,7 @@ describe('Manual handler', function () { }); it('Should accept message and callback function as arguments', function (done) { var oldMsg = 'test'; - var newMsg = 'analysis'; - var r = report( + report( new ErrorMessage().setMessage(oldMsg), function () { done(); } ); diff --git a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js index efcf225c356..ca42d5e3730 100644 --- a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js @@ -1,19 +1,21 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; + var assert = require('assert'); var omit = require('lodash.omit'); var extend = require('extend'); @@ -35,7 +37,7 @@ describe('manualRequestInformationExtractor', function () { var cbFn = function (value) { assert.deepEqual(value, DEFAULT_RETURN_VALUE); }; - f.fuzzFunctionForTypes(manualRequestInformationExtractor, ["object"], + f.fuzzFunctionForTypes(manualRequestInformationExtractor, ['object'], cbFn); }); }); @@ -53,56 +55,56 @@ describe('manualRequestInformationExtractor', function () { manualRequestInformationExtractor(FULL_VALID_INPUT), FULL_VALID_INPUT, [ - "Given a full valid input object these values should be reflected by" - , "the output of the request extraction" - ].join(" ") + 'Given a full valid input object these values should be reflected by', + 'the output of the request extraction' + ].join(' ') ); assert.deepEqual( - manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "method")), - extend({}, FULL_VALID_INPUT, {method: ""}), + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'method')), + extend({}, FULL_VALID_INPUT, {method: ''}), [ - "Given a full valid input object sans the method property these values" - , "should be reflected by the output of the request extraction" - ].join(" ") + 'Given a full valid input object sans the method property these values', + 'should be reflected by the output of the request extraction' + ].join(' ') ); assert.deepEqual( - manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "url")), - extend({}, FULL_VALID_INPUT, {url: ""}), + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'url')), + extend({}, FULL_VALID_INPUT, {url: ''}), [ - "Given a full valid input sans the url property these values should be" - , "reflected by the output of the request extraction" + 'Given a full valid input sans the url property these values should be', + 'reflected by the output of the request extraction' ] ); assert.deepEqual( - manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "userAgent")), - extend({}, FULL_VALID_INPUT, {"userAgent": ""}), + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'userAgent')), + extend({}, FULL_VALID_INPUT, {'userAgent': ''}), [ - "Given a full valid input sans the userAgent property these values" - , "should be reflected by the output of the request extraction" + 'Given a full valid input sans the userAgent property these values', + 'should be reflected by the output of the request extraction' ] ); assert.deepEqual( - manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "referrer")), - extend({}, FULL_VALID_INPUT, {referrer: ""}), + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'referrer')), + extend({}, FULL_VALID_INPUT, {referrer: ''}), [ - "Given a full valid input sans the referrer property these values" - , "should be reflected by the output of the request extraction" + 'Given a full valid input sans the referrer property these values', + 'should be reflected by the output of the request extraction' ] ); assert.deepEqual( - manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "statusCode")), + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'statusCode')), extend({}, FULL_VALID_INPUT, {statusCode: 0}), [ - "Given a full valid input sans the statusCode property these values" - , "should be reflected by the output of the request extraction" + 'Given a full valid input sans the statusCode property these values', + 'should be reflected by the output of the request extraction' ] ); assert.deepEqual( - manualRequestInformationExtractor(omit(FULL_VALID_INPUT, "remoteAddress")), - extend({}, FULL_VALID_INPUT, {remoteAddress: ""}), + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'remoteAddress')), + extend({}, FULL_VALID_INPUT, {remoteAddress: ''}), [ - "Given a full valid input sans the remoteAddress property these values" - , "should be reflected by the output of the request extraction" + 'Given a full valid input sans the remoteAddress property these values', + 'should be reflected by the output of the request extraction' ] ); }); diff --git a/packages/error-reporting/test/unit/testRequestInformationContainer.js b/packages/error-reporting/test/unit/testRequestInformationContainer.js index c66e48ed14b..a4c71b01e48 100644 --- a/packages/error-reporting/test/unit/testRequestInformationContainer.js +++ b/packages/error-reporting/test/unit/testRequestInformationContainer.js @@ -1,19 +1,21 @@ /** * Copyright 2016 Google Inc. All Rights Reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 * * http://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, + * 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. */ +'use strict'; + var assert = require('assert'); var RequestInformationContainer = require('../../src/classes/request-information-container.js'); var Fuzzer = require('../../utils/fuzzer.js'); @@ -28,38 +30,38 @@ describe('RequestInformationContainer', function () { cbFn = function () { assert.deepEqual(ric.url, ''); }; - f.fuzzFunctionForTypes(ric.setUrl, ["string"], cbFn, ric); + f.fuzzFunctionForTypes(ric.setUrl, ['string'], cbFn, ric); } ); it('Should return the method property as an empty string', function () { cbFn = function ( returnValue ) { assert.deepEqual(ric.method, ''); }; - f.fuzzFunctionForTypes(ric.setMethod, ["string"], cbFn, ric); + f.fuzzFunctionForTypes(ric.setMethod, ['string'], cbFn, ric); }); it('Should return the referrer property as an empty string', function () { cbFn = function ( returnValue ) { assert.deepEqual(ric.referrer, ''); }; - f.fuzzFunctionForTypes(ric.setReferrer, ["string"], cbFn, ric); + f.fuzzFunctionForTypes(ric.setReferrer, ['string'], cbFn, ric); }); it('Should return the userAgent property as an empty string', function () { cbFn = function ( returnValue ) { assert.deepEqual(ric.userAgent, ''); }; - f.fuzzFunctionForTypes(ric.setUserAgent, ["string"], cbFn, ric); + f.fuzzFunctionForTypes(ric.setUserAgent, ['string'], cbFn, ric); }); it('Should return the remoteAddress property as an empty string', function () { cbFn = function ( returnValue ) { assert.deepEqual(ric.remoteAddress, ''); }; - f.fuzzFunctionForTypes(ric.setRemoteAddress, ["string"], cbFn, ric); + f.fuzzFunctionForTypes(ric.setRemoteAddress, ['string'], cbFn, ric); }); it('Should return the default value for statusCode', function () { cbFn = function ( returnValue ) { assert.strictEqual(ric.statusCode, 0); }; - f.fuzzFunctionForTypes(ric.setStatusCode, ["number"], cbFn, ric); + f.fuzzFunctionForTypes(ric.setStatusCode, ['number'], cbFn, ric); }); }); describe('Fuzzing against RequestInformationContainer for positive cases', function () { diff --git a/packages/error-reporting/test/unit/testRestifyInterface.js b/packages/error-reporting/test/unit/testRestifyInterface.js index 46870464afc..c476d2d5667 100644 --- a/packages/error-reporting/test/unit/testRestifyInterface.js +++ b/packages/error-reporting/test/unit/testRestifyInterface.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var EventEmitter = require('events').EventEmitter; var assert = require('assert'); var restifyInterface = require('../../src/interfaces/restify.js'); @@ -22,7 +24,7 @@ var restifyInterface = require('../../src/interfaces/restify.js'); if (!EventEmitter.prototype.listenerCount) { EventEmitter.prototype.listenerCount = function(eventName) { return EventEmitter.listenerCount(this, eventName); - } + }; } describe('restifyInterface', function () { @@ -31,7 +33,7 @@ describe('restifyInterface', function () { var noOp = function () {return;}; describe('Attachment to the uncaughtException event', function () { it('Should attach one listener after instantiation', function () { - var ee = new EventEmitter; + var ee = new EventEmitter(); assert.strictEqual(ee.listenerCount(UNCAUGHT_EVENT), 0, 'Listeners on event should be zero'); // return the bound function which the user will actually interface with @@ -43,7 +45,7 @@ describe('restifyInterface', function () { }); }); describe('Request handler lifecycle events', function () { - var ee = new EventEmitter; + var ee = new EventEmitter(); var errorHandlerInstance = restifyInterface(null, null); var requestHandlerInstance = errorHandlerInstance(ee); describe('default path on invalid input', function () { @@ -55,8 +57,8 @@ describe('restifyInterface', function () { }); describe('default path without req/res error', function () { ee.removeAllListeners(); - var req = new EventEmitter; - var res = new EventEmitter; + var req = new EventEmitter(); + var res = new EventEmitter(); res.statusCode = 200; it('Should have 0 listeners on the finish event', function () { assert.strictEqual(res.listenerCount(FINISH), 0); @@ -88,7 +90,7 @@ describe('restifyInterface', function () { return { service: 'stub-service', version: 'stub-version' - } + }; }, lacksCredentials: function () { return false; @@ -99,8 +101,8 @@ describe('restifyInterface', function () { }; var errorHandlerInstance = restifyInterface(client, config); var requestHandlerInstance = errorHandlerInstance(ee); - var req = new EventEmitter; - var res = new EventEmitter; + var req = new EventEmitter(); + var res = new EventEmitter(); res.statusCode = 500; it('Should have 0 Listeners on the finish event', function () { assert.strictEqual(res.listenerCount(FINISH), 0); diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index 26d5f06e93d..99dc1def748 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -17,7 +17,6 @@ 'use strict'; var assert = require('assert'); var is = require('is'); -var isNull = is.null; var isString = is.string; var isNumber = is.number; var forEach = require('lodash.foreach'); @@ -47,7 +46,7 @@ function setEnv (serviceName, serviceVersion, moduleName, moduleVersion, functio GAE_MODULE_NAME: moduleName, GAE_MODULE_VERSION: moduleVersion, FUNCTION_NAME: functionName - }, function (val) {return !isString(val)})); + }, function (val) {return !isString(val);})); } function restoreEnv () { assign(process.env, env); diff --git a/packages/error-reporting/test/unit/testUncaught.js b/packages/error-reporting/test/unit/testUncaught.js index 756193c7c3f..e2ca61c0f87 100644 --- a/packages/error-reporting/test/unit/testUncaught.js +++ b/packages/error-reporting/test/unit/testUncaught.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var assert = require('assert'); var isString = require('is').string; var uncaughtSetup = require('../../src/interfaces/uncaught.js'); @@ -67,15 +69,14 @@ describe('Uncaught exception handler behvaiour', function () { }); describe('Uncaught exception handling shutdown behaviour', function () { before(function () { - if (!isString(process.env.GOOGLE_APPLICATION_CREDENTIALS) - || !isString(process.env.GCLOUD_PROJECT)) { - this.skip(); - return; + if (!isString(process.env.GOOGLE_APPLICATION_CREDENTIALS) || + !isString(process.env.GCLOUD_PROJECT)) { + return this.skip(); } }); after(function () { reattachOriginalListeners(); - }) + }); it('Should terminate before 2500ms', function (done) { var TERMINATE_MSG = 'Should terminate before 2500ms'; this.timeout(3500); diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js index 91b67767104..016604a9fa1 100644 --- a/packages/error-reporting/utils/fuzzer.js +++ b/packages/error-reporting/utils/fuzzer.js @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +// jscs:disable +// jshint ignore: start 'use strict'; var indexOf = require('lodash.indexof'); From 7567bb8dace80a6ce3c2de05f38030e6e9985255 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Tue, 28 Feb 2017 13:34:23 -0800 Subject: [PATCH 03/29] Remove koa injection switch since 0.12 is no longer officially supported --- packages/error-reporting/index.js | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/error-reporting/index.js b/packages/error-reporting/index.js index 7124110267a..61d0acaa4b7 100644 --- a/packages/error-reporting/index.js +++ b/packages/error-reporting/index.js @@ -15,19 +15,11 @@ */ 'use strict'; -// Check if Koa is usable -var useKoa = true; -try { - eval('(function *() {})'); -} catch (e) { - useKoa = false; -} - var Configuration = require('./src/configuration.js'); var AuthClient = require('./src/google-apis/auth-client.js'); // Begin error reporting interfaces -var koa = useKoa ? require('./src/interfaces/koa.js') : null; +var koa = require('./src/interfaces/koa.js'); var hapi = require('./src/interfaces/hapi.js'); var manual = require('./src/interfaces/manual.js'); var express = require('./src/interfaces/express.js'); @@ -99,10 +91,7 @@ function Errors(initConfiguration) { this.express = express(client, config); this.restify = restify(client, config); this.event = messageBuilder(config); - - if (koa) { - this.koa = koa(client, config); - } + this.koa = koa(client, config); } module.exports = Errors; From dc81d2c4da70c63dfff2970c458411d6336924dc Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 09:13:36 -0800 Subject: [PATCH 04/29] start jscs linting --- packages/error-reporting/index.js | 4 +-- .../src/classes/custom-stack-trace.js | 2 +- .../src/classes/error-message.js | 20 ++++++------- packages/error-reporting/src/configuration.js | 26 ++++++++-------- packages/error-reporting/src/error-router.js | 30 +++++++++---------- packages/error-reporting/src/logger.js | 5 ++-- 6 files changed, 43 insertions(+), 44 deletions(-) diff --git a/packages/error-reporting/index.js b/packages/error-reporting/index.js index 61d0acaa4b7..bd93e921779 100644 --- a/packages/error-reporting/index.js +++ b/packages/error-reporting/index.js @@ -74,7 +74,7 @@ var createLogger = require('./src/logger.js'); * reporting configuration */ function Errors(initConfiguration) { - if (!(this instanceof Errors)){ + if (!(this instanceof Errors)) { return new Errors(initConfiguration); } @@ -91,7 +91,7 @@ function Errors(initConfiguration) { this.express = express(client, config); this.restify = restify(client, config); this.event = messageBuilder(config); - this.koa = koa(client, config); + this.koa = koa(client, config); } module.exports = Errors; diff --git a/packages/error-reporting/src/classes/custom-stack-trace.js b/packages/error-reporting/src/classes/custom-stack-trace.js index dc6b62ae456..7e9d3ea8eba 100644 --- a/packages/error-reporting/src/classes/custom-stack-trace.js +++ b/packages/error-reporting/src/classes/custom-stack-trace.js @@ -32,7 +32,7 @@ var isFunction = is.fn; */ function stubbedNoOp() { - return JSON.stringify({error : 'Unable to capture stack trace information'}); + return JSON.stringify({error: 'Unable to capture stack trace information'}); } /** diff --git a/packages/error-reporting/src/classes/error-message.js b/packages/error-reporting/src/classes/error-message.js index 05fcfa5fbf8..fc2bb4196e3 100644 --- a/packages/error-reporting/src/classes/error-message.js +++ b/packages/error-reporting/src/classes/error-message.js @@ -43,7 +43,7 @@ var isObject = is.object; * @property {Object} serviceContext - The service information for the error * @property {String} serviceContext.service - The service that the error was * was produced on - * @property {String|Undefined} serviceContext.version - The service version + * @property {String|Undefined} serviceContext.version - The service version * that the error was produced on * @property {String} message - The error message * @property {Object} context - the request, user and report context @@ -67,19 +67,19 @@ var isObject = is.object; function ErrorMessage() { this.eventTime = (new Date()).toISOString(); - this.serviceContext = {service : 'node', version : undefined}; + this.serviceContext = {service: 'node', version: undefined}; this.message = ''; this.context = { - httpRequest : { - method : '', - url : '', - userAgent : '', - referrer : '', - responseStatusCode : 0, - remoteIp : '' + httpRequest: { + method: '', + url: '', + userAgent: '', + referrer: '', + responseStatusCode: 0, + remoteIp: '' }, user : '', - reportLocation : {filePath : '', lineNumber : 0, functionName : ''} + reportLocation : {filePath: '', lineNumber: 0, functionName: ''} }; } diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index f71c35bf1de..be35f8ee1ce 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -76,10 +76,10 @@ var Configuration = function(givenConfig, logger) { * The _shouldReportErrorsToAPI property is meant to denote whether or not * the Stackdriver error reporting library will actually try to report Errors * to the Stackdriver Error API. The value of this property is derived from - * the `NODE_ENV` environmental variable or the value of the ignoreEnvironmentCheck + * the `NODE_ENV` environmental variable or the value of ignoreEnvironmentChec * property if present in the runtime configuration. If either the `NODE_ENV` * variable is set to 'production' or the ignoreEnvironmentCheck propery on - * the runtime configuration is set to true then the error reporting library will + * the runtime configuration is set to true then the error reporting library * attempt to send errors to the Error API. Otherwise the value will remain * false and errors will not be reported to the API. * @memberof Configuration @@ -220,14 +220,12 @@ Configuration.prototype._checkLocalServiceContext = function() { var service; var version; - if (env.FUNCTION_NAME){ + if (env.FUNCTION_NAME) { service = env.FUNCTION_NAME; - } - else if (env.GAE_SERVICE){ + } else if (env.GAE_SERVICE){ service = env.GAE_SERVICE; version = env.GAE_VERSION; - } - else if (env.GAE_MODULE_NAME){ + } else if (env.GAE_MODULE_NAME){ service = env.GAE_MODULE_NAME; version = env.GAE_MODULE_VERSION; } @@ -237,7 +235,7 @@ Configuration.prototype._checkLocalServiceContext = function() { if (isObject(this._givenConfiguration.serviceContext)) { if (isString(this._givenConfiguration.serviceContext.service)) { - this._serviceContext.service = + this._serviceContext.service = this._givenConfiguration.serviceContext.service; } else if (has(this._givenConfiguration.serviceContext, 'service')) { throw new Error('config.serviceContext.service must be a string'); @@ -268,7 +266,7 @@ Configuration.prototype._gatherLocalConfiguration = function() { this._shouldReportErrorsToAPI = true; } else if (has(this._givenConfiguration, 'ignoreEnvironmentCheck') && !isBoolean(this._givenConfiguration.ignoreEnvironmentCheck)) { - throw new Error('config.ignoreEnvironmentCheck must be a boolean'); + throw new Error('config.ignoreEnvironmentCheck must be a boolean'); } else { this._shouldReportErrorsToAPI = env.NODE_ENV === 'production'; } @@ -313,11 +311,11 @@ Configuration.prototype._gatherLocalConfiguration = function() { * @function _checkAuthConfiguration * @returns {Undefined} - does not return anything */ -Configuration.prototype._checkAuthConfiguration = function () { +Configuration.prototype._checkAuthConfiguration = function() { if (!isNull(this._key) || !isNull(this._keyFilename) || - !isNull(this._credentials) || + !isNull(this._credentials) || !isEmpty(process.env.GOOGLE_APPLICATION_CREDENTIALS)) { - this._lacksValidCredentials = false; + this._lacksValidCredentials = false; } else { this._logger.warn([ 'Unable to find credential information on instance. This library will', @@ -404,11 +402,11 @@ Configuration.prototype.getShouldReportErrorsToAPI = function() { Configuration.prototype.getProjectId = function(cb) { var self = this; if (!isNull(this._projectId)) { - setImmediate(function () { + setImmediate(function() { cb(null, self._projectId); }); } else { - utils.getProjectId(function (err, projectId) { + utils.getProjectId(function(err, projectId) { if (err) { self._checkLocalProjectId(cb); } else { diff --git a/packages/error-reporting/src/error-router.js b/packages/error-reporting/src/error-router.js index 4ad2008e87f..d8dbcf5ab8e 100644 --- a/packages/error-reporting/src/error-router.js +++ b/packages/error-reporting/src/error-router.js @@ -42,21 +42,21 @@ function errorHandlerRouter(err, em) { } switch (typeof err) { - case 'object': - - handleObjectAsError(err, em); - break; - case 'string': - - handleStringAsError(err, em); - break; - case 'number': - - handleNumberAsError(err, em); - break; - default: - - handleUnknownAsError(err, em); + case 'object': { + handleObjectAsError(err, em); + break; + } + case 'string': { + handleStringAsError(err, em); + break; + } + case 'number': { + handleNumberAsError(err, em); + break; + } + default: { + handleUnknownAsError(err, em); + } } } diff --git a/packages/error-reporting/src/logger.js b/packages/error-reporting/src/logger.js index aa5cd0d6747..907778f505f 100644 --- a/packages/error-reporting/src/logger.js +++ b/packages/error-reporting/src/logger.js @@ -39,13 +39,14 @@ var logger = require('@google/cloud-diagnostics-common').logger; * @returns {Object} - returns an instance of the logger created with the given/ * default options */ -function createLogger (initConfiguration) { +function createLogger(initConfiguration) { // Default to log level: warn (2) var level = logger.WARN; if (has(process.env, 'GCLOUD_ERRORS_LOGLEVEL')) { // Cast env string as integer level = ~~process.env.GCLOUD_ERRORS_LOGLEVEL; - } else if (isObject(initConfiguration) && has(initConfiguration, 'logLevel')) { + } else if (isObject(initConfiguration) + && has(initConfiguration, 'logLevel')) { if (isString(initConfiguration.logLevel)) { // Cast string as integer level = ~~initConfiguration.logLevel; From d12de53839708efbb9f88858069b6f38479c25b8 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 09:20:50 -0800 Subject: [PATCH 05/29] remove all trailing spaces --- .../src/classes/error-message.js | 2 +- packages/error-reporting/src/configuration.js | 20 ++++++------- .../src/google-apis/auth-client.js | 2 +- .../error-reporting/src/interfaces/express.js | 2 +- .../error-reporting/src/interfaces/hapi.js | 2 +- packages/error-reporting/src/logger.js | 2 +- .../test/system-test/testAuthClient.js | 2 +- .../test-servers/express_scaffold_server.js | 6 ++-- .../test-servers/manual_scaffold_server.js | 2 +- .../test/unit/testErrorMessage.js | 6 ++-- .../test/unit/testExpressInterface.js | 2 +- .../test/unit/testExtractFromErrorClass.js | 2 +- .../test/unit/testManualHandler.js | 6 ++-- .../unit/testRequestInformationContainer.js | 2 +- .../test/unit/testServiceConfiguration.js | 28 +++++++++---------- .../error-reporting/test/unit/testUncaught.js | 2 +- 16 files changed, 44 insertions(+), 44 deletions(-) diff --git a/packages/error-reporting/src/classes/error-message.js b/packages/error-reporting/src/classes/error-message.js index fc2bb4196e3..c379a6e759d 100644 --- a/packages/error-reporting/src/classes/error-message.js +++ b/packages/error-reporting/src/classes/error-message.js @@ -103,7 +103,7 @@ ErrorMessage.prototype.setEventTimeToNow = function() { * @function setServiceContext * @chainable * @param {String} service - the service the error was reported on - * @param {String|Undefined} version - the version the service was on when the + * @param {String|Undefined} version - the version the service was on when the * error was reported * @returns {this} - returns the instance for chaining */ diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index be35f8ee1ce..4c67ccca6c6 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -77,10 +77,10 @@ var Configuration = function(givenConfig, logger) { * the Stackdriver error reporting library will actually try to report Errors * to the Stackdriver Error API. The value of this property is derived from * the `NODE_ENV` environmental variable or the value of ignoreEnvironmentChec - * property if present in the runtime configuration. If either the `NODE_ENV` - * variable is set to 'production' or the ignoreEnvironmentCheck propery on + * property if present in the runtime configuration. If either the `NODE_ENV` + * variable is set to 'production' or the ignoreEnvironmentCheck propery on * the runtime configuration is set to true then the error reporting library - * attempt to send errors to the Error API. Otherwise the value will remain + * attempt to send errors to the Error API. Otherwise the value will remain * false and errors will not be reported to the API. * @memberof Configuration * @private @@ -191,7 +191,7 @@ var Configuration = function(givenConfig, logger) { * names, if these are not set then it will defer to the _givenConfiguration * property if it is set on the instance. The function will check env variables * `GAE_MODULE_NAME` and `GAE_MODULE_VERSION` for `_serviceContext.service` and - * `_serviceContext.version` respectively. If these are not set the + * `_serviceContext.version` respectively. If these are not set the * `_serviceContext` properties will be left at default unless the given runtime * configuration supplies any values as substitutes. * @memberof Configuration @@ -201,15 +201,15 @@ var Configuration = function(givenConfig, logger) { */ Configuration.prototype._checkLocalServiceContext = function() { // Note: The GAE_MODULE_NAME environment variable is set on GAE. - // If the code is, in particular, running on GCF, then the + // If the code is, in particular, running on GCF, then the // FUNCTION_NAME environment variable is set. // // To determine the service name to use: - // If the user specified a service name it should be used, otherwise - // if the FUNCTION_NAME environment variable is set (indicating that the - // code is running on GCF) then the FUNCTION_NAME value should be used as - // the service name. If neither of these conditions are true, the - // value of the GAE_MODULE_NAME environment variable should be used as the + // If the user specified a service name it should be used, otherwise + // if the FUNCTION_NAME environment variable is set (indicating that the + // code is running on GCF) then the FUNCTION_NAME value should be used as + // the service name. If neither of these conditions are true, the + // value of the GAE_MODULE_NAME environment variable should be used as the // service name. // // To determine the service version to use: diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 4ccb2f71514..8ef93163cfa 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -100,7 +100,7 @@ RequestHandler.prototype.sendError = function(errorMessage, userCb) { self._logger.error([ 'Unable to retrieve a project id from the Google Metadata Service or', 'the local environment. Client will not be able to communicate with', - 'the Stackdriver Error Reporting API without a valid project id', + 'the Stackdriver Error Reporting API without a valid project id', 'Please make sure to supply a project id either through the', 'GCLOUD_PROJECT environmental variable or through the configuration', 'object given to this library on startup if not running on Google', diff --git a/packages/error-reporting/src/interfaces/express.js b/packages/error-reporting/src/interfaces/express.js index 332549aa2b9..07a0614a603 100644 --- a/packages/error-reporting/src/interfaces/express.js +++ b/packages/error-reporting/src/interfaces/express.js @@ -47,7 +47,7 @@ function makeExpressHandler(client, config) { function expressErrorHandler(err, req, res, next) { var ctxService = ''; var ctxVersion = ''; - + if (config.lacksCredentials()) { next(err); } diff --git a/packages/error-reporting/src/interfaces/hapi.js b/packages/error-reporting/src/interfaces/hapi.js index 28009a56091..1f123ce909e 100644 --- a/packages/error-reporting/src/interfaces/hapi.js +++ b/packages/error-reporting/src/interfaces/hapi.js @@ -95,7 +95,7 @@ function makeHapiPlugin(client, config) { em = hapiErrorHandler(request, new Error(request.response.message), config); - if (!config.lacksCredentials()) { + if (!config.lacksCredentials()) { client.sendError(em); } } diff --git a/packages/error-reporting/src/logger.js b/packages/error-reporting/src/logger.js index 907778f505f..270f9241fc7 100644 --- a/packages/error-reporting/src/logger.js +++ b/packages/error-reporting/src/logger.js @@ -45,7 +45,7 @@ function createLogger(initConfiguration) { if (has(process.env, 'GCLOUD_ERRORS_LOGLEVEL')) { // Cast env string as integer level = ~~process.env.GCLOUD_ERRORS_LOGLEVEL; - } else if (isObject(initConfiguration) + } else if (isObject(initConfiguration) && has(initConfiguration, 'logLevel')) { if (isString(initConfiguration.logLevel)) { // Cast string as integer diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index 324fdba47cd..888e355b467 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -75,7 +75,7 @@ describe('Behvaiour acceptance testing', function () { client.sendError({}, function (err, response, body) { assert(err instanceof Error); assert.strictEqual(err.message.toLowerCase(), - 'message cannot be empty.'); + 'message cannot be empty.'); assert.strictEqual(body, null); assert(isObject(response)); assert.strictEqual(response.statusCode, 400); diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js index 13c24014dc6..c19f2578097 100644 --- a/packages/error-reporting/test/test-servers/express_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -34,7 +34,7 @@ app.post('/testErrorHandling', function ( req, res, next ) { if ( has(req.body, 'test') && req.body.test !== true ) { - + return next(new Error('Error on Express Regular Error POST Route')); } else { @@ -74,7 +74,7 @@ app.get( app.get( '/getError', function ( req, res, next ) { - + return next(new Error('Error on Express Regular Error GET Route')); } ); @@ -92,7 +92,7 @@ function reportManualError ( ) { new Error('This is a manually reported error'), null, null, function ( err, res ) { if ( err ) { - + console.log(WARNING_HEADER); console.log('Got an error in sending error information to the API'); console.log(err); diff --git a/packages/error-reporting/test/test-servers/manual_scaffold_server.js b/packages/error-reporting/test/test-servers/manual_scaffold_server.js index 9c6f20b961e..72aae1f0195 100644 --- a/packages/error-reporting/test/test-servers/manual_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/manual_scaffold_server.js @@ -19,7 +19,7 @@ const errors = require('../../index.js')(); errors.report('Sample test string', (err, response, body) => { console.log( 'Callback from report:\n', - '\tError: ', err, '\n', + '\tError: ', err, '\n', '\tResponse Body:', body ); }); diff --git a/packages/error-reporting/test/unit/testErrorMessage.js b/packages/error-reporting/test/unit/testErrorMessage.js index 2f9f1bc76cc..8a968865c87 100644 --- a/packages/error-reporting/test/unit/testErrorMessage.js +++ b/packages/error-reporting/test/unit/testErrorMessage.js @@ -22,7 +22,7 @@ var ErrorMessage = require('../../src/classes/error-message.js'); describe('Instantiating a new ErrorMessage', function () { var em; beforeEach(function () {em = new ErrorMessage();}); - + it('Should have a default service context', function () { assert.deepEqual( em.serviceContext, @@ -73,7 +73,7 @@ describe('Fuzzing against setServiceContext', function () { var DEFAULT_SERVICE_VALUE = 'node'; var em; beforeEach(function () {em = new ErrorMessage()}); - + it('Should set the value for service context', function () { em.setServiceContext(AFFIRMATIVE_TEST_VALUE, AFFIRMATIVE_TEST_VALUE); assert.deepEqual( @@ -661,7 +661,7 @@ describe('Fuzzing against consumeRequestInformation', function () { ); } ); - it('Should return the instance on calling consumeRequestInformation', + it('Should return the instance on calling consumeRequestInformation', function () { assert( em.consumeRequestInformation(AFFIRMATIVE_TEST_VALUE) instanceof ErrorMessage diff --git a/packages/error-reporting/test/unit/testExpressInterface.js b/packages/error-reporting/test/unit/testExpressInterface.js index 3e4f2955d32..8d04fc544cd 100644 --- a/packages/error-reporting/test/unit/testExpressInterface.js +++ b/packages/error-reporting/test/unit/testExpressInterface.js @@ -52,7 +52,7 @@ describe('expressInterface', function () { var client = { sendError: function () { return; - } + } }; var testError = new Error('This is a test'); var validBoundHandler = expressInterface(client, stubbedConfig); diff --git a/packages/error-reporting/test/unit/testExtractFromErrorClass.js b/packages/error-reporting/test/unit/testExtractFromErrorClass.js index a2454ac7bdb..f5435d2f5a3 100644 --- a/packages/error-reporting/test/unit/testExtractFromErrorClass.js +++ b/packages/error-reporting/test/unit/testExtractFromErrorClass.js @@ -33,7 +33,7 @@ describe('Writing and reading ErrorMessage properties', function () { ); }); }); - describe('User field', function () { + describe('User field', function () { var em, err; var TEST_USER_INVALID = 12; beforeEach(function () { diff --git a/packages/error-reporting/test/unit/testManualHandler.js b/packages/error-reporting/test/unit/testManualHandler.js index 4ac4e6347bb..4b0b8031fd9 100644 --- a/packages/error-reporting/test/unit/testManualHandler.js +++ b/packages/error-reporting/test/unit/testManualHandler.js @@ -140,7 +140,7 @@ describe('Manual handler', function () { it('Should accept builder instance as only argument', function () { var msg = 'test'; var r = report(new ErrorMessage().setMessage(msg)); - assert.strictEqual(r.message, msg, + assert.strictEqual(r.message, msg, 'string message should propagate from error message instance'); }); it('Should accept builder and request as arguments', function () { @@ -151,7 +151,7 @@ describe('Manual handler', function () { new ErrorMessage().setMessage(msg).consumeRequestInformation(oldReq), newReq ); - assert.strictEqual(r.message, msg, + assert.strictEqual(r.message, msg, 'string message should propagate from error message instance'); assert.strictEqual(r.context.httpRequest.method, newReq.method, [ @@ -167,7 +167,7 @@ describe('Manual handler', function () { new ErrorMessage().setMessage(oldMsg), newMsg ); - assert.strictEqual(r.message, newMsg, + assert.strictEqual(r.message, newMsg, [ 'message argument supplied at report invocation should propagte and, if', 'supplied, should overwrite any prexisting data in the message field.' diff --git a/packages/error-reporting/test/unit/testRequestInformationContainer.js b/packages/error-reporting/test/unit/testRequestInformationContainer.js index a4c71b01e48..578e2f4e0c2 100644 --- a/packages/error-reporting/test/unit/testRequestInformationContainer.js +++ b/packages/error-reporting/test/unit/testRequestInformationContainer.js @@ -24,7 +24,7 @@ describe('RequestInformationContainer', function () { var f = new Fuzzer(); var cbFn, ric; beforeEach(function () {ric = new RequestInformationContainer();}); - describe('Fuzzing against RequestInformationContainer for negative cases', function () { + describe('Fuzzing against RequestInformationContainer for negative cases', function () { it('Should return the RequestInformationContainer.url propertym as an empty string', function () { cbFn = function () { diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index 99dc1def748..ad7386478bb 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -56,14 +56,14 @@ describe('Testing service configuration', function () { beforeEach(function () {sterilizeEnv();}); after(function () {restoreEnv();}); it( - 'A Configuration uses the function name as the service name on GCF ' + + 'A Configuration uses the function name as the service name on GCF ' + 'if the service name is not given in the given config', function () { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', 'someFunction'); var c = new Configuration({}, logger); assert.deepEqual(c.getServiceContext().service, 'someFunction'); - // FUNCTION_NAME is set and the user didn't specify a version, and so + // FUNCTION_NAME is set and the user didn't specify a version, and so // the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } @@ -76,7 +76,7 @@ describe('Testing service configuration', function () { setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); var c = new Configuration({}, logger); assert.deepEqual(c.getServiceContext().service, 'someFunction'); - // The user didn't specify a version and FUNCTION_NAME is defined, and + // The user didn't specify a version and FUNCTION_NAME is defined, and // so the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } @@ -89,7 +89,7 @@ describe('Testing service configuration', function () { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); var c = new Configuration({}, logger); assert.deepEqual(c.getServiceContext().service, 'someModuleName'); - // The user didn't specify a version, and FUNCTION_NAME is not defined, + // The user didn't specify a version, and FUNCTION_NAME is not defined, // and so use the GAE_MODULE_VERSION assert.deepEqual(c.getServiceContext().version, '1.0'); } @@ -107,7 +107,7 @@ describe('Testing service configuration', function () { } }, logger); assert.deepEqual(c.getServiceContext().service, 'customService'); - // The user didn't specify a version, but FUNCTION_NAME is defined, and + // The user didn't specify a version, but FUNCTION_NAME is defined, and // so the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } @@ -141,7 +141,7 @@ describe('Testing service configuration', function () { } }, logger); assert.deepEqual(c.getServiceContext().service, 'customService'); - // The user didn't specify a version and FUNCTION_NAME is not defined + // The user didn't specify a version and FUNCTION_NAME is not defined // and so the GAE_MODULE_VERSION should be used assert.deepEqual(c.getServiceContext().version, '1.0'); } @@ -173,7 +173,7 @@ describe('Testing service configuration', function () { } }, logger); assert.deepEqual(c.getServiceContext().service, 'customService'); - // The user didn't specify a version and thus because FUNCTION_NAME is + // The user didn't specify a version and thus because FUNCTION_NAME is // defined the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } @@ -255,13 +255,13 @@ describe('Testing service configuration', function () { // // The following tests always have GAE_SERVICE and GAE_VERSION not set // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the function name as the service name on GCF ' + + // 'A Configuration uses the function name as the service name on GCF ' + // 'if the service name is not given in the given config', // makeTest(null, null, 'someModuleName', '1.0', 'someFunction', // function(done) { // var c = new Configuration({}, logger); // assert.deepEqual(c.getServiceContext().service, 'someFunction'); - // // FUNCTION_NAME is set and the user didn't specify a version, and so + // // FUNCTION_NAME is set and the user didn't specify a version, and so // // the version should not be defined // assert.deepEqual(c.getServiceContext().version, undefined); @@ -278,7 +278,7 @@ describe('Testing service configuration', function () { // function(done) { // var c = new Configuration({}, logger); // assert.deepEqual(c.getServiceContext().service, 'someFunction'); - // // The user didn't specify a version and FUNCTION_NAME is defined, and + // // The user didn't specify a version and FUNCTION_NAME is defined, and // // so the version should not be defined // assert.deepEqual(c.getServiceContext().version, undefined); @@ -295,7 +295,7 @@ describe('Testing service configuration', function () { // function(done) { // var c = new Configuration({}, logger); // assert.deepEqual(c.getServiceContext().service, 'someModuleName'); - // // The user didn't specify a version, and FUNCTION_NAME is not defined, + // // The user didn't specify a version, and FUNCTION_NAME is not defined, // // and so use the GAE_MODULE_VERSION // assert.deepEqual(c.getServiceContext().version, '1.0'); @@ -316,7 +316,7 @@ describe('Testing service configuration', function () { // } // }, logger); // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user didn't specify a version, but FUNCTION_NAME is defined, and + // // The user didn't specify a version, but FUNCTION_NAME is defined, and // // so the version should not be defined // assert.deepEqual(c.getServiceContext().version, undefined); @@ -357,7 +357,7 @@ describe('Testing service configuration', function () { // } // }, logger); // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user didn't specify a version and FUNCTION_NAME is not defined + // // The user didn't specify a version and FUNCTION_NAME is not defined // // and so the GAE_MODULE_VERSION should be used // assert.deepEqual(c.getServiceContext().version, '1.0'); @@ -397,7 +397,7 @@ describe('Testing service configuration', function () { // } // }, logger); // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user didn't specify a version and thus because FUNCTION_NAME is + // // The user didn't specify a version and thus because FUNCTION_NAME is // // defined the version should not be defined // assert.deepEqual(c.getServiceContext().version, undefined); diff --git a/packages/error-reporting/test/unit/testUncaught.js b/packages/error-reporting/test/unit/testUncaught.js index e2ca61c0f87..7a96c6b52e9 100644 --- a/packages/error-reporting/test/unit/testUncaught.js +++ b/packages/error-reporting/test/unit/testUncaught.js @@ -80,7 +80,7 @@ describe('Uncaught exception handler behvaiour', function () { it('Should terminate before 2500ms', function (done) { var TERMINATE_MSG = 'Should terminate before 2500ms'; this.timeout(3500); - var isolate = spawn('./node_modules/mocha/bin/mocha', + var isolate = spawn('./node_modules/mocha/bin/mocha', ['../../test/fixtures/uncaughtExitBehaviour.js'], {env: process.env}); isolate.on('close', function () { done(); From d437090163727ac9b3996f01ba453261893aad6d Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 09:22:09 -0800 Subject: [PATCH 06/29] Replace occurences of non-compliant function declaration syntax --- packages/error-reporting/README.md | 6 +- .../src/google-apis/auth-client.js | 6 +- .../test/fixtures/configuration.js | 2 +- .../test/fixtures/uncaughtExitBehaviour.js | 16 +- .../test/system-test/testAuthClient.js | 132 ++++++------ .../test-servers/express_scaffold_server.js | 12 +- .../test/test-servers/hapi_scaffold_server.js | 4 +- .../test-servers/manual_scaffold_server.js | 4 +- .../test/unit/testConfigCredentials.js | 26 +-- .../test/unit/testConfiguration.js | 190 +++++++++--------- .../test/unit/testCustomStackTrace.js | 16 +- .../test/unit/testErrorMessage.js | 136 ++++++------- .../test/unit/testExpressInterface.js | 30 +-- .../testExpressRequestInformationExtractor.js | 14 +- .../test/unit/testExtractFromErrorClass.js | 32 +-- .../test/unit/testExtractFromObject.js | 42 ++-- .../test/unit/testHandleErrorClassError.js | 18 +- .../test/unit/testHandleNumberAsError.js | 16 +- .../test/unit/testHandleObjectAsError.js | 16 +- .../test/unit/testHandleStringAsError.js | 16 +- .../test/unit/testHandleUnknownAsError.js | 18 +- .../test/unit/testHapiInterface.js | 68 +++---- .../testHapiRequestInformationExtractor.js | 16 +- .../testKoaRequestInformationExtractor.js | 12 +- .../error-reporting/test/unit/testLogger.js | 28 +-- .../test/unit/testManualHandler.js | 48 ++--- .../testManualRequestInformationExtractor.js | 12 +- .../unit/testRequestInformationContainer.js | 44 ++-- .../test/unit/testRestifyInterface.js | 60 +++--- .../test/unit/testServiceConfiguration.js | 34 ++-- .../error-reporting/test/unit/testUncaught.js | 30 +-- packages/error-reporting/utils/fuzzer.js | 34 ++-- 32 files changed, 569 insertions(+), 569 deletions(-) diff --git a/packages/error-reporting/README.md b/packages/error-reporting/README.md index 6aa747d6048..a9b777b4d54 100644 --- a/packages/error-reporting/README.md +++ b/packages/error-reporting/README.md @@ -148,12 +148,12 @@ var app = express(); // Will create a errors instance based off env variables var errors = require('@google/cloud-errors')(); -app.get('/error', function ( req, res, next ) { +app.get('/error', function( req, res, next ) { res.send('Something broke!'); next(new Error('Custom error message')); }); -app.get('/exception', function () { +app.get('/exception', function() { JSON.parse('{\"malformedJson\": true'); }); @@ -175,7 +175,7 @@ server.start(); server.route({ method: 'GET', path: '/error', - handler: function ( request, reply ) { + handler: function( request, reply ) { throw new Error('Custom error message'); reply('Something broke!'); } diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 8ef93163cfa..05b180a4e0e 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -94,9 +94,9 @@ RequestHandler.prototype.sendError = function(errorMessage, userCb) { var self = this; var cb = isFunction(userCb) ? userCb : function() {}; if (self._config.getShouldReportErrorsToAPI()) { - self._config.getProjectId(function (err, id) { + self._config.getProjectId(function(err, id) { if (err) { - setImmediate(function () { cb(err, null, null); }); + setImmediate(function() { cb(err, null, null); }); self._logger.error([ 'Unable to retrieve a project id from the Google Metadata Service or', 'the local environment. Client will not be able to communicate with', @@ -112,7 +112,7 @@ RequestHandler.prototype.sendError = function(errorMessage, userCb) { url: getErrorReportURL(id, self._config.getKey()), method: 'POST', json: errorMessage - }, function (err, response, body) { + }, function(err, response, body) { if (err) { self._logger.error([ 'Encountered an error while attempting to transmit an error to the', diff --git a/packages/error-reporting/test/fixtures/configuration.js b/packages/error-reporting/test/fixtures/configuration.js index 2f89b554536..2e0834e6e61 100644 --- a/packages/error-reporting/test/fixtures/configuration.js +++ b/packages/error-reporting/test/fixtures/configuration.js @@ -19,7 +19,7 @@ var Configuration = require('../../src/configuration.js'); var FakeConfiguration = function(config) { - return Configuration.call(this, config, { warn: function () {} }); + return Configuration.call(this, config, { warn: function() {} }); }; FakeConfiguration.prototype = Object.create(Configuration.prototype); diff --git a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js index d3a7e8f1c1e..1b9e6230509 100644 --- a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js +++ b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js @@ -40,8 +40,8 @@ function restoreEnv () { process.env.NODE_ENV = env.NODE_ENV; } -describe('Uncaught Exception exit behaviour', function () { - before(function () { +describe('Uncaught Exception exit behaviour', function() { + before(function() { process.removeAllListeners(UNCAUGHT); if (!isString(process.env.GCLOUD_PROJECT)) { // The gcloud project id (GCLOUD_PROJECT) was not set as an env variable @@ -54,19 +54,19 @@ describe('Uncaught Exception exit behaviour', function () { } setEnv(); }); - after(function () { + after(function() { nock.cleanAll(); nock.enableNetConnect(); reattachOriginalListeners(); restoreEnv(); }); - it('Should attempt to report the uncaught exception', function (done) { + it('Should attempt to report the uncaught exception', function(done) { var id = 'xyz'; nock( 'http://metadata.google.internal/computeMetadata/v1/project' ).get('/project-id').times(1).reply(200, id); nock('https://accounts.google.com:443/o/oauth2') - .post('/token').query(function () {return true;}).reply(200, { + .post('/token').query(function() {return true;}).reply(200, { refresh_token: 'hello', access_token: 'goodbye', expiry_date: new Date(9999, 1, 1) @@ -74,18 +74,18 @@ describe('Uncaught Exception exit behaviour', function () { this.timeout(2000); nock( 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+id - ).post('/events:report').once().reply(200, function () { + ).post('/events:report').once().reply(200, function() { done(); return {success: true}; }); var cfg = new Configuration( {reportUncaughtExceptions: true, projectId: 'xyz'}); - cfg.lacksCredentials = function () { + cfg.lacksCredentials = function() { return false; }; client = new RequestHandler(cfg, createLogger({logLevel: 4})); uncaughtSetup(client, cfg); - setTimeout(function () { + setTimeout(function() { throw new Error('This error was supposed to be thrown'); }, 10); }); diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index 888e355b467..9ce71c01a9d 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -29,8 +29,8 @@ var forEach = require('lodash.foreach'); var assign = require('lodash.assign'); -describe('Behvaiour acceptance testing', function () { - before(function () { +describe('Behvaiour acceptance testing', function() { + before(function() { // Before starting the suite make sure we have the proper resources if (!isString(process.env.GCLOUD_PROJECT)) { console.error( @@ -53,11 +53,11 @@ describe('Behvaiour acceptance testing', function () { // In case we are running after unit mocks which were not destroyed properly nock.cleanAll(); }); - describe('Request/Response lifecycle mocking', function () { + describe('Request/Response lifecycle mocking', function() { var sampleError = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); var errorMessage = new ErrorMessage().setMessage(sampleError); var fakeService, client, logger; - beforeEach(function () { + beforeEach(function() { fakeService = nock( 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+ process.env.GCLOUD_PROJECT @@ -66,13 +66,13 @@ describe('Behvaiour acceptance testing', function () { client = new RequestHandler( new Configuration({ignoreEnvironmentCheck: true}, logger), logger); }); - afterEach(function () { + afterEach(function() { nock.cleanAll(); }); - describe('Receiving non-retryable errors', function () { - it('Should fail', function (done) { + describe('Receiving non-retryable errors', function() { + it('Should fail', function(done) { this.timeout(5000); - client.sendError({}, function (err, response, body) { + client.sendError({}, function(err, response, body) { assert(err instanceof Error); assert.strictEqual(err.message.toLowerCase(), 'message cannot be empty.'); @@ -83,47 +83,47 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('Receiving retryable errors', function () { - it('Should retry', function (done) { + describe('Receiving retryable errors', function() { + it('Should retry', function(done) { this.timeout(25000); var tries = 0; var intendedTries = 5; - fakeService.reply(429, function () { + 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, body) { + client.sendError(errorMessage, function(err, response, body) { assert.strictEqual(tries, intendedTries); done(); }); }); }); - describe('Using an API key', function () { - it('Should provide the key as a query string on outgoing requests', function (done) { + describe('Using an API key', function() { + it('Should provide the key as a query string on outgoing requests', function(done) { var key = process.env.STUBBED_API_KEY; var client = new RequestHandler(new Configuration( {key: key, ignoreEnvironmentCheck: true}, createLogger({logLevel: 5}))); - fakeService.query({key: key}).reply(200, function (uri) { + fakeService.query({key: key}).reply(200, function(uri) { assert(uri.indexOf('key='+key) > -1); return {}; }); - client.sendError(errorMessage, function () { + client.sendError(errorMessage, function() { done(); }); }); }); - describe('Callback-less invocation', function () { - it('Should still execute the request', function (done) { - fakeService.reply(200, function () { + describe('Callback-less invocation', function() { + it('Should still execute the request', function(done) { + fakeService.reply(200, function() { done(); }); client.sendError(errorMessage); }); }); }); - describe('System-live integration testing', function () { + describe('System-live integration testing', function() { var sampleError = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); var errorMessage = new ErrorMessage().setMessage(sampleError.stack); var oldEnv = { @@ -132,29 +132,29 @@ describe('Behvaiour acceptance testing', function () { NODE_ENV: process.env.NODE_ENV }; function sterilizeEnv () { - forEach(oldEnv, function (val, key) { + forEach(oldEnv, function(val, key) { delete process.env[key]; }); } function restoreEnv () { assign(process.env, oldEnv); } - describe('Client creation', function () { - describe('Using only project id', function () { - describe('As a runtime argument', function () { + describe('Client creation', function() { + describe('Using only project id', function() { + describe('As a runtime argument', function() { var cfg, logger; - before(function () { + before(function() { sterilizeEnv(); logger = createLogger({logLevel: 5}); cfg = new Configuration({projectId: oldEnv.GCLOUD_PROJECT, ignoreEnvironmentCheck: true}, logger); }); after(restoreEnv); - it('Should not throw on initialization', function (done) { + it('Should not throw on initialization', function(done) { this.timeout(10000); - assert.doesNotThrow(function () { + assert.doesNotThrow(function() { (new RequestHandler(cfg, logger)).sendError(errorMessage, - function (err, response, body) { + function(err, response, body) { assert.strictEqual(err, null); assert.strictEqual(response.statusCode, 200); assert(isObject(body) && isEmpty(body)); @@ -164,20 +164,20 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('As an env variable', function () { + describe('As an env variable', function() { var cfg, logger; - before(function () { + before(function() { sterilizeEnv(); process.env.GCLOUD_PROJECT = oldEnv.GCLOUD_PROJECT; logger = createLogger({logLevel: 5}); cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); }); after(restoreEnv); - it('Should not throw on initialization', function (done) { + it('Should not throw on initialization', function(done) { this.timeout(10000); - assert.doesNotThrow(function () { + assert.doesNotThrow(function() { (new RequestHandler(cfg, logger)).sendError(errorMessage, - function (err, response, body) { + function(err, response, body) { assert.strictEqual(err, null); assert.strictEqual(response.statusCode, 200); assert(isObject(body) && isEmpty(body)); @@ -188,21 +188,21 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('Using only project number', function () { - describe('As a runtime argument', function () { + describe('Using only project number', function() { + describe('As a runtime argument', function() { var cfg, logger; - before(function () { + before(function() { sterilizeEnv(); logger = createLogger({logLevel: 5}); cfg = new Configuration({projectId: parseInt(oldEnv.STUBBED_PROJECT_NUM), ignoreEnvironmentCheck: true}, logger); }); after(restoreEnv); - it('Should not throw on initialization', function (done) { + it('Should not throw on initialization', function(done) { this.timeout(10000); - assert.doesNotThrow(function () { + assert.doesNotThrow(function() { (new RequestHandler(cfg, logger)).sendError(errorMessage, - function (err, response, body) { + function(err, response, body) { assert.strictEqual(err, null); assert.strictEqual(response.statusCode, 200); assert(isObject(body) && isEmpty(body)); @@ -212,20 +212,20 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('As an env variable', function () { + describe('As an env variable', function() { var cfg, logger; - before(function () { + before(function() { sterilizeEnv(); process.env.GCLOUD_PROJECT = oldEnv.STUBBED_PROJECT_NUM; logger = createLogger({logLevel: 5}); cfg = new Configuration({ignoreEnvironmentCheck: true}, logger); }); after(restoreEnv); - it('Should not throw on initialization', function (done) { + it('Should not throw on initialization', function(done) { this.timeout(10000); - assert.doesNotThrow(function () { + assert.doesNotThrow(function() { (new RequestHandler(cfg, logger)).sendError(errorMessage, - function (err, response, body) { + function(err, response, body) { assert.strictEqual(err, null); assert.strictEqual(response.statusCode, 200); assert(isObject(body) && isEmpty(body)); @@ -237,8 +237,8 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('Error behvaiour', function () { - describe('With a configuration to not report errors', function () { + 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', @@ -246,17 +246,17 @@ describe('Behvaiour acceptance testing', function () { 'to true in the runtime configuration object' ].join(' '); var logger, client; - before(function () { + before(function() { delete process.env.NODE_ENV; logger = createLogger({logLevel: 5}); client = new RequestHandler(new Configuration(undefined, logger), logger); }); - after(function () { + after(function() { process.env.NODE_ENV = oldEnv.NODE_ENV; }); - it('Should callback with an error', function (done) { - client.sendError({}, function (err, response, body) { + it('Should callback with an error', function(done) { + client.sendError({}, function(err, response, body) { assert(err instanceof Error); assert.strictEqual(err.message, ERROR_STRING); assert.strictEqual(body, null); @@ -265,7 +265,7 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('An invalid env configuration', function () { + describe('An invalid env configuration', function() { var ERROR_STRING = [ 'Unable to find the project Id for communication with the Stackdriver', 'Error Reporting service. This app will be unable to send errors to', @@ -273,17 +273,17 @@ describe('Behvaiour acceptance testing', function () { 'runtime configuration or the GCLOUD_PROJECT environmental variable.' ].join(' '); var logger, client; - before(function () { + before(function() { delete process.env.GCLOUD_PROJECT; logger = createLogger({logLevel: 5}); client = new RequestHandler(new Configuration( {ignoreEnvironmentCheck: true}, logger), logger); }); - after(function () { + after(function() { process.env.GCLOUD_PROJECT = oldEnv.GCLOUD_PROJECT; }); - it('Should callback with an error', function (done) { - client.sendError(errorMessage, function (err, response, body) { + it('Should callback with an error', function(done) { + client.sendError(errorMessage, function(err, response, body) { assert(err instanceof Error); assert.strictEqual(err.message, ERROR_STRING); assert.strictEqual(response, null); @@ -293,12 +293,12 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('Success behaviour', function () { + describe('Success behaviour', function() { var er = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); var em = new ErrorMessage().setMessage(er.stack); - describe('Given a valid project id', function () { + describe('Given a valid project id', function() { var logger, client, cfg; - before(function () { + before(function() { sterilizeEnv(); logger = createLogger({logLevel: 5}); cfg = new Configuration({ @@ -308,8 +308,8 @@ describe('Behvaiour acceptance testing', function () { client = new RequestHandler(cfg, logger); }); after(restoreEnv); - it('Should succeed in its request', function (done) { - client.sendError(em, function (err, response, body) { + 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)); @@ -318,10 +318,10 @@ describe('Behvaiour acceptance testing', function () { }); }); }); - describe('Given a valid project number', function () { + describe('Given a valid project number', function() { var logger, client, cfg; - before(function () { - forEach(oldEnv, function (val, key) { + before(function() { + forEach(oldEnv, function(val, key) { delete process.env[key]; }); logger = createLogger({logLevel: 5}); @@ -331,11 +331,11 @@ describe('Behvaiour acceptance testing', function () { }, logger); client = new RequestHandler(cfg, logger); }); - after(function () { + after(function() { assign(process.env, oldEnv); }); - it('Should succeed in its request', function (done) { - client.sendError(em, function (err, response, body) { + 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)); diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js index c19f2578097..1581f64295d 100644 --- a/packages/error-reporting/test/test-servers/express_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -30,7 +30,7 @@ var bodyParser = require('body-parser'); app.use(bodyParser.json()); -app.post('/testErrorHandling', function ( req, res, next ) { +app.post('/testErrorHandling', function( req, res, next ) { if ( has(req.body, 'test') && req.body.test !== true ) { @@ -45,10 +45,10 @@ app.post('/testErrorHandling', function ( req, res, next ) { ); app.get( - '/customError', function ( req, res, next ) { + '/customError', function( req, res, next ) { errorHandler.report( - 'Error on Express Custom Error GET Route', function ( err, res ) { + 'Error on Express Custom Error GET Route', function( err, res ) { if ( err ) { @@ -73,7 +73,7 @@ app.get( ); app.get( - '/getError', function ( req, res, next ) { + '/getError', function( req, res, next ) { return next(new Error('Error on Express Regular Error GET Route')); } @@ -89,7 +89,7 @@ function throwUncaughtError ( ) { function reportManualError ( ) { console.log('Reporting a manual error..'); errorHandler.report( - new Error('This is a manually reported error'), null, null, function ( err, res ) { + new Error('This is a manually reported error'), null, null, function( err, res ) { if ( err ) { @@ -125,7 +125,7 @@ errorHandler.report( app.listen( 3000, - function ( ) { + function( ) { console.log('Scaffold Server has been started on port 3000'); reportManualError(); } diff --git a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js index 6019e4baed6..ef7fb645713 100644 --- a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js @@ -32,14 +32,14 @@ server.start( ); server.route({ - method: 'GET', path: '/get', handler: function ( request, reply ) { + method: 'GET', path: '/get', handler: function( request, reply ) { console.log('Got a GET'); throw new Error('an error'); } }); server.route({ - method: 'POST', path: '/post', handler: function ( request, reply ) { + method: 'POST', path: '/post', handler: function( request, reply ) { console.log('Got a POST', request.payload); throw new Error('An error on the hapi post route'); } diff --git a/packages/error-reporting/test/test-servers/manual_scaffold_server.js b/packages/error-reporting/test/test-servers/manual_scaffold_server.js index 72aae1f0195..8d562296641 100644 --- a/packages/error-reporting/test/test-servers/manual_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/manual_scaffold_server.js @@ -27,10 +27,10 @@ errors.report('Sample test string', (err, response, body) => { var express = require('express'); var app = express(); -app.get('/', function (req, res) { +app.get('/', function(req, res) { res.send('Hello World!'); }); -app.listen(3000, function () { +app.listen(3000, function() { console.log('Example app listening on port 3000!'); }); diff --git a/packages/error-reporting/test/unit/testConfigCredentials.js b/packages/error-reporting/test/unit/testConfigCredentials.js index 3d4d1814da4..8ec1d2964cf 100644 --- a/packages/error-reporting/test/unit/testConfigCredentials.js +++ b/packages/error-reporting/test/unit/testConfigCredentials.js @@ -32,8 +32,8 @@ function reattachOriginalListeners() { var oldg, olde; -describe('Testing use of runtime configurations', function () { - before(function () { +describe('Testing use of runtime configurations', function() { + before(function() { nock.cleanAll(); nock.disableNetConnect(); process.removeAllListeners('uncaughtException'); @@ -42,16 +42,16 @@ describe('Testing use of runtime configurations', function () { delete process.env.GCLOUD_PROJECT; process.env.NODE_ENV = 'production'; }); - after(function () { + after(function() { nock.enableNetConnect(); process.env.GCLOUD_PROJECT = oldg; process.env.NODE_ENV = olde; }); - afterEach(function () { + afterEach(function() { nock.cleanAll(); process.removeAllListeners('uncaughtException'); }); - it('Should use the keyFilename field of the config object', function (done) { + it('Should use the keyFilename field of the config object', function(done) { this.timeout(25000); var credentials = require('../fixtures/gcloud-credentials.json'); var config = { @@ -76,22 +76,22 @@ describe('Testing use of runtime configurations', function () { }); describe( 'use of the credentials field of the config object', - function () { - before(function () { + function() { + before(function() { process.env.GCLOUD_PROJECT = '0'; }); - after(function () { + after(function() { delete process.env.GCLOUD_PROJECT; nock.cleanAll(); }); - it('Should use the credentials field of the config object', function (done) { + it('Should use the credentials field of the config object', function(done) { var config = { credentials: require('../fixtures/gcloud-credentials.json'), reportUncaughtExceptions: false }; var agent = new Errors(config); var app = express(); - app.use('/', function () { + app.use('/', function() { throw '0'; }); app.use(agent.express); @@ -125,7 +125,7 @@ describe('Testing use of runtime configurations', function () { }); } ); - it('Should ignore credentials if keyFilename is provided', function (done) { + it('Should ignore credentials if keyFilename is provided', function(done) { var correctCredentials = require('../fixtures/gcloud-credentials.json'); var config = { keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json'), @@ -138,7 +138,7 @@ describe('Testing use of runtime configurations', function () { }, reportUncaughtExceptions: true }; - ['client_id', 'client_secret', 'refresh_token'].forEach(function (field) { + ['client_id', 'client_secret', 'refresh_token'].forEach(function(field) { assert(correctCredentials.hasOwnProperty(field)); assert(config.credentials.hasOwnProperty(field)); assert.notEqual(config.credentials[field], @@ -146,7 +146,7 @@ describe('Testing use of runtime configurations', function () { }); var agent = new Errors(config); var app = express(); - app.use('/', function () { + app.use('/', function() { throw '0'; }); app.use(agent.express); diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index 6b62628467b..2f062631ef3 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -52,19 +52,19 @@ function createDeadMetadataService () { return nock(METADATA_URL).get('/project-id').times(1).reply(500); } -describe('Configuration class', function () { - before(function () {sterilizeEnv();}); - after(function () {restoreEnv();}); +describe('Configuration class', function() { + before(function() {sterilizeEnv();}); + after(function() {restoreEnv();}); describe( 'Initialization', - function () { + function() { var f = new Fuzzer(); var stubConfig = {test: true}; - describe('fuzzing the constructor', function () { - it('Should return default values', function () { + describe('fuzzing the constructor', function() { + it('Should return default values', function() { var c; f.fuzzFunctionForTypes( - function (givenConfigFuzz) { + function(givenConfigFuzz) { c = new Configuration(givenConfigFuzz, logger); assert.deepEqual(c._givenConfiguration, {}); }, @@ -72,102 +72,102 @@ describe('Configuration class', function () { ); }); }); - describe('valid config and default values', function () { + describe('valid config and default values', function() { var c; - before(function () {process.env.NODE_ENV = 'development';}); - after(function () {sterilizeEnv();}); - it('Should not throw with a valid configuration', function () { - assert.doesNotThrow(function () { + before(function() {process.env.NODE_ENV = 'development';}); + after(function() {sterilizeEnv();}); + it('Should not throw with a valid configuration', function() { + assert.doesNotThrow(function() { c = new Configuration(stubConfig, logger); }); }); - it('Should have a property reflecting the config argument', function () { + it('Should have a property reflecting the config argument', function() { assert.deepEqual(c._givenConfiguration, stubConfig); }); - it('Should reportUncaughtExceptions', function () { + it('Should reportUncaughtExceptions', function() { assert.strictEqual(c.getReportUncaughtExceptions(), true); }); - it('Should not reportUncaughtExceptions', function () { + it('Should not reportUncaughtExceptions', function() { assert.strictEqual(c.getShouldReportErrorsToAPI(), false); }); - it('Should not have a project id', function () { + it('Should not have a project id', function() { assert.strictEqual(c._projectId, null); }); - it('Should not have a key', function () { + it('Should not have a key', function() { assert.strictEqual(c.getKey(), null); }); - it('Should have a default service context', function () { + it('Should have a default service context', function() { assert.deepEqual(c.getServiceContext(), {service: 'node', version: undefined}); }); - it('Should have a version corresponding to package.json', function () { + it('Should have a version corresponding to package.json', function() { assert.strictEqual(c.getVersion(), version); }); }); - describe('with ignoreEnvironmentCheck', function () { + describe('with ignoreEnvironmentCheck', function() { var conf = merge({}, stubConfig, {ignoreEnvironmentCheck: true}); var c = new Configuration(conf, logger); - it('Should reportErrorsToAPI', function () { + it('Should reportErrorsToAPI', function() { assert.strictEqual(c.getShouldReportErrorsToAPI(), true); }); }); - describe('without ignoreEnvironmentCheck', function () { - describe('Exception behvaiour without proper resources', function () { + describe('without ignoreEnvironmentCheck', function() { + describe('Exception behvaiour without proper resources', function() { var c; - before(function () { + before(function() { sterilizeEnv(); c = new Configuration(stubConfig, logger); }); - after(function () {sterilizeEnv();}); - it('Should error without proper config resource', function (done) { + after(function() {sterilizeEnv();}); + it('Should error without proper config resource', function(done) { this.timeout(3500); - c.getProjectId(function (err, id) { + c.getProjectId(function(err, id) { assert(err instanceof Error); assert.strictEqual(id, null); done(); }); }); }); - describe('report behaviour with production env', function () { + describe('report behaviour with production env', function() { var c; - before(function () { + before(function() { sterilizeEnv(); process.env.NODE_ENV = 'production'; c = new Configuration(undefined, logger); }); - after(function () {sterilizeEnv();}); - it('Should reportErrorsToAPI', function () { + after(function() {sterilizeEnv();}); + it('Should reportErrorsToAPI', function() { assert.strictEqual(c.getShouldReportErrorsToAPI(), true); }); }); - describe('exception behaviour', function () { - it('Should throw if invalid type for reportUncaughtExceptions', function () { - assert.throws(function () { + describe('exception behaviour', function() { + it('Should throw if invalid type for reportUncaughtExceptions', function() { + assert.throws(function() { new Configuration({reportUncaughtExceptions: 1}, logger); }); }); - it('Should throw if invalid type for key', function () { - assert.throws(function () { + it('Should throw if invalid type for key', function() { + assert.throws(function() { new Configuration({key: null}, logger); }); }); - it('Should throw if invalid type for ignoreEnvironmentCheck', function () { - assert.throws(function () { + it('Should throw if invalid type for ignoreEnvironmentCheck', function() { + assert.throws(function() { new Configuration({ignoreEnvironmentCheck: null}, logger); }); }); - it('Should throw if invalid type for serviceContext.service', function () { - assert.throws(function () { + it('Should throw if invalid type for serviceContext.service', function() { + assert.throws(function() { new Configuration({serviceContext: {service: false}}, logger); }); }); - it('Should throw if invalid type for serviceContext.version', function () { - assert.throws(function () { + it('Should throw if invalid type for serviceContext.version', function() { + assert.throws(function() { new Configuration({serviceContext: {version: true}}, logger); }); }); - it('Should not throw given an empty object for serviceContext', function () { - assert.doesNotThrow(function () { + it('Should not throw given an empty object for serviceContext', function() { + assert.doesNotThrow(function() { new Configuration({serviceContext: {}}, logger); }); }); @@ -175,35 +175,35 @@ describe('Configuration class', function () { }); } ); - describe('Configuration resource aquisition', function () { - before(function () {sterilizeEnv();}); - describe('project id from configuration instance', function () { + describe('Configuration resource aquisition', function() { + before(function() {sterilizeEnv();}); + describe('project id from configuration instance', function() { var pi = 'test'; var serve, c; - before(function () { + before(function() { serve = createDeadMetadataService(); c = new Configuration({projectId: pi}, logger); }); - after(function () {nock.cleanAll();}); - it('Should return the project id', function (done) { - c.getProjectId(function (err, id) { + after(function() {nock.cleanAll();}); + it('Should return the project id', function(done) { + c.getProjectId(function(err, id) { assert.strictEqual(err, null); assert.strictEqual(id, pi); done(); }); }); }); - describe('project number from configuration instance', function () { + describe('project number from configuration instance', function() { var pn = 1234; var serve, c; - before(function () { + before(function() { sterilizeEnv(); serve = createDeadMetadataService(); c = new Configuration({projectId: pn}, logger); }); - after(function () {nock.cleanAll(); sterilizeEnv();}); - it('Should return the project number', function (done) { - c.getProjectId(function (err, id) { + after(function() {nock.cleanAll(); sterilizeEnv();}); + it('Should return the project number', function(done) { + c.getProjectId(function(err, id) { assert.strictEqual(err, null); assert.strictEqual(pn.toString(), id); done(); @@ -211,39 +211,39 @@ describe('Configuration class', function () { }); }); }); - describe('Exception behaviour', function () { - describe('While lacking a project id', function () { + describe('Exception behaviour', function() { + describe('While lacking a project id', function() { var serve, c; - before(function () { + before(function() { sterilizeEnv(); serve = createDeadMetadataService(); c = new Configuration(undefined, logger); }); - after(function () { + after(function() { nock.cleanAll(); sterilizeEnv(); }); - it('Should error', function (done) { - c.getProjectId(function (err, id) { + it('Should error', function(done) { + c.getProjectId(function(err, id) { assert(err instanceof Error); assert.strictEqual(id, null); done(); }); }); }); - describe('Invalid type for projectId in runtime config', function () { + describe('Invalid type for projectId in runtime config', function() { var serve, c; - before(function () { + before(function() { sterilizeEnv(); serve = createDeadMetadataService(); c = new Configuration({projectId: null}, logger); }); - after(function () { + after(function() { nock.cleanAll(); sterilizeEnv(); }); - it('Should error', function (done) { - c.getProjectId(function (err, id) { + it('Should error', function(done) { + c.getProjectId(function(err, id) { assert(err instanceof Error); assert.strictEqual(id, null); done(); @@ -251,8 +251,8 @@ describe('Configuration class', function () { }); }); }); - describe('Resource aquisition', function () { - after(function () { + describe('Resource aquisition', function() { + after(function() { /* * !! IMPORTANT !! * THE restoreEnv FUNCTION SHOULD BE CALLED LAST AS THIS TEST FILE EXITS @@ -261,102 +261,102 @@ describe('Configuration class', function () { */ restoreEnv(); }); - describe('via env', function () { + describe('via env', function() { before(function() {sterilizeEnv();}); - afterEach(function () {sterilizeEnv();}); - describe('projectId', function () { + afterEach(function() {sterilizeEnv();}); + describe('projectId', function() { var c; var projectId = 'test-xyz'; - before(function () { + before(function() { process.env.GCLOUD_PROJECT = projectId; c = new Configuration(undefined, logger); }); - it('Should assign', function (done) { - c.getProjectId(function (err, id) { + it('Should assign', function(done) { + c.getProjectId(function(err, id) { assert.strictEqual(err, null); assert.strictEqual(id, projectId); done(); }); }); }); - describe('serviceContext', function () { + describe('serviceContext', function() { var c; var projectId = 'test-abc'; var serviceContext = { service: 'test', version: '1.x' }; - before(function () { + before(function() { process.env.GCLOUD_PROJECT = projectId; process.env.GAE_MODULE_NAME = serviceContext.service; process.env.GAE_MODULE_VERSION = serviceContext.version; c = new Configuration(undefined, logger); }); - it('Should assign', function () { + it('Should assign', function() { assert.deepEqual(c.getServiceContext(), serviceContext); }); }); }); - describe('via runtime configuration', function () { - before(function () {sterilizeEnv();}); - describe('serviceContext', function () { + describe('via runtime configuration', function() { + before(function() {sterilizeEnv();}); + describe('serviceContext', function() { var c; var projectId = 'xyz123'; var serviceContext = { service: 'evaluation', version: '2.x' }; - before(function () { + before(function() { c = new Configuration({ projectId: projectId, serviceContext: serviceContext }); }); - it('Should assign', function () { + it('Should assign', function() { assert.deepEqual(c.getServiceContext(), serviceContext); }); }); - describe('api key', function () { + describe('api key', function() { var c; var projectId = '987abc'; var key = '1337-api-key'; - before(function () { + before(function() { c = new Configuration({ key: key, projectId: projectId }, logger); }); - it('Should assign', function () { + it('Should assign', function() { assert.strictEqual(c.getKey(), key); }); }); - describe('reportUncaughtExceptions', function () { + describe('reportUncaughtExceptions', function() { var c; var projectId = '123-xyz'; var reportUncaughtExceptions = false; - before(function () { + before(function() { c = new Configuration({ projectId: projectId, reportUncaughtExceptions: reportUncaughtExceptions }); }); - it('Should assign', function () { + it('Should assign', function() { assert.strictEqual(c.getReportUncaughtExceptions(), reportUncaughtExceptions); }); }); }); - describe('via the metadata service', function () { - before(function () {sterilizeEnv();}); - describe('project id', function () { + describe('via the metadata service', function() { + before(function() {sterilizeEnv();}); + describe('project id', function() { var serve, c; var id = '6789'; - before(function () { + before(function() { serve = nock(METADATA_URL).get('/project-id').times(1).reply(200, id); c = new Configuration(undefined, logger); }); - it('Should assign', function (done) { - c.getProjectId(function (err, projectId) { + it('Should assign', function(done) { + c.getProjectId(function(err, projectId) { assert.strictEqual(err, null); assert.strictEqual(id, projectId); assert(serve.isDone()); diff --git a/packages/error-reporting/test/unit/testCustomStackTrace.js b/packages/error-reporting/test/unit/testCustomStackTrace.js index f7cc818c33d..ddee5867cc7 100644 --- a/packages/error-reporting/test/unit/testCustomStackTrace.js +++ b/packages/error-reporting/test/unit/testCustomStackTrace.js @@ -18,13 +18,13 @@ var assert = require('assert'); var CustomStackTrace = require('../../src/classes/custom-stack-trace.js'); -describe('Fuzzing the CustomStackTrace class', function () { +describe('Fuzzing the CustomStackTrace class', function() { var testFunction = function testFunction () { return ''; }; var cs; - beforeEach(function () { cs = new CustomStackTrace(); }); - it('Should accept value for file path', function () { + beforeEach(function() { cs = new CustomStackTrace(); }); + it('Should accept value for file path', function() { cs.setFilePath('test'); assert( cs.filePath === 'test', @@ -32,7 +32,7 @@ describe('Fuzzing the CustomStackTrace class', function () { 'should result in assignment' ); }); - it('Should reject invalid type for file path', function () { + it('Should reject invalid type for file path', function() { cs.setFilePath(null); assert( cs.filePath === '', @@ -40,7 +40,7 @@ describe('Fuzzing the CustomStackTrace class', function () { 'should result in default value of an empty string' ); }); - it('Should accept value for line number', function () { + it('Should accept value for line number', function() { cs.setLineNumber(10); assert( cs.lineNumber === 10, @@ -48,7 +48,7 @@ describe('Fuzzing the CustomStackTrace class', function () { 'should result in assignment' ); }); - it('Should reject invalid type for line number', function () { + it('Should reject invalid type for line number', function() { cs.setLineNumber('10'); assert( cs.lineNumber === 0, @@ -56,7 +56,7 @@ describe('Fuzzing the CustomStackTrace class', function () { 'should result in default value of number 0' ); }); - it('Should accept value for call list', function () { + it('Should accept value for call list', function() { cs.setStringifyStructuredCallList(testFunction); assert.strictEqual( cs.stringifyStucturedCallList, @@ -65,7 +65,7 @@ describe('Fuzzing the CustomStackTrace class', function () { 'setStringifyStructuredCallList should result in assignment' ); }); - it('Should reject incalid value for call list', function () { + it('Should reject incalid value for call list', function() { cs.setStringifyStructuredCallList(null); assert( ((typeof cs.setStringifyStructuredCallList) === 'function'), diff --git a/packages/error-reporting/test/unit/testErrorMessage.js b/packages/error-reporting/test/unit/testErrorMessage.js index 8a968865c87..04368252807 100644 --- a/packages/error-reporting/test/unit/testErrorMessage.js +++ b/packages/error-reporting/test/unit/testErrorMessage.js @@ -19,20 +19,20 @@ var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); -describe('Instantiating a new ErrorMessage', function () { +describe('Instantiating a new ErrorMessage', function() { var em; - beforeEach(function () {em = new ErrorMessage();}); + beforeEach(function() {em = new ErrorMessage();}); - it('Should have a default service context', function () { + it('Should have a default service context', function() { assert.deepEqual( em.serviceContext, { service: 'node', version: undefined } ); }); - it('Should have a default message', function () { + it('Should have a default message', function() { assert.strictEqual(em.message, ''); }); - it('Should have a default http context', function () { + it('Should have a default http context', function() { assert.deepEqual( em.context.httpRequest, { @@ -45,7 +45,7 @@ describe('Instantiating a new ErrorMessage', function () { } ); }); - it('Should have a default reportLocation', function () { + it('Should have a default reportLocation', function() { assert.deepEqual( em.context.reportLocation, { @@ -57,24 +57,24 @@ describe('Instantiating a new ErrorMessage', function () { }) }); -describe('Calling against setEventTimeToNow', function () { +describe('Calling against setEventTimeToNow', function() { var em; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set the eventTime property', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set the eventTime property', function() { em.setEventTimeToNow(); assert((typeof em.eventTime) === 'string'); }); }); -describe('Fuzzing against setServiceContext', function () { +describe('Fuzzing against setServiceContext', function() { var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var DEFAULT_TEST_VALUE = 'DEFAULT'; var DEFAULT_VERSION_VALUE = undefined; var DEFAULT_SERVICE_VALUE = 'node'; var em; - beforeEach(function () {em = new ErrorMessage()}); + beforeEach(function() {em = new ErrorMessage()}); - it('Should set the value for service context', function () { + it('Should set the value for service context', function() { em.setServiceContext(AFFIRMATIVE_TEST_VALUE, AFFIRMATIVE_TEST_VALUE); assert.deepEqual( em.serviceContext @@ -88,7 +88,7 @@ describe('Fuzzing against setServiceContext', function () { ].join(' ') ); }); - it('Should set the default values', function () { + it('Should set the default values', function() { em.setServiceContext(DEFAULT_TEST_VALUE, DEFAULT_TEST_VALUE); assert.deepEqual( em.serviceContext @@ -102,7 +102,7 @@ describe('Fuzzing against setServiceContext', function () { ].join(' ') ); }); - it('Should still set version with affirmative value', function () { + it('Should still set version with affirmative value', function() { em.setServiceContext(null, AFFIRMATIVE_TEST_VALUE); assert.deepEqual( em.serviceContext @@ -117,7 +117,7 @@ describe('Fuzzing against setServiceContext', function () { ].join(' ') ); }); - it('Should still set service with affirmative value', function () { + it('Should still set service with affirmative value', function() { em.setServiceContext(AFFIRMATIVE_TEST_VALUE, null); assert.deepEqual( em.serviceContext @@ -132,7 +132,7 @@ describe('Fuzzing against setServiceContext', function () { ].join(' ') ); }); - it('Should set default values on both', function () { + it('Should set default values on both', function() { em.setServiceContext(null, null); assert.deepEqual( em.serviceContext @@ -146,7 +146,7 @@ describe('Fuzzing against setServiceContext', function () { ].join(' ') ); }); - it('Should set default values on both', function () { + it('Should set default values on both', function() { em.setServiceContext(2, 1.3); assert.deepEqual( em.serviceContext @@ -160,7 +160,7 @@ describe('Fuzzing against setServiceContext', function () { ].join(' ') ); }); - it('Should set as default', function () { + it('Should set as default', function() { em.setServiceContext({ test: 'true' }, []); assert.deepEqual( em.serviceContext @@ -174,7 +174,7 @@ describe('Fuzzing against setServiceContext', function () { ].join(' ') ); }); - it('Should set as default', function () { + it('Should set as default', function() { em.setServiceContext(); assert.deepEqual( em.serviceContext @@ -189,13 +189,13 @@ describe('Fuzzing against setServiceContext', function () { describe( 'Fuzzing against setMessage', - function () { + function() { var em; - beforeEach(function () {em = new ErrorMessage()}); + beforeEach(function() {em = new ErrorMessage()}); var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - it('Should set the message', function () { + it('Should set the message', function() { em.setMessage(AFFIRMATIVE_TEST_VALUE); assert( em.message === AFFIRMATIVE_TEST_VALUE @@ -205,7 +205,7 @@ describe( ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setMessage(); assert( em.message === NEGATIVE_TEST_VALUE @@ -220,12 +220,12 @@ describe( describe( 'Fuzzing against setHttpMethod', - function () { + function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set the method', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set the method', function() { em.setHttpMethod(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.method === AFFIRMATIVE_TEST_VALUE @@ -235,7 +235,7 @@ describe( ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setHttpMethod(); assert( em.context.httpRequest.method === NEGATIVE_TEST_VALUE @@ -250,12 +250,12 @@ describe( describe( 'Fuzzing against setUrl', - function () { + function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set url', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set url', function() { em.setUrl(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.url === AFFIRMATIVE_TEST_VALUE @@ -265,7 +265,7 @@ describe( ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setUrl(); assert( em.context.httpRequest.url === NEGATIVE_TEST_VALUE @@ -281,12 +281,12 @@ describe( describe( 'Fuzzing against setUserAgent', - function () { + function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set userAgent', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set userAgent', function() { em.setUserAgent(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.userAgent === AFFIRMATIVE_TEST_VALUE @@ -296,7 +296,7 @@ describe( ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setUserAgent(); assert( em.context.httpRequest.userAgent === NEGATIVE_TEST_VALUE @@ -309,12 +309,12 @@ describe( } ); -describe('Fuzzing against setReferrer', function () { +describe('Fuzzing against setReferrer', function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set referrer', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set referrer', function() { em.setReferrer(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.referrer === AFFIRMATIVE_TEST_VALUE @@ -324,7 +324,7 @@ describe('Fuzzing against setReferrer', function () { ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setReferrer(); assert( em.context.httpRequest.referrer === NEGATIVE_TEST_VALUE @@ -336,12 +336,12 @@ describe('Fuzzing against setReferrer', function () { }); }); -describe('Fuzzing against setResponseStatusCode', function () { +describe('Fuzzing against setResponseStatusCode', function() { var em; var AFFIRMATIVE_TEST_VALUE = 200; var NEGATIVE_TEST_VALUE = 0; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set responseStatusCode', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set responseStatusCode', function() { em.setResponseStatusCode(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.responseStatusCode === AFFIRMATIVE_TEST_VALUE @@ -351,7 +351,7 @@ describe('Fuzzing against setResponseStatusCode', function () { ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setResponseStatusCode(); assert( em.context.httpRequest.responseStatusCode === NEGATIVE_TEST_VALUE @@ -363,12 +363,12 @@ describe('Fuzzing against setResponseStatusCode', function () { }); }); -describe('Fuzzing against setRemoteIp', function () { +describe('Fuzzing against setRemoteIp', function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set remoteIp', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set remoteIp', function() { em.setRemoteIp(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.remoteIp === AFFIRMATIVE_TEST_VALUE @@ -378,7 +378,7 @@ describe('Fuzzing against setRemoteIp', function () { ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setRemoteIp(); assert( em.context.httpRequest.remoteIp === NEGATIVE_TEST_VALUE @@ -392,12 +392,12 @@ describe('Fuzzing against setRemoteIp', function () { describe( 'Fuzzing against setUser', - function () { + function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set user', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set user', function() { em.setUser(AFFIRMATIVE_TEST_VALUE); assert( em.context.user === AFFIRMATIVE_TEST_VALUE @@ -407,7 +407,7 @@ describe( ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setUser(); assert( em.context.user === NEGATIVE_TEST_VALUE @@ -420,12 +420,12 @@ describe( } ); -describe('Fuzzing against setFilePath', function () { +describe('Fuzzing against setFilePath', function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set filePath', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set filePath', function() { em.setFilePath(AFFIRMATIVE_TEST_VALUE); assert( em.context.reportLocation.filePath === AFFIRMATIVE_TEST_VALUE @@ -435,7 +435,7 @@ describe('Fuzzing against setFilePath', function () { ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setFilePath(); assert( em.context.reportLocation.filePath === NEGATIVE_TEST_VALUE @@ -447,12 +447,12 @@ describe('Fuzzing against setFilePath', function () { }); }); -describe('Fuzzing against setLineNumber', function () { +describe('Fuzzing against setLineNumber', function() { var em; var AFFIRMATIVE_TEST_VALUE = 27; var NEGATIVE_TEST_VALUE = 0; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set lineNumber', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set lineNumber', function() { em.setLineNumber(AFFIRMATIVE_TEST_VALUE); assert( em.context.reportLocation.lineNumber === AFFIRMATIVE_TEST_VALUE @@ -462,7 +462,7 @@ describe('Fuzzing against setLineNumber', function () { ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setLineNumber(); assert( em.context.reportLocation.lineNumber === NEGATIVE_TEST_VALUE @@ -474,12 +474,12 @@ describe('Fuzzing against setLineNumber', function () { }); }); -describe('Fuzzing against setFunctionName', function () { +describe('Fuzzing against setFunctionName', function() { var em; var AFFIRMATIVE_TEST_VALUE = 'VALID_INPUT_AND_TYPE'; var NEGATIVE_TEST_VALUE = ''; - beforeEach(function () {em = new ErrorMessage()}); - it('Should set functionName', function () { + beforeEach(function() {em = new ErrorMessage()}); + it('Should set functionName', function() { em.setFunctionName(AFFIRMATIVE_TEST_VALUE); assert( em.context.reportLocation.functionName === AFFIRMATIVE_TEST_VALUE @@ -489,7 +489,7 @@ describe('Fuzzing against setFunctionName', function () { ].join(' ') ); }); - it('Should default', function () { + it('Should default', function() { em.setFunctionName(); assert( em.context.reportLocation.functionName === NEGATIVE_TEST_VALUE @@ -501,7 +501,7 @@ describe('Fuzzing against setFunctionName', function () { }); }); -describe('Fuzzing against consumeRequestInformation', function () { +describe('Fuzzing against consumeRequestInformation', function() { var em = new ErrorMessage(); var A_VALID_STRING = 'A_VALID_STRING'; var A_VALID_NUMBER = 201; @@ -524,7 +524,7 @@ describe('Fuzzing against consumeRequestInformation', function () { , statusCode: A_VALID_STRING , remoteAddress: undefined }; - it('Should consume the stubbed request object', function () { + it('Should consume the stubbed request object', function() { em.consumeRequestInformation(AFFIRMATIVE_TEST_VALUE); assert( em.context.httpRequest.method === A_VALID_STRING @@ -569,7 +569,7 @@ describe('Fuzzing against consumeRequestInformation', function () { ].join(' ') ); }); - it('Should default when consuming a malformed request object', function () { + it('Should default when consuming a malformed request object', function() { em.consumeRequestInformation(null); assert( em.context.httpRequest.method === A_VALID_STRING @@ -615,7 +615,7 @@ describe('Fuzzing against consumeRequestInformation', function () { ); }); it('Should default when consuming mistyped response object properties', - function () { + function() { em.consumeRequestInformation(NEGATIVE_TEST_VALUE); assert( em.context.httpRequest.method === NEGATIVE_STRING_CASE @@ -662,7 +662,7 @@ describe('Fuzzing against consumeRequestInformation', function () { } ); it('Should return the instance on calling consumeRequestInformation', - function () { + function() { assert( em.consumeRequestInformation(AFFIRMATIVE_TEST_VALUE) instanceof ErrorMessage , [ diff --git a/packages/error-reporting/test/unit/testExpressInterface.js b/packages/error-reporting/test/unit/testExpressInterface.js index 8d04fc544cd..5a032c19cd1 100644 --- a/packages/error-reporting/test/unit/testExpressInterface.js +++ b/packages/error-reporting/test/unit/testExpressInterface.js @@ -24,13 +24,13 @@ var Fuzzer = require('../../utils/fuzzer.js'); var Configuration = require('../fixtures/configuration.js'); var createLogger = require('../../src/logger.js'); -describe('expressInterface', function () { - describe('Exception handling', function () { - describe('Given invalid input', function () { - it('Should not throw errors', function () { +describe('expressInterface', function() { + describe('Exception handling', function() { + describe('Given invalid input', function() { + it('Should not throw errors', function() { var f = new Fuzzer(); assert.doesNotThrow( - function () { + function() { f.fuzzFunctionForTypes( expressInterface, ['object', 'object'] ); @@ -40,23 +40,23 @@ describe('expressInterface', function () { }); }); }); - describe('Intended behaviour', function () { + describe('Intended behaviour', function() { var stubbedConfig = new Configuration({ serviceContext: { service: 'a_test_service', version: 'a_version' } }, createLogger({logLevel: 4})); - stubbedConfig.lacksCredentials = function () { + stubbedConfig.lacksCredentials = function() { return false; }; var client = { - sendError: function () { + sendError: function() { return; } }; var testError = new Error('This is a test'); var validBoundHandler = expressInterface(client, stubbedConfig); - it('Should return the error message', function () { + it('Should return the error message', function() { var res = validBoundHandler(testError, null, null, null); assert.deepEqual( res, @@ -68,22 +68,22 @@ describe('expressInterface', function () { ) ); }); - describe('Calling back to express builtins', function () { - it('Should callback to next', function (done) { - var nextCb = function () { + describe('Calling back to express builtins', function() { + it('Should callback to next', function(done) { + var nextCb = function() { done(); }; validBoundHandler(testError, null, null, nextCb); }); - it('Should callback to sendError', function (done) { - var sendError = function () { + it('Should callback to sendError', function(done) { + var sendError = function() { done(); }; var client = { sendError: sendError }; var handler = expressInterface(client, stubbedConfig); - handler(testError, null, null, function (){return;}); + handler(testError, null, null, function(){return;}); }); }); }); diff --git a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js index e49c70582e3..1ddfd4bd702 100644 --- a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js @@ -23,7 +23,7 @@ var Fuzzer = require('../../utils/fuzzer.js'); var extend = require('extend'); describe('Behaviour under varying input', - function () { + function() { var f; var DEFAULT_RETURN_VALUE = { method: '', @@ -33,15 +33,15 @@ describe('Behaviour under varying input', statusCode: 0, remoteAddress: '' }; - beforeEach(function () {f = new Fuzzer();}); - it('Should return a default value given invalid input', function () { - var cbFn = function (value) { + beforeEach(function() {f = new Fuzzer();}); + it('Should return a default value given invalid input', function() { + var cbFn = function(value) { assert.deepEqual(value, DEFAULT_RETURN_VALUE); }; f.fuzzFunctionForTypes(expressRequestInformationExtractor, ['object', 'object'], cbFn); }); - it('Should return valid request object given valid input', function () { + it('Should return valid request object given valid input', function() { var FULL_REQ_DERIVATION_VALUE = { method: 'STUB_METHOD', url: 'www.TEST-URL.com', @@ -102,9 +102,9 @@ describe('Behaviour under varying input', remoteAddress: '', statusCode: 201 }; - var headerFactory = function (toDeriveFrom) { + var headerFactory = function(toDeriveFrom) { var lrn = extend({}, toDeriveFrom); - lrn.header = function ( toRet ) { + lrn.header = function( toRet ) { if (lrn.hasOwnProperty(toRet)) { return lrn[toRet]; } diff --git a/packages/error-reporting/test/unit/testExtractFromErrorClass.js b/packages/error-reporting/test/unit/testExtractFromErrorClass.js index f5435d2f5a3..0b8d9e65d84 100644 --- a/packages/error-reporting/test/unit/testExtractFromErrorClass.js +++ b/packages/error-reporting/test/unit/testExtractFromErrorClass.js @@ -21,9 +21,9 @@ var extractFromErrorClass = require('../../src/error-extractors/error.js'); var ErrorMessage = require('../../src/classes/error-message.js'); -describe('Writing and reading ErrorMessage properties', function () { - describe('Message field', function () { - it('Should set the message as the stack of the given error', function () { +describe('Writing and reading ErrorMessage properties', function() { + describe('Message field', function() { + it('Should set the message as the stack of the given error', function() { var TEST_MESSAGE = 'This is a test'; var em = new ErrorMessage(); var err = new Error(TEST_MESSAGE); @@ -33,61 +33,61 @@ describe('Writing and reading ErrorMessage properties', function () { ); }); }); - describe('User field', function () { + describe('User field', function() { var em, err; var TEST_USER_INVALID = 12; - beforeEach(function () { + beforeEach(function() { em = new ErrorMessage(); err = new Error(); }); - it('Should set the user field if given valid input', function () { + it('Should set the user field if given valid input', function() { var TEST_USER_VALID = 'TEST_USER'; err.user = TEST_USER_VALID; extractFromErrorClass(err, em); assert.strictEqual(em.context.user, TEST_USER_VALID); }); - it('Should default the user field if given invalid input', function () { + it('Should default the user field if given invalid input', function() { err.user = TEST_USER_INVALID; extractFromErrorClass(err, em); assert.strictEqual(em.context.user, ''); }); }); - describe('Service field', function () { + describe('Service field', function() { var em, err; var TEST_SERVICE_DEFAULT = {service: 'node', version: undefined}; - beforeEach(function () { + beforeEach(function() { em = new ErrorMessage(); err = new Error(); }); - it('Should set the field if given valid input', function () { + it('Should set the field if given valid input', function() { var TEST_SERVICE_VALID = {service: 'test', version: 'test'}; err.serviceContext = TEST_SERVICE_VALID; extractFromErrorClass(err, em); assert.deepEqual(err.serviceContext, TEST_SERVICE_VALID); }); - it('Should default the field if given invalid input', function () { + it('Should default the field if given invalid input', function() { var TEST_SERVICE_INVALID = 12; err.serviceContext = TEST_SERVICE_INVALID; extractFromErrorClass(err, em); assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); }); - it('Should default the field if not given input', function () { + it('Should default the field if not given input', function() { extractFromErrorClass(err, em); assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); }); }); - describe('Report location field', function () { + describe('Report location field', function() { var em, err; var TEST_STACK_DEFAULT = { filePath: '', lineNumber: 0, functionName: '' }; - beforeEach(function () { + beforeEach(function() { em = new ErrorMessage(); err = new Error(); }); - it('Should default the field if given invalid input', function () { + it('Should default the field if given invalid input', function() { var TEST_STACK_INVALID_CONTENTS = { filePath: null, lineNumber: '2', @@ -97,7 +97,7 @@ describe('Writing and reading ErrorMessage properties', function () { extractFromErrorClass(err, em); assert.deepEqual(em.context.reportLocation, TEST_STACK_DEFAULT); }); - it('Should default field if not given a valid type', function () { + it('Should default field if not given a valid type', function() { var TEST_STACK_INVALID_TYPE = []; err.stack = TEST_STACK_INVALID_TYPE; extractFromErrorClass(err, em); diff --git a/packages/error-reporting/test/unit/testExtractFromObject.js b/packages/error-reporting/test/unit/testExtractFromObject.js index c2cb546c4d6..58c75ae6a3e 100644 --- a/packages/error-reporting/test/unit/testExtractFromObject.js +++ b/packages/error-reporting/test/unit/testExtractFromObject.js @@ -20,87 +20,87 @@ var assert = require('assert'); var extractFromObject = require('../../src/error-extractors/object.js'); var ErrorMessage = require('../../src/classes/error-message.js'); -describe('Object value extraction as error message', function () { +describe('Object value extraction as error message', function() { var em, err; - beforeEach(function () { + beforeEach(function() { em = new ErrorMessage(); err = {}; }); - describe('Message field', function () { - it('Should write to the field given valid input', function () { + describe('Message field', function() { + it('Should write to the field given valid input', function() { var MESSAGE = 'test'; err = {message: MESSAGE}; extractFromObject(err, em); assert.strictEqual(em.message, MESSAGE); }); - it('Should default the field given lack-of input', function () { + it('Should default the field given lack-of input', function() { extractFromObject(err, em); assert.strictEqual(em.message, ''); }); }); - describe('User field', function () { - it('Should write to the field given valid input', function () { + describe('User field', function() { + it('Should write to the field given valid input', function() { var USER = 'test'; err.user = USER; extractFromObject(err, em); assert.strictEqual(em.context.user, USER); }); - it('Should default the field given lack-of input', function () { + it('Should default the field given lack-of input', function() { extractFromObject(err, em); assert.strictEqual(em.context.user, ''); }); }); - describe('filePath field', function () { - it('Should write to the field given valid input', function () { + describe('filePath field', function() { + it('Should write to the field given valid input', function() { var PATH = 'test'; err.filePath = PATH; extractFromObject(err, em); assert.strictEqual(em.context.reportLocation.filePath, PATH); }); - it('Should default the field given lack-of input', function () { + it('Should default the field given lack-of input', function() { extractFromObject(err, em); assert.strictEqual(em.context.reportLocation.filePath, ''); }); }); - describe('lineNumber field', function () { - it('Should write to the field given valid input', function () { + describe('lineNumber field', function() { + it('Should write to the field given valid input', function() { var LINE_NUMBER = 10; err.lineNumber = LINE_NUMBER; extractFromObject(err, em); assert.strictEqual(em.context.reportLocation.lineNumber, LINE_NUMBER); }); - it('Should default the field given lack-of input', function () { + it('Should default the field given lack-of input', function() { extractFromObject(err, em); assert.strictEqual(em.context.reportLocation.lineNumber, 0); }); }); - describe('functionName field', function () { - it('Should write to the field given valid input', function () { + describe('functionName field', function() { + it('Should write to the field given valid input', function() { var FUNCTION_NAME = 'test'; err.functionName = FUNCTION_NAME; extractFromObject(err, em); assert.strictEqual(em.context.reportLocation.functionName, FUNCTION_NAME); }); - it('Should default the field given lack-of input', function () { + it('Should default the field given lack-of input', function() { extractFromObject(err, em); assert.strictEqual(em.context.reportLocation.functionName, ''); }); }); - describe('serviceContext field', function () { + describe('serviceContext field', function() { var TEST_SERVICE_DEFAULT = {service: 'node', version: undefined}; - it('Should write to the field given valid input', function () { + it('Should write to the field given valid input', function() { var TEST_SERVICE_VALID = {service: 'test', version: 'test'}; err.serviceContext = TEST_SERVICE_VALID; extractFromObject(err, em); assert.deepEqual(em.serviceContext, TEST_SERVICE_VALID); }); - it('Should default the field given invalid input', function () { + it('Should default the field given invalid input', function() { var TEST_SERVICE_INVALID = 12; err.serviceContext = TEST_SERVICE_INVALID; extractFromObject(err, em); assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); }); - it('Should default the field given lack-of input', function () { + it('Should default the field given lack-of input', function() { extractFromObject(err, em); assert.deepEqual(em.serviceContext, TEST_SERVICE_DEFAULT); }); diff --git a/packages/error-reporting/test/unit/testHandleErrorClassError.js b/packages/error-reporting/test/unit/testHandleErrorClassError.js index 2e304af3975..ba1ce9f5575 100644 --- a/packages/error-reporting/test/unit/testHandleErrorClassError.js +++ b/packages/error-reporting/test/unit/testHandleErrorClassError.js @@ -20,7 +20,7 @@ var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleErrorClassError = require('../../src/error-handlers/error.js'); -describe('Behaviour under various type inputs', function () { +describe('Behaviour under various type inputs', function() { var em; var adversarialObjectInput = { stack: {} @@ -28,29 +28,29 @@ describe('Behaviour under various type inputs', function () { var adversarialObjectInputTwo = { stack: [] }; - beforeEach(function () {em = new ErrorMessage();}); - it('Should not throw given undefined', function () { + beforeEach(function() {em = new ErrorMessage();}); + it('Should not throw given undefined', function() { assert.doesNotThrow(handleErrorClassError.bind(null, undefined, em)); }); - it('Should not throw given null', function () { + it('Should not throw given null', function() { assert.doesNotThrow(handleErrorClassError.bind(null, null, em)); }); - it('Should not throw given a string', function () { + it('Should not throw given a string', function() { assert.doesNotThrow(handleErrorClassError.bind(null, 'string_test', em)); }); - it('Should not throw given a number', function () { + it('Should not throw given a number', function() { assert.doesNotThrow(handleErrorClassError.bind(null, 1.2, em)); }); - it('Should not throw given an array', function () { + it('Should not throw given an array', function() { assert.doesNotThrow(handleErrorClassError.bind(null, [], em)); }); - it('Should not throw given an object of invalid form', function () { + it('Should not throw given an object of invalid form', function() { assert.doesNotThrow( handleErrorClassError.bind(null, adversarialObjectInput, em)); assert.doesNotThrow( handleErrorClassError.bind(null, adversarialObjectInputTwo, em)); }); - it('Should not throw given valid input', function () { + it('Should not throw given valid input', function() { assert.doesNotThrow(handleErrorClassError.bind(null, new Error(), em)); }); }); diff --git a/packages/error-reporting/test/unit/testHandleNumberAsError.js b/packages/error-reporting/test/unit/testHandleNumberAsError.js index a3bfbe52368..89a3198a441 100644 --- a/packages/error-reporting/test/unit/testHandleNumberAsError.js +++ b/packages/error-reporting/test/unit/testHandleNumberAsError.js @@ -20,25 +20,25 @@ var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleNumberAsError = require('../../src/error-handlers/number.js'); -describe('handleNumberAsError behaviour under varying input', function () { +describe('handleNumberAsError behaviour under varying input', function() { var em; - beforeEach(function () {em = new ErrorMessage();}); - it('Should not throw given undefined', function () { + beforeEach(function() {em = new ErrorMessage();}); + it('Should not throw given undefined', function() { assert.doesNotThrow(handleNumberAsError.bind(null, undefined, em)); }); - it('Should not throw given null', function () { + it('Should not throw given null', function() { assert.doesNotThrow(handleNumberAsError.bind(null, null, em)); }); - it('Should not throw given a string', function () { + it('Should not throw given a string', function() { assert.doesNotThrow(handleNumberAsError.bind(null, 'test', em)); }); - it('Should not throw given an instance of Error', function () { + it('Should not throw given an instance of Error', function() { assert.doesNotThrow(handleNumberAsError.bind(null, new Error(), em)); }); - it('Should not throw given an object', function () { + it('Should not throw given an object', function() { assert.doesNotThrow(handleNumberAsError.bind(null, {}, em)); }); - it('Should not throw given valid input', function () { + it('Should not throw given valid input', function() { assert.doesNotThrow(handleNumberAsError.bind(null, 1.3, em)); }); }); diff --git a/packages/error-reporting/test/unit/testHandleObjectAsError.js b/packages/error-reporting/test/unit/testHandleObjectAsError.js index 7dd3983734e..58f84c86f0c 100644 --- a/packages/error-reporting/test/unit/testHandleObjectAsError.js +++ b/packages/error-reporting/test/unit/testHandleObjectAsError.js @@ -20,25 +20,25 @@ var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleObjectAsError = require('../../src/error-handlers/object.js'); -describe('handleObjectAsError behaviour under varying inputs', function () { +describe('handleObjectAsError behaviour under varying inputs', function() { var em; - beforeEach(function () {em = new ErrorMessage();}); - it('Should not throw given undefined', function () { + beforeEach(function() {em = new ErrorMessage();}); + it('Should not throw given undefined', function() { assert.doesNotThrow(handleObjectAsError.bind(null, undefined, em)); }); - it('Should not throw given null', function () { + it('Should not throw given null', function() { assert.doesNotThrow(handleObjectAsError.bind(null, null, em)); }); - it('Should not throw given a string', function () { + it('Should not throw given a string', function() { assert.doesNotThrow(handleObjectAsError.bind(null, 'msg', em)); }); - it('Should not throw given an instance of Error', function () { + it('Should not throw given an instance of Error', function() { assert.doesNotThrow(handleObjectAsError.bind(null, new Error(), em)); }); - it('Should not throw given a number', function () { + it('Should not throw given a number', function() { assert.doesNotThrow(handleObjectAsError.bind(null, 1.3, em)); }); - it('Should not throw given valid input', function () { + it('Should not throw given valid input', function() { assert.doesNotThrow(handleObjectAsError.bind(null, {}, em)); }); }); diff --git a/packages/error-reporting/test/unit/testHandleStringAsError.js b/packages/error-reporting/test/unit/testHandleStringAsError.js index e690ac3e8df..7218ef8513c 100644 --- a/packages/error-reporting/test/unit/testHandleStringAsError.js +++ b/packages/error-reporting/test/unit/testHandleStringAsError.js @@ -20,25 +20,25 @@ var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleStringAsError = require('../../src/error-handlers/string.js'); -describe('handleStringAsError behaviour under varying inputs', function () { +describe('handleStringAsError behaviour under varying inputs', function() { var em; - beforeEach(function () {em = new ErrorMessage();}); - it('Should not throw given undefined', function () { + beforeEach(function() {em = new ErrorMessage();}); + it('Should not throw given undefined', function() { assert.doesNotThrow(handleStringAsError.bind(null, undefined, em)); }); - it('Should not throw given null', function () { + it('Should not throw given null', function() { assert.doesNotThrow(handleStringAsError.bind(null, null, em)); }); - it('Should not throw given an object', function () { + it('Should not throw given an object', function() { assert.doesNotThrow(handleStringAsError.bind(null, {}, em)); }); - it('Should not throw given an array', function () { + it('Should not throw given an array', function() { assert.doesNotThrow(handleStringAsError.bind(null, [], em)); }); - it('Should not throw given an instance of Error', function () { + it('Should not throw given an instance of Error', function() { assert.doesNotThrow(handleStringAsError.bind(null, 1.3, em)); }); - it('Should not throw given valid input', function () { + it('Should not throw given valid input', function() { assert.doesNotThrow(handleStringAsError.bind(null, 'test', em)); }); }); diff --git a/packages/error-reporting/test/unit/testHandleUnknownAsError.js b/packages/error-reporting/test/unit/testHandleUnknownAsError.js index d3e86da353a..2865b64b538 100644 --- a/packages/error-reporting/test/unit/testHandleUnknownAsError.js +++ b/packages/error-reporting/test/unit/testHandleUnknownAsError.js @@ -20,28 +20,28 @@ var assert = require('assert'); var ErrorMessage = require('../../src/classes/error-message.js'); var handleUnknownAsError = require('../../src/error-handlers/unknown.js'); -describe('handleUnknownAsError behvaiour under varying input', function () { +describe('handleUnknownAsError behvaiour under varying input', function() { var em; - beforeEach(function () {em = new ErrorMessage();}); - it('Should not throw given undefined', function () { + beforeEach(function() {em = new ErrorMessage();}); + it('Should not throw given undefined', function() { assert.doesNotThrow(handleUnknownAsError.bind(null, undefined, em)); }); - it('Should not throw given null', function () { + it('Should not throw given null', function() { assert.doesNotThrow(handleUnknownAsError.bind(null, null, em)); }); - it('Should not throw given an object', function () { + it('Should not throw given an object', function() { assert.doesNotThrow(handleUnknownAsError.bind(null, {}, em)); }); - it('Should not throw given an array', function () { + it('Should not throw given an array', function() { assert.doesNotThrow(handleUnknownAsError.bind(null, [], em)); }); - it('Should not throw given an instance of Error', function () { + it('Should not throw given an instance of Error', function() { assert.doesNotThrow(handleUnknownAsError.bind(null, new Error(), em)); }); - it('Should not throw given a number', function () { + it('Should not throw given a number', function() { assert.doesNotThrow(handleUnknownAsError.bind(null, 1.3, em)); }); - it('Should not throw given a string', function () { + it('Should not throw given a string', function() { assert.doesNotThrow(handleUnknownAsError.bind(null, 'msg', em)); }); }); diff --git a/packages/error-reporting/test/unit/testHapiInterface.js b/packages/error-reporting/test/unit/testHapiInterface.js index 5afb34f5f2b..71a10589f12 100644 --- a/packages/error-reporting/test/unit/testHapiInterface.js +++ b/packages/error-reporting/test/unit/testHapiInterface.js @@ -27,63 +27,63 @@ var Fuzzer = require('../../utils/fuzzer.js'); var EventEmitter = require('events').EventEmitter; var Configuration = require('../fixtures/configuration.js'); -describe('Hapi interface', function () { - describe('Fuzzing the setup handler', function () { - it('Should not throw when fuzzed with invalid types', function () { +describe('Hapi interface', function() { + describe('Fuzzing the setup handler', function() { + it('Should not throw when fuzzed with invalid types', function() { var f = new Fuzzer(); - assert.doesNotThrow(function () { + assert.doesNotThrow(function() { f.fuzzFunctionForTypes(hapiInterface, ['object', 'object']); return; }); }); }); - describe('Providing valid input to the setup handler', function () { - var givenConfig = {getVersion: function () {return '1';}}; + describe('Providing valid input to the setup handler', function() { + var givenConfig = {getVersion: function() {return '1';}}; var plugin; - beforeEach(function () {plugin = hapiInterface(null, givenConfig);}); - it('should have plain object as plugin', function () { + beforeEach(function() {plugin = hapiInterface(null, givenConfig);}); + it('should have plain object as plugin', function() { assert(isObject(plugin)); }); - it('plugin should have a register function property', function () { + it('plugin should have a register function property', function() { assert(has(plugin, 'register') && isFunction(plugin.register)); }); it('the plugin\'s register property should have an attributes property', - function () { + function() { assert(has(plugin.register, 'attributes') && isObject(plugin.register.attributes)); } ); it('the plugin\'s attribute property should have a name property', - function () { + function() { assert(has(plugin.register.attributes, 'name')); assert.strictEqual(plugin.register.attributes.name, '@google/cloud-errors'); } ); it('the plugin\'s attribute property should have a version property', - function () { + function() { assert(has(plugin.register.attributes, 'version')); } ); }); - describe('hapiRegisterFunction behaviour', function () { + describe('hapiRegisterFunction behaviour', function() { var fakeServer; - beforeEach(function () {fakeServer = new EventEmitter();}); - it('Should call sendError when the request-error event is emitted', function () { + beforeEach(function() {fakeServer = new EventEmitter();}); + it('Should call sendError when the request-error event is emitted', function() { var fakeClient = { - sendError: function ( errMsg ) { + sendError: function( errMsg ) { assert(errMsg instanceof ErrorMessage, 'The value given to sendError should be an instance of Error message'); } }; var plugin = hapiInterface(fakeClient, { - lacksCredentials: function () { + lacksCredentials: function() { return false; }, - getVersion: function () { + getVersion: function() { return '1'; }, - getServiceContext: function () { + getServiceContext: function() { return {service: 'node'}; } }); @@ -91,10 +91,10 @@ describe('Hapi interface', function () { fakeServer.emit('request-error'); }); }); - describe('Behaviour around the request/response lifecycle', function () { + describe('Behaviour around the request/response lifecycle', function() { var EVENT = 'onPreResponse'; - var fakeServer, config, plugin, fakeClient = {sendError: function () {}}; - before(function () { + var fakeServer, config, plugin, fakeClient = {sendError: function() {}}; + before(function() { config = new Configuration({ projectId: 'xyz', serviceContext: { @@ -102,45 +102,45 @@ describe('Hapi interface', function () { version: '1.x' } }); - config.lacksCredentials = function () {return false;}; + config.lacksCredentials = function() {return false;}; plugin = hapiInterface(fakeClient, config); }); - beforeEach(function () { + beforeEach(function() { fakeServer = new EventEmitter(); fakeServer.ext = fakeServer.on; }); - afterEach(function () { + afterEach(function() { fakeServer.removeAllListeners(); }); - it('Should call continue when a boom preResponse is emitted', function (done) { - plugin.register(fakeServer, null, function () {}); + it('Should call continue when a boom preResponse is emitted', function(done) { + plugin.register(fakeServer, null, function() {}); fakeServer.emit(EVENT, {response: {isBoom: true}}, { - continue: function () { + continue: function() { // The continue function should be called done(); } } ); }); - it('Should call sendError when a boom response is received', function (done) { + it('Should call sendError when a boom response is received', function(done) { var fakeClient = { - sendError: function (err) { + sendError: function(err) { assert(err instanceof ErrorMessage); done(); } }; var plugin = hapiInterface(fakeClient, config); - plugin.register(fakeServer, null, function () {}); + plugin.register(fakeServer, null, function() {}); fakeServer.emit('onPreResponse', {response:{isBoom: true}}); }); - it('Should call next when completing a request', function (done) { - plugin.register(fakeServer, null, function (err) { + it('Should call next when completing a request', function(done) { + plugin.register(fakeServer, null, function(err) { // The next function should be called done(); }); fakeServer.emit(EVENT, {response: {isBoom: true}}, - {continue: function () {}}); + {continue: function() {}}); }); }); }); diff --git a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js index aec4b569217..e22e1dba45b 100644 --- a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js @@ -20,9 +20,9 @@ var assert = require('assert'); var hapiRequestInformationExtractor = require('../../src/request-extractors/hapi.js'); var Fuzzer = require('../../utils/fuzzer.js'); -describe('hapiRequestInformationExtractor behaviour', function () { - describe('behaviour given invalid input', function () { - it('Should produce the default value', function () { +describe('hapiRequestInformationExtractor behaviour', function() { + describe('behaviour given invalid input', function() { + it('Should produce the default value', function() { var DEFAULT_RETURN_VALUE = { method: '', url: '', @@ -32,7 +32,7 @@ describe('hapiRequestInformationExtractor behaviour', function () { remoteAddress: '' }; var f = new Fuzzer(); - var cbFn = function (value) { + var cbFn = function(value) { assert.deepEqual(value, DEFAULT_RETURN_VALUE); }; f.fuzzFunctionForTypes( @@ -42,7 +42,7 @@ describe('hapiRequestInformationExtractor behaviour', function () { ); }); }); - describe('behaviour given valid input', function () { + describe('behaviour given valid input', function() { var FULL_REQ_DERIVATION_VALUE = { method: 'STUB_METHOD', url: 'www.TEST-URL.com', @@ -106,17 +106,17 @@ describe('hapiRequestInformationExtractor behaviour', function () { remoteAddress: '', statusCode: 0 }; - it('Should produce the full request input', function () { + it('Should produce the full request input', function() { assert.deepEqual( hapiRequestInformationExtractor(FULL_REQ_DERIVATION_VALUE), FULL_REQ_EXPECTED_VALUE); }); - it('Should produce the partial request input', function () { + it('Should produce the partial request input', function() { assert.deepEqual( hapiRequestInformationExtractor(PARTIAL_REQ_DERIVATION_VALUE), PARTIAL_REQ_EXPECTED_VALUE); }); - it('Should produce the second partial request input', function () { + it('Should produce the second partial request input', function() { assert.deepEqual( hapiRequestInformationExtractor(ANOTHER_PARTIAL_REQ_DERIVATION_VALUE), ANOTHER_PARTIAL_REQ_EXPECTED_VALUE diff --git a/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js index fa7c8347e68..2b712038ac0 100644 --- a/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js @@ -20,9 +20,9 @@ var assert = require('assert'); var koaRequestInformationExtractor = require('../../src/request-extractors/koa.js'); var Fuzzer = require('../../utils/fuzzer.js'); -describe('koaRequestInformationExtractor', function () { - describe('Behaviour under invalid input', function () { - it('Should produce a default value', function () { +describe('koaRequestInformationExtractor', function() { + describe('Behaviour under invalid input', function() { + it('Should produce a default value', function() { var DEFAULT_RETURN_VALUE = { method: '', url: '', @@ -32,15 +32,15 @@ describe('koaRequestInformationExtractor', function () { remoteAddress: '' }; var f = new Fuzzer(); - var cbFn = function (value) { + var cbFn = function(value) { assert.deepEqual(value, DEFAULT_RETURN_VALUE); }; f.fuzzFunctionForTypes(koaRequestInformationExtractor, ['object', 'object'], cbFn); }); }); - describe('Behaviour under valid input', function () { - it('Should produce the expected value', function () { + describe('Behaviour under valid input', function() { + it('Should produce the expected value', function() { var FULL_REQ_DERIVATION_VALUE = { method: 'STUB_METHOD', url: 'www.TEST-URL.com', diff --git a/packages/error-reporting/test/unit/testLogger.js b/packages/error-reporting/test/unit/testLogger.js index 32f33e54647..a1f24b9a3fa 100644 --- a/packages/error-reporting/test/unit/testLogger.js +++ b/packages/error-reporting/test/unit/testLogger.js @@ -18,44 +18,44 @@ var assert = require('assert'); var createLogger = require('../../src/logger.js'); -describe('logger', function () { - describe('Initialization', function () { +describe('logger', function() { + describe('Initialization', function() { var oldEnv; - before(function () { + before(function() { oldEnv = process.env.GCLOUD_ERRORS_LOGLEVEL; delete process.env.GCLOUD_ERRORS_LOGLEVEL; }); - after(function () {process.env.GCLOUD_ERRORS_LOGLEVEL = oldEnv;}); - describe('Exception handling', function () { - it('Should not throw given undefined', function () { + after(function() {process.env.GCLOUD_ERRORS_LOGLEVEL = oldEnv;}); + describe('Exception handling', function() { + it('Should not throw given undefined', function() { assert.doesNotThrow(createLogger, createLogger()); }); - it('Should not throw given an empty object', function () { + it('Should not throw given an empty object', function() { assert.doesNotThrow(createLogger.bind(null, {}), createLogger()); }); - it('Should not throw given logLevel as a number', function () { + it('Should not throw given logLevel as a number', function() { assert.doesNotThrow(createLogger.bind(null, {logLevel: 3}), createLogger({logLevel: 3})); }); - it('Should not throw given logLevel as a string', function () { + it('Should not throw given logLevel as a string', function() { assert.doesNotThrow(createLogger.bind(null, {logLevel: '3'}), createLogger({logLevel: 3})); }); - it('Should not throw given an env variable to use', function () { + it('Should not throw given an env variable to use', function() { process.env.GCLOUD_ERRORS_LOGLEVEL = 4; assert.doesNotThrow(createLogger, createLogger({logLevel: 4})); delete process.env.GCLOUD_ERRORS_LOGLEVEL; }); - it('Should thow given logLevel as null', function () { + it('Should thow given logLevel as null', function() { assert.throws(createLogger.bind(null, {logLevel: null}), undefined); }); }); - describe('Default log level', function () { - it('Should be WARN', function () { + describe('Default log level', function() { + it('Should be WARN', function() { var buf = []; var orig = console._stdout.write; - console._stdout.write = function () { + console._stdout.write = function() { buf.push(arguments[0]); orig.apply(this, arguments); }; diff --git a/packages/error-reporting/test/unit/testManualHandler.js b/packages/error-reporting/test/unit/testManualHandler.js index 4b0b8031fd9..8547df6ae64 100644 --- a/packages/error-reporting/test/unit/testManualHandler.js +++ b/packages/error-reporting/test/unit/testManualHandler.js @@ -20,13 +20,13 @@ var assert = require('assert'); var manual = require('../../src/interfaces/manual.js'); var Configuration = require('../fixtures/configuration.js'); var config = new Configuration({}); -config.lacksCredentials = function () { +config.lacksCredentials = function() { return false; }; var ErrorMessage = require('../../src/classes/error-message.js'); // var nock = require('nock'); -describe('Manual handler', function () { +describe('Manual handler', function() { // nock.disableNetConnect(); // Mocked client var client = { @@ -38,21 +38,21 @@ describe('Manual handler', function () { } }; var report = manual(client, config); - describe('Report invocation behaviour', function () { - it('Should allow argument-less invocation', function () { + describe('Report invocation behaviour', function() { + it('Should allow argument-less invocation', function() { var r = report(); assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); }); - it('Should allow single string', function () { + it('Should allow single string', function() { var r = report('doohickey'); assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); assert(r.message.match(/doohickey/), 'string error should propagate'); }); - it('Should allow single instance of Error', function () { + it('Should allow single instance of Error', function() { var r = report(new Error('hokeypokey')); assert(r.message.match(/hokeypokey/)); }); - it('Should allow a single function as a malformed error input', function (done) { + it('Should allow a single function as a malformed error input', function(done) { this.timeout(2000); var r = report(function(err, res) { assert(false, 'callback should not be called'); @@ -63,31 +63,31 @@ describe('Manual handler', function () { done(); }, 1000); }); - it('Should callback to the supplied function', function (done) { + it('Should callback to the supplied function', function(done) { var r = report('malarkey', function(err, res) { done(); }); assert(r.message.match(/malarkey/), 'string error should propagate'); }); - it('Should replace the error string with the additional message', function (done) { + it('Should replace the error string with the additional message', function(done) { var r = report('monkey', 'wrench', function(err, res) { done(); }); assert.strictEqual(r.message, 'wrench', 'additional message should replace'); }); - it('Should allow a full array of optional arguments', function (done) { + it('Should allow a full array of optional arguments', function(done) { var r = report('donkey', { method: 'FETCH' }, 'cart', function(err, res) { done(); }); assert.strictEqual(r.message, 'cart', 'additional message should replace'); assert.strictEqual(r.context.httpRequest.method, 'FETCH'); }); - it('Should allow all optional arguments except the callback', function () { + it('Should allow all optional arguments except the callback', function() { var r = report('whiskey', { method: 'SIP' }, 'sour'); assert.strictEqual(r.message, 'sour', 'additional message should replace'); assert.strictEqual(r.context.httpRequest.method, 'SIP'); }); - it('Should allow a lack of additional message', function (done) { + it('Should allow a lack of additional message', function(done) { var r = report('ticky', { method: 'TACKEY' }, function(err, res) { done(); }); @@ -95,38 +95,38 @@ describe('Manual handler', function () { 'original message should be preserved'); assert.strictEqual(r.context.httpRequest.method, 'TACKEY'); }); - it('Should ignore arguments after callback value placement', function (done) { + it('Should ignore arguments after callback value placement', function(done) { var r = report('hockey', function(err, res) { done(); }, 'field'); assert(r.message.match('hockey') && !r.message.match('field'), 'string after callback should be ignored'); }); - it('Should ignore arguments after callback value placement', function (done) { + it('Should ignore arguments after callback value placement', function(done) { var r = report('passkey', function(err, res) { done(); }, { method: 'HONK'}); assert.notEqual(r.context.httpRequest.method, 'HONK'); }); - it('Should allow null arguments as placeholders', function (done) { + it('Should allow null arguments as placeholders', function(done) { var r = report('pokey', null, null, function(err, res) { done(); }); assert(r.message.match(/pokey/), 'string error should propagate'); }); - it('Should allow explicit undefined arguments as placeholders', function (done) { + it('Should allow explicit undefined arguments as placeholders', function(done) { var r = report('Turkey', undefined, undefined, function(err, res) { done(); }); assert(r.message.match(/Turkey/), 'string error should propagate'); }); - it('Should allow request to be supplied as undefined', function (done) { + it('Should allow request to be supplied as undefined', function(done) { var r = report('turnkey', undefined, 'solution', function(err, res) { done(); }); assert.strictEqual(r.message, 'solution', 'string error should propagate'); }); - it('Should allow additional message to be supplied as undefined', function (done) { + it('Should allow additional message to be supplied as undefined', function(done) { var r = report('Mickey', { method: 'SNIFF'}, undefined, function(err, res) { done(); }); @@ -136,14 +136,14 @@ describe('Manual handler', function () { }); }); - describe('Custom Payload Builder', function () { - it('Should accept builder instance as only argument', function () { + describe('Custom Payload Builder', function() { + it('Should accept builder instance as only argument', function() { var msg = 'test'; var r = report(new ErrorMessage().setMessage(msg)); assert.strictEqual(r.message, msg, 'string message should propagate from error message instance'); }); - it('Should accept builder and request as arguments', function () { + it('Should accept builder and request as arguments', function() { var msg = 'test'; var oldReq = {method: 'GET'}; var newReq = {method: 'POST'}; @@ -160,7 +160,7 @@ describe('Manual handler', function () { ].join('\n') ); }); - it('Should accept message and additional message params as arguments', function () { + it('Should accept message and additional message params as arguments', function() { var oldMsg = 'test'; var newMsg = 'analysis'; var r = report( @@ -173,11 +173,11 @@ describe('Manual handler', function () { 'supplied, should overwrite any prexisting data in the message field.' ].join('\n')); }); - it('Should accept message and callback function as arguments', function (done) { + it('Should accept message and callback function as arguments', function(done) { var oldMsg = 'test'; report( new ErrorMessage().setMessage(oldMsg), - function () { done(); } + function() { done(); } ); }); }); diff --git a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js index ca42d5e3730..93d32501d35 100644 --- a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js @@ -22,9 +22,9 @@ var extend = require('extend'); var manualRequestInformationExtractor = require('../../src/request-extractors/manual.js'); var Fuzzer = require('../../utils/fuzzer.js'); -describe('manualRequestInformationExtractor', function () { - describe('Behaviour given invalid input', function () { - it('Should return default values', function () { +describe('manualRequestInformationExtractor', function() { + describe('Behaviour given invalid input', function() { + it('Should return default values', function() { var DEFAULT_RETURN_VALUE = { method: '', url: '', @@ -34,14 +34,14 @@ describe('manualRequestInformationExtractor', function () { remoteAddress: '' }; var f = new Fuzzer(); - var cbFn = function (value) { + var cbFn = function(value) { assert.deepEqual(value, DEFAULT_RETURN_VALUE); }; f.fuzzFunctionForTypes(manualRequestInformationExtractor, ['object'], cbFn); }); }); - describe('Behaviour given valid input', function () { + describe('Behaviour given valid input', function() { var FULL_VALID_INPUT = { method: 'GET', url: 'http://0.0.0.0/myTestRoute', @@ -50,7 +50,7 @@ describe('manualRequestInformationExtractor', function () { statusCode: 500, remoteAddress: '0.0.0.1' }; - it('Should return expected output', function () { + it('Should return expected output', function() { assert.deepEqual( manualRequestInformationExtractor(FULL_VALID_INPUT), FULL_VALID_INPUT, diff --git a/packages/error-reporting/test/unit/testRequestInformationContainer.js b/packages/error-reporting/test/unit/testRequestInformationContainer.js index 578e2f4e0c2..2bb0d4446f1 100644 --- a/packages/error-reporting/test/unit/testRequestInformationContainer.js +++ b/packages/error-reporting/test/unit/testRequestInformationContainer.js @@ -20,74 +20,74 @@ var assert = require('assert'); var RequestInformationContainer = require('../../src/classes/request-information-container.js'); var Fuzzer = require('../../utils/fuzzer.js'); -describe('RequestInformationContainer', function () { +describe('RequestInformationContainer', function() { var f = new Fuzzer(); var cbFn, ric; - beforeEach(function () {ric = new RequestInformationContainer();}); - describe('Fuzzing against RequestInformationContainer for negative cases', function () { + beforeEach(function() {ric = new RequestInformationContainer();}); + describe('Fuzzing against RequestInformationContainer for negative cases', function() { it('Should return the RequestInformationContainer.url propertym as an empty string', - function () { - cbFn = function () { + function() { + cbFn = function() { assert.deepEqual(ric.url, ''); }; f.fuzzFunctionForTypes(ric.setUrl, ['string'], cbFn, ric); } ); - it('Should return the method property as an empty string', function () { - cbFn = function ( returnValue ) { + it('Should return the method property as an empty string', function() { + cbFn = function( returnValue ) { assert.deepEqual(ric.method, ''); }; f.fuzzFunctionForTypes(ric.setMethod, ['string'], cbFn, ric); }); - it('Should return the referrer property as an empty string', function () { - cbFn = function ( returnValue ) { + it('Should return the referrer property as an empty string', function() { + cbFn = function( returnValue ) { assert.deepEqual(ric.referrer, ''); }; f.fuzzFunctionForTypes(ric.setReferrer, ['string'], cbFn, ric); }); - it('Should return the userAgent property as an empty string', function () { - cbFn = function ( returnValue ) { + it('Should return the userAgent property as an empty string', function() { + cbFn = function( returnValue ) { assert.deepEqual(ric.userAgent, ''); }; f.fuzzFunctionForTypes(ric.setUserAgent, ['string'], cbFn, ric); }); - it('Should return the remoteAddress property as an empty string', function () { - cbFn = function ( returnValue ) { + it('Should return the remoteAddress property as an empty string', function() { + cbFn = function( returnValue ) { assert.deepEqual(ric.remoteAddress, ''); }; f.fuzzFunctionForTypes(ric.setRemoteAddress, ['string'], cbFn, ric); }); - it('Should return the default value for statusCode', function () { - cbFn = function ( returnValue ) { + it('Should return the default value for statusCode', function() { + cbFn = function( returnValue ) { assert.strictEqual(ric.statusCode, 0); }; f.fuzzFunctionForTypes(ric.setStatusCode, ['number'], cbFn, ric); }); }); - describe('Fuzzing against RequestInformationContainer for positive cases', function () { + describe('Fuzzing against RequestInformationContainer for positive cases', function() { var VALID_STRING_INPUT = 'valid'; var VALID_NUMBER_INPUT = 500; - it('Should assign the value to the url property', function () { + it('Should assign the value to the url property', function() { ric.setUrl(VALID_STRING_INPUT); assert.deepEqual(ric.url, VALID_STRING_INPUT); }); - it('Should assign the value to the method property', function () { + it('Should assign the value to the method property', function() { ric.setMethod(VALID_STRING_INPUT); assert.deepEqual(ric.method, VALID_STRING_INPUT); }); - it('Should assign the value to the referrer property', function () { + it('Should assign the value to the referrer property', function() { ric.setReferrer(VALID_STRING_INPUT); assert.deepEqual(ric.referrer, VALID_STRING_INPUT); }); - it('Should assign the value to the userAgent property', function () { + it('Should assign the value to the userAgent property', function() { ric.setUserAgent(VALID_STRING_INPUT); assert.deepEqual(ric.userAgent, VALID_STRING_INPUT); }); - it('Should assign the value to remoteAddress property', function () { + it('Should assign the value to remoteAddress property', function() { ric.setRemoteAddress(VALID_STRING_INPUT); assert.deepEqual(ric.remoteAddress, VALID_STRING_INPUT); }); - it('Should assign the value to statusCode property', function () { + it('Should assign the value to statusCode property', function() { ric.setStatusCode(VALID_NUMBER_INPUT); assert.deepEqual(ric.statusCode, VALID_NUMBER_INPUT); }); diff --git a/packages/error-reporting/test/unit/testRestifyInterface.js b/packages/error-reporting/test/unit/testRestifyInterface.js index c476d2d5667..a24c97d2119 100644 --- a/packages/error-reporting/test/unit/testRestifyInterface.js +++ b/packages/error-reporting/test/unit/testRestifyInterface.js @@ -27,12 +27,12 @@ if (!EventEmitter.prototype.listenerCount) { }; } -describe('restifyInterface', function () { +describe('restifyInterface', function() { var UNCAUGHT_EVENT = 'uncaughtException'; var FINISH = 'finish'; - var noOp = function () {return;}; - describe('Attachment to the uncaughtException event', function () { - it('Should attach one listener after instantiation', function () { + var noOp = function() {return;}; + describe('Attachment to the uncaughtException event', function() { + it('Should attach one listener after instantiation', function() { var ee = new EventEmitter(); assert.strictEqual(ee.listenerCount(UNCAUGHT_EVENT), 0, 'Listeners on event should be zero'); @@ -44,58 +44,58 @@ describe('restifyInterface', function () { 'Listeners on event should now be one'); }); }); - describe('Request handler lifecycle events', function () { + describe('Request handler lifecycle events', function() { var ee = new EventEmitter(); var errorHandlerInstance = restifyInterface(null, null); var requestHandlerInstance = errorHandlerInstance(ee); - describe('default path on invalid input', function () { - it('Should not throw', function () { - assert.doesNotThrow(function () { + describe('default path on invalid input', function() { + it('Should not throw', function() { + assert.doesNotThrow(function() { requestHandlerInstance(null, null, noOp); }); }); }); - describe('default path without req/res error', function () { + describe('default path without req/res error', function() { ee.removeAllListeners(); var req = new EventEmitter(); var res = new EventEmitter(); res.statusCode = 200; - it('Should have 0 listeners on the finish event', function () { + it('Should have 0 listeners on the finish event', function() { assert.strictEqual(res.listenerCount(FINISH), 0); }); - it('Should not throw while handling the req/res objects', function () { - assert.doesNotThrow(function () { + it('Should not throw while handling the req/res objects', function() { + assert.doesNotThrow(function() { requestHandlerInstance(req, res, noOp); }); }); - it('Should have 1 listener on the finish event after handling req/res', function () { + it('Should have 1 listener on the finish event after handling req/res', function() { assert.strictEqual(res.listenerCount(FINISH), 1); }); - it('Should not throw when emitting the finish event', function () { - assert.doesNotThrow(function () { + it('Should not throw when emitting the finish event', function() { + assert.doesNotThrow(function() { res.emit(FINISH); }); }); }); - describe('default path with req/res error', function (done) { + describe('default path with req/res error', function(done) { ee.removeAllListeners(); var client = { - sendError: function () { + sendError: function() { assert(true, 'sendError should be called'); } }; var config = { - getServiceContext: function ( ) { + getServiceContext: function( ) { assert(true, 'getServiceContext should be called'); return { service: 'stub-service', version: 'stub-version' }; }, - lacksCredentials: function () { + lacksCredentials: function() { return false; }, - getVersion: function () { + getVersion: function() { return '1'; } }; @@ -104,29 +104,29 @@ describe('restifyInterface', function () { var req = new EventEmitter(); var res = new EventEmitter(); res.statusCode = 500; - it('Should have 0 Listeners on the finish event', function () { + it('Should have 0 Listeners on the finish event', function() { assert.strictEqual(res.listenerCount(FINISH), 0); }); - it('Should not throw on instantiation', function () { - assert.doesNotThrow(function () { + it('Should not throw on instantiation', function() { + assert.doesNotThrow(function() { requestHandlerInstance(req, res, noOp); }); }); - it('Should have 1 listener on the finish event after instantiation', function () { + it('Should have 1 listener on the finish event after instantiation', function() { assert.strictEqual(res.listenerCount(FINISH), 1); }); - it('Should not throw on emission of the finish event', function () { - assert.doesNotThrow(function () { + it('Should not throw on emission of the finish event', function() { + assert.doesNotThrow(function() { res.emit(FINISH); }); }); - describe('Exercise the uncaughtException event path', function () { - it('Should call the sendError function property on the client', function (done) { - client.sendError = function () { + describe('Exercise the uncaughtException event path', function() { + it('Should call the sendError function property on the client', function(done) { + client.sendError = function() { assert(true, 'sendError should be called'); done(); }; - assert.doesNotThrow(function () { + assert.doesNotThrow(function() { ee.emit(UNCAUGHT_EVENT); }); }); diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index ad7386478bb..088b3211f5c 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -35,7 +35,7 @@ var env = { GAE_MODULE_NAME: process.env.GAE_MODULE_NAME }; function sterilizeEnv () { - forEach(env, function (val, key) { + forEach(env, function(val, key) { delete process.env[key]; }); } @@ -46,19 +46,19 @@ function setEnv (serviceName, serviceVersion, moduleName, moduleVersion, functio GAE_MODULE_NAME: moduleName, GAE_MODULE_VERSION: moduleVersion, FUNCTION_NAME: functionName - }, function (val) {return !isString(val);})); + }, function(val) {return !isString(val);})); } function restoreEnv () { assign(process.env, env); } -describe('Testing service configuration', function () { - beforeEach(function () {sterilizeEnv();}); - after(function () {restoreEnv();}); +describe('Testing service configuration', function() { + beforeEach(function() {sterilizeEnv();}); + after(function() {restoreEnv();}); it( 'A Configuration uses the function name as the service name on GCF ' + 'if the service name is not given in the given config', - function () { + function() { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', 'someFunction'); var c = new Configuration({}, logger); @@ -72,7 +72,7 @@ describe('Testing service configuration', function () { 'A Configuration uses the function name as the service name on GCF ' + 'if the service name is not given in the given config ' + 'even if the GAE_SERVICE was not set', - function () { + function() { setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); var c = new Configuration({}, logger); assert.deepEqual(c.getServiceContext().service, 'someFunction'); @@ -85,7 +85,7 @@ describe('Testing service configuration', function () { 'A Configuration uses the GAE_SERVICE env value as the service name ' + 'if the FUNCTION_NAME env variable is not set and the given config ' + 'does not specify the service name', - function () { + function() { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); var c = new Configuration({}, logger); assert.deepEqual(c.getServiceContext().service, 'someModuleName'); @@ -98,7 +98,7 @@ describe('Testing service configuration', function () { 'A Configuration uses the service name in the given config if it ' + 'was specified and both the GAE_SERVICE and FUNCTION_NAME ' + 'env vars are set', - function () { + function() { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', 'someFunction'); var c = new Configuration({ @@ -116,7 +116,7 @@ describe('Testing service configuration', function () { 'A Configuration uses the service name and version in the given config if ' + 'they were both specified and both the GAE_SERVICE and FUNCTION_NAME ' + 'env vars are set', - function () { + function() { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', 'someFunction'); var c = new Configuration({ @@ -133,7 +133,7 @@ describe('Testing service configuration', function () { it( 'A Configuration uses the service name in the given config if it ' + 'was specified and only the GAE_SERVICE env var is set', - function () { + function() { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); var c = new Configuration({ serviceContext: { @@ -149,7 +149,7 @@ describe('Testing service configuration', function () { it( 'A Configuration uses the service name and version in the given config if ' + 'they were both specified and only the GAE_SERVICE env var is set', - function () { + function() { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); var c = new Configuration({ serviceContext: { @@ -165,7 +165,7 @@ describe('Testing service configuration', function () { it( 'A Configuration uses the service name in the given config if it ' + 'was specified and only the FUNCTION_NAME env var is set', - function () { + function() { setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); var c = new Configuration({ serviceContext: { @@ -181,7 +181,7 @@ describe('Testing service configuration', function () { it( 'A Configuration uses the service name and version in the given config if ' + 'they were both specified and only the FUNCTION_NAME env var is set', - function () { + function() { setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); var c = new Configuration({ serviceContext: { @@ -198,7 +198,7 @@ describe('Testing service configuration', function () { 'A Configuration uses the service name "node" and no version if ' + 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ 'not specified a service name or version', - function () { + function() { var c = new Configuration({}, logger); assert.strictEqual(c.getServiceContext().service, 'node'); assert.strictEqual(c.getServiceContext().version, undefined); @@ -209,7 +209,7 @@ describe('Testing service configuration', function () { 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ 'not specified a service name or version even if GAE_VERSION has ' + 'been set', - function () { + function() { setEnv(null, 'InvalidVersion', null, 'InvalidVersion', null); var c = new Configuration({}, logger); assert.strictEqual(c.getServiceContext().service, 'node'); @@ -220,7 +220,7 @@ describe('Testing service configuration', function () { 'A Configuration uses the service name "node" and the user specified ' + 'version if GAE_SERVICE is not set, FUNCTION_NAME is not set, and the ' + 'user has not specified a service name but has specified a version', - function () { + function() { var c = new Configuration({ serviceContext: { version: '2.0' diff --git a/packages/error-reporting/test/unit/testUncaught.js b/packages/error-reporting/test/unit/testUncaught.js index 7a96c6b52e9..adb53df8746 100644 --- a/packages/error-reporting/test/unit/testUncaught.js +++ b/packages/error-reporting/test/unit/testUncaught.js @@ -36,56 +36,56 @@ function getConfig(reportUncaughtExceptions) { var c = new Configuration({ reportUncaughtExceptions: reportUncaughtExceptions }, createLogger({logLevel: 4})); - c.lacksCredentials = function () { + c.lacksCredentials = function() { return false; }; return c; } -describe('Uncaught exception handler behvaiour', function () { +describe('Uncaught exception handler behvaiour', function() { var UNCAUGHT = 'uncaughtException'; - describe('Instantiation', function () { - beforeEach(function () {process.removeAllListeners(UNCAUGHT);}); - it('Should throw without a configuration', function () { + describe('Instantiation', function() { + beforeEach(function() {process.removeAllListeners(UNCAUGHT);}); + it('Should throw without a configuration', function() { assert.throws(uncaughtSetup); }); - it('Should not throw given a valid configuration', function () { + it('Should not throw given a valid configuration', function() { assert.doesNotThrow(uncaughtSetup.bind(null, {}, getConfig(false))); assert.doesNotThrow(uncaughtSetup.bind(null, {}, getConfig(true))); }); - it('Should return the process object after instantiation', function () { + it('Should return the process object after instantiation', function() { assert.strictEqual(process, uncaughtSetup({}, getConfig(true))); }); it('Should not attach a listener to the uncaughtException event if ' + - 'reportUncaughtExceptions is false', function () { + 'reportUncaughtExceptions is false', function() { uncaughtSetup({}, getConfig(false)); assert.strictEqual(process.listeners(UNCAUGHT).length, 0); }); it('Should attach a listener to the uncaughtException event if ' + - 'reportUncaughtExceptions is true', function () { + 'reportUncaughtExceptions is true', function() { uncaughtSetup({}, getConfig(true)); assert.strictEqual(process.listeners(UNCAUGHT).length, 1); }); }); - describe('Uncaught exception handling shutdown behaviour', function () { - before(function () { + describe('Uncaught exception handling shutdown behaviour', function() { + before(function() { if (!isString(process.env.GOOGLE_APPLICATION_CREDENTIALS) || !isString(process.env.GCLOUD_PROJECT)) { return this.skip(); } }); - after(function () { + after(function() { reattachOriginalListeners(); }); - it('Should terminate before 2500ms', function (done) { + it('Should terminate before 2500ms', function(done) { var TERMINATE_MSG = 'Should terminate before 2500ms'; this.timeout(3500); var isolate = spawn('./node_modules/mocha/bin/mocha', ['../../test/fixtures/uncaughtExitBehaviour.js'], {env: process.env}); - isolate.on('close', function () { + isolate.on('close', function() { done(); }); - isolate.on('error', function () { + isolate.on('error', function() { console.log('Test isolate encountered error:', '\n', arguments); assert(false, TERMINATE_MSG); done(); diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js index 016604a9fa1..7c20703dc5b 100644 --- a/packages/error-reporting/utils/fuzzer.js +++ b/packages/error-reporting/utils/fuzzer.js @@ -33,7 +33,7 @@ function Fuzzer ( ) { } Fuzzer.prototype.generate = {}; -Fuzzer.prototype.generate.types = function ( ) { +Fuzzer.prototype.generate.types = function( ) { return [ "object", "array", @@ -46,7 +46,7 @@ Fuzzer.prototype.generate.types = function ( ) { ]; } -Fuzzer.prototype.generate.string = function ( len ) { +Fuzzer.prototype.generate.string = function( len ) { var lenChecked = isNumber(len) ? len : 10; var chars = []; @@ -58,12 +58,12 @@ Fuzzer.prototype.generate.string = function ( len ) { return chars.join(""); }; -Fuzzer.prototype.generate.boolean = function ( ) { +Fuzzer.prototype.generate.boolean = function( ) { return !!random(0, 1); } -Fuzzer.prototype.generate.alphaNumericString = function ( len ) { +Fuzzer.prototype.generate.alphaNumericString = function( len ) { var lenChecked = isNumber(len) ? len : 10; var chars = []; var thisRange = []; @@ -85,19 +85,19 @@ Fuzzer.prototype.generate.alphaNumericString = function ( len ) { return chars.join(""); } -Fuzzer.prototype.generate.function = function ( ) { +Fuzzer.prototype.generate.function = function( ) { var availableTypes = without(this.types(), "function"); var typeToGen = this.types()[random(0, availableTypes.length-1)]; var fnToCall = this[typeToGen]; - return function ( ) { + return function( ) { return fnToCall(); }; } -Fuzzer.prototype.generate.number = function ( lower, upper ) { +Fuzzer.prototype.generate.number = function( lower, upper ) { var lowerChecked = isNumber(lower) ? lower : 0; var upperChecked = isNumber(upper) ? upper : 100; @@ -105,17 +105,17 @@ Fuzzer.prototype.generate.number = function ( lower, upper ) { return random(lowerChecked, upperChecked); } -Fuzzer.prototype.generate.null = function ( ) { +Fuzzer.prototype.generate.null = function( ) { return null; } -Fuzzer.prototype.generate.undefined = function ( ) { +Fuzzer.prototype.generate.undefined = function( ) { return undefined; } -Fuzzer.prototype.generate.array = function ( len, ofOneType, currentDepth, allowedDepth ) { +Fuzzer.prototype.generate.array = function( len, ofOneType, currentDepth, allowedDepth ) { var lenChecked = isNumber(len) ? len : random(1, 10); var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType] : this.types(); @@ -162,7 +162,7 @@ Fuzzer.prototype.generate.array = function ( len, ofOneType, currentDepth, allow return arr; } -Fuzzer.prototype.generate.object = function ( numProperties, currentDepth, allowedDepth ) { +Fuzzer.prototype.generate.object = function( numProperties, currentDepth, allowedDepth ) { var numPropertiesChecked = isNumber(numProperties) ? numProperties : random(1, 10); var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; @@ -200,12 +200,12 @@ Fuzzer.prototype.generate.object = function ( numProperties, currentDepth, allow return obj; } -Fuzzer.prototype._backFillUnevenTypesArrays = function ( argsTypesArray ) { +Fuzzer.prototype._backFillUnevenTypesArrays = function( argsTypesArray ) { var largestIndex = 0; var largestLength = (maxBy( argsTypesArray - , function ( o ) { return o.length } + , function( o ) { return o.length } )).length; for ( var i = 0; i < argsTypesArray.length; i++ ) { @@ -222,7 +222,7 @@ Fuzzer.prototype._backFillUnevenTypesArrays = function ( argsTypesArray ) { return argsTypesArray; } -Fuzzer.prototype._normalizeTypesArrayLengths = function ( argsTypesArray ) { +Fuzzer.prototype._normalizeTypesArrayLengths = function( argsTypesArray ) { var allAreTheSameLength = true; var lastLength = argsTypesArray[0].length; @@ -244,7 +244,7 @@ Fuzzer.prototype._normalizeTypesArrayLengths = function ( argsTypesArray ) { return this._backFillUnevenTypesArrays( argsTypesArray ); } -Fuzzer.prototype._generateTypesToFuzzWith = function ( expectsArgTypes ) { +Fuzzer.prototype._generateTypesToFuzzWith = function( expectsArgTypes ) { var argsTypesArray = []; var tmpArray = this.generate.types(); @@ -276,7 +276,7 @@ Fuzzer.prototype._generateTypesToFuzzWith = function ( expectsArgTypes ) { return argsTypesArray; } -Fuzzer.prototype._generateValuesForFuzzTyping = function ( typesToFuzzOnEach, index ) { +Fuzzer.prototype._generateValuesForFuzzTyping = function( typesToFuzzOnEach, index ) { var args = []; var typeToGen = ""; @@ -289,7 +289,7 @@ Fuzzer.prototype._generateValuesForFuzzTyping = function ( typesToFuzzOnEach, in return args; } -Fuzzer.prototype.fuzzFunctionForTypes = function ( fnToFuzz, expectsArgTypes, cb, withContext ) { +Fuzzer.prototype.fuzzFunctionForTypes = function( fnToFuzz, expectsArgTypes, cb, withContext ) { var expectsArgTypesChecked = isArray(expectsArgTypes) ? expectsArgTypes : []; var typesToFuzzOnEach = this._generateTypesToFuzzWith( expectsArgTypesChecked ); var withContextChecked = (withContext !== undefined) ? withContext : null; From 3c0efb49f8bb524491ddf5f3f4033b1185bcbb26 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 09:27:35 -0800 Subject: [PATCH 07/29] remove spacing in function parens --- packages/error-reporting/README.md | 4 +- .../test/fixtures/uncaughtExitBehaviour.js | 6 +- .../test/system-test/testAuthClient.js | 10 +- .../test-servers/express_scaffold_server.js | 28 ++--- .../test/test-servers/hapi_scaffold_server.js | 12 +- .../test-servers/manual_scaffold_server.js | 2 +- .../test/unit/testConfigCredentials.js | 2 +- .../test/unit/testConfiguration.js | 4 +- .../test/unit/testCustomStackTrace.js | 12 +- .../test/unit/testErrorMessage.js | 110 +++++++++--------- .../test/unit/testExpressInterface.js | 8 +- .../testExpressRequestInformationExtractor.js | 16 +-- .../test/unit/testExtractFromErrorClass.js | 2 +- .../test/unit/testHapiInterface.js | 10 +- .../testHapiRequestInformationExtractor.js | 4 +- .../test/unit/testManualHandler.js | 8 +- .../testManualRequestInformationExtractor.js | 14 +-- .../unit/testRequestInformationContainer.js | 12 +- .../test/unit/testRestifyInterface.js | 2 +- .../test/unit/testServiceConfiguration.js | 52 ++++----- .../error-reporting/test/unit/testUncaught.js | 2 +- packages/error-reporting/utils/fuzzer.js | 110 +++++++++--------- 22 files changed, 215 insertions(+), 215 deletions(-) diff --git a/packages/error-reporting/README.md b/packages/error-reporting/README.md index a9b777b4d54..7e3ba7013f1 100644 --- a/packages/error-reporting/README.md +++ b/packages/error-reporting/README.md @@ -148,7 +148,7 @@ var app = express(); // Will create a errors instance based off env variables var errors = require('@google/cloud-errors')(); -app.get('/error', function( req, res, next ) { +app.get('/error', function(req, res, next) { res.send('Something broke!'); next(new Error('Custom error message')); }); @@ -175,7 +175,7 @@ server.start(); server.route({ method: 'GET', path: '/error', - handler: function( request, reply ) { + handler: function(request, reply) { throw new Error('Custom error message'); reply('Something broke!'); } diff --git a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js index 1b9e6230509..efbcc95c0c1 100644 --- a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js +++ b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js @@ -25,7 +25,7 @@ var originalHandlers = process.listeners('uncaughtException'); var UNCAUGHT = 'uncaughtException'; var client; -function reattachOriginalListeners ( ) { +function reattachOriginalListeners () { for (var i = 0; i < originalHandlers.length; i++) { process.on(UNCAUGHT, originalHandlers[i]); } @@ -64,7 +64,7 @@ describe('Uncaught Exception exit behaviour', function() { var id = 'xyz'; nock( 'http://metadata.google.internal/computeMetadata/v1/project' - ).get('/project-id').times(1).reply(200, id); + ).get('/project-id').times(1).reply(200, id); nock('https://accounts.google.com:443/o/oauth2') .post('/token').query(function() {return true;}).reply(200, { refresh_token: 'hello', @@ -74,7 +74,7 @@ describe('Uncaught Exception exit behaviour', function() { this.timeout(2000); nock( 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+id - ).post('/events:report').once().reply(200, function() { + ).post('/events:report').once().reply(200, function() { done(); return {success: true}; }); diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index 9ce71c01a9d..0dd6889ab65 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -61,7 +61,7 @@ describe('Behvaiour acceptance testing', function() { fakeService = nock( 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+ process.env.GCLOUD_PROJECT - ).persist().post('/events:report'); + ).persist().post('/events:report'); logger = createLogger({logLevel: 5}); client = new RequestHandler( new Configuration({ignoreEnvironmentCheck: true}, logger), logger); @@ -160,7 +160,7 @@ describe('Behvaiour acceptance testing', function() { assert(isObject(body) && isEmpty(body)); done(); } - ); + ); }); }); }); @@ -183,7 +183,7 @@ describe('Behvaiour acceptance testing', function() { assert(isObject(body) && isEmpty(body)); done(); } - ); + ); }); }); }); @@ -208,7 +208,7 @@ describe('Behvaiour acceptance testing', function() { assert(isObject(body) && isEmpty(body)); done(); } - ); + ); }); }); }); @@ -231,7 +231,7 @@ describe('Behvaiour acceptance testing', function() { assert(isObject(body) && isEmpty(body)); done(); } - ); + ); }); }); }); diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js index 1581f64295d..1617a7c9136 100644 --- a/packages/error-reporting/test/test-servers/express_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -30,10 +30,10 @@ var bodyParser = require('body-parser'); app.use(bodyParser.json()); -app.post('/testErrorHandling', function( req, res, next ) { +app.post('/testErrorHandling', function(req, res, next) { - if ( has(req.body, 'test') && req.body.test !== true ) { + if (has(req.body, 'test') && req.body.test !== true) { return next(new Error('Error on Express Regular Error POST Route')); } else { @@ -45,12 +45,12 @@ app.post('/testErrorHandling', function( req, res, next ) { ); app.get( - '/customError', function( req, res, next ) { + '/customError', function(req, res, next) { errorHandler.report( - 'Error on Express Custom Error GET Route', function( err, res ) { + 'Error on Express Custom Error GET Route', function(err, res) { - if ( err ) { + if (err) { console.log(WARNING_HEADER); console.log('Error in sending custom get error to api'); @@ -63,7 +63,7 @@ app.get( console.log(EXCLAMATION_LN); } } - ); + ); res.send('Success'); res.end(); @@ -73,7 +73,7 @@ app.get( ); app.get( - '/getError', function( req, res, next ) { + '/getError', function(req, res, next) { return next(new Error('Error on Express Regular Error GET Route')); } @@ -81,17 +81,17 @@ app.get( app.use(errorHandler.express); -function throwUncaughtError ( ) { +function throwUncaughtError () { console.log('Throwing an uncaught error..'); throw new Error('This is an uncaught error'); } -function reportManualError ( ) { +function reportManualError () { console.log('Reporting a manual error..'); errorHandler.report( - new Error('This is a manually reported error'), null, null, function( err, res ) { + new Error('This is a manually reported error'), null, null, function(err, res) { - if ( err ) { + if (err) { console.log(WARNING_HEADER); console.log('Got an error in sending error information to the API'); @@ -104,11 +104,11 @@ function reportManualError ( ) { console.log(EXCLAMATION_LN); } - if ( process.env.THROW_ON_STARTUP ) { + if (process.env.THROW_ON_STARTUP) { throwUncaughtError(); } } - ); + ); } console.log('reporting a manual error first'); errorHandler.report( @@ -125,7 +125,7 @@ errorHandler.report( app.listen( 3000, - function( ) { + function() { console.log('Scaffold Server has been started on port 3000'); reportManualError(); } diff --git a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js index ef7fb645713..4547a097e49 100644 --- a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js @@ -22,8 +22,8 @@ var server = new hapi.Server(); server.connection({ port: 3000 }); server.start( - ( err ) => { - if ( err ) { + (err) => { + if (err) { throw err; } console.log( @@ -32,14 +32,14 @@ server.start( ); server.route({ - method: 'GET', path: '/get', handler: function( request, reply ) { + method: 'GET', path: '/get', handler: function(request, reply) { console.log('Got a GET'); throw new Error('an error'); } }); server.route({ - method: 'POST', path: '/post', handler: function( request, reply ) { + method: 'POST', path: '/post', handler: function(request, reply) { console.log('Got a POST', request.payload); throw new Error('An error on the hapi post route'); } @@ -47,8 +47,8 @@ server.route({ server.register( - { register: errorHandler.hapi }, ( err ) => { - if ( err ) { + { register: errorHandler.hapi }, (err) => { + if (err) { console.error('There was an error in registering the plugin', err); } } diff --git a/packages/error-reporting/test/test-servers/manual_scaffold_server.js b/packages/error-reporting/test/test-servers/manual_scaffold_server.js index 8d562296641..1464f764279 100644 --- a/packages/error-reporting/test/test-servers/manual_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/manual_scaffold_server.js @@ -21,7 +21,7 @@ errors.report('Sample test string', (err, response, body) => { 'Callback from report:\n', '\tError: ', err, '\n', '\tResponse Body:', body - ); + ); }); var express = require('express'); diff --git a/packages/error-reporting/test/unit/testConfigCredentials.js b/packages/error-reporting/test/unit/testConfigCredentials.js index 8ec1d2964cf..0d7723b0bb4 100644 --- a/packages/error-reporting/test/unit/testConfigCredentials.js +++ b/packages/error-reporting/test/unit/testConfigCredentials.js @@ -124,7 +124,7 @@ describe('Testing use of runtime configurations', function() { }); }); } - ); + ); it('Should ignore credentials if keyFilename is provided', function(done) { var correctCredentials = require('../fixtures/gcloud-credentials.json'); var config = { diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index 2f062631ef3..c3327dbca58 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -69,7 +69,7 @@ describe('Configuration class', function() { assert.deepEqual(c._givenConfiguration, {}); }, ['object'] - ); + ); }); }); describe('valid config and default values', function() { @@ -174,7 +174,7 @@ describe('Configuration class', function() { }); }); } - ); + ); describe('Configuration resource aquisition', function() { before(function() {sterilizeEnv();}); describe('project id from configuration instance', function() { diff --git a/packages/error-reporting/test/unit/testCustomStackTrace.js b/packages/error-reporting/test/unit/testCustomStackTrace.js index ddee5867cc7..a66b505699a 100644 --- a/packages/error-reporting/test/unit/testCustomStackTrace.js +++ b/packages/error-reporting/test/unit/testCustomStackTrace.js @@ -30,7 +30,7 @@ describe('Fuzzing the CustomStackTrace class', function() { cs.filePath === 'test', 'Setting a valid string on the CustomStackTrace.filePath instance ' + 'should result in assignment' - ); + ); }); it('Should reject invalid type for file path', function() { cs.setFilePath(null); @@ -38,7 +38,7 @@ describe('Fuzzing the CustomStackTrace class', function() { cs.filePath === '', 'Setting an invalid type on the CustomStackTrace.filePath instance ' + 'should result in default value of an empty string' - ); + ); }); it('Should accept value for line number', function() { cs.setLineNumber(10); @@ -46,7 +46,7 @@ describe('Fuzzing the CustomStackTrace class', function() { cs.lineNumber === 10, 'Setting a valid number on the CustomStackTrace.lineNumber instance ' + 'should result in assignment' - ); + ); }); it('Should reject invalid type for line number', function() { cs.setLineNumber('10'); @@ -54,7 +54,7 @@ describe('Fuzzing the CustomStackTrace class', function() { cs.lineNumber === 0, 'Setting an invalid type on the CustomStackTrace.lineNumber instance ' + 'should result in default value of number 0' - ); + ); }); it('Should accept value for call list', function() { cs.setStringifyStructuredCallList(testFunction); @@ -63,7 +63,7 @@ describe('Fuzzing the CustomStackTrace class', function() { testFunction, 'Setting a valid function on the CustomStackTrace. ' + 'setStringifyStructuredCallList should result in assignment' - ); + ); }); it('Should reject incalid value for call list', function() { cs.setStringifyStructuredCallList(null); @@ -72,6 +72,6 @@ describe('Fuzzing the CustomStackTrace class', function() { 'Setting an invalid setStringifyStructuredCallList on the ' + 'CustomStackTrace. setStringifyStructuredCallList should result in a ' + 'default value of a function' - ); + ); }); }); diff --git a/packages/error-reporting/test/unit/testErrorMessage.js b/packages/error-reporting/test/unit/testErrorMessage.js index 04368252807..043d91b1f7b 100644 --- a/packages/error-reporting/test/unit/testErrorMessage.js +++ b/packages/error-reporting/test/unit/testErrorMessage.js @@ -27,7 +27,7 @@ describe('Instantiating a new ErrorMessage', function() { assert.deepEqual( em.serviceContext, { service: 'node', version: undefined } - ); + ); }); it('Should have a default message', function() { assert.strictEqual(em.message, ''); @@ -43,7 +43,7 @@ describe('Instantiating a new ErrorMessage', function() { responseStatusCode: 0, remoteIp: '' } - ); + ); }); it('Should have a default reportLocation', function() { assert.deepEqual( @@ -53,7 +53,7 @@ describe('Instantiating a new ErrorMessage', function() { lineNumber: 0, functionName: '' } - ); + ); }) }); @@ -86,7 +86,7 @@ describe('Fuzzing against setServiceContext', function() { 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should set the default values', function() { em.setServiceContext(DEFAULT_TEST_VALUE, DEFAULT_TEST_VALUE); @@ -100,7 +100,7 @@ describe('Fuzzing against setServiceContext', function() { 'In resetting to default valid values the instance should reflect the' , 'value update' ].join(' ') - ); + ); }); it('Should still set version with affirmative value', function() { em.setServiceContext(null, AFFIRMATIVE_TEST_VALUE); @@ -115,7 +115,7 @@ describe('Fuzzing against setServiceContext', function() { , 'setServiceContext should set the service property as an empty string' , 'but set the version property to the affirmative value.' ].join(' ') - ); + ); }); it('Should still set service with affirmative value', function() { em.setServiceContext(AFFIRMATIVE_TEST_VALUE, null); @@ -130,7 +130,7 @@ describe('Fuzzing against setServiceContext', function() { , 'setServiceContext should set the version property as an empty string' , 'but set the service property to the affirmative value.' ].join(' ') - ); + ); }); it('Should set default values on both', function() { em.setServiceContext(null, null); @@ -144,7 +144,7 @@ describe('Fuzzing against setServiceContext', function() { 'Providing null as the value to both arguments should set both' , 'properties as empty strings.' ].join(' ') - ); + ); }); it('Should set default values on both', function() { em.setServiceContext(2, 1.3); @@ -158,7 +158,7 @@ describe('Fuzzing against setServiceContext', function() { 'Providing numbers as the value to both arguments should set both' , 'properties as empty strings.' ].join(' ') - ); + ); }); it('Should set as default', function() { em.setServiceContext({ test: 'true' }, []); @@ -172,7 +172,7 @@ describe('Fuzzing against setServiceContext', function() { 'Providing arrays or objects as the value to both arguments' , 'should set both properties as empty strings.' ].join(' ') - ); + ); }); it('Should set as default', function() { em.setServiceContext(); @@ -183,7 +183,7 @@ describe('Fuzzing against setServiceContext', function() { , version: DEFAULT_VERSION_VALUE } , 'Providing no arguments should set both properties as empty strings' - ); + ); }) }); @@ -203,7 +203,7 @@ describe( 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setMessage(); @@ -213,7 +213,7 @@ describe( 'By providing no argument (undefined) to setMessage the property' , 'message should be set to an empty string on the instance' ].join(' ') - ); + ); }); } ); @@ -233,7 +233,7 @@ describe( 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setHttpMethod(); @@ -243,7 +243,7 @@ describe( 'By providing no argument (undefined) to setHttpMethod the property' , 'message should be set to an empty string on the instance' ].join(' ') - ); + ); }); } ); @@ -263,7 +263,7 @@ describe( 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setUrl(); @@ -273,7 +273,7 @@ describe( 'By providing no argument (undefined) to setUrl the property' , 'message should be set to an empty string on the instance' ].join(' ') - ); + ); }); } ); @@ -294,7 +294,7 @@ describe( 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setUserAgent(); @@ -304,7 +304,7 @@ describe( 'By providing no argument (undefined) to setUserAgent the property' , 'message should be set to an empty string on the instance' ].join(' ') - ); + ); }); } ); @@ -322,7 +322,7 @@ describe('Fuzzing against setReferrer', function() { 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setReferrer(); @@ -332,7 +332,7 @@ describe('Fuzzing against setReferrer', function() { 'By providing no argument (undefined) to setReferrer the property' , 'message should be set to an empty string on the instance' ].join(' ') - ); + ); }); }); @@ -349,7 +349,7 @@ describe('Fuzzing against setResponseStatusCode', function() { 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setResponseStatusCode(); @@ -359,7 +359,7 @@ describe('Fuzzing against setResponseStatusCode', function() { 'By providing no argument (undefined) to setResponseStatusCode the property' , 'message should be set to an empty string on the instance' ].join(' ') - ); + ); }); }); @@ -376,7 +376,7 @@ describe('Fuzzing against setRemoteIp', function() { 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setRemoteIp(); @@ -386,7 +386,7 @@ describe('Fuzzing against setRemoteIp', function() { 'By providing no argument (undefined) to setRemoteIp the property' , 'message should be set to an empty string on the instance' ].join(' ') - ); + ); }); }); @@ -405,7 +405,7 @@ describe( 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setUser(); @@ -415,7 +415,7 @@ describe( 'By providing no argument (undefined) to setUser the property' , 'user should be set to an empty string on the instance' ].join(' ') - ); + ); }); } ); @@ -433,7 +433,7 @@ describe('Fuzzing against setFilePath', function() { 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setFilePath(); @@ -443,7 +443,7 @@ describe('Fuzzing against setFilePath', function() { 'By providing no argument (undefined) to setFilePath the property' , 'filePath should be set to an empty string on the instance' ].join(' ') - ); + ); }); }); @@ -460,7 +460,7 @@ describe('Fuzzing against setLineNumber', function() { 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setLineNumber(); @@ -470,7 +470,7 @@ describe('Fuzzing against setLineNumber', function() { 'By providing no argument (undefined) to setLineNumber the property' , 'lineNumber should be set to an empty string on the instance' ].join(' ') - ); + ); }); }); @@ -487,7 +487,7 @@ describe('Fuzzing against setFunctionName', function() { 'In the affirmative case the value should be settable to a valid string' , 'and by setting this value this should mutate the instance' ].join(' ') - ); + ); }); it('Should default', function() { em.setFunctionName(); @@ -497,7 +497,7 @@ describe('Fuzzing against setFunctionName', function() { 'By providing no argument (undefined) to setFunctionName the property' , 'functionName should be set to an empty string on the instance' ].join(' ') - ); + ); }); }); @@ -532,42 +532,42 @@ describe('Fuzzing against consumeRequestInformation', function() { 'The error messages method, given a valid string, should be' , 'set to that value' ].join(' ') - ); + ); assert( em.context.httpRequest.url === A_VALID_STRING , [ 'The error messages url, given a valid string, should be' , 'set to that value' ].join(' ') - ); + ); assert( em.context.httpRequest.userAgent === A_VALID_STRING , [ 'The error messages userAgent, given a valid string, should be' , 'set to that value' ].join(' ') - ); + ); assert( em.context.httpRequest.referrer === A_VALID_STRING , [ 'The error messages referrer, given a valid string, should be' , 'set to that value' ].join(' ') - ); + ); assert( em.context.httpRequest.responseStatusCode === A_VALID_NUMBER , [ 'The error messages responseStatusCode, given a valid number, should be' , 'set to that value' ].join(' ') - ); + ); assert( em.context.httpRequest.remoteIp === A_VALID_STRING , [ 'The error messages remoteAddress, given a valid string, should be' , 'set to that value' ].join(' ') - ); + ); }); it('Should default when consuming a malformed request object', function() { em.consumeRequestInformation(null); @@ -577,42 +577,42 @@ describe('Fuzzing against consumeRequestInformation', function() { 'The error messages method, given an invalid type a the top-level' , 'should remain untouched' ].join(' ') - ); + ); assert( em.context.httpRequest.url === A_VALID_STRING , [ 'The error messages url, given an invalid type a the top-level' , 'should remain untouched' ].join(' ') - ); + ); assert( em.context.httpRequest.userAgent === A_VALID_STRING , [ 'The error messages userAgent, given an invalid type a the top-level' , 'should remain untouched' ].join(' ') - ); + ); assert( em.context.httpRequest.referrer === A_VALID_STRING , [ 'The error messages referrer, given an invalid type a the top-level' , 'should remain untouched' ].join(' ') - ); + ); assert( em.context.httpRequest.responseStatusCode === A_VALID_NUMBER , [ 'The error messages responseStatusCode, given an invalid type a the top-level' , 'should remain untouched' ].join(' ') - ); + ); assert( em.context.httpRequest.remoteIp === A_VALID_STRING , [ 'The error messages remoteAddress, given an invalid type a the top-level' , 'should remain untouched' ].join(' ') - ); + ); }); it('Should default when consuming mistyped response object properties', function() { @@ -623,44 +623,44 @@ describe('Fuzzing against consumeRequestInformation', function() { 'The error messages method, given an invalid input should default to' , 'the negative value' ].join(' ') - ); + ); assert( em.context.httpRequest.url === NEGATIVE_STRING_CASE , [ 'The error messages url, given an invalid input should default to' , 'the negative value' ].join(' ') - ); + ); assert( em.context.httpRequest.userAgent === NEGATIVE_STRING_CASE , [ 'The error messages userAgent, ggiven an invalid input should default to' , 'the negative value' ].join(' ') - ); + ); assert( em.context.httpRequest.referrer === NEGATIVE_STRING_CASE , [ 'The error messages referrer, given an invalid input should default to' , 'the negative value' ].join(' ') - ); + ); assert( em.context.httpRequest.responseStatusCode === NEGATIVE_NUMBER_CASE , [ 'The error messages responseStatusCode, given an invalid input should default to' , 'the negative value' ].join(' ') - ); + ); assert( em.context.httpRequest.remoteIp === NEGATIVE_STRING_CASE , [ 'The error messages remoteAddress, given an invalid input should default to' , 'the negative value' ].join(' ') - ); + ); } - ); + ); it('Should return the instance on calling consumeRequestInformation', function() { assert( @@ -669,14 +669,14 @@ describe('Fuzzing against consumeRequestInformation', function() { 'Calling consumeRequestInformation with valid input should return' , 'the ErrorMessage instance' ].join(' ') - ); + ); assert( em.consumeRequestInformation() instanceof ErrorMessage , [ 'Calling consumeRequestInformation with invalid input should return' , 'the ErrorMessage instance' ].join(' ') - ); + ); } - ); + ); }); diff --git a/packages/error-reporting/test/unit/testExpressInterface.js b/packages/error-reporting/test/unit/testExpressInterface.js index 5a032c19cd1..bdffab630aa 100644 --- a/packages/error-reporting/test/unit/testExpressInterface.js +++ b/packages/error-reporting/test/unit/testExpressInterface.js @@ -33,10 +33,10 @@ describe('expressInterface', function() { function() { f.fuzzFunctionForTypes( expressInterface, ['object', 'object'] - ); + ); return; } - ); + ); }); }); }); @@ -65,8 +65,8 @@ describe('expressInterface', function() { stubbedConfig._serviceContext.service, stubbedConfig._serviceContext.version), {eventTime: res.eventTime} - ) - ); + ) + ); }); describe('Calling back to express builtins', function() { it('Should callback to next', function(done) { diff --git a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js index 1ddfd4bd702..67bf0be19f9 100644 --- a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js @@ -104,7 +104,7 @@ describe('Behaviour under varying input', }; var headerFactory = function(toDeriveFrom) { var lrn = extend({}, toDeriveFrom); - lrn.header = function( toRet ) { + lrn.header = function(toRet) { if (lrn.hasOwnProperty(toRet)) { return lrn[toRet]; } @@ -115,7 +115,7 @@ describe('Behaviour under varying input', var tmpOutput = expressRequestInformationExtractor( headerFactory(FULL_REQ_DERIVATION_VALUE), FULL_RES_DERIVATION_VALUE - ); + ); assert.deepEqual(tmpOutput, FULL_REQ_EXPECTED_VALUE, [ 'Given a valid object input for the request parameter and an', @@ -123,11 +123,11 @@ describe('Behaviour under varying input', 'the expected full req output and the \'x-forwarded-for\' value', 'as the value for the \'remoteAddress\' property.' ].join(' ') - ); + ); tmpOutput = expressRequestInformationExtractor( headerFactory(PARTIAL_REQ_DERIVATION_VALUE), PARTIAL_RES_DERIVATION_VALUE - ); + ); assert.deepEqual( tmpOutput, PARTIAL_REQ_EXPECTED_VALUE, @@ -137,11 +137,11 @@ describe('Behaviour under varying input', 'the expected parital req output and the remoteAddress value', 'as the value for the \'remoteAddress\' property.' ].join(' ') - ); + ); tmpOutput = expressRequestInformationExtractor( headerFactory(ANOTHER_PARTIAL_REQ_DERIVATION_VALUE), ANOTHER_PARTIAL_RES_DERIVATION_VALUE - ); + ); assert.deepEqual( tmpOutput, ANOTHER_PARTIAL_REQ_EXPECTED_VALUE, @@ -151,7 +151,7 @@ describe('Behaviour under varying input', 'the request extractor should return an empty string', 'as the value for the \'remoteAddress\' property.' ].join(' ') - ); + ); } - ); + ); }); diff --git a/packages/error-reporting/test/unit/testExtractFromErrorClass.js b/packages/error-reporting/test/unit/testExtractFromErrorClass.js index 0b8d9e65d84..76c2a532975 100644 --- a/packages/error-reporting/test/unit/testExtractFromErrorClass.js +++ b/packages/error-reporting/test/unit/testExtractFromErrorClass.js @@ -30,7 +30,7 @@ describe('Writing and reading ErrorMessage properties', function() { extractFromErrorClass(err, em); assert.deepEqual(em.message, err.stack, 'Given a valid message the ' + 'error message should absorb the error stack as the message' - ); + ); }); }); describe('User field', function() { diff --git a/packages/error-reporting/test/unit/testHapiInterface.js b/packages/error-reporting/test/unit/testHapiInterface.js index 71a10589f12..702fd1bb775 100644 --- a/packages/error-reporting/test/unit/testHapiInterface.js +++ b/packages/error-reporting/test/unit/testHapiInterface.js @@ -52,26 +52,26 @@ describe('Hapi interface', function() { assert(has(plugin.register, 'attributes') && isObject(plugin.register.attributes)); } - ); + ); it('the plugin\'s attribute property should have a name property', function() { assert(has(plugin.register.attributes, 'name')); assert.strictEqual(plugin.register.attributes.name, '@google/cloud-errors'); } - ); + ); it('the plugin\'s attribute property should have a version property', function() { assert(has(plugin.register.attributes, 'version')); } - ); + ); }); describe('hapiRegisterFunction behaviour', function() { var fakeServer; beforeEach(function() {fakeServer = new EventEmitter();}); it('Should call sendError when the request-error event is emitted', function() { var fakeClient = { - sendError: function( errMsg ) { + sendError: function(errMsg) { assert(errMsg instanceof ErrorMessage, 'The value given to sendError should be an instance of Error message'); } @@ -121,7 +121,7 @@ describe('Hapi interface', function() { done(); } } - ); + ); }); it('Should call sendError when a boom response is received', function(done) { var fakeClient = { diff --git a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js index e22e1dba45b..e53df0c7a7a 100644 --- a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js @@ -39,7 +39,7 @@ describe('hapiRequestInformationExtractor behaviour', function() { hapiRequestInformationExtractor, ['object'], cbFn - ); + ); }); }); describe('behaviour given valid input', function() { @@ -120,7 +120,7 @@ describe('hapiRequestInformationExtractor behaviour', function() { assert.deepEqual( hapiRequestInformationExtractor(ANOTHER_PARTIAL_REQ_DERIVATION_VALUE), ANOTHER_PARTIAL_REQ_EXPECTED_VALUE - ); + ); }); }); }); diff --git a/packages/error-reporting/test/unit/testManualHandler.js b/packages/error-reporting/test/unit/testManualHandler.js index 8547df6ae64..b7722a8458e 100644 --- a/packages/error-reporting/test/unit/testManualHandler.js +++ b/packages/error-reporting/test/unit/testManualHandler.js @@ -150,7 +150,7 @@ describe('Manual handler', function() { var r = report( new ErrorMessage().setMessage(msg).consumeRequestInformation(oldReq), newReq - ); + ); assert.strictEqual(r.message, msg, 'string message should propagate from error message instance'); assert.strictEqual(r.context.httpRequest.method, newReq.method, @@ -158,7 +158,7 @@ describe('Manual handler', function() { 'request argument supplied at report invocation should propagte and, if', 'supplied, should overwrite any prexisting data in the field.' ].join('\n') - ); + ); }); it('Should accept message and additional message params as arguments', function() { var oldMsg = 'test'; @@ -166,7 +166,7 @@ describe('Manual handler', function() { var r = report( new ErrorMessage().setMessage(oldMsg), newMsg - ); + ); assert.strictEqual(r.message, newMsg, [ 'message argument supplied at report invocation should propagte and, if', @@ -178,7 +178,7 @@ describe('Manual handler', function() { report( new ErrorMessage().setMessage(oldMsg), function() { done(); } - ); + ); }); }); }); diff --git a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js index 93d32501d35..ff75f1eb9b9 100644 --- a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js @@ -58,7 +58,7 @@ describe('manualRequestInformationExtractor', function() { 'Given a full valid input object these values should be reflected by', 'the output of the request extraction' ].join(' ') - ); + ); assert.deepEqual( manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'method')), extend({}, FULL_VALID_INPUT, {method: ''}), @@ -66,7 +66,7 @@ describe('manualRequestInformationExtractor', function() { 'Given a full valid input object sans the method property these values', 'should be reflected by the output of the request extraction' ].join(' ') - ); + ); assert.deepEqual( manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'url')), extend({}, FULL_VALID_INPUT, {url: ''}), @@ -74,7 +74,7 @@ describe('manualRequestInformationExtractor', function() { 'Given a full valid input sans the url property these values should be', 'reflected by the output of the request extraction' ] - ); + ); assert.deepEqual( manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'userAgent')), extend({}, FULL_VALID_INPUT, {'userAgent': ''}), @@ -82,7 +82,7 @@ describe('manualRequestInformationExtractor', function() { 'Given a full valid input sans the userAgent property these values', 'should be reflected by the output of the request extraction' ] - ); + ); assert.deepEqual( manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'referrer')), extend({}, FULL_VALID_INPUT, {referrer: ''}), @@ -90,7 +90,7 @@ describe('manualRequestInformationExtractor', function() { 'Given a full valid input sans the referrer property these values', 'should be reflected by the output of the request extraction' ] - ); + ); assert.deepEqual( manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'statusCode')), extend({}, FULL_VALID_INPUT, {statusCode: 0}), @@ -98,7 +98,7 @@ describe('manualRequestInformationExtractor', function() { 'Given a full valid input sans the statusCode property these values', 'should be reflected by the output of the request extraction' ] - ); + ); assert.deepEqual( manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'remoteAddress')), extend({}, FULL_VALID_INPUT, {remoteAddress: ''}), @@ -106,7 +106,7 @@ describe('manualRequestInformationExtractor', function() { 'Given a full valid input sans the remoteAddress property these values', 'should be reflected by the output of the request extraction' ] - ); + ); }); }); }); diff --git a/packages/error-reporting/test/unit/testRequestInformationContainer.js b/packages/error-reporting/test/unit/testRequestInformationContainer.js index 2bb0d4446f1..4e78b33b878 100644 --- a/packages/error-reporting/test/unit/testRequestInformationContainer.js +++ b/packages/error-reporting/test/unit/testRequestInformationContainer.js @@ -32,33 +32,33 @@ describe('RequestInformationContainer', function() { }; f.fuzzFunctionForTypes(ric.setUrl, ['string'], cbFn, ric); } - ); + ); it('Should return the method property as an empty string', function() { - cbFn = function( returnValue ) { + cbFn = function(returnValue) { assert.deepEqual(ric.method, ''); }; f.fuzzFunctionForTypes(ric.setMethod, ['string'], cbFn, ric); }); it('Should return the referrer property as an empty string', function() { - cbFn = function( returnValue ) { + cbFn = function(returnValue) { assert.deepEqual(ric.referrer, ''); }; f.fuzzFunctionForTypes(ric.setReferrer, ['string'], cbFn, ric); }); it('Should return the userAgent property as an empty string', function() { - cbFn = function( returnValue ) { + cbFn = function(returnValue) { assert.deepEqual(ric.userAgent, ''); }; f.fuzzFunctionForTypes(ric.setUserAgent, ['string'], cbFn, ric); }); it('Should return the remoteAddress property as an empty string', function() { - cbFn = function( returnValue ) { + cbFn = function(returnValue) { assert.deepEqual(ric.remoteAddress, ''); }; f.fuzzFunctionForTypes(ric.setRemoteAddress, ['string'], cbFn, ric); }); it('Should return the default value for statusCode', function() { - cbFn = function( returnValue ) { + cbFn = function(returnValue) { assert.strictEqual(ric.statusCode, 0); }; f.fuzzFunctionForTypes(ric.setStatusCode, ['number'], cbFn, ric); diff --git a/packages/error-reporting/test/unit/testRestifyInterface.js b/packages/error-reporting/test/unit/testRestifyInterface.js index a24c97d2119..d97e13ba289 100644 --- a/packages/error-reporting/test/unit/testRestifyInterface.js +++ b/packages/error-reporting/test/unit/testRestifyInterface.js @@ -85,7 +85,7 @@ describe('restifyInterface', function() { } }; var config = { - getServiceContext: function( ) { + getServiceContext: function() { assert(true, 'getServiceContext should be called'); return { service: 'stub-service', diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index 088b3211f5c..95336bee9e2 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -67,7 +67,7 @@ describe('Testing service configuration', function() { // the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } - ); + ); it( 'A Configuration uses the function name as the service name on GCF ' + 'if the service name is not given in the given config ' + @@ -80,7 +80,7 @@ describe('Testing service configuration', function() { // so the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } - ); + ); it( 'A Configuration uses the GAE_SERVICE env value as the service name ' + 'if the FUNCTION_NAME env variable is not set and the given config ' + @@ -93,7 +93,7 @@ describe('Testing service configuration', function() { // and so use the GAE_MODULE_VERSION assert.deepEqual(c.getServiceContext().version, '1.0'); } - ); + ); it( 'A Configuration uses the service name in the given config if it ' + 'was specified and both the GAE_SERVICE and FUNCTION_NAME ' + @@ -111,7 +111,7 @@ describe('Testing service configuration', function() { // so the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } - ); + ); it( 'A Configuration uses the service name and version in the given config if ' + 'they were both specified and both the GAE_SERVICE and FUNCTION_NAME ' + @@ -129,7 +129,7 @@ describe('Testing service configuration', function() { // The user specified version should be used assert.deepEqual(c.getServiceContext().version, '2.0'); } - ); + ); it( 'A Configuration uses the service name in the given config if it ' + 'was specified and only the GAE_SERVICE env var is set', @@ -145,7 +145,7 @@ describe('Testing service configuration', function() { // and so the GAE_MODULE_VERSION should be used assert.deepEqual(c.getServiceContext().version, '1.0'); } - ); + ); it( 'A Configuration uses the service name and version in the given config if ' + 'they were both specified and only the GAE_SERVICE env var is set', @@ -161,7 +161,7 @@ describe('Testing service configuration', function() { // The user specified version should be used assert.deepEqual(c.getServiceContext().version, '2.0'); } - ); + ); it( 'A Configuration uses the service name in the given config if it ' + 'was specified and only the FUNCTION_NAME env var is set', @@ -177,7 +177,7 @@ describe('Testing service configuration', function() { // defined the version should not be defined assert.deepEqual(c.getServiceContext().version, undefined); } - ); + ); it( 'A Configuration uses the service name and version in the given config if ' + 'they were both specified and only the FUNCTION_NAME env var is set', @@ -193,7 +193,7 @@ describe('Testing service configuration', function() { // The user specified version should be used assert.strictEqual(c.getServiceContext().version, '2.0'); } - ); + ); it( 'A Configuration uses the service name "node" and no version if ' + 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ @@ -203,7 +203,7 @@ describe('Testing service configuration', function() { assert.strictEqual(c.getServiceContext().service, 'node'); assert.strictEqual(c.getServiceContext().version, undefined); } - ); + ); it( 'A Configuration uses the service name "node" and no version if ' + 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ @@ -215,7 +215,7 @@ describe('Testing service configuration', function() { assert.strictEqual(c.getServiceContext().service, 'node'); assert.strictEqual(c.getServiceContext().version, undefined); } - ); + ); it( 'A Configuration uses the service name "node" and the user specified ' + 'version if GAE_SERVICE is not set, FUNCTION_NAME is not set, and the ' + @@ -229,7 +229,7 @@ describe('Testing service configuration', function() { assert.deepEqual(c.getServiceContext().service, 'node'); assert.deepEqual(c.getServiceContext().version, '2.0'); } - ); + ); // it( // 'A Configuration uses the service name "node" and the user specified ' + @@ -250,7 +250,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // // The following tests always have GAE_SERVICE and GAE_VERSION not set // it( @@ -267,7 +267,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -284,7 +284,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -301,7 +301,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -322,7 +322,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -343,7 +343,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -363,7 +363,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -383,7 +383,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -403,7 +403,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -423,7 +423,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -438,7 +438,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -454,7 +454,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -473,7 +473,7 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); // it( // 'With GAE_SERVICE and GAE_VERSION not set: ' + @@ -493,5 +493,5 @@ describe('Testing service configuration', function() { // done(); // }) - // ); + //); }); diff --git a/packages/error-reporting/test/unit/testUncaught.js b/packages/error-reporting/test/unit/testUncaught.js index adb53df8746..a2a41c5c6e0 100644 --- a/packages/error-reporting/test/unit/testUncaught.js +++ b/packages/error-reporting/test/unit/testUncaught.js @@ -24,7 +24,7 @@ var createLogger = require('../../src/logger.js'); var originalHandlers = process.listeners('uncaughtException'); var spawn = require('child_process').spawn; -function reattachOriginalListeners ( ) { +function reattachOriginalListeners () { for (var i = 0; i < originalHandlers.length; i++) { process.on('uncaughtException', originalHandlers[i]); } diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js index 7c20703dc5b..039fbd41ad6 100644 --- a/packages/error-reporting/utils/fuzzer.js +++ b/packages/error-reporting/utils/fuzzer.js @@ -29,11 +29,11 @@ var isArray = is.array; var isNull = is.null; var isFunction = is.function; -function Fuzzer ( ) { } +function Fuzzer () { } Fuzzer.prototype.generate = {}; -Fuzzer.prototype.generate.types = function( ) { +Fuzzer.prototype.generate.types = function() { return [ "object", "array", @@ -46,11 +46,11 @@ Fuzzer.prototype.generate.types = function( ) { ]; } -Fuzzer.prototype.generate.string = function( len ) { +Fuzzer.prototype.generate.string = function(len) { var lenChecked = isNumber(len) ? len : 10; var chars = []; - for ( var i = 0; i < lenChecked; i++ ) { + for (var i = 0; i < lenChecked; i++) { chars.push(String.fromCharCode(random(32, 126))); } @@ -58,18 +58,18 @@ Fuzzer.prototype.generate.string = function( len ) { return chars.join(""); }; -Fuzzer.prototype.generate.boolean = function( ) { +Fuzzer.prototype.generate.boolean = function() { return !!random(0, 1); } -Fuzzer.prototype.generate.alphaNumericString = function( len ) { +Fuzzer.prototype.generate.alphaNumericString = function(len) { var lenChecked = isNumber(len) ? len : 10; var chars = []; var thisRange = []; var ranges = [[48, 57], [65, 90], [97, 122]]; - for ( var i = 0; i < lenChecked; i++ ) { + for (var i = 0; i < lenChecked; i++) { thisRange = ranges[random(0, 2)]; chars.push( @@ -77,27 +77,27 @@ Fuzzer.prototype.generate.alphaNumericString = function( len ) { random( thisRange[0] , thisRange[1] - ) - ) - ); + ) + ) + ); } return chars.join(""); } -Fuzzer.prototype.generate.function = function( ) { +Fuzzer.prototype.generate.function = function() { var availableTypes = without(this.types(), "function"); var typeToGen = this.types()[random(0, availableTypes.length-1)]; var fnToCall = this[typeToGen]; - return function( ) { + return function() { return fnToCall(); }; } -Fuzzer.prototype.generate.number = function( lower, upper ) { +Fuzzer.prototype.generate.number = function(lower, upper) { var lowerChecked = isNumber(lower) ? lower : 0; var upperChecked = isNumber(upper) ? upper : 100; @@ -105,17 +105,17 @@ Fuzzer.prototype.generate.number = function( lower, upper ) { return random(lowerChecked, upperChecked); } -Fuzzer.prototype.generate.null = function( ) { +Fuzzer.prototype.generate.null = function() { return null; } -Fuzzer.prototype.generate.undefined = function( ) { +Fuzzer.prototype.generate.undefined = function() { return undefined; } -Fuzzer.prototype.generate.array = function( len, ofOneType, currentDepth, allowedDepth ) { +Fuzzer.prototype.generate.array = function(len, ofOneType, currentDepth, allowedDepth) { var lenChecked = isNumber(len) ? len : random(1, 10); var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType] : this.types(); @@ -126,24 +126,24 @@ Fuzzer.prototype.generate.array = function( len, ofOneType, currentDepth, allowe currentDepthChecked += 1; // Deny the ability to nest more objects - if ( currentDepthChecked >= allowedDepthChecked ) { + if (currentDepthChecked >= allowedDepthChecked) { availableTypes = without(this.types(), "object", "array"); } - for ( var i = 0; i < lenChecked; i++ ) { + for (var i = 0; i < lenChecked; i++) { currentTypeBeingGenerated = availableTypes[random(0, availableTypes.length-1)]; - if ( currentTypeBeingGenerated === "object" ) { + if (currentTypeBeingGenerated === "object") { arr.push( this[currentTypeBeingGenerated]( null , currentDepthChecked , allowedDepthChecked - ) - ); - } else if ( currentTypeBeingGenerated === "array" ) { + ) + ); + } else if (currentTypeBeingGenerated === "array") { arr.push( this[currentTypeBeingGenerated]( @@ -151,8 +151,8 @@ Fuzzer.prototype.generate.array = function( len, ofOneType, currentDepth, allowe , ofOneType , currentDepthChecked , allowedDepthChecked - ) - ); + ) + ); } else { arr.push(this[currentTypeBeingGenerated]()); @@ -162,7 +162,7 @@ Fuzzer.prototype.generate.array = function( len, ofOneType, currentDepth, allowe return arr; } -Fuzzer.prototype.generate.object = function( numProperties, currentDepth, allowedDepth ) { +Fuzzer.prototype.generate.object = function(numProperties, currentDepth, allowedDepth) { var numPropertiesChecked = isNumber(numProperties) ? numProperties : random(1, 10); var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; @@ -173,22 +173,22 @@ Fuzzer.prototype.generate.object = function( numProperties, currentDepth, allowe var availableTypes = this.types() // Deny the ability to nest more objects - if ( currentDepth >= allowedDepth ) { + if (currentDepth >= allowedDepth) { availableTypes = without(availableTypes, "object", "array"); } var currentTypeBeingGenerated = 0; var currentKey = ""; - for ( var i = 0; i < numPropertiesChecked; i++ ) { + for (var i = 0; i < numPropertiesChecked; i++) { currentTypeBeingGenerated = availableTypes[random(0, availableTypes.length-1)]; currentKey = this.alphaNumericString(random(1, 10)); - if ( currentTypeBeingGenerated === "object" ) { + if (currentTypeBeingGenerated === "object") { obj[currentKey] = this[currentTypeBeingGenerated](null, currentDepthChecked, allowedDepthChecked); - } else if ( currentTypeBeingGenerated === "array" ) { + } else if (currentTypeBeingGenerated === "array") { obj[currentKey] = this[currentTypeBeingGenerated](null, null, currentDepthChecked, allowedDepthChecked); } else { @@ -200,21 +200,21 @@ Fuzzer.prototype.generate.object = function( numProperties, currentDepth, allowe return obj; } -Fuzzer.prototype._backFillUnevenTypesArrays = function( argsTypesArray ) { +Fuzzer.prototype._backFillUnevenTypesArrays = function(argsTypesArray) { var largestIndex = 0; var largestLength = (maxBy( argsTypesArray - , function( o ) { return o.length } - )).length; + , function(o) { return o.length } + )).length; - for ( var i = 0; i < argsTypesArray.length; i++ ) { - if ( argsTypesArray[i].length !== largestLength ) { + for (var i = 0; i < argsTypesArray.length; i++) { + if (argsTypesArray[i].length !== largestLength) { - while ( argsTypesArray[i].length < largestLength ) { + while (argsTypesArray[i].length < largestLength) { argsTypesArray[i].push( argsTypesArray[i][random(0, argsTypesArray[i].length-1)] - ); + ); } } } @@ -222,49 +222,49 @@ Fuzzer.prototype._backFillUnevenTypesArrays = function( argsTypesArray ) { return argsTypesArray; } -Fuzzer.prototype._normalizeTypesArrayLengths = function( argsTypesArray ) { +Fuzzer.prototype._normalizeTypesArrayLengths = function(argsTypesArray) { var allAreTheSameLength = true; var lastLength = argsTypesArray[0].length; - for ( var i = 1; i < argsTypesArray.length; i++ ) { + for (var i = 1; i < argsTypesArray.length; i++) { - if ( argsTypesArray[i].length !== lastLength ) { + if (argsTypesArray[i].length !== lastLength) { allAreTheSameLength = false; break; } } - if ( allAreTheSameLength ) { + if (allAreTheSameLength) { return argsTypesArray; } - return this._backFillUnevenTypesArrays( argsTypesArray ); + return this._backFillUnevenTypesArrays(argsTypesArray); } -Fuzzer.prototype._generateTypesToFuzzWith = function( expectsArgTypes ) { +Fuzzer.prototype._generateTypesToFuzzWith = function(expectsArgTypes) { var argsTypesArray = []; var tmpArray = this.generate.types(); - for ( var i = 0; i < expectsArgTypes.length; i++ ) { + for (var i = 0; i < expectsArgTypes.length; i++) { - if ( !isArray(expectsArgTypes[i]) ) { + if (!isArray(expectsArgTypes[i])) { argsTypesArray.push( without( this.generate.types() , expectsArgTypes[i] - ) - ); + ) + ); } else { - for ( var j = 0; j < expectsArgTypes[i].length; j++ ) { + for (var j = 0; j < expectsArgTypes[i].length; j++) { tmpArray = without( tmpArray , expectsArgTypes[i][j] - ); + ); } argsTypesArray.push([].concat(tmpArray)); @@ -276,11 +276,11 @@ Fuzzer.prototype._generateTypesToFuzzWith = function( expectsArgTypes ) { return argsTypesArray; } -Fuzzer.prototype._generateValuesForFuzzTyping = function( typesToFuzzOnEach, index ) { +Fuzzer.prototype._generateValuesForFuzzTyping = function(typesToFuzzOnEach, index) { var args = []; var typeToGen = ""; - for ( var i = 0; i < typesToFuzzOnEach.length; i++ ) { + for (var i = 0; i < typesToFuzzOnEach.length; i++) { typeToGen = typesToFuzzOnEach[i][index]; args.push(this.generate[typeToGen]()); @@ -289,21 +289,21 @@ Fuzzer.prototype._generateValuesForFuzzTyping = function( typesToFuzzOnEach, ind return args; } -Fuzzer.prototype.fuzzFunctionForTypes = function( fnToFuzz, expectsArgTypes, cb, withContext ) { +Fuzzer.prototype.fuzzFunctionForTypes = function(fnToFuzz, expectsArgTypes, cb, withContext) { var expectsArgTypesChecked = isArray(expectsArgTypes) ? expectsArgTypes : []; - var typesToFuzzOnEach = this._generateTypesToFuzzWith( expectsArgTypesChecked ); + var typesToFuzzOnEach = this._generateTypesToFuzzWith(expectsArgTypesChecked); var withContextChecked = (withContext !== undefined) ? withContext : null; var returnValue = undefined; - for ( var i = 0; i < typesToFuzzOnEach[0].length; i++ ) { + for (var i = 0; i < typesToFuzzOnEach[0].length; i++) { returnValue = fnToFuzz.apply( withContext , this._generateValuesForFuzzTyping(typesToFuzzOnEach, i) - ); + ); - if ( isFunction(cb) ) { + if (isFunction(cb)) { cb(returnValue); } From 2c692cece954d85b3be052d3fef3ddd76e41d154 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 09:28:29 -0800 Subject: [PATCH 08/29] remove all leading colon spaces --- .../src/classes/custom-stack-trace.js | 8 ++--- .../src/classes/error-message.js | 30 +++++++++---------- .../classes/request-information-container.js | 12 ++++---- packages/error-reporting/src/configuration.js | 6 ++-- .../src/google-apis/auth-client.js | 2 +- .../error-reporting/src/interfaces/hapi.js | 8 ++--- .../test/unit/testConfiguration.js | 2 +- .../test/unit/testServiceConfiguration.js | 2 +- packages/error-reporting/utils/fuzzer.js | 26 ++++++++-------- 9 files changed, 48 insertions(+), 48 deletions(-) diff --git a/packages/error-reporting/src/classes/custom-stack-trace.js b/packages/error-reporting/src/classes/custom-stack-trace.js index 7e9d3ea8eba..7eab92c4dfd 100644 --- a/packages/error-reporting/src/classes/custom-stack-trace.js +++ b/packages/error-reporting/src/classes/custom-stack-trace.js @@ -66,7 +66,7 @@ function CustomStackTrace() { */ CustomStackTrace.prototype.setFilePath = function(filePath) { - this.filePath = isString(filePath) ? filePath : ''; + this.filePath = isString(filePath) ? filePath: ''; return this; }; @@ -80,7 +80,7 @@ CustomStackTrace.prototype.setFilePath = function(filePath) { */ CustomStackTrace.prototype.setLineNumber = function(lineNumber) { - this.lineNumber = isNumber(lineNumber) ? lineNumber : 0; + this.lineNumber = isNumber(lineNumber) ? lineNumber: 0; return this; }; @@ -94,7 +94,7 @@ CustomStackTrace.prototype.setLineNumber = function(lineNumber) { */ CustomStackTrace.prototype.setFunctionName = function(functionName) { - this.functionName = isString(functionName) ? functionName : ''; + this.functionName = isString(functionName) ? functionName: ''; return this; }; @@ -109,7 +109,7 @@ CustomStackTrace.prototype.setFunctionName = function(functionName) { */ CustomStackTrace.prototype.setStringifyStructuredCallList = function(op) { - this.stringifyStucturedCallList = isFunction(op) ? op : stubbedNoOp; + this.stringifyStucturedCallList = isFunction(op) ? op: stubbedNoOp; return this; }; diff --git a/packages/error-reporting/src/classes/error-message.js b/packages/error-reporting/src/classes/error-message.js index c379a6e759d..63a3a4afd80 100644 --- a/packages/error-reporting/src/classes/error-message.js +++ b/packages/error-reporting/src/classes/error-message.js @@ -78,8 +78,8 @@ function ErrorMessage() { responseStatusCode: 0, remoteIp: '' }, - user : '', - reportLocation : {filePath: '', lineNumber: 0, functionName: ''} + user: '', + reportLocation: {filePath: '', lineNumber: 0, functionName: ''} }; } @@ -109,8 +109,8 @@ ErrorMessage.prototype.setEventTimeToNow = function() { */ ErrorMessage.prototype.setServiceContext = function(service, version) { - this.serviceContext.service = isString(service) ? service : 'node'; - this.serviceContext.version = isString(version) ? version : undefined; + this.serviceContext.service = isString(service) ? service: 'node'; + this.serviceContext.version = isString(version) ? version: undefined; return this; }; @@ -123,7 +123,7 @@ ErrorMessage.prototype.setServiceContext = function(service, version) { */ ErrorMessage.prototype.setMessage = function(message) { - this.message = isString(message) ? message : ''; + this.message = isString(message) ? message: ''; return this; }; @@ -137,7 +137,7 @@ ErrorMessage.prototype.setMessage = function(message) { */ ErrorMessage.prototype.setHttpMethod = function(method) { - this.context.httpRequest.method = isString(method) ? method : ''; + this.context.httpRequest.method = isString(method) ? method: ''; return this; }; @@ -150,7 +150,7 @@ ErrorMessage.prototype.setHttpMethod = function(method) { */ ErrorMessage.prototype.setUrl = function(url) { - this.context.httpRequest.url = isString(url) ? url : ''; + this.context.httpRequest.url = isString(url) ? url: ''; return this; }; @@ -163,7 +163,7 @@ ErrorMessage.prototype.setUrl = function(url) { */ ErrorMessage.prototype.setUserAgent = function(userAgent) { - this.context.httpRequest.userAgent = isString(userAgent) ? userAgent : ''; + this.context.httpRequest.userAgent = isString(userAgent) ? userAgent: ''; return this; }; @@ -176,7 +176,7 @@ ErrorMessage.prototype.setUserAgent = function(userAgent) { */ ErrorMessage.prototype.setReferrer = function(referrer) { - this.context.httpRequest.referrer = isString(referrer) ? referrer : ''; + this.context.httpRequest.referrer = isString(referrer) ? referrer: ''; return this; }; @@ -190,7 +190,7 @@ ErrorMessage.prototype.setReferrer = function(referrer) { ErrorMessage.prototype.setResponseStatusCode = function(responseStatusCode) { this.context.httpRequest.responseStatusCode = - isNumber(responseStatusCode) ? responseStatusCode : 0; + isNumber(responseStatusCode) ? responseStatusCode: 0; return this; }; @@ -203,7 +203,7 @@ ErrorMessage.prototype.setResponseStatusCode = function(responseStatusCode) { */ ErrorMessage.prototype.setRemoteIp = function(remoteIp) { - this.context.httpRequest.remoteIp = isString(remoteIp) ? remoteIp : ''; + this.context.httpRequest.remoteIp = isString(remoteIp) ? remoteIp: ''; return this; }; @@ -216,7 +216,7 @@ ErrorMessage.prototype.setRemoteIp = function(remoteIp) { */ ErrorMessage.prototype.setUser = function(user) { - this.context.user = isString(user) ? user : ''; + this.context.user = isString(user) ? user: ''; return this; }; @@ -229,7 +229,7 @@ ErrorMessage.prototype.setUser = function(user) { */ ErrorMessage.prototype.setFilePath = function(filePath) { - this.context.reportLocation.filePath = isString(filePath) ? filePath : ''; + this.context.reportLocation.filePath = isString(filePath) ? filePath: ''; return this; }; @@ -243,7 +243,7 @@ ErrorMessage.prototype.setFilePath = function(filePath) { ErrorMessage.prototype.setLineNumber = function(lineNumber) { this.context.reportLocation.lineNumber = - isNumber(lineNumber) ? lineNumber : 0; + isNumber(lineNumber) ? lineNumber: 0; return this; }; @@ -257,7 +257,7 @@ ErrorMessage.prototype.setLineNumber = function(lineNumber) { ErrorMessage.prototype.setFunctionName = function(functionName) { this.context.reportLocation.functionName = - isString(functionName) ? functionName : ''; + isString(functionName) ? functionName: ''; return this; }; diff --git a/packages/error-reporting/src/classes/request-information-container.js b/packages/error-reporting/src/classes/request-information-container.js index 70c76b846d9..1eea5c9bb85 100644 --- a/packages/error-reporting/src/classes/request-information-container.js +++ b/packages/error-reporting/src/classes/request-information-container.js @@ -57,7 +57,7 @@ function RequestInformationContainer() { */ RequestInformationContainer.prototype.setUrl = function(url) { - this.url = isString(url) ? url : ''; + this.url = isString(url) ? url: ''; return this; }; @@ -70,7 +70,7 @@ RequestInformationContainer.prototype.setUrl = function(url) { */ RequestInformationContainer.prototype.setMethod = function(method) { - this.method = isString(method) ? method : ''; + this.method = isString(method) ? method: ''; return this; }; @@ -83,7 +83,7 @@ RequestInformationContainer.prototype.setMethod = function(method) { */ RequestInformationContainer.prototype.setReferrer = function(referrer) { - this.referrer = isString(referrer) ? referrer : ''; + this.referrer = isString(referrer) ? referrer: ''; return this; }; @@ -96,7 +96,7 @@ RequestInformationContainer.prototype.setReferrer = function(referrer) { */ RequestInformationContainer.prototype.setUserAgent = function(userAgent) { - this.userAgent = isString(userAgent) ? userAgent : ''; + this.userAgent = isString(userAgent) ? userAgent: ''; return this; }; @@ -109,7 +109,7 @@ RequestInformationContainer.prototype.setUserAgent = function(userAgent) { */ RequestInformationContainer.prototype.setRemoteAddress = function(remoteIp) { - this.remoteAddress = isString(remoteIp) ? remoteIp : ''; + this.remoteAddress = isString(remoteIp) ? remoteIp: ''; return this; }; @@ -122,7 +122,7 @@ RequestInformationContainer.prototype.setRemoteAddress = function(remoteIp) { */ RequestInformationContainer.prototype.setStatusCode = function(statusCode) { - this.statusCode = isNumber(statusCode) ? statusCode : 0; + this.statusCode = isNumber(statusCode) ? statusCode: 0; return this; }; diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index 4c67ccca6c6..1a8e1844299 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -180,7 +180,7 @@ var Configuration = function(givenConfig, logger) { * @type {Object|Null} * @defaultvalue null */ - this._givenConfiguration = isObject(givenConfig) ? givenConfig : {}; + this._givenConfiguration = isObject(givenConfig) ? givenConfig: {}; this._checkLocalServiceContext(); this._gatherLocalConfiguration(); }; @@ -230,8 +230,8 @@ Configuration.prototype._checkLocalServiceContext = function() { version = env.GAE_MODULE_VERSION; } - this._serviceContext.service = isString(service) ? service : 'node'; - this._serviceContext.version = isString(version) ? version : undefined; + this._serviceContext.service = isString(service) ? service: 'node'; + this._serviceContext.version = isString(version) ? version: undefined; if (isObject(this._givenConfiguration.serviceContext)) { if (isString(this._givenConfiguration.serviceContext.service)) { diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 05b180a4e0e..e016441e657 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -92,7 +92,7 @@ function getErrorReportURL(projectId, key) { */ RequestHandler.prototype.sendError = function(errorMessage, userCb) { var self = this; - var cb = isFunction(userCb) ? userCb : function() {}; + var cb = isFunction(userCb) ? userCb: function() {}; if (self._config.getShouldReportErrorsToAPI()) { self._config.getProjectId(function(err, id) { if (err) { diff --git a/packages/error-reporting/src/interfaces/hapi.js b/packages/error-reporting/src/interfaces/hapi.js index 1f123ce909e..10f542c8863 100644 --- a/packages/error-reporting/src/interfaces/hapi.js +++ b/packages/error-reporting/src/interfaces/hapi.js @@ -112,13 +112,13 @@ function makeHapiPlugin(client, config) { } } - var hapiPlugin = {register : hapiRegisterFunction}; + var hapiPlugin = {register: hapiRegisterFunction}; var version = (isObject(config) && config.getVersion()) ? - config.getVersion() : '0.0.0'; + config.getVersion(): '0.0.0'; hapiPlugin.register.attributes = { - name : '@google/cloud-errors', - version : version + name: '@google/cloud-errors', + version: version }; return hapiPlugin; diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index c3327dbca58..4af5ae1131e 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -23,7 +23,7 @@ var version = require('../../package.json').version; var Fuzzer = require('../../utils/fuzzer.js'); var level = process.env.GCLOUD_ERRORS_LOGLEVEL; var logger = require('../../src/logger.js')({ - logLevel: isNumber(level) ? level : 4 + logLevel: isNumber(level) ? level: 4 }); var nock = require('nock'); diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index 95336bee9e2..7d65d3d57da 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -25,7 +25,7 @@ var omitBy = require('lodash.omitby'); var Configuration = require('../fixtures/configuration.js'); var level = process.env.GCLOUD_ERRORS_LOGLEVEL; var logger = require('../../src/logger.js')({ - logLevel: isNumber(level) ? level : 4 + logLevel: isNumber(level) ? level: 4 }); var env = { GAE_SERVICE: process.env.GAE_SERVICE, diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js index 039fbd41ad6..d3e1d06ce5a 100644 --- a/packages/error-reporting/utils/fuzzer.js +++ b/packages/error-reporting/utils/fuzzer.js @@ -47,7 +47,7 @@ Fuzzer.prototype.generate.types = function() { } Fuzzer.prototype.generate.string = function(len) { - var lenChecked = isNumber(len) ? len : 10; + var lenChecked = isNumber(len) ? len: 10; var chars = []; for (var i = 0; i < lenChecked; i++) { @@ -64,7 +64,7 @@ Fuzzer.prototype.generate.boolean = function() { } Fuzzer.prototype.generate.alphaNumericString = function(len) { - var lenChecked = isNumber(len) ? len : 10; + var lenChecked = isNumber(len) ? len: 10; var chars = []; var thisRange = []; var ranges = [[48, 57], [65, 90], [97, 122]]; @@ -99,8 +99,8 @@ Fuzzer.prototype.generate.function = function() { Fuzzer.prototype.generate.number = function(lower, upper) { - var lowerChecked = isNumber(lower) ? lower : 0; - var upperChecked = isNumber(upper) ? upper : 100; + var lowerChecked = isNumber(lower) ? lower: 0; + var upperChecked = isNumber(upper) ? upper: 100; return random(lowerChecked, upperChecked); } @@ -117,10 +117,10 @@ Fuzzer.prototype.generate.undefined = function() { Fuzzer.prototype.generate.array = function(len, ofOneType, currentDepth, allowedDepth) { - var lenChecked = isNumber(len) ? len : random(1, 10); - var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType] : this.types(); - var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; - var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth : 3; + var lenChecked = isNumber(len) ? len: random(1, 10); + var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType]: this.types(); + var currentDepthChecked = isNumber(currentDepth) ? currentDepth: 0; + var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth: 3; var arr = []; var currentTypeBeingGenerated = ""; currentDepthChecked += 1; @@ -164,9 +164,9 @@ Fuzzer.prototype.generate.array = function(len, ofOneType, currentDepth, allowed Fuzzer.prototype.generate.object = function(numProperties, currentDepth, allowedDepth) { - var numPropertiesChecked = isNumber(numProperties) ? numProperties : random(1, 10); - var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; - var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth : 3; + var numPropertiesChecked = isNumber(numProperties) ? numProperties: random(1, 10); + var currentDepthChecked = isNumber(currentDepth) ? currentDepth: 0; + var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth: 3; var obj = {}; currentDepthChecked += 1; @@ -290,9 +290,9 @@ Fuzzer.prototype._generateValuesForFuzzTyping = function(typesToFuzzOnEach, inde } Fuzzer.prototype.fuzzFunctionForTypes = function(fnToFuzz, expectsArgTypes, cb, withContext) { - var expectsArgTypesChecked = isArray(expectsArgTypes) ? expectsArgTypes : []; + var expectsArgTypesChecked = isArray(expectsArgTypes) ? expectsArgTypes: []; var typesToFuzzOnEach = this._generateTypesToFuzzWith(expectsArgTypesChecked); - var withContextChecked = (withContext !== undefined) ? withContext : null; + var withContextChecked = (withContext !== undefined) ? withContext: null; var returnValue = undefined; From 7122245272124111e18a16947da0815f6296bd4d Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 09:34:48 -0800 Subject: [PATCH 09/29] remove function paren spacing --- .../test/fixtures/uncaughtExitBehaviour.js | 8 +- .../test/system-test/testAuthClient.js | 12 +- .../test-servers/express_scaffold_server.js | 4 +- .../test/unit/testConfiguration.js | 6 +- .../test/unit/testCustomStackTrace.js | 2 +- .../test/unit/testServiceConfiguration.js | 274 +----------------- .../error-reporting/test/unit/testUncaught.js | 2 +- packages/error-reporting/utils/fuzzer.js | 2 +- 8 files changed, 23 insertions(+), 287 deletions(-) diff --git a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js index efbcc95c0c1..cf4898790dd 100644 --- a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js +++ b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js @@ -25,7 +25,7 @@ var originalHandlers = process.listeners('uncaughtException'); var UNCAUGHT = 'uncaughtException'; var client; -function reattachOriginalListeners () { +function reattachOriginalListeners() { for (var i = 0; i < originalHandlers.length; i++) { process.on(UNCAUGHT, originalHandlers[i]); } @@ -33,10 +33,10 @@ function reattachOriginalListeners () { var env = { NODE_ENV: process.env.NODE_ENV }; -function setEnv () { +function setEnv() { process.env.NODE_ENV = 'production'; } -function restoreEnv () { +function restoreEnv() { process.env.NODE_ENV = env.NODE_ENV; } @@ -73,7 +73,7 @@ describe('Uncaught Exception exit behaviour', function() { }); this.timeout(2000); nock( - 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+id + 'https://clouderrorreporting.googleapis.com/v1beta1/projects/' +id ).post('/events:report').once().reply(200, function() { done(); return {success: true}; diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index 0dd6889ab65..638549e060a 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -46,7 +46,7 @@ describe('Behvaiour acceptance testing', function() { this.skip(); } else if (process.env.NODE_ENV !== 'production') { console.error( - 'The NODE_ENV is not set to production as an env variable. Please set '+ + 'The NODE_ENV is not set to production as an env variable. Please set ' + 'NODE_ENV to production'); this.skip(); } @@ -59,7 +59,7 @@ describe('Behvaiour acceptance testing', function() { var fakeService, client, logger; beforeEach(function() { fakeService = nock( - 'https://clouderrorreporting.googleapis.com/v1beta1/projects/'+ + 'https://clouderrorreporting.googleapis.com/v1beta1/projects/' + process.env.GCLOUD_PROJECT ).persist().post('/events:report'); logger = createLogger({logLevel: 5}); @@ -90,7 +90,7 @@ describe('Behvaiour acceptance testing', function() { var intendedTries = 5; fakeService.reply(429, function() { tries += 1; - console.log('Mock Server Received Request:', tries+'/'+intendedTries); + console.log('Mock Server Received Request:', tries+'/' +intendedTries); return {error: 'Please try again later'}; }); client.sendError(errorMessage, function(err, response, body) { @@ -106,7 +106,7 @@ describe('Behvaiour acceptance testing', function() { {key: key, ignoreEnvironmentCheck: true}, createLogger({logLevel: 5}))); fakeService.query({key: key}).reply(200, function(uri) { - assert(uri.indexOf('key='+key) > -1); + assert(uri.indexOf('key=' +key) > -1); return {}; }); client.sendError(errorMessage, function() { @@ -131,12 +131,12 @@ describe('Behvaiour acceptance testing', function() { STUBBED_PROJECT_NUM: process.env.STUBBED_PROJECT_NUM, NODE_ENV: process.env.NODE_ENV }; - function sterilizeEnv () { + function sterilizeEnv() { forEach(oldEnv, function(val, key) { delete process.env[key]; }); } - function restoreEnv () { + function restoreEnv() { assign(process.env, oldEnv); } describe('Client creation', function() { diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js index 1617a7c9136..c8229a8e4ff 100644 --- a/packages/error-reporting/test/test-servers/express_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -81,12 +81,12 @@ app.get( app.use(errorHandler.express); -function throwUncaughtError () { +function throwUncaughtError() { console.log('Throwing an uncaught error..'); throw new Error('This is an uncaught error'); } -function reportManualError () { +function reportManualError() { console.log('Reporting a manual error..'); errorHandler.report( new Error('This is a manually reported error'), null, null, function(err, res) { diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index 4af5ae1131e..afddb038913 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -36,19 +36,19 @@ var env = { GAE_MODULE_NAME: process.env.GAE_MODULE_NAME, GAE_MODULE_VERSION: process.env.GAE_MODULE_VERSION }; -function sterilizeEnv () { +function sterilizeEnv() { delete process.env.NODE_ENV; delete process.env.GCLOUD_PROJECT; delete process.env.GAE_MODULE_NAME; delete process.env.GAE_MODULE_VERSION; } -function restoreEnv () { +function restoreEnv() { process.env.NODE_ENV = env.NODE_ENV; process.env.GCLOUD_PROJECT = env.GCLOUD_PROJECT; process.env.GAE_MODULE_NAME = env.GAE_MODULE_NAME; process.env.GAE_MODULE_VERSION = env.GAE_MODULE_VERSION; } -function createDeadMetadataService () { +function createDeadMetadataService() { return nock(METADATA_URL).get('/project-id').times(1).reply(500); } diff --git a/packages/error-reporting/test/unit/testCustomStackTrace.js b/packages/error-reporting/test/unit/testCustomStackTrace.js index a66b505699a..fe1f9ad5e64 100644 --- a/packages/error-reporting/test/unit/testCustomStackTrace.js +++ b/packages/error-reporting/test/unit/testCustomStackTrace.js @@ -19,7 +19,7 @@ var assert = require('assert'); var CustomStackTrace = require('../../src/classes/custom-stack-trace.js'); describe('Fuzzing the CustomStackTrace class', function() { - var testFunction = function testFunction () { + var testFunction = function testFunction() { return ''; }; var cs; diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index 7d65d3d57da..1d4cc772d69 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -34,12 +34,12 @@ var env = { FUNCTION_NAME: process.env.FUNCTION_NAME, GAE_MODULE_NAME: process.env.GAE_MODULE_NAME }; -function sterilizeEnv () { +function sterilizeEnv() { forEach(env, function(val, key) { delete process.env[key]; }); } -function setEnv (serviceName, serviceVersion, moduleName, moduleVersion, functionName) { +function setEnv(serviceName, serviceVersion, moduleName, moduleVersion, functionName) { assign(process.env, omitBy({ GAE_SERVICE: serviceName, GAE_VERSION: serviceVersion, @@ -48,7 +48,7 @@ function setEnv (serviceName, serviceVersion, moduleName, moduleVersion, functio FUNCTION_NAME: functionName }, function(val) {return !isString(val);})); } -function restoreEnv () { +function restoreEnv() { assign(process.env, env); } @@ -196,7 +196,7 @@ describe('Testing service configuration', function() { ); it( 'A Configuration uses the service name "node" and no version if ' + - 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ + 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has ' + 'not specified a service name or version', function() { var c = new Configuration({}, logger); @@ -206,7 +206,7 @@ describe('Testing service configuration', function() { ); it( 'A Configuration uses the service name "node" and no version if ' + - 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has '+ + 'GAE_SERVICE is not set, FUNCTION_NAME is not set, and the user has ' + 'not specified a service name or version even if GAE_VERSION has ' + 'been set', function() { @@ -230,268 +230,4 @@ describe('Testing service configuration', function() { assert.deepEqual(c.getServiceContext().version, '2.0'); } ); - - // it( - // 'A Configuration uses the service name "node" and the user specified ' + - // 'version if GAE_SERVICE is not set, FUNCTION_NAME is not set, and the ' + - // 'user has not specified a service name but has specified a version even ' + - // 'if GAE_VERSION has been set', - // makeTest(null, 'InvalidVersion', - // null, 'InvalidVersion', - // null, - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // version: '2.0' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'node'); - // assert.deepEqual(c.getServiceContext().version, '2.0'); - - // done(); - // }) - //); - - // // The following tests always have GAE_SERVICE and GAE_VERSION not set - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the function name as the service name on GCF ' + - // 'if the service name is not given in the given config', - // makeTest(null, null, 'someModuleName', '1.0', 'someFunction', - // function(done) { - // var c = new Configuration({}, logger); - // assert.deepEqual(c.getServiceContext().service, 'someFunction'); - // // FUNCTION_NAME is set and the user didn't specify a version, and so - // // the version should not be defined - // assert.deepEqual(c.getServiceContext().version, undefined); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the function name as the service name on GCF ' + - // 'if the service name is not given in the given config ' + - // 'even if the GAE_MODULE_NAME was not set', - // makeTest(null, null, null, '1.0', 'someFunction', - // function(done) { - // var c = new Configuration({}, logger); - // assert.deepEqual(c.getServiceContext().service, 'someFunction'); - // // The user didn't specify a version and FUNCTION_NAME is defined, and - // // so the version should not be defined - // assert.deepEqual(c.getServiceContext().version, undefined); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the GAE_MODULE_NAME env value as the service name ' + - // 'if the FUNCTION_NAME env variable is not set and the given config ' + - // 'does not specify the service name', - // makeTest(null, null, 'someModuleName', '1.0', null, - // function(done) { - // var c = new Configuration({}, logger); - // assert.deepEqual(c.getServiceContext().service, 'someModuleName'); - // // The user didn't specify a version, and FUNCTION_NAME is not defined, - // // and so use the GAE_MODULE_VERSION - // assert.deepEqual(c.getServiceContext().version, '1.0'); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name in the given config if it ' + - // 'was specified and both the GAE_MODULE_NAME and FUNCTION_NAME ' + - // 'env vars are set', - // makeTest(null, null, 'someModuleName', '1.0', 'someFunction', - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // service: 'customService' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user didn't specify a version, but FUNCTION_NAME is defined, and - // // so the version should not be defined - // assert.deepEqual(c.getServiceContext().version, undefined); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name and version in the given config if ' + - // 'they were both specified and both the GAE_MODULE_NAME and FUNCTION_NAME ' + - // 'env vars are set', - // makeTest(null, null, 'someModuleName', '1.0', 'someFunction', - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // service: 'customService', - // version: '2.0' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user specified version should be used - // assert.deepEqual(c.getServiceContext().version, '2.0'); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name in the given config if it ' + - // 'was specified and only the GAE_MODULE_NAME env var is set', - // makeTest(null, null, 'someModuleName', '1.0', null, - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // service: 'customService' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user didn't specify a version and FUNCTION_NAME is not defined - // // and so the GAE_MODULE_VERSION should be used - // assert.deepEqual(c.getServiceContext().version, '1.0'); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name and version in the given config if ' + - // 'they were both specified and only the GAE_MODULE_NAME env var is set', - // makeTest(null, null, 'someModuleName', '1.0', null, - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // service: 'customService', - // version: '2.0' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user specified version should be used - // assert.deepEqual(c.getServiceContext().version, '2.0'); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name in the given config if it ' + - // 'was specified and only the FUNCTION_NAME env var is set', - // makeTest(null, null, null, '1.0', 'someFunction', - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // service: 'customService' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user didn't specify a version and thus because FUNCTION_NAME is - // // defined the version should not be defined - // assert.deepEqual(c.getServiceContext().version, undefined); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name and version in the given config if ' + - // 'they were both specified and only the FUNCTION_NAME env var is set', - // makeTest(null, null, null, '1.0', 'someFunction', - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // service: 'customService', - // version: '2.0' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'customService'); - // // The user specified version should be used - // assert.deepEqual(c.getServiceContext().version, '2.0'); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name "node" and no version if ' + - // 'GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the user has '+ - // 'not specified a service name or version', - // makeTest(null, null, null, null, null, - // function(done) { - // var c = new Configuration({}, logger); - // assert.deepEqual(c.getServiceContext().service, 'node'); - // assert.deepEqual(c.getServiceContext().version, undefined); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name "node" and no version if ' + - // 'GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the user has '+ - // 'not specified a service name or version even if GAE_MODULE_VERSION has ' + - // 'been set', - // makeTest(null, null, null, '1.0', null, - // function(done) { - // var c = new Configuration({}, logger); - // assert.deepEqual(c.getServiceContext().service, 'node'); - // assert.deepEqual(c.getServiceContext().version, undefined); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name "node" and the user specified ' + - // 'version if GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the ' + - // 'user has not specified a service name but has specified a version', - // makeTest(null, null, null, null, null, - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // version: '2.0' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'node'); - // assert.deepEqual(c.getServiceContext().version, '2.0'); - - // done(); - // }) - //); - - // it( - // 'With GAE_SERVICE and GAE_VERSION not set: ' + - // 'A Configuration uses the service name "node" and the user specified ' + - // 'version if GAE_MODULE_NAME is not set, FUNCTION_NAME is not set, and the ' + - // 'user has not specified a service name but has specified a version even ' + - // 'if GAE_MODULE_VERSION has been set', - // makeTest(null, null, null, '1.0', null, - // function(done) { - // var c = new Configuration({ - // serviceContext: { - // version: '2.0' - // } - // }, logger); - // assert.deepEqual(c.getServiceContext().service, 'node'); - // assert.deepEqual(c.getServiceContext().version, '2.0'); - - // done(); - // }) - //); }); diff --git a/packages/error-reporting/test/unit/testUncaught.js b/packages/error-reporting/test/unit/testUncaught.js index a2a41c5c6e0..06105c6fcf4 100644 --- a/packages/error-reporting/test/unit/testUncaught.js +++ b/packages/error-reporting/test/unit/testUncaught.js @@ -24,7 +24,7 @@ var createLogger = require('../../src/logger.js'); var originalHandlers = process.listeners('uncaughtException'); var spawn = require('child_process').spawn; -function reattachOriginalListeners () { +function reattachOriginalListeners() { for (var i = 0; i < originalHandlers.length; i++) { process.on('uncaughtException', originalHandlers[i]); } diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js index d3e1d06ce5a..67df622a023 100644 --- a/packages/error-reporting/utils/fuzzer.js +++ b/packages/error-reporting/utils/fuzzer.js @@ -29,7 +29,7 @@ var isArray = is.array; var isNull = is.null; var isFunction = is.function; -function Fuzzer () { } +function Fuzzer() { } Fuzzer.prototype.generate = {}; From 86569c55b6b7c10b1a915c7f2a2069394794da6b Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 10:08:29 -0800 Subject: [PATCH 10/29] both linters be linting --- packages/error-reporting/src/configuration.js | 6 +- .../src/google-apis/auth-client.js | 4 +- .../error-reporting/src/interfaces/koa.js | 2 +- packages/error-reporting/src/logger.js | 4 +- .../src/request-extractors/express.js | 1 + .../src/request-extractors/hapi.js | 1 + .../test/fixtures/uncaughtExitBehaviour.js | 7 +- .../test/system-test/testAuthClient.js | 67 ++++++++++--------- .../test-servers/express_scaffold_server.js | 56 ++++++++-------- .../test/unit/testConfigCredentials.js | 25 ++++--- .../test/unit/testConfiguration.js | 22 +++--- .../test/unit/testExpressInterface.js | 2 +- .../testExpressRequestInformationExtractor.js | 8 +-- .../test/unit/testHapiInterface.js | 13 ++-- .../testHapiRequestInformationExtractor.js | 3 +- .../testKoaRequestInformationExtractor.js | 8 ++- .../test/unit/testManualHandler.js | 56 ++++++++-------- .../testManualRequestInformationExtractor.js | 14 ++-- .../unit/testRequestInformationContainer.js | 11 +-- .../test/unit/testRestifyInterface.js | 6 +- .../test/unit/testServiceConfiguration.js | 14 ++-- .../error-reporting/test/unit/testUncaught.js | 4 +- 22 files changed, 181 insertions(+), 153 deletions(-) diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index 1a8e1844299..fe85dd0182a 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -222,10 +222,10 @@ Configuration.prototype._checkLocalServiceContext = function() { if (env.FUNCTION_NAME) { service = env.FUNCTION_NAME; - } else if (env.GAE_SERVICE){ + } else if (env.GAE_SERVICE) { service = env.GAE_SERVICE; version = env.GAE_VERSION; - } else if (env.GAE_MODULE_NAME){ + } else if (env.GAE_MODULE_NAME) { service = env.GAE_MODULE_NAME; version = env.GAE_MODULE_VERSION; } @@ -407,7 +407,7 @@ Configuration.prototype.getProjectId = function(cb) { }); } else { utils.getProjectId(function(err, projectId) { - if (err) { + if (err) { self._checkLocalProjectId(cb); } else { self._projectId = projectId; diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index e016441e657..669962a9bec 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -148,8 +148,8 @@ RequestHandler.prototype.sendError = function(errorMessage, userCb) { * invoked once the transaction has completed * @param {Error|Null} err - The error, if applicable, generated during the * transaction - * @param {Object|Undefined|Null} response - The response, if applicable, received - * during the transaction + * @param {Object|Undefined|Null} response - The response, if applicable, + * received during the transaction * @param {Any} body - The response body if applicable */ diff --git a/packages/error-reporting/src/interfaces/koa.js b/packages/error-reporting/src/interfaces/koa.js index 8e3768aa4b1..e3f4751d068 100644 --- a/packages/error-reporting/src/interfaces/koa.js +++ b/packages/error-reporting/src/interfaces/koa.js @@ -40,7 +40,7 @@ function koaErrorHandler(client, config) { * @param {Function} next - the result of the request handlers to yield * @returns {Undefined} does not return anything */ - return function * (next) { + return function *(next) { var em; var svc = config.getServiceContext(); diff --git a/packages/error-reporting/src/logger.js b/packages/error-reporting/src/logger.js index 270f9241fc7..0f8b7607b60 100644 --- a/packages/error-reporting/src/logger.js +++ b/packages/error-reporting/src/logger.js @@ -45,8 +45,8 @@ function createLogger(initConfiguration) { if (has(process.env, 'GCLOUD_ERRORS_LOGLEVEL')) { // Cast env string as integer level = ~~process.env.GCLOUD_ERRORS_LOGLEVEL; - } else if (isObject(initConfiguration) - && has(initConfiguration, 'logLevel')) { + } else if (isObject(initConfiguration) && + has(initConfiguration, 'logLevel')) { if (isString(initConfiguration.logLevel)) { // Cast string as integer level = ~~initConfiguration.logLevel; diff --git a/packages/error-reporting/src/request-extractors/express.js b/packages/error-reporting/src/request-extractors/express.js index 3ebd034b88e..197e73978b7 100644 --- a/packages/error-reporting/src/request-extractors/express.js +++ b/packages/error-reporting/src/request-extractors/express.js @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +// jscs:disable requireEarlyReturn 'use strict'; var is = require('is'); var isFunction = is.fn; diff --git a/packages/error-reporting/src/request-extractors/hapi.js b/packages/error-reporting/src/request-extractors/hapi.js index 9751864e191..cc44bf1764d 100644 --- a/packages/error-reporting/src/request-extractors/hapi.js +++ b/packages/error-reporting/src/request-extractors/hapi.js @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +// jscs:disable requireEarlyReturn 'use strict'; var has = require('lodash.has'); var is = require('is'); diff --git a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js index cf4898790dd..7f4b8728ad0 100644 --- a/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js +++ b/packages/error-reporting/test/fixtures/uncaughtExitBehaviour.js @@ -41,14 +41,15 @@ function restoreEnv() { } describe('Uncaught Exception exit behaviour', function() { - before(function() { + before(function() { process.removeAllListeners(UNCAUGHT); if (!isString(process.env.GCLOUD_PROJECT)) { // The gcloud project id (GCLOUD_PROJECT) was not set as an env variable this.skip(); process.exit(1); } else if (!isString(process.env.GOOGLE_APPLICATION_CREDENTIALS)) { - // The app credentials (GOOGLE_APPLICATION_CREDENTIALS) was not set as an env variable + // The app credentials (GOOGLE_APPLICATION_CREDENTIALS) + // was not set as an env variable this.skip(); process.exit(1); } @@ -73,7 +74,7 @@ describe('Uncaught Exception exit behaviour', function() { }); this.timeout(2000); nock( - 'https://clouderrorreporting.googleapis.com/v1beta1/projects/' +id + 'https://clouderrorreporting.googleapis.com/v1beta1/projects/' + id ).post('/events:report').once().reply(200, function() { done(); return {success: true}; diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index 638549e060a..ea38afc8e51 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -27,6 +27,7 @@ var isString = is.string; var isEmpty = is.empty; var forEach = require('lodash.foreach'); var assign = require('lodash.assign'); +const ERR_TOKEN = '_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'; describe('Behvaiour acceptance testing', function() { @@ -34,7 +35,7 @@ describe('Behvaiour acceptance testing', function() { // Before starting the suite make sure we have the proper resources if (!isString(process.env.GCLOUD_PROJECT)) { console.error( - 'The gcloud project id (GCLOUD_PROJECT) was not set as an env variable'); + 'The gcloud project id (GCLOUD_PROJECT) was not set in the env'); this.skip(); } else if (!isString(process.env.STUBBED_API_KEY)) { console.error( @@ -42,19 +43,19 @@ describe('Behvaiour acceptance testing', function() { this.skip(); } else if (!isString(process.env.STUBBED_PROJECT_NUM)) { console.error( - 'The project number (STUBBED_PROJECT_NUM) was not set as an env variable'); + 'The project number (STUBBED_PROJECT_NUM) was not set in the env'); this.skip(); } else if (process.env.NODE_ENV !== 'production') { console.error( - 'The NODE_ENV is not set to production as an env variable. Please set ' + - 'NODE_ENV to production'); + 'The NODE_ENV is not set to production as an env variable. Please ' + + 'set NODE_ENV to production'); this.skip(); } // In case we are running after unit mocks which were not destroyed properly nock.cleanAll(); }); describe('Request/Response lifecycle mocking', function() { - var sampleError = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); + var sampleError = new Error(ERR_TOKEN); var errorMessage = new ErrorMessage().setMessage(sampleError); var fakeService, client, logger; beforeEach(function() { @@ -90,7 +91,8 @@ describe('Behvaiour acceptance testing', function() { var intendedTries = 5; fakeService.reply(429, function() { tries += 1; - console.log('Mock Server Received Request:', tries+'/' +intendedTries); + console.log('Mock Server Received Request:', tries + '/' + + intendedTries); return {error: 'Please try again later'}; }); client.sendError(errorMessage, function(err, response, body) { @@ -100,19 +102,21 @@ describe('Behvaiour acceptance testing', function() { }); }); describe('Using an API key', function() { - it('Should provide the key as a query string on outgoing requests', function(done) { - var key = process.env.STUBBED_API_KEY; - 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 provide the key as a query string on outgoing requests', + function(done) { + var key = process.env.STUBBED_API_KEY; + 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(); + }); + } + ); }); describe('Callback-less invocation', function() { it('Should still execute the request', function(done) { @@ -124,7 +128,7 @@ describe('Behvaiour acceptance testing', function() { }); }); describe('System-live integration testing', function() { - var sampleError = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); + var sampleError = new Error(ERR_TOKEN); var errorMessage = new ErrorMessage().setMessage(sampleError.stack); var oldEnv = { GCLOUD_PROJECT: process.env.GCLOUD_PROJECT, @@ -194,8 +198,10 @@ describe('Behvaiour acceptance testing', function() { before(function() { sterilizeEnv(); logger = createLogger({logLevel: 5}); - cfg = new Configuration({projectId: parseInt(oldEnv.STUBBED_PROJECT_NUM), - ignoreEnvironmentCheck: true}, logger); + cfg = new Configuration({ + projectId: parseInt(oldEnv.STUBBED_PROJECT_NUM), + ignoreEnvironmentCheck: true + }, logger); }); after(restoreEnv); it('Should not throw on initialization', function(done) { @@ -241,9 +247,9 @@ describe('Behvaiour acceptance testing', 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' + '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() { @@ -267,10 +273,11 @@ describe('Behvaiour acceptance testing', function() { }); describe('An invalid env configuration', function() { var ERROR_STRING = [ - 'Unable to find the project Id for communication with the Stackdriver', - 'Error Reporting service. This app will be unable to send errors to', - 'the reporting service unless a valid project Id is supplied via', - 'runtime configuration or the GCLOUD_PROJECT environmental variable.' + 'Unable to find the project Id for communication with the', + 'Stackdriver Error Reporting service. This app will be unable to', + 'send errors to the reporting service unless a valid project Id', + 'is supplied via runtime configuration or the GCLOUD_PROJECT', + 'environmental variable.' ].join(' '); var logger, client; before(function() { @@ -294,7 +301,7 @@ describe('Behvaiour acceptance testing', function() { }); }); describe('Success behaviour', function() { - var er = new Error('_@google_STACKDRIVER_INTEGRATION_TEST_ERROR__'); + var er = new Error(ERR_TOKEN); var em = new ErrorMessage().setMessage(er.stack); describe('Given a valid project id', function() { var logger, client, cfg; diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js index c8229a8e4ff..86b28b43edd 100644 --- a/packages/error-reporting/test/test-servers/express_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +// jscs:disable requireEarlyReturn 'use strict'; @@ -33,15 +34,15 @@ app.use(bodyParser.json()); app.post('/testErrorHandling', function(req, res, next) { - if (has(req.body, 'test') && req.body.test !== true) { + if (has(req.body, 'test') && req.body.test !== true) { - return next(new Error('Error on Express Regular Error POST Route')); - } else { + return next(new Error('Error on Express Regular Error POST Route')); + } else { - res.send('Success'); - res.end(); - } + res.send('Success'); + res.end(); } +} ); app.get( @@ -89,37 +90,38 @@ function throwUncaughtError() { function reportManualError() { console.log('Reporting a manual error..'); errorHandler.report( - new Error('This is a manually reported error'), null, null, function(err, res) { + new Error('This is a manually reported error'), null, null, + function(err, res) { - if (err) { + if (err) { - console.log(WARNING_HEADER); - console.log('Got an error in sending error information to the API'); - console.log(err); - console.log(EXCLAMATION_LN); - } else { + console.log(WARNING_HEADER); + console.log('Got an error in sending error information to the API'); + console.log(err); + console.log(EXCLAMATION_LN); + } else { - console.log(EXCLAMATION_LN); - console.log('Successfully sent error information to the API'); - console.log(EXCLAMATION_LN); - } + console.log(EXCLAMATION_LN); + console.log('Successfully sent error information to the API'); + console.log(EXCLAMATION_LN); + } - if (process.env.THROW_ON_STARTUP) { - throwUncaughtError(); + if (process.env.THROW_ON_STARTUP) { + throwUncaughtError(); + } } - } - ); + ); } console.log('reporting a manual error first'); errorHandler.report( new Error('This is a test'), (err, res) => { - console.log('reported first manual error'); - if (err) { - console.log('Error was unable to be reported', err); - } else { - console.log('Error reported!'); - } + console.log('reported first manual error'); + if (err) { + console.log('Error was unable to be reported', err); + } else { + console.log('Error reported!'); + } } ); diff --git a/packages/error-reporting/test/unit/testConfigCredentials.js b/packages/error-reporting/test/unit/testConfigCredentials.js index 0d7723b0bb4..31b456a31c2 100644 --- a/packages/error-reporting/test/unit/testConfigCredentials.js +++ b/packages/error-reporting/test/unit/testConfigCredentials.js @@ -71,9 +71,9 @@ describe('Testing use of runtime configurations', function() { access_token: 'goodbye', expiry_date: new Date(9999, 1, 1) }); - var agent = new Errors(config); - agent.report(new Error('a b c')); - }); + var agent = new Errors(config); + agent.report(new Error('a b c')); + }); describe( 'use of the credentials field of the config object', function() { @@ -84,7 +84,7 @@ describe('Testing use of runtime configurations', function() { delete process.env.GCLOUD_PROJECT; nock.cleanAll(); }); - it('Should use the credentials field of the config object', function(done) { + it('Should use the credentials field of the object', function(done) { var config = { credentials: require('../fixtures/gcloud-credentials.json'), reportUncaughtExceptions: false @@ -99,9 +99,12 @@ describe('Testing use of runtime configurations', function() { nock.enableNetConnect('localhost'); var scope = nock('https://accounts.google.com/o/oauth2') .intercept('/token', 'POST', function(body) { - assert.strictEqual(body.client_id, config.credentials.client_id); - assert.strictEqual(body.client_secret, config.credentials.client_secret); - assert.strictEqual(body.refresh_token, config.credentials.refresh_token); + assert.strictEqual(body.client_id, + config.credentials.client_id); + assert.strictEqual(body.client_secret, + config.credentials.client_secret); + assert.strictEqual(body.refresh_token, + config.credentials.refresh_token); return true; }).reply(200, { refresh_token: 'hello', @@ -109,7 +112,7 @@ describe('Testing use of runtime configurations', function() { expiry_date: new Date(9999, 1, 1) }); - // Since we have to get an auth token, this always gets intercepted second + // Since we have to get an auth token -- this gets intercepted second nock('https://clouderrorreporting.googleapis.com/v1beta1/projects/0') .post('/events:report', function() { assert(scope.isDone()); @@ -156,8 +159,10 @@ describe('Testing use of runtime configurations', function() { var scope = nock('https://accounts.google.com/o/oauth2') .intercept('/token', 'POST', function(body) { assert.strictEqual(body.client_id, correctCredentials.client_id); - assert.strictEqual(body.client_secret, correctCredentials.client_secret); - assert.strictEqual(body.refresh_token, correctCredentials.refresh_token); + assert.strictEqual(body.client_secret, + correctCredentials.client_secret); + assert.strictEqual(body.refresh_token, + correctCredentials.refresh_token); return true; }).reply(200, { refresh_token: 'hello', diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index afddb038913..f4b77d6efd3 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -101,7 +101,7 @@ describe('Configuration class', function() { {service: 'node', version: undefined}); }); it('Should have a version corresponding to package.json', function() { - assert.strictEqual(c.getVersion(), version); + assert.strictEqual(c.getVersion(), version); }); }); describe('with ignoreEnvironmentCheck', function() { @@ -141,7 +141,7 @@ describe('Configuration class', function() { }); }); describe('exception behaviour', function() { - it('Should throw if invalid type for reportUncaughtExceptions', function() { + it('Should throw', function() { assert.throws(function() { new Configuration({reportUncaughtExceptions: 1}, logger); }); @@ -151,26 +151,28 @@ describe('Configuration class', function() { new Configuration({key: null}, logger); }); }); - it('Should throw if invalid type for ignoreEnvironmentCheck', function() { + it('Should throw if invalid for ignoreEnvironmentCheck', function() { assert.throws(function() { new Configuration({ignoreEnvironmentCheck: null}, logger); }); }); - it('Should throw if invalid type for serviceContext.service', function() { + it('Should throw if invalid for serviceContext.service', function() { assert.throws(function() { new Configuration({serviceContext: {service: false}}, logger); }); }); - it('Should throw if invalid type for serviceContext.version', function() { + it('Should throw if invalid for serviceContext.version', function() { assert.throws(function() { new Configuration({serviceContext: {version: true}}, logger); }); }); - it('Should not throw given an empty object for serviceContext', function() { - assert.doesNotThrow(function() { - new Configuration({serviceContext: {}}, logger); - }); - }); + it('Should not throw given an empty object for serviceContext', + function() { + assert.doesNotThrow(function() { + new Configuration({serviceContext: {}}, logger); + }); + } + ); }); }); } diff --git a/packages/error-reporting/test/unit/testExpressInterface.js b/packages/error-reporting/test/unit/testExpressInterface.js index bdffab630aa..33d2350f95c 100644 --- a/packages/error-reporting/test/unit/testExpressInterface.js +++ b/packages/error-reporting/test/unit/testExpressInterface.js @@ -83,7 +83,7 @@ describe('expressInterface', function() { sendError: sendError }; var handler = expressInterface(client, stubbedConfig); - handler(testError, null, null, function(){return;}); + handler(testError, null, null, function() {return;}); }); }); }); diff --git a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js index 67bf0be19f9..ad1b4594af6 100644 --- a/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testExpressRequestInformationExtractor.js @@ -17,8 +17,8 @@ 'use strict'; var assert = require('assert'); -var expressRequestInformationExtractor = require('../../src/request-extractors/express.js'); - +var expressRequestInformationExtractor = + require('../../src/request-extractors/express.js'); var Fuzzer = require('../../utils/fuzzer.js'); var extend = require('extend'); @@ -53,7 +53,7 @@ describe('Behaviour under varying input', } }; var FULL_RES_DERIVATION_VALUE = { - 'statusCode': 200 + statusCode: 200 }; var FULL_REQ_EXPECTED_VALUE = { method: 'STUB_METHOD', @@ -154,4 +154,4 @@ describe('Behaviour under varying input', ); } ); -}); + }); diff --git a/packages/error-reporting/test/unit/testHapiInterface.js b/packages/error-reporting/test/unit/testHapiInterface.js index 702fd1bb775..fe5d0213a40 100644 --- a/packages/error-reporting/test/unit/testHapiInterface.js +++ b/packages/error-reporting/test/unit/testHapiInterface.js @@ -69,11 +69,11 @@ describe('Hapi interface', function() { describe('hapiRegisterFunction behaviour', function() { var fakeServer; beforeEach(function() {fakeServer = new EventEmitter();}); - it('Should call sendError when the request-error event is emitted', function() { + it('Should call fn when the request-error event is emitted', function() { var fakeClient = { sendError: function(errMsg) { assert(errMsg instanceof ErrorMessage, - 'The value given to sendError should be an instance of Error message'); + 'should be an instance of Error message'); } }; var plugin = hapiInterface(fakeClient, { @@ -93,7 +93,8 @@ describe('Hapi interface', function() { }); describe('Behaviour around the request/response lifecycle', function() { var EVENT = 'onPreResponse'; - var fakeServer, config, plugin, fakeClient = {sendError: function() {}}; + var fakeClient = {sendError: function() {}}; + var fakeServer, config, plugin; before(function() { config = new Configuration({ projectId: 'xyz', @@ -112,7 +113,7 @@ describe('Hapi interface', function() { afterEach(function() { fakeServer.removeAllListeners(); }); - it('Should call continue when a boom preResponse is emitted', function(done) { + it('Should call continue when a boom is emitted', function(done) { plugin.register(fakeServer, null, function() {}); fakeServer.emit(EVENT, {response: {isBoom: true}}, { @@ -123,7 +124,7 @@ describe('Hapi interface', function() { } ); }); - it('Should call sendError when a boom response is received', function(done) { + it('Should call sendError when a boom is received', function(done) { var fakeClient = { sendError: function(err) { assert(err instanceof ErrorMessage); @@ -132,7 +133,7 @@ describe('Hapi interface', function() { }; var plugin = hapiInterface(fakeClient, config); plugin.register(fakeServer, null, function() {}); - fakeServer.emit('onPreResponse', {response:{isBoom: true}}); + fakeServer.emit('onPreResponse', {response: {isBoom: true}}); }); it('Should call next when completing a request', function(done) { plugin.register(fakeServer, null, function(err) { diff --git a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js index e53df0c7a7a..c580910987c 100644 --- a/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testHapiRequestInformationExtractor.js @@ -17,7 +17,8 @@ 'use strict'; var assert = require('assert'); -var hapiRequestInformationExtractor = require('../../src/request-extractors/hapi.js'); +var hapiRequestInformationExtractor = + require('../../src/request-extractors/hapi.js'); var Fuzzer = require('../../utils/fuzzer.js'); describe('hapiRequestInformationExtractor behaviour', function() { diff --git a/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js index 2b712038ac0..45dddf7fa22 100644 --- a/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testKoaRequestInformationExtractor.js @@ -17,7 +17,8 @@ 'use strict'; var assert = require('assert'); -var koaRequestInformationExtractor = require('../../src/request-extractors/koa.js'); +var koaRequestInformationExtractor = + require('../../src/request-extractors/koa.js'); var Fuzzer = require('../../utils/fuzzer.js'); describe('koaRequestInformationExtractor', function() { @@ -51,7 +52,7 @@ describe('koaRequestInformationExtractor', function() { ip: '0.0.0.0' }; var FULL_RES_DERIVATION_VALUE = { - 'status': 200 + status: 200 }; var FULL_REQ_EXPECTED_VALUE = { method: 'STUB_METHOD', @@ -62,7 +63,8 @@ describe('koaRequestInformationExtractor', function() { statusCode: 200 }; assert.deepEqual( - koaRequestInformationExtractor(FULL_REQ_DERIVATION_VALUE, FULL_RES_DERIVATION_VALUE), + koaRequestInformationExtractor(FULL_REQ_DERIVATION_VALUE, + FULL_RES_DERIVATION_VALUE), FULL_REQ_EXPECTED_VALUE); }); }); diff --git a/packages/error-reporting/test/unit/testManualHandler.js b/packages/error-reporting/test/unit/testManualHandler.js index b7722a8458e..bb39e4ed048 100644 --- a/packages/error-reporting/test/unit/testManualHandler.js +++ b/packages/error-reporting/test/unit/testManualHandler.js @@ -30,7 +30,7 @@ describe('Manual handler', function() { // nock.disableNetConnect(); // Mocked client var client = { - sendError: function(e, cb) { + sendError: function(e, cb) { // immediately callback if (cb) { setImmediate(cb); @@ -41,24 +41,24 @@ describe('Manual handler', function() { describe('Report invocation behaviour', function() { it('Should allow argument-less invocation', function() { var r = report(); - assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); + assert(r instanceof ErrorMessage, 'should be an inst of ErrorMessage'); }); it('Should allow single string', function() { var r = report('doohickey'); - assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); + assert(r instanceof ErrorMessage, 'should be an inst of ErrorMessage'); assert(r.message.match(/doohickey/), 'string error should propagate'); }); - it('Should allow single instance of Error', function() { + it('Should allow single inst of Error', function() { var r = report(new Error('hokeypokey')); assert(r.message.match(/hokeypokey/)); }); - it('Should allow a single function as a malformed error input', function(done) { + it('Should allow a function as a malformed error input', function(done) { this.timeout(2000); var r = report(function(err, res) { assert(false, 'callback should not be called'); done(); }); - assert(r instanceof ErrorMessage, 'should be an instance of ErrorMessage'); + assert(r instanceof ErrorMessage, 'should be an inst of ErrorMessage'); setTimeout(function() { done(); }, 1000); @@ -69,22 +69,23 @@ describe('Manual handler', function() { }); assert(r.message.match(/malarkey/), 'string error should propagate'); }); - it('Should replace the error string with the additional message', function(done) { + it('replace the error string with the additional message', function(done) { var r = report('monkey', 'wrench', function(err, res) { done(); }); - assert.strictEqual(r.message, 'wrench', 'additional message should replace'); + assert.strictEqual(r.message, 'wrench', + 'additional message should replace'); }); it('Should allow a full array of optional arguments', function(done) { - var r = report('donkey', { method: 'FETCH' }, 'cart', function(err, res) { + var r = report('donkey', { method: 'FETCH' }, 'cart', function(err, res) { done(); }); - assert.strictEqual(r.message, 'cart', 'additional message should replace'); + assert.strictEqual(r.message, 'cart', 'additional message replace'); assert.strictEqual(r.context.httpRequest.method, 'FETCH'); }); it('Should allow all optional arguments except the callback', function() { var r = report('whiskey', { method: 'SIP' }, 'sour'); - assert.strictEqual(r.message, 'sour', 'additional message should replace'); + assert.strictEqual(r.message, 'sour', 'additional message replace'); assert.strictEqual(r.context.httpRequest.method, 'SIP'); }); it('Should allow a lack of additional message', function(done) { @@ -95,14 +96,14 @@ describe('Manual handler', function() { 'original message should be preserved'); assert.strictEqual(r.context.httpRequest.method, 'TACKEY'); }); - it('Should ignore arguments after callback value placement', function(done) { + it('Should ignore arguments', function(done) { var r = report('hockey', function(err, res) { done(); }, 'field'); assert(r.message.match('hockey') && !r.message.match('field'), 'string after callback should be ignored'); }); - it('Should ignore arguments after callback value placement', function(done) { + it('Should ignore arguments', function(done) { var r = report('passkey', function(err, res) { done(); }, { method: 'HONK'}); @@ -114,7 +115,7 @@ describe('Manual handler', function() { }); assert(r.message.match(/pokey/), 'string error should propagate'); }); - it('Should allow explicit undefined arguments as placeholders', function(done) { + it('Should allow explicit undefined', function(done) { var r = report('Turkey', undefined, undefined, function(err, res) { done(); }); @@ -124,12 +125,13 @@ describe('Manual handler', function() { var r = report('turnkey', undefined, 'solution', function(err, res) { done(); }); - assert.strictEqual(r.message, 'solution', 'string error should propagate'); + assert.strictEqual(r.message, 'solution', 'error should propagate'); }); - it('Should allow additional message to be supplied as undefined', function(done) { - var r = report('Mickey', { method: 'SNIFF'}, undefined, function(err, res) { - done(); - }); + it('Should allow additional message', function(done) { + var r = + report('Mickey', { method: 'SNIFF'}, undefined, function(err, res) { + done(); + }); assert(r.message.match(/Mickey/) && !r.message.match(/SNIFF/), 'string error should propagate'); assert.strictEqual(r.context.httpRequest.method, 'SNIFF'); @@ -137,11 +139,11 @@ describe('Manual handler', function() { }); describe('Custom Payload Builder', function() { - it('Should accept builder instance as only argument', function() { + it('Should accept builder inst as only argument', function() { var msg = 'test'; var r = report(new ErrorMessage().setMessage(msg)); assert.strictEqual(r.message, msg, - 'string message should propagate from error message instance'); + 'string message should propagate from error message inst'); }); it('Should accept builder and request as arguments', function() { var msg = 'test'; @@ -152,15 +154,15 @@ describe('Manual handler', function() { newReq ); assert.strictEqual(r.message, msg, - 'string message should propagate from error message instance'); + 'string message should propagate from error message inst'); assert.strictEqual(r.context.httpRequest.method, newReq.method, [ - 'request argument supplied at report invocation should propagte and, if', - 'supplied, should overwrite any prexisting data in the field.' + 'request argument supplied at report invocation should propagte and', + 'if supplied, should overwrite any prexisting data in the field.' ].join('\n') ); }); - it('Should accept message and additional message params as arguments', function() { + it('Should accept message and additional message params as', function() { var oldMsg = 'test'; var newMsg = 'analysis'; var r = report( @@ -169,11 +171,11 @@ describe('Manual handler', function() { ); assert.strictEqual(r.message, newMsg, [ - 'message argument supplied at report invocation should propagte and, if', + 'message supplied at report invocation should propagte and, if', 'supplied, should overwrite any prexisting data in the message field.' ].join('\n')); }); - it('Should accept message and callback function as arguments', function(done) { + it('Should accept message and callback function', function(done) { var oldMsg = 'test'; report( new ErrorMessage().setMessage(oldMsg), diff --git a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js index ff75f1eb9b9..43fc1661474 100644 --- a/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js +++ b/packages/error-reporting/test/unit/testManualRequestInformationExtractor.js @@ -19,7 +19,8 @@ var assert = require('assert'); var omit = require('lodash.omit'); var extend = require('extend'); -var manualRequestInformationExtractor = require('../../src/request-extractors/manual.js'); +var manualRequestInformationExtractor = + require('../../src/request-extractors/manual.js'); var Fuzzer = require('../../utils/fuzzer.js'); describe('manualRequestInformationExtractor', function() { @@ -63,7 +64,7 @@ describe('manualRequestInformationExtractor', function() { manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'method')), extend({}, FULL_VALID_INPUT, {method: ''}), [ - 'Given a full valid input object sans the method property these values', + 'Given a full valid input object sans the method property values', 'should be reflected by the output of the request extraction' ].join(' ') ); @@ -71,13 +72,13 @@ describe('manualRequestInformationExtractor', function() { manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'url')), extend({}, FULL_VALID_INPUT, {url: ''}), [ - 'Given a full valid input sans the url property these values should be', + 'Given a valid input sans the url property these values should be', 'reflected by the output of the request extraction' ] ); assert.deepEqual( manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'userAgent')), - extend({}, FULL_VALID_INPUT, {'userAgent': ''}), + extend({}, FULL_VALID_INPUT, {userAgent: ''}), [ 'Given a full valid input sans the userAgent property these values', 'should be reflected by the output of the request extraction' @@ -100,10 +101,11 @@ describe('manualRequestInformationExtractor', function() { ] ); assert.deepEqual( - manualRequestInformationExtractor(omit(FULL_VALID_INPUT, 'remoteAddress')), + manualRequestInformationExtractor(omit(FULL_VALID_INPUT, + 'remoteAddress')), extend({}, FULL_VALID_INPUT, {remoteAddress: ''}), [ - 'Given a full valid input sans the remoteAddress property these values', + 'Given a valid input sans the remoteAddress property these values', 'should be reflected by the output of the request extraction' ] ); diff --git a/packages/error-reporting/test/unit/testRequestInformationContainer.js b/packages/error-reporting/test/unit/testRequestInformationContainer.js index 4e78b33b878..baf2fcf691f 100644 --- a/packages/error-reporting/test/unit/testRequestInformationContainer.js +++ b/packages/error-reporting/test/unit/testRequestInformationContainer.js @@ -17,15 +17,16 @@ 'use strict'; var assert = require('assert'); -var RequestInformationContainer = require('../../src/classes/request-information-container.js'); +var RequestInformationContainer = + require('../../src/classes/request-information-container.js'); var Fuzzer = require('../../utils/fuzzer.js'); describe('RequestInformationContainer', function() { var f = new Fuzzer(); var cbFn, ric; beforeEach(function() {ric = new RequestInformationContainer();}); - describe('Fuzzing against RequestInformationContainer for negative cases', function() { - it('Should return the RequestInformationContainer.url propertym as an empty string', + describe('Fuzzing against RequestInformationContainer', function() { + it('Should return the property as an empty string', function() { cbFn = function() { assert.deepEqual(ric.url, ''); @@ -51,7 +52,7 @@ describe('RequestInformationContainer', function() { }; f.fuzzFunctionForTypes(ric.setUserAgent, ['string'], cbFn, ric); }); - it('Should return the remoteAddress property as an empty string', function() { + it('Should return the property as an empty string', function() { cbFn = function(returnValue) { assert.deepEqual(ric.remoteAddress, ''); }; @@ -64,7 +65,7 @@ describe('RequestInformationContainer', function() { f.fuzzFunctionForTypes(ric.setStatusCode, ['number'], cbFn, ric); }); }); - describe('Fuzzing against RequestInformationContainer for positive cases', function() { + describe('Fuzzing against for positive cases', function() { var VALID_STRING_INPUT = 'valid'; var VALID_NUMBER_INPUT = 500; it('Should assign the value to the url property', function() { diff --git a/packages/error-reporting/test/unit/testRestifyInterface.js b/packages/error-reporting/test/unit/testRestifyInterface.js index d97e13ba289..781204f0bc9 100644 --- a/packages/error-reporting/test/unit/testRestifyInterface.js +++ b/packages/error-reporting/test/unit/testRestifyInterface.js @@ -68,7 +68,7 @@ describe('restifyInterface', function() { requestHandlerInstance(req, res, noOp); }); }); - it('Should have 1 listener on the finish event after handling req/res', function() { + it('Should have 1 listener', function() { assert.strictEqual(res.listenerCount(FINISH), 1); }); it('Should not throw when emitting the finish event', function() { @@ -112,7 +112,7 @@ describe('restifyInterface', function() { requestHandlerInstance(req, res, noOp); }); }); - it('Should have 1 listener on the finish event after instantiation', function() { + it('Should have 1 listener on the finish event', function() { assert.strictEqual(res.listenerCount(FINISH), 1); }); it('Should not throw on emission of the finish event', function() { @@ -121,7 +121,7 @@ describe('restifyInterface', function() { }); }); describe('Exercise the uncaughtException event path', function() { - it('Should call the sendError function property on the client', function(done) { + it('Should call the sendError function property', function(done) { client.sendError = function() { assert(true, 'sendError should be called'); done(); diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index 1d4cc772d69..66817c7beae 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -39,13 +39,13 @@ function sterilizeEnv() { delete process.env[key]; }); } -function setEnv(serviceName, serviceVersion, moduleName, moduleVersion, functionName) { +function setEnv(serviceName, serviceVersion, moduleName, mv, fn) { assign(process.env, omitBy({ GAE_SERVICE: serviceName, GAE_VERSION: serviceVersion, GAE_MODULE_NAME: moduleName, - GAE_MODULE_VERSION: moduleVersion, - FUNCTION_NAME: functionName + GAE_MODULE_VERSION: mv, + FUNCTION_NAME: fn }, function(val) {return !isString(val);})); } function restoreEnv() { @@ -113,7 +113,7 @@ describe('Testing service configuration', function() { } ); it( - 'A Configuration uses the service name and version in the given config if ' + + 'A Configuration uses the service name and version in the given config' + 'they were both specified and both the GAE_SERVICE and FUNCTION_NAME ' + 'env vars are set', function() { @@ -147,7 +147,7 @@ describe('Testing service configuration', function() { } ); it( - 'A Configuration uses the service name and version in the given config if ' + + 'A Configuration uses the service name and version in the given config ' + 'they were both specified and only the GAE_SERVICE env var is set', function() { setEnv('someModuleName', '1.0', 'InvalidName', 'InvalidVersion', null); @@ -179,8 +179,8 @@ describe('Testing service configuration', function() { } ); it( - 'A Configuration uses the service name and version in the given config if ' + - 'they were both specified and only the FUNCTION_NAME env var is set', + 'A Configuration uses the service name and version in the given config ' + + 'if they were both specified and only the FUNCTION_NAME env var is set', function() { setEnv(null, '1.0', null, 'InvalidVersion', 'someFunction'); var c = new Configuration({ diff --git a/packages/error-reporting/test/unit/testUncaught.js b/packages/error-reporting/test/unit/testUncaught.js index 06105c6fcf4..8d9fb503a7e 100644 --- a/packages/error-reporting/test/unit/testUncaught.js +++ b/packages/error-reporting/test/unit/testUncaught.js @@ -60,12 +60,12 @@ describe('Uncaught exception handler behvaiour', function() { 'reportUncaughtExceptions is false', function() { uncaughtSetup({}, getConfig(false)); assert.strictEqual(process.listeners(UNCAUGHT).length, 0); - }); + }); it('Should attach a listener to the uncaughtException event if ' + 'reportUncaughtExceptions is true', function() { uncaughtSetup({}, getConfig(true)); assert.strictEqual(process.listeners(UNCAUGHT).length, 1); - }); + }); }); describe('Uncaught exception handling shutdown behaviour', function() { before(function() { From abb9b35d29fd59e565126cf9c934b1a7494fb865 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 11:59:33 -0800 Subject: [PATCH 11/29] use new common.Service class. Remove testConfigCredentials file since this concern is handled by Service class --- packages/error-reporting/package.json | 1 + .../src/google-apis/auth-client.js | 170 +++++++++------- .../test/system-test/testAuthClient.js | 6 +- .../test-servers/manual_scaffold_server.js | 15 +- .../test/unit/testConfigCredentials.js | 187 ------------------ 5 files changed, 101 insertions(+), 278 deletions(-) delete mode 100644 packages/error-reporting/test/unit/testConfigCredentials.js diff --git a/packages/error-reporting/package.json b/packages/error-reporting/package.json index 2f3898a0287..f7af6548c5b 100644 --- a/packages/error-reporting/package.json +++ b/packages/error-reporting/package.json @@ -39,6 +39,7 @@ "tape": "^4.5.1" }, "dependencies": { + "@google-cloud/common": "^0.12.0", "@google/cloud-diagnostics-common": "0.3.0", "extend": "^3.0.0", "is": "^3.2.0", diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 669962a9bec..239b9758ca6 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -16,7 +16,8 @@ /*jshint unused:false*/ 'use strict'; -var commonDiag = require('@google/cloud-diagnostics-common'); +const common = require('@google-cloud/common'); +const pkg = require('../../package.json'); var logger = require('../logger.js'); var is = require('is'); var isFunction = is.fn; @@ -53,84 +54,105 @@ var API = 'https://clouderrorreporting.googleapis.com/v1beta1/projects'; * address the correct project in the Error Reporting API * @property {Object} _logger - the instance-cached logger instance */ -function RequestHandler(config, logger) { - this._request = commonDiag.utils.authorizedRequestFactory(SCOPES, { - keyFile: config.getKeyFilename(), - credentials: config.getCredentials() - }); - this._config = config; - this._logger = logger; -} - -/** - * Compute the URL that errors should be reported to given the projectId and - * optional key. - * @param {String} projectId - the project id of the application. - * @param {String|Null} [key] - the API key used to authenticate against the - * service in place of application default credentials. - * @returns {String} computed URL that the errors should be reported to. - * @private - */ -function getErrorReportURL(projectId, key) { - var url = [API, projectId, 'events:report'].join('/'); - if (isString(key)) { - url += '?key=' + key; +class RequestHandler extends common.Service { + /** + * Compute the URL that errors should be reported to given the projectId and + * optional key. + * @param {String} projectId - the project id of the application. + * @param {String|Null} [key] - the API key used to authenticate against the + * service in place of application default credentials. + * @returns {String} computed URL that the errors should be reported to. + * @static + */ + static getErrorReportURL(projectId, key) { + var url = [API, projectId, 'events:report'].join('/'); + if (isString(key)) { + url += '?key=' + key; + } + return url; } - return url; -} - -/** - * Creates a request options object given the value of the error message and - * will callback to the user supplied callback if given one. If a callback is - * not given then the request will execute and silently dissipate. - * @function sendError - * @param {ErrorMessage} payload - the ErrorMessage instance to JSON.stringify - * for submission to the service - * @param {RequestHandler~requestCallback} [userCb] - function called when the - * request has succeeded or failed. - * @returns {Undefined} - does not return anything - */ -RequestHandler.prototype.sendError = function(errorMessage, userCb) { - var self = this; - var cb = isFunction(userCb) ? userCb: function() {}; - if (self._config.getShouldReportErrorsToAPI()) { - self._config.getProjectId(function(err, id) { - if (err) { - setImmediate(function() { cb(err, null, null); }); - self._logger.error([ - 'Unable to retrieve a project id from the Google Metadata Service or', - 'the local environment. Client will not be able to communicate with', - 'the Stackdriver Error Reporting API without a valid project id', - 'Please make sure to supply a project id either through the', - 'GCLOUD_PROJECT environmental variable or through the configuration', - 'object given to this library on startup if not running on Google', - 'Cloud Platform.' - ].join(' ')); - return; - } - self._request({ - url: getErrorReportURL(id, self._config.getKey()), - method: 'POST', - json: errorMessage - }, function(err, response, body) { + /** + * No-operation stub function for user callback substitution + * @param {Error|Null} err - the error + * @param {Object|Null} response - the response object + * @param {Any} body - the response body + * @returns {Null} + * @static + */ + static noOp(err, response, body) { + return null; + } + /** + * @constructor + * @param {Configuration} config - an instance of the Configuration class + * @param {Logger} logger - an instance of logger + */ + constructor(config, logger) { + super({ + packageJson: pkg, + projectIdRequired: false, + baseUrl: 'https://clouderrorreporting.googleapis.com/v1beta1/', + scopes: SCOPES + }, config); + this._config = config; + this._logger = logger; + } + /** + * Creates a request options object given the value of the error message and + * will callback to the user supplied callback if given one. If a callback is + * not given then the request will execute and silently dissipate. + * @function sendError + * @param {ErrorMessage} payload - the ErrorMessage instance to JSON.stringify + * for submission to the service + * @param {RequestHandler~requestCallback} [userCb] - function called when the + * request has succeeded or failed. + * @returns {Undefined} - does not return anything + * @instance + */ + sendError(errorMessage, userCb) { + var self = this; + var cb = isFunction(userCb) ? userCb : RequestHandler.noOp; + if (this._config.getShouldReportErrorsToAPI()) { + this._config.getProjectId((err, id) => { if (err) { - self._logger.error([ - 'Encountered an error while attempting to transmit an error to the', - 'Stackdriver Error Reporting API.' - ].join(' '), err); + setImmediate(function() { cb(err, null, null); }); + this._logger.error([ + 'Unable to retrieve a project id from the Google Metadata Service or', + 'the local environment. Client will not be able to communicate with', + 'the Stackdriver Error Reporting API without a valid project id', + 'Please make sure to supply a project id either through the', + 'GCLOUD_PROJECT environmental variable or through the configuration', + 'object given to this library on startup if not running on Google', + 'Cloud Platform.' + ].join(' ')); + return; } - cb(err, response, body); + console.log('SENDING', JSON.stringify(errorMessage, null, 2)) + this.request({ + uri: RequestHandler.getErrorReportURL(id, this._config.getKey()), + method: 'POST', + json: errorMessage + }, (err, body, response) => { + if (err) { + this._logger.error([ + 'Encountered an error while attempting to transmit an error to the', + 'Stackdriver Error Reporting API.' + ].join(' '), err); + } + cb(err, response, body); + }); }); - }); - } else { - cb(new Error([ - '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(' ')), null, null); + } else { + cb(new Error([ + '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(' ')), null, null); + } } -}; +} + /** * The requestCallback callback function is called on completion of an API * request whether that completion is success or failure. The request can either diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index ea38afc8e51..788a3f6a60d 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -75,9 +75,9 @@ describe('Behvaiour acceptance testing', function() { this.timeout(5000); client.sendError({}, function(err, response, body) { assert(err instanceof Error); + console.log('here is the message', err.message.toLowerCase(), body, response.statusCode); assert.strictEqual(err.message.toLowerCase(), 'message cannot be empty.'); - assert.strictEqual(body, null); assert(isObject(response)); assert.strictEqual(response.statusCode, 400); done(); @@ -88,7 +88,7 @@ describe('Behvaiour acceptance testing', function() { it('Should retry', function(done) { this.timeout(25000); var tries = 0; - var intendedTries = 5; + var intendedTries = 4; fakeService.reply(429, function() { tries += 1; console.log('Mock Server Received Request:', tries + '/' + @@ -265,7 +265,6 @@ describe('Behvaiour acceptance testing', function() { client.sendError({}, function(err, response, body) { assert(err instanceof Error); assert.strictEqual(err.message, ERROR_STRING); - assert.strictEqual(body, null); assert.strictEqual(response, null); done(); }); @@ -294,7 +293,6 @@ describe('Behvaiour acceptance testing', function() { assert(err instanceof Error); assert.strictEqual(err.message, ERROR_STRING); assert.strictEqual(response, null); - assert.strictEqual(body, null); done(); }); }); diff --git a/packages/error-reporting/test/test-servers/manual_scaffold_server.js b/packages/error-reporting/test/test-servers/manual_scaffold_server.js index 1464f764279..cbdcd9472fb 100644 --- a/packages/error-reporting/test/test-servers/manual_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/manual_scaffold_server.js @@ -20,17 +20,6 @@ errors.report('Sample test string', (err, response, body) => { console.log( 'Callback from report:\n', '\tError: ', err, '\n', - '\tResponse Body:', body + '\tResponse Body:' ); -}); - -var express = require('express'); -var app = express(); - -app.get('/', function(req, res) { - res.send('Hello World!'); -}); - -app.listen(3000, function() { - console.log('Example app listening on port 3000!'); -}); +}); \ No newline at end of file diff --git a/packages/error-reporting/test/unit/testConfigCredentials.js b/packages/error-reporting/test/unit/testConfigCredentials.js deleted file mode 100644 index 31b456a31c2..00000000000 --- a/packages/error-reporting/test/unit/testConfigCredentials.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Copyright 2016 Google Inc. All Rights Reserved. - * - * 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 - * - * http://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. - */ -'use strict'; - -var assert = require('assert'); -var path = require('path'); -var nock = require('nock'); -var http = require('http'); -var express = require('express'); -var Errors = require('../..'); - -var originalHandlers = process.listeners('uncaughtException'); - -function reattachOriginalListeners() { - for (var i = 0; i < originalHandlers.length; i++) { - process.on('uncaughtException', originalHandlers[i]); - } -} - -var oldg, olde; - -describe('Testing use of runtime configurations', function() { - before(function() { - nock.cleanAll(); - nock.disableNetConnect(); - process.removeAllListeners('uncaughtException'); - oldg = process.env.GCLOUD_PROJECT; - olde = process.env.NODE_ENV; - delete process.env.GCLOUD_PROJECT; - process.env.NODE_ENV = 'production'; - }); - after(function() { - nock.enableNetConnect(); - process.env.GCLOUD_PROJECT = oldg; - process.env.NODE_ENV = olde; - }); - afterEach(function() { - nock.cleanAll(); - process.removeAllListeners('uncaughtException'); - }); - it('Should use the keyFilename field of the config object', function(done) { - this.timeout(25000); - var credentials = require('../fixtures/gcloud-credentials.json'); - var config = { - keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json'), - reportUncaughtExceptions: false, - projectId: '0' - }; - nock('https://accounts.google.com/o/oauth2') - .post('/token', function(body) { - assert.strictEqual(body.client_id, credentials.client_id); - assert.strictEqual(body.client_secret, credentials.client_secret); - assert.strictEqual(body.refresh_token, credentials.refresh_token); - done(); - return true; - }).times(1).reply(200, { - refresh_token: 'hello', - access_token: 'goodbye', - expiry_date: new Date(9999, 1, 1) - }); - var agent = new Errors(config); - agent.report(new Error('a b c')); - }); - describe( - 'use of the credentials field of the config object', - function() { - before(function() { - process.env.GCLOUD_PROJECT = '0'; - }); - after(function() { - delete process.env.GCLOUD_PROJECT; - nock.cleanAll(); - }); - it('Should use the credentials field of the object', function(done) { - var config = { - credentials: require('../fixtures/gcloud-credentials.json'), - reportUncaughtExceptions: false - }; - var agent = new Errors(config); - var app = express(); - app.use('/', function() { - throw '0'; - }); - app.use(agent.express); - var server = app.listen(3000, function() { - nock.enableNetConnect('localhost'); - var scope = nock('https://accounts.google.com/o/oauth2') - .intercept('/token', 'POST', function(body) { - assert.strictEqual(body.client_id, - config.credentials.client_id); - assert.strictEqual(body.client_secret, - config.credentials.client_secret); - assert.strictEqual(body.refresh_token, - config.credentials.refresh_token); - return true; - }).reply(200, { - refresh_token: 'hello', - access_token: 'goodbye', - expiry_date: new Date(9999, 1, 1) - }); - - // Since we have to get an auth token -- this gets intercepted second - nock('https://clouderrorreporting.googleapis.com/v1beta1/projects/0') - .post('/events:report', function() { - assert(scope.isDone()); - nock.cleanAll(); - server.close(); - reattachOriginalListeners(); - done(); - return true; - }).reply(200); - - http.get({port: 3000, path: '/'}, function(res) {}); - }); - }); - } - ); - it('Should ignore credentials if keyFilename is provided', function(done) { - var correctCredentials = require('../fixtures/gcloud-credentials.json'); - var config = { - keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json'), - projectId: '0', - credentials: { - client_id: 'a', - client_secret: 'b', - refresh_token: 'c', - type: 'authorized_user' - }, - reportUncaughtExceptions: true - }; - ['client_id', 'client_secret', 'refresh_token'].forEach(function(field) { - assert(correctCredentials.hasOwnProperty(field)); - assert(config.credentials.hasOwnProperty(field)); - assert.notEqual(config.credentials[field], - correctCredentials[field]); - }); - var agent = new Errors(config); - var app = express(); - app.use('/', function() { - throw '0'; - }); - app.use(agent.express); - var server = app.listen(3000, function() { - nock.disableNetConnect(); - nock.enableNetConnect('localhost'); - var scope = nock('https://accounts.google.com/o/oauth2') - .intercept('/token', 'POST', function(body) { - assert.strictEqual(body.client_id, correctCredentials.client_id); - assert.strictEqual(body.client_secret, - correctCredentials.client_secret); - assert.strictEqual(body.refresh_token, - correctCredentials.refresh_token); - return true; - }).reply(200, { - refresh_token: 'hello', - access_token: 'goodbye', - expiry_date: new Date(9999, 1, 1) - }); - - // Since we have to get an auth token, this always gets intercepted second - nock('https://clouderrorreporting.googleapis.com/v1beta1/projects/0') - .post('/events:report', function() { - assert(scope.isDone()); - nock.cleanAll(); - server.close(); - reattachOriginalListeners(); - done(); - return true; - }).reply(200); - - http.get({port: 3000, path: '/'}, function(res) {}); - }); - }); -}); From e674ef896eaf7c6fc8e90bf5d48a304cdab5d078 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 12:02:04 -0800 Subject: [PATCH 12/29] remove debug log calls --- packages/error-reporting/src/google-apis/auth-client.js | 1 - packages/error-reporting/test/system-test/testAuthClient.js | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 239b9758ca6..06496045661 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -127,7 +127,6 @@ class RequestHandler extends common.Service { ].join(' ')); return; } - console.log('SENDING', JSON.stringify(errorMessage, null, 2)) this.request({ uri: RequestHandler.getErrorReportURL(id, this._config.getKey()), method: 'POST', diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index 788a3f6a60d..6f9dc70e683 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -75,7 +75,6 @@ describe('Behvaiour acceptance testing', function() { this.timeout(5000); client.sendError({}, function(err, response, body) { assert(err instanceof Error); - console.log('here is the message', err.message.toLowerCase(), body, response.statusCode); assert.strictEqual(err.message.toLowerCase(), 'message cannot be empty.'); assert(isObject(response)); From 19d89afc5e217ef14623a32c08f6baabb25c616d Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 12:10:53 -0800 Subject: [PATCH 13/29] fix linting errors --- .../src/google-apis/auth-client.js | 26 +++++++++---------- .../test/system-test/testAuthClient.js | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 06496045661..82b9ca32191 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -82,7 +82,7 @@ class RequestHandler extends common.Service { static noOp(err, response, body) { return null; } - /** + /** * @constructor * @param {Configuration} config - an instance of the Configuration class * @param {Logger} logger - an instance of logger @@ -117,13 +117,13 @@ class RequestHandler extends common.Service { if (err) { setImmediate(function() { cb(err, null, null); }); this._logger.error([ - 'Unable to retrieve a project id from the Google Metadata Service or', - 'the local environment. Client will not be able to communicate with', - 'the Stackdriver Error Reporting API without a valid project id', - 'Please make sure to supply a project id either through the', - 'GCLOUD_PROJECT environmental variable or through the configuration', - 'object given to this library on startup if not running on Google', - 'Cloud Platform.' + 'Unable to retrieve a project id from the Google Metadata Service', + 'or the local environment. Client will not be able to communicate', + 'with the Stackdriver Error Reporting API without a valid project', + 'id. Please make sure to supply a project id either through the', + 'GCLOUD_PROJECT environmental variable or through the', + 'configuration object given to this library on startup if not', + 'running on Google Cloud Platform.' ].join(' ')); return; } @@ -134,8 +134,8 @@ class RequestHandler extends common.Service { }, (err, body, response) => { if (err) { this._logger.error([ - 'Encountered an error while attempting to transmit an error to the', - 'Stackdriver Error Reporting API.' + 'Encountered an error while attempting to transmit an error to', + 'the Stackdriver Error Reporting API.' ].join(' '), err); } cb(err, response, body); @@ -144,9 +144,9 @@ class RequestHandler extends common.Service { } else { cb(new Error([ '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' + '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(' ')), null, null); } } diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/test/system-test/testAuthClient.js index 6f9dc70e683..fe9bf3571ca 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/test/system-test/testAuthClient.js @@ -248,7 +248,7 @@ describe('Behvaiour acceptance testing', function() { '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' + 'property to true in the runtime configuration object' ].join(' '); var logger, client; before(function() { From b664f6dcfd2af251643023ba156bc208488f677c Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 1 Mar 2017 12:11:18 -0800 Subject: [PATCH 14/29] remove dependency on cloud-diagnostics-common --- packages/error-reporting/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/error-reporting/package.json b/packages/error-reporting/package.json index f7af6548c5b..66da046ee42 100644 --- a/packages/error-reporting/package.json +++ b/packages/error-reporting/package.json @@ -40,7 +40,6 @@ }, "dependencies": { "@google-cloud/common": "^0.12.0", - "@google/cloud-diagnostics-common": "0.3.0", "extend": "^3.0.0", "is": "^3.2.0", "lodash.has": "^4.5.2" From 93a940c98f9d7f4ea9430645c18dee2e3f6e1c51 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Fri, 10 Mar 2017 07:20:52 -0800 Subject: [PATCH 15/29] fix ternary operator spacing --- .../src/classes/custom-stack-trace.js | 8 +++--- .../src/classes/error-message.js | 26 +++++++++---------- .../classes/request-information-container.js | 12 ++++----- packages/error-reporting/src/configuration.js | 6 ++--- .../test/unit/testConfiguration.js | 2 +- .../test/unit/testServiceConfiguration.js | 2 +- packages/error-reporting/utils/fuzzer.js | 24 ++++++++--------- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/packages/error-reporting/src/classes/custom-stack-trace.js b/packages/error-reporting/src/classes/custom-stack-trace.js index 7eab92c4dfd..7e9d3ea8eba 100644 --- a/packages/error-reporting/src/classes/custom-stack-trace.js +++ b/packages/error-reporting/src/classes/custom-stack-trace.js @@ -66,7 +66,7 @@ function CustomStackTrace() { */ CustomStackTrace.prototype.setFilePath = function(filePath) { - this.filePath = isString(filePath) ? filePath: ''; + this.filePath = isString(filePath) ? filePath : ''; return this; }; @@ -80,7 +80,7 @@ CustomStackTrace.prototype.setFilePath = function(filePath) { */ CustomStackTrace.prototype.setLineNumber = function(lineNumber) { - this.lineNumber = isNumber(lineNumber) ? lineNumber: 0; + this.lineNumber = isNumber(lineNumber) ? lineNumber : 0; return this; }; @@ -94,7 +94,7 @@ CustomStackTrace.prototype.setLineNumber = function(lineNumber) { */ CustomStackTrace.prototype.setFunctionName = function(functionName) { - this.functionName = isString(functionName) ? functionName: ''; + this.functionName = isString(functionName) ? functionName : ''; return this; }; @@ -109,7 +109,7 @@ CustomStackTrace.prototype.setFunctionName = function(functionName) { */ CustomStackTrace.prototype.setStringifyStructuredCallList = function(op) { - this.stringifyStucturedCallList = isFunction(op) ? op: stubbedNoOp; + this.stringifyStucturedCallList = isFunction(op) ? op : stubbedNoOp; return this; }; diff --git a/packages/error-reporting/src/classes/error-message.js b/packages/error-reporting/src/classes/error-message.js index 63a3a4afd80..9683c87f08d 100644 --- a/packages/error-reporting/src/classes/error-message.js +++ b/packages/error-reporting/src/classes/error-message.js @@ -109,8 +109,8 @@ ErrorMessage.prototype.setEventTimeToNow = function() { */ ErrorMessage.prototype.setServiceContext = function(service, version) { - this.serviceContext.service = isString(service) ? service: 'node'; - this.serviceContext.version = isString(version) ? version: undefined; + this.serviceContext.service = isString(service) ? service : 'node'; + this.serviceContext.version = isString(version) ? version : undefined; return this; }; @@ -123,7 +123,7 @@ ErrorMessage.prototype.setServiceContext = function(service, version) { */ ErrorMessage.prototype.setMessage = function(message) { - this.message = isString(message) ? message: ''; + this.message = isString(message) ? message : ''; return this; }; @@ -137,7 +137,7 @@ ErrorMessage.prototype.setMessage = function(message) { */ ErrorMessage.prototype.setHttpMethod = function(method) { - this.context.httpRequest.method = isString(method) ? method: ''; + this.context.httpRequest.method = isString(method) ? method : ''; return this; }; @@ -150,7 +150,7 @@ ErrorMessage.prototype.setHttpMethod = function(method) { */ ErrorMessage.prototype.setUrl = function(url) { - this.context.httpRequest.url = isString(url) ? url: ''; + this.context.httpRequest.url = isString(url) ? url : ''; return this; }; @@ -163,7 +163,7 @@ ErrorMessage.prototype.setUrl = function(url) { */ ErrorMessage.prototype.setUserAgent = function(userAgent) { - this.context.httpRequest.userAgent = isString(userAgent) ? userAgent: ''; + this.context.httpRequest.userAgent = isString(userAgent) ? userAgent : ''; return this; }; @@ -176,7 +176,7 @@ ErrorMessage.prototype.setUserAgent = function(userAgent) { */ ErrorMessage.prototype.setReferrer = function(referrer) { - this.context.httpRequest.referrer = isString(referrer) ? referrer: ''; + this.context.httpRequest.referrer = isString(referrer) ? referrer : ''; return this; }; @@ -190,7 +190,7 @@ ErrorMessage.prototype.setReferrer = function(referrer) { ErrorMessage.prototype.setResponseStatusCode = function(responseStatusCode) { this.context.httpRequest.responseStatusCode = - isNumber(responseStatusCode) ? responseStatusCode: 0; + isNumber(responseStatusCode) ? responseStatusCode : 0; return this; }; @@ -203,7 +203,7 @@ ErrorMessage.prototype.setResponseStatusCode = function(responseStatusCode) { */ ErrorMessage.prototype.setRemoteIp = function(remoteIp) { - this.context.httpRequest.remoteIp = isString(remoteIp) ? remoteIp: ''; + this.context.httpRequest.remoteIp = isString(remoteIp) ? remoteIp : ''; return this; }; @@ -216,7 +216,7 @@ ErrorMessage.prototype.setRemoteIp = function(remoteIp) { */ ErrorMessage.prototype.setUser = function(user) { - this.context.user = isString(user) ? user: ''; + this.context.user = isString(user) ? user : ''; return this; }; @@ -229,7 +229,7 @@ ErrorMessage.prototype.setUser = function(user) { */ ErrorMessage.prototype.setFilePath = function(filePath) { - this.context.reportLocation.filePath = isString(filePath) ? filePath: ''; + this.context.reportLocation.filePath = isString(filePath) ? filePath : ''; return this; }; @@ -243,7 +243,7 @@ ErrorMessage.prototype.setFilePath = function(filePath) { ErrorMessage.prototype.setLineNumber = function(lineNumber) { this.context.reportLocation.lineNumber = - isNumber(lineNumber) ? lineNumber: 0; + isNumber(lineNumber) ? lineNumber : 0; return this; }; @@ -257,7 +257,7 @@ ErrorMessage.prototype.setLineNumber = function(lineNumber) { ErrorMessage.prototype.setFunctionName = function(functionName) { this.context.reportLocation.functionName = - isString(functionName) ? functionName: ''; + isString(functionName) ? functionName : ''; return this; }; diff --git a/packages/error-reporting/src/classes/request-information-container.js b/packages/error-reporting/src/classes/request-information-container.js index 1eea5c9bb85..70c76b846d9 100644 --- a/packages/error-reporting/src/classes/request-information-container.js +++ b/packages/error-reporting/src/classes/request-information-container.js @@ -57,7 +57,7 @@ function RequestInformationContainer() { */ RequestInformationContainer.prototype.setUrl = function(url) { - this.url = isString(url) ? url: ''; + this.url = isString(url) ? url : ''; return this; }; @@ -70,7 +70,7 @@ RequestInformationContainer.prototype.setUrl = function(url) { */ RequestInformationContainer.prototype.setMethod = function(method) { - this.method = isString(method) ? method: ''; + this.method = isString(method) ? method : ''; return this; }; @@ -83,7 +83,7 @@ RequestInformationContainer.prototype.setMethod = function(method) { */ RequestInformationContainer.prototype.setReferrer = function(referrer) { - this.referrer = isString(referrer) ? referrer: ''; + this.referrer = isString(referrer) ? referrer : ''; return this; }; @@ -96,7 +96,7 @@ RequestInformationContainer.prototype.setReferrer = function(referrer) { */ RequestInformationContainer.prototype.setUserAgent = function(userAgent) { - this.userAgent = isString(userAgent) ? userAgent: ''; + this.userAgent = isString(userAgent) ? userAgent : ''; return this; }; @@ -109,7 +109,7 @@ RequestInformationContainer.prototype.setUserAgent = function(userAgent) { */ RequestInformationContainer.prototype.setRemoteAddress = function(remoteIp) { - this.remoteAddress = isString(remoteIp) ? remoteIp: ''; + this.remoteAddress = isString(remoteIp) ? remoteIp : ''; return this; }; @@ -122,7 +122,7 @@ RequestInformationContainer.prototype.setRemoteAddress = function(remoteIp) { */ RequestInformationContainer.prototype.setStatusCode = function(statusCode) { - this.statusCode = isNumber(statusCode) ? statusCode: 0; + this.statusCode = isNumber(statusCode) ? statusCode : 0; return this; }; diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index fe85dd0182a..0424ce91b8c 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -180,7 +180,7 @@ var Configuration = function(givenConfig, logger) { * @type {Object|Null} * @defaultvalue null */ - this._givenConfiguration = isObject(givenConfig) ? givenConfig: {}; + this._givenConfiguration = isObject(givenConfig) ? givenConfig : {}; this._checkLocalServiceContext(); this._gatherLocalConfiguration(); }; @@ -230,8 +230,8 @@ Configuration.prototype._checkLocalServiceContext = function() { version = env.GAE_MODULE_VERSION; } - this._serviceContext.service = isString(service) ? service: 'node'; - this._serviceContext.version = isString(version) ? version: undefined; + this._serviceContext.service = isString(service) ? service : 'node'; + this._serviceContext.version = isString(version) ? version : undefined; if (isObject(this._givenConfiguration.serviceContext)) { if (isString(this._givenConfiguration.serviceContext.service)) { diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index f4b77d6efd3..86961d87bdc 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -23,7 +23,7 @@ var version = require('../../package.json').version; var Fuzzer = require('../../utils/fuzzer.js'); var level = process.env.GCLOUD_ERRORS_LOGLEVEL; var logger = require('../../src/logger.js')({ - logLevel: isNumber(level) ? level: 4 + logLevel: isNumber(level) ? level : 4 }); var nock = require('nock'); diff --git a/packages/error-reporting/test/unit/testServiceConfiguration.js b/packages/error-reporting/test/unit/testServiceConfiguration.js index 66817c7beae..f1dc4e634f9 100644 --- a/packages/error-reporting/test/unit/testServiceConfiguration.js +++ b/packages/error-reporting/test/unit/testServiceConfiguration.js @@ -25,7 +25,7 @@ var omitBy = require('lodash.omitby'); var Configuration = require('../fixtures/configuration.js'); var level = process.env.GCLOUD_ERRORS_LOGLEVEL; var logger = require('../../src/logger.js')({ - logLevel: isNumber(level) ? level: 4 + logLevel: isNumber(level) ? level : 4 }); var env = { GAE_SERVICE: process.env.GAE_SERVICE, diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js index 67df622a023..ea46dc4f84a 100644 --- a/packages/error-reporting/utils/fuzzer.js +++ b/packages/error-reporting/utils/fuzzer.js @@ -47,7 +47,7 @@ Fuzzer.prototype.generate.types = function() { } Fuzzer.prototype.generate.string = function(len) { - var lenChecked = isNumber(len) ? len: 10; + var lenChecked = isNumber(len) ? len : 10; var chars = []; for (var i = 0; i < lenChecked; i++) { @@ -64,7 +64,7 @@ Fuzzer.prototype.generate.boolean = function() { } Fuzzer.prototype.generate.alphaNumericString = function(len) { - var lenChecked = isNumber(len) ? len: 10; + var lenChecked = isNumber(len) ? len : 10; var chars = []; var thisRange = []; var ranges = [[48, 57], [65, 90], [97, 122]]; @@ -99,8 +99,8 @@ Fuzzer.prototype.generate.function = function() { Fuzzer.prototype.generate.number = function(lower, upper) { - var lowerChecked = isNumber(lower) ? lower: 0; - var upperChecked = isNumber(upper) ? upper: 100; + var lowerChecked = isNumber(lower) ? lower : 0; + var upperChecked = isNumber(upper) ? upper : 100; return random(lowerChecked, upperChecked); } @@ -117,10 +117,10 @@ Fuzzer.prototype.generate.undefined = function() { Fuzzer.prototype.generate.array = function(len, ofOneType, currentDepth, allowedDepth) { - var lenChecked = isNumber(len) ? len: random(1, 10); + var lenChecked = isNumber(len) ? len : random(1, 10); var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType]: this.types(); - var currentDepthChecked = isNumber(currentDepth) ? currentDepth: 0; - var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth: 3; + var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; + var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth : 3; var arr = []; var currentTypeBeingGenerated = ""; currentDepthChecked += 1; @@ -164,9 +164,9 @@ Fuzzer.prototype.generate.array = function(len, ofOneType, currentDepth, allowed Fuzzer.prototype.generate.object = function(numProperties, currentDepth, allowedDepth) { - var numPropertiesChecked = isNumber(numProperties) ? numProperties: random(1, 10); - var currentDepthChecked = isNumber(currentDepth) ? currentDepth: 0; - var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth: 3; + var numPropertiesChecked = isNumber(numProperties) ? numProperties : random(1, 10); + var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; + var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth : 3; var obj = {}; currentDepthChecked += 1; @@ -290,9 +290,9 @@ Fuzzer.prototype._generateValuesForFuzzTyping = function(typesToFuzzOnEach, inde } Fuzzer.prototype.fuzzFunctionForTypes = function(fnToFuzz, expectsArgTypes, cb, withContext) { - var expectsArgTypesChecked = isArray(expectsArgTypes) ? expectsArgTypes: []; + var expectsArgTypesChecked = isArray(expectsArgTypes) ? expectsArgTypes : []; var typesToFuzzOnEach = this._generateTypesToFuzzWith(expectsArgTypesChecked); - var withContextChecked = (withContext !== undefined) ? withContext: null; + var withContextChecked = (withContext !== undefined) ? withContext : null; var returnValue = undefined; From bf4e6b0f3fde8936fcfb138be6aabdcfefdf65eb Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Fri, 10 Mar 2017 07:22:04 -0800 Subject: [PATCH 16/29] remove comment from jshintrc --- packages/error-reporting/.jshintrc | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/error-reporting/.jshintrc b/packages/error-reporting/.jshintrc index bf58ca099dd..53d73b7e997 100644 --- a/packages/error-reporting/.jshintrc +++ b/packages/error-reporting/.jshintrc @@ -17,7 +17,6 @@ "undef": true, "unused": "vars", "globals": { - /* Mocha-provided globals */ "describe": false, "it": false, "before": false, From e2f0ed982ff8b85f86897f55b421311bf305a014 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Fri, 10 Mar 2017 07:22:41 -0800 Subject: [PATCH 17/29] remove 0.12 node runtime from travis.yml --- packages/error-reporting/.travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/error-reporting/.travis.yml b/packages/error-reporting/.travis.yml index 1aefc8a9b21..e7b113a8011 100644 --- a/packages/error-reporting/.travis.yml +++ b/packages/error-reporting/.travis.yml @@ -1,7 +1,6 @@ sudo: false language: node_js node_js: -- '0.12' - '4' - '6' - '7' From 4785e7ac618bf67f761e0d1fa3698bc7914a801e Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Mon, 13 Mar 2017 11:24:17 -0700 Subject: [PATCH 18/29] fix ternary statement in fuzzer --- packages/error-reporting/utils/fuzzer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/error-reporting/utils/fuzzer.js b/packages/error-reporting/utils/fuzzer.js index ea46dc4f84a..956a688aae3 100644 --- a/packages/error-reporting/utils/fuzzer.js +++ b/packages/error-reporting/utils/fuzzer.js @@ -118,7 +118,7 @@ Fuzzer.prototype.generate.undefined = function() { Fuzzer.prototype.generate.array = function(len, ofOneType, currentDepth, allowedDepth) { var lenChecked = isNumber(len) ? len : random(1, 10); - var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType]: this.types(); + var availableTypes = (isString(ofOneType) && (indexOf(this.types(), ofOneType) > -1)) ? [ofOneType] : this.types(); var currentDepthChecked = isNumber(currentDepth) ? currentDepth : 0; var allowedDepthChecked = isNumber(allowedDepth) ? allowedDepth : 3; var arr = []; From 9ca6f901c5de44e4925519655dbabd6e3669ded9 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Mon, 20 Mar 2017 16:30:44 -0700 Subject: [PATCH 19/29] rename module; README tweaks --- packages/error-reporting/README.md | 93 ++++++--------------------- packages/error-reporting/package.json | 9 ++- 2 files changed, 25 insertions(+), 77 deletions(-) diff --git a/packages/error-reporting/README.md b/packages/error-reporting/README.md index 7e3ba7013f1..41b063bb8a2 100644 --- a/packages/error-reporting/README.md +++ b/packages/error-reporting/README.md @@ -1,10 +1,6 @@ # Node.js module for Stackdriver Error Reporting [![NPM Version][npm-image]][npm-url] -[![Build Status][travis-image]][travis-url] -[![Test Coverage][coveralls-image]][coveralls-url] -[![Dependency Status][david-image]][david-url] -[![devDependency Status][david-dev-image]][david-dev-url] [![Known Vulnerabilities][snyk-image]][snyk-url] > **This is not an official Google product.** This module is experimental and may not be ready for use. @@ -19,10 +15,10 @@ applications running in almost any environment. Here's an introductory video: ## Prerequisites -1. Your application needs to use Node.js version 0.12 or greater. +1. Your application needs to use Node.js version 4.x or greater. 1. You need a [Google Cloud project](https://console.cloud.google.com). Your application can run anywhere, but errors are reported to a particular project. 1. [Enable the Stackdriver Error Reporting API](https://console.cloud.google.com/apis/api/clouderrorreporting.googleapis.com/overview) for your project. -1. The module will only send errors when the `NODE_ENV` environment variable is +1. The module will only send errors when the `NODE_ENV` environment variable is set to `production` or the `ignoreEnvironmentCheck` property given in the runtime configuration object is set to `true`. @@ -34,14 +30,14 @@ runtime configuration object is set to `true`. ```shell # Install through npm while saving to the local 'package.json' - npm install --save @google/cloud-errors + npm install --save @google-cloud/error-reporting ``` 1. **Instrument your application:** ```JS // Require the library and initialize the error handler - var errors = require('@google/cloud-errors')({ - serviceContext: {service: 'my-service'} // not needed on Google App Engine + var errors = require('@google-cloud/error-reporting')({ + serviceContext: {service: 'my-service'} // not needed on Google Cloud }); // Report an error to the Stackdriver Error Reporting API @@ -54,7 +50,7 @@ runtime configuration object is set to `true`. ## Running on Google Cloud Platform -### Google App Engine flexible environment +### Google App Engine Flexible environment If you are using [Google App Engine flexible environment](https://cloud.google.com/appengine/docs/flexible/), you do not have to do any additional configuration. @@ -86,7 +82,7 @@ If your application is running outside of Google Cloud Platform, such as locally ```JS // Require and start the agent with configuration options - var errors = require('@google/cloud-errors')({ + var errors = require('@google-cloud/error-reporting')({ // The path to your key file: keyFilename: '/path/to/keyfile.json', @@ -95,14 +91,14 @@ If your application is running outside of Google Cloud Platform, such as locally }); ``` -On Google App Engine, these environment variables are already set. +When running on Google Cloud Platform, we handle these for you automatically. ## Configuration The following code snippet lists all available configuration options. All configuration options are optional. ```js -var errors = require('@google/cloud-errors')({ +var errors = require('@google-cloud/error-reporting')({ projectId: 'my-project-id', keyFilename: '/path/to/keyfile.json', credentials: require('./path/to/keyfile.json'), @@ -115,7 +111,7 @@ var errors = require('@google/cloud-errors')({ reportUncaughtExceptions: true, // determines the logging level internal to the library; levels range 0-5 // defaults to 2 (warnings) - logLevel: 2, + logLevel: 2, serviceContext: { service: 'my-service', version: 'my-service-version' @@ -128,7 +124,7 @@ var errors = require('@google/cloud-errors')({ ### Reporting Manually ```JS -var errors = require('@google/cloud-errors').start(); +var errors = require('@google-cloud/error-reporting')(); // Use the error message builder to custom set all message fields var errorEvt = errors.event() .setMessage('My error message') @@ -146,7 +142,7 @@ errors.report('My error message'); var express = require('express'); var app = express(); // Will create a errors instance based off env variables -var errors = require('@google/cloud-errors')(); +var errors = require('@google-cloud/error-reporting')(); app.get('/error', function(req, res, next) { res.send('Something broke!'); @@ -166,7 +162,7 @@ app.listen(3000); ```JS var hapi = require('hapi'); -var errors = require('@google/cloud-errors')(); +var errors = require('@google-cloud/error-reporting')(); var server = new hapi.Server(); server.connection({ port: 3000 }); @@ -186,10 +182,8 @@ server.register({ register: errors.hapi }); ### Using Koa -**Note**: Koa is not supported in Node.js v0.12 unless the `--harmony` flag is enabled. - ```JS -var errors = require('@google/cloud-errors')(); +var errors = require('@google-cloud/error-reporting')(); var koa = require('koa'); var app = koa(); @@ -216,7 +210,7 @@ function respond(req, res, next) { } var restify = require('restify'); -var errors = require('@google/cloud-errors')(); +var errors = require('@google-cloud/error-reporting')(); var server = restify.createServer(); @@ -227,59 +221,10 @@ server.head('/hello/:name', respond); server.listen(8080); ``` -## Contributing changes - -Install the dependencies: - -```bash -npm install -``` - -Add your unit tests to: - -``` -tests/unit/ -``` - -Run the test suite: - -```bash -npm test -``` - -Run the coverage suite (will also run the test suite): - -```bash -npm run-script coverage -``` - -Run the style checking suite: - -```bash -npm run-script style -``` - -Pre-commit, run the Pre-commit hook to run Clang Formatter *(Must have Clang - Formatter installed prior to use)* - -```bash -git commit -``` - -*Then commit your changes and make a pull-request* - [gcloud-sdk]: https://cloud.google.com/sdk/gcloud/ [app-default-credentials]: https://developers.google.com/identity/protocols/application-default-credentials [service-account]: https://console.developers.google.com/apis/credentials/serviceaccountkey -[npm-image]: https://badge.fury.io/js/%40google%2Fcloud-errors.svg -[npm-url]: https://npmjs.org/package/@google/cloud-errors -[travis-image]: https://travis-ci.org/GoogleCloudPlatform/cloud-errors-nodejs.svg?branch=master -[travis-url]: https://travis-ci.org/GoogleCloudPlatform/cloud-errors-nodejs -[coveralls-image]: https://coveralls.io/repos/GoogleCloudPlatform/cloud-errors-nodejs/badge.svg?branch=master&service=github -[coveralls-url]: https://coveralls.io/github/GoogleCloudPlatform/cloud-errors-nodejs?branch=master -[david-image]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs.svg -[david-url]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs -[david-dev-image]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs/dev-status.svg -[david-dev-url]: https://david-dm.org/GoogleCloudPlatform/cloud-errors-nodejs?type=dev -[snyk-image]: https://snyk.io/test/github/GoogleCloudPlatform/cloud-errors-nodejs/badge.svg -[snyk-url]: https://snyk.io/test/github/GoogleCloudPlatform/cloud-errors-nodejs +[npm-image]: https://badge.fury.io/js/%40google-cloud%2Ferror-reporting.svg +[npm-url]: https://npmjs.org/package/@google-cloud/error-reporting +[snyk-image]: https://snyk.io/test/npm/@google-cloud/error-reporting/badge.svg +[snyk-url]: https://snyk.io/test/npm/@google-cloud/error-reporting diff --git a/packages/error-reporting/package.json b/packages/error-reporting/package.json index 66da046ee42..334cdd1ba3a 100644 --- a/packages/error-reporting/package.json +++ b/packages/error-reporting/package.json @@ -1,9 +1,9 @@ { - "name": "@google/cloud-errors", + "name": "@google-cloud/error-reporting", "version": "0.1.0", - "description": "Node.js module for Google Stackdriver Error Reporting", + "description": "Stackdriver Error Reporting Client Library for Node.js", "main": "index.js", - "repository": "GoogleCloudPlatform/cloud-errors-nodejs", + "repository": "GoogleCloudPlatform/google-cloud-node", "scripts": { "test": "$(npm bin)/nyc --exclude=\"fuzzer.js\" $(npm bin)/mocha ./test/unit/*.js", "integration-tests": "$(npm bin)/nyc --exclude=\"error-message.js\" $(npm bin)/mocha ./test/system-test/*.js", @@ -48,5 +48,8 @@ "exclude": [ "./utils/fuzzer.js" ] + }, + "engines": { + "node": ">=4.0" } } From 217c3a5c7c3c9263cdf1708b1fe00c47f82a9bce Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Fri, 24 Mar 2017 09:37:54 -0700 Subject: [PATCH 20/29] start addressing pr feedback (round 2) --- packages/error-reporting/.npmignore | 5 -- packages/error-reporting/.travis.yml | 8 -- packages/error-reporting/package.json | 23 +++--- packages/error-reporting/src/configuration.js | 36 +-------- .../src/google-apis/auth-client.js | 3 +- packages/error-reporting/src/logger.js | 11 +-- .../test/unit/testConfiguration.js | 81 +++---------------- .../error-reporting/test/unit/testLogger.js | 11 +-- 8 files changed, 38 insertions(+), 140 deletions(-) delete mode 100644 packages/error-reporting/.npmignore delete mode 100644 packages/error-reporting/.travis.yml diff --git a/packages/error-reporting/.npmignore b/packages/error-reporting/.npmignore deleted file mode 100644 index 8c2961713d8..00000000000 --- a/packages/error-reporting/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -/bin -/coverage -/doc -/test -*.enc diff --git a/packages/error-reporting/.travis.yml b/packages/error-reporting/.travis.yml deleted file mode 100644 index e7b113a8011..00000000000 --- a/packages/error-reporting/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -sudo: false -language: node_js -node_js: -- '4' -- '6' -- '7' -script: -- npm run-script test diff --git a/packages/error-reporting/package.json b/packages/error-reporting/package.json index 334cdd1ba3a..f10025e64c5 100644 --- a/packages/error-reporting/package.json +++ b/packages/error-reporting/package.json @@ -5,20 +5,19 @@ "main": "index.js", "repository": "GoogleCloudPlatform/google-cloud-node", "scripts": { - "test": "$(npm bin)/nyc --exclude=\"fuzzer.js\" $(npm bin)/mocha ./test/unit/*.js", - "integration-tests": "$(npm bin)/nyc --exclude=\"error-message.js\" $(npm bin)/mocha ./test/system-test/*.js", - "style": "$(npm bin)/jshint lib index.js", + "test": "nyc --exclude=\"fuzzer.js\" $(npm bin)/mocha ./test/unit/*.js", + "system-test": "nyc --exclude=\"error-message.js\" $(npm bin)/mocha ./test/system-test/*.js", + "lint": "jshint src/ index.js", "coverage": "./bin/test.sh -l", - "coveralls": "./bin/test.sh", - "docs": "$(npm bin)/jsdoc -d docs index.js src/" + "docs": "jsdoc -d docs index.js src/", + "publish-module": "node ../../scripts/publish.js error-reporting" }, "author": "Google Inc.", "license": "Apache 2.0", "devDependencies": { "body-parser": "^1.15.1", - "coveralls": "^2.11.11", "express": "^4.13.4", - "hapi": "^13.4.1", + "hapi": "^16.1.0", "istanbul": "^0.4.3", "jsdoc": "git+https://github.com/jsdoc3/jsdoc.git", "jshint": "^2.9.2", @@ -35,8 +34,7 @@ "mocha": "^3.2.0", "nock": "^9.0.0", "nyc": "^10.0.0", - "restify": "^4.1.0", - "tape": "^4.5.1" + "restify": "^4.1.0" }, "dependencies": { "@google-cloud/common": "^0.12.0", @@ -51,5 +49,10 @@ }, "engines": { "node": ">=4.0" - } + }, + "files": [ + "src", + "utils", + "index.js" + ] } diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index 0424ce91b8c..5e5d077bf24 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -16,8 +16,6 @@ 'use strict'; var env = process.env; -var commonDiag = require('@google/cloud-diagnostics-common'); -var utils = commonDiag.utils; var has = require('lodash.has'); var is = require('is'); var isObject = is.object; @@ -348,29 +346,15 @@ Configuration.prototype._checkAuthConfiguration = function() { Configuration.prototype._checkLocalProjectId = function(cb) { if (isString(this._projectId)) { // already has been set by the metadata service - cb(null, this._projectId); + return this._projectId; } else if (has(this._givenConfiguration, 'projectId')) { if (isString(this._givenConfiguration.projectId)) { this._projectId = this._givenConfiguration.projectId; - cb(null, this._projectId); } else if (isNumber(this._givenConfiguration.projectId)) { this._projectId = this._givenConfiguration.projectId.toString(); - cb(null, this._projectId); - } else { - cb(new Error('config.projectId must be a string or number'), null); } - } else if (isString(env.GCLOUD_PROJECT) && !isEmpty(env.GCLOUD_PROJECT)) { - // GCLOUD_PROJECT is set, set on instance - this._projectId = env.GCLOUD_PROJECT; - cb(null, this._projectId); - } else { - cb(new Error([ - 'Unable to find the project Id for communication with the Stackdriver', - 'Error Reporting service. This app will be unable to send errors to the', - 'reporting service unless a valid project Id is supplied via runtime', - 'configuration or the GCLOUD_PROJECT environmental variable.' - ].join(' ')), null); } + return this._projectId; }; /** * Returns the _reportUncaughtExceptions property on the instance. @@ -400,21 +384,7 @@ Configuration.prototype.getShouldReportErrorsToAPI = function() { * @returns {String|Null} - returns the _projectId property */ Configuration.prototype.getProjectId = function(cb) { - var self = this; - if (!isNull(this._projectId)) { - setImmediate(function() { - cb(null, self._projectId); - }); - } else { - utils.getProjectId(function(err, projectId) { - if (err) { - self._checkLocalProjectId(cb); - } else { - self._projectId = projectId; - cb(null, self._projectId); - } - }); - } + return this._checkLocalProjectId(); }; /** * Returns the _key property on the instance. diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 82b9ca32191..00d4644435c 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -92,7 +92,8 @@ class RequestHandler extends common.Service { packageJson: pkg, projectIdRequired: false, baseUrl: 'https://clouderrorreporting.googleapis.com/v1beta1/', - scopes: SCOPES + scopes: SCOPES, + projectId: config.getProjectId() }, config); this._config = config; this._logger = logger; diff --git a/packages/error-reporting/src/logger.js b/packages/error-reporting/src/logger.js index 0f8b7607b60..dca61b987a7 100644 --- a/packages/error-reporting/src/logger.js +++ b/packages/error-reporting/src/logger.js @@ -21,7 +21,7 @@ var is = require('is'); var isObject = is.object; var isString = is.string; var isNumber = is.number; -var logger = require('@google/cloud-diagnostics-common').logger; +var logger = require('@google-cloud/common').logger; /** * Creates an instance of the Google Cloud Diagnostics logger class. This * instance will be configured to log at the level given by the environment or @@ -44,20 +44,21 @@ function createLogger(initConfiguration) { var level = logger.WARN; if (has(process.env, 'GCLOUD_ERRORS_LOGLEVEL')) { // Cast env string as integer - level = ~~process.env.GCLOUD_ERRORS_LOGLEVEL; + level = logger.LEVELS[~~process.env.GCLOUD_ERRORS_LOGLEVEL] || + logger.LEVELS.warn; } else if (isObject(initConfiguration) && has(initConfiguration, 'logLevel')) { if (isString(initConfiguration.logLevel)) { // Cast string as integer - level = ~~initConfiguration.logLevel; + level = logger.LEVELS[~~initConfiguration.logLevel] || logger.LEVELS.warn; } else if (isNumber(initConfiguration.logLevel)) { - level = initConfiguration.logLevel; + level = logger.LEVELS[initConfiguration.logLevel] || logger.LEVELS.warn; } else { throw new Error('config.logLevel must be a number or decimal ' + 'representation of a number in string form'); } } - return logger.create(level, '@google/cloud-errors'); + return logger({level: level, tag: '@google/cloud-errors'}); } module.exports = createLogger; diff --git a/packages/error-reporting/test/unit/testConfiguration.js b/packages/error-reporting/test/unit/testConfiguration.js index 86961d87bdc..13529cfca04 100644 --- a/packages/error-reporting/test/unit/testConfiguration.js +++ b/packages/error-reporting/test/unit/testConfiguration.js @@ -112,22 +112,6 @@ describe('Configuration class', function() { }); }); describe('without ignoreEnvironmentCheck', function() { - describe('Exception behvaiour without proper resources', function() { - var c; - before(function() { - sterilizeEnv(); - c = new Configuration(stubConfig, logger); - }); - after(function() {sterilizeEnv();}); - it('Should error without proper config resource', function(done) { - this.timeout(3500); - c.getProjectId(function(err, id) { - assert(err instanceof Error); - assert.strictEqual(id, null); - done(); - }); - }); - }); describe('report behaviour with production env', function() { var c; before(function() { @@ -181,18 +165,13 @@ describe('Configuration class', function() { before(function() {sterilizeEnv();}); describe('project id from configuration instance', function() { var pi = 'test'; - var serve, c; + var c; before(function() { - serve = createDeadMetadataService(); c = new Configuration({projectId: pi}, logger); }); after(function() {nock.cleanAll();}); - it('Should return the project id', function(done) { - c.getProjectId(function(err, id) { - assert.strictEqual(err, null); - assert.strictEqual(id, pi); - done(); - }); + it('Should return the project id', function() { + assert.strictEqual(c.getProjectId(), pi); }); }); describe('project number from configuration instance', function() { @@ -200,16 +179,11 @@ describe('Configuration class', function() { var serve, c; before(function() { sterilizeEnv(); - serve = createDeadMetadataService(); c = new Configuration({projectId: pn}, logger); }); after(function() {nock.cleanAll(); sterilizeEnv();}); - it('Should return the project number', function(done) { - c.getProjectId(function(err, id) { - assert.strictEqual(err, null); - assert.strictEqual(pn.toString(), id); - done(); - }); + it('Should return the project number', function() { + assert.strictEqual(c.getProjectId(), pn.toString()); }); }); }); @@ -225,12 +199,8 @@ describe('Configuration class', function() { nock.cleanAll(); sterilizeEnv(); }); - it('Should error', function(done) { - c.getProjectId(function(err, id) { - assert(err instanceof Error); - assert.strictEqual(id, null); - done(); - }); + it('Should return null', function() { + assert.strictEqual(c.getProjectId(), null); }); }); describe('Invalid type for projectId in runtime config', function() { @@ -244,12 +214,8 @@ describe('Configuration class', function() { nock.cleanAll(); sterilizeEnv(); }); - it('Should error', function(done) { - c.getProjectId(function(err, id) { - assert(err instanceof Error); - assert.strictEqual(id, null); - done(); - }); + it('Should return null', function() { + assert.strictEqual(c.getProjectId(), null); }); }); }); @@ -266,19 +232,15 @@ describe('Configuration class', function() { describe('via env', function() { before(function() {sterilizeEnv();}); afterEach(function() {sterilizeEnv();}); - describe('projectId', function() { + describe('no longer tests env itself', function() { var c; var projectId = 'test-xyz'; before(function() { process.env.GCLOUD_PROJECT = projectId; c = new Configuration(undefined, logger); }); - it('Should assign', function(done) { - c.getProjectId(function(err, id) { - assert.strictEqual(err, null); - assert.strictEqual(id, projectId); - done(); - }); + it('Should assign', function() { + assert.strictEqual(c.getProjectId(), null); }); }); describe('serviceContext', function() { @@ -348,24 +310,5 @@ describe('Configuration class', function() { }); }); }); - describe('via the metadata service', function() { - before(function() {sterilizeEnv();}); - describe('project id', function() { - var serve, c; - var id = '6789'; - before(function() { - serve = nock(METADATA_URL).get('/project-id').times(1).reply(200, id); - c = new Configuration(undefined, logger); - }); - it('Should assign', function(done) { - c.getProjectId(function(err, projectId) { - assert.strictEqual(err, null); - assert.strictEqual(id, projectId); - assert(serve.isDone()); - done(); - }); - }); - }); - }); }); }); diff --git a/packages/error-reporting/test/unit/testLogger.js b/packages/error-reporting/test/unit/testLogger.js index a1f24b9a3fa..cd7aa29e57f 100644 --- a/packages/error-reporting/test/unit/testLogger.js +++ b/packages/error-reporting/test/unit/testLogger.js @@ -52,16 +52,9 @@ describe('logger', function() { }); }); describe('Default log level', function() { - it('Should be WARN', function() { - var buf = []; - var orig = console._stdout.write; - console._stdout.write = function() { - buf.push(arguments[0]); - orig.apply(this, arguments); - }; - var logger = createLogger({}); + it('Should be able to WARN by default', function() { + var logger = createLogger(); logger.warn('test warning message'); - assert(buf.pop().match(/test warning message/)); }); }); }); From b27025f21d87086f51f7f36a4da304c2ad7096dc Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Thu, 30 Mar 2017 08:22:27 -0700 Subject: [PATCH 21/29] address pr feedback --- packages/error-reporting/CHANGELOG.md | 29 ---- packages/error-reporting/CONTRIBUTING.md | 20 --- packages/error-reporting/LICENSE | 202 ----------------------- packages/error-reporting/bin/test.sh | 80 --------- packages/error-reporting/package.json | 2 - 5 files changed, 333 deletions(-) delete mode 100644 packages/error-reporting/CHANGELOG.md delete mode 100644 packages/error-reporting/CONTRIBUTING.md delete mode 100644 packages/error-reporting/LICENSE delete mode 100755 packages/error-reporting/bin/test.sh diff --git a/packages/error-reporting/CHANGELOG.md b/packages/error-reporting/CHANGELOG.md deleted file mode 100644 index c1d3b6c082d..00000000000 --- a/packages/error-reporting/CHANGELOG.md +++ /dev/null @@ -1,29 +0,0 @@ -# Node.js Agent for Google Cloud Errors ChangeLog - -## 2016-10-03, Version 0.1.0 (Experimental), @matthewloring - -### Notable changes - -**configuration**: - - * [[`4d25c759cd`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/4d25c759cd)] - Update uncaught handler to terminate on timeout #35 (#50) (Cristian Cavalli) - * [[`82b78614f5`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/82b78614f5)] - Remove anonymous function invocation on import and create start method (#44) (Cristian Cavalli) - -### Commits - -* [[`16e15a08bc`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/16e15a08bc)] - Update diagnostics common (#60) (Matthew Loring) [#60](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/pull/60) -* [[`bc03aebd78`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/bc03aebd78)] - Add tests for restify interface (#58) (Cristian Cavalli) -* [[`22fa09a2e0`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/22fa09a2e0)] - Update testUncaught.js with env detection (#57) (Cristian Cavalli) -* [[`be4b47b385`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/be4b47b385)] - Add log-level option to runtime configuration #51 (#54) (Cristian Cavalli) -* [[`6b113f3db7`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/6b113f3db7)] - Update defaults for service context on Error Message #52 (#53) (Cristian Cavalli) -* [[`4d25c759cd`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/4d25c759cd)] - Update uncaught handler to terminate on timeout #35 (#50) (Cristian Cavalli) -* [[`e3c527a03c`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/e3c527a03c)] - Add the Common Diagnostics Logger to Errors (#43) (Cristian Cavalli) -* [[`53b7b5225c`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/53b7b5225c)] - Remove keyfile option from configuration (#49) (Cristian Cavalli) -* [[`82b78614f5`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/82b78614f5)] - Remove anonymous function invocation on import and create start method (#44) (Cristian Cavalli) -* [[`31b24f7580`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/31b24f7580)] - New configuration flow (#36) (Cristian Cavalli) -* [[`04b1c8367a`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/04b1c8367a)] - add tests and fix arguments for manual report (#47) (Ali Ijaz Sheikh) -* [[`4a3896d05a`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/4a3896d05a)] - Avoid using bind in various handlers (#46) (Ali Ijaz Sheikh) -* [[`be6576f90d`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/be6576f90d)] - Minor README and package.json fixes (#45) (Ali Ijaz Sheikh) -* [[`6ae1f38821`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/6ae1f38821)] - Update example text (#42) (Cristian Cavalli) -* [[`cba91ddea9`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/cba91ddea9)] - Fix test quickstart instructions in README (Steren) -* [[`404c72bbf4`](https://github.com/GoogleCloudPlatform/cloud-errors-nodejs/commit/404c72bbf4)] - README update reportUncaughtExceptions (Steren) diff --git a/packages/error-reporting/CONTRIBUTING.md b/packages/error-reporting/CONTRIBUTING.md deleted file mode 100644 index 718ada1164b..00000000000 --- a/packages/error-reporting/CONTRIBUTING.md +++ /dev/null @@ -1,20 +0,0 @@ -# How to become a contributor and submit your own code - -## Contributor License Agreements - -We'd love to accept your patches! Before we can take them, we have to jump a couple of legal hurdles. - -Please fill out either the individual or corporate Contributor License Agreement (CLA). - - * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html). - * If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html). - -Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests. - -## Contributing A Patch - -1. Submit an issue describing your proposed change to the repo in question. -1. The repo owner will respond to your issue promptly. -1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). -1. Fork the desired repo, develop and test your code changes. -1. Submit a pull request. \ No newline at end of file diff --git a/packages/error-reporting/LICENSE b/packages/error-reporting/LICENSE deleted file mode 100644 index 25dd99930e2..00000000000 --- a/packages/error-reporting/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016 Google Inc. - - 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 - - http://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. diff --git a/packages/error-reporting/bin/test.sh b/packages/error-reporting/bin/test.sh deleted file mode 100755 index 58c11ad4a02..00000000000 --- a/packages/error-reporting/bin/test.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash - -IS_TESTING_LOCALLY=false - -function basicSetup { - export NODE_ENV=production - if [ -d ./test/configuration ]; then - # Remove the old configuration - rm -rf ./test/configuration - fi - mkdir ./test/configuration -} - -function basicTeardown { - unset NODE_ENV - rm -rf ./test/configuration -} - -function trustedSetup { - export GCLOUD_PROJECT=`cat ./test/configuration/stub_project_id.txt` - export STUBBED_API_KEY=`cat ./test/configuration/stub_api_key.txt` - export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/test/configuration/stub_default_credentials.json -} - -function trustedTeardown { - unset GCLOUD_PROJECT - unset STUBBED_API_KEY - unset GOOGLE_APPLICATION_CREDENTIALS -} - -function decryptAcceptanceCredentials { - openssl aes-256-cbc -K $encrypted_7e22a7c28f69_key \ - -iv $encrypted_7e22a7c28f69_iv -in config.tar.enc \ - -out ./test/configuration/config.tar -d \ - && tar xvf ./test/configuration/config.tar -} - -function runFullSuite { - $(npm bin)/nyc report --reporter=text-lcov \ - $(npm bin)/mocha ./test/system-test/*.js ./test/unit/*.js \ - ./test/fixtures/*.js | \ - $(npm bin)/coveralls coveralls && rm -rf ./coverage -} - -function runUnitSuite { - $(npm bin)/nyc report --reporter=text-lcov \ - $(npm bin)/mocha ./test/unit/*.js | \ - $(npm bin)/coveralls && rm -rf ./coverage -} - -function run { - basicSetup - if [ "$IS_TESTING_LOCALLY" = "true" ] - then - echo "Running integration and unit suites in local development mode" - runFullSuite - elif [ "$TRAVIS_TRUSTED_INTERNAL_MERGE" = "true" ] - then - echo "Running integration and unit suites in container mode" - decryptAcceptanceCredentials - trustedSetup - runFullSuite - trustedTeardown - else - echo "Running unit suite" - runUnitSuite - fi - basicTeardown -} - -while getopts "l" opt -do - case $opt in - l) - IS_TESTING_LOCALLY=true - ;; - esac -done - -run \ No newline at end of file diff --git a/packages/error-reporting/package.json b/packages/error-reporting/package.json index f10025e64c5..90f36fd68f7 100644 --- a/packages/error-reporting/package.json +++ b/packages/error-reporting/package.json @@ -1,6 +1,5 @@ { "name": "@google-cloud/error-reporting", - "version": "0.1.0", "description": "Stackdriver Error Reporting Client Library for Node.js", "main": "index.js", "repository": "GoogleCloudPlatform/google-cloud-node", @@ -8,7 +7,6 @@ "test": "nyc --exclude=\"fuzzer.js\" $(npm bin)/mocha ./test/unit/*.js", "system-test": "nyc --exclude=\"error-message.js\" $(npm bin)/mocha ./test/system-test/*.js", "lint": "jshint src/ index.js", - "coverage": "./bin/test.sh -l", "docs": "jsdoc -d docs index.js src/", "publish-module": "node ../../scripts/publish.js error-reporting" }, From 245563fed374a48c6e20e6bac6450b9d43035703 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Thu, 30 Mar 2017 10:47:39 -0700 Subject: [PATCH 22/29] pr feedback, fix issue with system tests --- packages/error-reporting/README.md | 42 +++++------ packages/error-reporting/package.json | 9 +-- .../src/google-apis/auth-client.js | 54 +++++--------- .../{test => }/system-test/testAuthClient.js | 74 +++++++++---------- 4 files changed, 79 insertions(+), 100 deletions(-) rename packages/error-reporting/{test => }/system-test/testAuthClient.js (88%) diff --git a/packages/error-reporting/README.md b/packages/error-reporting/README.md index 41b063bb8a2..2a71a0dfdb8 100644 --- a/packages/error-reporting/README.md +++ b/packages/error-reporting/README.md @@ -6,7 +6,7 @@ > **This is not an official Google product.** This module is experimental and may not be ready for use. > This module uses APIs that may be undocumented and are subject to change without notice. -This modules provides Stackdriver Error Reporting support for Node.js applications. +This module provides Stackdriver Error Reporting support for Node.js applications. [Stackdriver Error Reporting](https://cloud.google.com/error-reporting/) is a feature of Google Cloud Platform that allows in-depth monitoring and viewing of errors reported by applications running in almost any environment. Here's an introductory video: @@ -64,7 +64,7 @@ If you already have VMs that were created without API access and do not wish to Container Engine nodes need to also be created with the `https://www.googleapis.com/auth/cloud-platform` scope, which is configurable during cluster creation. Alternatively, you can follow the instructions for using a service account under [running elsewhere](#running-elsewhere). It's recommended that you store the service account credentials as [Kubernetes Secret](http://kubernetes.io/v1.1/docs/user-guide/secrets.html). -## Running elsewhere +## Running Elsewhere If your application is running outside of Google Cloud Platform, such as locally, on-premise, or on another cloud provider, you can still use Stackdriver Errors. @@ -80,16 +80,16 @@ If your application is running outside of Google Cloud Platform, such as locally * If you are running your application on a development machine or test environment where you are using the [`gcloud` command line tools][gcloud-sdk], and are logged using `gcloud beta auth application-default login`, you already have sufficient credentials, and a service account key is not required. * Alternatively, you may set the `keyFilename` or `credentials` configuration field to the full path or contents to the key file, respectively. Setting either of these fields will override either setting `GOOGLE_APPLICATION_CREDENTIALS` or logging in using `gcloud`. For example: - ```JS - // Require and start the agent with configuration options - var errors = require('@google-cloud/error-reporting')({ - // The path to your key file: - keyFilename: '/path/to/keyfile.json', +```js + // Require and start the agent with configuration options + var errors = require('@google-cloud/error-reporting')({ + // The path to your key file: + keyFilename: '/path/to/keyfile.json', - // Or the contents of the key file: - credentials: require('./path/to/keyfile.json') - }); - ``` + // Or the contents of the key file: + credentials: require('./path/to/keyfile.json') + }); +``` When running on Google Cloud Platform, we handle these for you automatically. @@ -123,7 +123,7 @@ var errors = require('@google-cloud/error-reporting')({ ### Reporting Manually -```JS +```js var errors = require('@google-cloud/error-reporting')(); // Use the error message builder to custom set all message fields var errorEvt = errors.event() @@ -138,18 +138,18 @@ errors.report('My error message'); ### Using Express -```JS +```js var express = require('express'); var app = express(); -// Will create a errors instance based off env variables +// Will create an errors instance based off env variables var errors = require('@google-cloud/error-reporting')(); -app.get('/error', function(req, res, next) { +app.get('/error', (req, res, next) => { res.send('Something broke!'); next(new Error('Custom error message')); }); -app.get('/exception', function() { +app.get('/exception', () => { JSON.parse('{\"malformedJson\": true'); }); @@ -160,7 +160,7 @@ app.listen(3000); ### Using Hapi -```JS +```js var hapi = require('hapi'); var errors = require('@google-cloud/error-reporting')(); @@ -171,9 +171,9 @@ server.start(); server.route({ method: 'GET', path: '/error', - handler: function(request, reply) { - throw new Error('Custom error message'); + handler: (request, reply) => { reply('Something broke!'); + throw new Error('Custom error message'); } }); @@ -182,7 +182,7 @@ server.register({ register: errors.hapi }); ### Using Koa -```JS +```js var errors = require('@google-cloud/error-reporting')(); var koa = require('koa'); var app = koa(); @@ -204,7 +204,7 @@ app.listen(3000); ### Using Restify -```JS +```js function respond(req, res, next) { next(new Error('this is a restify error')); } diff --git a/packages/error-reporting/package.json b/packages/error-reporting/package.json index 90f36fd68f7..a136385d484 100644 --- a/packages/error-reporting/package.json +++ b/packages/error-reporting/package.json @@ -4,20 +4,17 @@ "main": "index.js", "repository": "GoogleCloudPlatform/google-cloud-node", "scripts": { - "test": "nyc --exclude=\"fuzzer.js\" $(npm bin)/mocha ./test/unit/*.js", - "system-test": "nyc --exclude=\"error-message.js\" $(npm bin)/mocha ./test/system-test/*.js", + "test": "nyc --exclude=\"fuzzer.js\" mocha ./test/unit/*.js", + "system-test": "nyc --exclude=\"error-message.js\" mocha ./system-test/*.js", "lint": "jshint src/ index.js", - "docs": "jsdoc -d docs index.js src/", "publish-module": "node ../../scripts/publish.js error-reporting" }, "author": "Google Inc.", - "license": "Apache 2.0", + "license": "Apache-2.0", "devDependencies": { "body-parser": "^1.15.1", "express": "^4.13.4", "hapi": "^16.1.0", - "istanbul": "^0.4.3", - "jsdoc": "git+https://github.com/jsdoc3/jsdoc.git", "jshint": "^2.9.2", "koa": "^1.2.0", "lodash.assign": "^4.2.0", diff --git a/packages/error-reporting/src/google-apis/auth-client.js b/packages/error-reporting/src/google-apis/auth-client.js index 00d4644435c..d5c31fa0b9c 100644 --- a/packages/error-reporting/src/google-apis/auth-client.js +++ b/packages/error-reporting/src/google-apis/auth-client.js @@ -56,20 +56,19 @@ var API = 'https://clouderrorreporting.googleapis.com/v1beta1/projects'; */ class RequestHandler extends common.Service { /** - * Compute the URL that errors should be reported to given the projectId and - * optional key. - * @param {String} projectId - the project id of the application. + * Returns a query-string request object if a string key is given, otherwise + * will return null. * @param {String|Null} [key] - the API key used to authenticate against the * service in place of application default credentials. - * @returns {String} computed URL that the errors should be reported to. + * @returns {Object|Null} api key query string object for use with request or + * null in case no api key is given * @static */ - static getErrorReportURL(projectId, key) { - var url = [API, projectId, 'events:report'].join('/'); + static manufactureQueryString(key) { if (isString(key)) { - url += '?key=' + key; + return {key: key}; } - return url; + return null; } /** * No-operation stub function for user callback substitution @@ -88,12 +87,13 @@ class RequestHandler extends common.Service { * @param {Logger} logger - an instance of logger */ constructor(config, logger) { + var pid = config.getProjectId(); super({ packageJson: pkg, - projectIdRequired: false, baseUrl: 'https://clouderrorreporting.googleapis.com/v1beta1/', scopes: SCOPES, - projectId: config.getProjectId() + projectId: pid !== null ? pid : undefined, + projectIdRequired: true }, config); this._config = config; this._logger = logger; @@ -114,33 +114,19 @@ class RequestHandler extends common.Service { var self = this; var cb = isFunction(userCb) ? userCb : RequestHandler.noOp; if (this._config.getShouldReportErrorsToAPI()) { - this._config.getProjectId((err, id) => { + this.request({ + uri: 'events:report', + qs: RequestHandler.manufactureQueryString(this._config.getKey()), + method: 'POST', + json: errorMessage + }, (err, body, response) => { if (err) { - setImmediate(function() { cb(err, null, null); }); this._logger.error([ - 'Unable to retrieve a project id from the Google Metadata Service', - 'or the local environment. Client will not be able to communicate', - 'with the Stackdriver Error Reporting API without a valid project', - 'id. Please make sure to supply a project id either through the', - 'GCLOUD_PROJECT environmental variable or through the', - 'configuration object given to this library on startup if not', - 'running on Google Cloud Platform.' - ].join(' ')); - return; + 'Encountered an error while attempting to transmit an error to', + 'the Stackdriver Error Reporting API.' + ].join(' '), err); } - this.request({ - uri: RequestHandler.getErrorReportURL(id, this._config.getKey()), - method: 'POST', - json: errorMessage - }, (err, body, response) => { - if (err) { - this._logger.error([ - 'Encountered an error while attempting to transmit an error to', - 'the Stackdriver Error Reporting API.' - ].join(' '), err); - } - cb(err, response, body); - }); + cb(err, response, body); }); } else { cb(new Error([ diff --git a/packages/error-reporting/test/system-test/testAuthClient.js b/packages/error-reporting/system-test/testAuthClient.js similarity index 88% rename from packages/error-reporting/test/system-test/testAuthClient.js rename to packages/error-reporting/system-test/testAuthClient.js index fe9bf3571ca..c0b02ab1ba4 100644 --- a/packages/error-reporting/test/system-test/testAuthClient.js +++ b/packages/error-reporting/system-test/testAuthClient.js @@ -17,10 +17,10 @@ 'use strict'; var assert = require('assert'); var nock = require('nock'); -var RequestHandler = require('../../src/google-apis/auth-client.js'); -var ErrorMessage = require('../../src/classes/error-message.js'); -var Configuration = require('../fixtures/configuration.js'); -var createLogger = require('../../src/logger.js'); +var RequestHandler = require('../src/google-apis/auth-client.js'); +var ErrorMessage = require('../src/classes/error-message.js'); +var Configuration = require('../test/fixtures/configuration.js'); +var createLogger = require('../src/logger.js'); var is = require('is'); var isObject = is.object; var isString = is.string; @@ -34,22 +34,18 @@ describe('Behvaiour acceptance testing', function() { before(function() { // Before starting the suite make sure we have the proper resources if (!isString(process.env.GCLOUD_PROJECT)) { - console.error( + throw new Error( 'The gcloud project id (GCLOUD_PROJECT) was not set in the env'); - this.skip(); } else if (!isString(process.env.STUBBED_API_KEY)) { - console.error( + throw new Error( 'The api key (STUBBED_API_KEY) was not set as an env variable'); - this.skip(); } else if (!isString(process.env.STUBBED_PROJECT_NUM)) { - console.error( + throw new Error( 'The project number (STUBBED_PROJECT_NUM) was not set in the env'); - this.skip(); } else if (process.env.NODE_ENV !== 'production') { - console.error( + throw new Error( 'The NODE_ENV is not set to production as an env variable. Please ' + 'set NODE_ENV to production'); - this.skip(); } // In case we are running after unit mocks which were not destroyed properly nock.cleanAll(); @@ -269,33 +265,33 @@ describe('Behvaiour acceptance testing', function() { }); }); }); - describe('An invalid env configuration', function() { - var ERROR_STRING = [ - 'Unable to find the project Id for communication with the', - 'Stackdriver Error Reporting service. This app will be unable to', - 'send errors to the reporting service unless a valid project Id', - 'is supplied via runtime configuration or the GCLOUD_PROJECT', - 'environmental variable.' - ].join(' '); - var logger, client; - before(function() { - delete process.env.GCLOUD_PROJECT; - logger = createLogger({logLevel: 5}); - client = new RequestHandler(new Configuration( - {ignoreEnvironmentCheck: true}, logger), logger); - }); - after(function() { - process.env.GCLOUD_PROJECT = oldEnv.GCLOUD_PROJECT; - }); - it('Should callback with an error', function(done) { - client.sendError(errorMessage, function(err, response, body) { - assert(err instanceof Error); - assert.strictEqual(err.message, ERROR_STRING); - assert.strictEqual(response, null); - done(); - }); - }); - }); + // describe('An invalid env configuration', function() { + // var ERROR_STRING = [ + // 'Unable to find the project Id for communication with the', + // 'Stackdriver Error Reporting service. This app will be unable to', + // 'send errors to the reporting service unless a valid project Id', + // 'is supplied via runtime configuration or the GCLOUD_PROJECT', + // 'environmental variable.' + // ].join(' '); + // var logger, client; + // before(function() { + // delete process.env.GCLOUD_PROJECT; + // logger = createLogger({logLevel: 5}); + // client = new RequestHandler(new Configuration( + // {ignoreEnvironmentCheck: true}, logger), logger); + // }); + // after(function() { + // process.env.GCLOUD_PROJECT = oldEnv.GCLOUD_PROJECT; + // }); + // it('Should callback with an error', function(done) { + // client.sendError(errorMessage, function(err, response, body) { + // assert(err instanceof Error); + // assert.strictEqual(err.message, ERROR_STRING); + // assert.strictEqual(response, null); + // done(); + // }); + // }); + // }); }); describe('Success behaviour', function() { var er = new Error(ERR_TOKEN); From fbf933d6c295c7b6950fe4005f771c48fe274c38 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Thu, 30 Mar 2017 10:55:43 -0700 Subject: [PATCH 23/29] fix spacing on README --- packages/error-reporting/README.md | 62 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/packages/error-reporting/README.md b/packages/error-reporting/README.md index 2a71a0dfdb8..54f56ab2b7c 100644 --- a/packages/error-reporting/README.md +++ b/packages/error-reporting/README.md @@ -28,21 +28,21 @@ runtime configuration object is set to `true`. In your project, on the command line: - ```shell - # Install through npm while saving to the local 'package.json' - npm install --save @google-cloud/error-reporting + ``` + # Install through npm while saving to the local 'package.json' + npm install --save @google-cloud/error-reporting ``` 1. **Instrument your application:** - ```JS - // Require the library and initialize the error handler - var errors = require('@google-cloud/error-reporting')({ - serviceContext: {service: 'my-service'} // not needed on Google Cloud - }); +```js +// Require the library and initialize the error handler +var errors = require('@google-cloud/error-reporting')({ + serviceContext: {service: 'my-service'} // not needed on Google Cloud +}); - // Report an error to the Stackdriver Error Reporting API - errors.report(new Error('Something broke!')); - ``` +// Report an error to the Stackdriver Error Reporting API +errors.report(new Error('Something broke!')); +``` 1. **View reported errors:** @@ -99,23 +99,23 @@ The following code snippet lists all available configuration options. All config ```js var errors = require('@google-cloud/error-reporting')({ - projectId: 'my-project-id', - keyFilename: '/path/to/keyfile.json', - credentials: require('./path/to/keyfile.json'), - // if true library will attempt to report errors to the service regardless - // of the value of NODE_ENV - // defaults to false - ignoreEnvironmentCheck: false, - // determines if the library will attempt to report uncaught exceptions - // defaults to true - reportUncaughtExceptions: true, - // determines the logging level internal to the library; levels range 0-5 - // defaults to 2 (warnings) - logLevel: 2, - serviceContext: { - service: 'my-service', - version: 'my-service-version' - } + projectId: 'my-project-id', + keyFilename: '/path/to/keyfile.json', + credentials: require('./path/to/keyfile.json'), + // if true library will attempt to report errors to the service regardless + // of the value of NODE_ENV + // defaults to false + ignoreEnvironmentCheck: false, + // determines if the library will attempt to report uncaught exceptions + // defaults to true + reportUncaughtExceptions: true, + // determines the logging level internal to the library; levels range 0-5 + // defaults to 2 (warnings) + logLevel: 2, + serviceContext: { + service: 'my-service', + version: 'my-service-version' + } }); ``` @@ -145,12 +145,12 @@ var app = express(); var errors = require('@google-cloud/error-reporting')(); app.get('/error', (req, res, next) => { - res.send('Something broke!'); - next(new Error('Custom error message')); + res.send('Something broke!'); + next(new Error('Custom error message')); }); app.get('/exception', () => { - JSON.parse('{\"malformedJson\": true'); + JSON.parse('{\"malformedJson\": true'); }); app.use(errors.express); From 58af01191072abe99c32d60c6453e6ecf0650942 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Tue, 4 Apr 2017 11:35:14 -0700 Subject: [PATCH 24/29] address documentation feedback, move index into ./src/ --- packages/error-reporting/package.json | 2 +- packages/error-reporting/src/configuration.js | 2 +- packages/error-reporting/{ => src}/index.js | 57 +++++++++++++++++-- .../test-servers/express_scaffold_server.js | 2 +- .../test/test-servers/hapi_scaffold_server.js | 2 +- .../test/test-servers/koa_scaffold_server.js | 2 +- .../test-servers/manual_scaffold_server.js | 2 +- .../test-servers/restify_scaffold_server.js | 2 +- scripts/docs/config.js | 4 ++ 9 files changed, 64 insertions(+), 11 deletions(-) rename packages/error-reporting/{ => src}/index.js (72%) diff --git a/packages/error-reporting/package.json b/packages/error-reporting/package.json index a136385d484..7bdcd643a36 100644 --- a/packages/error-reporting/package.json +++ b/packages/error-reporting/package.json @@ -1,7 +1,7 @@ { "name": "@google-cloud/error-reporting", "description": "Stackdriver Error Reporting Client Library for Node.js", - "main": "index.js", + "main": "./src/index.js", "repository": "GoogleCloudPlatform/google-cloud-node", "scripts": { "test": "nyc --exclude=\"fuzzer.js\" mocha ./test/unit/*.js", diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index 5e5d077bf24..3a13b1cac0c 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -411,7 +411,7 @@ Configuration.prototype.getKeyFilename = function() { * @memberof Configuration * @public * @function getCredentials - * @returns {Credentials\Null} - returns the _credentials property + * @returns {Credentials|Null} - returns the _credentials property */ Configuration.prototype.getCredentials = function() { return this._credentials; diff --git a/packages/error-reporting/index.js b/packages/error-reporting/src/index.js similarity index 72% rename from packages/error-reporting/index.js rename to packages/error-reporting/src/index.js index bd93e921779..a51127b0f14 100644 --- a/packages/error-reporting/index.js +++ b/packages/error-reporting/src/index.js @@ -1,4 +1,4 @@ -/** +/*! * Copyright 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -69,9 +69,11 @@ var createLogger = require('./src/logger.js'); * this function will also return an interface which can be used manually via * the `report` function property, with hapi via the `hapi` object property or * with express via the `express` function property. - * @function initConfiguration + * @function Errors * @param {ConfigurationOptions} initConfiguration - the desired project/error * reporting configuration + * @constructor + * @alias module:error-reporting */ function Errors(initConfiguration) { if (!(this instanceof Errors)) { @@ -86,11 +88,58 @@ function Errors(initConfiguration) { uncaughtException(client, config); // Build the application interfaces for use by the hosting application - this.hapi = hapi(client, config); + /** + * @example + * // Use to report errors manually like so + * var errors = require('@google-cloud/error-reporting')(); + * errors.report(new Error('xyz'), () => console.log('done!')); + */ this.report = manual(client, config); + /** + * @example + * // Use to create and report errors manually with a high-degree + * // of manual control + * var errors = require('@google-cloud/error-reporting')(); + * var err = errors.event() + * .setMessage('My error message') + * .setUser('root@nexus'); + * errors.report(err, () => console.log('done!')); + */ + this.event = messageBuilder(config); + /** + * @example + * var errors = require('@google-cloud/error-reporting')(); + * var server = new hapi.Server(); + * server.connection({ port: 3000 }); + * server.start(); + * // AFTER ALL OTHER ROUTE HANDLERS + * server.register({register: errors.hapi}); + */ + this.hapi = hapi(client, config); + /** + * @example + * var errors = require('@google-cloud/error-reporting')(); + * var app = express(); + * // AFTER ALL OTHER ROUTE HANDLERS + * app.use(errors.express); + * app.listen(3000); + */ this.express = express(client, config); + /** + * @example + * var errors = require('@google-cloud/error-reporting')(); + * var server = restify.createServer(); + * // BEFORE ALL OTHER ROUTE HANDLERS + * server.use(errors.restify(server)); + */ this.restify = restify(client, config); - this.event = messageBuilder(config); + /** + * @example + * var errors = require('@google-cloud/error-reporting')(); + * var app = koa(); + * // BEFORE ALL OTHER ROUTE HANDLERS HANDLERS + * app.use(errors.koa); + */ this.koa = koa(client, config); } diff --git a/packages/error-reporting/test/test-servers/express_scaffold_server.js b/packages/error-reporting/test/test-servers/express_scaffold_server.js index 86b28b43edd..f9a6efeca79 100644 --- a/packages/error-reporting/test/test-servers/express_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/express_scaffold_server.js @@ -22,7 +22,7 @@ var EXCLAMATION_LN = '\n!!'; var has = require('lodash.has'); var express = require('express'); var app = express(); -var errorHandler = require('../../index.js')({ +var errorHandler = require('../../src/index.js')({ onUncaughtException: 'report', key: process.env.STUBBED_API_KEY, projectId: process.env.STUBBED_PROJECT_NUM diff --git a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js index 4547a097e49..e16e50d8220 100644 --- a/packages/error-reporting/test/test-servers/hapi_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/hapi_scaffold_server.js @@ -16,7 +16,7 @@ 'use strict'; var hapi = require('hapi'); -var errorHandler = require('../../index.js')(); +var errorHandler = require('../../src/index.js')(); var server = new hapi.Server(); server.connection({ port: 3000 }); diff --git a/packages/error-reporting/test/test-servers/koa_scaffold_server.js b/packages/error-reporting/test/test-servers/koa_scaffold_server.js index 37388f8c41e..6e9bf3aceb8 100644 --- a/packages/error-reporting/test/test-servers/koa_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/koa_scaffold_server.js @@ -17,7 +17,7 @@ // jscs:disable 'use strict'; -var errorHandler = require('../../index.js')({ +var errorHandler = require('../../src/index.js')({ onUncaughtException: 'report' }); var koa = require('koa'); diff --git a/packages/error-reporting/test/test-servers/manual_scaffold_server.js b/packages/error-reporting/test/test-servers/manual_scaffold_server.js index cbdcd9472fb..1831bc18d22 100644 --- a/packages/error-reporting/test/test-servers/manual_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/manual_scaffold_server.js @@ -15,7 +15,7 @@ */ 'use strict'; -const errors = require('../../index.js')(); +const errors = require('../../src/index.js')(); errors.report('Sample test string', (err, response, body) => { console.log( 'Callback from report:\n', diff --git a/packages/error-reporting/test/test-servers/restify_scaffold_server.js b/packages/error-reporting/test/test-servers/restify_scaffold_server.js index 19c40c5aa92..8b8d4655a73 100644 --- a/packages/error-reporting/test/test-servers/restify_scaffold_server.js +++ b/packages/error-reporting/test/test-servers/restify_scaffold_server.js @@ -20,7 +20,7 @@ function respond(req, res, next) { } var restify = require('restify'); -var errorHandler = require('../../index.js')(); +var errorHandler = require('../../src/index.js')(); var server = restify.createServer(); diff --git a/scripts/docs/config.js b/scripts/docs/config.js index 66045a27041..8857ef3ede1 100644 --- a/scripts/docs/config.js +++ b/scripts/docs/config.js @@ -46,6 +46,10 @@ module.exports = { title: 'Google Cloud', instanceName: 'gcloud' }, + 'error-reporting': { + title: 'Error Reporting', + instanceName: 'errors' + }, bigquery: { title: 'BigQuery' }, From ace6a152d4cf48322e4a893e33ab319ebf66094e Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Tue, 4 Apr 2017 15:37:46 -0700 Subject: [PATCH 25/29] fix lint --- packages/error-reporting/src/configuration.js | 3 ++- packages/error-reporting/src/index.js | 2 +- packages/error-reporting/src/logger.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/error-reporting/src/configuration.js b/packages/error-reporting/src/configuration.js index 3a13b1cac0c..36add709104 100644 --- a/packages/error-reporting/src/configuration.js +++ b/packages/error-reporting/src/configuration.js @@ -347,7 +347,8 @@ Configuration.prototype._checkLocalProjectId = function(cb) { if (isString(this._projectId)) { // already has been set by the metadata service return this._projectId; - } else if (has(this._givenConfiguration, 'projectId')) { + } + if (has(this._givenConfiguration, 'projectId')) { if (isString(this._givenConfiguration.projectId)) { this._projectId = this._givenConfiguration.projectId; } else if (isNumber(this._givenConfiguration.projectId)) { diff --git a/packages/error-reporting/src/index.js b/packages/error-reporting/src/index.js index a51127b0f14..dee7e68a3cd 100644 --- a/packages/error-reporting/src/index.js +++ b/packages/error-reporting/src/index.js @@ -88,7 +88,7 @@ function Errors(initConfiguration) { uncaughtException(client, config); // Build the application interfaces for use by the hosting application - /** + /** * @example * // Use to report errors manually like so * var errors = require('@google-cloud/error-reporting')(); diff --git a/packages/error-reporting/src/logger.js b/packages/error-reporting/src/logger.js index dca61b987a7..9024814ee44 100644 --- a/packages/error-reporting/src/logger.js +++ b/packages/error-reporting/src/logger.js @@ -44,7 +44,7 @@ function createLogger(initConfiguration) { var level = logger.WARN; if (has(process.env, 'GCLOUD_ERRORS_LOGLEVEL')) { // Cast env string as integer - level = logger.LEVELS[~~process.env.GCLOUD_ERRORS_LOGLEVEL] || + level = logger.LEVELS[~~process.env.GCLOUD_ERRORS_LOGLEVEL] || logger.LEVELS.warn; } else if (isObject(initConfiguration) && has(initConfiguration, 'logLevel')) { From f3f613410a584fbf8fc2b863b94cd78100da81ce Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 5 Apr 2017 08:40:40 -0700 Subject: [PATCH 26/29] change function syntax in examples because jshint is complianing --- packages/error-reporting/src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/error-reporting/src/index.js b/packages/error-reporting/src/index.js index dee7e68a3cd..677f728f33e 100644 --- a/packages/error-reporting/src/index.js +++ b/packages/error-reporting/src/index.js @@ -92,7 +92,7 @@ function Errors(initConfiguration) { * @example * // Use to report errors manually like so * var errors = require('@google-cloud/error-reporting')(); - * errors.report(new Error('xyz'), () => console.log('done!')); + * errors.report(new Error('xyz'), function () {console.log('done!')}); */ this.report = manual(client, config); /** @@ -103,7 +103,7 @@ function Errors(initConfiguration) { * var err = errors.event() * .setMessage('My error message') * .setUser('root@nexus'); - * errors.report(err, () => console.log('done!')); + * errors.report(err, function () {console.log('done!')}); */ this.event = messageBuilder(config); /** From a403a34fc2ad1433207835527fdbfd98dcc46c7a Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Wed, 5 Apr 2017 08:55:49 -0700 Subject: [PATCH 27/29] fix snippet test --- packages/error-reporting/src/index.js | 28 +++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/error-reporting/src/index.js b/packages/error-reporting/src/index.js index 677f728f33e..8bf37dc7ea5 100644 --- a/packages/error-reporting/src/index.js +++ b/packages/error-reporting/src/index.js @@ -15,18 +15,18 @@ */ 'use strict'; -var Configuration = require('./src/configuration.js'); -var AuthClient = require('./src/google-apis/auth-client.js'); +var Configuration = require('./configuration.js'); +var AuthClient = require('./google-apis/auth-client.js'); // Begin error reporting interfaces -var koa = require('./src/interfaces/koa.js'); -var hapi = require('./src/interfaces/hapi.js'); -var manual = require('./src/interfaces/manual.js'); -var express = require('./src/interfaces/express.js'); -var restify = require('./src/interfaces/restify'); -var messageBuilder = require('./src/interfaces/message-builder.js'); -var uncaughtException = require('./src/interfaces/uncaught.js'); -var createLogger = require('./src/logger.js'); +var koa = require('./interfaces/koa.js'); +var hapi = require('./interfaces/hapi.js'); +var manual = require('./interfaces/manual.js'); +var express = require('./interfaces/express.js'); +var restify = require('./interfaces/restify'); +var messageBuilder = require('./interfaces/message-builder.js'); +var uncaughtException = require('./interfaces/uncaught.js'); +var createLogger = require('./logger.js'); /** * @typedef ConfigurationOptions @@ -92,7 +92,9 @@ function Errors(initConfiguration) { * @example * // Use to report errors manually like so * var errors = require('@google-cloud/error-reporting')(); - * errors.report(new Error('xyz'), function () {console.log('done!')}); + * errors.report(new Error('xyz'), function () { + * console.log('done!'); + * }); */ this.report = manual(client, config); /** @@ -103,7 +105,9 @@ function Errors(initConfiguration) { * var err = errors.event() * .setMessage('My error message') * .setUser('root@nexus'); - * errors.report(err, function () {console.log('done!')}); + * errors.report(err, function () { + * console.log('done!'); + * }); */ this.event = messageBuilder(config); /** From 4485f5e09c103f23cfb78e5c1a36a15557bdbb79 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Thu, 6 Apr 2017 08:48:16 -0700 Subject: [PATCH 28/29] remove errors requires from example comments --- packages/error-reporting/src/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/error-reporting/src/index.js b/packages/error-reporting/src/index.js index 8bf37dc7ea5..541469b4fee 100644 --- a/packages/error-reporting/src/index.js +++ b/packages/error-reporting/src/index.js @@ -91,7 +91,6 @@ function Errors(initConfiguration) { /** * @example * // Use to report errors manually like so - * var errors = require('@google-cloud/error-reporting')(); * errors.report(new Error('xyz'), function () { * console.log('done!'); * }); @@ -101,7 +100,6 @@ function Errors(initConfiguration) { * @example * // Use to create and report errors manually with a high-degree * // of manual control - * var errors = require('@google-cloud/error-reporting')(); * var err = errors.event() * .setMessage('My error message') * .setUser('root@nexus'); @@ -112,7 +110,6 @@ function Errors(initConfiguration) { this.event = messageBuilder(config); /** * @example - * var errors = require('@google-cloud/error-reporting')(); * var server = new hapi.Server(); * server.connection({ port: 3000 }); * server.start(); @@ -122,7 +119,6 @@ function Errors(initConfiguration) { this.hapi = hapi(client, config); /** * @example - * var errors = require('@google-cloud/error-reporting')(); * var app = express(); * // AFTER ALL OTHER ROUTE HANDLERS * app.use(errors.express); @@ -131,7 +127,6 @@ function Errors(initConfiguration) { this.express = express(client, config); /** * @example - * var errors = require('@google-cloud/error-reporting')(); * var server = restify.createServer(); * // BEFORE ALL OTHER ROUTE HANDLERS * server.use(errors.restify(server)); @@ -139,7 +134,6 @@ function Errors(initConfiguration) { this.restify = restify(client, config); /** * @example - * var errors = require('@google-cloud/error-reporting')(); * var app = koa(); * // BEFORE ALL OTHER ROUTE HANDLERS HANDLERS * app.use(errors.koa); From 475eedbf53abcc0a1414d7ec6dc24393e147daa7 Mon Sep 17 00:00:00 2001 From: Cristian Cavalli Date: Thu, 6 Apr 2017 09:15:57 -0700 Subject: [PATCH 29/29] fix snippet tests; add dependencies for errors snippet tests. --- packages/error-reporting/src/index.js | 4 +++ test/docs.js | 38 ++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/error-reporting/src/index.js b/packages/error-reporting/src/index.js index 541469b4fee..8a134e8bd29 100644 --- a/packages/error-reporting/src/index.js +++ b/packages/error-reporting/src/index.js @@ -110,6 +110,7 @@ function Errors(initConfiguration) { this.event = messageBuilder(config); /** * @example + * var hapi = require('hapi'); * var server = new hapi.Server(); * server.connection({ port: 3000 }); * server.start(); @@ -119,6 +120,7 @@ function Errors(initConfiguration) { this.hapi = hapi(client, config); /** * @example + * var express = require('express'); * var app = express(); * // AFTER ALL OTHER ROUTE HANDLERS * app.use(errors.express); @@ -127,6 +129,7 @@ function Errors(initConfiguration) { this.express = express(client, config); /** * @example + * var restify = require('restify'); * var server = restify.createServer(); * // BEFORE ALL OTHER ROUTE HANDLERS * server.use(errors.restify(server)); @@ -134,6 +137,7 @@ function Errors(initConfiguration) { this.restify = restify(client, config); /** * @example + * var koa = require('koa'); * var app = koa(); * // BEFORE ALL OTHER ROUTE HANDLERS HANDLERS * app.use(errors.koa); diff --git a/test/docs.js b/test/docs.js index 315a07b4546..a267202362d 100644 --- a/test/docs.js +++ b/test/docs.js @@ -69,15 +69,48 @@ var FakeConsole = Object.keys(console) return console; }, {}); -// For {module:datastore} docs. +// For {module:datastore && module:error-reporting} docs. var FakeExpress = function() { return { get: function(route, callback) { callback({ query: {} }, {}); + }, + use: function() {}, + listen: function() {} + }; +}; + +// For {module:error-reporting} docs. +var FakeHapi = function() { + return { + Server: function() { + return { + connection: function() {}, + start: function() {}, + register: function() {} + }; + } + }; +}; + +// For {module:error-reporting} docs. +var FakeRestify = function() { + return { + createServer: function() { + return { + use: function() {}, + on: function() {} + }; } }; }; +var FakeKoa = function() { + return { + use: function() {} + }; +}; + // For {module:vision} docs. var FakeLevel = function() { return { @@ -290,6 +323,9 @@ function createSnippet(mod, instantiation, method) { 'keyFilename: \'\'' ) .replace('require(\'express\')', FakeExpress.toString()) + .replace('require(\'hapi\')', '(' + FakeHapi.toString() + '())') + .replace('require(\'restify\')', '(' + FakeRestify.toString() + '())') + .replace('require(\'koa\')', FakeKoa.toString()) .replace('require(\'level\')', FakeLevel.toString()) .replace('require(\'bluebird\')', FakeBluebird.toString()) .replace('require(\'bunyan\')', '(' + fakeBunyan.toString() + '())')