From d4b5c636edfaedf7826ab48a079c503262b72041 Mon Sep 17 00:00:00 2001 From: ericschmidtatwork Date: Wed, 12 Oct 2022 17:20:04 -0700 Subject: [PATCH 1/2] Fix/update GCF Memorystore sample --- functions/memorystore/redis/README.md | 2 ++ functions/memorystore/redis/index.js | 14 ++++---- functions/memorystore/redis/package.json | 1 + .../memorystore/redis/test/index.test.js | 35 +++++++++++++++---- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/functions/memorystore/redis/README.md b/functions/memorystore/redis/README.md index b25e0884c5..58652a3fad 100644 --- a/functions/memorystore/redis/README.md +++ b/functions/memorystore/redis/README.md @@ -5,5 +5,7 @@ See: * [Cloud Functions Cloud Memorystore sample source code][code] +* [Connecting to a Redis instance from Cloud Functions][tutorial] [code]: index.js +[tutorial]: https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-functions diff --git a/functions/memorystore/redis/index.js b/functions/memorystore/redis/index.js index 7575de4a50..ff2c5633c1 100644 --- a/functions/memorystore/redis/index.js +++ b/functions/memorystore/redis/index.js @@ -16,7 +16,7 @@ // [START functions_memorystore_redis] -const {promisify} = require('util'); +const functions = require('@google-cloud/functions-framework'); const redis = require('redis'); const REDISHOST = process.env.REDISHOST || 'localhost'; @@ -24,24 +24,22 @@ const REDISPORT = process.env.REDISPORT || 6379; const redisClient = redis.createClient({ socket: { - port: REDISPORT, host: REDISHOST, + port: REDISPORT, }, }); -redisClient.connect(); redisClient.on('error', err => console.error('ERR:REDIS:', err)); +redisClient.connect(); -const incrAsync = promisify(redisClient.incr).bind(redisClient); - -exports.visitCount = async (req, res) => { +functions.http('visitCount', async (req, res) => { try { - const response = await incrAsync('visits'); + const response = await redisClient.incr('visits'); res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(`Visit count: ${response}`); } catch (err) { console.log(err); res.status(500).send(err.message); } -}; +}); // [END functions_memorystore_redis] diff --git a/functions/memorystore/redis/package.json b/functions/memorystore/redis/package.json index 79eebcd682..4318effeba 100644 --- a/functions/memorystore/redis/package.json +++ b/functions/memorystore/redis/package.json @@ -16,6 +16,7 @@ "test": "mocha test/*.test.js --timeout=20000 --exit" }, "dependencies": { + "@google-cloud/functions-framework": "^3.1.2", "redis": "^4.0.0" }, "devDependencies": { diff --git a/functions/memorystore/redis/test/index.test.js b/functions/memorystore/redis/test/index.test.js index fcbe86e4ec..35c6ad830f 100644 --- a/functions/memorystore/redis/test/index.test.js +++ b/functions/memorystore/redis/test/index.test.js @@ -14,10 +14,13 @@ 'use strict'; -const sinon = require('sinon'); const assert = require('assert'); +const sinon = require('sinon'); +const {getFunction} = require('@google-cloud/functions-framework/testing'); + +const redis = require('redis'); -const getMocks = () => { +const getHttpMocks = () => { return { req: {}, res: { @@ -29,13 +32,31 @@ const getMocks = () => { }; }; +const stubRedis = () => { + sinon.stub(redis, 'createClient').callsFake(() => { + return { + on: sinon.stub(), + connect: sinon.stub(), + incr: sinon.stub().resolves(42), + }; + }); +}; + +const restoreRedis = () => { + redis.createClient.restore(); +}; + describe('functions_memorystore_redis', () => { describe('visitCount', () => { - it('should successfully increment the Redis counter', async () => { - const program = require('../'); - const mocks = getMocks(); + beforeEach(stubRedis); + afterEach(restoreRedis); + + it('should respond with current visit count', async () => { + require('..'); + const visitCount = getFunction('visitCount'); + const mocks = getHttpMocks(); - await program.visitCount(mocks.req, mocks.res); + await visitCount(mocks.req, mocks.res); assert(!mocks.res.status.called); assert(!mocks.res.send.called); @@ -43,7 +64,7 @@ describe('functions_memorystore_redis', () => { assert(mocks.res.end.calledOnce); const [response] = mocks.res.end.firstCall.args; - assert(response.startsWith('Visit count:')); + assert(response === 'Visit count: 42'); }); }); }); From 8d83415db8b590645572cdc4a94eab0c41d0ae5f Mon Sep 17 00:00:00 2001 From: ericschmidtatwork Date: Wed, 16 Nov 2022 16:12:48 -0800 Subject: [PATCH 2/2] Add workflow file for running tests --- .github/workflows/functions-memorystore.yaml | 67 ++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/functions-memorystore.yaml diff --git a/.github/workflows/functions-memorystore.yaml b/.github/workflows/functions-memorystore.yaml new file mode 100644 index 0000000000..77afdaa6e7 --- /dev/null +++ b/.github/workflows/functions-memorystore.yaml @@ -0,0 +1,67 @@ +name: functions-memorystore +on: + push: + branches: + - main + paths: + - 'functions/memorystore/redis/**' + pull_request: + paths: + - 'functions/memorystore/redis/**' + pull_request_target: + types: [labeled] + schedule: + - cron: '0 0 * * 0' +jobs: + test: + if: ${{ github.event.action != 'labeled' || github.event.label.name == 'actions:force-run' }} + runs-on: ubuntu-latest + timeout-minutes: 60 + permissions: + contents: 'write' + pull-requests: 'write' + id-token: 'write' + steps: + - uses: actions/checkout@v3 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + - uses: google-github-actions/auth@v1.0.0 + with: + workload_identity_provider: 'projects/1046198160504/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider' + service_account: 'kokoro-system-test@long-door-651.iam.gserviceaccount.com' + create_credentials_file: 'true' + access_token_lifetime: 600s + - uses: actions/setup-node@v3 + with: + node-version: 14 + - run: npm install + working-directory: functions/memorystore/redis + - run: npm test + working-directory: functions/memorystore/redis + env: + MOCHA_REPORTER_SUITENAME: functions_memorystore + MOCHA_REPORTER_OUTPUT: functions_memorystore_sponge_log.xml + MOCHA_REPORTER: xunit + - if: ${{ github.event.action == 'labeled' && github.event.label.name == 'actions:force-run' }} + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + await github.rest.issues.removeLabel({ + name: 'actions:force-run', + owner: 'GoogleCloudPlatform', + repo: 'nodejs-docs-samples', + issue_number: context.payload.pull_request.number + }); + } catch (e) { + if (!e.message.includes('Label does not exist')) { + throw e; + } + } + - if: ${{ github.event_name == 'schedule' && always() }} + run: | + curl https://github.com/googleapis/repo-automation-bots/releases/download/flakybot-1.1.0/flakybot -o flakybot -s -L + chmod +x ./flakybot + ./flakybot --repo GoogleCloudPlatform/nodejs-docs-samples --commit_hash ${{github.sha}} --build_url https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}