You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by al...@apache.org on 2020/04/14 07:53:30 UTC

[openwhisk-wskdebug] branch master updated (4dc9faa -> fa5b0b4)

This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git.


    from 4dc9faa  fix: if agent was leftover restore first before installing agent
     new 480d373  add debug() logs with DEBUG=wskdebug providing time spent details
     new e2fd50d  performance: avoid reading namespace list if not in wskprops, use from initial action GET
     new 560f81d  performance: keep action code in memory and use that on restore
     new ef712b8  performance: create backup action in parallel when debugger is already ready
     new ff21682  performance: parallelize container and openwhisk tasks at startup
     new 4b4662f  fix missing EOL at end of file
     new 18cf6a8  remove incorrect and unnecessary module export statements in agents
     new b903c36  performance: move `docker info` check out of critical path
     new fa5b0b4  performance: do not delete backup and helper actions on exit by default

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 agent/agent-activationdb.js                        |   3 +-
 agent/agent-concurrency.js                         |   3 +-
 agent/agent-ngrok.js                               |   3 +-
 index.js                                           |   7 ++
 package-lock.json                                  |  57 ++++++++-
 package.json                                       |   5 +-
 src/agentmgr.js                                    | 104 +++++++++++++----
 .../nodejs/commonjs-flat/action.js => src/debug.js |  13 ++-
 src/debugger.js                                    | 128 ++++++++++++--------
 src/invoker.js                                     |  26 +++--
 src/watcher.js                                     |   2 +
 test/agentmgr.test.js                              | 129 ++++++++++++++++-----
 test/install/Dockerfile                            |   2 +-
 test/ngrok.test.js                                 |   4 +-
 test/test.js                                       |   2 -
 15 files changed, 354 insertions(+), 134 deletions(-)
 copy test/nodejs/commonjs-flat/action.js => src/debug.js (65%)


[openwhisk-wskdebug] 08/09: performance: move `docker info` check out of critical path

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit b903c368137f32acaf3aab17f3e2b721e536faa0
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 23:44:45 2020 -0700

    performance: move `docker info` check out of critical path
---
 src/debugger.js         | 4 ----
 src/invoker.js          | 5 ++++-
 test/install/Dockerfile | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/debugger.js b/src/debugger.js
