diff --git a/packages/deployment/lib/lambda.js b/packages/deployment/lib/lambda.js index 20ffcab3276..29f4f9a5960 100644 --- a/packages/deployment/lib/lambda.js +++ b/packages/deployment/lib/lambda.js @@ -10,7 +10,6 @@ const yauzl = require('yauzl'); const { Lambda } = require('kes'); - /** * A sub-class of the Kes Lambda class that changes * how kes handles Lambda function compression and @@ -42,18 +41,19 @@ class UpdatedLambda extends Lambda { */ async zipLambda(lambda) { - let msg = `Zipping ${lambda.local}`; // skip if the file with the same hash is zipped // and is a valid zip file - if (fs.existsSync(lambda.local)) { + if (await fs.pathExists(lambda.local)) { try { await (util.promisify(yauzl.open))(lambda.local); // Verify yauzl can open the .zip file return Promise.resolve(lambda); } catch (e) { - console.log(`${lambda.local} appears to be an invalid zip file, and will be re-built`); + console.log(`${lambda.local} is invalid and will be rebuilt`); } } + + let msg = `Zipping ${lambda.local}`; const fileList = [lambda.source]; if (lambda.useMessageAdapter) { const kesFolder = path.join(this.config.kesFolder, 'build', 'adapter'); @@ -62,12 +62,16 @@ class UpdatedLambda extends Lambda { } console.log(`${msg} for ${lambda.name}`); - return utils.zip(lambda.local, fileList) - .then(() => lambda) - .catch((e) => { - console.log(`Error zipping ${e}`); - throw (e); - }); + + try { + await utils.zip(lambda.local, fileList); + } + catch (e) { + console.log(`Error zipping ${e}`); + throw e; + } + + return lambda; } /** diff --git a/packages/deployment/test/test_lambda.js b/packages/deployment/test/test_lambda.js index 1c6a920e327..54d66d4fcb0 100644 --- a/packages/deployment/test/test_lambda.js +++ b/packages/deployment/test/test_lambda.js @@ -88,104 +88,92 @@ test.serial('zipLambda: works for lambda using message adapter', async (t) => { ); }); -test.serial( - `zipLambda: given an invalid zip file generated from a previous run, - a new valid lambda file is generated`, - async (t) => { - t.context.lambda.useMessageAdapter = true; - const lambdaLocalOrigin = t.context.lambda.local; - const lambdaRemoteOrigin = t.context.lambda.remote; - - // put an empty lambda zip file there as the result of the previous run - const existingLambdaLocal = path.join( - path.dirname(t.context.lambda.local), - `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.local)}` - ); - - await fs.writeFile(existingLambdaLocal, 'hello'); - t.is(fs.statSync(existingLambdaLocal).size, 5); - - const testLambda = new Lambda(t.context.config); - await testLambda.zipLambda(testLambda.buildS3Path(t.context.lambda)); - t.truthy(fs.statSync(t.context.lambda.local)); - t.true(fs.statSync(t.context.lambda.local).size > 5); - t.is(t.context.lambda.local, existingLambdaLocal); - - t.is( - path.basename(t.context.lambda.local), - `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaLocalOrigin)}` - ); - t.is( - path.basename(t.context.lambda.remote), - `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaRemoteOrigin)}` - ); - } -); - - -test.serial( - `zipLambda: for lambda using message adapter, no new file is generated - if the task and message adapter are not updated`, - async (t) => { - t.context.lambda.useMessageAdapter = true; - - // put a lambda zip file there as the result of the previous run - const existingLambdaLocal = path.join( - path.dirname(t.context.lambda.local), - `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.local)}` - ); - - const existingLambdaRemote = path.join( - path.dirname(t.context.lambda.remote), - `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.remote)}` - ); - - await fs.copy(zipFixturePath, existingLambdaLocal); - t.is(fs.statSync(existingLambdaLocal).size, zipFixtureSize); - - const testLambda = new Lambda(t.context.config); - await testLambda.zipLambda(testLambda.buildS3Path(t.context.lambda)); - t.truthy(fs.statSync(t.context.lambda.local)); - t.is(fs.statSync(t.context.lambda.local).size, zipFixtureSize); - t.is(t.context.lambda.local, existingLambdaLocal); - t.is(t.context.lambda.remote, existingLambdaRemote); - } -); - -test.serial( - `zipLambda: for lambda using message adapter, a new file is created - if the message adapter is updated`, - async (t) => { - t.context.lambda.useMessageAdapter = true; - const lambdaLocalOrigin = t.context.lambda.local; - const lambdaRemoteOrigin = t.context.lambda.remote; - - // put an empty lambda zip file there as the result of the previous run - const existingLambdaLocal = path.join( - path.dirname(t.context.lambda.local), - `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.local)}` - ); - - await fs.writeFile(existingLambdaLocal, 'hello'); - t.is(fs.statSync(existingLambdaLocal).size, 5); - - // message adapter is updated, a new lambda zip file is generated - const adapterHashOrigin = Lambda.messageAdapterZipFileHash; - Lambda.messageAdapterZipFileHash = `${adapterHashOrigin}123`; - - const testLambda = new Lambda(t.context.config); - await testLambda.zipLambda(testLambda.buildS3Path(t.context.lambda)); - t.truthy(fs.statSync(t.context.lambda.local)); - t.true(fs.statSync(t.context.lambda.local).size > 5); - t.not(t.context.lambda.local, existingLambdaLocal); - - t.is( - path.basename(t.context.lambda.local), - `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaLocalOrigin)}` - ); - t.is( - path.basename(t.context.lambda.remote), - `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaRemoteOrigin)}` - ); - } -); +test.serial('zipLambda: given an invalid zip file generated from a previous run, a new valid lambda file is generated', async (t) => { // eslint-disable-line max-len + t.context.lambda.useMessageAdapter = true; + const lambdaLocalOrigin = t.context.lambda.local; + const lambdaRemoteOrigin = t.context.lambda.remote; + + // put an empty lambda zip file there as the result of the previous run + const existingLambdaLocal = path.join( + path.dirname(t.context.lambda.local), + `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.local)}` + ); + + await fs.writeFile(existingLambdaLocal, 'hello'); + t.is(fs.statSync(existingLambdaLocal).size, 5); + + const testLambda = new Lambda(t.context.config); + await testLambda.zipLambda(testLambda.buildS3Path(t.context.lambda)); + t.truthy(fs.statSync(t.context.lambda.local)); + t.true(fs.statSync(t.context.lambda.local).size > 5); + t.is(t.context.lambda.local, existingLambdaLocal); + + t.is( + path.basename(t.context.lambda.local), + `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaLocalOrigin)}` + ); + t.is( + path.basename(t.context.lambda.remote), + `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaRemoteOrigin)}` + ); +}); + + +test.serial('zipLambda: for lambda using message adapter, no new file is generated if the task and message adapter are not updated', async (t) => { // eslint-disable-line max-len + t.context.lambda.useMessageAdapter = true; + + // put a lambda zip file there as the result of the previous run + const existingLambdaLocal = path.join( + path.dirname(t.context.lambda.local), + `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.local)}` + ); + + const existingLambdaRemote = path.join( + path.dirname(t.context.lambda.remote), + `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.remote)}` + ); + + await fs.copy(zipFixturePath, existingLambdaLocal); + t.is(fs.statSync(existingLambdaLocal).size, zipFixtureSize); + + const testLambda = new Lambda(t.context.config); + await testLambda.zipLambda(testLambda.buildS3Path(t.context.lambda)); + t.truthy(fs.statSync(t.context.lambda.local)); + t.is(fs.statSync(t.context.lambda.local).size, zipFixtureSize); + t.is(t.context.lambda.local, existingLambdaLocal); + t.is(t.context.lambda.remote, existingLambdaRemote); +}); + +test.serial('zipLambda: for lambda using message adapter, a new file is created if the message adapter is updated', async (t) => { // eslint-disable-line max-len + t.context.lambda.useMessageAdapter = true; + const lambdaLocalOrigin = t.context.lambda.local; + const lambdaRemoteOrigin = t.context.lambda.remote; + + // put an empty lambda zip file there as the result of the previous run + const existingLambdaLocal = path.join( + path.dirname(t.context.lambda.local), + `${Lambda.messageAdapterZipFileHash}-${path.basename(t.context.lambda.local)}` + ); + + await fs.writeFile(existingLambdaLocal, 'hello'); + t.is(fs.statSync(existingLambdaLocal).size, 5); + + // message adapter is updated, a new lambda zip file is generated + const adapterHashOrigin = Lambda.messageAdapterZipFileHash; + Lambda.messageAdapterZipFileHash = `${adapterHashOrigin}123`; + + const testLambda = new Lambda(t.context.config); + await testLambda.zipLambda(testLambda.buildS3Path(t.context.lambda)); + t.truthy(fs.statSync(t.context.lambda.local)); + t.true(fs.statSync(t.context.lambda.local).size > 5); + t.not(t.context.lambda.local, existingLambdaLocal); + + t.is( + path.basename(t.context.lambda.local), + `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaLocalOrigin)}` + ); + t.is( + path.basename(t.context.lambda.remote), + `${Lambda.messageAdapterZipFileHash}-${path.basename(lambdaRemoteOrigin)}` + ); +});