UNPKG

9.62 kBJavaScriptView Raw
1'use strict'
2
3const assert = require('chai').assert
4const path = require('path')
5const fs = require('fs-extra')
6const spawn = require('child_process').spawn
7const execSync = require('child_process').execSync
8const nodeLambdaPath = path.join(__dirname, '..', 'bin', 'node-lambda')
9
10/* global before, after, describe, it */
11// The reason for specifying the node command in this test is to support Windows.
12describe('bin/node-lambda', () => {
13 describe('node-lambda run', () => {
14 const _testMain = (expectedValues, done) => {
15 const run = spawn('node', [
16 nodeLambdaPath, 'run',
17 '--handler', '__test.handler',
18 '--eventFile', 'event.json'
19 ])
20 let stdoutString = ''
21 let stderrString = ''
22 run.stdout.on('data', (data) => {
23 stdoutString += data.toString().replace(/\r|\n/g, '')
24 })
25 run.stderr.on('data', (data) => {
26 stderrString += data.toString().replace(/\r|\n/g, '')
27 })
28
29 run.on('exit', (code) => {
30 if (expectedValues.stdoutRegExp) {
31 assert.match(stdoutString, expectedValues.stdoutRegExp)
32 }
33 if (expectedValues.stderrRegExp) {
34 assert.match(stderrString, expectedValues.stderrRegExp)
35 }
36 assert.equal(code, expectedValues.exitCode)
37 done()
38 })
39 }
40
41 const _generateEventFile = (eventObj) => {
42 fs.writeFileSync('event.json', JSON.stringify(eventObj))
43 }
44
45 before(() => {
46 execSync(`node ${nodeLambdaPath} setup`)
47 fs.copy(path.join(__dirname, 'handler', 'index.js'), '__test.js')
48 })
49
50 after(() => {
51 [
52 '.env',
53 'context.json',
54 'event.json',
55 'deploy.env',
56 'event_sources.json',
57 '__test.js'
58 ].forEach((file) => fs.unlinkSync(file))
59 })
60
61 describe('node-lambda run (Handler only sync processing)', () => {
62 const eventObj = {
63 asyncTest: false,
64 callbackWaitsForEmptyEventLoop: true // True is the default value of Lambda
65 }
66
67 it('`node-lambda run` exitCode is `0` (callback(null))', (done) => {
68 _generateEventFile(Object.assign(eventObj, {
69 callbackCode: 'callback(null);'
70 }))
71 _testMain({ stdoutRegExp: /Success:$/, exitCode: 0 }, done)
72 })
73
74 it('`node-lambda run` exitCode is `0` (callback(null, "text"))', (done) => {
75 _generateEventFile(Object.assign(eventObj, {
76 callbackCode: 'callback(null, "text");'
77 }))
78 _testMain({ stdoutRegExp: /Success:"text"$/, exitCode: 0 }, done)
79 })
80
81 it('`node-lambda run` exitCode is `255` (callback(new Error("e")))', (done) => {
82 _generateEventFile(Object.assign(eventObj, {
83 callbackCode: 'callback(new Error("e"));'
84 }))
85 _testMain({ stdoutRegExp: /Error: Error: e$/, exitCode: 255 }, done)
86 })
87 })
88
89 describe('node-lambda run (Handler includes async processing)', () => {
90 describe('callbackWaitsForEmptyEventLoop = true', function () {
91 this.timeout(5000) // give it time to setTimeout
92
93 const eventObj = {
94 asyncTest: true,
95 callbackWaitsForEmptyEventLoop: true
96 }
97
98 it('`node-lambda run` exitCode is `0` (callback(null))', (done) => {
99 _generateEventFile(Object.assign(eventObj, {
100 callbackCode: 'callback(null);'
101 }))
102 _testMain({ stdoutRegExp: /Success:sleep 3500 msec$/, exitCode: 0 }, done)
103 })
104
105 it('`node-lambda run` exitCode is `0` (callback(null, "text"))', (done) => {
106 _generateEventFile(Object.assign(eventObj, {
107 callbackCode: 'callback(null, "text");'
108 }))
109 _testMain({ stdoutRegExp: /Success:"text"sleep 3500 msec$/, exitCode: 0 }, done)
110 })
111
112 it('`node-lambda run` exitCode is `255` (callback(new Error("e")))', (done) => {
113 _generateEventFile(Object.assign(eventObj, {
114 callbackCode: 'callback(new Error("e"));'
115 }))
116 _testMain({ stdoutRegExp: /Error: Error: esleep 3500 msec$/, exitCode: 255 }, done)
117 })
118 })
119
120 describe('callbackWaitsForEmptyEventLoop = false', () => {
121 const eventObj = {
122 asyncTest: true,
123 callbackWaitsForEmptyEventLoop: false
124 }
125
126 it('`node-lambda run` exitCode is `0` (callback(null))', (done) => {
127 _generateEventFile(Object.assign(eventObj, {
128 callbackCode: 'callback(null);'
129 }))
130 _testMain({ stdoutRegExp: /Success:$/, exitCode: 0 }, done)
131 })
132
133 it('`node-lambda run` exitCode is `0` (callback(null, "text"))', (done) => {
134 _generateEventFile(Object.assign(eventObj, {
135 callbackCode: 'callback(null, "text");'
136 }))
137 _testMain({ stdoutRegExp: /Success:"text"$/, exitCode: 0 }, done)
138 })
139
140 it('`node-lambda run` exitCode is `255` (callback(new Error("e")))', (done) => {
141 _generateEventFile(Object.assign(eventObj, {
142 callbackCode: 'callback(new Error("e"));'
143 }))
144 _testMain({ stdoutRegExp: /Error: Error: e$/, exitCode: 255 }, done)
145 })
146 })
147 })
148
149 describe('node-lambda run (Runtime is not supported)', () => {
150 const eventObj = {
151 asyncTest: false,
152 callbackWaitsForEmptyEventLoop: true // True is the default value of Lambda
153 }
154
155 before(() => {
156 process.env.AWS_RUNTIME = 'test'
157 })
158 after(() => {
159 process.env.AWS_RUNTIME = 'nodejs6.10'
160 })
161
162 it('`node-lambda run` exitCode is `254` (callback(null))', (done) => {
163 _generateEventFile(Object.assign(eventObj, {
164 callbackCode: 'callback(null);'
165 }))
166 _testMain({
167 stderrRegExp: /^Runtime \[test\] is not supported\.$/,
168 exitCode: 254
169 }, done)
170 })
171 })
172
173 describe('node-lambda run (Multiple events))', () => {
174 const eventObj = [{
175 asyncTest: false,
176 callbackWaitsForEmptyEventLoop: true,
177 callbackCode: 'callback(null);',
178 no: 1
179 }, {
180 asyncTest: false,
181 callbackWaitsForEmptyEventLoop: true,
182 callbackCode: 'callback(null);',
183 no: 2
184 }, {
185 asyncTest: false,
186 callbackWaitsForEmptyEventLoop: true,
187 callbackCode: 'callback(null);',
188 no: 3
189 }]
190
191 it('`node-lambda run` exitCode is `0`', function (done) {
192 this.timeout(10000) // give it time to multiple executions
193 _generateEventFile(eventObj)
194 _testMain({
195 stdoutRegExp: / no: 1 .+ no: 2 .+ no: 3 .+Success:/,
196 exitCode: 0
197 }, done)
198 })
199 })
200
201 describe('node-lambda run (disable Multiple events))', () => {
202 const eventObj = [{
203 asyncTest: false,
204 callbackWaitsForEmptyEventLoop: true,
205 callbackCode: 'callback(null);',
206 no: 1
207 }, {
208 asyncTest: false,
209 callbackWaitsForEmptyEventLoop: true,
210 callbackCode: 'callback(null);',
211 no: 2
212 }, {
213 asyncTest: false,
214 callbackWaitsForEmptyEventLoop: true,
215 callbackCode: 'callback(null);',
216 no: 3
217 }]
218
219 it('`node-lambda run` exitCode is `0`', function (done) {
220 this.timeout(10000) // give it time to multiple executions
221
222 _generateEventFile(eventObj)
223 const run = spawn('node', [
224 nodeLambdaPath, 'run',
225 '--handler', 'index.handler',
226 '--eventFile', 'event.json',
227 '-M', 'false'
228 ])
229 let stdoutString = ''
230 run.stdout.on('data', (data) => {
231 stdoutString += data.toString().replace(/\r|\n/g, '')
232 })
233
234 run.on('exit', (code) => {
235 const expected = 'Running index.handler==================================event ' +
236 '[ { asyncTest: false, callbackWaitsForEmptyEventLoop: true, callbackCode: \'callback(null);\', no: 1 }, ' +
237 '{ asyncTest: false, callbackWaitsForEmptyEventLoop: true, callbackCode: \'callback(null);\', no: 2 }, ' +
238 '{ asyncTest: false, callbackWaitsForEmptyEventLoop: true, callbackCode: \'callback(null);\', no: 3 } ]' +
239 '==================================Stopping index.handlerSuccess:'
240
241 assert.equal(stdoutString, expected)
242 assert.equal(code, 0)
243 done()
244 })
245 })
246 })
247 })
248
249 describe('node-lambda duplicate check of short option', () => {
250 const duplicateCheckTestFunc = (type, done) => {
251 const cmd = spawn('node', [nodeLambdaPath, type, '-h'])
252 let stdoutString = ''
253 cmd.stdout.on('data', (data) => {
254 stdoutString += data.toString()
255 })
256
257 cmd.on('exit', (code) => {
258 assert.equal(code, 0)
259
260 const shortOptions = stdoutString.split('\n').filter(line => {
261 return line.match(/^\s+-/)
262 }).map(line => {
263 return line.split(/\s+/)[1]
264 })
265 const uniqueShortOptions = shortOptions.filter((option, index, array) => {
266 return array.indexOf(option) === index
267 })
268 assert.equal(shortOptions.length, uniqueShortOptions.length)
269 done()
270 })
271 }
272
273 ['deploy', 'run', 'setup'].forEach(type => {
274 it(`cmd:${type}`, (done) => {
275 duplicateCheckTestFunc(type, done)
276 })
277 })
278 })
279
280 describe('node-lambda --version', () => {
281 const packageJson = require(path.join(__dirname, '..', 'package.json'))
282 it('The current version is displayed', () => {
283 const ret = execSync(`node ${nodeLambdaPath} --version`)
284 assert.equal(ret.toString().trim(), packageJson.version)
285 })
286 })
287})