diff --git a/.circleci/config.yml b/.circleci/config.yml index 9a9c06a..68fc522 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,90 +3,88 @@ workflows: version: 2 tests: jobs: &workflow_jobs - - node6: - filters: - tags: - only: /.*/ - # - node8: - # filters: - # tags: - # only: /.*/ - # - node10: - # filters: - # tags: - # only: /.*/ - lint: - requires: - - node6 - # - node8 - # - node10 - filters: + filters: &all_commits tags: only: /.*/ - - system_tests: + - node6: requires: - lint - filters: - branches: - only: master - tags: - only: '/^v[\d.]+$/' - - publish_npm: + filters: *all_commits + - node8: requires: - - system_tests + - lint + filters: *all_commits + nightly: + triggers: + - schedule: + cron: 0 7 * * * filters: branches: - ignore: /.*/ - tags: - only: '/^v[\d.]+$/' + only: master + jobs: *workflow_jobs jobs: + lint: + docker: + - image: 'node:8' + user: node + steps: + - checkout + - run: &npm_install_and_link + name: Install and link the module + command: |- + mkdir -p /home/node/.npm-global + ./.circleci/npm-install-retry.js + environment: + NPM_CONFIG_PREFIX: /home/node/.npm-global + - run: + name: Run linting. + command: npm run lint + environment: + NPM_CONFIG_PREFIX: /home/node/.npm-global node6: docker: - image: 'node:6' - steps: &unit_tests_steps + user: node + steps: &tests_steps - checkout + - run: + name: Decrypt credentials. + command: | + if ! [[ -z "${SERVICE_ACCOUNT_ENCRYPTION_KEY}" ]]; then + for encrypted_key in .circleci/*.json.enc; do + openssl aes-256-cbc -d -in $encrypted_key \ + -out $(echo $encrypted_key | sed 's/\.enc//') \ + -k "${SERVICE_ACCOUNT_ENCRYPTION_KEY}" + done + fi - run: name: Install and configure Cloud SDK command: | - echo $KEYFILE > key.json - curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-209.0.0-linux-x86_64.tar.gz | tar xz - mv ./google-cloud-sdk /opt - export PATH=$PATH:/opt/google-cloud-sdk/bin + curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-228.0.0-linux-x86_64.tar.gz | tar xz -C /tmp + export PATH=$PATH:/tmp/google-cloud-sdk/bin gcloud components install beta -q gcloud components update -q gcloud config set project cloud-functions-emulator gcloud config set compute/region us-central1 - gcloud auth activate-service-account --key-file key.json - - run: yarn - - run: yarn test + gcloud auth activate-service-account --key-file .circleci/key.json + - run: *npm_install_and_link + - run: + name: Run tests. + command: npm test + environment: + GCLOUD_PROJECT: cloud-functions-emulator + GOOGLE_APPLICATION_CREDENTIALS: .circleci/key.json - run: node_modules/.bin/codecov - # node8: - # docker: - # - image: 'node:8' - # steps: *unit_tests_steps - # node10: - # docker: - # - image: 'node:10' - # steps: *unit_tests_steps - lint: - docker: - - image: 'node:6' - steps: - - checkout - - run: yarn install - - run: npm run lint - system_tests: + - run: + name: Remove unencrypted key. + command: | + if ! [[ -z "${SERVICE_ACCOUNT_ENCRYPTION_KEY}" ]]; then + rm .circleci/*.json + fi + when: always + node8: docker: - - image: 'node:6' + - image: 'node:8' user: node - steps: - - checkout - - run: yarn - - run: yarn run system-test - publish_npm: - docker: - - image: 'node:10' - steps: - - checkout - - run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc - - run: npm publish + steps: *tests_steps diff --git a/.circleci/key.json.enc b/.circleci/key.json.enc new file mode 100644 index 0000000..ac007af Binary files /dev/null and b/.circleci/key.json.enc differ diff --git a/.circleci/npm-install-retry.js b/.circleci/npm-install-retry.js new file mode 100755 index 0000000..ae3220d --- /dev/null +++ b/.circleci/npm-install-retry.js @@ -0,0 +1,60 @@ +#!/usr/bin/env node + +let spawn = require('child_process').spawn; + +// +//USE: ./index.js [... NPM ARGS] +// + +let timeout = process.argv[2] || 60000; +let attempts = process.argv[3] || 3; +let args = process.argv.slice(4); +if (args.length === 0) { + args = ['install']; +} + +(function npm() { + let timer; + args.push('--verbose'); + let proc = spawn('npm', args); + proc.stdout.pipe(process.stdout); + proc.stderr.pipe(process.stderr); + proc.stdin.end(); + proc.stdout.on('data', () => { + setTimer(); + }); + proc.stderr.on('data', () => { + setTimer(); + }); + + // side effect: this also restarts when npm exits with a bad code even if it + // didnt timeout + proc.on('close', (code, signal) => { + clearTimeout(timer); + if (code || signal) { + console.log('[npm-are-you-sleeping] npm exited with code ' + code + ''); + + if (--attempts) { + console.log('[npm-are-you-sleeping] restarting'); + npm(); + } else { + console.log('[npm-are-you-sleeping] i tried lots of times. giving up.'); + throw new Error("npm install fails"); + } + } + }); + + function setTimer() { + clearTimeout(timer); + timer = setTimeout(() => { + console.log('[npm-are-you-sleeping] killing npm with SIGTERM'); + proc.kill('SIGTERM'); + // wait a couple seconds + timer = setTimeout(() => { + // its it's still not closed sigkill + console.log('[npm-are-you-sleeping] killing npm with SIGKILL'); + proc.kill('SIGKILL'); + }, 2000); + }, timeout); + } +})(); diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b4dfe9..20dcf30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +##### 1.0.0-beta.6 - XX November 2018 + +###### Breaking changes +- Removed support for using the Gcloud SDK to interact with the emulator +- Removed used of googleapis library + +###### Other +- Upgraded all dependencies + ##### 1.0.0-beta.5 - 31 July 2018 ###### Bug fixes diff --git a/package.json b/package.json index 1671169..1eba2a1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@google-cloud/functions-emulator", "description": "Google Cloud Functions Emulator", - "version": "1.0.0-beta.5", + "version": "1.0.0-beta.6", "license": "Apache-2.0", "author": "Google Inc.", "engines": { @@ -59,7 +59,7 @@ "scripts": { "lint": "semistandard", "fix": "semistandard --fix", - "mocha": "mocha test/_setup test/ --recursive -t 120000 -S -R spec --require intelli-espower-loader", + "mocha": "mocha test/_setup test/system/ --recursive -t 120000 -S -R spec --require intelli-espower-loader", "unit-test": "npm run mocha -- --grep \"unit/\"", "system-test": "npm run mocha -- --grep \"system/\"", "mocha-debug": "mocha debug test/_setup test/ --recursive -t 120000 -S -R spec --require intelli-espower-loader", @@ -73,17 +73,16 @@ "generate-scaffolding": "repo-tools generate contributors coc contributing license pr_template pkgjson" }, "dependencies": { - "@google-cloud/storage": "^1.7.0", - "adm-zip": "^0.4.11", - "ajv": "^6.5.2", + "@google-cloud/storage": "1.7.0", + "adm-zip": "^0.4.13", + "ajv": "^6.5.5", + "axios": "^0.18.0", "body-parser": "^1.18.3", "chokidar": "^2.0.4", "cli-table3": "^0.5.1", - "colors": "^1.3.1", + "colors": "^1.3.2", "configstore": "^4.0.0", - "express": "^4.16.3", - "googleapis": "^35.0.0", - "got": "^9.0.0", + "express": "^4.16.4", "http-proxy": "^1.17.0", "lodash": "4.17.11", "make-dir": "1.3.0", @@ -92,23 +91,23 @@ "semver": "5.6.0", "serializerr": "1.0.3", "tmp": "0.0.33", - "uuid": "3.2.1", + "uuid": "3.3.2", "winston": "3.1.0", "xdg-basedir": "3.0.0", - "yargs": "11.0.0" + "yargs": "12.0.2" }, "devDependencies": { - "@google-cloud/nodejs-repo-tools": "^3.0.0", - "codecov": "^3.0.4", + "@google-cloud/nodejs-repo-tools": "2.3.5", + "codecov": "^3.1.0", "intelli-espower-loader": "^1.0.1", "mocha": "^5.2.0", - "nock": "^10.0.0", - "nyc": "^13.0.0", - "power-assert": "^1.6.0", - "proxyquire": "^2.0.0", - "semistandard": "^13.0.0", + "nock": "^10.0.2", + "nyc": "^13.1.0", + "power-assert": "^1.6.1", + "proxyquire": "^2.1.0", + "semistandard": "^13.0.1", "semistandard-format": "^3.0.0", - "sinon": "^7.0.0", - "supertest": "^3.0.0" + "sinon": "^7.1.1", + "supertest": "^3.3.0" } } diff --git a/src/cli/commands/delete.js b/src/cli/commands/delete.js index 88cf918..651775a 100644 --- a/src/cli/commands/delete.js +++ b/src/cli/commands/delete.js @@ -59,7 +59,7 @@ exports.handler = (opts) => { function poll () { controller.write('.'); controller.client.getOperation(operation.name) - .then(([operation]) => { + .then((operation) => { if (!operation.done) { setTimeout(poll, 500); } else { diff --git a/src/cli/commands/deploy.js b/src/cli/commands/deploy.js index 72daa0b..55e20b1 100644 --- a/src/cli/commands/deploy.js +++ b/src/cli/commands/deploy.js @@ -144,13 +144,13 @@ exports.handler = (opts) => { return controller.doIfRunning() // Deploy the function .then(() => controller.deploy(opts.functionName, opts)) - .then(([operation, response]) => { + .then(([operation]) => { // Poll the operation return new Promise((resolve, reject) => { function poll () { controller.write('.'); controller.client.getOperation(operation.name) - .then(([operation]) => { + .then((operation) => { if (!operation.done) { setTimeout(poll, 500); } else { diff --git a/src/cli/controller.js b/src/cli/controller.js index d9b3ee6..41cdb9b 100644 --- a/src/cli/controller.js +++ b/src/cli/controller.js @@ -23,9 +23,6 @@ * CLI - - Emulator * |--<-- RestClient - HTTP1.1 - JSON --<--| * - * The Gcloud SDK can be used to talk to the Emulator as well, just do: - * - * gcloud config set api_endpoint_overrides/cloudfunctions http://localhost:8008/ */ 'use strict'; @@ -34,9 +31,9 @@ require('colors'); const _ = require('lodash'); const AdmZip = require('adm-zip'); +const axios = require('axios'); const exec = require('child_process').exec; const fs = require('fs'); -const got = require('got'); const path = require('path'); const spawn = require('child_process').spawn; const Storage = require('@google-cloud/storage'); @@ -367,14 +364,15 @@ class Controller { this.log(`You paused execution. Connect to the debugger on port ${opts.port} to resume execution and begin debugging.`); } - return got.post(`http://${this.config.host}:${this.config.supervisorPort}/api/debug`, { - body: { + return axios.request({ + url: `http://${this.config.host}:${this.config.supervisorPort}/api/debug`, + method: 'POST', + data: { type: type, name: cloudfunction.name, port: opts.port, pause: opts.pause - }, - json: true + } }); }); } @@ -390,10 +388,11 @@ class Controller { .then( () => this.undeploy(name).then(() => this._create(name, opts)), (err) => { - if (err.code === 404 || err.code === 5) { + const error = err.response.data.error; + if (error.code === 404 || error.code === 5) { return this._create(name, opts); } - return Promise.reject(err); + return Promise.reject(error); } ); } @@ -563,12 +562,13 @@ class Controller { reset (name, opts) { return this.client.getFunction(name) .then(([cloudfunction]) => { - return got.post(`http://${this.config.host}:${this.config.supervisorPort}/api/reset`, { - body: { + return axios.request({ + url: `http://${this.config.host}:${this.config.supervisorPort}/api/reset`, + method: 'POST', + data: { name: cloudfunction.name, keep: opts.keep - }, - json: true + } }); }); } diff --git a/src/client/rest-client.js b/src/client/rest-client.js index ffda5c9..7f6872a 100644 --- a/src/client/rest-client.js +++ b/src/client/rest-client.js @@ -16,7 +16,7 @@ 'use strict'; const _ = require('lodash'); -const google = require('googleapis'); +const axios = require('axios'); const net = require('net'); const path = require('path'); const url = require('url'); @@ -27,34 +27,14 @@ const Model = require('../model'); const { CloudFunction } = Model; class RestClient extends Client { - _action (method, params) { - return this.getService() - .then((functionsService) => { - return new Promise((resolve, reject) => { - _.get(functionsService, method).call(functionsService, params, (err, body, response) => { - if (err) { - reject(err); - } else { - resolve([body, response]); - } - }); - }); - }); - } - callFunction (name, data, opts) { var resource = { data: data }; if (opts) { resource = _.merge(resource, opts); } - return this._action( - 'projects.locations.functions.call', - { - name: CloudFunction.formatName(this.config.projectId, this.config.region, name), - resource: resource - } - ).then(([body, response]) => { + return axios.post(this.getUrl(`${CloudFunction.formatName(this.config.projectId, this.config.region, name)}:call`), resource).then((response) => { + const body = response.data; if (body.result && typeof body.result === 'string') { try { body.result = JSON.parse(body.result); @@ -73,50 +53,21 @@ class RestClient extends Client { } createFunction (cloudfunction) { - return this._action( - 'projects.locations.functions.create', - { - location: CloudFunction.formatLocation(this.config.projectId, this.config.region), - resource: cloudfunction - } - ); + return axios.post(this.getUrl(`${CloudFunction.formatLocation(this.config.projectId, this.config.region)}/functions`), cloudfunction).then((response) => [response.data, response]); } deleteFunction (name) { - return this._action( - 'projects.locations.functions.delete', - { - name: CloudFunction.formatName(this.config.projectId, this.config.region, name) - } - ); + return axios.request({ + url: this.getUrl(CloudFunction.formatName(this.config.projectId, this.config.region, name)), + method: 'DELETE' + }).then((response) => [response.data, response]); } generateUploadUrl (name) { - return this._action( - 'projects.locations.functions.generateUploadUrl', - { - parent: CloudFunction.formatLocation(this.config.projectId, this.config.region) - } - ); - } - - getService () { - return new Promise((resolve, reject) => { - const discoveryPath = '$discovery/rest'; - const parts = url.parse(this.getUrl(discoveryPath)); - const discoveryUrl = url.format(_.merge(parts, { - pathname: discoveryPath, - search: '?version=v1' - })); - - google.discoverAPI(discoveryUrl, (err, functions) => { - if (err) { - reject(err); - } else { - resolve(functions); - } - }); - }); + return axios.post( + this.getUrl(`${CloudFunction.formatLocation(this.config.projectId, this.config.region)}/functions:generateUploadUrl`) + ) + .then((response) => [response.data, response]); } getUrl (pathname) { @@ -129,26 +80,20 @@ class RestClient extends Client { } getFunction (name) { - return this._action( - 'projects.locations.functions.get', - { - name: CloudFunction.formatName(this.config.projectId, this.config.region, name) - } - ).then(([body, response]) => [new CloudFunction(body.name, body), response]); + return axios.get(this.getUrl(CloudFunction.formatName(this.config.projectId, this.config.region, name))) + .then((response) => [new CloudFunction(response.data.name, response.data), response]); } getOperation (name) { - return this._action('operations.get', { name }); + return axios.get(this.getUrl(name)).then(response => response.data); } listFunctions () { - return this._action( - 'projects.locations.functions.list', - { - pageSize: 100, - parent: CloudFunction.formatLocation(this.config.projectId, this.config.region) + return axios.get(this.getUrl(`${CloudFunction.formatLocation(this.config.projectId, this.config.region)}/functions`), { + params: { + pageSize: 100 } - ).then(([body, response]) => [body.functions.map((cloudfunction) => new CloudFunction(cloudfunction.name, cloudfunction)), response]); + }).then((response) => [response.data.functions.map((cloudfunction) => new CloudFunction(cloudfunction.name, cloudfunction)), response]); } testConnection () { diff --git a/src/model/functions.js b/src/model/functions.js index 39147b6..4d46fe8 100644 --- a/src/model/functions.js +++ b/src/model/functions.js @@ -17,9 +17,9 @@ const _ = require('lodash'); const AdmZip = require('adm-zip'); +const axios = require('axios'); const Configstore = require('configstore'); const fs = require('fs'); -const got = require('got'); const logger = require('winston'); const os = require('os'); const path = require('path'); @@ -339,7 +339,7 @@ class Functions { } } - logger.debug(JSON.stringify(request.function, null, 2)); + logger.debug(request.function); // TODO: Filter out fields that cannot be edited by the user cloudfunction = this.cloudfunction(cloudfunction.name, cloudfunction); @@ -388,11 +388,12 @@ class Functions { return new Promise((resolve, reject) => { setTimeout(() => { - got.post(`${this.getSupervisorHost()}/api/deploy`, { - body: { + return axios.request({ + url: `${this.getSupervisorHost()}/api/deploy`, + method: 'POST', + data: { name: cloudfunction.name - }, - json: true + } }).then(resolve, (err) => { if (err && err.response && err.response.body) { if (err.response.body.error) { @@ -521,11 +522,12 @@ class Functions { // Delete the CloudFunction this.adapter.deleteFunction(name) .then(() => { - return got.post(`${this.getSupervisorHost()}/api/delete`, { - body: { + return axios.request({ + url: `${this.getSupervisorHost()}/api/delete`, + method: 'POST', + data: { name: cloudfunction.name - }, - json: true + } }); }) .then(() => { diff --git a/src/service/rest-service.js b/src/service/rest-service.js index 3c5478f..cd88b82 100644 --- a/src/service/rest-service.js +++ b/src/service/rest-service.js @@ -15,34 +15,28 @@ 'use strict'; +const axios = require('axios'); const bodyParser = require('body-parser'); -const Configstore = require('configstore'); const express = require('express'); const fs = require('fs'); -const got = require('got'); const logger = require('winston'); -const path = require('path'); -const url = require('url'); const uuid = require('uuid'); const Errors = require('../utils/errors'); const Model = require('../model'); -const pkg = require('../../package.json'); const Service = require('./service'); const { CloudFunction, Operation } = Model; // TODO: Support more than one version. const API_VERSION = 'v1'; -const DISCOVERY_URL = `https://cloudfunctions.googleapis.com/$discovery/rest?version=${API_VERSION}`; class RestService extends Service { constructor (...args) { super(...args); this.type = 'REST'; - this._discovery = new Configstore(path.join(pkg.name, '/.discovery')); // Standard ExpressJS app. Where possible this should mimic the *actual* // setup of Cloud Functions regarding the use of body parsers etc. @@ -68,10 +62,6 @@ class RestService extends Service { }); this.server - .get( - `/([$])discovery/rest`, - (req, res, next) => this.getDiscoveryDoc(req, res).catch(next) - ) .delete( `/${API_VERSION}/projects/:project/locations/:location/functions/:name`, (req, res, next) => this.deleteFunction(req, res).catch(next) @@ -112,13 +102,6 @@ class RestService extends Service { * */ callFunction (req, res) { - if (req.headers['user-agent'].includes('google-cloud-sdk') && typeof req.body.data === 'string') { - try { - req.body.data = JSON.parse(req.body.data); - } catch (err) { - - } - } try { req.body.auth = JSON.parse(req.body.auth); } catch (err) { @@ -147,11 +130,14 @@ class RestService extends Service { event.auth = req.body.auth || { admin: true }; } - return got.post(`${this.functions.getSupervisorHost()}/${req.params.project}/${req.params.location}/${req.params.name}`, { - body: JSON.stringify(cloudfunction.httpsTrigger ? event.data : event), + return axios.request({ + url: `${this.functions.getSupervisorHost()}/${req.params.project}/${req.params.location}/${req.params.name}`, + method: 'POST', + data: JSON.stringify(cloudfunction.httpsTrigger ? event.data : event), headers: { 'Content-Type': 'application/json' - } + }, + responseType: 'text' }); }) .then((response) => { @@ -159,7 +145,7 @@ class RestService extends Service { .status(200) .send({ executionId: eventId, - result: response.body + result: response.data }) .end(); }, (err) => { @@ -167,7 +153,7 @@ class RestService extends Service { .status(200) .send({ executionId: eventId, - error: err.response ? err.response.body : err.message + error: err.response ? err.response.data : err.message }) .end(); }); @@ -220,48 +206,6 @@ class RestService extends Service { }); } - /** - * Gets the Google Cloud Functions API discovery doc. - * - * @param {object} req The request. - * @param {object} res The response. - */ - getDiscoveryDoc (req, res) { - return Promise.resolve() - .then(() => { - const doc = this._discovery.all; - if (typeof doc === 'object' && Object.keys(doc).length > 0 && doc.version === API_VERSION) { - return doc; - } - return got(DISCOVERY_URL, { - query: { - version: req.query.version - } - }) - .then((response) => { - const doc = JSON.parse(response.body); - this._discovery.set(doc); - return doc; - }) - .catch((err) => { - if (err && err.statusCode === 404) { - return Promise.reject(new Errors.NotFoundError('Discovery document not found for API service.')); - } - return Promise.reject(err); - }); - }) - .then((doc) => { - // TODO: Change the baseUrl and rootUrl - doc.baseUrl = doc.rootUrl = url.format({ - hostname: this.config.host, - port: this.config.port, - protocol: `${req.protocol}:` - }) + '/'; - doc.canonicalName = 'Cloud Functions Emulator'; - res.status(200).json(doc).end(); - }); - } - /** * Gets a function. * @@ -277,16 +221,6 @@ class RestService extends Service { logger.debug('RestService#getFunction', name); return this.functions.getFunction(name) .then((cloudfunction) => { - if (req.get('user-agent') && - req.get('user-agent').includes('google-cloud-sdk') && - cloudfunction.status === 'DEPLOYING') { - // For some reason the Cloud SDK doesn't wait for the operation to be - // done before printing the function to the user, instead it polls for - // the function. So here pretend the function doesn't exist until it's - // no longer deploying. - return Promise.reject(this.functions._getFunctionNotFoundError(name)); - } - res.status(200).json(cloudfunction).end(); }); } diff --git a/test/system/cli/index.test.js b/test/system/cli/index.test.js index b4ac47d..bc2a436 100644 --- a/test/system/cli/index.test.js +++ b/test/system/cli/index.test.js @@ -15,7 +15,7 @@ 'use strict'; -const got = require(`got`); +const axios = require(`axios`); const path = require(`path`); process.env.XDG_CONFIG_HOME = path.join(__dirname, `../`); @@ -40,7 +40,6 @@ const config = new Configstore(path.join(pkg.name, `config`)); const server = new Configstore(path.join(pkg.name, `.active-server`)); const functions = new Configstore(path.join(pkg.name, `.functions`)); const operations = new Configstore(path.join(pkg.name, `.operations`)); -const prefix = `Google Cloud Functions Emulator`; const GCLOUD = process.env.GCLOUD_CMD_OVERRIDE || `gcloud`; const HOST = 'localhost'; @@ -95,12 +94,12 @@ function makeTests (service, override) { }) .then(() => tools.spawnAsyncWithIO('node', ['bin/functions', 'restart'], cwd)) .then((results) => { - assert(results.output.includes(`${prefix} STARTED`)); + assert(results.output.includes(`STARTED`)); return tools.tryTest(() => { return tools.spawnAsyncWithIO('node', ['bin/functions', 'clear'], cwd) .then((results) => { - assert(results.output.includes(`${prefix} CLEARED`)); + assert(results.output.includes(`CLEARED`)); }); }).start(); }); @@ -119,18 +118,18 @@ function makeTests (service, override) { }) .then(() => tools.spawnAsyncWithIO('node', ['bin/functions', 'restart'], cwd)) .then((results) => { - assert(results.output.includes(`${prefix} STARTED`)); + assert(results.output.includes(`STARTED`)); return tools.tryTest(() => { return tools.spawnAsyncWithIO('node', ['bin/functions', 'clear'], cwd) .then((results) => { - assert(results.output.includes(`${prefix} CLEARED`)); + assert(results.output.includes(`CLEARED`)); }); }).start(); }) .then(() => tools.spawnAsyncWithIO('node', ['bin/functions', 'stop'], cwd)) .then((results) => { - assert(results.output.includes(`${prefix} STOPPED`)); + assert(results.output.includes(`STOPPED`)); }); }); @@ -437,9 +436,7 @@ function makeTests (service, override) { }); it(`should call (via request) an HTTP function that exceeds its timeout`, () => { - return got(`http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloSlow`, { - json: true - }).then((response) => { + return axios.get(`http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloSlow`).then((response) => { assert.fail(`should have failed`); }).catch((err) => { assert.equal(err.response.statusCode, 500); @@ -459,9 +456,7 @@ function makeTests (service, override) { }); it(`should call (via request) an HTTP function that fails to respond (crashes asynchronously)`, () => { - return got(`http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloNoResponse`, { - json: true - }).then((response) => { + return axios.get(`http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloNoResponse`).then((response) => { assert.fail(`should have failed`); }).catch((err) => { assert.equal(err.response.statusCode, 500); @@ -492,12 +487,12 @@ function makeTests (service, override) { }); it(`should call an HTTP function via trigger URL`, () => { - return got(`http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloGET`, { + return axios.request({ + url: `http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloGET`, method: 'GET', headers: { 'x-api-key': 'any' - }, - json: true + } }).then((response) => { assert.equal(response.body.headers[`x-api-key`], `any`); assert.equal(response.body.method, `GET`); @@ -507,12 +502,12 @@ function makeTests (service, override) { }); it(`should call an HTTP function via trigger URL with extras`, () => { - return got(`http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloGET/test?foo=bar&beep=boop`, { + return axios.request({ + url: `http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}/helloGET/test?foo=bar&beep=boop`, method: 'GET', headers: { 'x-api-key': 'any' - }, - json: true + } }).then((response) => { assert.equal(response.body.headers[`x-api-key`], `any`); assert.equal(response.body.method, `GET`); @@ -595,7 +590,7 @@ function makeTests (service, override) { assert(output.includes(`helloPOST`)); output = run(`${cmd} clear ${shortArgs}`, cwd); - assert(output.includes(`${prefix} CLEARED`)); + assert(output.includes(`CLEARED`)); output = run(`${cmd} list ${shortArgs}`, cwd); assert(output.includes(`No functions deployed`)); @@ -624,7 +619,6 @@ function makeTests (service, override) { describe(`status`, () => { it(`should show the server status`, () => { let output = run(`${cmd} status ${shortArgs}`, cwd); - assert(output.includes(`${prefix}`)); assert(output.includes(`RUNNING`)); assert(output.includes(`http://localhost:${REST_PORT}/`)); assert(output.includes(`http://localhost:${SUPERVISOR_PORT}/${PROJECT_ID}/${REGION}`)); @@ -662,5 +656,4 @@ describe(`system/cli`, () => { }); makeTests(`rest`); - makeTests(`rest`, `${GCLOUD} beta functions`); });