├── .gitignore ├── .lintstagedrc ├── .prettierrc ├── LICENSE.md ├── README.md ├── adash.js ├── doc └── images │ ├── cli.jpg │ ├── cli_testp.gif │ ├── monitor.gif │ ├── monitor.jpg │ ├── monitor_path.jpg │ └── watch.gif ├── package.json └── src ├── actions ├── addp.js ├── adds.js ├── index.js ├── monitor.js ├── testg.js └── testp.js └── helpers ├── api.js ├── fail.js ├── pass.js ├── setupStore.js └── testResultHandler.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | # Distributions 64 | dist -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "**/*.+(js|jsx|json|md)": [ 3 | "prettier --write", 4 | "git add" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": false, 4 | "jsxBracketSameLine": false, 5 | "printWidth": 80, 6 | "proseWrap": "always", 7 | "semi": false, 8 | "singleQuote": true, 9 | "tabWidth": 2, 10 | "trailingComma": "all", 11 | "useTabs": false 12 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2020 Felipe de Almeida Silva 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ADASH Cli 2 | 3 | ADASH Cli is a tool for ABAP developers. 4 | It allows easy monitoring of packages tests and integration of ABAP tests into CI/CD pipelines. 5 | It works in conjunction with [ADASH Services](https://github.com/xinitrc86/adash-services) installed and set up at your(s) ABAP backend(s). 6 | 7 | Its intention is to help teams monitor and nurture their code bases, enable CI/CD pipelines by providing an easy way of running ABAP Unit tests from anywhere. It also provides a cool watch feature for your code under test! 8 | 9 | ## Install 10 | 11 | ```bash 12 | # with npm 13 | npm install adash-cli -g 14 | 15 | ``` 16 | 17 | ## Usage 18 | 19 | ### Monitor/Watch 20 | 21 | ```bash 22 | 23 | adash adds dev -host https://dev-abap.org:8200 -a sap/zadash -c 200 24 | adash addp zbc_adash -s dev 25 | ... 26 | adash addp zdemo -s dev 27 | adash mon dev 28 | ``` 29 | **Monitor** 30 | 31 | ![Monitor](https://raw.githubusercontent.com/xinitrc86/adash-cli/master/doc/images/monitor.gif) 32 | 33 | **Watch** 34 | 35 | ![Watch](https://raw.githubusercontent.com/xinitrc86/adash-cli/master/doc/images/watch.gif) 36 | 37 | ### CI/CD Pipelines 38 | 39 | Use a simple command for validating your ABAP packages: 40 | 41 | ```bash 42 | 43 | adash adds dev -host https://dev-abap.org:8200 -a sap/zadash 44 | adash testp zadash -s dev -u user -p secret -i 45 | ``` 46 | Or relly on environment variables for a direct 47 | ```bash 48 | adash testp zadash -i 49 | ``` 50 | 51 | ![Cli testp](https://raw.githubusercontent.com/xinitrc86/adash-cli/master/doc/images/cli_testp.gif) 52 | 53 | ## Commands 54 | 55 | ``` 56 | -i --insecure 57 | ``` 58 | Is available at most of the commands that require communication, as most of dev systems have self signed certificates ;) 59 | 60 | ### testp|tp 61 | Usage: testp|tp \ [options]\ 62 | Tests a \ in the given system. 63 | 64 | Examples 65 | ```bash 66 | adash testp ZADASH -s DEV 67 | ``` 68 | 69 | Options:\ 70 | -s, --system [system] System to test the package\ 71 | or\ 72 | -u, --username [username] User for ADASH Services endpoint\ 73 | -p, --password [password] Password for ADASH Services endpoint\ 74 | -h, --host [host] Host:port for ADASH Services endpoint\ 75 | -a, --adash [adash] Endpoint for ADASH services, default /sap/zadash\ 76 | -c, --client [client] System client if services not tagged to a default one 77 | 78 | ### testg|tg 79 | Usage: testg|tg \ [options] 80 | 81 | Tests a \ of packagse in the given system. 82 | 83 | Examples 84 | ```bash 85 | adash testg myPackages -s DEV 86 | ``` 87 | 88 | Options:\ 89 | -s, --system [system] System to test the group\ 90 | or\ 91 | -u, --username [username] User for ADASH Services endpoint\ 92 | -p, --password [password] Password for ADASH Services endpoint\ 93 | -h, --host [host] Host:port for ADASH Services endpoint\ 94 | -a, --adash [adash] Endpoint for ADASH services, default /sap/zadash\ 95 | -c, --client [client] System client if services not tagged to a default one 96 | 97 | ## addsys|adds 98 | Usage: addsys|adds \ [options]\ 99 | Adds a \ that has ADASH Services\ 100 | 101 | Examples 102 | ```bash 103 | adash adds dev -h https://my-server.com:8200 -a sap/zadash -u john -p secret 104 | ``` 105 | 106 | Options:\ 107 | -u, --username [username] User for ADASH Services endpoint\ 108 | -p, --password [password] Password for ADASH Services endpoint\ 109 | -h, --host [host] Host:port for ADASH Services endpoint\ 110 | -a, --adash [adash] Endpoint for ADASH services, default /sap/zadash\ 111 | -c, --client [client] System client if services not tagged to a default one\ 112 | 113 | Systems are stored at HOMEDIR/.adash/systems.json 114 | 115 | ## addpackage|addp 116 | Usage: addpackage|addp \ [options] \ 117 | Adds a \ to the monitoring services of ADASH Services. 118 | 119 | Examples 120 | ```bash 121 | adash addp zadash -g teamA -s dev 122 | ``` 123 | 124 | Options:\ 125 | -g, --group \[group] Test group for monitoring\ 126 | -s, --system [system] System to add package for monitoring\ 127 | or\ 128 | -u, --username [username] User for ADASH Services endpoint\ 129 | -p, --password [password] Password for ADASH Services endpoint\ 130 | -h, --host [host] Host:port for ADASH Services endpoint\ 131 | -a, --adash [adash] Endpoint for ADASH services, default /sap/zadash\ 132 | -c, --client [client] System client if services not tagged to a default one 133 | 134 | \[group]:\ 135 | Creates a group inside the system configuration and allow split monitoring of packages.\ 136 | * group 1:\ 137 | ** package a\ 138 | ** package b 139 | 140 | * group 2:\ 141 | ** package c\ 142 | ** package a 143 | 144 | Backend will always store all added packages for monitoring. 145 | 146 | ## monitor|mon 147 | Usage: monitor|mon \[group] [options] 148 | Opens the \[group] of packages for monitoring. When no group is provided, the monitor will list all packages being monitored by ADASH in the backend. It requires the addition of a system widh adds (for now). 149 | 150 | Examples 151 | ```bash 152 | adash mon myPackages -s dev 153 | ``` 154 | or, to monitor all packages added to adash 155 | ```bash 156 | adash mon -s dev 157 | ``` 158 | 159 | 160 | Options:\ 161 | -s, --system \ System for the monitoring. 162 | 163 | Monitors a group. It uses [ADASH Monitor](https://github.com/xinitrc86/adash-monitor), connecting to the target system and displaying the last test results for the given group. 164 | 165 | ## Environment variables 166 | 167 | ADASH Cli will look for the following environment variables when not provided trough the command line. 168 | 169 | ADASH_USERNAME\ 170 | ADASH_PASSWORD\ 171 | ADASH_HOST\ 172 | ADASH_ENDPOINT\ 173 | ADASH_CLIENT 174 | 175 | This happens individually, meaning that your system setup may have the host and end point, the user is through -u and the password through ADASH_PASSORD environment variable. 176 | 177 | ### Help/Contribution 178 | 179 | ## Help Needed! 180 | Any help or even suggestions are welcome. 181 | Specially on downporting the services as they currently relly on too many new syntax elements...anyone knows any abap transpiler? ;) 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /adash.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('dotenv').config(); 4 | 5 | /** 6 | * This is the common way to import a package in NodeJS. 7 | * The CommonJS module system is used. 8 | */ 9 | 10 | const adash = require('commander'); 11 | const testPackage = require('./src/actions/testp'); 12 | const testGroup = require('./src/actions/testg'); 13 | const monitor = require('./src/actions/monitor'); 14 | const addSys = require('./src/actions/adds'); 15 | const addPackage = require('./src/actions/addp') 16 | const {version} = require('./package'); 17 | 18 | /** 19 | * Without using `.command`, this works as the root command. 20 | */ 21 | adash 22 | .version(version, '-v, --version'); 23 | adash 24 | .command('testp') 25 | .alias('tp') 26 | .description('Tests a package in a system') 27 | .arguments('') 28 | .option('-s, --system [system', 'Set up system for test to run') 29 | .option('-i, --insecure [insecure]', 'Bypass local SSL verification') 30 | .option('-u, --username [username]', 'User for endpoint') 31 | .option('-p, --password [password]', 'Password for endpoint') 32 | .option('-h, --host [host]','Host & port Netweaver ') 33 | .option('-a, --adash [adash]', 'Path to ADASH on host, default /sap/zadash') 34 | .option('-c, --client [client]', 'System client if services not tagged to a default one') 35 | .action(testPackage); 36 | adash 37 | .command('testg') 38 | .alias('tg') 39 | .description('Tests group in a system') 40 | .arguments('') 41 | .option('-s, --system [system]', 'Set up system for test to run') 42 | .option('-i, --insecure [insecure]', 'Bypass local SSL verification') 43 | .option('-u, --username [username]', 'User for endpoint') 44 | .option('-p, --password [password]', 'Password for endpoint') 45 | .option('-h, --host [host]','Host & port Netweaver ') 46 | .option('-a, --adash [adash]', 'Path to ADASH on host, default /sap/zadash') 47 | .option('-c, --client [client]', 'System client if services not tagged to a default one') 48 | .action(testGroup); 49 | adash 50 | .command('addsys') 51 | .alias('adds') 52 | .description('Adds a system with ADASH Services') 53 | .arguments('') 54 | .option('-u, --username [username]', 'User for endpoint') 55 | .option('-p, --password <[password]', 'Password for endpoint') 56 | .option('-h, --host ', 'Host & port Netweaver ') 57 | .option('-a, --adash [adash]', 'Path to ADASH on host, default /sap/zadash') 58 | .option('-c, --client [client]', 'System client if services not tagged to a default one') 59 | .action(addSys); 60 | adash 61 | .command('addpackage') 62 | .alias('addp') 63 | .description('Adds a package to be monitored') 64 | .arguments('') 65 | .option('-g, --group ', 'Test group for monitoring') 66 | .option('-s, --system ', 'System for the package to be monitored') 67 | .option('-i, --insecure [insecure]', 'Bypass local SSL verification') 68 | .option('-u, --username [username]', 'User for endpoint') 69 | .option('-p, --password [password]', 'Password for endpoint') 70 | .option('-h, --host [host]','Host & port Netweaver ') 71 | .option('-a, --adash [adash]', 'Path to ADASH on host, default /sap/zadash') 72 | .option('-c, --client [client]', 'System client if services not tagged to a default one') 73 | 74 | .action(addPackage); 75 | adash 76 | .command('monitor') 77 | .alias('mon') 78 | .description('Display dashboard for the monitored tests') 79 | .arguments('[group]') 80 | .option('-s, --system ', 'System for monitoring') 81 | .action(monitor); 82 | 83 | 84 | /** 85 | * Other commands will be redirected to the help message. 86 | */ 87 | adash.command('*').action(() => adash.help()); 88 | 89 | adash.parse(process.argv); 90 | 91 | if (adash.args.length === 0) { 92 | adash.help() 93 | } 94 | -------------------------------------------------------------------------------- /doc/images/cli.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinitrc86/adash-cli/951e006307642da0592a60ec226ed3001d1e7584/doc/images/cli.jpg -------------------------------------------------------------------------------- /doc/images/cli_testp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinitrc86/adash-cli/951e006307642da0592a60ec226ed3001d1e7584/doc/images/cli_testp.gif -------------------------------------------------------------------------------- /doc/images/monitor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinitrc86/adash-cli/951e006307642da0592a60ec226ed3001d1e7584/doc/images/monitor.gif -------------------------------------------------------------------------------- /doc/images/monitor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinitrc86/adash-cli/951e006307642da0592a60ec226ed3001d1e7584/doc/images/monitor.jpg -------------------------------------------------------------------------------- /doc/images/monitor_path.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinitrc86/adash-cli/951e006307642da0592a60ec226ed3001d1e7584/doc/images/monitor_path.jpg -------------------------------------------------------------------------------- /doc/images/watch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinitrc86/adash-cli/951e006307642da0592a60ec226ed3001d1e7584/doc/images/watch.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "adash-cli", 3 | "version": "0.0.4", 4 | "description": "ADASH Cli for ADASH Services", 5 | "main": "adash.js", 6 | "bin": { 7 | "adash": "/adash.js" 8 | }, 9 | "repository": { 10 | "type" : "git", 11 | "url" : "https://github.com/xinitrc86/adash-cli.git" 12 | }, 13 | "author": "xinitrc86 ", 14 | "license": "MIT", 15 | "dependencies": { 16 | "@ui5/server": "^2.0.3", 17 | "axios": "^0.19.2", 18 | "chalk": "^4.1.0", 19 | "commander": "^2.20.0", 20 | "dotenv": "^8.2.0", 21 | "fs": "0.0.1-security", 22 | "https": "^1.0.0", 23 | "open": "^7.0.4", 24 | "path": "^0.12.7", 25 | "ui5-middleware-route-proxy": "^1.0.7" 26 | }, 27 | "devDependencies": { 28 | "eslint": "^7.2.0" 29 | }, 30 | "scripts": { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/actions/addp.js: -------------------------------------------------------------------------------- 1 | const setupStore = require('../helpers/setupStore') 2 | const api = require('../helpers/api') 3 | 4 | 5 | module.exports = (testPackage, cmd) => { 6 | 7 | 8 | const connectionConfig = setupStore.getConnectionConfig(cmd) 9 | console.log('Adding package ' + testPackage + ' to ' + connectionConfig.host + '...' ) 10 | 11 | api.addForMonitoring('devc',testPackage,connectionConfig) 12 | .then( 13 | ok=>(cmd.system && setupStore.addPackage(testPackage,cmd.system,cmd.group) ) 14 | ) 15 | .catch(error => { 16 | process.exit(1) 17 | }) 18 | 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /src/actions/adds.js: -------------------------------------------------------------------------------- 1 | const path = require("path") 2 | const fs = require('fs') 3 | const setupStore = require('../helpers/setupStore') 4 | 5 | module.exports = (systemToAdd, cmd) => { 6 | 7 | const config = getConfig(cmd) 8 | console.log('Adding system ' + systemToAdd + '...') 9 | setupStore.addSystem(systemToAdd,config) 10 | 11 | 12 | }; 13 | 14 | function getConfig(options) { 15 | //several bash would translate /sap/zadash to /sap/adash 16 | //requiring the entry to be sap/zadash 17 | let argAdashPath = options.adash 18 | if (argAdashPath && argAdashPath.charAt(0) !== '/'){ 19 | argAdashPath = `/${argAdashPath}` 20 | } 21 | else if (!argAdashPath){ 22 | argAdashPath = `/sap/zadash` 23 | } 24 | 25 | const systemOptions = { 26 | config:{ 27 | username: options.username || process.env.ADASH_USERNAME, 28 | password: options.password || process.env.ADASH_PASSWORD, 29 | host: options.host || process.env.ADASH_HOST, 30 | adash: argAdashPath || process.env.ADASH_PATH, 31 | client: options.client || process.env.ADASH_CLIENT 32 | } 33 | }; 34 | if (!systemOptions.config.host || !systemOptions.config.adash) { 35 | throw new Error('Please setup a host as https://your-server.com:8200'); 36 | } 37 | 38 | return systemOptions; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/actions/index.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = () => { 3 | console.log(`ADASH Command Line Interface: no command given.`); 4 | }; 5 | -------------------------------------------------------------------------------- /src/actions/monitor.js: -------------------------------------------------------------------------------- 1 | const setupStore = require('../helpers/setupStore') 2 | const server = require("@ui5/server/lib/server"); 3 | const path = require('path') 4 | const open = require("open") 5 | const fs = require('fs') 6 | 7 | module.exports = (testGroup, cmd) => { 8 | 9 | const system = setupStore.getSystem(cmd.system) 10 | const systemConfig = system.config 11 | //when inexistent the monitor will display 12 | //all packages that were setup in target system 13 | const group = system.groups[testGroup] 14 | 15 | 16 | writeGroupToMonitor(group); 17 | 18 | let monitorUi5Setup = getMonitorServeSetup(systemConfig); 19 | 20 | addBackendProxyMiddleware(); 21 | server.serve(monitorUi5Setup, { port: '8080' }).then(({ h2, port: actualPort }) => { 22 | let index = `http://localhost:${actualPort}/index.html` 23 | open(index, { url: true }); 24 | }) 25 | 26 | 27 | } 28 | 29 | function writeGroupToMonitor(group) { 30 | setupStore.setupMonitoringGroup(group) 31 | } 32 | 33 | function addBackendProxyMiddleware() { 34 | const middlewareRepository = require("@ui5/server/lib/middleware/middlewareRepository"); 35 | middlewareRepository.addMiddleware({ 36 | specVersion: '', 37 | middlewarePath: path.join(require.resolve('ui5-middleware-route-proxy/lib/proxy')), 38 | name: 'ui5-middleware-route-proxy' 39 | }); 40 | } 41 | 42 | function getMonitorServeSetup(systemConfig) { 43 | 44 | let monitorUi5Setup = { 45 | id: 'adash', 46 | version: '0.1.0', 47 | path: setupStore.getMonitorPath(), 48 | specVersion: '2.0', 49 | metadata: { name: 'adash', namespace: 'adash/ui/monitor' }, 50 | type: 'application', 51 | dependencies: [], 52 | framework: { 53 | name: 'SAPUI5', 54 | version: '1.76.0', 55 | libraries: [] 56 | }, 57 | server: { 58 | customMiddleware: [ 59 | { 60 | name: 'ui5-middleware-route-proxy', 61 | afterMiddleware: 'compression', 62 | configuration: { 63 | '/sap/opu/': { 64 | target: systemConfig.host, 65 | auth: { 66 | client: systemConfig.client, 67 | user: systemConfig.username, 68 | pass: systemConfig.password 69 | } 70 | } 71 | } 72 | } 73 | ] 74 | }, 75 | kind: 'project', 76 | resources: { 77 | configuration: { 78 | paths: { 79 | webapp: '/' 80 | }, 81 | propertiesFileSourceEncoding: 'UTF-8' 82 | }, 83 | pathMappings: { '/': '/' } 84 | } 85 | }; 86 | 87 | //for adash endpoint 88 | monitorUi5Setup.server.customMiddleware[0].configuration[systemConfig.adash] = { 89 | target: systemConfig.host, 90 | auth: { 91 | client: systemConfig.client, 92 | user: systemConfig.username, 93 | pass: systemConfig.password 94 | } 95 | }; 96 | 97 | return monitorUi5Setup; 98 | } 99 | -------------------------------------------------------------------------------- /src/actions/testg.js: -------------------------------------------------------------------------------- 1 | const api = require('../helpers/api') 2 | const setupStore = require('../helpers/setupStore') 3 | const resultHandler = require('../helpers/testResultHandler') 4 | 5 | 6 | 7 | module.exports = (testGroup, cmd) => { 8 | 9 | if (!cmd.system) { 10 | throw new Error('Please inform a sistem') 11 | } 12 | 13 | const system = setupStore.getSystem(cmd.system) 14 | const connectionConfig = setupStore.getConnectionConfig(cmd) 15 | 16 | const group = system.groups[testGroup] 17 | if (!group) { 18 | throw new Error('Group ' + testGroup + ' not found on system ' + cmd.system) 19 | } 20 | 21 | console.log('Testing group ' + testGroup + '...') 22 | 23 | Promise.all( 24 | group.map(package => { 25 | console.log('Testing package ' + package + '...') 26 | return api.testPackage(package,connectionConfig) 27 | }) 28 | ).then(responses => { 29 | let hasFails = false 30 | responses.map(data => { 31 | let hasFails = (data.STATUS === '1-') 32 | resultsHandler(data => { 33 | resultHandler(data) 34 | }) 35 | if (hasFails) 36 | process.exit(1) 37 | 38 | }) 39 | }) 40 | .catch(error => { 41 | process.exit(1) 42 | }) 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /src/actions/testp.js: -------------------------------------------------------------------------------- 1 | const setupStore = require('../helpers/setupStore') 2 | const api = require('../helpers/api') 3 | const resultHandler = require('../helpers/testResultHandler') 4 | 5 | module.exports = (testPackage, cmd) => { 6 | 7 | const connectionConfig = setupStore.getConnectionConfig(cmd) 8 | console.log('Testing package ' + testPackage + '...') 9 | 10 | const response = api.testPackage(testPackage, connectionConfig) 11 | response 12 | .then(data => { 13 | resultHandler(data,true) 14 | }) 15 | .catch(error => { 16 | process.exit(1) 17 | }) 18 | }; 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/helpers/api.js: -------------------------------------------------------------------------------- 1 | const https = require('https'); 2 | path = require('path') 3 | const fs = require('fs'); 4 | let axios = require('axios'); 5 | 6 | 7 | async function testPackage(testPackage,systemConfig) { 8 | 9 | setInsecureIfRequested(systemConfig) 10 | 11 | const username = process.env.ADASH_USERNAME || systemConfig.username 12 | const password = process.env.ADASH_PASSWORD || systemConfig.password 13 | const host = process.env.ADASH_HOST || systemConfig.host 14 | const path = process.env.ADASH_PATH || systemConfig.adash 15 | const baseURL = `${host}${path}` 16 | 17 | try { 18 | const response = await axios.get('/devc/' + testPackage + '/test', { 19 | baseURL: baseURL, 20 | auth: { 21 | username: username, 22 | password: password, 23 | } 24 | }) 25 | //ABAP Swagger adds DATA, everything on upper 26 | return response.data.DATA; 27 | } catch (error) { 28 | console.log(`Unable to reach ${baseURL} 29 | Error: ${error.code}` ); 30 | process.exitCode = 1; 31 | } 32 | } 33 | 34 | async function addForMonitoring(type,component,systemConfig) { 35 | 36 | const username = process.env.ADASH_USERNAME || systemConfig.username 37 | const password = process.env.ADASH_PASSWORD || systemConfig.password 38 | const host = process.env.ADASH_HOST || systemConfig.host 39 | const path = process.env.ADASH_PATH || systemConfig.adash 40 | const baseURL = `${host}${path}` 41 | 42 | setInsecureIfRequested(systemConfig) 43 | 44 | try { 45 | const response = await axios.get(`/${type}/${component}/add`, { 46 | baseURL: baseURL, 47 | auth: { 48 | username: username, 49 | password: password, 50 | } 51 | }) 52 | return true; 53 | } catch (error) { 54 | console.log(`Unable to reach ${baseURL} 55 | Error: ${error.code}` ); 56 | process.exitCode = 1; 57 | } 58 | } 59 | 60 | function setInsecureIfRequested(options) { 61 | if (options.insecure) { 62 | axios = axios.create({ 63 | httpsAgent: new https.Agent({ 64 | rejectUnauthorized: false 65 | }) 66 | }) 67 | } 68 | } 69 | 70 | async function downloadMonitor(monitorPath){ 71 | const componentPreloadPath = path.join(monitorPath,'/Component-preload.js') 72 | const indexPath = path.join(monitorPath,'/index.html') 73 | 74 | if (!fs.existsSync(monitorPath)){ 75 | fs.mkdirSync(monitorPath) 76 | } 77 | 78 | const monitor = await axios.get('/xinitrc86/adash-monitor/master/Component-preload.js',{ 79 | baseURL: 'https://raw.githubusercontent.com' 80 | }) 81 | 82 | fs.writeFileSync(componentPreloadPath,monitor.data) 83 | 84 | const index = await axios.get('/xinitrc86/adash-monitor/master/index.html',{ 85 | baseURL: 'https://raw.githubusercontent.com' 86 | }) 87 | 88 | fs.writeFileSync(indexPath,index.data) 89 | 90 | } 91 | 92 | 93 | module.exports = { 94 | downloadMonitor, 95 | testPackage, 96 | addForMonitoring 97 | } 98 | -------------------------------------------------------------------------------- /src/helpers/fail.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | const log = console.log; 3 | 4 | module.exports = (data) => { 5 | log(chalk.bold.red('FAIL')); 6 | data.TESTS.map(test => { 7 | if (test.STATUS === '1-') { 8 | log(' ' + chalk.red('On: ') + test.NAME + chalk.yellow(' Test: ') + test.TEST_CLASS + ' ' + test.TEST_METHOD); 9 | log(' ' + chalk.red('Error: ') + chalk.white(test.FAILURE_HEADER)); 10 | log(' ' + chalk.white(test.FAILURE_DETAILS)); 11 | log('') 12 | } 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /src/helpers/pass.js: -------------------------------------------------------------------------------- 1 | let chalk = require('chalk'); 2 | const log = console.log; 3 | 4 | module.exports = (data) => { 5 | log(chalk.bold.green(' PASS ')); 6 | // @ToDo: on verbose 7 | data.SUMARIES.map(test => { 8 | log(chalk.green('PASS: ') + test.TYPE + ' ' + test.NAME ); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /src/helpers/setupStore.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const api = require('./api') 3 | const fs = require('fs') 4 | const chalk = require('chalk') 5 | 6 | const _adashFolder = path.join(require("os").homedir(), ".adash") 7 | const _adashSystemsFile = path.join( _adashFolder, "systems.json") 8 | const _adashMonitorPath = path.join(_adashFolder,'/monitor') 9 | 10 | const getMonitorPath = ()=>{ 11 | return _adashMonitorPath 12 | } 13 | 14 | const getFolderPath = () =>{ 15 | return _adashFolder 16 | } 17 | 18 | const getSystems = () =>{ 19 | 20 | let systems = {} 21 | 22 | try { 23 | let rawdata = fs.readFileSync(_adashSystemsFile); 24 | systems = JSON.parse(rawdata); 25 | 26 | 27 | } catch (error) { 28 | systems = {}; 29 | if (!fs.existsSync(_adashFolder)){ 30 | fs.mkdirSync(_adashFolder) 31 | } 32 | fs.writeFileSync(_adashSystemsFile,JSON.stringify(systems)) 33 | } 34 | 35 | return systems; 36 | 37 | 38 | } 39 | 40 | 41 | const getConnectionConfig = function(options) { 42 | //several bash would translate /sap/zadash to /sap/adash 43 | //requiring the entry to be sap/zadash 44 | 45 | let systemConfig = {} 46 | if (options.system){ 47 | systemConfig = getSystem(options.system).config 48 | } 49 | 50 | let argAdashPath = options.adash 51 | if (argAdashPath && argAdashPath.charAt(0) !== '/'){ 52 | argAdashPath = `/${argAdashPath}` 53 | } 54 | else if (!argAdashPath){ 55 | argAdashPath = `/sap/zadash` 56 | } 57 | 58 | const connectionConfig = { 59 | insecure: options.insecure, 60 | username: options.username || process.env.ADASH_USERNAME || systemConfig.username, 61 | password: options.password || process.env.ADASH_PASSWORD || systemConfig.password, 62 | host: options.host || process.env.ADASH_HOST || systemConfig.host, 63 | adash: argAdashPath || process.env.ADASH_PATH || systemConfig.adash, 64 | client: options.client || process.env.ADASH_CLIENT || systemConfig.client 65 | }; 66 | 67 | if (!connectionConfig.host || !connectionConfig.adash) { 68 | console.log(chalk.red('Please setup a host as https://your-server.com:8200')) 69 | console.log('By either adding a system, command options, environment variables or a combination!') 70 | process.exit(1) 71 | } 72 | 73 | if (!connectionConfig.username || !connectionConfig.password) { 74 | console.log(chalk.red('Please setup a user and name')) 75 | console.log('By either adding a system, command options, environment variables or a combination!') 76 | process.exit(1) 77 | } 78 | 79 | return connectionConfig; 80 | } 81 | 82 | 83 | const getSystem = (system) =>{ 84 | 85 | const systems = getSystems(); 86 | if (!systems[system]){ 87 | throw new Error('System ' + system + ' is not set up.') 88 | } 89 | 90 | return systems[system]; 91 | 92 | } 93 | 94 | const addSystem = (sysName,sysEntry) =>{ 95 | 96 | let systems = getSystems(); 97 | if (!systems[sysName]){ 98 | systems[sysName] = sysEntry 99 | }else{ 100 | systems[sysName] = { 101 | ...systems[sysName], 102 | ...sysEntry 103 | } 104 | } 105 | 106 | fs.writeFileSync(_adashSystemsFile,JSON.stringify(systems)) 107 | } 108 | 109 | const addPackage = (testPackage,system,group) => { 110 | 111 | let systemConfig = getSystem(system) 112 | let systemGroups = systemConfig.groups || {} 113 | 114 | if (group) { 115 | let other = systemGroups[group] || [] 116 | if (!other.find( package => package === testPackage )){ 117 | other.push(testPackage) 118 | } 119 | systemGroups[group] = other; 120 | } 121 | 122 | systemConfig.groups = systemGroups 123 | 124 | addSystem(system,systemConfig) 125 | 126 | } 127 | 128 | 129 | const setupMonitoringGroup = group =>{ 130 | 131 | api.downloadMonitor(_adashMonitorPath) 132 | .then( dummy=>{ 133 | let adashCliJSON = path.join(_adashMonitorPath, '/adash-cli.json'); 134 | console.log("oops"); 135 | if (!group && fs.existsSync(adashCliJSON) ){ 136 | fs.unlinkSync(adashCliJSON) 137 | } 138 | else if (group){ 139 | fs.writeFileSync(adashCliJSON, JSON.stringify(group)); 140 | } 141 | }) 142 | } 143 | 144 | const store = { 145 | getMonitorPath, 146 | setupMonitoringGroup, 147 | getFolderPath, 148 | getSystems, 149 | getSystem, 150 | getConnectionConfig, 151 | addSystem, 152 | addPackage 153 | } 154 | 155 | module.exports = store -------------------------------------------------------------------------------- /src/helpers/testResultHandler.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk') 2 | 3 | const STATUS = { 4 | success: '1', 5 | fail: '1-', 6 | neutral: '0' 7 | } 8 | const pass = require('./pass'); 9 | const fail = require('./fail'); 10 | 11 | module.exports = (data,failOnError) => { 12 | 13 | switch (data.STATUS) { 14 | case STATUS.success: 15 | pass(data) 16 | return true 17 | 18 | case STATUS.fail: 19 | fail(data) 20 | if (failOnError) 21 | process.exit(1) 22 | case STATUS.neutral: 23 | console.log(chalk.red('No tests executed.')) 24 | process.exit(1) 25 | 26 | } 27 | } --------------------------------------------------------------------------------