Removing Cloudant references  (#6)

* Replace Cloudant provider tests with Pluggable Provider system tests

- Remove redundant Cloudant provider tests
- Add Systems Tests to verify basic operations of the pluggable provider
- Create "noop" feed plugin for system tests
- Replace remaining references to "cloudant" in the project repository

* Fixing issues discovered when running on local openwhisk deployment

- Make provider action dependencies explicit rather than relying on runtime.
- Replace Cloudant library with Nano
- Support building & running as Docker image
diff --git a/.travis.yml b/.travis.yml
index 2b9de2a..5f21879 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,12 +30,12 @@
 deploy:
   # deploy latest
   - provider: script
-    script: ./tools/travis/deploy.sh openwhisk cloudantprovider latest
+    script: ./tools/travis/deploy.sh openwhisk pluggable_feed_provider latest
     on:
       branch: master
   # deploy tag
   - provider: script
-    script: ./tools/travis/deploy.sh openwhisk cloudantprovider $TRAVIS_TAG
+    script: ./tools/travis/deploy.sh openwhisk pluggable_feed_provider $TRAVIS_TAG
     on:
       tags: true
       all_branches: true
diff --git a/Dockerfile b/Dockerfile
index 9a4c6d7..853a9d6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,13 +1,11 @@
-FROM node:8.14.0
+FROM node:10
 
-# only package.json
-ADD package.json /
-RUN cd / && npm install --production
+ADD provider /provider
 
-# App
-ADD provider/. /cloudantTrigger/
+WORKDIR /provider
+
+RUN npm install --production
 
 EXPOSE 8080
 
-# Run the app
-CMD ["/bin/bash", "-c", "node /cloudantTrigger/app.js"]
+CMD "./run.sh"
diff --git a/README.md b/README.md
index 472ca3d..abacd93 100644
--- a/README.md
+++ b/README.md
@@ -112,4 +112,40 @@
 - `/<NAMESPACE>/<EVENT_PROVIDER>/changes` 
 - `/<NAMESPACE>/<EVENT_PROVIDER>-web/changesWebAction` 
 
-The `changes` action is used to handle the incoming [trigger feed requests](https://github.com/apache/incubator-openwhisk/blob/master/docs/feeds.md). Trigger feeds events are passed to the `changesWebAction` which interfaces with the Trigger DB table. Changes to this table are listened to by the event provider, which calls the plugin to handle adding and removing trigger event sources.
\ No newline at end of file
+The `changes` action is used to handle the incoming [trigger feed requests](https://github.com/apache/incubator-openwhisk/blob/master/docs/feeds.md). Trigger feeds events are passed to the `changesWebAction` which interfaces with the Trigger DB table. Changes to this table are listened to by the event provider, which calls the plugin to handle adding and removing trigger event sources.
+
+## Testing
+
+Systems tests are available which verifies the following behaviour for the pluggable feed provider:
+
+- Register new triggers for an example feed.
+- Retrieve details of registered triggers. 
+- Fire triggers on external events.
+- Allow removal of registered triggers.
+
+### Setup
+
+These tests use an example "no-op" feed plugin, which fires a single event after trigger registration. This code is available in the `./provider/tests/resources/noop-trigger-feed` directory. Before running the tests, make sure the feed actions have been installed into an instance of the platform using this plugin as the event provider. The provider backend also needs running with this plugin.
+
+The following environment variables need defining before the tests can be executed.
+
+- `OW_NOOP_FEED`: trigger feed action identifier (e.g. `/<NS>/noop-trigger-feed/changes`)
+- `OW_APIHOST`: Apache OpenWhisk platform hostname.
+- `OW_API_KEY`: API key for Apache OpenWhisk instance.
+
+### Running
+
+```
+npm test
+```
+
+The tests consist of a single test case which runs through all the behaviours above with the sample event provider plugin. If successful, the following output should be shown in the console.
+
+```
+> openwhisk-pluggable-provider@0.0.1 test ~/generic-provider/provider
+> ava tests/index.js
+
+  ✔ should be able to create trigger with pluggable provider feed source (3.2s)
+
+  1 test passed
+```
\ No newline at end of file
diff --git a/actions/event-actions/changesFeed_package.json b/actions/event-actions/changesFeed_package.json
index d1738c6..4fdc70d 100644
--- a/actions/event-actions/changesFeed_package.json
+++ b/actions/event-actions/changesFeed_package.json
@@ -1,5 +1,8 @@
 {
   "name": "changesFeed",
   "version": "1.0.0",
-  "main": "changes.js"
+  "main": "changes.js",
+  "dependencies": {
+    "request": "^2.88.0"
+  }
 }
diff --git a/actions/event-actions/changesWeb_package.json b/actions/event-actions/changesWeb_package.json
index 5c46d8d..c3fa807 100644
--- a/actions/event-actions/changesWeb_package.json
+++ b/actions/event-actions/changesWeb_package.json
@@ -3,6 +3,8 @@
   "version": "1.0.0",
   "main": "changesWebAction.js",
   "dependencies" : {
-    "@cloudant/cloudant": "3.0.0"
+    "nano": "^8.1.0",
+    "moment": "^2.24.0",
+    "request": "^2.88.0"
   }
 }
diff --git a/actions/event-actions/lib/Database.js b/actions/event-actions/lib/Database.js
index 9bc180d..04d18e5 100644
--- a/actions/event-actions/lib/Database.js
+++ b/actions/event-actions/lib/Database.js
@@ -2,8 +2,8 @@
 
 // constructor for DB object - a thin, promise-loving wrapper around nano
 module.exports = function(dbURL, dbName) {
-    var cloudant = require('@cloudant/cloudant')(dbURL);
-    this.db = cloudant.db.use(dbName);
+    var nano = require('nano')(dbURL);
+    this.db = nano.db.use(dbName);
     var utilsDB = this;
 
     this.getWorkerID = function(availabeWorkers) {
@@ -53,7 +53,7 @@
                     resolve();
                 }
                 else {
-                    reject(common.sendError(err.statusCode, 'error creating cloudant trigger.', err.message));
+                    reject(common.sendError(err.statusCode, 'error creating plugin provider trigger.', err.message));
                 }
             });
         });
diff --git a/actions/event-actions/lib/common.js b/actions/event-actions/lib/common.js
index 0e23904..aaeb744 100644
--- a/actions/event-actions/lib/common.js
+++ b/actions/event-actions/lib/common.js
@@ -26,11 +26,11 @@
             }
             else {
                 if (response) {
-                    console.log('cloudant: Error invoking whisk action:', response.statusCode, body);
+                    console.log('pluggableProvider: Error invoking whisk action:', response.statusCode, body);
                     reject(body);
                 }
                 else {
-                    console.log('cloudant: Error invoking whisk action:', error);
+                    console.log('pluggableProvider: Error invoking whisk action:', error);
                     reject(error);
                 }
             }
diff --git a/build.gradle b/build.gradle
index 662b5c0..9c7f76a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,2 +1,2 @@
-ext.dockerImageName = 'catalog_cloudanttrigger'
+ext.dockerImageName = 'pluggable_feed_provider'
 apply from: 'gradle/docker.gradle'
diff --git a/installCatalog.sh b/installCatalog.sh
index 8d39d5b..a3a6102 100755
--- a/installCatalog.sh
+++ b/installCatalog.sh
@@ -56,7 +56,6 @@
 
 $WSK_CLI -i --apihost "$EDGEHOST" package update --auth "$AUTH" --shared yes /$NAMESPACE/$EVENT_PROVIDER \
     -a description "$EVENT_PROVIDER service" \
-    -a parameters '[  {"name":"bucket", "required":false, "bindTime":true, "description": "Your Cloudant username"}, {"name":"password", "required":false, "type":"password", "bindTime":true, "description": "Your Cloudant password"}, {"name":"host", "required":true, "bindTime":true, "description": "This is usually your username.cloudant.com"}, {"name":"iamApiKey", "required":false}, {"name":"iamUrl", "required":false}, {"name":"dbname", "required":false, "description": "The name of your Cloudant database"}, {"name":"overwrite", "required":false, "type": "boolean"} ]' \
     -p EVENT_PROVIDER $EVENT_PROVIDER \
     -p NAMESPACE $NAMESPACE \
     -p apihost "$APIHOST"
@@ -69,14 +68,13 @@
 fi
 
 cp -f changesFeed_package.json package.json
-zip -r changesFeed.zip lib package.json changes.js
+npm install
+zip -r changesFeed.zip lib package.json changes.js node_modules
 
 $WSK_CLI -i --apihost "$EDGEHOST" action update --kind "$ACTION_RUNTIME_VERSION" --auth "$AUTH" /$NAMESPACE/$EVENT_PROVIDER/changes "$PACKAGE_HOME/actions/event-actions/changesFeed.zip" \
     -t 90000 \
     -a feed true \
-    -a description 'Event provider change feed' \
-    -a parameters '[ {"name":"dbname", "required":true, "updatable":false}, {"name":"iamApiKey", "required":false, "updatable":false}, {"name":"iamUrl", "required":false, "updatable":false}, {"name": "filter", "required":false, "updatable":true, "type": "string", "description": "The name of your Cloudant database filter"}, {"name": "query_params", "required":false, "updatable":true, "description": "JSON Object containing query parameters that are passed to the filter"} ]' \
-    -a sampleInput '{ "dbname": "mydb", "filter": "mailbox/by_status", "query_params": {"status": "new"} }'
+    -a description 'Event provider change feed'
 
 WEB="-web"
 
diff --git a/provider/Logger.js b/provider/Logger.js
index c4b5261..ce58190 100644
--- a/provider/Logger.js
+++ b/provider/Logger.js
@@ -12,7 +12,7 @@
             },
             formatter: function(options) {
                 // Return string will be passed to logger.
-                return '[' + options.timestamp() +'] ['+ options.level.toUpperCase() +'] [??] [cloudantTrigger] ' + options.message;
+                return '[' + options.timestamp() +'] ['+ options.level.toUpperCase() +'] [??] [pluggableProviderTrigger] ' + options.message;
             }
         })
     ]
diff --git a/provider/app.js b/provider/app.js
index 4cf7376..5d051f3 100644
--- a/provider/app.js
+++ b/provider/app.js
@@ -9,7 +9,6 @@
 const express = require('express');
 const bodyParser = require('body-parser');
 const bluebird = require('bluebird');
-const Cloudant = require('@cloudant/cloudant')
 const redis = require('redis')
 bluebird.promisifyAll(redis.RedisClient.prototype);
 const logger = require('./Logger');
@@ -26,11 +25,17 @@
 app.use(bodyParser.urlencoded({ extended: false }));
 app.set('port', process.env.PORT || 8080);
 
