Adding BDD cucumber testing component 21/30221/4
authorilanap <ilanap@amdocs.com>
Sun, 4 Feb 2018 15:06:22 +0000 (17:06 +0200)
committerAvi Gaffa <avi.gaffa@amdocs.com>
Thu, 8 Feb 2018 09:30:17 +0000 (09:30 +0000)
Change-Id: I4fd7eb798cbc7cad85562453fb0a6f74fd12ff5b
Issue-ID: SDC-990
Signed-off-by: ilanap <ilanap@amdocs.com>
46 files changed:
openecomp-bdd/.gitignore [new file with mode: 0644]
openecomp-bdd/README.txt [new file with mode: 0644]
openecomp-bdd/config.json [new file with mode: 0644]
openecomp-bdd/cucumber.js [new file with mode: 0644]
openecomp-bdd/features/Example_Collaboration.feature [new file with mode: 0644]
openecomp-bdd/features/Example_HEAT.feature [new file with mode: 0644]
openecomp-bdd/features/Example_ResponseData_CheckAndManipulation.feature [new file with mode: 0644]
openecomp-bdd/features/Example_Rest_Calls.feature [new file with mode: 0644]
openecomp-bdd/features/Example_ToscaTranslationFlow.feature [new file with mode: 0644]
openecomp-bdd/features/Example_VLM.feature [new file with mode: 0644]
openecomp-bdd/features/Example_VSP.feature [new file with mode: 0644]
openecomp-bdd/features/TOSCA/CapabilityDataType.feature [new file with mode: 0644]
openecomp-bdd/features/TOSCA/HeatToToscaTranslation.feature [new file with mode: 0644]
openecomp-bdd/features/TOSCA/HeatValidation.feature [new file with mode: 0644]
openecomp-bdd/package.json [new file with mode: 0644]
openecomp-bdd/plugins/README.md [new file with mode: 0644]
openecomp-bdd/plugins/jsdoc_config.json [new file with mode: 0644]
openecomp-bdd/plugins/reporter.js [new file with mode: 0644]
openecomp-bdd/plugins/steps.js [new file with mode: 0644]
openecomp-bdd/pom.xml [new file with mode: 0644]
openecomp-bdd/report/.gitignore [new file with mode: 0644]
openecomp-bdd/resources/downloads/.gitignore [new file with mode: 0644]
openecomp-bdd/resources/downloads/VSPPackage.zip [new file with mode: 0644]
openecomp-bdd/resources/downloads/base_mux.zip [new file with mode: 0644]
openecomp-bdd/resources/json/createVF.json [new file with mode: 0644]
openecomp-bdd/resources/json/createVLM.json [new file with mode: 0644]
openecomp-bdd/resources/json/createVSP.json [new file with mode: 0644]
openecomp-bdd/resources/uploads/BASE_MUX.zip [new file with mode: 0644]
openecomp-bdd/resources/uploads/NEW_NC_with_manifest.zip [new file with mode: 0644]
openecomp-bdd/resources/uploads/errorHeat.zip [new file with mode: 0644]
openecomp-bdd/resources/uploads/zipWithExternalPort.zip [new file with mode: 0644]
openecomp-bdd/resources/yaml/CB_BASE.yaml [new file with mode: 0644]
openecomp-bdd/resources/yaml/Nested_FSB1ServiceTemplate.yaml [new file with mode: 0644]
openecomp-bdd/stepDefinitions/Collaboration_Steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/General_Steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/InputData_steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/Item_steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/NetworkPackage_steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/Questionnaire_steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/REST_Steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/Utils.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/VF_steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/VLM_steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/VSP_steps.js [new file with mode: 0644]
openecomp-bdd/stepDefinitions/world.js [new file with mode: 0644]
openecomp-bdd/yarn.lock [new file with mode: 0644]

