-
-
Notifications
You must be signed in to change notification settings - Fork 795
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8d61bde
commit 0cb9256
Showing
13 changed files
with
344 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import { EOL } from 'os' | ||
import { promises as fsPromises } from 'fs' | ||
import { sep, resolve, parse as pathParse } from 'path' | ||
import execa, { sync } from 'execa' | ||
import STS from 'aws-sdk/clients/sts' | ||
|
||
const { writeFile, readFile, mkdir, rmdir } = fsPromises | ||
const { parse, stringify } = JSON | ||
const { cwd } = process | ||
|
||
const MIN_ALLOWED_SESSION_DURATION_S = 900 | ||
const SESSION_TIMEOUT_MS = 850 * 1000 | ||
const PAYLOAD_IDENTIFIER = 'offline_payload' | ||
|
||
export default class GoRunner { | ||
#env = null | ||
#handlerPath = null | ||
#tmpPath = null | ||
#tmpFile = null | ||
#profile = null | ||
#handle = null | ||
#credentials = null | ||
#goEnv = null | ||
|
||
constructor(funOptions, env, v3Utils) { | ||
const { handlerPath, provider } = funOptions | ||
|
||
this.#env = env | ||
this.#handlerPath = handlerPath | ||
this.#profile = provider.profile || 'default' | ||
|
||
if (v3Utils) { | ||
this.log = v3Utils.log | ||
this.progress = v3Utils.progress | ||
this.writeText = v3Utils.writeText | ||
this.v3Utils = v3Utils | ||
} | ||
|
||
// Make sure we have the mock-lambda runner | ||
sync('go', ['get', 'github.com/icarus-sullivan/mock-lambda@e065469']) | ||
} | ||
|
||
async cleanup() { | ||
// Clean up session timeout | ||
if (this.#handle !== null) { | ||
clearTimeout(this.#handle) | ||
} | ||
|
||
await this.cleanArtifacts() | ||
} | ||
|
||
_parsePayload(value) { | ||
const log = [] | ||
let payload | ||
|
||
for (const item of value.split(EOL)) { | ||
if (item.indexOf(PAYLOAD_IDENTIFIER) === -1) { | ||
log.push(item) | ||
} else if (item.indexOf(PAYLOAD_IDENTIFIER) !== -1) { | ||
try { | ||
const { | ||
offline_payload: { success, error }, | ||
} = parse(item) | ||
if (success) { | ||
payload = success | ||
} else if (error) { | ||
payload = error | ||
} | ||
} catch (err) { | ||
// @ignore | ||
} | ||
} | ||
} | ||
|
||
// Log to console in case engineers want to see the rest of the info | ||
if (this.log) { | ||
this.log(log.join(EOL)) | ||
} else { | ||
console.log(log.join(EOL)) | ||
} | ||
|
||
return payload | ||
} | ||
|
||
async cleanArtifacts() { | ||
try { | ||
await rmdir(this.#tmpPath, { recursive: true }) | ||
} catch (e) { | ||
// @ignore | ||
} | ||
|
||
this.#tmpFile = null | ||
this.#tmpPath = null | ||
} | ||
|
||
clearCredentials() { | ||
this.#credentials = null | ||
this.#handle = null | ||
} | ||
|
||
async run(event, context) { | ||
const { dir } = pathParse(this.#handlerPath) | ||
const handlerCodeRoot = dir.split(sep).slice(0, -1).join(sep) | ||
const handlerCode = await readFile(`${this.#handlerPath}.go`, 'utf8') | ||
this.#tmpPath = resolve(handlerCodeRoot, 'tmp') | ||
this.#tmpFile = resolve(this.#tmpPath, 'main.go') | ||
|
||
const out = handlerCode.replace( | ||
'"github.com/aws/aws-lambda-go/lambda"', | ||
'lambda "github.com/icarus-sullivan/mock-lambda"', | ||
) | ||
|
||
try { | ||
await mkdir(this.#tmpPath, { recursive: true }) | ||
} catch (e) { | ||
// @ignore | ||
} | ||
|
||
try { | ||
await writeFile(this.#tmpFile, out, 'utf8') | ||
} catch (e) { | ||
// @ignore | ||
} | ||
|
||
// Get go env to run this locally | ||
if (!this.#goEnv) { | ||
const goEnvResponse = await execa('go', ['env'], { | ||
stdio: 'pipe', | ||
encoding: 'utf-8', | ||
}) | ||
|
||
const goEnvString = goEnvResponse.stdout || goEnvResponse.stderr | ||
this.#goEnv = goEnvString.split(EOL).reduce((a, b) => { | ||
const [k, v] = b.split('="') | ||
// eslint-disable-next-line no-param-reassign | ||
a[k] = v ? v.slice(0, -1) : '' | ||
return a | ||
}, {}) | ||
} | ||
|
||
// Get session credentials to pass to go | ||
if (!this.#credentials) { | ||
const sts = new STS() | ||
|
||
const { Credentials } = await sts | ||
.getSessionToken({ | ||
DurationSeconds: MIN_ALLOWED_SESSION_DURATION_S, // 900-inf | ||
}) | ||
.promise() | ||
|
||
this.#credentials = Credentials | ||
this.#handle = setTimeout( | ||
this.clearCredentials.bind(this), | ||
SESSION_TIMEOUT_MS, | ||
) | ||
} | ||
|
||
// Remove our root, since we want to invoke go relatively | ||
const cwdPath = `${this.#tmpFile}`.replace(`${cwd()}${sep}`, '') | ||
const cp = await execa(`go`, ['run', cwdPath], { | ||
stdio: 'pipe', | ||
env: { | ||
...this.#env, | ||
...this.#goEnv, | ||
AWS_ACCESS_KEY_ID: this.#credentials.AccessKeyId, | ||
AWS_SECRET_ACCESS_KEY: this.#credentials.SecretAccessKey, | ||
AWS_SESSION_TOKEN: this.#credentials.SessionToken, | ||
AWS_PROFILE: this.#profile, | ||
AWS_LAMBDA_LOG_GROUP_NAME: context.logGroupName, | ||
AWS_LAMBDA_LOG_STREAM_NAME: context.logStreamName, | ||
AWS_LAMBDA_FUNCTION_NAME: context.functionName, | ||
AWS_LAMBDA_FUNCTION_MEMORY_SIZE: context.memoryLimitInMB, | ||
AWS_LAMBDA_FUNCTION_VERSION: context.functionVersion, | ||
LAMBDA_EVENT: stringify(event), | ||
LAMBDA_CONTEXT: stringify(context), | ||
IS_LAMBDA_AUTHORIZER: | ||
event.type === 'REQUEST' || event.type === 'TOKEN', | ||
IS_LAMBDA_REQUEST_AUTHORIZER: event.type === 'REQUEST', | ||
IS_LAMBDA_TOKEN_AUTHORIZER: event.type === 'TOKEN', | ||
PATH: process.env.PATH, | ||
}, | ||
encoding: 'utf-8', | ||
}) | ||
|
||
// Clean up after we created the temporary file | ||
await this.cleanArtifacts() | ||
|
||
if (cp.stderr) { | ||
throw new Error(cp.stderr) | ||
} | ||
|
||
return this._parsePayload(cp.stdout) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './GoRunner.js' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import execa from 'execa' | ||
|
||
export default async function checkGoVersion() { | ||
let goVersion | ||
try { | ||
const { stdout } = await execa('go', ['version']) | ||
if (stdout.match(/go1.\d+/g)) { | ||
goVersion = '1.x' | ||
} | ||
} catch (err) { | ||
// @ignore | ||
} | ||
|
||
return goVersion | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module serverless-offline-go1.x-test | ||
|
||
go 1.13 | ||
|
||
require ( | ||
github.com/aws/aws-lambda-go v1.28.0 | ||
github.com/icarus-sullivan/mock-lambda v0.0.0-20220114085425-44091545252e // indirect | ||
github.com/urfave/cli v1.22.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||
github.com/aws/aws-lambda-go v1.13.2 h1:8lYuRVn6rESoUNZXdbCmtGB4bBk4vcVYojiHjE4mMrM= | ||
github.com/aws/aws-lambda-go v1.13.2/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= | ||
github.com/aws/aws-lambda-go v1.28.0 h1:fZiik1PZqW2IyAN4rj+Y0UBaO1IDFlsNo9Zz/XnArK4= | ||
github.com/aws/aws-lambda-go v1.28.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU= | ||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | ||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/icarus-sullivan/mock-lambda v0.0.0-20220114085425-44091545252e h1:cPv6jHZPqHlu73UmtFEVPRNHGnSrd43OKwpQKVktLcs= | ||
github.com/icarus-sullivan/mock-lambda v0.0.0-20220114085425-44091545252e/go.mod h1:2iuLAENWZqxe/B6XUDWw/3ioQ9d1fwhgFTlwVeIBpzY= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | ||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { platform } from 'os' | ||
import { resolve } from 'path' | ||
import fetch from 'node-fetch' | ||
import { joinUrl, setup, teardown } from '../../_testHelpers/index.js' | ||
|
||
jest.setTimeout(180000) | ||
|
||
const _describe = | ||
process.env.GO1X_DETECTED && platform() !== 'win32' ? describe : describe.skip | ||
|
||
_describe('Go 1.x with GoRunner', () => { | ||
// init | ||
beforeAll(() => | ||
setup({ | ||
servicePath: resolve(__dirname), | ||
}), | ||
) | ||
|
||
// cleanup | ||
afterAll(() => teardown()) | ||
|
||
// | ||
;[ | ||
{ | ||
description: 'should work with go1.x without docker', | ||
expected: { | ||
message: 'Hello Go 1.x!', | ||
}, | ||
path: '/dev/hello', | ||
}, | ||
].forEach(({ description, expected, path }) => { | ||
test(description, async () => { | ||
const url = joinUrl(TEST_BASE_URL, path) | ||
const response = await fetch(url) | ||
const json = await response.json() | ||
|
||
expect(json).toEqual(expected) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-lambda-go/events" | ||
"github.com/aws/aws-lambda-go/lambda" | ||
) | ||
|
||
func Handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { | ||
return events.APIGatewayProxyResponse{ | ||
Body: "{\"message\": \"Hello Go 1.x!\"}", | ||
StatusCode: 200, | ||
}, nil | ||
} | ||
|
||
func main() { | ||
lambda.Start(Handler) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
service: docker-go-1.x-tests | ||
|
||
plugins: | ||
- ../../../../ | ||
|
||
provider: | ||
memorySize: 128 | ||
name: aws | ||
region: us-east-1 # default | ||
runtime: go1.x | ||
stage: dev | ||
versionFunctions: false | ||
|
||
functions: | ||
hello: | ||
events: | ||
- http: | ||
method: get | ||
path: hello | ||
handler: hello/main.go |