index 2cce15f..434f71f 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -60,10 +60,6 @@ class Debugger {
         this.agentMgr = new AgentMgr(this.argv, this.wsk, this.actionName);
         this.watcher = new Watcher(this.argv, this.wsk);
 
-        // quick fail for missing requirements such as docker not running
-        await OpenWhiskInvoker.checkIfAvailable();
-        debug("verified that docker is available and running");
-
         // get the action metadata
         const actionMetadata = await this.agentMgr.peekAction();
         debug("fetched action metadata from openwhisk");
diff --git a/src/invoker.js b/src/invoker.js
index 9a92318..35fff0e 100644
--- a/src/invoker.js
+++ b/src/invoker.js
@@ -83,7 +83,7 @@ class OpenWhiskInvoker {
         this.containerName = this.asContainerName(`wskdebug-${this.action.name}-${Date.now()}`);
     }
 
-    static async checkIfAvailable() {
+    async checkIfDockerAvailable() {
         try {
             execute("docker info", {stdio: 'ignore'});
         } catch (e) {
@@ -189,6 +189,9 @@ class OpenWhiskInvoker {
 
         let showDockerRunOutput = this.verbose;
 
+        // quick fail for missing requirements such as docker not running
+        await this.checkIfDockerAvailable();
+
         try {
             execute(`docker inspect --type=image ${this.image} 2> /dev/null`);
         } catch (e) {
diff --git a/test/install/Dockerfile b/test/install/Dockerfile
index a45d187..029ba79 100644
--- a/test/install/Dockerfile
+++ b/test/install/Dockerfile
@@ -38,4 +38,4 @@ RUN wskdebug --ngrok myaction 2>&1 | grep -A 10 "ngrok dependency required for -
 RUN npm install -g ngrok --unsafe-perm=true
 
 # then we should get another error (as we can't run it without docker)
-RUN wskdebug --ngrok myaction 2>&1 | grep -A 10 "Docker not running on local system. A local docker environment is required for the debugger."
+RUN wskdebug --ngrok myaction 2>&1 | grep -A 10 -E "(Error: Unknown Error From API: socket hang up|Docker not running on local system. A local docker environment is required for the debugger.)"


[openwhisk-wskdebug] 02/09: performance: avoid reading namespace list if not in wskprops, use from initial action GET

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit e2fd50dcf084ab52e0c4133cb359375a27213789
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 17:44:15 2020 -0700

    performance: avoid reading namespace list if not in wskprops, use from initial action GET
---
 src/debugger.js | 45 +++++++++++----------------------------------
 1 file changed, 11 insertions(+), 34 deletions(-)

diff --git a/src/debugger.js b/src/debugger.js
index 7343fb6..db33974 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -35,6 +35,7 @@ class Debugger {
     constructor(argv) {
         this.startTime = Date.now();
         debug("starting debugger");
+
         this.argv = argv;
         this.actionName = argv.action;
 
@@ -46,11 +47,16 @@ class Debugger {
         if (argv.ignoreCerts) {
             this.wskProps.ignore_certs = true;
         }
+
+        try {
+            this.wsk = openwhisk(this.wskProps);
+        } catch (err) {
+            console.error(`Error: Could not setup openwhisk client: ${err.message}`);
+            process.exit(1);
+        }
     }
 
     async start() {
-        await this.setupWsk();
-
         this.agentMgr = new AgentMgr(this.argv, this.wsk, this.actionName);
         this.watcher = new Watcher(this.argv, this.wsk);
 
@@ -58,13 +64,13 @@ class Debugger {
         await OpenWhiskInvoker.checkIfAvailable();
         debug("verified that docker is available and running");
 
-        console.info(`Starting debugger for /${this.wskProps.namespace}/${this.actionName}`);
-
         // get the action metadata
         const actionMetadata = await this.agentMgr.peekAction();
-
         debug("fetched action metadata from openwhisk");
 
+        this.wskProps.namespace = actionMetadata.namespace;
+        console.info(`Starting debugger for /${this.wskProps.namespace}/${this.actionName}`);
+
         // local debug container
         this.invoker = new OpenWhiskInvoker(this.actionName, actionMetadata, this.argv, this.wskProps, this.wsk);
 
@@ -236,35 +242,6 @@ class Debugger {
         this.ready = false;
     }
 
-    // ------------------------------------------------< openwhisk utils >------------------
-
-    async setupWsk() {
-        if (!this.wsk) {
-            try {
-                this.wsk = openwhisk(this.wskProps);
-            } catch (err) {
-                console.error(`Error: Could not setup openwhisk client: ${err.message}`);
-                process.exit(1);
-            }
-            if (this.wskProps.namespace === undefined) {
-                // there is a strict 1-1 bijection between auth and namespace, hence auth is enough.
-                // while the openwhisk() client does not care about the namespace being set,
-                // some code here in wskdebug relies on it to be set correctly.
-                const namespaces = await this.wsk.namespaces.list();
-                if (!namespaces || namespaces.length < 1) {
-                    console.error("Error: Unknown namespace. Please specify as NAMESPACE in .wskprops.");
-                    process.exit(2);
-                }
-                if (namespaces.length > 1) {
-                    console.error("Error: OpenWhisk reports access to more than one namespace. Please specify the namespace to use as NAMESPACE in .wskprops.", namespaces);
-                    process.exit(2);
-                }
-                this.wskProps.namespace = namespaces[0];
-                debug(`fetched namespace name: ${this.wskProps.namespace} (was not in wskprops file)`);
-            }
-        }
-    }
-
     // ------------------------------------------------< utils >-----------------
 
     async tryCatch(task, message="Error during shutdown:") {


[openwhisk-wskdebug] 01/09: add debug() logs with DEBUG=wskdebug providing time spent details

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit 480d373638e93ac72d9b4c6447fe3930265726ad
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 17:02:01 2020 -0700

    add debug() logs with DEBUG=wskdebug providing time spent details
---
 index.js          |  2 ++
 package-lock.json | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 package.json      |  3 +++
 src/agentmgr.js   | 10 ++++++++++
 src/debug.js      | 21 +++++++++++++++++++++
 src/debugger.js   | 31 +++++++++++++++++++++++++++++--
 src/invoker.js    | 21 ++++++++++++++-------
 src/watcher.js    |  2 ++
 8 files changed, 132 insertions(+), 12 deletions(-)

diff --git a/index.js b/index.js
index 0406efe..18d13ff 100644
--- a/index.js
+++ b/index.js
@@ -21,6 +21,7 @@ const yargs = require("yargs");
 const Debugger = require("./src/debugger");
 const path = require("path");
 const fs = require("fs");
+const debug = require('./src/debug');
 
 function enableConsoleColors() {
     // colorful console.error() and co
@@ -286,6 +287,7 @@ function registerExitHandler(dbg) {
 }
 
 async function wskdebug(args, isCommandLine=false) {
+    debug("wskdebug arguments:", args);
     const originalConsole = enableConsoleColors();
 
     try {
diff --git a/package-lock.json b/package-lock.json
index 28b394f..00a4067 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -655,9 +655,9 @@
             }
         },
         "debug": {
-            "version": "3.2.6",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-            "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
             "requires": {
                 "ms": "^2.1.1"
             }
@@ -1938,6 +1938,15 @@
                     "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
                     "dev": true
                 },
+                "debug": {
+                    "version": "3.2.6",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+                    "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+                    "dev": true,
+                    "requires": {
+                        "ms": "^2.1.1"
+                    }
+                },
                 "emoji-regex": {
                     "version": "7.0.3",
                     "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@@ -2106,6 +2115,17 @@
             "requires": {
                 "debug": "^3.1.0",
                 "lodash": "^4.16.4"
+            },
+            "dependencies": {
+                "debug": {
+                    "version": "3.2.6",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+                    "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+                    "dev": true,
+                    "requires": {
+                        "ms": "^2.1.1"
+                    }
+                }
             }
         },
         "mock-require": {
@@ -2160,6 +2180,16 @@
                 "debug": "^3.2.6",
                 "iconv-lite": "^0.4.4",
                 "sax": "^1.2.4"
+            },
+            "dependencies": {
+                "debug": {
+                    "version": "3.2.6",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+                    "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+                    "requires": {
+                        "ms": "^2.1.1"
+                    }
+                }
             }
         },
         "nice-try": {
@@ -2419,6 +2449,11 @@
                 "callsites": "^3.0.0"
             }
         },
+        "parse-ms": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz",
+            "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA=="
+        },
         "path-exists": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -2462,6 +2497,19 @@
             "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
             "dev": true
         },
+        "pretty-bytes": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
+            "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg=="
+        },
+        "pretty-ms": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-6.0.1.tgz",
+            "integrity": "sha512-ke4njoVmlotekHlHyCZ3wI/c5AMT8peuHs8rKJqekj/oR5G8lND2dVpicFlUz5cbZgE290vvkMuDwfj/OcW1kw==",
+            "requires": {
+                "parse-ms": "^2.1.0"
+            }
+        },
         "process-on-spawn": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
diff --git a/package.json b/package.json
index 6aa1af5..b717ddf 100644
--- a/package.json
+++ b/package.json
@@ -42,12 +42,15 @@
         "file": "test/logfile.setup.js"
     },
     "dependencies": {
+        "debug": "^4.1.1",
         "fetch-retry": "^3.1.0",
         "fs-extra": "^8.1.0",
         "isomorphic-fetch": "^2.2.1",
         "livereload": "^0.9.1",
         "manakin": "^0.5.2",
         "openwhisk": "^3.21.1",
+        "pretty-bytes": "^5.3.0",
+        "pretty-ms": "^6.0.1",
         "yargs": "^15.3.1"
     },
     "peerDependencies": {
diff --git a/src/agentmgr.js b/src/agentmgr.js
index ecf33a2..1806c05 100644
--- a/src/agentmgr.js
+++ b/src/agentmgr.js
@@ -27,6 +27,7 @@ try {
 
 const fs = require('fs-extra');
 const sleep = require('util').promisify(setTimeout);
+const debug = require('./debug');
 
 function getAnnotation(action, key) {
     const a = action.annotations.find(a => a.key === key);
@@ -76,6 +77,7 @@ async function deleteActionIfExists(wsk, name) {
     if (await actionExists(wsk, name)) {
         await wsk.actions.delete(name);
     }
+    debug(`restore: ensured removal of action ${name}`);
 }
 
 
@@ -170,6 +172,7 @@ class AgentMgr {
             // agent using ngrok for forwarding
             agentName = "ngrok";
             agentCode = await this.ngrokAgent.getAgent(action);
+            debug("started local ngrok proxy");
 
         } else {
             this.concurrency = await this.openwhiskSupports("concurrency");
@@ -197,6 +200,7 @@ class AgentMgr {
             name: backupName,
             action: action
         });
+        debug(`created action backup ${backupName}`);
 
         if (this.argv.verbose) {
             console.log(`Original action backed up at ${backupName}.`);
@@ -220,6 +224,7 @@ class AgentMgr {
                 await this.pushAgent(action, agentCode, backupName);
             }
         }
+        debug(`installed agent (${agentName}) in place of ${this.actionName}`);
 
         if (this.argv.verbose) {
             console.log(`Agent installed.`);
@@ -238,6 +243,7 @@ class AgentMgr {
         } finally {
             if (this.ngrokAgent) {
                 await this.ngrokAgent.stop();
+                debug("ngrok shut down");
             }
         }
     }
@@ -404,15 +410,18 @@ class AgentMgr {
         try {
             // the original was backed up in the copy
             const original = await this.wsk.actions.get(copy);
+            debug("restore: fetched action original from backup copy (move step 1)");
 
             // copy the backup (copy) to the regular action
             await this.wsk.actions.update({
                 name: this.actionName,
                 action: original
             });
+            debug("restore: restored action with original (move step 2)");
 
             // remove the backup
             await this.wsk.actions.delete(copy);
+            debug("restore: deleted backup copy (move step 3)");
 
             // remove any helpers if they exist
             await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_invoked`);
@@ -492,6 +501,7 @@ class AgentMgr {
                 ]
             }
         });
+        debug(`created helper action ${actionName}`);
     }
 
     // ----------------------------------------< openwhisk feature detection >-----------------
diff --git a/src/debug.js b/src/debug.js
new file mode 100644
index 0000000..6e4cc49
--- /dev/null
+++ b/src/debug.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+// common debug() instance for shared time spent measurments (+millis)
+module.exports = require('debug')('wskdebug');
diff --git a/src/debugger.js b/src/debugger.js
index 3bf6433..7343fb6 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -24,12 +24,17 @@ const Watcher = require('./watcher');
 const openwhisk = require('openwhisk');
 const { spawnSync } = require('child_process');
 const sleep = require('util').promisify(setTimeout);
+const debug = require('./debug');
+const prettyBytes = require('pretty-bytes');
+const prettyMilliseconds = require('pretty-ms');
 
 /**
  * Central component of wskdebug.
  */
 class Debugger {
     constructor(argv) {
+        this.startTime = Date.now();
+        debug("starting debugger");
         this.argv = argv;
         this.actionName = argv.action;
 
@@ -51,12 +56,15 @@ class Debugger {
 
         // quick fail for missing requirements such as docker not running
         await OpenWhiskInvoker.checkIfAvailable();
+        debug("verified that docker is available and running");
 
         console.info(`Starting debugger for /${this.wskProps.namespace}/${this.actionName}`);
 
         // get the action metadata
         const actionMetadata = await this.agentMgr.peekAction();
 
+        debug("fetched action metadata from openwhisk");
+
         // local debug container
         this.invoker = new OpenWhiskInvoker(this.actionName, actionMetadata, this.argv, this.wskProps, this.wsk);
 
@@ -70,10 +78,17 @@ class Debugger {
             // start container - get it up fast for VSCode to connect within its 10 seconds timeout
             await this.invoker.startContainer();
 
+            debug(`started container: ${this.invoker.name()}`);
+
             // get code and /init local container
             const actionWithCode = await this.agentMgr.readActionWithCode();
+
+            debug(`fetched action code from openwhisk (${prettyBytes(actionWithCode.exec.code.length)})`);
+
             await this.invoker.init(actionWithCode);
 
+            debug("installed action on container (/init)");
+
             // setup agent in openwhisk
             await this.agentMgr.installAgent(actionWithCode, this.invoker);
 
@@ -87,10 +102,17 @@ class Debugger {
 
             console.log();
             console.info(`Action     : ${this.actionName}`);
-            this.invoker.logInfo();
+            if (this.sourcePath) {
+                console.info(`Sources    : ${this.invoker.getSourcePath()}`);
+            }
+            console.info(`Image      : ${this.invoker.getImage()}`);
+            console.info(`Container  : ${this.invoker.name()}`);
+            console.info(`Debug type : ${this.invoker.getDebugKind()}`);
+            console.info(`Debug port : localhost:${this.invoker.getPort()}`);
             if (this.argv.condition) {
                 console.info(`Condition  : ${this.argv.condition}`);
             }
+            console.info(`Startup    : ${prettyMilliseconds(Date.now() - this.startTime)}`)
             console.log();
             console.info(`Ready, waiting for activations! Use CTRL+C to exit`);
 
@@ -183,6 +205,8 @@ class Debugger {
             return;
         }
         this.shuttingDown = true;
+        const shutdownStart = Date.now();
+        debug("shutting down...");
 
         // only log this if we started properly
         if (this.ready) {
@@ -198,14 +222,16 @@ class Debugger {
         }
         if (this.invoker) {
             await this.tryCatch(this.invoker.stop());
+            debug(`stopped container: ${this.invoker.name()}`);
         }
         if (this.watcher) {
             await this.tryCatch(this.watcher.stop());
+            debug("stopped source file watching");
         }
 
         // only log this if we started properly
         if (this.ready) {
-            console.log(`Done`);
+            console.log(`Done (shutdown took ${prettyMilliseconds(Date.now() - shutdownStart)})`);
         }
         this.ready = false;
     }
@@ -234,6 +260,7 @@ class Debugger {
                     process.exit(2);
                 }
                 this.wskProps.namespace = namespaces[0];
+                debug(`fetched namespace name: ${this.wskProps.namespace} (was not in wskprops file)`);
             }
         }
     }
diff --git a/src/invoker.js b/src/invoker.js
index f2fe6dc..9a92318 100644
--- a/src/invoker.js
+++ b/src/invoker.js
@@ -241,13 +241,20 @@ class OpenWhiskInvoker {
         });
     }
 
-    async logInfo() {
-        if (this.sourcePath) {
-            console.info(`Sources    : ${this.sourcePath}`);
-        }
-        console.info(`Image      : ${this.image}`);
-        console.info(`Debug type : ${this.debugKind}`);
-        console.info(`Debug port : localhost:${this.debug.port}`)
+    getSourcePath() {
+        return this.sourcePath;
+    }
+
+    getImage() {
+        return this.image;
+    }
+
+    getDebugKind() {
+        return this.debugKind;
+    }
+
+    getPort() {
+        return this.debug.port;
     }
 
     async init(actionWithCode) {
diff --git a/src/watcher.js b/src/watcher.js
index 4e0fd91..dcea5a6 100644
--- a/src/watcher.js
+++ b/src/watcher.js
@@ -20,6 +20,7 @@
 const fs = require('fs-extra');
 const livereload = require('livereload');
 const { spawnSync } = require('child_process');
+const debug = require('./debug');
 
 class Watcher {
     constructor(argv, wsk) {
@@ -105,6 +106,7 @@ class Watcher {
             if (this.argv.livereload) {
                 console.info(`LiveReload enabled for ${watch} on port ${this.liveReloadServer.config.port}`);
             }
+            debug("started source file watching");
         }
     }
 


[openwhisk-wskdebug] 05/09: performance: parallelize container and openwhisk tasks at startup

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit ff21682af597785596990e5790e81ecef635eb4e
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 22:09:16 2020 -0700

    performance: parallelize container and openwhisk tasks at startup
---
 src/agentmgr.js | 21 ++++++++++---------
 src/debug.js    | 10 +++++++++
 src/debugger.js | 63 ++++++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 68 insertions(+), 26 deletions(-)

diff --git a/src/agentmgr.js b/src/agentmgr.js
index 452e49a..e12e9f7 100644
--- a/src/agentmgr.js
+++ b/src/agentmgr.js
@@ -28,7 +28,6 @@ try {
 const fs = require('fs-extra');
 const sleep = require('util').promisify(setTimeout);
 const debug = require('./debug');
-const prettyBytes = require('pretty-bytes');
 const clone = require('clone');
 
 function getAnnotation(action, key) {
@@ -118,10 +117,12 @@ class AgentMgr {
             try {
                 const backup = await getWskActionWithoutCode(this.wsk, backupName);
 
-                if (isAgent(backup)) {
+                if (!backup) {
+                    // backup is also an agent (should not happen)
+                    throw new Error(`Dang! Agent is already installed and action backup is missing.\n\nPlease redeploy your action first before running wskdebug again.`);
+
+                } else if (isAgent(backup)) {
                     // backup is also an agent (should not happen)
-                    // backup is useless, delete it
-                    // await this.wsk.actions.delete(backupName);
                     throw new Error(`Dang! Agent is already installed and action backup is broken (${backupName}).\n\nPlease redeploy your action first before running wskdebug again.`);
 
                 } else {
@@ -157,8 +158,6 @@ class AgentMgr {
             this.actionWithCode = await this.restoreAction();
         } else {
             this.actionWithCode = await this.wsk.actions.get(this.actionName);
-            debug(`fetched action code from openwhisk (${prettyBytes(this.actionWithCode.exec.code.length)})`);
-
         }
         // extra sanity check
         if (isAgent(this.actionWithCode)) {
@@ -168,7 +167,7 @@ class AgentMgr {
         return this.actionWithCode;
     }
 
-    async installAgent(invoker) {
+    async installAgent(invoker, debugTask) {
         this.agentInstalled = true;
 
         let agentName;
@@ -190,7 +189,7 @@ class AgentMgr {
             // agent using ngrok for forwarding
             agentName = "ngrok";
             agentCode = await this.ngrokAgent.getAgent(agentAction);
-            debug("started local ngrok proxy");
+            debugTask("started local ngrok proxy");
 
         } else {
             this.concurrency = await this.openwhiskSupports("concurrency");
@@ -216,11 +215,13 @@ class AgentMgr {
         // create copy in case wskdebug gets killed hard
         // do async as this can be slow for larger actions and this is part of the critical startup path
         this.createBackup = (async () => {
+            const debugTask = debug.task();
+
             await this.wsk.actions.update({
                 name: backupName,
                 action: agentAction
             });
-            debug(`created action backup ${backupName}`);
+            debugTask(`created action backup ${backupName}`);
         })();
 
         if (this.argv.verbose) {
@@ -245,7 +246,7 @@ class AgentMgr {
                 await this.pushAgent(agentAction, agentCode, backupName);
             }
         }
-        debug(`installed agent (${agentName}) in place of ${this.actionName}`);
+        debugTask(`installed agent '${agentName}' in place of ${this.actionName}`);
 
         if (this.argv.verbose) {
             console.log(`Agent installed.`);
diff --git a/src/debug.js b/src/debug.js
index 6e4cc49..bbe46f8 100644
--- a/src/debug.js
+++ b/src/debug.js
@@ -19,3 +19,13 @@
 
 // common debug() instance for shared time spent measurments (+millis)
 module.exports = require('debug')('wskdebug');
+
+// start a sub debug instance for logging times in parallel promises
+module.exports.task = () => {
+    const debug = require('debug')('wskdebug')
+    // trick to start time measurement from now on without logging an extra line
+    debug.log = () => {};
+    debug();
+    delete debug.log;
+    return debug;
+}
\ No newline at end of file
diff --git a/src/debugger.js b/src/debugger.js
index 91d8d79..2cce15f 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -25,6 +25,7 @@ const openwhisk = require('openwhisk');
 const { spawnSync } = require('child_process');
 const sleep = require('util').promisify(setTimeout);
 const debug = require('./debug');
+const prettyBytes = require('pretty-bytes');
 const prettyMilliseconds = require('pretty-ms');
 
 /**
@@ -74,26 +75,57 @@ class Debugger {
         this.invoker = new OpenWhiskInvoker(this.actionName, actionMetadata, this.argv, this.wskProps, this.wsk);
 
         try {
-            // run build initially (would be required by starting container)
-            if (this.argv.onBuild) {
-                console.info("=> Build:", this.argv.onBuild);
-                spawnSync(this.argv.onBuild, {shell: true, stdio: "inherit"});
-            }
+            // parallelize slower work using promises
+
+            // task 1 - start local container
+            const containerTask = (async () => {
+                const debugTask = debug.task();
+                // run build initially (would be required by starting container)
+                if (this.argv.onBuild) {
+                    console.info("=> Build:", this.argv.onBuild);
+                    spawnSync(this.argv.onBuild, {shell: true, stdio: "inherit"});
+                }
+
+                // start container - get it up fast for VSCode to connect within its 10 seconds timeout
+                await this.invoker.startContainer();
+
+                debugTask(`started container: ${this.invoker.name()}`);
+            })();
+
+            // task 2 - fetch action code from openwhisk
+            const openwhiskTask = (async () => {
+                const debugTask = debug.task();
+                const actionWithCode = await this.agentMgr.readActionWithCode();
+
+                debugTask(`got action code (${prettyBytes(actionWithCode.exec.code.length)})`);
+                return actionWithCode;
+            })();
+
+            // wait for both tasks 1 & 2
+            const results = await Promise.all([containerTask, openwhiskTask]);
+            const actionWithCode = results[1];
+
+            // parallelize slower work using promises again
 
-            // start container - get it up fast for VSCode to connect within its 10 seconds timeout
-            await this.invoker.startContainer();
+            // task 3 - initialize local container with code
+            const initTask = (async () => {
+                const debugTask = debug.task();
 
-            debug(`started container: ${this.invoker.name()}`);
+                // /init local container
+                await this.invoker.init(actionWithCode);
 
-            // get code and /init local container
-            const actionWithCode = await this.agentMgr.readActionWithCode();
+                debugTask("installed action on container");
+            })();
 
-            await this.invoker.init(actionWithCode);
+            // task 4 - install agent in openwhisk
+            const agentTask = (async () => {
+                const debugTask = debug.task();
 
-            debug("installed action on container (/init)");
+                // setup agent in openwhisk
+                await this.agentMgr.installAgent(this.invoker, debugTask);
+            })();
 
-            // setup agent in openwhisk
-            await this.agentMgr.installAgent(this.invoker);
+            await Promise.all([initTask, agentTask]);
 
             if (this.argv.onStart) {
                 console.log("On start:", this.argv.onStart);
@@ -115,9 +147,8 @@ class Debugger {
             if (this.argv.condition) {
                 console.info(`Condition  : ${this.argv.condition}`);
             }
-            console.info(`Startup    : ${prettyMilliseconds(Date.now() - this.startTime)}`)
             console.log();
-            console.info(`Ready, waiting for activations! Use CTRL+C to exit`);
+            console.info(`Ready for activations. Started in ${prettyMilliseconds(Date.now() - this.startTime)}. Use CTRL+C to exit`);
 
             this.ready = true;
 


[openwhisk-wskdebug] 03/09: performance: keep action code in memory and use that on restore

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit 560f81d0ad70e1969bdc09c2bf0faec8ae37c243
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 18:01:53 2020 -0700

    performance: keep action code in memory and use that on restore
    
    instead of reading it again from the backup action with another slow request
---
 package-lock.json     |  3 +--
 package.json          |  2 +-
 src/agentmgr.js       | 54 ++++++++++++++++++++++++++++++++++++++-------------
 src/debugger.js       |  5 +----
 test/agentmgr.test.js |  2 --
 test/ngrok.test.js    |  3 +--
 test/test.js          |  1 -
 7 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 00a4067..ce21bad 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -583,8 +583,7 @@
         "clone": {
             "version": "2.1.2",
             "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
-            "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
-            "dev": true
+            "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
         },
         "codecov": {
             "version": "3.6.5",
diff --git a/package.json b/package.json
index b717ddf..27004d0 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
         "file": "test/logfile.setup.js"
     },
     "dependencies": {
+        "clone": "^2.1.2",
         "debug": "^4.1.1",
         "fetch-retry": "^3.1.0",
         "fs-extra": "^8.1.0",
@@ -58,7 +59,6 @@
     },
     "devDependencies": {
         "chmodr": "^1.2.0",
-        "clone": "^2.1.2",
         "codecov": "^3.6.5",
         "eslint": "^6.8.0",
         "eslint-config-problems": "^4.0.0",
diff --git a/src/agentmgr.js b/src/agentmgr.js
index 1806c05..d862e05 100644
--- a/src/agentmgr.js
+++ b/src/agentmgr.js
@@ -28,6 +28,8 @@ try {
 const fs = require('fs-extra');
 const sleep = require('util').promisify(setTimeout);
 const debug = require('./debug');
+const prettyBytes = require('pretty-bytes');
+const clone = require('clone');
 
 function getAnnotation(action, key) {
     const a = action.annotations.find(a => a.key === key);
@@ -152,17 +154,33 @@ class AgentMgr {
         // user can switch between agents (ngrok or not), hence we need to restore first
         // (better would be to track the agent + its version and avoid a restore, but that's TBD)
         if (this.agentInstalled) {
-            return this.restoreAction();
+            this.actionWithCode = await this.restoreAction();
+        } else {
+            this.actionWithCode = await this.wsk.actions.get(this.actionName);
+            debug(`fetched action code from openwhisk (${prettyBytes(this.actionWithCode.exec.code.length)})`);
+
+        }
+        // extra sanity check
+        if (isAgent(this.actionWithCode)) {
+            throw new Error("Action seems to be a left over wskdebug agent instead of the original action. Possible bug in wskdebug. Please redeploy your action. Aborting.");
         }
 
-        return this.wsk.actions.get(this.actionName);
+        return this.actionWithCode;
     }
 
-    async installAgent(action, invoker) {
+    async installAgent(invoker) {
         this.agentInstalled = true;
 
         let agentName;
 
+        // base agent on the original action to keep default parameters & annotations
+        const agentAction = this.actionWithCode ? clone(this.actionWithCode) : {
+            exec: {},
+            limits: {},
+            annotations: [],
+            parameters: []
+        };
+
         // choose the right agent implementation
         let agentCode;
         if (this.argv.ngrok) {
@@ -171,7 +189,7 @@ class AgentMgr {
 
             // agent using ngrok for forwarding
             agentName = "ngrok";
-            agentCode = await this.ngrokAgent.getAgent(action);
+            agentCode = await this.ngrokAgent.getAgent(agentAction);
             debug("started local ngrok proxy");
 
         } else {
@@ -198,7 +216,7 @@ class AgentMgr {
         // create copy
         await this.wsk.actions.update({
             name: backupName,
-            action: action
+            action: agentAction
         });
         debug(`created action backup ${backupName}`);
 
@@ -207,21 +225,21 @@ class AgentMgr {
         }
 
         if (this.argv.condition) {
-            action.parameters.push({
+            agentAction.parameters.push({
                 key: "$condition",
                 value: this.argv.condition
             });
         }
 
         try {
-            await this.pushAgent(action, agentCode, backupName);
+            await this.pushAgent(agentAction, agentCode, backupName);
         } catch (e) {
             // openwhisk does not support concurrent nodejs actions, try with another
             if (e.statusCode === 400 && e.error && typeof e.error.error === "string" && e.error.error.includes("concurrency")) {
                 console.log(`The Openwhisk server does not support concurrent actions, using alternative agent. Consider using --ngrok for a possibly faster agent.`);
                 this.concurrency = false;
                 agentCode = await this.getPollingActivationDbAgent();
-                await this.pushAgent(action, agentCode, backupName);
+                await this.pushAgent(agentAction, agentCode, backupName);
             }
         }
         debug(`installed agent (${agentName}) in place of ${this.actionName}`);
@@ -408,20 +426,30 @@ class AgentMgr {
         const copy = getActionCopyName(this.actionName);
 
         try {
-            // the original was backed up in the copy
-            const original = await this.wsk.actions.get(copy);
-            debug("restore: fetched action original from backup copy (move step 1)");
+            // unfortunately, openwhisk does not support a server-side "move action" API,
+            // otherwise the next 3 steps (read, update, delete) could be a single
+            // and presumably fast move operation
+
+            let original;
+            if (this.actionWithCode) {
+                // normal case during shutdown: we have the original action in memory
+                original = this.actionWithCode;
+            } else {
+                // the original was fetched before or was backed up in the copy
+                original = await this.wsk.actions.get(copy)
+                debug("restore: fetched action original from backup copy");
+            }
 
             // copy the backup (copy) to the regular action
             await this.wsk.actions.update({
                 name: this.actionName,
                 action: original
             });
-            debug("restore: restored action with original (move step 2)");
+            debug("restore: restored original action");
 
             // remove the backup
             await this.wsk.actions.delete(copy);
-            debug("restore: deleted backup copy (move step 3)");
+            debug("restore: deleted backup copy");
 
             // remove any helpers if they exist
             await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_invoked`);
diff --git a/src/debugger.js b/src/debugger.js
index db33974..91d8d79 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -25,7 +25,6 @@ const openwhisk = require('openwhisk');
 const { spawnSync } = require('child_process');
 const sleep = require('util').promisify(setTimeout);
 const debug = require('./debug');
-const prettyBytes = require('pretty-bytes');
 const prettyMilliseconds = require('pretty-ms');
 
 /**
@@ -89,14 +88,12 @@ class Debugger {
             // get code and /init local container
             const actionWithCode = await this.agentMgr.readActionWithCode();
 
-            debug(`fetched action code from openwhisk (${prettyBytes(actionWithCode.exec.code.length)})`);
-
             await this.invoker.init(actionWithCode);
 
             debug("installed action on container (/init)");
 
             // setup agent in openwhisk
-            await this.agentMgr.installAgent(actionWithCode, this.invoker);
+            await this.agentMgr.installAgent(this.invoker);
 
             if (this.argv.onStart) {
                 console.log("On start:", this.argv.onStart);
diff --git a/test/agentmgr.test.js b/test/agentmgr.test.js
index d9163c9..b7fae8d 100644
--- a/test/agentmgr.test.js
+++ b/test/agentmgr.test.js
@@ -122,7 +122,6 @@ describe('agentmgr',  function() {
             }]);
 
         // shutdown/restore process
-        test.mockReadBackupAction(action, code);
         test.mockRestoreAction(action, code);
         test.mockRemoveBackupAction(action);
         test.openwhiskNock()
@@ -234,7 +233,6 @@ describe('agentmgr',  function() {
         );
 
         // 6. restore
-        test.mockReadBackupAction(action, actionCode);
         test.mockRestoreAction(action, actionCode);
         test.mockRemoveBackupAction(action);
 
diff --git a/test/ngrok.test.js b/test/ngrok.test.js
index a095659..b9485e6 100644
--- a/test/ngrok.test.js
+++ b/test/ngrok.test.js
@@ -155,8 +155,7 @@ describe('ngrok',  function() {
             .matchHeader("authorization", test.openwhiskApiAuthHeader())
             .reply(200, test.nodejsActionDescription(actionName));
 
-        test.mockReadBackupAction(actionName);
-        test.mockRestoreAction(actionName);
+        test.mockRestoreAction(actionName, code);
         test.mockRemoveBackupAction(actionName);
 
         // wskdebug myaction action.js --ngrok -p ${test.port}
diff --git a/test/test.js b/test/test.js
index d39c539..d59e77e 100644
--- a/test/test.js
+++ b/test/test.js
@@ -191,7 +191,6 @@ function expectAgent(name, code, binary=false) {
     mockInstallAgent(name);
 
     // shutdown/restore process
-    mockReadBackupAction(name, code, binary);
     mockRestoreAction(name, code, binary);
     mockRemoveBackupAction(name);
 }


[openwhisk-wskdebug] 04/09: performance: create backup action in parallel when debugger is already ready

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit ef712b8eb808f918e94e541376f67ea4f91b19e9
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 18:49:30 2020 -0700

    performance: create backup action in parallel when debugger is already ready
    
    saves many seconds on startup with larger actions
---
 src/agentmgr.js | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/agentmgr.js b/src/agentmgr.js
index d862e05..452e49a 100644
--- a/src/agentmgr.js
+++ b/src/agentmgr.js
@@ -213,15 +213,18 @@ class AgentMgr {
             console.log(`Installing agent in OpenWhisk (${agentName})...`);
         }
 
-        // create copy
-        await this.wsk.actions.update({
-            name: backupName,
-            action: agentAction
-        });
-        debug(`created action backup ${backupName}`);
+        // create copy in case wskdebug gets killed hard
+        // do async as this can be slow for larger actions and this is part of the critical startup path
+        this.createBackup = (async () => {
+            await this.wsk.actions.update({
+                name: backupName,
+                action: agentAction
+            });
+            debug(`created action backup ${backupName}`);
+        })();
 
         if (this.argv.verbose) {
-            console.log(`Original action backed up at ${backupName}.`);
+            console.log(`Original action will be backed up at ${backupName}.`);
         }
 
         if (this.argv.condition) {
@@ -255,6 +258,9 @@ class AgentMgr {
 
     async shutdown() {
         try {
+            // make sure we finished creating the backup
+            await this.createBackup;
+
             if (this.agentInstalled) {
                 await this.restoreAction();
             }


[openwhisk-wskdebug] 09/09: performance: do not delete backup and helper actions on exit by default

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit fa5b0b48fa7e3bad922b94ee80e5ff6f70800ded
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Tue Apr 14 00:41:38 2020 -0700

    performance: do not delete backup and helper actions on exit by default
    
    add --cleanup option to do so and warn user about the behavior
---
 index.js              |   5 ++
 src/agentmgr.js       |  25 +++++++---
 test/agentmgr.test.js | 127 ++++++++++++++++++++++++++++++++++++++------------
 test/ngrok.test.js    |   1 -
 test/test.js          |   1 -
 5 files changed, 121 insertions(+), 38 deletions(-)

diff --git a/index.js b/index.js
index 18d13ff..6724d6a 100644
--- a/index.js
+++ b/index.js
@@ -192,6 +192,11 @@ function yargsOptions(yargs) {
         group: "Agent options:",
         describe: "Ngrok region to use. Defaults to 'us'."
     });
+    yargs.option("cleanup", {
+        type: "boolean",
+        group: "Agent options:",
+        describe: "Remove backup and any helper actions on exit. Makes shutdown slower."
+    });
 
     // nodejs options
     yargs.option("inspect", {
diff --git a/src/agentmgr.js b/src/agentmgr.js
index e12e9f7..3275b72 100644
--- a/src/agentmgr.js
+++ b/src/agentmgr.js
@@ -199,7 +199,7 @@ class AgentMgr {
                 agentCode = await this.getConcurrencyAgent();
 
             } else {
-                console.log("This OpenWhisk does not support action concurrency. Debugging will be a bit slower. Consider using '--ngrok' which might be a faster option.");
+                console.warn("This OpenWhisk does not support action concurrency. Debugging will be a bit slower. Consider using '--ngrok' which might be a faster option.");
 
                 agentName = "polling activation db";
                 agentCode = await this.getPollingActivationDbAgent();
@@ -454,13 +454,24 @@ class AgentMgr {
             });
             debug("restore: restored original action");
 
-            // remove the backup
-            await this.wsk.actions.delete(copy);
-            debug("restore: deleted backup copy");
+            if (this.argv.cleanup) {
+                console.log("Removing extra actions due to --cleanup...");
+                // remove the backup
+                await this.wsk.actions.delete(copy);
+                debug("restore: deleted backup copy");
 
-            // remove any helpers if they exist
-            await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_invoked`);
-            await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_completed`);
+                // remove any helpers if they exist
+                await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_invoked`);
+                await deleteActionIfExists(this.wsk, `${this.actionName}_wskdebug_completed`);
+
+            } else {
+                console.warn(`Skipping removal of extra actions. Remove using --cleanup if desired:`);
+                console.warn(`- ${copy}`);
+                if (!this.concurrency) {
+                    console.warn(`- ${this.actionName}_wskdebug_invoked`);
+                    console.warn(`- ${this.actionName}_wskdebug_completed`);
+                }
+            }
 
             return original;
 
diff --git a/test/agentmgr.test.js b/test/agentmgr.test.js
index b7fae8d..77a2d66 100644
--- a/test/agentmgr.test.js
+++ b/test/agentmgr.test.js
@@ -39,10 +39,7 @@ describe('agentmgr',  function() {
         test.afterEach();
     });
 
-    it("should use non-concurrrent agent if openwhisk does not support concurrency", async function() {
-        const action = "myaction";
-        const code = `const main = () => ({ msg: 'WRONG' });`;
-
+    function mockActivationDbAgent(action, code) {
         test.mockAction(action, code);
 
         test.mockCreateBackupAction(action);
@@ -78,7 +75,6 @@ describe('agentmgr',  function() {
             .matchHeader("authorization", test.openwhiskApiAuthHeader())
             .reply(200, test.nodejsActionDescription(action));
 
-
         // invocation
         test.openwhiskNock()
             .get(`${test.openwhiskApiUrl()}/activations`)
@@ -123,31 +119,17 @@ describe('agentmgr',  function() {
 
         // shutdown/restore process
         test.mockRestoreAction(action, code);
-        test.mockRemoveBackupAction(action);
-        test.openwhiskNock()
-            .get(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_invoked?code=false`)
-            .matchHeader("authorization", test.openwhiskApiAuthHeader())
-            .reply(200, {});
-        test.openwhiskNock()
-            .delete(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_invoked`)
-            .matchHeader("authorization", test.openwhiskApiAuthHeader())
-            .reply(200, {});
-        test.openwhiskNock()
-            .get(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_completed?code=false`)
-            .matchHeader("authorization", test.openwhiskApiAuthHeader())
-            .reply(200, {});
-        test.openwhiskNock()
-            .delete(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_completed`)
-            .matchHeader("authorization", test.openwhiskApiAuthHeader())
-            .reply(200, {});
+    }
 
+    it("should use non-concurrent agent if openwhisk does not support concurrency", async function() {
+        const action = "myaction";
+        const code = `const main = () => ({ msg: 'CORRECT' });`;
+
+        mockActivationDbAgent(action, code);
 
-        process.chdir("test/nodejs/plain-flat");
         const argv = {
             port: test.port,
-            action: "myaction",
-            sourcePath: `${process.cwd()}/action.js`,
-            invokeParams: '{ "key": "invocationOnSourceModification" }'
+            action: "myaction"
         };
 
         const dbgr = new Debugger(argv);
@@ -212,8 +194,6 @@ describe('agentmgr',  function() {
             .matchHeader("authorization", test.openwhiskApiAuthHeader())
             .reply(200, agentDescriptionWithoutCode);
 
-        test.mockRemoveBackupAction(action);
-
         // 4. install agent
         test.openwhiskNock()
             .put(
@@ -234,7 +214,6 @@ describe('agentmgr',  function() {
 
         // 6. restore
         test.mockRestoreAction(action, actionCode);
-        test.mockRemoveBackupAction(action);
 
         // -----------------
 
@@ -242,4 +221,94 @@ describe('agentmgr',  function() {
 
         test.assertAllNocksInvoked();
     });
+
+    it("should remove backup action if --cleanup is set", async function() {
+        const action = "myaction";
+        const code = `const main = () => ({ msg: 'CORRECT' });`;
+
+        test.mockActionAndInvocation(
+            action,
+            code,
+            {},
+            { msg: "CORRECT" }
+        );
+
+        test.mockRemoveBackupAction(action);
+        test.openwhiskNock()
+            .get(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_invoked?code=false`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+        test.openwhiskNock()
+            .delete(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_invoked`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+        test.openwhiskNock()
+            .get(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_completed?code=false`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+        test.openwhiskNock()
+            .delete(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_completed`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+
+        const argv = {
+            port: test.port,
+            action: "myaction",
+            cleanup: true
+        };
+
+        const dbgr = new Debugger(argv);
+        await dbgr.start();
+        dbgr.run();
+
+        // wait a bit
+        await test.sleep(500);
+
+        await dbgr.stop();
+
+        test.assertAllNocksInvoked();
+    });
+
+    it("should remove helper actions if --cleanup is set and activation db agent is used", async function() {
+        const action = "myaction";
+        const code = `const main = () => ({ msg: 'CORRECT' });`;
+
+        mockActivationDbAgent(action, code);
+
+        test.mockRemoveBackupAction(action);
+        test.openwhiskNock()
+            .get(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_invoked?code=false`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+        test.openwhiskNock()
+            .delete(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_invoked`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+        test.openwhiskNock()
+            .get(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_completed?code=false`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+        test.openwhiskNock()
+            .delete(`${test.openwhiskApiUrlActions()}/${action}_wskdebug_completed`)
+            .matchHeader("authorization", test.openwhiskApiAuthHeader())
+            .reply(200, {});
+
+        const argv = {
+            port: test.port,
+            action: "myaction",
+            cleanup: true
+        };
+
+        const dbgr = new Debugger(argv);
+        await dbgr.start();
+        dbgr.run();
+
+        // wait a bit
+        await test.sleep(500);
+
+        await dbgr.stop();
+
+        test.assertAllNocksInvoked();
+    });
+
 });
diff --git a/test/ngrok.test.js b/test/ngrok.test.js
index b9485e6..88e2c4b 100644
--- a/test/ngrok.test.js
+++ b/test/ngrok.test.js
@@ -156,7 +156,6 @@ describe('ngrok',  function() {
             .reply(200, test.nodejsActionDescription(actionName));
 
         test.mockRestoreAction(actionName, code);
-        test.mockRemoveBackupAction(actionName);
 
         // wskdebug myaction action.js --ngrok -p ${test.port}
         const argv = {
diff --git a/test/test.js b/test/test.js
index d59e77e..d81bee1 100644
--- a/test/test.js
+++ b/test/test.js
@@ -192,7 +192,6 @@ function expectAgent(name, code, binary=false) {
 
     // shutdown/restore process
     mockRestoreAction(name, code, binary);
-    mockRemoveBackupAction(name);
 }
 
 function nockActivation(name, bodyFn) {


[openwhisk-wskdebug] 06/09: fix missing EOL at end of file

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit 4b4662f2026ce80fdd06969a3c899ce547552bcf
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 23:29:26 2020 -0700

    fix missing EOL at end of file
---
 src/debug.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/debug.js b/src/debug.js
index bbe46f8..17ac7b9 100644
--- a/src/debug.js
+++ b/src/debug.js
@@ -28,4 +28,4 @@ module.exports.task = () => {
     debug();
     delete debug.log;
     return debug;
-}
\ No newline at end of file
+}


[openwhisk-wskdebug] 07/09: remove incorrect and unnecessary module export statements in agents

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit 18cf6a87d6186bf0974d7a5909af33987f12694c
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Mon Apr 13 23:33:17 2020 -0700

    remove incorrect and unnecessary module export statements in agents
---
 agent/agent-activationdb.js | 3 +--
 agent/agent-concurrency.js  | 3 +--
 agent/agent-ngrok.js        | 3 +--
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/agent/agent-activationdb.js b/agent/agent-activationdb.js
index 5234596..f251d2d 100644
--- a/agent/agent-activationdb.js
+++ b/agent/agent-activationdb.js
@@ -150,6 +150,7 @@ async function doMain(args) {
 }
 
 // OpenWhisk does not like raw exceptions, the error object should be the string message only
+// eslint-disable-next-line no-unused-vars
 async function main(args) {
     try {
         return await doMain(args);
@@ -158,5 +159,3 @@ async function main(args) {
         return Promise.reject({ error: e.message, code: e.code});
     }
 }
-
-module.export = main;
diff --git a/agent/agent-concurrency.js b/agent/agent-concurrency.js
index 63ad5a6..90f63e6 100644
--- a/agent/agent-concurrency.js
+++ b/agent/agent-concurrency.js
@@ -137,6 +137,7 @@ async function doMain(args) {
 }
 
 // OpenWhisk does not like raw exceptions, the error object should be the string message only
+// eslint-disable-next-line no-unused-vars
 async function main(args) {
     try {
         return await doMain(args);
@@ -145,5 +146,3 @@ async function main(args) {
         return Promise.reject({ error: e.message, code: e.code});
     }
 }
-
-module.export = main;
diff --git a/agent/agent-ngrok.js b/agent/agent-ngrok.js
index fa71cca..ccb8deb 100644
--- a/agent/agent-ngrok.js
+++ b/agent/agent-ngrok.js
@@ -100,6 +100,7 @@ async function doMain(args) {
 }
 
 // OpenWhisk does not like raw exceptions, the error object should be the string message only
+// eslint-disable-next-line no-unused-vars
 async function main(args) {
     try {
         return await doMain(args);
@@ -108,5 +109,3 @@ async function main(args) {
         return Promise.reject({ error: e.message, code: e.code});
     }
 }
-
-module.export = main;