diff --git a/openecomp-bdd/.gitignore b/openecomp-bdd/.gitignore
new file mode 100644 (file)
index 0000000..d2fe79b
--- /dev/null
@@ -0,0 +1,9 @@
+.idea
+.vscode
+.history
+debug.log
+dist
+docs
+node_modules
+.npmrc
+npm-debug.log
\ No newline at end of file
diff --git a/openecomp-bdd/README.txt b/openecomp-bdd/README.txt
new file mode 100644 (file)
index 0000000..35250ed
--- /dev/null
@@ -0,0 +1,4 @@
+In order to setup the project:
+
+Run "mvn install -DskipTests", this will create the documentation under the "docs".
+Open the index.html under the docs directory and continue from there.
\ No newline at end of file
diff --git a/openecomp-bdd/config.json b/openecomp-bdd/config.json
new file mode 100644 (file)
index 0000000..0a3ab03
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "protocol" : "http",
+  "server": "SET_TO_YOUR_SERVER_IP",
+
+  "port": 8285,
+  "prefix":"sdc1/feProxy/onboarding-api/v1.0",
+  "vf_prefix":"sdc1/feProxy/rest/v1"
+}
\ No newline at end of file
diff --git a/openecomp-bdd/cucumber.js b/openecomp-bdd/cucumber.js
new file mode 100644 (file)
index 0000000..4ade9b1
--- /dev/null
@@ -0,0 +1,3 @@
+module.exports = {
+       "default" : "--require stepDefinitions -f summary -r ./features -f json:report/report.json"
+};
\ No newline at end of file
diff --git a/openecomp-bdd/features/Example_Collaboration.feature b/openecomp-bdd/features/Example_Collaboration.feature
new file mode 100644 (file)
index 0000000..c799efd
--- /dev/null
@@ -0,0 +1,26 @@
+Feature: Collaboration Example File
+
+  Background: Init
+    Given I want to create a VLM
+    Scenario: Testing permissions for contributors and Owners
+      Then I want to check user "mb033001" has no permissions on this Item
+
+      When I want to add user "mb0001" as a contributor to this Item
+      Then I want to get the permissions for this Item
+      Then I want to check property "listCount" for value 2
+      Then I want to check user "cs0008" has role "owner" on this Item
+      Then I want to check user "mb0001" has role "contributor" on this Item
+
+      When I want to set the user to "aaaa"
+      Then I want the following to fail
+      When I want to get the permissions for this Item
+
+      When I want to set the user to "mb0001"
+      Then I want the following to fail
+      When I want to change the owner to user "mb0001" on this Item
+
+      When I want to set the user to "cs0008"
+      When I want to change the owner to user "mb0001" on this Item
+      Then I want to get the permissions for this Item
+      Then I want to check user "cs0008" has role "contributor" on this Item
+      Then I want to check user "mb0001" has role "owner" on this Item
\ No newline at end of file
diff --git a/openecomp-bdd/features/Example_HEAT.feature b/openecomp-bdd/features/Example_HEAT.feature
new file mode 100644 (file)
index 0000000..9ee67a4
--- /dev/null
@@ -0,0 +1,22 @@
+Feature: Heat Example File
+  Scenario: Test with update for heat file and check for validation warning
+    # Use ONLY during development. Example for running a test with an existing item in order to not create an item each test.
+    # Given Item "c99b775cc0764746b15a32b728c10402" and version Id "f044f9e265ac46c2882cb14c4b1732a5"
+    Given I want to create a VLM
+
+    When I want to create a VSP with onboarding type "NetworkPackage"
+    Then I want to make sure this Item has status "Draft"
+
+    When I want to upload a NetworkPackage for this VSP from path "resources/uploads/BASE_MUX.zip"
+    And I want to process the NetworkPackage file for this VSP
+
+    When I want to download the NetworkPackage for this VSP to path "resources/downloads/base_mux.zip"
+    Then I want to check property "data[0].file" for value "CB_BASE.yaml"
+
+    Then I want to set the input data to:
+    """
+    {"modules":[{"name":"module_1","isBase":false,"yaml":"CB_BASE.yaml"}],"unassigned":[],"artifacts":["MUX_Parameters.env","CB_MUX.yaml"],"nested":[]}
+    """
+    Then I want to update for path "/vendor-software-products/{item.id}/versions/{item.versionId}/orchestration-template-candidate/manifest" with the input data from the context
+    Then I want to process the NetworkPackage file for this VSP
+    Then I want to check property "errors['CB_MUX.yaml'][0].level" for value "WARNING"
\ No newline at end of file
diff --git a/openecomp-bdd/features/Example_ResponseData_CheckAndManipulation.feature b/openecomp-bdd/features/Example_ResponseData_CheckAndManipulation.feature
new file mode 100644 (file)
index 0000000..d9d9458
--- /dev/null
@@ -0,0 +1,22 @@
+Feature: Example for checking response data
+  Scenario: Example Checks
+    # setting some data just for testing purposes
+    Given Response Data:
+    """
+    {
+      "field1" : "string field",
+      "field2" : "true",
+      "field3": "5",
+      "field4" : [{"entry1":"a"},{"entry2":"b"},{"entry3":"c"}]
+    }
+    """
+    # printing out for test purposes
+    Then I want to print the context data
+
+    # running the different options of checking the respone data
+    Then I want to check property "field1" for value "string field"
+    Then I want to check property "field2" to be "true"
+    Then I want to check property "field3" for value 5
+    Then I want to check property "field4" to have length 3
+    Then I want to check property "field4[0].entry1" exists
+    Then I want to check property "field4[0].no_exist" does not exist
diff --git a/openecomp-bdd/features/Example_Rest_Calls.feature b/openecomp-bdd/features/Example_Rest_Calls.feature
new file mode 100644 (file)
index 0000000..e650fed
--- /dev/null
@@ -0,0 +1,36 @@
+Feature: Example Rest Calls
+  Scenario: Call Rest CRUD
+
+# Following will override the server set in the config.json. Use ONLY during development
+#    Given Server host "localhost"
+    Given I want to create a VLM
+    Given I want to create a VSP with onboarding type "Manual"
+
+    # do an update
+    Then I want to get path "/vendor-software-products/{item.id}/versions/{item.versionId}"
+
+    # dealing with getting to the correct input data from the request
+    Then I want to remove "id" from the input data
+    Then I want to remove "version" from the input data
+    Then I want to remove "candidateOnboardingOrigin" from the input data
+    Then I want to remove "onboardingOrigin" from the input data
+    Then I want to remove "onboardingMethod" from the input data
+    Then I want to update the input property "description" with value "updated"
+    Then I want to update for path "/vendor-software-products/{item.id}/versions/{item.versionId}" with the input data from the context
+
+    # do a create
+    Then I want to create input data
+    Then I want to update the input property "name" with a random value
+    Then I want to create for path "/vendor-software-products/{item.id}/versions/{item.versionId}/processes" with the input data from the context
+    Then I want to copy to property "lastProcessId" from response data path "value"
+    # do a delete
+    Then I want to delete for path "/vendor-software-products/{item.id}/versions/{item.versionId}/processes" with the value from saved property "lastProcessId"
+
+    When I want to set property "lastProcessId" to value "NotExisting"
+    Then I want the following to fail
+    When I want to delete for path "/vendor-software-products/{item.id}/versions/{item.versionId}/processes" with the value from saved property "lastProcessId"
+
+  Scenario: Create VLM through commands
+    When I want to set the input data to file "resources/json/createVLM.json"
+    Then I want to update the input property "vendorName" with a random value
+    Then I want to create for path "/vendor-license-models" with the input data from the context
diff --git a/openecomp-bdd/features/Example_ToscaTranslationFlow.feature b/openecomp-bdd/features/Example_ToscaTranslationFlow.feature
new file mode 100644 (file)
index 0000000..4b20cd3
--- /dev/null
@@ -0,0 +1,48 @@
+Feature: Tosca Validation Flow
+
+  Background: Init
+    Given I want to create a VLM
+
+  Scenario: Full - Create and submit VSP Network Package and Create VF
+    When I want to create a VSP with onboarding type "NetworkPackage"
+
+    Then I want to upload a NetworkPackage for this VSP from path "resources/uploads/BASE_MUX.zip"
+    And I want to process the NetworkPackage file for this VSP
+
+    Then I want to commit this Item
+    And I want to submit this VSP
+    And I want to package this VSP
+
+    Then I want to make sure this Item has status "Certified"
+
+    Then I want to get the package for this Item to path "resources/downloads/VSPPackage.zip"
+    And I want to compare the content of the entry "Artifacts/CB_BASE.yaml" in the zip "resources/downloads/VSPPackage.zip" with file "resources/yaml/CB_BASE.yaml"
+
+    Then I want to create a VF for this Item
+
+  Scenario: Full - Same flow for different HEAT file
+    When I want to create a VSP with onboarding type "NetworkPackage"
+
+    Then I want to upload a NetworkPackage for this VSP from path "resources/uploads/NEW_NC_with_manifest.zip"
+    And I want to process the NetworkPackage file for this VSP
+
+    Then I want to commit this Item
+    And I want to submit this VSP
+    And I want to package this VSP
+
+    Then I want to get the package for this Item to path "resources/downloads/VSPPackage.zip"
+    Then I want to create a VF for this Item
+
+  Scenario: Test Validation Error
+    When I want to create a VSP with onboarding type "NetworkPackage"
+
+    Then I want to upload a NetworkPackage for this VSP from path "resources/uploads/errorHeat.zip"
+    And I want to process the NetworkPackage file for this VSP
+    And I want to print the context data
+
+    Then I want to check property "errors['first.env'][0].level" for value "ERROR"
+    Then I want to check property "errors['first.env'][0].message" for value "ERROR: [YML1]: Invalid YAML format Problem - [empty yaml]"
+
+  Scenario: yaml to json
+    When I want to load the yaml content of the entry "CB_BASE.yaml" in the zip "resources/uploads/BASE_MUX.zip" to context
+    Then I want to check property "parameters.vnf_name.description" for value "Unique name for this VF instance"
\ No newline at end of file
diff --git a/openecomp-bdd/features/Example_VLM.feature b/openecomp-bdd/features/Example_VLM.feature
new file mode 100644 (file)
index 0000000..f4093ff
--- /dev/null
@@ -0,0 +1,46 @@
+Feature: VLM Example File
+  Scenario: VLM Defaults
+
+    When I want to create a VLM
+    Then I want to make sure this Item has status "Draft"
+    When I want to submit this VLM
+    Then I want to make sure this Item has status "Certified"
+    Then I want to create a new version for this Item
+
+  Scenario: Testing revisions with VLM
+    When I want to create a VLM
+
+    When I want to get path "/items/{item.id}/versions/{item.versionId}/revisions"
+    Then I want to check property "listCount" for value 1
+
+    # example creating input data
+    Then I want to create input data
+    Then I want to update the input property "name" with a random value
+    Then I want to update the input property "type" with value "Universal"
+    Then I want to create for path "/vendor-license-models/{item.id}/versions/{item.versionId}/license-key-groups" with the input data from the context
+    Then I want to copy to property "lastProcessId" from response data path "value"
+    Then I want to commit this Item
+
+    Then I want to get path "/items/{item.id}/versions/{item.versionId}/revisions"
+    Then I want to check property "listCount" for value 2
+    Then I want to copy to property "setRevision" from response data path "results[1].id"
+
+    When I want to revert this Item to the revision with the value from saved property "setRevision"
+    Then I want to get path "/items/{item.id}/versions/{item.versionId}/revisions"
+    Then I want to check property "listCount" for value 2
+
+    When I want to get path "/vendor-license-models/{item.id}/versions/{item.versionId}/license-key-groups"
+    Then I want to check property "listCount" for value 0
+
+    Then I want to create input data
+    Then I want to update the input property "name" with a random value
+    Then I want to update the input property "type" with value "Universal"
+    Then I want to create for path "/vendor-license-models/{item.id}/versions/{item.versionId}/license-key-groups" with the input data from the context
+    Then I want to copy to property "newLKG" from response data path "value"
+    Then I want to delete for path "/vendor-license-models/{item.id}/versions/{item.versionId}/license-key-groups" with the value from saved property "newLKG"
+
+    When I want to set property "NotExisting" to value "NotExisting"
+    Then I want the following to fail with error code "GENERAL_ERROR_REST_ID"
+    Then I want to revert this Item to the revision with the value from saved property "NotExisting"
+    Then I want to revert this Item to the revision with the value from saved property "setRevision"
+
diff --git a/openecomp-bdd/features/Example_VSP.feature b/openecomp-bdd/features/Example_VSP.feature
new file mode 100644 (file)
index 0000000..5cffa58
--- /dev/null
@@ -0,0 +1,60 @@
+Feature: VSP Example File
+
+  Background: Init
+    Given I want to create a VLM
+
+  Scenario: Create and submit VSP Network Package
+    When I want to create a VSP with onboarding type "NetworkPackage"
+    Then I want to make sure this Item has status "Draft"
+
+    When I want to upload a NetworkPackage for this VSP from path "resources/uploads/BASE_MUX.zip"
+    And I want to process the NetworkPackage file for this VSP
+
+    Then I want to commit this Item
+    And I want to submit this VSP
+    And I want to package this VSP
+
+    Then I want to make sure this Item has status "Certified"
+    When I want to get the package for this Item to path "resources/downloads/VSPPackage.zip"
+    Then I want to compare the content of the entry "Artifacts/CB_BASE.yaml" in the zip "resources/downloads/VSPPackage.zip" with file "resources/yaml/CB_BASE.yaml"
+    When I want to load the yaml content of the entry "Artifacts/CB_BASE.yaml" in the zip "resources/downloads/VSPPackage.zip" to context
+    Then I want to check property "parameters.vnf_name.description" for value "Unique name for this VF instance"
+    When I want to load the json content of the entry "Artifacts/MANIFEST.json" in the zip "resources/downloads/VSPPackage.zip" to context
+    Then I want to check property "description" for value "for testing"
+  Scenario: Create VSP Manual
+    When I want to create a VSP with onboarding type "Manual"
+    Then I want to make sure this Item has status "Draft"
+
+    When I want to create a VSP with onboarding type "Manual"
+    Then I want to get path "/vendor-software-products/{item.id}/versions/{item.versionId}"
+
+    When I want to get path "/vendor-software-products/{item.id}/versions/{item.versionId}/components"
+    Then I want to check property "listCount" for value 0
+
+    When I want to add a component
+    Then I want to get path "/vendor-software-products/{item.id}/versions/{item.versionId}/components"
+    Then I want to check property "listCount" for value 1
+
+    Then I want the following to fail with error code "VSP_VFC_COUNT_EXCEED"
+    When I want to add a component
+
+    Then I want to commit this Item
+    Then I want the following to fail
+    When I want to submit this VSP
+
+
+  Scenario: VSP Questionnaire Examples
+    Given I want to create a VSP with onboarding type "Manual"
+
+    When I want to get the questionnaire for this item
+
+    When I want to add a component
+    Then I want to get path "/vendor-software-products/{item.id}/versions/{item.versionId}/components"
+    Then I want to check property "listCount" for value 1
+
+    Then I want to get the questionnaire for this item
+    And I want to update this questionnaire with value "15" for property "general/storageDataReplication/storageReplicationSize"
+    And I want to update this questionnaire
+
+    When I want to get the questionnaire for this item
+    Then I want to check this questionnaire has value "15" for property "general/storageDataReplication/storageReplicationSize"
\ No newline at end of file
diff --git a/openecomp-bdd/features/TOSCA/CapabilityDataType.feature b/openecomp-bdd/features/TOSCA/CapabilityDataType.feature
new file mode 100644 (file)
index 0000000..64a0377
--- /dev/null
@@ -0,0 +1,24 @@
+Feature: Tosca Validation Flow
+
+  Background: Init
+    Given I want to create a VLM
+
+  Scenario: Test Capability type in service template
+    When I want to create a VSP with onboarding type "NetworkPackage"
+
+    Then I want to upload a NetworkPackage for this VSP from path "resources/uploads/zipWithExternalPort.zip"
+    And I want to process the NetworkPackage file for this VSP
+
+    Then I want to commit this Item
+    And I want to submit this VSP
+    And I want to package this VSP
+
+   Then I want to get the package for this Item to path "resources/downloads/VSPPackage.zip"
+   And I want to compare the content of the entry "Definitions/Nested_FSB1ServiceTemplate.yaml" in the zip "resources/downloads/VSPPackage.zip" with file "resources/yaml/Nested_FSB1ServiceTemplate.yaml"
+
+    Then I want to create a VF for this Item
+
+    #And I want to load the yaml content of the entry "Definitions/Nested_FSB1ServiceTemplate
+    # .yaml" in the zip "resources/downloads/VSPPackage.zip" to context
+    #And I want to check property "topology_template.node_templates.FSB1_FSB1_OAM.capabilities"
+    # for value { port_mirroring: { properties: { connection_point: [Object] } } }
\ No newline at end of file
diff --git a/openecomp-bdd/features/TOSCA/HeatToToscaTranslation.feature b/openecomp-bdd/features/TOSCA/HeatToToscaTranslation.feature
new file mode 100644 (file)
index 0000000..29d87cd
--- /dev/null
@@ -0,0 +1,20 @@
+Feature: Tosca Validation Flow
+
+  Background: Init
+    Given I want to create a VLM
+
+  Scenario: Full - Create and submit VSP Network Package and Create VF
+    When I want to create a VSP with onboarding type "NetworkPackage"
+
+    Then I want to upload a NetworkPackage for this VSP from path "resources/uploads/BASE_MUX.zip"
+    And I want to process the NetworkPackage file for this VSP
+
+    Then I want to commit this Item
+    And I want to submit this VSP
+    And I want to package this VSP
+
+    Then I want to make sure this Item has status "Certified"
+
+    Then I want to get the package for this Item to path "resources/downloads/VSPPackage.zip"
+
+    Then I want to create a VF for this Item
diff --git a/openecomp-bdd/features/TOSCA/HeatValidation.feature b/openecomp-bdd/features/TOSCA/HeatValidation.feature
new file mode 100644 (file)
index 0000000..69d6093
--- /dev/null
@@ -0,0 +1,14 @@
+Feature: Tosca Validation Flow
+
+  Background: Init
+    Given I want to create a VLM
+
+  Scenario: Test Validation Error
+    When I want to create a VSP with onboarding type "NetworkPackage"
+
+    Then I want to upload a NetworkPackage for this VSP from path "resources/uploads/errorHeat.zip"
+    And I want to process the NetworkPackage file for this VSP
+    And I want to print the context data
+
+    Then I want to check property "errors['first.env'][0].level" for value "ERROR"
+    Then I want to check property "errors['first.env'][0].message" for value "ERROR: [YML1]: Invalid YAML format Problem - [empty yaml]"
\ No newline at end of file
diff --git a/openecomp-bdd/package.json b/openecomp-bdd/package.json
new file mode 100644 (file)
index 0000000..6d866f1
--- /dev/null
@@ -0,0 +1,31 @@
+{
+  "name": "sdctests",
+  "version": "1.0.0",
+  "description": "SDC Cucumber testing",
+  "main": "reporter.js",
+  "directories": {
+    "doc": "docs"
+  },
+  "scripts": {
+    "test": "cucumber-js",
+    "test-and-report": "npm-run-all -c -s test cucumber-html-report",
+    "cucumber-html-report": "node plugins/reporter.js",
+    "cucumber-docs": "jsdoc ./stepDefinitions  -c plugins/jsdoc_config.json --readme plugins/README.md"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "assert": "^1.4.1",
+    "cucumber": "^3.2.1",
+    "cucumber-html-reporter": "^3.0.4",
+    "docdash": "^0.4.0",
+    "jsdoc": "^3.5.5",
+    "jsdoc-one-page": "0.0.5",
+    "lodash": "^4.17.4",
+    "node-zip": "^1.1.1",
+    "normalize-newline": "^3.0.0",
+    "npm-run-all": "^4.1.2",
+    "request": "^2.83.0",
+    "yamljs": "^0.3.0"
+  }
+}
diff --git a/openecomp-bdd/plugins/README.md b/openecomp-bdd/plugins/README.md
new file mode 100644 (file)
index 0000000..50d4758
--- /dev/null
@@ -0,0 +1,23 @@
+<br>
+<h1>Welcome!</h1>
+This is the documentation for using the BDD testing framework for SDC.<br>
+The Modules on the left contains all steps for particalar aress and/or explanations of what they do.<br>
+<br><br>
+<h3>How to set the server</h3>
+<li> Either update the config.json file and set the server
+<li> Or set the SERVER environment variable and it will override the configuration file
+<h3>How to run with Maven</h3>
+<li>"mvn install" will install npm if needed, download all modules and create the documentation under the "docs" folder
+<li>"mvn test-and-report" will run all  tests in the features folder and create an HTML report under the "reports" folder
+<h3>How to develop tests</h3>
+You can open the project in IntelliJ and Webstorm to run and develop scenarios.<br>
+<li><b>You will need to install the Cucumber.Js plugin</b> In order to install, go to "Settings/Plugins". If cucumber.js in not on the list, go to "Browse repositories.." and install .
+<li>First time only: Right click on feature file and try to run. Now go to "Run/edit configurations" and set the "executable path" to the "node_modules\.bin\cucumber-js.cmd" under your current project.
+<li>Now you can run the feature files by right clicking on the file and selecting "Run" from IDEA.<br>
+<li>Add to existing scenarios or create new files under the "features" directory for additional tests
+<br>
+<li>You can also run a specific test from the command line by running "npm run test -- [features/path to file]
+<h3>More Information</h3>
+<li> More on <a href="https://cucumber.io/docs/reference">Cucumber</a>
+<li> More on <a herf="https://github.com/cucumber/cucumber/wiki/Gherkin">Gherkin</a>
+<li> More on <a href="https://github.com/cucumber/cucumber-js">Cucumber-js</a>
diff --git a/openecomp-bdd/plugins/jsdoc_config.json b/openecomp-bdd/plugins/jsdoc_config.json
new file mode 100644 (file)
index 0000000..a5a608e
--- /dev/null
@@ -0,0 +1,15 @@
+{
+  "tags": {
+    "allowUnknownTags": true
+  },
+  "templates": {
+    "default": {
+      "outputSourceFiles": false
+    }
+  },
+  "plugins": ["plugins/steps"],
+  "opts": {
+    "template": "node_modules/jsdoc-one-page",
+    "destination": "docs/"
+  }
+}
\ No newline at end of file
diff --git a/openecomp-bdd/plugins/reporter.js b/openecomp-bdd/plugins/reporter.js
new file mode 100644 (file)
index 0000000..8913789
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+var reporter = require('cucumber-html-reporter');
+
+var options = {
+       theme: 'bootstrap',
+       jsonFile: 'report/report.json',
+       output: 'report/report.html',
+       reportSuiteAsScenarios: true,
+       launchReport: false,
+       metadata: {
+               "ONAP" : "Some build",
+               "Executed": "Local"
+       }
+};
+
+reporter.generate(options);
+
diff --git a/openecomp-bdd/plugins/steps.js b/openecomp-bdd/plugins/steps.js
new file mode 100644 (file)
index 0000000..2faa7ef
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+/**
+ * @module plugins/steptag
+ */
+'use strict';
+
+
+exports.handlers = {
+       /**
+        * Support @step tag.
+        *
+        * @step description
+        */
+       newDoclet: function(e) {
+               var tags = e.doclet.tags;
+               var tag;
+               var value;
+
+               // any user-defined tags in this doclet?
+               if (typeof tags !== 'undefined') {
+
+                       tags = tags.filter(function($) {
+                               return $.title === 'step' || $.title === 'examplefile';
+                       });
+
+                       if (tags.length) {
+                               // take the first one
+                               tag = tags[0];
+                               let step = null;
+                               let exampleFile = null;
+                               for (tag in tags) {
+                                       if (tags[tag].title === "step") {
+                                               step = "<b>" + tags[tag].value + "</b><br>";
+                                       }
+                                       if (tags[tag].title === "examplefile") {
+                                               exampleFile = "<i> Example Features File: " + tags[tag].value + "</i><br>";
+                                       }
+                               }
+                               if (exampleFile !== null) {
+                                       step += exampleFile;
+                               }
+                               e.doclet.meta = e.doclet.meta || {};
+                               if (e.doclet.description !== undefined) {
+                                       e.doclet.description =  step +  e.doclet.description;
+                               } else {
+                                       e.doclet.description =  step;
+                               }
+                       }
+               }
+       }
+};
\ No newline at end of file
diff --git a/openecomp-bdd/pom.xml b/openecomp-bdd/pom.xml
new file mode 100644 (file)
index 0000000..69eadf3
--- /dev/null
@@ -0,0 +1,120 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.openecomp.sdc</groupId>
+    <artifactId>onboarding-cucumber</artifactId>
+    <name>cucumber-report</name>
+    <version>1.2.0-SNAPSHOT</version>
+
+    <parent>
+        <groupId>org.openecomp.sdc</groupId>
+        <artifactId>sdc-onboarding</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+        <relativePath>../onboarding</relativePath>
+    </parent>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-clean-plugin</artifactId>
+                <version>2.6.1</version>
+                <executions>
+                    <execution>
+                        <id>clean.dist.folder</id>
+                        <phase>clean</phase>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                        <configuration>
+                            <filesets>
+                                <fileset>
+                                    <directory>${basedir}/report</directory>
+                                    <includes>
+                                        <include>**/*</include>
+                                    </includes>
+                                </fileset>
+                                <fileset>
+                                    <directory>${basedir}/resources/downloads</directory>
+                                    <includes>
+                                        <include>**/*</include>
+                                    </includes>
+                                </fileset>
+                              <fileset>
+                                <directory>${basedir}/docs</directory>
+                                <includes>
+                                  <include>**/*</include>
+                                </includes>
+                              </fileset>
+                            </filesets>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- ============================================= -->
+            <!-- Build the UI module node code -->
+            <!-- ============================================= -->
+            <plugin>
+                <groupId>com.github.eirslett</groupId>
+                <artifactId>frontend-maven-plugin</artifactId>
+                <version>1.6</version>
+
+                <configuration>
+                    <installDirectory>${project.parent.parent.basedir}</installDirectory>
+                </configuration>
+
+                <executions>
+
+                    <execution>
+                        <id>install node and yarn</id>
+                        <goals>
+                            <goal>install-node-and-yarn</goal>
+                        </goals>
+                        <configuration>
+                            <nodeVersion>v9.4.0</nodeVersion>
+                            <yarnVersion>v1.3.2</yarnVersion>
+                        </configuration>
+                    </execution>
+
+                    <execution>
+                        <id>yarn run install</id>
+                        <goals>
+                            <goal>yarn</goal>
+                        </goals>
+                        <configuration>
+                            <arguments>install</arguments>
+                        </configuration>
+                    </execution>
+                  <execution>
+                    <id>yarn run cucumber docs</id>
+                    <goals>
+                      <goal>yarn</goal>
+                    </goals>
+                    <configuration>
+                        <yarnInheritsProxyConfigFromMaven>false</yarnInheritsProxyConfigFromMaven>
+                      <arguments>run cucumber-docs</arguments>
+                    </configuration>
+                  </execution>
+
+                  <execution>
+                    <id>yarn run cucumber test</id>
+                    <goals>
+                      <goal>yarn</goal>
+                    </goals>
+                    <configuration>
+                        <yarnInheritsProxyConfigFromMaven>false</yarnInheritsProxyConfigFromMaven>
+                      <arguments>run test-and-report</arguments>
+                    </configuration>
+                    <phase>test</phase>
+                  </execution>
+
+
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+
+</project>
diff --git a/openecomp-bdd/report/.gitignore b/openecomp-bdd/report/.gitignore
new file mode 100644 (file)
index 0000000..dee5695
--- /dev/null
@@ -0,0 +1 @@
+*.*
\ No newline at end of file
diff --git a/openecomp-bdd/resources/downloads/.gitignore b/openecomp-bdd/resources/downloads/.gitignore
new file mode 100644 (file)
index 0000000..dee5695
--- /dev/null
@@ -0,0 +1 @@
+*.*
\ No newline at end of file
diff --git a/openecomp-bdd/resources/downloads/VSPPackage.zip b/openecomp-bdd/resources/downloads/VSPPackage.zip
new file mode 100644 (file)
index 0000000..633cb73
Binary files /dev/null and b/openecomp-bdd/resources/downloads/VSPPackage.zip differ
diff --git a/openecomp-bdd/resources/downloads/base_mux.zip b/openecomp-bdd/resources/downloads/base_mux.zip
new file mode 100644 (file)
index 0000000..1cc7ea4
Binary files /dev/null and b/openecomp-bdd/resources/downloads/base_mux.zip differ
diff --git a/openecomp-bdd/resources/json/createVF.json b/openecomp-bdd/resources/json/createVF.json
new file mode 100644 (file)
index 0000000..2ddd0f5
--- /dev/null
@@ -0,0 +1,50 @@
+{
+  "artifacts": {},
+  "toscaArtifacts": {},
+  "contactId": "REPLACE USER_ID",
+  "categories": [
+    {
+      "name": "Generic",
+      "normalizedName": "generic",
+      "uniqueId": "REPLACE CATEGORY VSP",
+      "icons": null,
+      "subcategories": [
+        {
+          "name": "Abstract",
+          "normalizedName": "abstract",
+          "uniqueId": "REPLACE SUBCATEGORY VSP",
+          "icons": [
+            "objectStorage",
+            "compute"
+          ],
+          "groupings": null,
+          "ownerId": null,
+          "empty": false
+        }
+      ],
+      "ownerId": null,
+      "empty": false
+    }
+  ],
+  "description": "REPLACE VSP DESCRIPTION",
+  "icon": "defaulticon",
+  "componentInstancesProperties": {},
+  "componentInstancesAttributes": {},
+  "name": "REPLACE VSP NAME",
+  "tags": [
+    "REPLACE VSP NAME"
+  ],
+  "capabilities": {},
+  "requirements": {},
+  "deploymentArtifacts": {},
+  "componentType": "RESOURCE",
+  "vendorName": "REPLACE VLM NAME",
+  "vendorRelease": "1.0",
+  "componentInstances": [],
+  "properties": [],
+  "attributes": [],
+  "groups": [],
+  "resourceType": "VF",
+  "csarUUID": "REPLACE VSP ID",
+  "csarVersion": "1.0"
+}
\ No newline at end of file
diff --git a/openecomp-bdd/resources/json/createVLM.json b/openecomp-bdd/resources/json/createVLM.json
new file mode 100644 (file)
index 0000000..9431c07
--- /dev/null
@@ -0,0 +1 @@
+{"vendorName":"RANDOM","description":"VLM Description","iconRef":"icon"}
diff --git a/openecomp-bdd/resources/json/createVSP.json b/openecomp-bdd/resources/json/createVSP.json
new file mode 100644 (file)
index 0000000..6f63261
--- /dev/null
@@ -0,0 +1,11 @@
+{
+        "vendorId":"REPLACE",
+        "name": "RANDOM",
+        "category":"resourceNewCategory.generic",
+        "subCategory":"resourceNewCategory.generic.abstract",
+        "onboardingMethod":"REPLACE",
+        "description":"for testing",
+        "vendorName":"REPLACE",
+        "icon":"icon",
+        "licensingData":{}
+}
diff --git a/openecomp-bdd/resources/uploads/BASE_MUX.zip b/openecomp-bdd/resources/uploads/BASE_MUX.zip
new file mode 100644 (file)
index 0000000..4e7fbcf
Binary files /dev/null and b/openecomp-bdd/resources/uploads/BASE_MUX.zip differ
diff --git a/openecomp-bdd/resources/uploads/NEW_NC_with_manifest.zip b/openecomp-bdd/resources/uploads/NEW_NC_with_manifest.zip
new file mode 100644 (file)
index 0000000..403cb7b
Binary files /dev/null and b/openecomp-bdd/resources/uploads/NEW_NC_with_manifest.zip differ
diff --git a/openecomp-bdd/resources/uploads/errorHeat.zip b/openecomp-bdd/resources/uploads/errorHeat.zip
new file mode 100644 (file)
index 0000000..21444fa
Binary files /dev/null and b/openecomp-bdd/resources/uploads/errorHeat.zip differ
diff --git a/openecomp-bdd/resources/uploads/zipWithExternalPort.zip b/openecomp-bdd/resources/uploads/zipWithExternalPort.zip
new file mode 100644 (file)
index 0000000..3d6b3d0
Binary files /dev/null and b/openecomp-bdd/resources/uploads/zipWithExternalPort.zip differ
diff --git a/openecomp-bdd/resources/yaml/CB_BASE.yaml b/openecomp-bdd/resources/yaml/CB_BASE.yaml
new file mode 100644 (file)
index 0000000..4aef40b
--- /dev/null
@@ -0,0 +1,91 @@
+heat_template_version: 2013-05-23
+
+description: >
+ BASE TEMPLATE
+
+parameters:
+    vnf_name:
+        type: string
+        description: Unique name for this VF instance
+        
+    vnf_id:
+        type: string
+        description: Unique ID for this VF instance        
+      
+    network_in_cidr:
+      type: string
+      description: IN network address (CIDR notation)
+      
+    network_out_cidr:
+      type: string
+      description: MUX out network address (CIDR notation)
+
+    network_in_gw_ip:
+      type: string
+      description: IN network gw address 
+
+    network_out_gw_ip:
+      type: string
+      description: MUX out network gw address 
+    
+resources:
+    random-str:
+      type: OS::Heat::RandomString
+      properties:
+        length: 4
+        
+    CB_IN_Net:
+        type: OS::Neutron::Net
+        properties:
+            name: 
+              str_replace:
+                template: CB_IN_Net_rand
+                params:
+                  rand: { get_resource: random-str }
+
+    CB_IN_Subnet:
+      type: OS::Neutron::Subnet
+      properties:
+        name:
+          str_replace:
+            template: CB_IN_Net_rand
+            params:
+              rand: { get_resource: random-str }
+        network_id: { get_resource: CB_IN_Net }
+        cidr: { get_param: network_in_cidr }
+        gateway_ip: { get_param: network_in_gw_ip }
+      
+    CB_OUT_Net:
+        type: OS::Neutron::Net
+        properties:
+            name: 
+              str_replace:
+                template: CB_OUT_Net_rand
+                params:
+                  rand: { get_resource: random-str }
+
+    CB_OUT_Subnet:
+        type: OS::Neutron::Subnet
+        properties:
+            network_id: { get_resource: CB_OUT_Net }
+            cidr: { get_param: network_out_cidr }
+            gateway_ip: { get_param: network_out_gw_ip }
+            
+outputs:
+
+    CB_IN_Net:
+      description: ID of the customer facing network
+      value: { get_resource: CB_IN_Net }
+      
+    CB_IN_Subnet:
+      description: ID of the customer facing subnet
+      value: { get_resource: CB_IN_Subnet }
+      
+    CB_OUT_Net:
+      description: ID of the Internet Facing network
+      value: { get_resource: CB_OUT_Net }
+      
+    CB_OUT_Subnet:
+      description: ID of the Internet Facing subnet
+      value: { get_resource: CB_OUT_Subnet }
diff --git a/openecomp-bdd/resources/yaml/Nested_FSB1ServiceTemplate.yaml b/openecomp-bdd/resources/yaml/Nested_FSB1ServiceTemplate.yaml
new file mode 100644 (file)
index 0000000..b41b5ea
--- /dev/null
@@ -0,0 +1,306 @@
+tosca_definitions_version: tosca_simple_yaml_1_0_0
+metadata:
+  template_name: Nested_FSB1
+imports:
+- openecomp_heat_index:
+    file: openecomp-heat/_index.yml
+- GlobalSubstitutionTypes:
+    file: GlobalSubstitutionTypesServiceTemplate.yaml
+- openecomp_index:
+    file: openecomp/_index.yml
+node_types:
+  org.openecomp.resource.vfc.compute.nodes.heat.FSB1:
+    derived_from: org.openecomp.resource.vfc.nodes.heat.nova.Server
+topology_template:
+  inputs:
+    port_FSB1_OAM_subnetpoolid:
+      type: string
+      required: true
+    compute_FSB1_availability_zone:
+      type: list
+      required: true
+      entry_schema:
+        type: string
+    index_value:
+      type: integer
+      description: Index value of this substitution service template runtime instance
+      required: false
+      default: 0
+      constraints:
+      - greater_or_equal: 0
+    port_FSB1_OAM_order:
+      type: integer
+      required: true
+    port_FSB1_OAM_exCP_naming:
+      type: org.openecomp.datatypes.Naming
+      required: true
+    port_FSB1_OAM_ip_requirements:
+      type: list
+      required: true
+      entry_schema:
+        type: org.openecomp.datatypes.network.IpRequirements
+    vm_flavor_name:
+      type: string
+      required: true
+    port_FSB1_OAM_network:
+      type: list
+      required: true
+      entry_schema:
+        type: string
+    port_FSB1_OAM_network_role:
+      type: string
+      required: true
+    port_FSB1_OAM_vlan_requirements:
+      type: list
+      required: true
+      entry_schema:
+        type: org.openecomp.datatypes.network.VlanRequirements
+    port_FSB1_OAM_network_role_tag:
+      type: string
+      required: true
+    compute_FSB1_name:
+      type: list
+      required: true
+      entry_schema:
+        type: string
+    port_FSB1_OAM_fixed_ips:
+      type: list
+      required: true
+      entry_schema:
+        type: org.openecomp.datatypes.heat.neutron.port.FixedIps
+    port_FSB1_OAM_mac_requirements:
+      type: org.openecomp.datatypes.network.MacRequirements
+      required: true
+  node_templates:
+    FSB1_FSB1_OAM:
+      type: org.openecomp.resource.cp.v2.extNeutronCP
+      properties:
+        ip_requirements:
+          get_input: port_FSB1_OAM_ip_requirements
+        network_role:
+          get_input: port_FSB1_OAM_network_role
+        fixed_ips:
+          get_input:
+          - port_FSB1_OAM_fixed_ips
+          - index_value
+        subnetpoolid:
+          get_input: port_FSB1_OAM_subnetpoolid
+        mac_requirements:
+          get_input: port_FSB1_OAM_mac_requirements
+        exCP_naming:
+          get_input: port_FSB1_OAM_exCP_naming
+        vlan_requirements:
+          get_input: port_FSB1_OAM_vlan_requirements
+        network_role_tag:
+          get_input: port_FSB1_OAM_network_role_tag
+        order:
+          get_input: port_FSB1_OAM_order
+        network:
+          get_input:
+          - port_FSB1_OAM_network
+          - index_value
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: FSB1
+          relationship: tosca.relationships.network.BindsTo
+      capabilities:
+        port_mirroring:
+          properties:
+            connection_point:
+              nf_type: ''
+              nfc_type: FSB1
+              network_role:
+                get_input: port_FSB1_OAM_network_role
+              pps_capacity: ''
+    FSB1:
+      type: org.openecomp.resource.vfc.compute.nodes.heat.FSB1
+      properties:
+        availability_zone:
+          get_input:
+          - compute_FSB1_availability_zone
+          - index_value
+        flavor:
+          get_input: vm_flavor_name
+        name:
+          get_input:
+          - compute_FSB1_name
+          - index_value
+  substitution_mappings:
+    node_type: org.openecomp.resource.abstract.nodes.FSB1
+    capabilities:
+      network.incoming.bytes.rate_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.incoming.bytes.rate
+      network.outgoing.bytes_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.outgoing.bytes
+      disk.capacity_FSB1:
+      - FSB1
+      - disk.capacity
+      disk.read.bytes.rate_FSB1:
+      - FSB1
+      - disk.read.bytes.rate
+      disk.device.latency_FSB1:
+      - FSB1
+      - disk.device.latency
+      disk.allocation_FSB1:
+      - FSB1
+      - disk.allocation
+      disk.read.bytes_FSB1:
+      - FSB1
+      - disk.read.bytes
+      disk.device.capacity_FSB1:
+      - FSB1
+      - disk.device.capacity
+      cpu_util_FSB1:
+      - FSB1
+      - cpu_util
+      disk.device.write.requests.rate_FSB1:
+      - FSB1
+      - disk.device.write.requests.rate
+      network.outgoing.bytes.rate_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.outgoing.bytes.rate
+      disk.root.size_FSB1:
+      - FSB1
+      - disk.root.size
+      feature_FSB1:
+      - FSB1
+      - feature
+      forwarder_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - forwarder
+      memory.resident_FSB1:
+      - FSB1
+      - memory.resident
+      network.incoming.packets.rate_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.incoming.packets.rate
+      cpu_FSB1:
+      - FSB1
+      - cpu
+      disk.write.requests.rate_FSB1:
+      - FSB1
+      - disk.write.requests.rate
+      feature_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - feature
+      instance_FSB1:
+      - FSB1
+      - instance
+      disk.device.read.bytes.rate_FSB1:
+      - FSB1
+      - disk.device.read.bytes.rate
+      cpu.delta_FSB1:
+      - FSB1
+      - cpu.delta
+      disk.write.bytes_FSB1:
+      - FSB1
+      - disk.write.bytes
+      disk.device.read.requests.rate_FSB1:
+      - FSB1
+      - disk.device.read.requests.rate
+      disk.device.read.requests_FSB1:
+      - FSB1
+      - disk.device.read.requests
+      disk.ephemeral.size_FSB1:
+      - FSB1
+      - disk.ephemeral.size
+      binding_FSB1:
+      - FSB1
+      - binding
+      disk.device.write.bytes_FSB1:
+      - FSB1
+      - disk.device.write.bytes
+      network.outgoing.packets.rate_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.outgoing.packets.rate
+      binding_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - binding
+      attachment_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - attachment
+      network.incoming.bytes_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.incoming.bytes
+      memory_FSB1:
+      - FSB1
+      - memory
+      network.incoming.packets_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.incoming.packets
+      disk.device.read.bytes_FSB1:
+      - FSB1
+      - disk.device.read.bytes
+      disk.device.usage_FSB1:
+      - FSB1
+      - disk.device.usage
+      disk.write.bytes.rate_FSB1:
+      - FSB1
+      - disk.write.bytes.rate
+      scalable_FSB1:
+      - FSB1
+      - scalable
+      disk.usage_FSB1:
+      - FSB1
+      - disk.usage
+      network.outpoing.packets_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - network.outpoing.packets
+      host_FSB1:
+      - FSB1
+      - host
+      disk.device.allocation_FSB1:
+      - FSB1
+      - disk.device.allocation
+      os_FSB1:
+      - FSB1
+      - os
+      vcpus_FSB1:
+      - FSB1
+      - vcpus
+      disk.write.requests_FSB1:
+      - FSB1
+      - disk.write.requests
+      disk.device.write.bytes.rate_FSB1:
+      - FSB1
+      - disk.device.write.bytes.rate
+      endpoint_FSB1:
+      - FSB1
+      - endpoint
+      disk.latency_FSB1:
+      - FSB1
+      - disk.latency
+      memory.usage_FSB1:
+      - FSB1
+      - memory.usage
+      disk.read.requests_FSB1:
+      - FSB1
+      - disk.read.requests
+      disk.device.write.requests_FSB1:
+      - FSB1
+      - disk.device.write.requests
+      disk.iops_FSB1:
+      - FSB1
+      - disk.iops
+      disk.device.iops_FSB1:
+      - FSB1
+      - disk.device.iops
+      port_mirroring_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - port_mirroring
+    requirements:
+      link_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - link
+      dependency_FSB1_FSB1_OAM:
+      - FSB1_FSB1_OAM
+      - dependency
+      dependency_FSB1:
+      - FSB1
+      - dependency
+      local_storage_FSB1:
+      - FSB1
+      - local_storage
diff --git a/openecomp-bdd/stepDefinitions/Collaboration_Steps.js b/openecomp-bdd/stepDefinitions/Collaboration_Steps.js
new file mode 100644 (file)
index 0000000..5b5062c
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When, Given} = require('cucumber');
+const assert = require('assert');
+const util = require('./Utils.js');
+
+/**
+ * @module Collaboration
+ * @description Adds the user with the given user ID as a contributor on the item
+ * @exampleFile Example_Collaboration.feature
+ * @step I want to add user {string} as a contributor to this Item
+ **/
+When('I want to add user {string} as a contributor to this Item', function(string)  {
+       let path = '/items/' + this.context.item.id + '/permissions/Contributor';
+       let inputData = {removedUsersIds:[],addedUsersIds:[string]};
+       return util.request(this.context, 'PUT', path, inputData);
+});
+
+/**
+ * @module Collaboration
+ * @description Adds the user with the given user ID as a contributor on the item
+ * @exampleFile Example_Collaboration.feature
+ * @step I want to remove user {string} as a contributor to this Item
+ **/
+When('I want to remove user {string} as a contributor to this Item', function(string)  {
+       let path = '/items/' + this.context.item.id + '/permissions/Contributor';
+       let inputData = {removedUsersIds:[string],addedUsersIds:[]};
+       return util.request(this.context, 'PUT', path, inputData);
+});
+
+/**
+ * @module Collaboration
+ * @description Changes the owner to the given User ID
+ * @exampleFile Example_Collaboration.feature
+ * @step I want to change the owner to user {string} on this Item
+ **/
+When('I want to change the owner to user {string} on this Item', function(string)  {
+       let path = '/items/' + this.context.item.id + '/permissions/Owner';
+       let inputData = {removedUsersIds:[],addedUsersIds:[string]};
+       return util.request(this.context, 'PUT', path, inputData);
+});
+
+
+/**
+ * @module Collaboration
+ * @description Checks the role for a user on the item by User id and Role can be either: Contributor/Owner
+ * @exampleFile Example_Collaboration.feature
+ * @step I want check user {string} has role {string} on this Item
+ **/
+When('I want to check user {string} has role {string} on this Item', function(string, string2)  {
+       let path = '/items/' + this.context.item.id + '/permissions';
+       return util.request(this.context, 'GET', path).then(results => {
+               for (i in results.data.results) {
+                       if (results.data.results[i].userId === string) {
+                               assert.equal(string2.toLowerCase(), results.data.results[i].permission.toLowerCase());
+                               return;
+                       }
+               }
+               assert.fail('User not found');
+       });
+});
+
+/**
+ * @module Collaboration
+ * @description Checks the user wth this Id has no permissions on this item
+ * @exampleFile Example_Collaboration.feature
+ * @step I want check user {string} has rno permissions on this Item
+ **/
+When('I want to check user {string} has no permissions on this Item', function(string)  {
+       let path = '/items/' + this.context.item.id + '/permissions';
+       return util.request(this.context, 'GET', path).then(results => {
+               for (i in results.data.results) {
+                       if (results.data.results[i].userId === string) {
+                               assert.fail('Found', null, 'User should not have permissions');
+                               return;
+                       }
+               }
+       });
+});
+
+/**
+ * @module Collaboration
+ * @description Gets the permissions for the Item
+ * @exampleFile Example_Collaboration.feature
+ * @step I want to get the permissions for this Item
+ **/
+When('I want to get the permissions for this Item', function()  {
+       let path = '/items/' + this.context.item.id + '/permissions';
+       return util.request(this.context, 'GET', path);
+});
+
+/**
+ * @module Collaboration
+ * @description Changes the user for the Rest calls
+ * @exampleFile Example_Collaboration.feature
+ * @step I want to set the user to {string}
+ **/
+When('I want to set the user to {string}', function(string)  {
+       this.context.headers.USER_ID = string;
+});
diff --git a/openecomp-bdd/stepDefinitions/General_Steps.js b/openecomp-bdd/stepDefinitions/General_Steps.js
new file mode 100644 (file)
index 0000000..389112d
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When, Given} = require('cucumber');
+const assert = require('assert');
+const _ = require('lodash');
+const normalizeNewline = require('normalize-newline');
+require('node-zip');
+YAML = require('yamljs');
+const fs = require('fs');
+const util = require('./Utils.js');
+
+/**
+ * @module ContextData
+ * @description  Use with "Given". Use ONLY for local testing when you know the value of the Item you want to use
+ * instead of creating a new one.
+ * @step Item {string} and version Id {string}
+ **/
+Given('Item {string} and version Id {string}', function (string, string2) {
+       this.context.item.id = string;
+       this.context.item.versionId = string2;
+});
+/**
+ * @module ContextData
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+ * @description Response Data::<br>
+ *     """<br>
+ *         {jsonObject}<br>
+ *             """<br>
+ * @step  Use with "Given". Use ONLY for local testing, creates a response data object
+ **/
+Given('Response Data:', function (docString) {
+       this.context.responseData = JSON.parse(docString);
+});
+
+/**
+ * @module ContextData
+ * @description Sets the server for the test. overrides configuration.
+ * @step Server with IP
+ **/
+Given('Server host {string}', function (string) {
+       this.setServer(string);
+});
+
+/**
+ * @module ContextData
+ * @description Copy a property from the response data to context Item/VLM/VSP data, example: vsp.componentId
+ * @step I want to save on the context for {string} property {string} with value {string}
+ **/
+Then('I want to save on the context for {string} property {string} with value {string}', function(string, string1, string2)  {
+       assert.equal(_.includes(['VLM', 'VSP', 'Item'], string), true);
+       let val = _.get(this.context.responseData, string2);
+       _.set(this.context, string1, val);
+});
+/**
+ * @module ContextData
+ * @description Copy a property from the response data to saved data on the context. Example: save newly generated IDs. Response data value can be from a path, xample: results[0].id
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want to save to property {string} from response data path {string}
+ **/
+Then('I want to copy to property {string} from response data path {string}', function(string, string2)  {
+       let val = _.get(this.context.responseData, string2);
+       _.set(this.context, string, val);
+});
+/**
+ * @module ContextData
+ * @description This will set the value of a saved property on the context
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want to set property {string} to value {string}
+ **/
+Then('I want to set property {string} to value {string}', function(string, string2)  {
+       _.set(this.context, string, string2);
+});
+
+/**
+ * @module ResponseData
+ * @description Will check the output data for a property and a value. property can be a path (example: results[0].id)
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+ * @step I want to check property {string} for value {string}
+ **/
+Then('I want to check property {string} for value {string}', function(string, string2)  {
+       assert.equal(_.get(this.context.responseData, string), string2);
+});
+/**
+ * @module ResponseData
+ * @description Will check the output data for a property and a integer. property can be a path (example: results[0].id)
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+ * @step I want to check property {string} for value {int}
+ **/
+Then('I want to check property {string} for value {int}', function(string, int)  {
+       assert.equal(_.get(this.context.responseData, string), int);
+});
+/**
+ * @module ResponseData
+ * @description Will check the output data for a property and a boolean. property can be a path (example: results[0].id)
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+ * @step I want to check property {string} to be "True/False"
+ **/
+Then('I want to check property {string} to be {string}', function(string, string2)  {
+       assert.equal(_.get(this.context.responseData, string), string2.toLowerCase());
+});
+/**
+ * @module ResponseData
+ * @description Will check the output data for a property and a boolean. property can be a path (example: results[0].id)
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+ * @step I want to check property {string} to have length {int}
+ **/
+Then('I want to check property {string} to have length {int}', function(string, intLength)  {
+       let arrayProp = _.get(this.context.responseData, string);
+       assert.equal(arrayProp.length, intLength);
+});
+/**
+ * @module ResponseData
+ * @description Will check the output data for a property and make sure it exists
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+ * @step I want to check property {string} exists
+ **/
+Then('I want to check property {string} exists', function(string)  {
+       assert.equal(_.has(this.context.responseData, string), true);
+});
+/**
+ * @module ResponseData
+ * @description Will check the output data for a property and make sure it does not exist
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+ * @step I want to check property {string} does not exist
+ **/
+Then('I want to check property {string} does not exist', function(string)  {
+       assert.equal(_.has(this.context.responseData, string), false);
+});
+
+/**
+* @module ContextData
+* @description Use during development to see what is on the context
+ * @exampleFile Example_ResponseData_CheckAndManipulation.feature
+* @step I want to print context data
+**/
+Then('I want to print the context data', function()  {
+       console.log('------------ context ---------------');
+       console.log(JSON.stringify(this.context, null, 2));
+       console.log('--------------------------------------');
+});
+/**
+ * @module ContextData
+ * @description Set this in order to check that the following Rest call will not have response code 200
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want the following to fail
+ **/
+Then('I want the following to fail', function()  {
+       this.context.shouldFail = true;
+});
+
+/**
+ * @module ContextData
+ * @description Set this in order to check that the following Rest call will have the error code on the return data
+ * @exampleFile Example_VSP.feature
+ * @step I want the following to fail with error code {string}
+ **/
+Then('I want the following to fail with error code {string}', function(string)  {
+       this.context.shouldFail = true;
+       this.context.errorCode = string;
+});
+
+/**
+ * @module ZipData
+ * @description Use this in order to extract a file from a zip file and to compare it to a local file (string comparison).
+ * @exampleFile Example_VSP.feature
+ * @step I want to compare the content of the entry {string} in the zip {string} with file {string}
+ **/
+Then ('I want to compare the content of the entry {string} in the zip {string} with file {string}', function (string, string2, string3) {
+       let zipFile = fs.readFileSync(string2, 'binary');
+       let zip = new JSZip(zipFile, {base64: false, checkCRC32: true});
+       let fileData = zip.files[string]._data;
+       let compareFileData = fs.readFileSync(string3, {encoding: 'ascii'});
+       assert.equal(normalizeNewline(compareFileData), normalizeNewline(fileData));
+});
+
+/**
+ * @module ZipData
+ * @description Loads the yaml from zip file onto the context responseData as JSON for running checks on the output
+ * @exampleFile Example_VSP.feature
+ * @step I want to load the yaml content of the entry {string} in the zip {string} to context
+ **/
+Then ('I want to load the yaml content of the entry {string} in the zip {string} to context', function (string, string2, callback) {
+       let zipFile = fs.readFileSync(string2, 'binary');
+       let zip = new JSZip(zipFile, {base64: false, checkCRC32: true});
+       let fileData = zip.files[string]._data;
+       let nativeObject = YAML.parse(fileData);
+       this.context.responseData = nativeObject;
+       callback();
+});
+
+
+/**
+ * @module ZipData
+ * @description Loads the json from zip file onto the context responseData for running check son the output
+ * @exampleFile Example_VSP.feature
+ * @step I want to load the json content of the entry {string} in the zip {string} to context
+ **/
+When('I want to load the json content of the entry {string} in the zip {string} to context', function (string, string2, callback) {
+       let zipFile = fs.readFileSync(string2, 'binary');
+       let zip = new JSZip(zipFile, {base64: false, checkCRC32: true});
+       let str = zip.files[string]._data;
+       this.context.responseData = JSON.parse(str);
+       callback();
+});
\ No newline at end of file
diff --git a/openecomp-bdd/stepDefinitions/InputData_steps.js b/openecomp-bdd/stepDefinitions/InputData_steps.js
new file mode 100644 (file)
index 0000000..73695d0
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When, Given} = require('cucumber');
+const assert = require('assert');
+const _ = require('lodash');
+const fs = require('fs');
+const util = require('./Utils.js');
+
+/**
+ * @module InputData
+ * @description creates an ampty input data object
+ * @exampleFile Example_Rest_Calls.feature, Example_VLM.feature
+ * @step I want to create input data
+ **/
+When('I want to create input data', function () {
+       this.context.inputData = {};
+});
+
+/**
+ * @module InputData
+ * @exampleFile Example_Heat.feature
+ * @description I want to set the input data to:<br>
+ *     """<br>
+ *         {jsonObject}<br>
+ *             """<br>
+ * @step creates an input data element with the given json object
+ **/
+When('I want to set the input data to:', function (docString) {
+       this.context.inputData = JSON.parse(docString);
+});
+
+/**
+ * @module InputData
+ * @description creates an input data object from the json in the given file
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want to set the input data to file {string}
+ **/
+When('I want to set the input data to file {string}', function (string) {
+       this.context.inputData = util.getJSONFromFile(string);
+});
+
+/**
+ * @module InputData
+ * @description sets the property on the input data to the given value
+ * @exampleFile Example_Rest_Calls.feature, Example_VLM.feature
+ * @step I want to update the input property {string} with value {string}
+ **/
+Then('I want to update the input property {string} with value {string}', function(string, string2)  {
+       _.set(this.context.inputData, string, string2);
+});
+
+/**
+ * @module InputData
+ * @description removes a property from the input data object
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want to remove {string} from the input data
+ **/
+Then('I want to remove {string} from the input data', function(string)  {
+       delete this.context.inputData[string];
+});
+
+/**
+ * @module InputData
+ * @description sets the input data property to a random value
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want to update the input property {string} with a random value
+ **/
+Then('I want to update the input property {string} with a random value', function(string)  {
+       _.set(this.context.inputData, string, util.random());
+});
diff --git a/openecomp-bdd/stepDefinitions/Item_steps.js b/openecomp-bdd/stepDefinitions/Item_steps.js
new file mode 100644 (file)
index 0000000..165df6c
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When} = require('cucumber');
+const assert = require('assert');
+const util = require('./Utils.js');
+/**
+ * @module Item
+ * @description uses item id and version id from context
+ * @exampleFile Example_VSP.feature, Example_VLM.feature
+ * @step I want to make sure this Item has status {string}
+ **/
+Then('I want to make sure this Item has status {string}', function (string) {
+       let path = '/items/' + this.context.item.id + '/versions';
+       return util.request(this.context, 'GET', path).then(result => {
+               assert.equal(result.data.results[0].id, this.context.item.versionId);
+               assert.equal(result.data.results[0].status, string);
+       });
+});
+/**
+ * @module Item
+ * @description uses item id and version id from context
+ * @exampleFile Example_VSP.feature, Example_VLM.feature
+ * @step I want to commit this Item
+ **/
+Then('I want to commit this Item', function () {
+       let path = '/items/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/actions';
+       let inputData = {action: 'Commit', commitRequest: {message: '00Behave'}};
+       return util.request(this.context, 'PUT', path, inputData);
+});
+/**
+ * @module Item
+ * @description creates a new major version. item id and version id from context
+ * @exampleFile Example_VLM.feature
+ * @step I want to create a new version for this Item
+ **/
+Then('I want to create a new version for this Item', function () {
+       let path = '/items/' + this.context.item.id + '/versions/' + this.context.item.versionId;
+       let inputData = {description: 'Behave Version', creationMethod: 'major'};
+       return util.request(this.context, 'POST', path, inputData).then(result => {
+               assert.equal(result.data.status, 'Draft');
+       });
+});
+/**
+ * @module Item
+ * @description reverts to a revision with a given saved property. Should be set from the revision list first
+ * @exampleFile Example_VLM.feature
+ * @step I want to commit this Item
+ **/
+Then('I want to revert this Item to the revision with the value from saved property {string}', function (string) {
+       let path = '/items/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/actions';
+       let inputData = {action: 'Revert', revisionRequest: {revisionId: this.context[string]}};
+       return util.request(this.context, 'PUT', path, inputData);
+});
+
diff --git a/openecomp-bdd/stepDefinitions/NetworkPackage_steps.js b/openecomp-bdd/stepDefinitions/NetworkPackage_steps.js
new file mode 100644 (file)
index 0000000..731d5b8
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When} = require('cucumber');
+const assert = require('assert');
+const util = require('./Utils.js');
+const _ = require('lodash');
+const fs = require('fs');
+require('node-zip');
+
+/**
+ * @module NetworkPackage
+ * @description Uploads the NetworkPackage file to the VSP on the context
+ * @exampleFile Example_HEAT.feature
+ * @step I want to upload a NetworkPackage for this VSP from path {string}
+ **/
+Then('I want to upload a NetworkPackage for this VSP from path {string}', function (string) {
+       let path =  '/vendor-software-products/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/orchestration-template-candidate';
+       return util.request(this.context, 'POST', path, string, true);
+});
+
+/**
+ * @module NetworkPackage
+ * @description Downloads the network package to disk
+ * @exampleFile Example_HEAT.feature
+ * @step I want to download the NetworkPackage for this VSP to path {string}
+ **/
+When('I want to download the NetworkPackage for this VSP to path {string}', function (string, callback) {
+       let path =  '/vendor-software-products/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/orchestration-template-candidate';
+       return [util.download(this.context, path, string, callback)];
+});
+
+/**
+ * @module NetworkPackage
+ * @description Processes the NetworkPackage file on the server
+ * @exampleFile Example_HEAT.feature
+ * @step I want to process the NetworkPackage file for this VSP
+ **/
+Then('I want to process the NetworkPackage file for this VSP', function () {
+       let path = '/vendor-software-products/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/orchestration-template-candidate/process';
+       return util.request(this.context, 'PUT', path, this.context.inputData);
+});
diff --git a/openecomp-bdd/stepDefinitions/Questionnaire_steps.js b/openecomp-bdd/stepDefinitions/Questionnaire_steps.js
new file mode 100644 (file)
index 0000000..ce35a1c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When} = require('cucumber');
+const assert = require('assert');
+const util = require('./Utils.js');
+const _ = require('lodash');
+
+/**
+ * @module Questionnaire
+ * @description Gets the questionnaire for the current item and saves it on the context
+ * @exampleFile Example_VSP.feature
+ * @step I want to get the questionnaire for this item
+ **/
+Then('I want to get the questionnaire for this item', function () {
+       let path = "/vendor-software-products/" + this.context.item.id + "/versions/" + this.context.item.versionId + "/questionnaire";
+       return util.request(this.context, 'GET', path).then(result => {
+               this.context.qdata = JSON.parse(result.data.data);
+               this.context.qschema = result.data.schema;
+               this.context.qurl = path;
+       });
+});
+
+/**
+ * @module Questionnaire
+ * @description Gets the questionnaire for the current item and component and saves it on the context
+ * @exampleFile Example_VSP.feature
+ * @step I want to get the questionnaire for this component
+ **/
+Then('I want to get the questionnaire for this component', function () {
+       let path = "/vendor-software-products/" + this.context.item.id + "/versions/" + this.context.item.versionId + "/components/" + this.context.componentId  + "/questionnaire";
+       return util.request(this.context, 'GET', path).then(result => {
+               this.context.qdata = JSON.parse(result.data.data);
+               this.context.qschema = result.data.schema;
+               this.context.qurl = path;
+       });
+});
+
+
+/**
+ * @module Questionnaire
+ * @description Updates the property for the saved questionnaire
+ * @exampleFile Example_VSP.feature
+ * @step I want to update this questionnaire with value {string} for path {string}
+ **/
+Then('I want to update this questionnaire with value {string} for property {string}', function (string, string2) {
+       _.set(this.context.qdata, string, string2);
+});
+
+/**
+ * @module Questionnaire
+ * @description Checks the questionnaire data on the context for the given value and property
+ * @exampleFile Example_VSP.feature
+ * @step I want to check this questionnaire has value {string} for property {string}
+ **/
+Then('I want to check this questionnaire has value {string} for property {string}', function (string, string2) {
+       assert.equal(_.get(this.context.qdata, string), string2);
+});
+
+/**
+ * @module Questionnaire
+ * @description Updates the the questionnaire data from the context to the same url that loaded it
+ * @exampleFile Example_VSP.feature
+ * @step I want to update this questionnaire
+ **/
+Then('I want to update this questionnaire', function () {
+       return util.request(this.context, 'PUT', this.context.qurl, this.context.qdata);
+});
\ No newline at end of file
diff --git a/openecomp-bdd/stepDefinitions/REST_Steps.js b/openecomp-bdd/stepDefinitions/REST_Steps.js
new file mode 100644 (file)
index 0000000..314f868
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {When} = require('cucumber');
+const _ = require('lodash');
+const util = require('./Utils.js');
+_.templateSettings.interpolate = /{([\s\S]+?)}/g;
+
+function getPath(path, context) {
+       let compiled = _.template(path);
+       return compiled(context);
+}
+/**
+ * @module Rest_Calls
+ * @description makes a GET request to the given path (path is appended after the "onboarding-api/v1.0" prefix)<br>
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want to get path {string}
+ **/
+When('I want to get path {string}', function(string)  {
+       let path = getPath(string, this.context);
+       return util.request(this.context, 'GET', path);
+});
+
+/**
+ * @module Rest_Calls
+ * @description makes a DELETE request to the given path and appends the saved property (path is appended after the "onboarding-api/v1.0" prefix)<br>
+ * @exampleFile Example_Rest_Calls.feature
+ * @step I want to delete for path {string} with the value from saved property {string}
+ **/
+When('I want to delete for path {string} with the value from saved property {string}', function(string, string2)  {
+       let path = getPath(string, this.context);
+       path += '/' + this.context[string2];
+       return util.request(this.context, 'DELETE', path);
+});
+
+
+/**
+ * @module Rest_Calls
+ * @description makes a PUT request to the given path and sends the input data from the context (path is appended after the "onboarding-api/v1.0" prefix)<br>
+ *     @exampleFile Example_Rest_Calls.feature
+ * @step I want to update for path {string} with the input data from the context
+ **/
+When('I want to update for path {string} with the input data from the context', function(string)  {
+       let path = getPath(string, this.context);
+       return util.request(this.context, 'PUT', path, this.context.inputData);
+});
+
+/**
+ * @module Rest_Calls
+ * @description makes a POST request to the given path and sends the input data from the context (path is appended after the "onboarding-api/v1.0" prefix)<br>
+ *     @exampleFile Example_Rest_Calls.feature
+ * @step I want to create for path {string} with the input data from the context
+ **/
+When('I want to create for path {string} with the input data from the context', function(string)  {
+       let path = getPath(string, this.context);
+       return util.request(this.context, 'POST', path, this.context.inputData);
+});
diff --git a/openecomp-bdd/stepDefinitions/Utils.js b/openecomp-bdd/stepDefinitions/Utils.js
new file mode 100644 (file)
index 0000000..e818e72
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const request = require('request');
+const fs = require('fs');
+require('node-zip');
+
+function _request(context, method, path, data, isBinary=false, isVFCall=false) {
+       let server = (isVFCall) ? context.vf_server : context.onboarding_server;
+       let options = {
+               method: method,
+               url: server + path,
+               headers: context.headers
+       };
+       return new Promise(function (resolve, reject) {
+               if (method === 'POST' || method === 'PUT') {
+                       if (isBinary) {
+                               var formData = {
+                                       upload: fs.createReadStream(data),
+                               };
+                               options.formData = formData;
+                       } else {
+                               options.json = data;
+                       }
+               }
+               request(options, function (err, result, data) {
+                       context.inputData = null;
+                       if (err) {
+                               console.error('Request URL: ' + result.request.uri.href);
+                               console.error('Request Method: ' + result.request.method);
+                               console.error('Response Status Code: ' +result.statusCode);
+                               console.log(err);
+                               reject(err);
+                       } else {
+                               let isExpected = (context.shouldFail) ? (result.statusCode != 200 && result.statusCode != 201) : (result.statusCode == 200 || result.statusCode == 201);
+                               if (!isExpected) {
+                                       console.error('Request URL: ' + result.request.uri.href);
+                                       console.error('Request Method: ' + result.request.method);
+                                       console.error('Response Status Code: ' +result.statusCode);
+                                       console.error(result.body);
+                                       reject('Status Code was ' + result.statusCode);
+                               }
+                               if (context.shouldFail && context.errorCode) {
+                                       let errorCode = data.errorCode;
+                                       let contextErrorCode = context.errorCode;
+                                       context.errorCode = null;
+                                       if (errorCode !== contextErrorCode) {
+                                               reject('Error Code was ' + errorCode + ' instead of ' + contextErrorCode);
+                                       }
+                               }
+                               if (context.shouldFail) {
+                                       context.shouldFail = false;
+                                       resolve({statusCode: result.statusCode, data: {}});
+                                       return;
+                               }
+                               if (method === 'GET' && isBinary) {
+                                       // downloading (NetworkPackage) files
+                                       return ({
+                                               blob: blobUtil.createBlob([data], {type: 'text/plain'}),
+                                               headers: result.headers
+                                       });
+                               } else {
+                                       if (typeof data === 'string' && data) {
+                                               data = JSON.parse(data);
+                                       }
+                                       context.responseData = data;
+                                       context.inputData = data;
+                                       resolve({statusCode: result.statusCode, data: data});
+                               }
+                       }
+               });
+       });
+}
+
+function download(context, path, filePath,  callback){
+               let options = {
+                       method: 'GET',
+                       url: context.onboarding_server + path,
+                       headers: context.headers
+               };
+               var file = fs.createWriteStream(filePath);
+               var r = request(options).pipe(file);
+               r.on('error', function (err) {
+                       console.log(err);
+                       callback(err);
+               });
+               r.on('finish', function () {
+                       file.close();
+                       let zipFile = fs.readFileSync(filePath, 'binary');
+                       let zip = new JSZip(zipFile, {base64: false, checkCRC32: true});
+                       if (zip.files['MANIFEST.json']) {
+                               let manifestData = zip.files['MANIFEST.json']._data;
+                               manifestData = manifestData.replace(/\\n/g, '');
+                               context.responseData = JSON.parse(manifestData);
+                       }
+                       callback();
+               });
+
+};
+
+function _random() {
+       let d = new Date();
+       return d.getTime().toString().split('').reverse().join('');
+}
+
+function _getJSONFromFile(file) {
+       return JSON.parse(fs.readFileSync(file, 'utf8'));
+}
+
+
+module.exports = {
+       request: _request,
+       random : _random,
+       getJSONFromFile: _getJSONFromFile,
+       download: download
+};
diff --git a/openecomp-bdd/stepDefinitions/VF_steps.js b/openecomp-bdd/stepDefinitions/VF_steps.js
new file mode 100644 (file)
index 0000000..d00cf9c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When} = require('cucumber');
+const assert = require('assert');
+const util = require('./Utils.js');
+
+
+/**
+ * @module VF
+ * @description Creates a VF for this Item (does NOT work on localhost). will get the data for the item and then update the input
+ * data for the VF call.
+ * @exampleFile Example_VSP.feature
+ * @step I want to create a VF for this Item
+ **/
+Then('I want to create a VF for this Item', function () {
+       return util.request(this.context, 'GET', '/vendor-software-products/' + this.context.item.id + '/versions/' + this.context.item.versionId).then(result => {
+               this.context.inputData = util.getJSONFromFile('resources/json/createVF.json');
+               // start replacing stuff
+               this.context.inputData.contactId = this.context.headers["USER_ID"];
+               this.context.inputData.categories[0].uniqueId = result.data.category;
+               this.context.inputData.categories[0].subcategories[0].uniqueId = result.data.subCategory;
+               this.context.inputData.description = result.data.description;
+               this.context.inputData.name = result.data.name;
+               this.context.inputData.tags[0] = result.data.name;
+               this.context.inputData.vendorName = result.data.vendorName;
+               this.context.inputData.csarUUID = this.context.item.id;
+               return util.request(this.context, 'POST', '/catalog/resources', this.context.inputData, false, true);
+       });
+});
+
diff --git a/openecomp-bdd/stepDefinitions/VLM_steps.js b/openecomp-bdd/stepDefinitions/VLM_steps.js
new file mode 100644 (file)
index 0000000..6e0dd31
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When, Given} = require('cucumber');
+const assert = require('assert');
+const util = require('./Utils.js');
+
+/**
+ * @module VLM
+ * @description Creates a new VLM with a random name and saves the id and versionId on the context item object and the context vlm object<br>
+ *     Input data  will be taken from the 'resources/json/createVLM.json' file.
+ *@exampleFile Example_VLM.feature
+ * @step I want to create a VLM
+ **/
+When('I want to create a VLM', function()  {
+       let inputData = util.getJSONFromFile('resources/json/createVLM.json');
+       inputData.vendorName = util.random();
+       let path = '/vendor-license-models';
+       return util.request(this.context, 'POST', path, inputData).then(result => {
+               this.context.item ={id : result.data.itemId, versionId: result.data.version.id};
+               this.context.vlm = {id : result.data.itemId, name : inputData.vendorName};
+       });
+});
+
+/**
+ * @module VLM
+ * @exampleFile Example_VLM.feature
+ * @step I want to submit this VLM
+ **/
+Then('I want to submit this VLM', function()  {
+       let inputData = {action: 'Submit'};
+       let path = '/vendor-license-models/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/actions';
+       return util.request(this.context, 'PUT', path, inputData);
+});
+
diff --git a/openecomp-bdd/stepDefinitions/VSP_steps.js b/openecomp-bdd/stepDefinitions/VSP_steps.js
new file mode 100644 (file)
index 0000000..b957e6f
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const {Then, When} = require('cucumber');
+const assert = require('assert');
+const util = require('./Utils.js');
+const _ = require('lodash');
+
+
+/**
+ * @module VSP
+ * @description Creates a new VSP with a random name and saves the id and versionId on the context item object and the context vsp object<br>
+ *     Input data will be taken from the 'resources/json/createVSP.json' file.
+ *     Vendor id and name are taken from the vlm on the context (requires a VLM to be created first).
+ *     @exampleFile Example_VSP.feature
+ * @step I want to create a VSP with onboarding type {string}
+ **/
+When('I want to create a VSP with onboarding type {string}', function(string)  {
+       let inputData = util.getJSONFromFile('resources/json/createVSP.json');
+       inputData.onboardingMethod = string;
+       inputData.vendorName = this.context.vlm.name;
+       inputData.vendorId = this.context.vlm.id;
+       inputData.name = util.random();
+       let path = '/vendor-software-products';
+       return util.request(this.context, 'POST', path, inputData).then(result => {
+               this.context.item = {id : result.data.itemId, versionId: result.data.version.id};
+               this.context.vsp = {id : result.data.itemId, versionId: result.data.version.id};
+       });
+});
+
+/**
+ * @module VSP
+ * @description Creates a new VSP with the 'NetowrkPackage' onboarding type and with a random name and saves the id and versionId on the context item object and the context vsp object<br>
+ *     Input data will be taken from the 'resources/json/createVSP.json' file.
+ *     Vendor id and name are taken from the vlm on the context (requires a VLM to be created first).
+ *     @exampleFile Example_VSP.feature
+ * @step I want to create a VSP with onboarding type {string}
+ **/
+When('I want to create a VSP', function()  {
+       let inputData = util.getJSONFromFile('resources/json/createVSP.json');
+       inputData.vendorName = this.context.vlm.name;
+       inputData.vendorId = this.context.vlm.id;
+       inputData.name = util.random();
+       let path = '/vendor-software-products';
+       return util.request(this.context, 'POST', path, inputData).then(result => {
+               this.context.item = {id : result.data.itemId, versionId: result.data.version.id};
+               this.context.vsp = {id : result.data.itemId, versionId: result.data.version.id};
+       });
+});
+
+
+/**
+ * @module VSP
+ * @exampleFile Example_VSP.feature
+ * @step I want to submit this VSP
+ **/
+Then('I want to submit this VSP', function () {
+       let path = '/vendor-software-products/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/actions';
+       let inputData = {action: 'Submit'};
+       return util.request(this.context, 'PUT', path, inputData);
+});
+
+/**
+ * @module VSP
+ * @exampleFile Example_VSP.feature
+ * @step I want to package this VSP
+ **/
+Then('I want to package this VSP', function () {
+       let path = '/vendor-software-products/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/actions';
+       let inputData = {action: 'Create_Package'};
+       return util.request(this.context, 'PUT', path, inputData);
+});
+
+/**
+ * @module VSP
+ * @description Adds a component to the current item
+ * @exampleFile Example_VSP.feature
+ * @step I want to add a component
+ **/
+Then('I want to add a component', function () {
+       let path = '/vendor-software-products/' + this.context.item.id + '/versions/' + this.context.item.versionId + '/components';
+       let inputData = {name: 'Cucumber Name', displayName: 'Cucumber', description: 'Cucumber Description'};
+       return util.request(this.context, 'POST', path, inputData).then(result => {
+               this.context.componentId = result.data.vfcId;
+       });
+});
+
+
+/**
+ * @module VSP
+ * @description Downloads the packaged file for this component to the given path
+ * @exampleFile Example_VSP.feature
+ * @step I want to get the package for this Item to path {string}
+ **/
+When('I want to get the package for this Item to path {string}', function (string, callback) {
+       let path =  '/vendor-software-products/packages/' + this.context.item.id;
+       return [util.download(this.context, path, string, callback)];
+});
\ No newline at end of file
diff --git a/openecomp-bdd/stepDefinitions/world.js b/openecomp-bdd/stepDefinitions/world.js
new file mode 100644 (file)
index 0000000..e87a9b5
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright Â© 2016-2017 European Support Limited
+ *
+ * Licensed 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.
+ */
+const { setWorldConstructor } = require('cucumber');
+const config = require('../config.json');
+var {setDefaultTimeout} = require('cucumber');
+
+/**
+ * @module Context
+ * @description Context that is used per feature file and can be accessed as 'this.context' in all steps.<Br>
+ *<Br>
+ * Contains the following items:<br>
+ * <li>this.context.server <ul>REST server and onboarding prefix including version. set either in configuration file or from the command line or SERVER environment variable</ul>
+ * <li>this.context.vlm <ul>When a VLM has been created, this has the an id and versionId set to the correct IDs.</ul>
+ * <li>this.context.vsp <ul>When a VSP has been created, this has the an id and versionId and componentId set to the correct IDs.</ul>
+ * <li>this.context.item <ul>When a VLM or VSP has been created, this has the an id and versionId set to the correct IDs.</ul>
+ * <li>this.context <ul>Object with properties that were saved in the steps.</ul>
+ * <li>this.context.inputdata <ul><b>Automatically updated with the last responseData from the Rest call</b><br>Object with properties that were prepares in the steps.</ul>
+ * <li>this.context.responseData <ul>Response from the last REST call.</ul>
+ **/
+class CustomWorld {
+       constructor(options) {
+               this.context = {}
+               if (options.parameters && options.parameters.server) {
+                       this.context.server =  options.parameters.server;
+               } else if (process.env.SERVER) {
+                       this.context.server = process.env.SERVER;
+               } else {
+                       this.context.server = config.server;
+               }
+               this.context.onboarding_server = (config.protocol + '://' + this.context.server + ':' + config.port + '/' + config.prefix);
+               this.context.vf_server = (config.protocol + '://' + this.context.server + ':' + config.port + '/' + config.vf_prefix);
+
+
+               this.context.headers = {};
+               this.context.headers['USER_ID']  = 'cs0008';
+
+               this.context.vlm = {id: null, versionId: null};
+               this.context.vsp = {id: null, versionId: null};
+               this.context.item = {id: null, versionId: null, componentId: null};
+
+               this.context.shouldFail = false;
+               this.context.errorCode = null;
+               this.context.inputData = null;
+               this.context.responseData = null;
+
+               this.setServer = function(server) {
+                       this.context.onboarding_server = (config.protocol + '://' +server + ':' + config.port + '/' + config.prefix);
+                       this.context.vf_server = (config.protocol + '://' +server + ':' + config.port + '/' + config.vf_prefix);
+               }
+
+               setDefaultTimeout(60 * 1000);
+       }
+}
+
+
+setWorldConstructor(CustomWorld)
diff --git a/openecomp-bdd/yarn.lock b/openecomp-bdd/yarn.lock
new file mode 100644 (file)
index 0000000..6324af4
--- /dev/null
@@ -0,0 +1,1186 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+ajv@^5.1.0:
+  version "5.5.2"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
+  dependencies:
+    co "^4.6.0"
+    fast-deep-equal "^1.0.0"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.3.0"
+
+ansi-styles@^3.1.0, ansi-styles@^3.2.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
+  dependencies:
+    color-convert "^1.9.0"
+
+any-promise@^1.0.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
+
+argparse@^1.0.7:
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+  dependencies:
+    sprintf-js "~1.0.2"
+
+array-filter@~0.0.0:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
+
+array-map@~0.0.0:
+  version "0.0.0"
+  resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
+
+array-reduce@~0.0.0:
+  version "0.0.0"
+  resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
+
+asn1@~0.2.3:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+assert@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91"
+  dependencies:
+    util "0.10.3"
+
+assertion-error-formatter@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-2.0.1.tgz#6bbdffaec8e2fa9e2b0eb158bfe353132d7c0a9b"
+  dependencies:
+    diff "^3.0.0"
+    pad-right "^0.2.2"
+    repeat-string "^1.6.1"
+
+asynckit@^0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+aws-sign2@~0.7.0:
+  version "0.7.0"
+  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+
+aws4@^1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+
+babel-runtime@^6.11.6:
+  version "6.26.0"
+  resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
+  dependencies:
+    core-js "^2.4.0"
+    regenerator-runtime "^0.11.0"
+
+babylon@7.0.0-beta.19:
+  version "7.0.0-beta.19"
+  resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.19.tgz#e928c7e807e970e0536b078ab3e0c48f9e052503"
+
+balanced-match@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
+
+bcrypt-pbkdf@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+  dependencies:
+    tweetnacl "^0.14.3"
+
+becke-ch--regex--s0-0-v1--base--pl--lib@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/becke-ch--regex--s0-0-v1--base--pl--lib/-/becke-ch--regex--s0-0-v1--base--pl--lib-1.2.0.tgz#2e73e9d21f2c2e6f5a5454045636f0ab93e46130"
+
+bluebird@^3.4.1, bluebird@~3.5.0:
+  version "3.5.1"
+  resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
+
+boom@4.x.x:
+  version "4.3.1"
+  resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
+  dependencies:
+    hoek "4.x.x"
+
+boom@5.x.x:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
+  dependencies:
+    hoek "4.x.x"
+
+brace-expansion@^1.1.7:
+  version "1.1.8"
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
+  dependencies:
+    balanced-match "^1.0.0"
+    concat-map "0.0.1"
+
+builtin-modules@^1.0.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+
+caseless@~0.12.0:
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+
+catharsis@~0.8.9:
+  version "0.8.9"
+  resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.9.tgz#98cc890ca652dd2ef0e70b37925310ff9e90fc8b"
+  dependencies:
+    underscore-contrib "~0.3.0"
+
+chalk@^2.1.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
+  dependencies:
+    ansi-styles "^3.1.0"
+    escape-string-regexp "^1.0.5"
+    supports-color "^4.0.0"
+
+cli-table@^0.3.1:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
+  dependencies:
+    colors "1.0.3"
+
+co@^4.6.0:
+  version "4.6.0"
+  resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+color-convert@^1.9.0:
+  version "1.9.1"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
+  dependencies:
+    color-name "^1.1.1"
+
+color-name@^1.1.1:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+
+colors@1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
+
+colors@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+  dependencies:
+    delayed-stream "~1.0.0"
+
+commander@^2.9.0:
+  version "2.13.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
+
+concat-map@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+core-js@^2.4.0:
+  version "2.5.3"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
+
+core-util-is@1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+cross-spawn@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
+  dependencies:
+    lru-cache "^4.0.1"
+    shebang-command "^1.2.0"
+    which "^1.2.9"
+
+cryptiles@3.x.x:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
+  dependencies:
+    boom "5.x.x"
+
+cucumber-expressions@^5.0.7:
+  version "5.0.13"
+  resolved "https://registry.yarnpkg.com/cucumber-expressions/-/cucumber-expressions-5.0.13.tgz#f174597dae6d2f0121294ac2ea65443249cf1587"
+  dependencies:
+    becke-ch--regex--s0-0-v1--base--pl--lib "^1.2.0"
+
+cucumber-html-reporter@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/cucumber-html-reporter/-/cucumber-html-reporter-3.0.4.tgz#1be0dee83f30a2f4719207859a5440ce082ffadd"
+  dependencies:
+    find "^0.2.7"
+    fs-extra "^3.0.1"
+    js-base64 "^2.3.2"
+    jsonfile "^3.0.0"
+    lodash "^4.17.2"
+    open "0.0.5"
+
+cucumber-tag-expressions@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/cucumber-tag-expressions/-/cucumber-tag-expressions-1.1.1.tgz#7f5c7b70009bc2b666591bfe64854578bedee85a"
+
+cucumber@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/cucumber/-/cucumber-3.2.1.tgz#7898509bf6f3fe4ef5fa30ba987bd53d88d53251"
+  dependencies:
+    assertion-error-formatter "^2.0.1"
+    babel-runtime "^6.11.6"
+    bluebird "^3.4.1"
+    cli-table "^0.3.1"
+    colors "^1.1.2"
+    commander "^2.9.0"
+    cucumber-expressions "^5.0.7"
+    cucumber-tag-expressions "^1.1.1"
+    duration "^0.2.0"
+    escape-string-regexp "^1.0.5"
+    figures "2.0.0"
+    gherkin "^5.0.0"
+    glob "^7.0.0"
+    indent-string "^3.1.0"
+    is-generator "^1.0.2"
+    is-stream "^1.1.0"
+    lodash "^4.0.0"
+    mz "^2.4.0"
+    progress "^2.0.0"
+    resolve "^1.3.3"
+    stack-chain "^2.0.0"
+    stacktrace-js "^2.0.0"
+    string-argv "0.0.2"
+    title-case "^2.1.1"
+    util-arity "^1.0.2"
+    verror "^1.9.0"
+
+d@1:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
+  dependencies:
+    es5-ext "^0.10.9"
+
+d@~0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309"
+  dependencies:
+    es5-ext "~0.10.2"
+
+dashdash@^1.12.0:
+  version "1.14.1"
+  resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+  dependencies:
+    assert-plus "^1.0.0"
+
+define-properties@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
+  dependencies:
+    foreach "^2.0.5"
+    object-keys "^1.0.8"
+
+delayed-stream@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+diff@^3.0.0:
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
+
+docdash@^0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/docdash/-/docdash-0.4.0.tgz#05c3a50d83189981699ee0c076d3a3950db7ec00"
+
+duplexer@~0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
+
+duration@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/duration/-/duration-0.2.0.tgz#5f9c4dfaafff655de986112efe25c5978dd85146"
+  dependencies:
+    d "~0.1.1"
+    es5-ext "~0.10.2"
+
+ecc-jsbn@~0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+  dependencies:
+    jsbn "~0.1.0"
+
+error-ex@^1.3.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
+  dependencies:
+    is-arrayish "^0.2.1"
+
+error-stack-parser@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.1.tgz#a3202b8fb03114aa9b40a0e3669e48b2b65a010a"
+  dependencies:
+    stackframe "^1.0.3"
+
+es-abstract@^1.4.3:
+  version "1.10.0"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
+  dependencies:
+    es-to-primitive "^1.1.1"
+    function-bind "^1.1.1"
+    has "^1.0.1"
+    is-callable "^1.1.3"
+    is-regex "^1.0.4"
+
+es-to-primitive@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
+  dependencies:
+    is-callable "^1.1.1"
+    is-date-object "^1.0.1"
+    is-symbol "^1.0.1"
+
+es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
+  version "0.10.38"
+  resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.38.tgz#fa7d40d65bbc9bb8a67e1d3f9cc656a00530eed3"
+  dependencies:
+    es6-iterator "~2.0.3"
+    es6-symbol "~3.1.1"
+
+es6-iterator@~2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
+  dependencies:
+    d "1"
+    es5-ext "^0.10.35"
+    es6-symbol "^3.1.1"
+
+es6-symbol@^3.1.1, es6-symbol@~3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+
+escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+event-stream@~3.3.0:
+  version "3.3.4"
+  resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
+  dependencies:
+    duplexer "~0.1.1"
+    from "~0"
+    map-stream "~0.1.0"
+    pause-stream "0.0.11"
+    split "0.3"
+    stream-combiner "~0.0.4"
+    through "~2.3.1"
+
+extend@~3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+extsprintf@1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+
+extsprintf@^1.2.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
+
+fast-deep-equal@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
+
+fast-json-stable-stringify@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
+
+figures@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
+  dependencies:
+    escape-string-regexp "^1.0.5"
+
+find@^0.2.7:
+  version "0.2.9"
+  resolved "https://registry.yarnpkg.com/find/-/find-0.2.9.tgz#4b73f1ff9e56ad91b76e716407fe5ffe6554bb8c"
+  dependencies:
+    traverse-chain "~0.1.0"
+
+foreach@^2.0.5:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
+
+forever-agent@~0.6.1:
+  version "0.6.1"
+  resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~2.3.1:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
+  dependencies:
+    asynckit "^0.4.0"
+    combined-stream "^1.0.5"
+    mime-types "^2.1.12"
+
+from@~0:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
+
+fs-extra@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291"
+  dependencies:
+    graceful-fs "^4.1.2"
+    jsonfile "^3.0.0"
+    universalify "^0.1.0"
+
+fs.realpath@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+function-bind@^1.0.2, function-bind@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+
+getpass@^0.1.1:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+  dependencies:
+    assert-plus "^1.0.0"
+
+gherkin@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/gherkin/-/gherkin-5.0.0.tgz#96def41198ec3908258b511af74f655a2764d2a1"
+
+glob@^7.0.0, glob@^7.0.5:
+  version "7.1.2"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.4"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
+graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
+  version "4.1.11"
+  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+har-schema@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+
+har-validator@~5.0.3:
+  version "5.0.3"
+  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
+  dependencies:
+    ajv "^5.1.0"
+    har-schema "^2.0.0"
+
+has-flag@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
+
+has@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
+  dependencies:
+    function-bind "^1.0.2"
+
+hawk@~6.0.2:
+  version "6.0.2"
+  resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
+  dependencies:
+    boom "4.x.x"
+    cryptiles "3.x.x"
+    hoek "4.x.x"
+    sntp "2.x.x"
+
+hoek@4.x.x:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
+
+hosted-git-info@^2.1.4:
+  version "2.5.0"
+  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
+
+http-signature@~1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+  dependencies:
+    assert-plus "^1.0.0"
+    jsprim "^1.2.2"
+    sshpk "^1.7.0"
+
+indent-string@^3.1.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
+
+inflight@^1.0.4:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+  dependencies:
+    once "^1.3.0"
+    wrappy "1"
+
+inherits@2:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+inherits@2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+
+is-arrayish@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+
+is-builtin-module@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
+  dependencies:
+    builtin-modules "^1.0.0"
+
+is-callable@^1.1.1, is-callable@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
+
+is-date-object@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+
+is-generator@^1.0.2:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3"
+
+is-regex@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
+  dependencies:
+    has "^1.0.1"
+
+is-stream@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+is-symbol@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
+
+is-typedarray@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+isexe@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+
+isstream@~0.1.2:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+js-base64@^2.3.2:
+  version "2.4.3"
+  resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582"
+
+js2xmlparser@~3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-3.0.0.tgz#3fb60eaa089c5440f9319f51760ccd07e2499733"
+  dependencies:
+    xmlcreate "^1.0.1"
+
+jsbn@~0.1.0:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+
+jsdoc-one-page@0.0.5:
+  version "0.0.5"
+  resolved "https://registry.yarnpkg.com/jsdoc-one-page/-/jsdoc-one-page-0.0.5.tgz#8701e022159844dbd9cb64d9504974059604f58a"
+
+jsdoc@^3.5.5:
+  version "3.5.5"
+  resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.5.5.tgz#484521b126e81904d632ff83ec9aaa096708fa4d"
+  dependencies:
+    babylon "7.0.0-beta.19"
+    bluebird "~3.5.0"
+    catharsis "~0.8.9"
+    escape-string-regexp "~1.0.5"
+    js2xmlparser "~3.0.0"
+    klaw "~2.0.0"
+    marked "~0.3.6"
+    mkdirp "~0.5.1"
+    requizzle "~0.2.1"
+    strip-json-comments "~2.0.1"
+    taffydb "2.6.2"
+    underscore "~1.8.3"
+
+json-parse-better-errors@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a"
+
+json-schema-traverse@^0.3.0:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
+
+json-schema@0.2.3:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stringify-safe@~5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+jsonfile@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
+  optionalDependencies:
+    graceful-fs "^4.1.6"
+
+jsonify@~0.0.0:
+  version "0.0.0"
+  resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+jsprim@^1.2.2:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
+  dependencies:
+    assert-plus "1.0.0"
+    extsprintf "1.3.0"
+    json-schema "0.2.3"
+    verror "1.10.0"
+
+jszip@2.5.0:
+  version "2.5.0"
+  resolved "https://registry.yarnpkg.com/jszip/-/jszip-2.5.0.tgz#7444fd8551ddf3e5da7198fea0c91bc8308cc274"
+  dependencies:
+    pako "~0.2.5"
+
+klaw@~2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/klaw/-/klaw-2.0.0.tgz#59c128e0dc5ce410201151194eeb9cbf858650f6"
+  dependencies:
+    graceful-fs "^4.1.9"
+
+load-json-file@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
+  dependencies:
+    graceful-fs "^4.1.2"
+    parse-json "^4.0.0"
+    pify "^3.0.0"
+    strip-bom "^3.0.0"
+
+lodash@^4.0.0, lodash@^4.17.2, lodash@^4.17.4:
+  version "4.17.4"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+
+lower-case@^1.1.1:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
+
+lru-cache@^4.0.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
+  dependencies:
+    pseudomap "^1.0.2"
+    yallist "^2.1.2"
+
+map-stream@~0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
+
+marked@~0.3.6:
+  version "0.3.12"
+  resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.12.tgz#7cf25ff2252632f3fe2406bde258e94eee927519"
+
+memorystream@^0.3.1:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
+
+mime-db@~1.30.0:
+  version "1.30.0"
+  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
+
+mime-types@^2.1.12, mime-types@~2.1.17:
+  version "2.1.17"
+  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
+  dependencies:
+    mime-db "~1.30.0"
+
+minimatch@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+  dependencies:
+    brace-expansion "^1.1.7"
+
+minimist@0.0.8:
+  version "0.0.8"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+
+mkdirp@~0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+  dependencies:
+    minimist "0.0.8"
+
+mz@^2.4.0:
+  version "2.7.0"
+  resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
+  dependencies:
+    any-promise "^1.0.0"
+    object-assign "^4.0.1"
+    thenify-all "^1.0.0"
+
+no-case@^2.2.0:
+  version "2.3.2"
+  resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
+  dependencies:
+    lower-case "^1.1.1"
+
+node-zip@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/node-zip/-/node-zip-1.1.1.tgz#94d1ad674a3cd46a1588dd736f4a9a78c757eb62"
+  dependencies:
+    jszip "2.5.0"
+
+normalize-newline@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/normalize-newline/-/normalize-newline-3.0.0.tgz#1cbea804aba436001f83938ab21ec039d69ae9d3"
+
+normalize-package-data@^2.3.2:
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
+  dependencies:
+    hosted-git-info "^2.1.4"
+    is-builtin-module "^1.0.0"
+    semver "2 || 3 || 4 || 5"
+    validate-npm-package-license "^3.0.1"
+
+npm-run-all@^4.1.2:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.2.tgz#90d62d078792d20669139e718621186656cea056"
+  dependencies:
+    ansi-styles "^3.2.0"
+    chalk "^2.1.0"
+    cross-spawn "^5.1.0"
+    memorystream "^0.3.1"
+    minimatch "^3.0.4"
+    ps-tree "^1.1.0"
+    read-pkg "^3.0.0"
+    shell-quote "^1.6.1"
+    string.prototype.padend "^3.0.0"
+
+oauth-sign@~0.8.2:
+  version "0.8.2"
+  resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^4.0.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object-keys@^1.0.8:
+  version "1.0.11"
+  resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
+
+once@^1.3.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+  dependencies:
+    wrappy "1"
+
+open@0.0.5:
+  version "0.0.5"
+  resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc"
+
+pad-right@^0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/pad-right/-/pad-right-0.2.2.tgz#6fbc924045d244f2a2a244503060d3bfc6009774"
+  dependencies:
+    repeat-string "^1.5.2"
+
+pako@~0.2.5:
+  version "0.2.9"
+  resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
+
+parse-json@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+  dependencies:
+    error-ex "^1.3.1"
+    json-parse-better-errors "^1.0.1"
+
+path-is-absolute@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-parse@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+path-type@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
+  dependencies:
+    pify "^3.0.0"
+
+pause-stream@0.0.11:
+  version "0.0.11"
+  resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
+  dependencies:
+    through "~2.3"
+
+performance-now@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
+
+pify@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
+
+progress@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
+
+ps-tree@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014"
+  dependencies:
+    event-stream "~3.3.0"
+
+pseudomap@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
+
+punycode@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@~6.5.1:
+  version "6.5.1"
+  resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
+
+read-pkg@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
+  dependencies:
+    load-json-file "^4.0.0"
+    normalize-package-data "^2.3.2"
+    path-type "^3.0.0"
+
+regenerator-runtime@^0.11.0:
+  version "0.11.1"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+
+repeat-string@^1.5.2, repeat-string@^1.6.1:
+  version "1.6.1"
+  resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+
+request@^2.83.0:
+  version "2.83.0"
+  resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
+  dependencies:
+    aws-sign2 "~0.7.0"
+    aws4 "^1.6.0"
+    caseless "~0.12.0"
+    combined-stream "~1.0.5"
+    extend "~3.0.1"
+    forever-agent "~0.6.1"
+    form-data "~2.3.1"
+    har-validator "~5.0.3"
+    hawk "~6.0.2"
+    http-signature "~1.2.0"
+    is-typedarray "~1.0.0"
+    isstream "~0.1.2"
+    json-stringify-safe "~5.0.1"
+    mime-types "~2.1.17"
+    oauth-sign "~0.8.2"
+    performance-now "^2.1.0"
+    qs "~6.5.1"
+    safe-buffer "^5.1.1"
+    stringstream "~0.0.5"
+    tough-cookie "~2.3.3"
+    tunnel-agent "^0.6.0"
+    uuid "^3.1.0"
+
+requizzle@~0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.1.tgz#6943c3530c4d9a7e46f1cddd51c158fc670cdbde"
+  dependencies:
+    underscore "~1.6.0"
+
+resolve@^1.3.3:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
+  dependencies:
+    path-parse "^1.0.5"
+
+safe-buffer@^5.0.1, safe-buffer@^5.1.1:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
+
+"semver@2 || 3 || 4 || 5":
+  version "5.5.0"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
+
+shebang-command@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
+  dependencies:
+    shebang-regex "^1.0.0"
+
+shebang-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+
+shell-quote@^1.6.1:
+  version "1.6.1"
+  resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
+  dependencies:
+    array-filter "~0.0.0"
+    array-map "~0.0.0"
+    array-reduce "~0.0.0"
+    jsonify "~0.0.0"
+
+sntp@2.x.x:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
+  dependencies:
+    hoek "4.x.x"
+
+source-map@0.5.6:
+  version "0.5.6"
+  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
+
+spdx-correct@~1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
+  dependencies:
+    spdx-license-ids "^1.0.2"
+
+spdx-expression-parse@~1.0.0:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
+
+spdx-license-ids@^1.0.2:
+  version "1.2.2"
+  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+
+split@0.3:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
+  dependencies:
+    through "2"
+
+sprintf-js@~1.0.2:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+
+sshpk@^1.7.0:
+  version "1.13.1"
+  resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
+  dependencies:
+    asn1 "~0.2.3"
+    assert-plus "^1.0.0"
+    dashdash "^1.12.0"
+    getpass "^0.1.1"
+  optionalDependencies:
+    bcrypt-pbkdf "^1.0.0"
+    ecc-jsbn "~0.1.1"
+    jsbn "~0.1.0"
+    tweetnacl "~0.14.0"
+
+stack-chain@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-2.0.0.tgz#d73d1172af89565f07438b5bcc086831b6689b2d"
+
+stack-generator@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.2.tgz#3c13d952a596ab9318fec0669d0a1df8b87176c7"
+  dependencies:
+    stackframe "^1.0.4"
+
+stackframe@^1.0.3, stackframe@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b"
+
+stacktrace-gps@^3.0.1:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.2.tgz#33f8baa4467323ab2bd1816efa279942ba431ccc"
+  dependencies:
+    source-map "0.5.6"
+    stackframe "^1.0.4"
+
+stacktrace-js@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.0.tgz#776ca646a95bc6c6b2b90776536a7fc72c6ddb58"
+  dependencies:
+    error-stack-parser "^2.0.1"
+    stack-generator "^2.0.1"
+    stacktrace-gps "^3.0.1"
+
+stream-combiner@~0.0.4:
+  version "0.0.4"
+  resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
+  dependencies:
+    duplexer "~0.1.1"
+
+string-argv@0.0.2:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736"
+
+string.prototype.padend@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0"
+  dependencies:
+    define-properties "^1.1.2"
+    es-abstract "^1.4.3"
+    function-bind "^1.0.2"
+
+stringstream@~0.0.5:
+  version "0.0.5"
+  resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-bom@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+
+strip-json-comments@~2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+
+supports-color@^4.0.0:
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
+  dependencies:
+    has-flag "^2.0.0"
+
+taffydb@2.6.2:
+  version "2.6.2"
+  resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268"
+
+thenify-all@^1.0.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
+  dependencies:
+    thenify ">= 3.1.0 < 4"
+
+"thenify@>= 3.1.0 < 4":
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
+  dependencies:
+    any-promise "^1.0.0"
+
+through@2, through@~2.3, through@~2.3.1:
+  version "2.3.8"
+  resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+
+title-case@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa"
+  dependencies:
+    no-case "^2.2.0"
+    upper-case "^1.0.3"
+
+tough-cookie@~2.3.3:
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
+  dependencies:
+    punycode "^1.4.1"
+
+traverse-chain@~0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1"
+
+tunnel-agent@^0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+  dependencies:
+    safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+  version "0.14.5"
+  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+underscore-contrib@~0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/underscore-contrib/-/underscore-contrib-0.3.0.tgz#665b66c24783f8fa2b18c9f8cbb0e2c7d48c26c7"
+  dependencies:
+    underscore "1.6.0"
+
+underscore@1.6.0, underscore@~1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
+
+underscore@~1.8.3:
+  version "1.8.3"
+  resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
+
+universalify@^0.1.0:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
+
+upper-case@^1.0.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
+
+util-arity@^1.0.2:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/util-arity/-/util-arity-1.1.0.tgz#59d01af1fdb3fede0ac4e632b0ab5f6ce97c9330"
+
+util@0.10.3:
+  version "0.10.3"
+  resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
+  dependencies:
+    inherits "2.0.1"
+
+uuid@^3.1.0:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
+
+validate-npm-package-license@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
+  dependencies:
+    spdx-correct "~1.0.0"
+    spdx-expression-parse "~1.0.0"
+
+verror@1.10.0, verror@^1.9.0:
+  version "1.10.0"
+  resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+  dependencies:
+    assert-plus "^1.0.0"
+    core-util-is "1.0.2"
+    extsprintf "^1.2.0"
+
+which@^1.2.9:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
+  dependencies:
+    isexe "^2.0.0"
+
+wrappy@1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+xmlcreate@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-1.0.2.tgz#fa6bf762a60a413fb3dd8f4b03c5b269238d308f"
+
+yallist@^2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
+
+yamljs@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.3.0.tgz#dc060bf267447b39f7304e9b2bfbe8b5a7ddb03b"
+  dependencies:
+    argparse "^1.0.7"
+    glob "^7.0.5"