-if (!process.env.DB_URL) {
-  throw new Error('Missing DB_URL environment parameter.')
+const db_env_vars = ['DB_PROTOCOL', 'DB_HOST', 'DB_USERNAME', 'DB_PASSWORD']
+
+for (let env_var of db_env_vars) {
+  if (!process.env[env_var]) {
+    throw new Error(`Missing ${env_var} environment parameter.`)
+  }
 }
 
-const dbUrl = process.env.DB_URL;
+const dbUrl = process.env.DB_PROTOCOL + '://' + process.env.DB_USERNAME + ':' 
+  + process.env.DB_PASSWORD + '@' + process.env.DB_HOST
+
 // This is the database that will store the managed triggers.
 const databaseName = process.env.TRIGGERS_DB || constants.DEFAULT_TRIGGERS_DB;
 
@@ -60,11 +65,11 @@
     const method = 'createDatabase';
     logger.info(method, 'creating the trigger database', dbUrl);
 
-    const cloudant = Cloudant(dbUrl);
+    const nano = require('nano')(dbUrl)
 
-    if (cloudant !== null) {
+    if (nano !== null) {
         return new Promise(function (resolve, reject) {
-            cloudant.db.create(databaseName, function (err, body) {
+            nano.db.create(databaseName, function (err, body) {
                 if (!err) {
                     logger.info(method, 'created trigger database:', databaseName);
                 }
@@ -85,7 +90,7 @@
                     }
                 };
 
-                createDesignDoc(cloudant.db.use(databaseName), viewDDName, viewDD)
+                createDesignDoc(nano.db.use(databaseName), viewDDName, viewDD)
                 .then(db => {
                     const filterDD = {
                         filters: {
@@ -125,7 +130,7 @@
         });
     }
     else {
-        Promise.reject('cloudant provider did not get created.  check db URL: ' + dbUrl);
+        Promise.reject('pluggable feed provider did not get created.  check db URL: ' + dbUrl);
     }
 }
 
@@ -190,7 +195,7 @@
 // Initialize the Provider Server
 function init(server, EventProvider) {
     const method = 'init';
-    let cloudantDb;
+    let database;
     let providerTriggersManager;
 
     if (server !== null) {
@@ -203,11 +208,11 @@
 
     createDatabase()
     .then(db => {
-        cloudantDb = db;
+        database = db;
         return createRedisClient();
     })
     .then(client => {
-        providerTriggersManager = new ProviderTriggersManager(logger, cloudantDb, EventProvider, client);
+        providerTriggersManager = new ProviderTriggersManager(logger, database, EventProvider, client);
         return providerTriggersManager.initRedis();
     })
     .then(() => {
diff --git a/provider/lib/health.js b/provider/lib/health.js
index f329ba9..a205ab9 100644
--- a/provider/lib/health.js
+++ b/provider/lib/health.js
@@ -71,9 +71,9 @@
             deleteDocFromDB(existingCanaryID, 0);
         }
 
-        //create new cloudant trigger and canary doc
+        //create new trigger and canary doc
         var docSuffix = utils.worker + utils.host + '_' + Date.now();
-        triggerName = 'cloudant_' + docSuffix;
+        triggerName = 'pluggable_provider_' + docSuffix;
         canaryDocID = 'canary_' + docSuffix;
 
         //update status monitor object
@@ -212,5 +212,4 @@
             }
         });
     }
-
 };
diff --git a/provider/lib/triggers_manager.js b/provider/lib/triggers_manager.js
index ee162c5..f5672d5 100644
--- a/provider/lib/triggers_manager.js
+++ b/provider/lib/triggers_manager.js
@@ -438,6 +438,7 @@
         authHandler.handleAuth(triggerData)
         .then(auth => {
             options.auth = auth;
+            options.rejectUnauthorized = false
             request(options, cb);
         })
         .catch(err => {
diff --git a/provider/lib/utils.js b/provider/lib/utils.js
index c863d74..5ae07fb 100644
--- a/provider/lib/utils.js
+++ b/provider/lib/utils.js
@@ -84,7 +84,7 @@
                 });
 
                 feed.on('confirm', function () {
-                    logger.info(method, 'Added cloudant data trigger', triggerData.id, 'listening for changes in database', triggerData.dbname);
+                    logger.info(method, 'Added plugin provider data trigger', triggerData.id, 'listening for changes in database', triggerData.dbname);
                     if (isMonitoringTrigger(triggerData.monitor, triggerData.id)) {
                         self.monitorStatus.triggerStarted = "success";
                     }
diff --git a/provider/package.json b/provider/package.json
index 4d665d0..cd996fe 100644
--- a/provider/package.json
+++ b/provider/package.json
@@ -7,10 +7,10 @@
   },
   "scripts": {
     "start": "node app.js",
-    "start-local": "npm link $EVENT_PROVIDER && node app.js"
+    "start-local": "npm link $EVENT_PROVIDER && node app.js",
+    "test": "ava tests/index.js"
   },
   "dependencies": {
-    "@cloudant/cloudant": "3.0.0",
     "bluebird": "^3.5.0",
     "body-parser": "^1.12.0",
     "express": "^4.12.2",
@@ -18,10 +18,15 @@
     "json-stringify-safe": "^5.0.1",
     "lodash": ">=4.17.5",
     "moment": "^2.11.1",
+    "nano": "^8.1.0",
     "redis": "^2.7.1",
     "request": "^2.83.0",
     "request-promise": "^1.0.2",
     "systeminformation": "^3.19.0",
     "winston": "^2.1.1"
+  },
+  "devDependencies": {
+    "ava": "^2.0.0",
+    "openwhisk": "^3.19.0"
   }
 }
diff --git a/provider/run.sh b/provider/run.sh
new file mode 100755
index 0000000..9e0c25a
--- /dev/null
+++ b/provider/run.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -e
+set -u
+
+npm install $EVENT_PROVIDER
+npm start
diff --git a/provider/tests/index.js b/provider/tests/index.js
new file mode 100644
index 0000000..52b1ba1
--- /dev/null
+++ b/provider/tests/index.js
@@ -0,0 +1,71 @@
+"use strict";
+
+import test from 'ava';
+import openwhisk from 'openwhisk';
+
+const TEST_TRIGGER = 'test-trigger'
+const TEST_RULE = 'test-rule'
+
+test.before(async t => {
+  if (!process.env.OW_APIHOST) {
+    throw new Error('Missing OW_APIHOST environment parameter')
+  }
+
+  if (!process.env.OW_API_KEY) {
+    throw new Error('Missing OW_API_KEY environment parameter')
+  }
+
+  if (!process.env.OW_NOOP_FEED) {
+    throw new Error('Missing OW_NOOP_FEED environment parameter')
+  }
+
+  const options = { apihost: process.env.OW_APIHOST, api_key: process.env.OW_API_KEY }
+  const ow = openwhisk(options)
+  t.context.ow = ow
+
+  await ow.triggers.update({ name: TEST_TRIGGER })
+  await ow.rules.update({name: TEST_RULE, action: '/whisk.system/utils/echo', trigger: TEST_TRIGGER})
+})
+
+test('should be able to create trigger with pluggable provider feed source', async t => {
+  const params = {trigger_payload: {value: 'testing 1 2 3'}}
+  const name = process.env.OW_NOOP_FEED
+
+  const ow = t.context.ow
+
+  const now = Date.now()
+
+  // register trigger feed with provider
+  const create_result = await ow.feeds.create({name, trigger: TEST_TRIGGER, params})
+  t.true(create_result.response.success, 'create trigger feed worked')
+
+  // retrieve trigger details from feed provider
+  const result = await ow.feeds.get({name, trigger: TEST_TRIGGER})
+
+  t.true(result.response.result.status.active, 'test trigger feed is enabled')
+  t.true(result.response.result.config._id.endsWith(TEST_TRIGGER))
+  
+  let activations = []
+  while(activations.length < 1) {
+    activations = await ow.activations.list({since: now})
+    activations = activations.filter(actv => actv.name === 'echo')
+  }
+
+  // remote trigger from feed provider
+  await ow.feeds.delete({name, trigger: TEST_TRIGGER})
+
+  // should fail to retrieve once trigger is removed from feed provider.
+  try {
+    await ow.feeds.get({name, trigger: TEST_TRIGGER})
+    t.fail()
+  } catch (err) {
+    t.true(!!err.message.match('could not find trigger'));
+  }
+});
+
+test.after.always('cleanup', async t => {
+  const ow = t.context.ow
+
+  await ow.triggers.delete({ name: TEST_TRIGGER })
+  await ow.rules.delete({ name: TEST_RULE })
+});
diff --git a/provider/tests/resources/noop-trigger-feed/index.js b/provider/tests/resources/noop-trigger-feed/index.js
new file mode 100644
index 0000000..9f5b108
--- /dev/null
+++ b/provider/tests/resources/noop-trigger-feed/index.js
@@ -0,0 +1,13 @@
+module.exports = function (trigger_manager, logger) {
+  const add = async (trigger_id, trigger_params) => {
+    setTimeout(() => {
+      console.log('firing trigger once', trigger_id, trigger_params)
+      trigger_manager.fireTrigger(trigger_id, trigger_params)
+    }, 1000)
+  }
+  const remove = async trigger_id => {}
+
+  return { add, remove }
+}
+
+module.exports.validate = async trigger_params => ({})
diff --git a/provider/tests/resources/noop-trigger-feed/package.json b/provider/tests/resources/noop-trigger-feed/package.json
new file mode 100644
index 0000000..1df8a2c
--- /dev/null
+++ b/provider/tests/resources/noop-trigger-feed/package.json
@@ -0,0 +1,11 @@
+{
+  "name": "noop-trigger-feed",
+  "version": "1.0.0",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "James Thomas <james@jamesthom.as> (https://jamesthom.as)",
+  "license": "Apache-2.0"
+}
diff --git a/settings.gradle b/settings.gradle
index 4e7220b..35b0ed8 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,6 +1,6 @@
 include 'tests'
 
-rootProject.name = 'openwhisk-package-cloudant'
+rootProject.name = 'openwhisk-pluggable-provider'
 
 gradle.ext.openwhisk = [
         version: '1.0.0-SNAPSHOT'
diff --git a/tests/build.gradle b/tests/build.gradle
deleted file mode 100644
index 0589ef3..0000000
--- a/tests/build.gradle
+++ /dev/null
@@ -1,39 +0,0 @@
-apply plugin: 'scala'
-apply plugin: 'eclipse'
-compileTestScala.options.encoding = 'UTF-8'
-
-
-repositories {
-    mavenCentral()
-    maven {
-        url 'https://oss.sonatype.org/content/repositories/snapshots/'
-    }
-    mavenLocal()
-
-}
-
-tasks.withType(Test) {
-    testLogging {
-        events "passed", "skipped", "failed"
-        showStandardStreams = true
-        exceptionFormat = 'full'
-    }
-    outputs.upToDateWhen { false } // force tests to run every time
-}
-
-task testHealth(type: Test) {
-    systemProperty 'test.router', 'true'
-    include 'system/health/**'
-}
-
-dependencies {
-    compile "org.scala-lang:scala-library:${gradle.scala.version}"
-    compile 'com.cloudant:cloudant-client:1.0.1'
-    compile "org.apache.openwhisk:openwhisk-tests:${gradle.openwhisk.version}:tests"
-    compile "org.apache.openwhisk:openwhisk-tests:${gradle.openwhisk.version}:test-sources"
-
-}
-
-tasks.withType(ScalaCompile) {
-    scalaCompileOptions.additionalParameters = gradle.scala.compileFlags
-}
diff --git a/tests/dat/attach.txt b/tests/dat/attach.txt
deleted file mode 100644
index 630ac45..0000000
--- a/tests/dat/attach.txt
+++ /dev/null
@@ -1 +0,0 @@
-My hovercraft is full of eels!
diff --git a/tests/dat/filterdesigndoc.txt b/tests/dat/filterdesigndoc.txt
deleted file mode 100644
index c62bd45..0000000
--- a/tests/dat/filterdesigndoc.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "_id": "_design/test_filter",
-    "filters": {
-      "fruit": "function (doc, req) { return doc.kind === 'fruit' || (req && req.query && req.query.type === doc.type); }",
-      "vegetable": "function (doc, req) { return doc.kind === 'vegetable' || (req && req.query && req.query.type === doc.type); }"
-    }
-}
diff --git a/tests/dat/indexdesigndoc.txt b/tests/dat/indexdesigndoc.txt
deleted file mode 100644
index 0ea3d2b..0000000
--- a/tests/dat/indexdesigndoc.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "ddoc":"test-query-index",
-  "name": "test-query-index",
-  "type": "json", 
-  "index": {
-    "fields": ["date"]
-  }
-}
diff --git a/tests/dat/searchdesigndoc.txt b/tests/dat/searchdesigndoc.txt
deleted file mode 100644
index 833827c..0000000
--- a/tests/dat/searchdesigndoc.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "_id": "_design/test_design",
-  "views": {
-    "test_view": {
-      "map": "function (doc) {\n  emit(doc._id, 1);\n}"
-    }
-  },
-  "language": "javascript",
-  "indexes": {
-    "test_search": {
-      "analyzer": "standard",
-      "index": "function (doc) {\n  index(\"date\", doc.date);\n}"
-    }
-  }
-}
diff --git a/tests/src/test/scala/system/CloudantUtil.java b/tests/src/test/scala/system/CloudantUtil.java
deleted file mode 100755
index a8c9c61..0000000
--- a/tests/src/test/scala/system/CloudantUtil.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * 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.
- */
-package system;
-
-import com.cloudant.client.api.CloudantClient;
-import com.cloudant.client.api.Database;
-import com.google.gson.*;
-import com.jayway.restassured.response.Response;
-import common.TestUtils;
-
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.Date;
-import java.util.Map;
-import java.util.Properties;
-import java.util.UUID;
-
-import static com.jayway.restassured.RestAssured.given;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Basic tests of the cloudant trigger function.
- */
-public class CloudantUtil {
-    public static final String USER_PROPERTY = "user";
-    public static final String PWD_PROPERTY = "password";
-    public static final String DBNAME_PROPERTY = "dbname";
-    public static final String DOC_ID = "testId";
-
-    /**
-     * The root of the Cloudant installation.
-     */
-    private static final String CLOUDANT_INSTALL_FILE = "installCatalog.sh";
-    private static final String CLOUDANT_HOME = getCloudantHome();
-    public static final File ATTACHMENT_FILE_PATH = getFileRelativeToCloudantHome("tests/dat/attach.txt");
-    public static final File INDEX_DDOC_PATH = getFileRelativeToCloudantHome("tests/dat/indexdesigndoc.txt");
-    public static final File VIEW_AND_SEARCH_DDOC_PATH = getFileRelativeToCloudantHome("tests/dat/searchdesigndoc.txt");
-    public static final File FILTER_DDOC_PATH = getFileRelativeToCloudantHome("tests/dat/filterdesigndoc.txt");
-
-    private static Gson gson = new Gson();
-
-    private static class ResponsePair {
-        public final Integer fst;
-        public final JsonObject snd;
-
-        public ResponsePair(Integer a, JsonObject b) {
-            this.fst = a;
-            this.snd = b;
-        }
-    }
-
-    public static class Credential {
-        public final String user;
-        public final String password;
-        public final String dbname;
-
-        public String host() {
-            return user + ".cloudant.com";
-        }
-
-        public Credential(String user, String password, String dbname) {
-            this.user = user;
-            this.password = password;
-            this.dbname = dbname;
-        }
-
-        public Credential(Properties props) {
-            this(props.getProperty(USER_PROPERTY), props.getProperty(PWD_PROPERTY), props.getProperty(DBNAME_PROPERTY));
-        }
-
-        public static Credential makeFromVCAPFile(String vcapService, String dbNamePrefix) {
-            // Create database name using dbNamePrefix and generated uuid
-            String uniqueSuffix = UUID.randomUUID().toString().replace("-", "");
-            String dbname = dbNamePrefix.toLowerCase() + "-" + uniqueSuffix;
-
-            Map<String,String> credentials = TestUtils.getVCAPcredentials(vcapService);
-            String username = credentials.get("username");
-            String password = credentials.get("password");
-            Properties props = new Properties();
-            props.setProperty(USER_PROPERTY, username);
-            props.setProperty(PWD_PROPERTY, password);
-            props.setProperty(DBNAME_PROPERTY, dbname);
-            return new Credential(props);
-        }
-
-    }
-
-    public static void setUp(Credential credential) throws Exception {
-        deleteTestDatabase(credential);
-        for (int i = 0; i < 5; i++) {
-            try {
-                ResponsePair response = CloudantUtil.createTestDatabase(credential, false);
-                if (response.fst == 201)
-                    return;
-                // respond code is sometimes not 201 but still ok
-                // (might be 200 or 202)
-                if (response.snd.has("ok")) {
-                    if (response.snd.get("ok").getAsBoolean())
-                        return;
-                }
-                if (response.snd.has("reason")) {
-                    String reason = response.snd.get("reason").getAsString();
-                    if (reason.contains("exists"))
-                        return;
-                }
-            } catch (Throwable t) {
-                Thread.sleep(1000);
-            }
-        }
-        assertTrue("failed to create database " + credential.dbname, false);
-    }
-
-    public static void unsetUp(Credential credential) throws Exception {
-        deleteTestDatabase(credential);
-    }
-
-    /**
-     * Delete a user-specific Cloudant database.
-     *
-     * @throws UnsupportedEncodingException
-     * @throws InterruptedException
-     */
-    public static JsonObject deleteTestDatabase(Credential credential) throws UnsupportedEncodingException, InterruptedException {
-        return deleteTestDatabase(credential, null);
-    }
-
-    public static JsonObject deleteTestDatabase(Credential credential, String dbName) throws UnsupportedEncodingException, InterruptedException {
-        // Use DELETE to delete the database.
-        // This could fail if the database already exists, but that's ok.
-        Response response = null;
-        String db = (dbName != null && !dbName.isEmpty()) ? dbName : credential.dbname;
-        assertTrue("failed to determine database name", db != null && !db.isEmpty());
-        response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().delete("/" + db);
-        System.out.format("Response of delete database %s: %s\n", db, response.asString());
-        return (JsonObject) new JsonParser().parse(response.asString());
-    }
-
-    /**
-     * Create a user-specific Cloudant database that will be used for this test.
-     *
-     * @throws UnsupportedEncodingException
-     */
-    public static ResponsePair createTestDatabase(Credential credential) throws UnsupportedEncodingException {
-        return createTestDatabase(credential, true);
-    }
-
-    private static ResponsePair createTestDatabase(Credential credential, boolean failIfCannotCreate) throws UnsupportedEncodingException {
-        // Use PUT to create the database.
-        // This could fail if the database already exists, but that's ok.
-        String dbName = credential.dbname;
-        assertTrue("failed to determine database name", dbName != null && !dbName.isEmpty());
-        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().put("/" + dbName);
-        System.out.format("Response of create database %s: %s\n", dbName, response.asString());
-        if (failIfCannotCreate)
-            assertTrue("failed to create database " + dbName, response.statusCode() == 201 || response.statusCode() == 202);
-        return new ResponsePair(response.statusCode(), (JsonObject) new JsonParser().parse(response.asString()));
-    }
-
-    /**
-     * read a user-specific Cloudant database to verify database action test
-     * cases.
-     *
-     * @throws UnsupportedEncodingException
-     */
-    public static JsonObject readTestDatabase(Credential credential) {
-        try {
-            String db = credential.dbname;
-            Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().get("/" + db);
-            System.out.format("Response of HTTP GET for database %s: %s\n", credential.dbname, response.asString());
-            return gson.fromJson(response.asString(), JsonObject.class);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static Response readTestDatabase(Credential credential, String dbName) {
-        try {
-            String db = (dbName != null && !dbName.isEmpty()) ? dbName : credential.dbname;
-            Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).when().get("/" + db);
-            System.out.format("Response of HTTP GET for database %s: %s\n", credential.dbname, response.asString());
-            return response;
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    /**
-     * create a document in the cloudant database
-     *
-     * @throws UnsupportedEncodingException
-     */
-    public static JsonObject createDocument(Credential credential, String jsonObj) throws UnsupportedEncodingException {
-        JsonObject obj = new JsonParser().parse(jsonObj).getAsJsonObject();
-
-        CloudantClient client = new CloudantClient(credential.user, credential.user, credential.password);
-        Database db = client.database(credential.dbname, false);
-        com.cloudant.client.api.model.Response res = db.post(obj);
-        client.shutdown();
-
-        JsonObject ret = new JsonObject();
-        ret.addProperty("ok", true);
-        ret.addProperty("id", res.getId());
-        ret.addProperty("rev", res.getRev());
-        return ret;
-    }
-
-    /**
-     * get a document from the cloudant database
-     *
-     * @throws UnsupportedEncodingException
-     */
-    public static JsonObject getDocument(Credential credential, String docId) throws UnsupportedEncodingException {
-        // use GET to get the document
-        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).get("/" + credential.dbname + "/" + docId);
-        String responseStr = response.asString();
-        if (responseStr.length() > 500)
-            responseStr = responseStr.substring(0, 500);
-        System.out.format("Response of get document from database %s: %s\n", credential.dbname, responseStr);
-        return (JsonObject) new JsonParser().parse(response.asString());
-    }
-
-    /**
-     * delete a document from the cloudant database
-     *
-     * @throws UnsupportedEncodingException
-     */
-    public static JsonObject deleteDocument(Credential credential, JsonObject jsonObj) throws UnsupportedEncodingException {
-        CloudantClient client = new CloudantClient(credential.user, credential.user, credential.password);
-        Database db = client.database(credential.dbname, false);
-        com.cloudant.client.api.model.Response res = null;
-        try {
-            res = db.remove(jsonObj);
-        }
-        catch(Exception e) {
-            System.out.format("Exception thrown during document delete: %s", e.toString());
-        }
-        finally {
-            client.shutdown();
-        }
-
-        JsonObject ret = new JsonObject();
-        ret.addProperty("id", res.getId());
-        ret.addProperty("rev", res.getRev());
-        return ret;
-    }
-
-    /**
-     * Read bulk documents from the cloudant database
-     *
-     * @throws UnsupportedEncodingException
-     */
-    public static JsonArray bulkDocuments(Credential credential, JsonArray bulkDocs) throws UnsupportedEncodingException {
-        JsonObject docs = new JsonObject();
-        docs.add("docs", bulkDocs);
-        // use GET to get the document
-        String dbname = credential.dbname;
-        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).contentType("application/json").body(docs.toString()).post("/" + credential.dbname + "/_bulk_docs?include_docs=true");
-        String responseStr = response.asString();
-        if (responseStr.length() > 500)
-            responseStr = responseStr.substring(0, 500);
-        System.out.format("Response of get document from database %s: %s\n", dbname, responseStr);
-        return (JsonArray) new JsonParser().parse(response.asString());
-    }
-
-    public static JsonObject createDocParameterForWhisk() {
-        return createDocParameterForWhisk(null);
-    }
-
-    public static JsonObject createDocParameterForWhisk(String doc) {
-        JsonObject cloudantDoc = new JsonObject();
-        String now = new Date().toString();
-        cloudantDoc.addProperty("_id", DOC_ID);
-        cloudantDoc.addProperty("date", now);
-        // Create JSON object that will be passed as an argument to whisk cli
-        JsonObject param = new JsonObject();
-        if (doc != null && !doc.isEmpty()) {
-            param.addProperty("doc", doc);
-        } else {
-            param.addProperty("doc", cloudantDoc.toString());
-        }
-        return param;
-    }
-
-    public static JsonArray createDocumentArray(int numDocs) {
-        // Array of docs for bulk
-        JsonArray bulkDocs = new JsonArray();
-        for (int i = 1; i <= numDocs; i++) {
-            JsonObject cloudantDoc = new JsonObject();
-            String now = new Date().toString();
-            cloudantDoc.addProperty("_id", CloudantUtil.DOC_ID + i);
-            cloudantDoc.addProperty("date", now);
-            bulkDocs.add(cloudantDoc);
-        }
-        return bulkDocs;
-    }
-
-    /**
-     * Only keep _id and _rev for each document in the JSON array.
-     */
-    public static JsonArray updateDocsWithOnlyIdAndRev(JsonArray docs) {
-        for (int i = 0; i < docs.size(); i++) {
-            JsonElement id = docs.get(i).getAsJsonObject().get("id");
-            JsonElement rev = docs.get(i).getAsJsonObject().get("rev");
-            docs.get(i).getAsJsonObject().add("_id", id);
-            docs.get(i).getAsJsonObject().add("_rev", rev);
-        }
-        return docs;
-    }
-
-    public static JsonArray addDeletedPropertyToDocs(JsonArray docs) {
-        for (int i = 0; i < docs.size(); i++) {
-            JsonElement id = docs.get(i).getAsJsonObject().get("id");
-            JsonElement rev = docs.get(i).getAsJsonObject().get("rev");
-            docs.get(i).getAsJsonObject().add("_id", id);
-            docs.get(i).getAsJsonObject().add("_rev", rev);
-            docs.get(i).getAsJsonObject().addProperty("_deleted", true);
-        }
-        return docs;
-    }
-
-    public static JsonObject createDesignFromFile(File jsonFile) throws JsonSyntaxException, IOException {
-        return gson.fromJson(readFile(jsonFile), JsonObject.class);
-    }
-
-    public static String readFile(File jsonFile) throws IOException {
-        return new String(Files.readAllBytes(jsonFile.toPath()), StandardCharsets.UTF_8);
-    }
-
-    /**
-     * Create an index in the cloudant database
-     *
-     * @throws UnsupportedEncodingException
-     */
-    public static JsonObject createIndex(Credential credential, String jsonObj) throws UnsupportedEncodingException {
-        Response response = given().port(443).baseUri(cloudantAccount(credential.user)).auth().basic(credential.user, credential.password).contentType("application/json").body(jsonObj).when().post("/" + credential.dbname + "/_index");
-        System.out.format("Response of create document in database %s: %s\n", credential.dbname, response.asString());
-        assertTrue("failed to create index in database " + credential.dbname, response.statusCode() == 200);
-        return (JsonObject) new JsonParser().parse(response.asString());
-    }
-
-    /**
-     * Create a document with attachment in a cloudant database
-     *
-     * @throws UnsupportedEncodingException
-     * @throws FileNotFoundException
-     */
-    public static com.cloudant.client.api.model.Response createDocumentWithAttachment(Credential credential, File attachmentFilePath) throws UnsupportedEncodingException, FileNotFoundException {
-        InputStream attachStream = new FileInputStream(attachmentFilePath);
-        String contentType = "text/plain";
-
-        CloudantClient client = new CloudantClient(credential.user, credential.user, credential.password);
-        Database db = client.database(credential.dbname, false);
-        return db.saveAttachment(attachStream, attachmentFilePath.getName(), contentType);
-    }
-
-    private static String cloudantAccount(String user) {
-        return "https://" + user + ".cloudant.com";
-    }
-
-    public static File getFileRelativeToCloudantHome(String name) {
-        return new File(CLOUDANT_HOME, name);
-    }
-
-    private static String getCloudantHome() {
-        String dir = System.getProperty("user.dir");
-
-        if (dir != null) {
-            // Look in the directory tree recursively.
-            File propfile = findFileRecursively(dir, CLOUDANT_INSTALL_FILE);
-            return propfile != null ? propfile.getParent() : null;
-        } else return null;
-    }
-
-    private static File findFileRecursively(String dir, String needle) {
-        if (dir != null) {
-            File base = new File(dir);
-            File file = new File(base, needle);
-            if (file.exists()) {
-                return file;
-            } else {
-                return findFileRecursively(base.getParent(), needle);
-            }
-        } else return null;
-    }
-
-}
diff --git a/tests/src/test/scala/system/health/CloudantHealthFeedTests.scala b/tests/src/test/scala/system/health/CloudantHealthFeedTests.scala
deleted file mode 100644
index 545178e..0000000
--- a/tests/src/test/scala/system/health/CloudantHealthFeedTests.scala
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * 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.
- */
-package system.health
-
-import java.time.{Clock, Instant}
-
-import org.junit.runner.RunWith
-import org.scalatest.{BeforeAndAfterEach, FlatSpec, Inside}
-import org.scalatest.junit.JUnitRunner
-import common._
-import spray.json.DefaultJsonProtocol._
-import spray.json._
-import system.CloudantUtil
-
-/**
- * Tests for Cloudant trigger service
- */
-@RunWith(classOf[JUnitRunner])
-class CloudantHealthFeedTests
-    extends FlatSpec
-    with TestHelpers
-    with Inside
-    with WskTestHelpers
-    with WskActorSystem
-    with BeforeAndAfterEach {
-
-    val wskprops = WskProps()
-    val wsk = new Wsk
-    val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
-    val myCloudantCreds = CloudantUtil.Credential.makeFromVCAPFile("cloudantNoSQLDB", this.getClass.getSimpleName)
-    val maxRetries = System.getProperty("max.retries", "30").toInt
-
-    behavior of "Cloudant Health trigger service"
-
-    override def beforeEach() = {
-        CloudantUtil.setUp(myCloudantCreds)
-        CloudantUtil.createDocument(myCloudantCreds, "{\"_id\":\"testid\", \"kind\":\"vegetable\", \"type\":\"tomato\"}")
-    }
-
-    override def afterEach() = {
-        // wait 10 seconds to give the cloudant provider a chance to clean
-        // up trigger feeds before deleting the database
-        Thread.sleep(10 * 1000)
-        CloudantUtil.unsetUp(myCloudantCreds)
-    }
-
-    it should "fire changes when a document is created" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val ruleName = s"dummyCloudantRule-${System.currentTimeMillis}"
-            val actionName = s"dummyCloudantAction-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            // the package cloudant should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("fetched package cloudant")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            // create action
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, defaultAction)
-            }
-
-            // create whisk stuff
-            println(s"Creating trigger: $triggerName")
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> myCloudantCreds.user.toJson,
-                        "password" -> myCloudantCreds.password.toJson,
-                        "host" -> myCloudantCreds.host().toJson,
-                        "dbname" -> myCloudantCreds.dbname.toJson))
-            }
-
-            // create rule
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, name) => rule.create(name, trigger = triggerName, action = actionName)
-            }
-
-            val activationsBeforeChange = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-            activationsBeforeChange should be(0)
-
-            // create a test doc in the sample db
-            CloudantUtil.createDocument(myCloudantCreds, "{\"test\":\"test_doc1\"}")
-            val now = Instant.now(Clock.systemUTC())
-            println(s"created a test doc at $now")
-
-            // get activation list of the trigger, expecting exactly 1
-            val activations = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-            val nowPoll = Instant.now(Clock.systemUTC())
-            println(s"Found activation size ($nowPoll): $activations")
-            withClue("Change feed trigger count: ") { activations should be(1) }
-
-            // delete the whisk trigger, which must also delete the feed
-            wsk.trigger.delete(triggerName)
-
-            // recreate the trigger now without the feed
-            wsk.trigger.create(triggerName)
-
-            // create a test doc in the sample db, this should not fire the trigger
-            println("create another test doc")
-            CloudantUtil.createDocument(myCloudantCreds, "{\"test\":\"test_doc2\"}")
-
-            println("checking for new triggers (no new ones expected)")
-            val activationsAfterDelete = wsk.activation.pollFor(N = 2, Some(triggerName)).length
-            println(s"Found activation size after delete: $activationsAfterDelete")
-            activationsAfterDelete should be(1)
-    }
-
-    it should "fire changes when a document is deleted" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val ruleName = s"dummyCloudantRule-${System.currentTimeMillis}"
-            val actionName = s"dummyCloudantAction-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("Fetching cloudant package.")
-            packageGetResult.stdout should include("ok")
-
-            println("Creating cloudant package binding.")
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            // create action
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, defaultAction)
-            }
-
-            println(s"Creating trigger: $triggerName")
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> myCloudantCreds.user.toJson,
-                        "password" -> myCloudantCreds.password.toJson,
-                        "host" -> myCloudantCreds.host().toJson,
-                        "dbname" -> myCloudantCreds.dbname.toJson,
-                        "maxTriggers" -> (-1).toJson))
-            }
-
-            // create rule
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, name) => rule.create(name, trigger = triggerName, action = actionName)
-            }
-
-            val activationsBeforeDelete = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-            activationsBeforeDelete should be(0)
-
-            // delete a test doc in the sample db and verify trigger is fired
-            println("delete a test doc")
-            CloudantUtil.deleteDocument(myCloudantCreds, CloudantUtil.getDocument(myCloudantCreds, "testid"))
-
-            val activations = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-            activations should be(1)
-    }
-
-    it should "return correct status and configuration" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            // the package cloudant should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("fetched package cloudant")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            //Create filter design doc
-            val filterDesignDoc = CloudantUtil.createDesignFromFile(CloudantUtil.FILTER_DDOC_PATH).toString
-            val getResponse = CloudantUtil.createDocument(myCloudantCreds, filterDesignDoc)
-            getResponse.get("ok").getAsString shouldBe "true"
-
-            val username = myCloudantCreds.user
-            val password = myCloudantCreds.password
-            val host = myCloudantCreds.host()
-            val dbName = myCloudantCreds.dbname
-            val port = 443
-            val protocol = "https"
-            val since = "0"
-            val filter = "test_filter/fruit"
-            val queryParams = JsObject("type" -> JsString("tomato"))
-
-            // create trigger feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> username.toJson,
-                        "password" -> password.toJson,
-                        "host" -> host.toJson,
-                        "dbname" -> dbName.toJson,
-                        "filter" -> filter.toJson,
-                        "query_params" -> queryParams,
-                        "protocol" -> protocol.toJson,
-                        "port" -> port.toJson,
-                        "since" -> since.toJson
-                    ))
-            }
-            feedCreationResult.stdout should include("ok")
-
-            val actionName = s"$packageName/$feed"
-            val run = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, run) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = result.getFields("config").head.asInstanceOf[JsObject].fields
-                            val status = result.getFields("status").head.asInstanceOf[JsObject].fields
-
-                            config should contain("name" -> triggerName.toJson)
-                            config should contain("username" -> username.toJson)
-                            config should contain("password" -> password.toJson)
-                            config should contain("dbname" -> dbName.toJson)
-                            config should contain("filter" -> filter.toJson)
-                            config should contain("query_params" -> queryParams)
-                            config should contain("protocol" -> protocol.toJson)
-                            config should contain("port" -> port.toJson)
-                            config should contain("since" -> since.toJson)
-                            config should contain key "namespace"
-
-                            status should contain("active" -> true.toJson)
-                            status should contain key "dateChanged"
-                            status should contain key "dateChangedISO"
-                            status should not(contain key "reason")
-                    }
-            }
-    }
-
-    it should "update filter and query_params parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            // the package cloudant should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("fetched package cloudant")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            //Create filter design doc
-            val filterDesignDoc = CloudantUtil.createDesignFromFile(CloudantUtil.FILTER_DDOC_PATH).toString
-            val getResponse = CloudantUtil.createDocument(myCloudantCreds, filterDesignDoc)
-            getResponse.get("ok").getAsString shouldBe "true"
-
-            val username = myCloudantCreds.user
-            val password = myCloudantCreds.password
-            val host = myCloudantCreds.host()
-            val dbName = myCloudantCreds.dbname
-            val filter = "test_filter/fruit"
-            val queryParams = JsObject("type" -> JsString("tomato"))
-
-            // create trigger feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> username.toJson,
-                        "password" -> password.toJson,
-                        "host" -> host.toJson,
-                        "dbname" -> dbName.toJson,
-                        "filter" -> filter.toJson,
-                        "query_params" -> queryParams,
-                        "since" -> "0".toJson
-                    ))
-            }
-            feedCreationResult.stdout should include("ok")
-
-            val actionName = s"$packageName/$feed"
-            val readRunResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, readRunResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                            config should contain("filter" -> filter.toJson)
-                            config should contain("query_params" -> queryParams)
-                    }
-            }
-
-            val updatedFilter = "test_filter/vegetable"
-            val updatedQueryParams = JsObject("type" -> JsString("celery"))
-
-            val updateRunAction = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "UPDATE".toJson,
-                "authKey" -> wskProps.authKey.toJson,
-                "filter" -> updatedFilter.toJson,
-                "query_params" -> updatedQueryParams
-            ))
-
-            withActivation(wsk.activation, updateRunAction) {
-                activation => activation.response.success shouldBe true
-            }
-
-            val runResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, runResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                            config should contain("filter" -> updatedFilter.toJson)
-                            config should contain("query_params" -> updatedQueryParams)
-                    }
-            }
-
-    }
-}
diff --git a/tests/src/test/scala/system/packages/CloudantAccountActionsTests.scala b/tests/src/test/scala/system/packages/CloudantAccountActionsTests.scala
deleted file mode 100644
index eeb593c..0000000
--- a/tests/src/test/scala/system/packages/CloudantAccountActionsTests.scala
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * 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.
- */
-package system.packages
-
-import common._
-import org.junit.runner.RunWith
-import org.scalatest.FlatSpec
-import org.scalatest.junit.JUnitRunner
-import spray.json.DefaultJsonProtocol._
-import spray.json._
-import system.CloudantUtil
-import org.apache.openwhisk.utils.JsHelpers
-
-import scala.collection.mutable.HashSet
-
-@RunWith(classOf[JUnitRunner])
-class CloudantAccountActionsTests extends FlatSpec
-    with TestHelpers
-    with WskTestHelpers {
-
-    val wskprops = WskProps()
-    val wsk = new Wsk
-
-    val credential = CloudantUtil.Credential.makeFromVCAPFile("cloudantNoSQLDB", this.getClass.getSimpleName)
-
-    behavior of "Cloudant account actions"
-
-
-    it should """create cloudant database""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-            val dbName = credential.dbname.concat("create_db")
-
-            try {
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson))
-                }
-
-                //create database
-                println("Invoking the create-database action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/create-database",
-                    Map("dbname" -> dbName.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                }
-                val response = CloudantUtil.readTestDatabase(credential, dbName)
-                response.getStatusCode should be (200)
-            }
-            finally {
-                CloudantUtil.deleteTestDatabase(credential, dbName)
-            }
-    }
-
-    it should """create cloudant database with undefined dbname""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("Fetching cloudant package.")
-            packageGetResult.stdout should include("ok")
-
-            println("Creating cloudant package binding.")
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) =>
-                    pkg.bind("/whisk.system/cloudant", name,
-                        Map("username" -> credential.user.toJson,
-                            "password" -> credential.password.toJson,
-                            "host" -> credential.host().toJson))
-            }
-
-            //create database
-            println("Invoking the create-database action.")
-            withActivation(wsk.activation, wsk.action.invoke(s"$packageName/create-database")) {
-                activation =>
-                    activation.response.success shouldBe false
-                    val result = activation.response.result.get
-                    result.fields.get("error") shouldBe Some(JsString("dbname is required."))
-            }
-    }
-
-    it should """read cloudant database""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson))
-                }
-
-                println("Invoking the read-database action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/read-database",
-                    Map("dbname" -> credential.dbname.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("db_name") shouldBe Some(JsString(credential.dbname))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read cloudant database that does not exist""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("Fetching cloudant package.")
-            packageGetResult.stdout should include("ok")
-
-            println("Creating cloudant package binding.")
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) =>
-                    pkg.bind("/whisk.system/cloudant", name,
-                        Map("username" -> credential.user.toJson,
-                            "password" -> credential.password.toJson,
-                            "host" -> credential.host().toJson))
-            }
-
-            println("Invoking the read-database action.")
-            withActivation(wsk.activation, wsk.action.invoke(s"$packageName/read-database",
-                Map("dbname" -> "doesNotExistDB".toJson))) {
-                activation =>
-                    activation.response.success shouldBe false
-                    val result = activation.response.result.get
-                    JsHelpers.getFieldPath(result, "error", "statusCode") shouldBe Some(JsNumber(404))
-            }
-    }
-
-    it should """delete cloudant database""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson))
-                }
-
-                println("Invoking the delete-database action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/delete-database",
-                    Map("dbname" -> credential.dbname.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                }
-                val response = CloudantUtil.readTestDatabase(credential)
-                response.get("error").getAsString shouldBe "not_found"
-                response.get("reason").getAsString shouldBe "Database does not exist."
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """delete cloudant database with incorrect hostname""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> "invalidHost".toJson))
-                }
-
-                println("Invoking the delete-database action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/delete-database",
-                    Map("dbname" -> credential.dbname.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe defined
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list all cloudant databases""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson))
-                }
-
-                println("Invoking the list-all-databases action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/list-all-databases")) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        val matchedDBs = new HashSet[JsValue]
-                        val databases = result.fields("all_databases").asInstanceOf[JsArray].elements
-                        databases map {
-                            case x@JsString(credential.dbname) => matchedDBs.add(x)
-                            case _ => None
-                        }
-                        matchedDBs.size should be > 0
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list all cloudant databases with incorrect user""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> "invalidUser".toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson))
-                }
-
-                println("Invoking the list-all-databases action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/list-all-databases")) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        JsHelpers.getFieldPath(result, "error", "statusCode") shouldBe Some(JsNumber(401))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-}
diff --git a/tests/src/test/scala/system/packages/CloudantBindingTests.scala b/tests/src/test/scala/system/packages/CloudantBindingTests.scala
deleted file mode 100644
index 52bff54..0000000
--- a/tests/src/test/scala/system/packages/CloudantBindingTests.scala
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.
- */
-package system.packages
-
-import common.{TestHelpers, Wsk, WskProps, WskTestHelpers}
-import org.junit.runner.RunWith
-import org.scalatest.FlatSpec
-import org.scalatest.junit.JUnitRunner
-import spray.json.DefaultJsonProtocol._
-import spray.json._
-import system.CloudantUtil
-
-@RunWith(classOf[JUnitRunner])
-class CloudantBindingTests extends FlatSpec
-    with TestHelpers
-    with WskTestHelpers {
-
-    val wskprops = WskProps()
-    val wsk = new Wsk
-
-    val myCloudantCreds = CloudantUtil.Credential.makeFromVCAPFile("cloudantNoSQLDB", this.getClass.getSimpleName)
-
-    behavior of "Cloudant binding"
-
-    /**
-     * Simulate bluemix package binding by supplying a "url" parameter.
-     * Additionally, leave out other key parameters (e.g. username, password)
-     * to ensure that the action uses the "url" bound parameter.
-     */
-    it should """Use "url" property if it is available""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val packageName = "cloudantBindingWithURL"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("""Creating cloudant package binding with only a "url" parameter.""")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("url" -> s"https://${myCloudantCreds.user}:${myCloudantCreds.password}@${myCloudantCreds.host}".toJson))
-                }
-
-                println("Invoking the document-create action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/create-document",
-                    Map(
-                        "dbname" -> myCloudantCreds.dbname.toJson,
-                        "doc" -> JsObject("message" -> "I used the url parameter.".toJson)))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                }
-            } finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-
-    /**
-     * Simulate a user creating their own binding with "username", "password", and "host".
-     * Do not include "url" in the binding to ensure the package uses the other bound properties.
-     */
-    it should """Use "username", "password", and "host" if "url" is not available""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val packageName = "cloudantBindingWithoutURL"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("""Creating cloudant package binding with "username", "pasword" and "host".""")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> myCloudantCreds.user.toJson,
-                                "password" -> myCloudantCreds.password.toJson,
-                                "host" -> myCloudantCreds.host().toJson))
-                }
-
-                println("Invoking the document-create action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/create-document",
-                    Map(
-                        "dbname" -> myCloudantCreds.dbname.toJson,
-                        "doc" -> JsObject("message" -> "This time I didn't use the URL param.".toJson)))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                }
-            } finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-}
diff --git a/tests/src/test/scala/system/packages/CloudantDatabaseActionsTests.scala b/tests/src/test/scala/system/packages/CloudantDatabaseActionsTests.scala
deleted file mode 100644
index 66df2b0..0000000
--- a/tests/src/test/scala/system/packages/CloudantDatabaseActionsTests.scala
+++ /dev/null
@@ -1,1885 +0,0 @@
-/*
- * 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.
- */
-package system.packages
-
-import java.util.Date
-
-import common._
-import org.junit.runner.RunWith
-import org.scalatest.FlatSpec
-import org.scalatest.junit.JUnitRunner
-import spray.json.DefaultJsonProtocol._
-import spray.json._
-import system.CloudantUtil
-import org.apache.openwhisk.utils.JsHelpers
-
-@RunWith(classOf[JUnitRunner])
-class CloudantDatabaseActionsTests extends FlatSpec
-    with TestHelpers
-    with WskTestHelpers {
-
-    val wskprops = WskProps()
-    val wsk = new Wsk
-
-    val credential = CloudantUtil.Credential.makeFromVCAPFile("cloudantNoSQLDB", this.getClass.getSimpleName)
-
-    behavior of "Cloudant database actions"
-
-
-    it should """create cloudant document""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val doc = CloudantUtil.createDocParameterForWhisk().get("doc").getAsString
-                val docJSObj = doc.parseJson.asJsObject
-
-                println("Invoking the create-document action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/create-document",
-                    Map("doc" -> docJSObj))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                }
-                val getResponse = CloudantUtil.getDocument(credential, "testId")
-                Some(JsString(getResponse.get("date").getAsString)) shouldBe docJSObj.fields.get("date")
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read cloudant document""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                println("Invoking the read-document action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/read-document",
-                    Map(
-                        "docid" -> response.get("id").getAsString.toJson,
-                        "params" -> JsObject("revs_info" -> JsBoolean(true))))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("date") shouldBe defined
-                        activation.response.result.get.fields.get("_rev") shouldBe defined
-                        activation.response.result.get.fields.get("_revs_info") shouldBe defined
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read cloudant document with read action""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                println("Invoking the read action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/read",
-                    Map(
-                        "docid" -> response.get("id").getAsString.toJson,
-                        "params" -> JsObject("revs_info" -> JsBoolean(true))))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("date") shouldBe defined
-                        activation.response.result.get.fields.get("_rev") shouldBe defined
-                        activation.response.result.get.fields.get("_revs_info") shouldBe defined
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read cloudant document with undefined docid""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                println("Invoking the read-document action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/read-document"))
-                    {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("docid is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """write cloudant document""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val doc = CloudantUtil.createDocParameterForWhisk().get("doc").getAsString
-                val docJSObj = doc.parseJson.asJsObject
-
-                println("Invoking the write action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/write",
-                    Map("doc" -> docJSObj))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                }
-                val getResponse = CloudantUtil.getDocument(credential, "testId")
-                Some(JsString(getResponse.get("date").getAsString)) shouldBe docJSObj.fields.get("date")
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """write existing cloudant document with overwrite""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                val docJSObj = doc.parseJson.asJsObject
-
-                println("Invoking the write action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/write",
-                    Map("doc" -> docJSObj,
-                        "overwrite" -> "true".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                }
-                val getResponse = CloudantUtil.getDocument(credential, "testId")
-                Some(JsString(getResponse.get("date").getAsString)) shouldBe docJSObj.fields.get("date")
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """write new cloudant document with overwrite""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val doc = CloudantUtil.createDocParameterForWhisk().get("doc").getAsString
-                val docJSObj = doc.parseJson.asJsObject
-
-                println("Invoking the write action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/write",
-                    Map("doc" -> docJSObj,
-                        "overwrite" -> "true".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                }
-                val getResponse = CloudantUtil.getDocument(credential, "testId")
-                Some(JsString(getResponse.get("date").getAsString)) shouldBe docJSObj.fields.get("date")
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """update cloudant document""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                val docJSObj = doc.parseJson.asJsObject
-                val updatedDoc = JsObject(docJSObj.fields
-                        + ("_rev" -> JsString(response.get("rev").getAsString))
-                        + ("updated" -> JsBoolean(true)))
-
-                println("Invoking the update-document action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/update-document",
-                    Map("doc" -> updatedDoc))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                        activation.response.result.get.fields.get("rev") shouldBe defined
-                }
-                val getResponse = CloudantUtil.getDocument(credential, "testId")
-                getResponse.get("updated").getAsBoolean shouldBe true
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """update cloudant document with missing revision""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                val docJSObj = doc.parseJson.asJsObject
-                val updatedDoc = JsObject(docJSObj.fields + ("updated" -> JsBoolean(true)))
-
-                println("Invoking the update-document action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/update-document",
-                    Map("doc" -> updatedDoc))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("doc and doc._rev are required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """delete cloudant document""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                println("Invoking the delete-document action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/delete-document",
-                    Map("docid" -> response.get("id").getAsString.toJson,
-                        "docrev" -> response.get("rev").getAsString.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                        activation.response.result.get.fields.get("rev") shouldBe defined
-                        activation.response.result.get.fields.get("rev") shouldBe defined
-                }
-                //Assert that document does not exist
-                val getResponse = CloudantUtil.getDocument(credential, response.get("id").getAsString)
-                getResponse.get("error").getAsString shouldBe "not_found"
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """delete cloudant document with undefined docid""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                println("Invoking the delete-document action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"$packageName/delete-document",
-                    Map("docrev" -> response.get("rev").getAsString.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("docid is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list cloudant documents""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                val docJSObj = doc.parseJson.asJsObject
-                println("Invoking the list-documents action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/list-documents",
-                    Map("doc" -> docJSObj))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("total_rows") shouldBe Some(JsNumber("1"))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list cloudant documents with undefined host""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test doc
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                val docJSObj = doc.parseJson.asJsObject
-                println("Invoking the list-documents action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/list-documents",
-                    Map("doc" -> docJSObj))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("cloudant account host is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list all cloudant design documents""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create design doc
-                val designDoc = CloudantUtil.createDesignFromFile(CloudantUtil.INDEX_DDOC_PATH)
-                val response = CloudantUtil.createIndex(credential, designDoc.toString)
-                response.get("result").getAsString shouldBe "created"
-
-                println("Invoking the list-design-documents action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/list-design-documents",
-                    Map("includedocs" -> "true".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        val rows = result.fields("rows").asInstanceOf[JsArray].elements(0).asJsObject
-                        rows.fields.get("doc") shouldBe defined
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list all cloudant design documents with undefined dbname""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson))
-                }
-
-                println("Invoking the list-design-documents action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/list-design-documents",
-                    Map("includedocs" -> "true".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("dbname is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """create cloudant query index""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test design index doc
-                val indexDesignDoc = CloudantUtil.createDesignFromFile(CloudantUtil.INDEX_DDOC_PATH).toString
-                val indexDocJSObj = indexDesignDoc.parseJson.asJsObject
-
-                println("Invoking the create-query-index action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/create-query-index",
-                    Map("index" -> indexDocJSObj))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("result") shouldBe Some(JsString("created"))
-                        val docResponse = CloudantUtil.getDocument(credential, "_design/test-query-index")
-                        docResponse.get("views").toString should include ("test-query-index")
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """create cloudant query index with undefined index""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                println("Invoking the create-query-index action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/create-query-index")) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("index is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list cloudant query indexes""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test design index doc
-                val indexDesignDoc = CloudantUtil.createDesignFromFile(CloudantUtil.INDEX_DDOC_PATH).toString
-                val response = CloudantUtil.createDocument(credential, indexDesignDoc)
-                response.get("ok").getAsString shouldBe "true"
-
-                println("Invoking the list-query-indexes action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/list-query-indexes")) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        val indexes = result.fields("indexes").asInstanceOf[JsArray].elements(0).asJsObject
-                        indexes.fields.get("name") shouldBe Some(JsString("_all_docs"))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """list cloudant query indexes with incorrect dbname""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.substring(1).toJson))
-                }
-
-                println("Invoking the list-query-indexes action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/list-query-indexes")) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        JsHelpers.getFieldPath(result, "error", "statusCode") shouldBe Some(JsNumber(404))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant exec query find""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                val docJSObj = doc.parseJson.asJsObject
-                println("Invoking the exec-query-find action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/exec-query-find",
-                    Map("query" -> JsObject("selector" -> JsObject("_id" -> JsObject("$gt" -> JsNumber(0))))))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        val docs = result.fields("docs").asInstanceOf[JsArray].elements(0).asJsObject
-                        docs.fields.get("date") shouldBe docJSObj.fields.get("date")
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant exec query search""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test document for search query
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                //Create test design doc
-                val designDoc = CloudantUtil.createDesignFromFile(CloudantUtil.VIEW_AND_SEARCH_DDOC_PATH).toString
-                val getResponse = CloudantUtil.createDocument(credential, designDoc)
-                getResponse.get("ok").getAsString shouldBe "true"
-
-                //Create search query
-                val needle = new Date().toString.substring(0, 2) + '*'
-                println("Invoking the exec-query-search action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/exec-query-search",
-                    Map("search" -> JsObject("q" -> s"date:$needle".toJson),
-                        "docid" -> "test_design".toJson,
-                        "indexname" -> "test_search".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("bookmark") shouldBe defined
-                        val rows = result.fields("rows").asInstanceOf[JsArray].elements(0).asJsObject
-                        rows.fields.get("id") shouldBe Some(JsString("testId"))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant exec query search with undefined search""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test document for search query
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                //Create test design doc
-                val designDoc = CloudantUtil.createDesignFromFile(CloudantUtil.VIEW_AND_SEARCH_DDOC_PATH).toString
-                val getResponse = CloudantUtil.createDocument(credential, designDoc)
-                getResponse.get("ok").getAsString shouldBe "true"
-
-                //Create search query
-                println("Invoking the exec-query-search action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/exec-query-search",
-                    Map("docid" -> "test_design".toJson,
-                        "indexname" -> "test_search".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("search query is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant exec query view""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test document for search query
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                //Create test design doc
-                val designDoc = CloudantUtil.createDesignFromFile(CloudantUtil.VIEW_AND_SEARCH_DDOC_PATH).toString
-                val getResponse = CloudantUtil.createDocument(credential, designDoc)
-                getResponse.get("ok").getAsString shouldBe "true"
-
-                //Create search query
-                println("Invoking the exec-query-view action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/exec-query-view",
-                    Map("docid" -> "test_design".toJson,
-                        "viewname" -> "test_view".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        val rows = result.fields("rows").asInstanceOf[JsArray].elements(0).asJsObject
-                        rows.fields.get("key") shouldBe Some(JsString("testId"))
-                        rows.fields.get("value") shouldBe Some(JsNumber(1))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant exec query view with undefined viewname""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test document for search query
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                //Create test design doc
-                val designDoc = CloudantUtil.createDesignFromFile(CloudantUtil.VIEW_AND_SEARCH_DDOC_PATH).toString
-                val getResponse = CloudantUtil.createDocument(credential, designDoc)
-                getResponse.get("ok").getAsString shouldBe "true"
-
-                //Create search query
-                println("Invoking the exec-query-view action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/exec-query-view",
-                    Map("docid" -> "test_design".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("viewname is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant delete query index""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test index
-                val index = CloudantUtil.createDesignFromFile(CloudantUtil.INDEX_DDOC_PATH)
-                val response = CloudantUtil.createIndex(credential, index.toString)
-                response.get("result").getAsString shouldBe "created"
-                val id = response.get("id").getAsString
-
-                println("Invoking the delete-query-index action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/delete-query-index",
-                    Map("docid" -> id.toJson,
-                        "indexname" -> index.get("name").getAsString.toJson,
-                        "indextype" -> "json".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("ok") shouldBe Some(JsBoolean(true))
-                }
-                val getResponse = CloudantUtil.getDocument(credential, id)
-                getResponse.get("error").getAsString shouldBe "not_found"
-                getResponse.get("reason").getAsString shouldBe "deleted"
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant delete query index with undefined indextype""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test index
-                val index = CloudantUtil.createDesignFromFile(CloudantUtil.INDEX_DDOC_PATH)
-                val response = CloudantUtil.createIndex(credential, index.toString)
-                response.get("result").getAsString shouldBe "created"
-                val id = response.get("id").getAsString
-
-                println("Invoking the delete-query-index action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/delete-query-index",
-                    Map("docid" -> id.toJson,
-                        "indexname" -> index.get("name").getAsString.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("indextype is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant delete view""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                //Create test index
-                val view = CloudantUtil.createDesignFromFile(CloudantUtil.VIEW_AND_SEARCH_DDOC_PATH)
-                val response = CloudantUtil.createDocument(credential, view.toString)
-                response.get("ok").getAsString shouldBe "true"
-                val id = response.get("id").getAsString
-
-                println("Invoking the delete-view action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/delete-view",
-                    Map("docid" -> id.toJson,
-                        "viewname" -> "test_view".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("ok") shouldBe Some(JsBoolean(true))
-                }
-                //Assert that view is deleted
-                val getResponse = CloudantUtil.getDocument(credential, id)
-                getResponse.get("views").toString shouldBe "{}"
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant delete view with undefined docic""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                println("Invoking the delete-view action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/delete-view",
-                    Map("viewname" -> "test_view".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("docid is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant create bulk documents""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                val numDocs = 5
-                val docsArray = CloudantUtil.createDocumentArray(numDocs).toString
-                val docsJsArray = docsArray.parseJson.asInstanceOf[JsArray]
-
-                println("Invoking the manage-bulk-documents.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/manage-bulk-documents",
-                    Map("docs" -> JsObject("docs" -> docsJsArray)))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        for (i <- 1 to numDocs) {
-                            val response = CloudantUtil.getDocument(credential, s"testId$i")
-                            val doc = result.fields("docs").asInstanceOf[JsArray].elements(i-1).asJsObject
-                            Some(JsString(response.get("_rev").getAsString)) shouldBe doc.fields.get("rev")
-                        }
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant update bulk documents""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                val numDocs = 5
-                val bulkDocs = CloudantUtil.createDocumentArray(numDocs)
-                //Create test docs for updating
-                val responses = CloudantUtil.bulkDocuments(credential, bulkDocs)
-                val updateDocsArray = CloudantUtil.updateDocsWithOnlyIdAndRev(responses).toString
-                val updatedDocsJsArray = updateDocsArray.parseJson.asInstanceOf[JsArray]
-
-                println("Invoking the manage-bulk-documents.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/manage-bulk-documents",
-                    Map("docs" -> JsObject("docs" -> updatedDocsJsArray)))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        for (i <- 1 to numDocs) {
-                            val response = CloudantUtil.getDocument(credential, s"testId$i")
-                            val doc = result.fields("docs").asInstanceOf[JsArray].elements(i-1).asJsObject
-                            Some(JsString(response.get("_rev").getAsString)) shouldBe doc.fields.get("rev")
-                        }
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant update bulk documents with malformed JSON params""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                val numDocs = 5
-                val bulkDocs = CloudantUtil.createDocumentArray(numDocs)
-                //Create test docs for updating
-                val responses = CloudantUtil.bulkDocuments(credential, bulkDocs)
-                val updateDocsArray = CloudantUtil.updateDocsWithOnlyIdAndRev(responses).toString
-                val updatedDocsJsArray = updateDocsArray.parseJson.asInstanceOf[JsArray]
-
-                println("Invoking the manage-bulk-documents.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/manage-bulk-documents",
-                    Map("docs" -> updatedDocsJsArray))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        JsHelpers.getFieldPath(result, "error", "statusCode") shouldBe Some(JsNumber(400))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant delete bulk documents""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                val numDocs = 5
-                val bulkDocs = CloudantUtil.createDocumentArray(numDocs)
-                //Create test docs for updating
-                val responses = CloudantUtil.bulkDocuments(credential, bulkDocs)
-                //Update document array with deleted field
-                val deleteDocsArray = CloudantUtil.addDeletedPropertyToDocs(responses).toString
-                val deleteddDocsJsArray = deleteDocsArray.parseJson.asInstanceOf[JsArray]
-
-                println("Invoking the manage-bulk-documents.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/manage-bulk-documents",
-                    Map("docs" -> JsObject("docs" -> deleteddDocsJsArray)))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        for (i <- 1 to numDocs) {
-                            val response = CloudantUtil.getDocument(credential, s"testId$i")
-                            response.get("error").getAsString shouldBe "not_found"
-                            response.get("reason").getAsString shouldBe "deleted"
-                        }
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """cloudant delete bulk documents with undefined password""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-                val numDocs = 5
-                val bulkDocs = CloudantUtil.createDocumentArray(numDocs)
-                //Create test docs for updating
-                val responses = CloudantUtil.bulkDocuments(credential, bulkDocs)
-                //Update document array with deleted field
-                val deleteDocsArray = CloudantUtil.addDeletedPropertyToDocs(responses).toString
-                val deleteddDocsJsArray = deleteDocsArray.parseJson.asInstanceOf[JsArray]
-
-                println("Invoking the manage-bulk-documents.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/manage-bulk-documents",
-                    Map("docs" -> JsObject("docs" -> deleteddDocsJsArray)))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("cloudant account password is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read changes feed""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val doc = CloudantUtil.createDocParameterForWhisk().get("doc").getAsString
-                val docJSObj = doc.parseJson.asJsObject
-
-                println("Invoking the read-changes-feed action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/read-changes-feed",
-                    Map("doc" -> docJSObj))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("last_seq") shouldBe defined
-                        result.fields.get("pending") shouldBe Some(JsNumber("0"))
-                        result.fields("results").asInstanceOf[JsArray].elements.size shouldBe 0
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read changes feed with undefined dbname""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson))
-                }
-
-                val doc = CloudantUtil.createDocParameterForWhisk().get("doc").getAsString
-                val docJSObj = doc.parseJson.asJsObject
-
-                println("Invoking the read-changes-feed action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/read-changes-feed",
-                    Map("doc" -> docJSObj))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("dbname is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """create attachment""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                //Create test document
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                //Get attachment text file
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-                val attachmentData = CloudantUtil.readFile(attachFile).trim()
-
-                println("Invoking the create-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/create-attachment",
-                    Map("docid" -> response.get("id").getAsString.toJson,
-                        "docrev" -> response.get("rev").getAsString.toJson,
-                        "attachment" -> attachmentData.toJson,
-                        "attachmentname" -> attachFile.getName.toJson,
-                        "contenttype" -> "text/plain".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                        activation.response.result.get.fields.get("rev") shouldBe defined
-                }
-                val getResponse = CloudantUtil.getDocument(credential, "testId")
-                getResponse.get("_attachments").getAsJsonObject().has(attachFile.getName()) shouldBe true
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """create attachment with undefined attachment""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                //Create test document
-                val doc = CloudantUtil.createDocParameterForWhisk.get("doc").getAsString
-                val response = CloudantUtil.createDocument(credential, doc)
-                response.get("ok").getAsString shouldBe "true"
-
-                //Get attachment text file
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-
-                println("Invoking the create-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/create-attachment",
-                    Map("docid" -> response.get("id").getAsString.toJson,
-                        "docrev" -> response.get("rev").getAsString.toJson,
-                        "attachmentname" -> attachFile.getName.toJson,
-                        "contenttype" -> "text/plain".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe defined
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read attachment""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-                val id = CloudantUtil.createDocumentWithAttachment(credential, attachFile).getId
-                val origData = CloudantUtil.readFile(CloudantUtil.ATTACHMENT_FILE_PATH)
-                val bytes = Array.fill[Byte](100)(0)
-
-                println("Invoking the read-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/read-attachment",
-                    Map("docid" -> id.toJson,
-                        "attachmentname" -> attachFile.getName.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        var i = 0
-                        result.fields("data").asInstanceOf[JsArray].elements.foreach({ x =>
-                            bytes.update(i, x.convertTo[Byte])
-                            i += 1
-                        })
-                        val byteString = new String(bytes, "utf-8")
-                        origData.trim shouldBe byteString.trim
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """read attachment with undefined attachmentname""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-                val id = CloudantUtil.createDocumentWithAttachment(credential, attachFile).getId
-
-                println("Invoking the read-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/read-attachment",
-                    Map("docid" -> id.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("attachmentname is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """update attachment""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-                val id = CloudantUtil.createDocumentWithAttachment(credential, attachFile).getId
-                val attachmentName = "attach.txt"
-                val getResponse = CloudantUtil.getDocument(credential, id)
-                val attachment = getResponse.get("_attachments").getAsJsonObject.get(attachmentName).getAsJsonObject
-
-                println("Invoking the update-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/update-attachment",
-                    Map("docid" -> id.toJson,
-                        "attachmentname" -> attachFile.getName.toJson,
-                        "docrev" -> getResponse.get("_rev").getAsString.toJson,
-                        "attachment" -> "new_update_string".toJson,
-                        "attachmentname" -> attachmentName.toJson,
-                        "contenttype" -> "text/plain".toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        val result = activation.response.result.get
-                        result.fields.get("id") shouldBe Some(JsString(id))
-                }
-                val docResponse = CloudantUtil.getDocument(credential, id)
-                val updatedAttachment = docResponse.get("_attachments").getAsJsonObject.get(attachmentName).getAsJsonObject
-                getResponse.get("_attachments").getAsJsonObject.has(attachmentName) shouldBe true
-                attachment.get("revpos") should not be updatedAttachment.get("revpos")
-                attachment.get("digest") should not be updatedAttachment.get("digest")
-        }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """update attachment with undefined contenttype""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-                val id = CloudantUtil.createDocumentWithAttachment(credential, attachFile).getId
-                val attachmentName = "attach.txt"
-                val getResponse = CloudantUtil.getDocument(credential, id)
-
-                println("Invoking the update-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/update-attachment",
-                    Map("docid" -> id.toJson,
-                        "attachmentname" -> attachFile.getName.toJson,
-                        "docrev" -> getResponse.get("_rev").getAsString.toJson,
-                        "attachment" -> "new_update_string".toJson,
-                        "attachmentname" -> attachmentName.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        result.fields.get("error") shouldBe Some(JsString("contenttype is required."))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """delete attachment""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                //Create document with attachment
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-                val id = CloudantUtil.createDocumentWithAttachment(credential, attachFile).getId
-                val getResponse = CloudantUtil.getDocument(credential, id)
-
-                println("Invoking the delete-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/delete-attachment",
-                    Map("docid" -> getResponse.get("_id").getAsString.toJson,
-                        "docrev" -> getResponse.get("_rev").getAsString.toJson,
-                        "attachmentname" -> attachFile.getName.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe true
-                        activation.response.result.get.fields.get("id") shouldBe defined
-                        activation.response.result.get.fields.get("rev") shouldBe defined
-                }
-                //Assert that attachment does not exist in doc
-                val response = CloudantUtil.getDocument(credential, id).toString
-                val docJSObject = response.parseJson.asJsObject
-                docJSObject.fields.get("_attachments") should not be defined
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-
-    it should """delete attachment with undefined doc revision""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp
-            val packageName = "dummyCloudantPackage"
-
-            try {
-                CloudantUtil.setUp(credential)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) =>
-                        pkg.bind("/whisk.system/cloudant", name,
-                            Map("username" -> credential.user.toJson,
-                                "password" -> credential.password.toJson,
-                                "host" -> credential.host().toJson,
-                                "dbname" -> credential.dbname.toJson))
-                }
-
-                //Create document with attachment
-                val attachFile = CloudantUtil.ATTACHMENT_FILE_PATH
-                val id = CloudantUtil.createDocumentWithAttachment(credential, attachFile).getId
-                val getResponse = CloudantUtil.getDocument(credential, id)
-
-                println("Invoking the delete-attachment action.")
-                withActivation(wsk.activation, wsk.action.invoke(s"${packageName}/delete-attachment",
-                    Map("docid" -> getResponse.get("_id").getAsString.toJson,
-                        "attachmentname" -> attachFile.getName.toJson))) {
-                    activation =>
-                        activation.response.success shouldBe false
-                        val result = activation.response.result.get
-                        JsHelpers.getFieldPath(result, "error", "statusCode") shouldBe Some(JsNumber(400))
-                }
-            }
-            finally {
-                CloudantUtil.unsetUp(credential)
-            }
-    }
-}
diff --git a/tests/src/test/scala/system/packages/CloudantFeedTests.scala b/tests/src/test/scala/system/packages/CloudantFeedTests.scala
deleted file mode 100644
index 5b433d5..0000000
--- a/tests/src/test/scala/system/packages/CloudantFeedTests.scala
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * 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.
- */
-package system.packages
-
-import common.TestUtils.ANY_ERROR_EXIT
-import common._
-import org.junit.runner.RunWith
-import org.scalatest.{FlatSpec, Inside}
-import org.scalatest.junit.JUnitRunner
-import spray.json.DefaultJsonProtocol._
-import spray.json._
-import system.CloudantUtil
-
-/**
- * Tests for Cloudant trigger service
- */
-@RunWith(classOf[JUnitRunner])
-class CloudantFeedTests
-    extends FlatSpec
-    with TestHelpers
-    with Inside
-    with WskTestHelpers
-    with WskActorSystem {
-
-    val wskprops = WskProps()
-    val wsk = new Wsk
-    val myCloudantCreds = CloudantUtil.Credential.makeFromVCAPFile("cloudantNoSQLDB", this.getClass.getSimpleName)
-    val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
-    val maxRetries = System.getProperty("max.retries", "30").toInt
-
-    behavior of "Cloudant trigger service"
-
-    it should "return useful error message when changes feed does not include host parameter" in withAssetCleaner(wskprops) {
-
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            // the package cloudant should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("fetched package cloudant")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            // create whisk stuff
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> myCloudantCreds.user.toJson,
-                        "password" -> myCloudantCreds.password.toJson,
-                        "dbname" -> myCloudantCreds.dbname.toJson),
-                        expectedExitCode = 246)
-            }
-            feedCreationResult.stderr should include("cloudant trigger feed: missing host parameter")
-
-    }
-
-    it should "return useful error message when changes feed does not include dbname parameter" in withAssetCleaner(wskprops) {
-
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            // the package cloudant should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("fetched package cloudant")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            // create whisk stuff
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> myCloudantCreds.user.toJson,
-                        "password" -> myCloudantCreds.password.toJson,
-                        "host" -> myCloudantCreds.host().toJson),
-                        expectedExitCode = 246)
-            }
-            feedCreationResult.stderr should include("cloudant trigger feed: missing dbname parameter")
-
-    }
-
-    it should "return useful error message when changes feed does not include password parameter" in withAssetCleaner(wskprops) {
-
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            // the package cloudant should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("fetched package cloudant")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            // create whisk stuff
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> myCloudantCreds.user.toJson,
-                        "dbname" -> myCloudantCreds.dbname.toJson,
-                        "host" -> myCloudantCreds.host().toJson),
-                        expectedExitCode = 246)
-            }
-            feedCreationResult.stderr should include("cloudant trigger feed: Must specify parameter/s of iamApiKey or username/password")
-
-    }
-
-    it should "return useful error message when changes feed does not include username parameter" in withAssetCleaner(wskprops) {
-
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            // the package cloudant should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("fetched package cloudant")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            // create whisk stuff
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "password" -> myCloudantCreds.password.toJson,
-                        "dbname" -> myCloudantCreds.dbname.toJson,
-                        "host" -> myCloudantCreds.host().toJson),
-                        expectedExitCode = 246)
-            }
-            feedCreationResult.stderr should include("cloudant trigger feed: Must specify parameter/s of iamApiKey or username/password")
-
-    }
-
-    it should "throw error if Cloudant connection is invalid" in withAssetCleaner(wskprops) {
-
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-            println("Fetching cloudant package.")
-            packageGetResult.stdout should include("ok")
-
-            println("Creating cloudant package binding.")
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-            }
-
-            println("Creating cloudant trigger feed with wrong password.")
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                        "username" -> myCloudantCreds.user.toJson,
-                        "password" -> "WRONG_PASSWORD".toJson,
-                        "host" -> myCloudantCreds.host().toJson,
-                        "dbname" -> myCloudantCreds.dbname.toJson,
-                        "maxTriggers" -> 1.toJson),
-                        expectedExitCode = ANY_ERROR_EXIT)
-            }
-            println("Creating cloudant trigger should give an error because not confirmed database.")
-            feedCreationResult.stderr should include("error")
-
-    }
-
-    it should "disable after reaching max triggers" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val ruleName = s"dummyCloudantRule-${System.currentTimeMillis}"
-            val actionName = s"dummyCloudantAction-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-                }
-
-                // create action
-                assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
-                    action.create(name, defaultAction)
-                }
-
-                println("Creating cloudant trigger feed.")
-                assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                    (trigger, name) =>
-                        trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                            "username" -> myCloudantCreds.user.toJson,
-                            "password" -> myCloudantCreds.password.toJson,
-                            "host" -> myCloudantCreds.host().toJson,
-                            "dbname" -> myCloudantCreds.dbname.toJson,
-                            "maxTriggers" -> 1.toJson))
-                }
-
-                // create rule
-                assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
-                    rule.create(name, trigger = triggerName, action = actionName)
-                }
-
-                val activationsBeforeCreate = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-                activationsBeforeCreate should be(0)
-
-                // Create test docs in cloudant and assert that document was inserted successfully
-                println("Creating a test doc-1 in the cloudant")
-                val response1 = CloudantUtil.createDocument(myCloudantCreds, "{\"test\":\"test_doc_1\"}")
-                response1.get("ok").getAsString should be("true")
-
-                println("Checking for activations")
-                val activations = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-                println(s"Found activation size (should be exactly 1): $activations")
-                activations should be(1)
-
-                println("Creating a test doc-2 in the cloudant")
-                val response2 = CloudantUtil.createDocument(myCloudantCreds, "{\"test\":\"test_doc_2\"}")
-                response2.get("ok").getAsString should be("true")
-
-                println("No activations should be created for test_doc_2 since trigger is disabled")
-                val newactivations = wsk.activation.pollFor(N = 2, Some(triggerName)).length
-                println(s"Activation size should still be one: $newactivations")
-                newactivations should be(1)
-
-            } finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-
-    it should """filter out triggers that do not meet the filter criteria""" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val ruleName = s"dummyCloudantRule-${System.currentTimeMillis}"
-            val actionName = s"dummyCloudantAction-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-                }
-
-                // create action
-                assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
-                    action.create(name, defaultAction)
-                }
-
-                //Create filter design doc
-                val filterDesignDoc = CloudantUtil.createDesignFromFile(CloudantUtil.FILTER_DDOC_PATH).toString
-                val getResponse = CloudantUtil.createDocument(myCloudantCreds, filterDesignDoc)
-                getResponse.get("ok").getAsString shouldBe "true"
-
-                println("Creating cloudant trigger feed.")
-                assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                    (trigger, name) =>
-                        trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                            "username" -> myCloudantCreds.user.toJson,
-                            "password" -> myCloudantCreds.password.toJson,
-                            "host" -> myCloudantCreds.host().toJson,
-                            "dbname" -> myCloudantCreds.dbname.toJson,
-                            "filter" -> "test_filter/fruit".toJson,
-                            "query_params" -> JsObject("type" -> JsString("tomato"))))
-                }
-
-                // create rule
-                assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
-                    rule.create(name, trigger = triggerName, action = actionName)
-                }
-
-                val activationsBeforeCreate = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-                activationsBeforeCreate should be(0)
-
-                // Create test docs in cloudant and assert that document was inserted successfully
-                println("Creating a test doc-1 in the cloudant")
-                val response1 = CloudantUtil.createDocument(myCloudantCreds, "{\"kind\":\"fruit\", \"type\":\"apple\"}")
-                response1.get("ok").getAsString should be("true")
-
-                println("Checking for activations")
-                val activations = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-                println(s"Found activation size (should be exactly 1): $activations")
-                activations should be(1)
-
-                println("Creating a test doc-2 in the cloudant")
-                val response2 = CloudantUtil.createDocument(myCloudantCreds, "{\"kind\":\"dairy\",\"type\":\"butter\"}")
-                response2.get("ok").getAsString should be("true")
-
-                println("checking for new activations (not expected since it should be filtered out)")
-                val noNewActivations = wsk.activation.pollFor(N = 2, Some(triggerName)).length
-                println(s"Found activation size (should still be 1): $noNewActivations")
-                noNewActivations should be(1)
-
-                println("Creating a test doc-3 in the cloudant")
-                val response3 = CloudantUtil.createDocument(myCloudantCreds, "{\"kind\":\"debatable\", \"type\":\"tomato\"}")
-                response3.get("ok").getAsString should be("true")
-
-                println("Checking for new activations (should now have 2)")
-                val newActivations = wsk.activation.pollFor(N = 3, Some(triggerName), retries = maxRetries).length
-                println(s"Found activation size (should be 2): $newActivations")
-                newActivations should be(2)
-
-            }
-            finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-
-    it should "not return fields in configuration that are not passed in during trigger create" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                // the package cloudant should be there
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("fetched package cloudant")
-                packageGetResult.stdout should include("ok")
-
-                // create package binding
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-                }
-
-                val username = myCloudantCreds.user
-                val password = myCloudantCreds.password
-                val host = myCloudantCreds.host()
-                val dbName = myCloudantCreds.dbname
-
-                // create whisk stuff
-                val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                    (trigger, name) =>
-                        trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                            "username" -> username.toJson,
-                            "password" -> password.toJson,
-                            "host" -> host.toJson,
-                            "dbname" -> dbName.toJson
-                        ))
-                }
-                feedCreationResult.stdout should include("ok")
-
-                val actionName = s"$packageName/$feed"
-                val run = wsk.action.invoke(actionName, parameters = Map(
-                    "triggerName" -> triggerName.toJson,
-                    "lifecycleEvent" -> "READ".toJson,
-                    "authKey" -> wskProps.authKey.toJson
-                ))
-
-                withActivation(wsk.activation, run) {
-                    activation =>
-                        activation.response.success shouldBe true
-
-                        inside(activation.response.result) {
-                            case Some(result) =>
-                                val config = result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                                config should contain key "username"
-                                config should contain key "password"
-                                config should contain key "host"
-                                config should contain key "dbname"
-
-                                config should not {
-                                    contain key "query_params"
-                                    contain key "filter"
-                                    contain key "protocol"
-                                    contain key "since"
-                                    contain key "port"
-                                }
-                        }
-                }
-            } finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-
-    it should "reject trigger update without passing in any updatable parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                // the package cloudant should be there
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("fetched package cloudant")
-                packageGetResult.stdout should include("ok")
-
-                // create package binding
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-                }
-
-                val username = myCloudantCreds.user
-                val password = myCloudantCreds.password
-                val host = myCloudantCreds.host()
-                val dbName = myCloudantCreds.dbname
-
-                // create whisk stuff
-                val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                    (trigger, name) =>
-                        trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                            "username" -> username.toJson,
-                            "password" -> password.toJson,
-                            "host" -> host.toJson,
-                            "dbname" -> dbName.toJson
-                        ))
-                }
-                feedCreationResult.stdout should include("ok")
-
-                val actionName = s"$packageName/$feed"
-                val run = wsk.action.invoke(actionName, parameters = Map(
-                    "triggerName" -> triggerName.toJson,
-                    "lifecycleEvent" -> "UPDATE".toJson,
-                    "authKey" -> wskProps.authKey.toJson
-                ))
-
-                withActivation(wsk.activation, run) {
-                    activation =>
-                        activation.response.success shouldBe false
-                }
-            } finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-
-    it should "reject trigger update when query_params is passed in and no filter is defined" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                // the package cloudant should be there
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("fetched package cloudant")
-                packageGetResult.stdout should include("ok")
-
-                // create package binding
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-                }
-
-                val username = myCloudantCreds.user
-                val password = myCloudantCreds.password
-                val host = myCloudantCreds.host()
-                val dbName = myCloudantCreds.dbname
-
-                // create whisk stuff
-                val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                    (trigger, name) =>
-                        trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                            "username" -> username.toJson,
-                            "password" -> password.toJson,
-                            "host" -> host.toJson,
-                            "dbname" -> dbName.toJson
-                        ))
-                }
-                feedCreationResult.stdout should include("ok")
-
-                val actionName = s"$packageName/$feed"
-                val run = wsk.action.invoke(actionName, parameters = Map(
-                    "triggerName" -> triggerName.toJson,
-                    "lifecycleEvent" -> "UPDATE".toJson,
-                    "authKey" -> wskProps.authKey.toJson,
-                    "query_params" -> JsObject("type" -> JsString("tomato"))
-                ))
-
-                withActivation(wsk.activation, run) {
-                    activation =>
-                        activation.response.success shouldBe false
-                }
-            } finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-
-    it should "filter out triggers that do not meet the filter criteria before and after updating query_params" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp // shadow global props and make implicit
-            val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
-            val ruleName = s"dummyCloudantRule-${System.currentTimeMillis}"
-            val actionName = s"dummyCloudantAction-${System.currentTimeMillis}"
-            val packageName = "dummyCloudantPackage"
-            val feed = "changes"
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
-                println("Fetching cloudant package.")
-                packageGetResult.stdout should include("ok")
-
-                println("Creating cloudant package binding.")
-                assetHelper.withCleaner(wsk.pkg, packageName) {
-                    (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
-                }
-
-                // create action
-                assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
-                    action.create(name, defaultAction)
-                }
-
-                //Create filter design doc
-                val filterDesignDoc = CloudantUtil.createDesignFromFile(CloudantUtil.FILTER_DDOC_PATH).toString
-                val getResponse = CloudantUtil.createDocument(myCloudantCreds, filterDesignDoc)
-                getResponse.get("ok").getAsString shouldBe "true"
-
-                println("Creating cloudant trigger feed.")
-                assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                    (trigger, name) =>
-                        trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
-                            "username" -> myCloudantCreds.user.toJson,
-                            "password" -> myCloudantCreds.password.toJson,
-                            "host" -> myCloudantCreds.host().toJson,
-                            "dbname" -> myCloudantCreds.dbname.toJson,
-                            "filter" -> "test_filter/fruit".toJson,
-                            "query_params" -> JsObject("type" -> JsString("tomato"))))
-                }
-
-                // create rule
-                assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
-                    rule.create(name, trigger = triggerName, action = actionName)
-                }
-
-                val activationsBeforeCreate = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-                activationsBeforeCreate should be(0)
-
-                // Create test docs in cloudant and assert that document was inserted successfully
-                println("Creating a test doc-1 in the cloudant")
-                val response1 = CloudantUtil.createDocument(myCloudantCreds, "{\"kind\":\"fruit\", \"type\":\"apple\"}")
-                response1.get("ok").getAsString should be("true")
-
-                println("Checking for activations")
-                val activations = wsk.activation.pollFor(N = 1, Some(triggerName), retries = maxRetries).length
-                println(s"Found activation size (should be exactly 1): $activations")
-                activations should be(1)
-
-                println("Creating a test doc-2 in the cloudant")
-                val response2 = CloudantUtil.createDocument(myCloudantCreds, "{\"kind\":\"dairy\",\"type\":\"butter\"}")
-                response2.get("ok").getAsString should be("true")
-
-                println("checking for new activations (not expected since it should be filtered out)")
-                val noNewActivations = wsk.activation.pollFor(N = 2, Some(triggerName)).length
-                println(s"Found activation size (should still be 1): $noNewActivations")
-                noNewActivations should be(1)
-
-                println("Updating trigger query_params.")
-                val feedUpdateResult = wsk.action.invoke(s"$packageName/$feed", parameters = Map(
-                    "triggerName" -> triggerName.toJson,
-                    "lifecycleEvent" -> "UPDATE".toJson,
-                    "authKey" -> wskProps.authKey.toJson,
-                    "query_params" -> JsObject("type" -> JsString("avocado"))
-                ))
-
-                withActivation(wsk.activation, feedUpdateResult) {
-                    activation =>
-                        activation.response.success shouldBe true
-                }
-
-                println("Giving the trigger service a moment to process the update")
-                Thread.sleep(maxRetries * 1000)
-
-                val runResult = wsk.action.invoke(s"$packageName/$feed", parameters = Map(
-                    "triggerName" -> triggerName.toJson,
-                    "lifecycleEvent" -> "READ".toJson,
-                    "authKey" -> wskProps.authKey.toJson
-                ))
-
-                withActivation(wsk.activation, runResult) {
-                    activation =>
-                        activation.response.success shouldBe true
-
-                        inside(activation.response.result) {
-                            case Some(result) =>
-                                val config = result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                                config should contain("filter" -> "test_filter/fruit".toJson)
-                                config should contain("query_params" -> JsObject("type" -> JsString("avocado")))
-                        }
-                }
-
-                println("Creating a test doc-3 in the cloudant")
-                val response3 = CloudantUtil.createDocument(myCloudantCreds, "{\"kind\":\"berry\", \"type\":\"avocado\"}")
-                response3.get("ok").getAsString should be("true")
-
-                println("Checking for new activations (should now have 2)")
-                val newActivations = wsk.activation.pollFor(N = 3, Some(triggerName), retries = maxRetries).length
-                println(s"Found activation size (should be 2): $newActivations")
-                newActivations should be(2)
-
-            }
-            finally {
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-}
diff --git a/tests/src/test/scala/system/packages/CloudantFeedWebTests.scala b/tests/src/test/scala/system/packages/CloudantFeedWebTests.scala
deleted file mode 100644
index 499e61a..0000000
--- a/tests/src/test/scala/system/packages/CloudantFeedWebTests.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.
- */
-package system.packages
-
-import com.jayway.restassured.RestAssured
-import com.jayway.restassured.config.SSLConfig
-import com.jayway.restassured.http.ContentType
-import common.TestUtils.FORBIDDEN
-import common.{Wsk, WskProps}
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import org.scalatest.{BeforeAndAfter, FlatSpec, Matchers}
-import spray.json._
-
-@RunWith(classOf[JUnitRunner])
-class CloudantFeedWebTests
-    extends FlatSpec
-    with BeforeAndAfter
-    with Matchers {
-
-    val wskprops = WskProps()
-
-    val webAction = "/whisk.system/cloudantWeb/changesWebAction"
-    val webActionURL = s"https://${wskprops.apihost}/api/v1/web$webAction.http"
-
-    val requiredParams = JsObject(
-        "triggerName" -> JsString("/invalidNamespace/invalidTrigger"),
-        "authKey" -> JsString("DoesNotWork"),
-        "dbname" -> JsString("DoesNotExist"),
-        "host" -> JsString("bad.hostname"),
-        "username" -> JsString("username"),
-        "password" -> JsString("password")
-    )
-
-    behavior of "Cloudant changes web action"
-
-    it should "not be obtainable using the CLI" in {
-        val wsk = new Wsk()
-        implicit val wp = wskprops
-
-        wsk.action.get(webAction, FORBIDDEN)
-    }
-
-    it should "reject post of a trigger due to missing triggerName argument" in {
-        val params = JsObject(requiredParams.fields - "triggerName")
-
-        makePostCallWithExpectedResult(params, JsObject("error" -> JsString("no trigger name parameter was provided")), 400)
-    }
-
-    it should "reject post of a trigger due to missing host argument" in {
-        val params = JsObject(requiredParams.fields - "host")
-
-        makePostCallWithExpectedResult(params, JsObject("error" -> JsString("cloudant trigger feed: missing host parameter")), 400)
-    }
-
-    it should "reject post of a trigger due to missing username argument" in {
-        val params = JsObject(requiredParams.fields - "username")
-
-        makePostCallWithExpectedResult(params, JsObject("error" -> JsString("cloudant trigger feed: Must specify parameter/s of iamApiKey or username/password")), 400)
-    }
-
-    it should "reject post of a trigger due to missing password argument" in {
-        val params = JsObject(requiredParams.fields - "password")
-
-        makePostCallWithExpectedResult(params, JsObject("error" -> JsString("cloudant trigger feed: Must specify parameter/s of iamApiKey or username/password")), 400)
-    }
-
-    it should "reject post of a trigger due to missing dbname argument" in {
-        val params = JsObject(requiredParams.fields - "dbname")
-
-        makePostCallWithExpectedResult(params, JsObject("error" -> JsString("cloudant trigger feed: missing dbname parameter")), 400)
-    }
-
-    it should "reject post of a trigger when authentication fails" in {
-
-        makePostCallWithExpectedResult(requiredParams, JsObject("error" -> JsString("Trigger authentication request failed.")), 401)
-    }
-
-    it should "reject delete of a trigger due to missing triggerName argument" in {
-        val params = JsObject(requiredParams.fields - "triggerName")
-
-        makeDeleteCallWithExpectedResult(params, JsObject("error" -> JsString("no trigger name parameter was provided")), 400)
-    }
-
-    it should "reject delete of a trigger when authentication fails" in {
-        makeDeleteCallWithExpectedResult(requiredParams, JsObject("error" -> JsString("Trigger authentication request failed.")), 401)
-    }
-
-    def makePostCallWithExpectedResult(params: JsObject, expectedResult: JsObject, expectedCode: Int) = {
-        val response = RestAssured.given()
-                .contentType(ContentType.JSON)
-                .config(RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))
-                .body(params.toString())
-                .post(webActionURL)
-        assert(response.statusCode() == expectedCode)
-        response.body.asString.parseJson.asJsObject shouldBe expectedResult
-    }
-
-    def makeDeleteCallWithExpectedResult(params: JsObject, expectedResult: JsObject, expectedCode: Int) = {
-        val response = RestAssured.given()
-                .contentType(ContentType.JSON)
-                .config(RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))
-                .body(params.toString())
-                .delete(webActionURL)
-        assert(response.statusCode() == expectedCode)
-        response.body.asString.parseJson.asJsObject shouldBe expectedResult
-    }
-
-}
diff --git a/tests/src/test/scala/system/packages/CloudantMultiWorkersTests.scala b/tests/src/test/scala/system/packages/CloudantMultiWorkersTests.scala
deleted file mode 100644
index ebeed58..0000000
--- a/tests/src/test/scala/system/packages/CloudantMultiWorkersTests.scala
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-package system.packages
-
-import com.jayway.restassured.RestAssured
-import com.jayway.restassured.config.SSLConfig
-import com.jayway.restassured.http.ContentType
-import common.TestUtils.DONTCARE_EXIT
-import common._
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import org.scalatest.{FlatSpec, Matchers}
-import spray.json.DefaultJsonProtocol._
-import spray.json._
-import system.CloudantUtil
-import org.apache.openwhisk.core.WhiskConfig
-import org.apache.openwhisk.core.database.test.ExtendedCouchDbRestClient
-import org.apache.openwhisk.utils.{JsHelpers, retry}
-
-import scala.concurrent.Await
-import scala.concurrent.duration.DurationInt
-
-
-@RunWith(classOf[JUnitRunner])
-class CloudantMultiWorkersTests extends FlatSpec
-    with Matchers
-    with WskActorSystem
-    with WskTestHelpers
-    with StreamLogging {
-
-    val wskprops = WskProps()
-    val wsk = new Wsk
-    val auth = WhiskProperties.getBasicAuth
-    val user = auth.fst
-    val password = auth.snd
-
-    val dbProtocol = WhiskProperties.getProperty("db.protocol")
-    val dbHost = WhiskProperties.getProperty("db.host")
-    val dbPort = WhiskProperties.getProperty("db.port").toInt
-    val dbUsername = WhiskProperties.getProperty("db.username")
-    val dbPassword = WhiskProperties.getProperty("db.password")
-    val dbPrefix = WhiskProperties.getProperty(WhiskConfig.dbPrefix)
-
-    val webAction = "/whisk.system/cloudantWeb/changesWebAction"
-    val webActionURL = s"https://${wskprops.apihost}/api/v1/web$webAction.http"
-
-    val myCloudantCreds = CloudantUtil.Credential.makeFromVCAPFile("cloudantNoSQLDB", this.getClass.getSimpleName)
-
-    behavior of "Cloudant multi workers feed tests"
-
-    it should "create triggers assigned to worker10 and worker11" in withAssetCleaner(WskProps()) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-
-            val worker10Trigger = s"worker10CloudantTrigger-${System.currentTimeMillis}"
-            val worker10Params = JsObject(
-                "triggerName" -> JsString(worker10Trigger),
-                "authKey" -> JsString(s"$user:$password"),
-                "username" -> myCloudantCreds.user.toJson,
-                "password" -> myCloudantCreds.password.toJson,
-                "host" -> myCloudantCreds.host().toJson,
-                "dbname" -> myCloudantCreds.dbname.toJson,
-                "workers" -> JsArray(JsString("worker10")))
-
-            val worker11Trigger = s"worker11CloudantTrigger-${System.currentTimeMillis}"
-            val worker11Params = JsObject(
-                "triggerName" -> JsString(worker11Trigger),
-                "authKey" -> JsString(s"$user:$password"),
-                "username" -> myCloudantCreds.user.toJson,
-                "password" -> myCloudantCreds.password.toJson,
-                "host" -> myCloudantCreds.host().toJson,
-                "dbname" -> myCloudantCreds.dbname.toJson,
-                "workers" -> JsArray(JsString("worker10"), JsString("worker11")))
-
-            try {
-                CloudantUtil.setUp(myCloudantCreds)
-
-                wsk.trigger.create(worker10Trigger)
-
-                //create trigger feed and assign to worker10
-                makePostCallWithExpectedResult(worker10Params, 200)
-
-                wsk.trigger.create(worker11Trigger)
-
-                //create trigger feed and assign to worker10 or worker11
-                //the one with the least assigned triggers will be chosen
-                makePostCallWithExpectedResult(worker11Params, 200)
-
-                val dbName = s"${dbPrefix}cloudanttrigger"
-                val client = new ExtendedCouchDbRestClient(dbProtocol, dbHost, dbPort, dbUsername, dbPassword, dbName)
-
-                retry({
-                    val result = Await.result(client.getAllDocs(includeDocs = Some(true)), 15.seconds)
-                    result should be('right)
-                    val documents = result.right.get
-                    val worker11Doc = documents
-                            .fields("rows")
-                            .convertTo[List[JsObject]]
-                            .filter(_.fields("id").convertTo[String].equals(s":_:$worker11Trigger"))
-
-                    JsHelpers.getFieldPath(worker11Doc.head, "doc", "worker") shouldBe Some(JsString("worker11"))
-                })
-            } finally {
-                //delete trigger feeds and triggers
-                makeDeleteCallWithExpectedResult(worker10Params, DONTCARE_EXIT)
-                makeDeleteCallWithExpectedResult(worker11Params, DONTCARE_EXIT)
-
-                wsk.trigger.delete(worker10Trigger, expectedExitCode = DONTCARE_EXIT)
-                wsk.trigger.delete(worker11Trigger, expectedExitCode = DONTCARE_EXIT)
-
-                CloudantUtil.unsetUp(myCloudantCreds)
-            }
-    }
-
-    def makePostCallWithExpectedResult(params: JsObject, expectedCode: Int) = {
-        val response = RestAssured.given()
-                .contentType(ContentType.JSON)
-                .config(RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))
-                .body(params.toString())
-                .post(webActionURL)
-        assert(response.statusCode() == expectedCode)
-    }
-
-    def makeDeleteCallWithExpectedResult(params: JsObject, expectedCode: Int) = {
-        val response = RestAssured.given()
-                .contentType(ContentType.JSON)
-                .config(RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))
-                .body(params.toString())
-                .delete(webActionURL)
-        assert(expectedCode == DONTCARE_EXIT || response.statusCode() == expectedCode)
-    }
-
-
-}