UNPKG

@webscale-networks/cloudedge-handlers

Version:

Webscale Networks CloudEDGE Handlers for cloud-agnostic edge function execution

168 lines (155 loc) 5.62 kB
const child_process = require('child_process'); const fs = require('fs'); const fsExtra = require('fs-extra'); const os = require('os'); const path = require('path'); const { argv } = require('process'); const _ = require('lodash'); // Reference: https://nodejs.org/api/process.html#process_exit_codes. const ERROR_CODE = 1; const INVALID_ARGUMENT_CODE = 9; const SUCCESS_CODE = 0; const HANDLER_PACKAGE_PATH = path.join('node_modules', '@webscale-networks', 'cloudedge-handlers'); // Normalizes the user's provider name. // Currently, the only accepted provider is 'aws'. providerName = (provider) => { normalizedProvider = provider.toLowerCase(); if (normalizedProvider == 'aws') { return 'lambda'; } return normalizedProvider; }; // Finds the root directory of the user's handler. The root directory will // contain the handler file's manifest.json, which is a required file for // handlers. computeRootDirectory = (scriptPath) => { const directories = path.dirname(scriptPath).split(path.sep); for (let i = directories.length; i >= 0; i--) { const currentPath = directories.slice(0, i).join(path.sep); if (fs.existsSync(path.join(currentPath, 'manifest.json'))) { return currentPath; } } return scriptPath; }; // Returns the location of the @webscale-networks/cloudedge-handlers node // module. computeModuleDirectory = (rootDir) => { return path.join(rootDir, HANDLER_PACKAGE_PATH); }; // Creates a temporary directory, copies in Webscale's handler execution context // node module and returns the temporary directory path. createTemporaryDirectory = (srcDir) => { tmpDir = fs.mkdtempSync( path.join( os.tmpdir(), 'cloudedge-handlers-execution-testing', ), ); fsExtra.copySync(srcDir, tmpDir, { dereference: true }); return tmpDir; }; // Installs the dependencies of Webscale's handler execution context node // module. npmInstall = (tempDir) => { try { process.chdir(tempDir); child_process.execSync('npm install'); } catch (error) { console.error(`${error.message}`); console.error(`${error.stderr}`); console.log(`${error.stdout}`); return error.status; } return SUCCESS_CODE; }; // Runs the cloud provider specific handler tests and returns the exit code of // the test run. runCloudProviderTests = (provider, rootDir) => { try { const vars = _.cloneDeep(process.env); vars['HANDLER_ROOT_DIR'] = rootDir; child_process.execSync( `jest execution_testing/${provider}/src/index.js --testMatch=**/*.js`, { env: vars }, ); } catch (error) { console.error(`${error.message}`); console.error(`${error.stderr}`); console.log(`${error.stdout}`); return error.status; } return SUCCESS_CODE; }; // Runs the Webscale handler interface tests and returns the exit code of the // test run. runHandlerInterfaceTests = (rootDir) => { try { const vars = _.cloneDeep(process.env); vars['HANDLER_ROOT_DIR'] = rootDir; child_process.execSync( 'jest execution_testing/webscale/src/index.js --testMatch=**/*.js', { env: vars }, ); } catch (error) { console.error(`${error.message}`); console.error(`${error.stderr}`); console.log(`${error.stdout}`); return error.status; } return SUCCESS_CODE; }; // Remove the temporary directory. destroyTemporaryDirectory = (dir) => { fs.rmdirSync(dir, { recursive: true }); }; // Runs all handler unit tests. This includes cloud provider specific tests and // Webscale handler interface tests. Returns an exit code. runTests = (rootDir, provider) => { const handlerDirectory = computeModuleDirectory(rootDir); const tmpDir = createTemporaryDirectory(handlerDirectory); const installExitCode = npmInstall(tmpDir); if (installExitCode == SUCCESS_CODE) { providerTestsExitCode = runCloudProviderTests(provider, rootDir); if (providerTestsExitCode != SUCCESS_CODE) { statusCode = providerTestsExitCode; } else { handlerInterfaceTestsExitCode = runHandlerInterfaceTests(rootDir); if (handlerInterfaceTestsExitCode != SUCCESS_CODE) { statusCode = handlerInterfaceTestsExitCode; } else { statusCode = SUCCESS_CODE; } } } else { statusCode = installExitCode; } destroyTemporaryDirectory(tmpDir); return statusCode; }; // Jest is configured not to run tests found in node package's node_modules. As // a result, this script will copy Webscale's handler execution context module // into a temporary directory, run the included cloud provider specific and // Webscale handler interface tests, report to standard out and standard error. // This only returns a 0 status code if all tests pass. // // For more information on Jest, see: // https://github.com/facebook/jest/issues/11781 // https://github.com/facebook/jest/issues/5039 try { if (argv.length != 3) { console.error(` Usage: node run-execution-testing.js <cloud-provider> where <cloud-provider> is one of ('aws'). `); process.exit(INVALID_ARGUMENT_CODE); } const args = process.argv.slice(1); const provider = providerName(args[1]); const rootDir = computeRootDirectory(args[0]); process.exit(runTests(rootDir, provider)); } catch (err) { console.error(err); process.exit(ERROR_CODE); }