From 637206b5e05910cc3bdd64bbd35d296ce282524c Mon Sep 17 00:00:00 2001 From: ilanap Date: Sun, 4 Feb 2018 17:06:22 +0200 Subject: [PATCH] Adding BDD cucumber testing component Change-Id: I4fd7eb798cbc7cad85562453fb0a6f74fd12ff5b Issue-ID: SDC-990 Signed-off-by: ilanap --- openecomp-bdd/.gitignore | 9 + openecomp-bdd/README.txt | 4 + openecomp-bdd/config.json | 8 + openecomp-bdd/cucumber.js | 3 + .../features/Example_Collaboration.feature | 26 + openecomp-bdd/features/Example_HEAT.feature | 22 + ...ample_ResponseData_CheckAndManipulation.feature | 22 + openecomp-bdd/features/Example_Rest_Calls.feature | 36 + .../features/Example_ToscaTranslationFlow.feature | 48 + openecomp-bdd/features/Example_VLM.feature | 46 + openecomp-bdd/features/Example_VSP.feature | 60 + .../features/TOSCA/CapabilityDataType.feature | 24 + .../features/TOSCA/HeatToToscaTranslation.feature | 20 + .../features/TOSCA/HeatValidation.feature | 14 + openecomp-bdd/package.json | 31 + openecomp-bdd/plugins/README.md | 23 + openecomp-bdd/plugins/jsdoc_config.json | 15 + openecomp-bdd/plugins/reporter.js | 31 + openecomp-bdd/plugins/steps.js | 65 ++ openecomp-bdd/pom.xml | 120 ++ openecomp-bdd/report/.gitignore | 1 + openecomp-bdd/resources/downloads/.gitignore | 1 + openecomp-bdd/resources/downloads/VSPPackage.zip | Bin 0 -> 44169 bytes openecomp-bdd/resources/downloads/base_mux.zip | Bin 0 -> 3844 bytes openecomp-bdd/resources/json/createVF.json | 50 + openecomp-bdd/resources/json/createVLM.json | 1 + openecomp-bdd/resources/json/createVSP.json | 11 + openecomp-bdd/resources/uploads/BASE_MUX.zip | Bin 0 -> 3779 bytes .../resources/uploads/NEW_NC_with_manifest.zip | Bin 0 -> 1545 bytes openecomp-bdd/resources/uploads/errorHeat.zip | Bin 0 -> 1304 bytes .../resources/uploads/zipWithExternalPort.zip | Bin 0 -> 1453 bytes openecomp-bdd/resources/yaml/CB_BASE.yaml | 91 ++ .../resources/yaml/Nested_FSB1ServiceTemplate.yaml | 306 +++++ .../stepDefinitions/Collaboration_Steps.js | 113 ++ openecomp-bdd/stepDefinitions/General_Steps.js | 217 ++++ openecomp-bdd/stepDefinitions/InputData_steps.js | 83 ++ openecomp-bdd/stepDefinitions/Item_steps.js | 67 ++ .../stepDefinitions/NetworkPackage_steps.js | 54 + .../stepDefinitions/Questionnaire_steps.js | 80 ++ openecomp-bdd/stepDefinitions/REST_Steps.js | 69 ++ openecomp-bdd/stepDefinitions/Utils.js | 128 +++ openecomp-bdd/stepDefinitions/VF_steps.js | 43 + openecomp-bdd/stepDefinitions/VLM_steps.js | 47 + openecomp-bdd/stepDefinitions/VSP_steps.js | 110 ++ openecomp-bdd/stepDefinitions/world.js | 69 ++ openecomp-bdd/yarn.lock | 1186 ++++++++++++++++++++ 46 files changed, 3354 insertions(+) create mode 100644 openecomp-bdd/.gitignore create mode 100644 openecomp-bdd/README.txt create mode 100644 openecomp-bdd/config.json create mode 100644 openecomp-bdd/cucumber.js create mode 100644 openecomp-bdd/features/Example_Collaboration.feature create mode 100644 openecomp-bdd/features/Example_HEAT.feature create mode 100644 openecomp-bdd/features/Example_ResponseData_CheckAndManipulation.feature create mode 100644 openecomp-bdd/features/Example_Rest_Calls.feature create mode 100644 openecomp-bdd/features/Example_ToscaTranslationFlow.feature create mode 100644 openecomp-bdd/features/Example_VLM.feature create mode 100644 openecomp-bdd/features/Example_VSP.feature create mode 100644 openecomp-bdd/features/TOSCA/CapabilityDataType.feature create mode 100644 openecomp-bdd/features/TOSCA/HeatToToscaTranslation.feature create mode 100644 openecomp-bdd/features/TOSCA/HeatValidation.feature create mode 100644 openecomp-bdd/package.json create mode 100644 openecomp-bdd/plugins/README.md create mode 100644 openecomp-bdd/plugins/jsdoc_config.json create mode 100644 openecomp-bdd/plugins/reporter.js create mode 100644 openecomp-bdd/plugins/steps.js create mode 100644 openecomp-bdd/pom.xml create mode 100644 openecomp-bdd/report/.gitignore create mode 100644 openecomp-bdd/resources/downloads/.gitignore create mode 100644 openecomp-bdd/resources/downloads/VSPPackage.zip create mode 100644 openecomp-bdd/resources/downloads/base_mux.zip create mode 100644 openecomp-bdd/resources/json/createVF.json create mode 100644 openecomp-bdd/resources/json/createVLM.json create mode 100644 openecomp-bdd/resources/json/createVSP.json create mode 100644 openecomp-bdd/resources/uploads/BASE_MUX.zip create mode 100644 openecomp-bdd/resources/uploads/NEW_NC_with_manifest.zip create mode 100644 openecomp-bdd/resources/uploads/errorHeat.zip create mode 100644 openecomp-bdd/resources/uploads/zipWithExternalPort.zip create mode 100644 openecomp-bdd/resources/yaml/CB_BASE.yaml create mode 100644 openecomp-bdd/resources/yaml/Nested_FSB1ServiceTemplate.yaml create mode 100644 openecomp-bdd/stepDefinitions/Collaboration_Steps.js create mode 100644 openecomp-bdd/stepDefinitions/General_Steps.js create mode 100644 openecomp-bdd/stepDefinitions/InputData_steps.js create mode 100644 openecomp-bdd/stepDefinitions/Item_steps.js create mode 100644 openecomp-bdd/stepDefinitions/NetworkPackage_steps.js create mode 100644 openecomp-bdd/stepDefinitions/Questionnaire_steps.js create mode 100644 openecomp-bdd/stepDefinitions/REST_Steps.js create mode 100644 openecomp-bdd/stepDefinitions/Utils.js create mode 100644 openecomp-bdd/stepDefinitions/VF_steps.js create mode 100644 openecomp-bdd/stepDefinitions/VLM_steps.js create mode 100644 openecomp-bdd/stepDefinitions/VSP_steps.js create mode 100644 openecomp-bdd/stepDefinitions/world.js create mode 100644 openecomp-bdd/yarn.lock diff --git a/openecomp-bdd/.gitignore b/openecomp-bdd/.gitignore new file mode 100644 index 0000000000..d2fe79b459 --- /dev/null +++ b/openecomp-bdd/.gitignore @@ -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 index 0000000000..35250ed375 --- /dev/null +++ b/openecomp-bdd/README.txt @@ -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 index 0000000000..0a3ab03650 --- /dev/null +++ b/openecomp-bdd/config.json @@ -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 index 0000000000..4ade9b1cb3 --- /dev/null +++ b/openecomp-bdd/cucumber.js @@ -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 index 0000000000..c799efda12 --- /dev/null +++ b/openecomp-bdd/features/Example_Collaboration.feature @@ -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 index 0000000000..9ee67a4dcb --- /dev/null +++ b/openecomp-bdd/features/Example_HEAT.feature @@ -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 index 0000000000..d9d94582ca --- /dev/null +++ b/openecomp-bdd/features/Example_ResponseData_CheckAndManipulation.feature @@ -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 index 0000000000..e650fede66 --- /dev/null +++ b/openecomp-bdd/features/Example_Rest_Calls.feature @@ -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 index 0000000000..4b20cd3404 --- /dev/null +++ b/openecomp-bdd/features/Example_ToscaTranslationFlow.feature @@ -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 index 0000000000..f4093ff07e --- /dev/null +++ b/openecomp-bdd/features/Example_VLM.feature @@ -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 index 0000000000..5cffa585c5 --- /dev/null +++ b/openecomp-bdd/features/Example_VSP.feature @@ -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 index 0000000000..64a0377db5 --- /dev/null +++ b/openecomp-bdd/features/TOSCA/CapabilityDataType.feature @@ -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 index 0000000000..29d87cd2c2 --- /dev/null +++ b/openecomp-bdd/features/TOSCA/HeatToToscaTranslation.feature @@ -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 index 0000000000..69d6093776 --- /dev/null +++ b/openecomp-bdd/features/TOSCA/HeatValidation.feature @@ -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 index 0000000000..6d866f1344 --- /dev/null +++ b/openecomp-bdd/package.json @@ -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 index 0000000000..50d4758042 --- /dev/null +++ b/openecomp-bdd/plugins/README.md @@ -0,0 +1,23 @@ +
+

Welcome!

+This is the documentation for using the BDD testing framework for SDC.
+The Modules on the left contains all steps for particalar aress and/or explanations of what they do.
+

+

How to set the server

+
  • Either update the config.json file and set the server +
  • Or set the SERVER environment variable and it will override the configuration file +

    How to run with Maven

    +
  • "mvn install" will install npm if needed, download all modules and create the documentation under the "docs" folder +
  • "mvn test-and-report" will run all tests in the features folder and create an HTML report under the "reports" folder +

    How to develop tests

    +You can open the project in IntelliJ and Webstorm to run and develop scenarios.
    +
  • You will need to install the Cucumber.Js plugin In order to install, go to "Settings/Plugins". If cucumber.js in not on the list, go to "Browse repositories.." and install . +
  • 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. +
  • Now you can run the feature files by right clicking on the file and selecting "Run" from IDEA.
    +
  • Add to existing scenarios or create new files under the "features" directory for additional tests +
    +
  • You can also run a specific test from the command line by running "npm run test -- [features/path to file] +

    More Information

    +
  • More on Cucumber +
  • More on Gherkin +
  • More on Cucumber-js diff --git a/openecomp-bdd/plugins/jsdoc_config.json b/openecomp-bdd/plugins/jsdoc_config.json new file mode 100644 index 0000000000..a5a608e805 --- /dev/null +++ b/openecomp-bdd/plugins/jsdoc_config.json @@ -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 index 0000000000..8913789c95 --- /dev/null +++ b/openecomp-bdd/plugins/reporter.js @@ -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 index 0000000000..2faa7efbd8 --- /dev/null +++ b/openecomp-bdd/plugins/steps.js @@ -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 = "" + tags[tag].value + "
    "; + } + if (tags[tag].title === "examplefile") { + exampleFile = " Example Features File: " + tags[tag].value + "
    "; + } + } + 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 index 0000000000..69eadf36a5 --- /dev/null +++ b/openecomp-bdd/pom.xml @@ -0,0 +1,120 @@ + + 4.0.0 + + org.openecomp.sdc + onboarding-cucumber + cucumber-report + 1.2.0-SNAPSHOT + + + org.openecomp.sdc + sdc-onboarding + 1.2.0-SNAPSHOT + ../onboarding + + + + + + maven-clean-plugin + 2.6.1 + + + clean.dist.folder + clean + + clean + + + + + ${basedir}/report + + **/* + + + + ${basedir}/resources/downloads + + **/* + + + + ${basedir}/docs + + **/* + + + + + + + + + + + + + com.github.eirslett + frontend-maven-plugin + 1.6 + + + ${project.parent.parent.basedir} + + + + + + install node and yarn + + install-node-and-yarn + + + v9.4.0 + v1.3.2 + + + + + yarn run install + + yarn + + + install + + + + yarn run cucumber docs + + yarn + + + false + run cucumber-docs + + + + + yarn run cucumber test + + yarn + + + false + run test-and-report + + test + + + + + + + + + + diff --git a/openecomp-bdd/report/.gitignore b/openecomp-bdd/report/.gitignore new file mode 100644 index 0000000000..dee5695746 --- /dev/null +++ b/openecomp-bdd/report/.gitignore @@ -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 index 0000000000..dee5695746 --- /dev/null +++ b/openecomp-bdd/resources/downloads/.gitignore @@ -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 index 0000000000000000000000000000000000000000..633cb7363ce86d7cf20fe576183da8b77a49d842 GIT binary patch literal 44169 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 literal 0 HcmV?d00001 diff --git a/openecomp-bdd/resources/downloads/base_mux.zip b/openecomp-bdd/resources/downloads/base_mux.zip new file mode 100644 index 0000000000000000000000000000000000000000..1cc7ea446c854e90df57c73b1a70b5bcc8785b62 GIT binary patch literal 3844 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 B=3f8+ literal 0 HcmV?d00001 diff --git a/openecomp-bdd/resources/json/createVF.json b/openecomp-bdd/resources/json/createVF.json new file mode 100644 index 0000000000..2ddd0f5c09 --- /dev/null +++ b/openecomp-bdd/resources/json/createVF.json @@ -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 index 0000000000..9431c070e6 --- /dev/null +++ b/openecomp-bdd/resources/json/createVLM.json @@ -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 index 0000000000..6f63261beb --- /dev/null +++ b/openecomp-bdd/resources/json/createVSP.json @@ -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 index 0000000000000000000000000000000000000000..4e7fbcf31ded645aac8df57e9b7e3295ddc171c3 GIT binary patch literal 3779 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 FzW{Ql<5~a! literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..403cb7be1faa500ba13ab43050f745e91b3de27a GIT binary patch literal 1545 zcmZ{kcTkge9LC>3*c$>;Lp5lkSStbr&T-0;5ne;X64|l@WQU<3MhPT_V;Hb98&swU z3KURTN`nvsh~$M5kdY8QmM9{SimXP@vsAA4`{TL${qcP6x#xQi9u$Qm01-eEs7<|u z?PRIX+ywyO01N=+go-n=Qy)YqO)LnqWy&pezgjjpCr)!FQL-`~hb9?ZbV{Xi zs`6cvG~~Yb!_~OywD8&^XB3)vmM>>!nodrQu0gbfHDt_!;mi*Fw@}7$G1wSqpWQXW zKx{YwC<;S`g!x7X`+4em61+mSV?%=L?Qub`bQD`8KJ26vs94zv3SFn{o@wTr=GkkR z*6($$$--Ft@i6e&<*MWSdU|7TR{^}>@3HRY*!46<#MMp&L$fNQvLBP!9!xZ%ujOdJ zV;0S8S>|WxYiH?Uev(pSCEoU8n5gu>SrTaS(ona1V|5L8z;a^afe{u;^o>;(bFrkX z*>w$m>B@709H#L}-a4GtUb$=9X4R@uuX(ZaSi{Nvm<#D-2gs{OCUEr1$F{fz*XMhu z-SrnF43NDM6ID!0~K^%lGT&IMIjV_O+#s*^Ju9E(nl7nBq;z5a~*t(6)n zr@yA0-C=|%99V2w-nly_JON!w=0o}(+!-YocU!eEHX(J-`P#Qd3K+NK0JBl=TjYICXk4E457zwWt6}5J>98kr#mBXw zGxl~XJR6GZi{mBp6n)x2`uIM)S%_UZ*`taR`U{yxNeChW|JIul`pEhN)fe?%SnqR5 z08kLttLy3Q73t?`<>wXkx!rb0+pv6NS>mMAX?|`pn00IfXG5^R)Yz@J#wVE6%Uf*$-Da2+ceZpqny#O zS5eKbL7JZqvQduo3AAq?>UXj0CB{+qXz6mC|TBILMJ^DL0uV(UTkYXPEg}sZNX5U0;9%IfGFH zRVPXbxqO(@UKw+B3NyG%?G0;o-aTjmZYqF=Y9v?|wLTxAWsSE58`9|~ZbWwqBm;|l=n*;*%cZN)giP*w22-p$vY5a6 zL~psQ$nxsqgh6ag>EMx#=81T6y(SXw*)-wtXzU%QeJbhB4AX5J@&@4};@)F(CwcYz zGy#@PeK*0o3ig-F4z%VF%LrjSqC&q#SfNqR>-ByG@!Du;PJ&pcArF=yhX%^i0;@ZE z@F>Akks5!s0K$NX!I6pstN;nenQelQ#`Ahk=A@^~IRCe?mtlAiCV~L|Z_?1h0|5XS zfcm1}4V?7XZy2Bs+!DV=I%N&PstYo{D6dL(kZ}U~kNwth*=+xp5b^!gY$nip6u&s$ zdYGO6nbf;1zlE^%zBd!L=KgSmpzFl8; H5di)HI$53s literal 0 HcmV?d00001 diff --git a/openecomp-bdd/resources/uploads/errorHeat.zip b/openecomp-bdd/resources/uploads/errorHeat.zip new file mode 100644 index 0000000000000000000000000000000000000000..21444fadb7d3f32bb47536180ff8aad551b6bc73 GIT binary patch literal 1304 zcmWIWW@Zs#0D;d5J>Fmjl;8x?X_-aEC3>lOWdTrS9AIT8AO79^4wN=yW?S7c3S+{`oC+dpA9ItQr9b3Hh^|#W{aOPk0)F+)aJ;rfByhtvwv^YXQVlVfd z>3ja4Z`VJK7IrUO*7WYXsEjkef3t7$dTsHRrY95j%*%fh z<|0<3`!Hjrky5~U_O}xstDoq)dWO;awCeOC{2(J3N}nT|QfG+r2fveK>9V_G7c& z9QD8OddgbGMKi7(m2#>UeCf{?yymjtrKJ!0IquB$jqh8qM2p!f!*8Kq!H;t*A58rA z>C_*aW5O*z-=@8OtfT2%5+nJ={=(lh-&M0#n_XVCO*PN=fzlW4lgqRBowHiVW0bb{ zZ__--$_eG+3ZHM~d|Mdz`0pk5FMN-WtCd9V`p1as=iFU;dbb1pdLQa%Uq?SrH`m}0 zy{zK=yr~m5avd@dXe&Qh&M~w5#?gbm3m+)#nxdmrv?ZM5$d)Hb3#aVc?R)FeHLDjT zC;u1zcMn=0-c!iy|D^hucYsmvL>>N`c}l8oVqwp2B|bEm{XvNLtInO)+lkydTP~iB zl~}#|;hK?B^n<*uJUUx0QEs z*j-Zlu`=YztH+$DlL~G9yW1b{wdPs$lwDA5r{Dj-3wcBmt_K#>1j{&Vj<9Je4q_umtNUk@3bJl&($_}<7_rF8G^mW@sS zbghl^mpLoD6?}D8HW0S>l6PgxTC>u~x2JN~a)oZ;m{zUdePt;NYlQi>&Br+OHo0C{ zr68qfeq6kHcRAzfZVx%RS$ytmzjqwsoWwWtuwGaHq{Ws=Ve=vbZ+>?Ct22@BiSB$K zhUHIh8k#!$~a7A literal 0 HcmV?d00001 diff --git a/openecomp-bdd/resources/uploads/zipWithExternalPort.zip b/openecomp-bdd/resources/uploads/zipWithExternalPort.zip new file mode 100644 index 0000000000000000000000000000000000000000..3d6b3d09b4c9db8d3667e5940a7295c2df178e7a GIT binary patch literal 1453 zcmWIWW@Zs#U}E54m{7^=dB^+A&2P*M47bD>82A|&7*Y##vx*br^HNLnDid>ajz*l# zzilS6pZ&ythbLPYFDe-NUVLewaB|zacAaBQ-;8)zbOX)AJykqTWkx-zm)GRblz~tl`AZI*0L$5y$@K{l>cR0^RME^&+5Y` zHXe`+oTX|~@=Vz?gkx3Q1-A`Ni(~rVA7=>ApVOj{6xkN&6ErK(HEBxF%2_j}o!$L= zcE5a+_iy>EvW4pGJge6T+6Zy}`nJh>nwX@c>eq#nLYkhN76*$jZ4FK zonGH*(N&Y`UcP$jx=k%9;Cuqxmrdg495Ign|K=|K`TDUgm%!N%X`f`?zpr&{gd{ONw&}MWLq&SJ71K&MD|X@meX%I)QV&)Hc#bA@HyVM-DHx;`x!Hq zCMhOcmAZJp@kL8A#ZjpZv0o>dEobi*HcxGXFf=^n5F8bt#avr;l;9;^%j4= zJ^D~T+w!pFsZJ-8d0Mv=*sk1ZuzHf;c{;tgu2e70VU_HoE>{z=;ufDj9UZcHZ|w!A zZ(e?dkI>+Sdae>XV&K6zdmfK(`a9brg(c0&A%R#k>u>YP*_q-=!+(PHKCl$KOUP+8i{B*N!wtlQ~ zf0ub<`=^3H=>wX&4D6@)#g|F>d7H}kn8wV>vM{|`U~*M`o9&#N-wJlTo&M&h@V4Lo z=I*m|KPy;l=-!u}=kYh^b4|#Ky(wJB_=}x?zLb%i=6^c!8+$;V)$vTfQ{TCKpUzEM zS}I{PGh@1XFyC)wm6?@G?PfCkJXpjxGg)uD&tGks0?Xse|2{o7%P=(7RA%Aj(3-SI znYYgGa=-b9Qz=qWDM|lfPowSRr{(Bk)~KWKUeyW6eO9-)>bC&t>%Gdg%$x@hW1B`=3=4vR%)%?`_BHo3;_R zrTh5S)VxVr#dJ#Gjr~~#2Dt}5D`qWU7xGo;UqNyH3ZFfb|7qRyeOad*@$%9}mzT92 zcQ)EA3=RGgvSQDF9>a}|EJmomP(XaE(>b_X@gRkuaz(oWDu!vX~#O!I;dB}JzuxNM!#JoW4>*(j{ z<{BKLmsOmfXX@wA-DDuLpS!O8xF4(EwKW>~PEI8nD_;mHE*8^U#%IndxWC%!^_S}R z-{0>&SIQ7@u&B?;!FSG*cJC>2J00hR#>LocFYM9izF6>hs+`*bJ4PqNn@L_`*)v?X zo;>B%K4C+Y( + 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 index 0000000000..b41b5ea5e2 --- /dev/null +++ b/openecomp-bdd/resources/yaml/Nested_FSB1ServiceTemplate.yaml @@ -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 index 0000000000..5b5062cf34 --- /dev/null +++ b/openecomp-bdd/stepDefinitions/Collaboration_Steps.js @@ -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 index 0000000000..389112da84 --- /dev/null +++ b/openecomp-bdd/stepDefinitions/General_Steps.js @@ -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::
    + * """
    + * {jsonObject}
    + * """
    + * @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 index 0000000000..73695d0e7f --- /dev/null +++ b/openecomp-bdd/stepDefinitions/InputData_steps.js @@ -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:
    + * """
    + * {jsonObject}
    + * """
    + * @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 index 0000000000..165df6ca30 --- /dev/null +++ b/openecomp-bdd/stepDefinitions/Item_steps.js @@ -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 index 0000000000..731d5b8470 --- /dev/null +++ b/openecomp-bdd/stepDefinitions/NetworkPackage_steps.js @@ -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 index 0000000000..ce35a1c9ce --- /dev/null +++ b/openecomp-bdd/stepDefinitions/Questionnaire_steps.js @@ -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 index 0000000000..314f86825b --- /dev/null +++ b/openecomp-bdd/stepDefinitions/REST_Steps.js @@ -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)
    + * @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)
    + * @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)
    + * @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)
    + * @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 index 0000000000..e818e72b1b --- /dev/null +++ b/openecomp-bdd/stepDefinitions/Utils.js @@ -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 index 0000000000..d00cf9ca6a --- /dev/null +++ b/openecomp-bdd/stepDefinitions/VF_steps.js @@ -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 index 0000000000..6e0dd318cf --- /dev/null +++ b/openecomp-bdd/stepDefinitions/VLM_steps.js @@ -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
    + * 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 index 0000000000..b957e6f723 --- /dev/null +++ b/openecomp-bdd/stepDefinitions/VSP_steps.js @@ -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
    + * 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
    + * 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 index 0000000000..e87a9b588f --- /dev/null +++ b/openecomp-bdd/stepDefinitions/world.js @@ -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.
    + *
    + * Contains the following items:
    + *
  • this.context.server
      REST server and onboarding prefix including version. set either in configuration file or from the command line or SERVER environment variable
    + *
  • this.context.vlm
      When a VLM has been created, this has the an id and versionId set to the correct IDs.
    + *
  • this.context.vsp
      When a VSP has been created, this has the an id and versionId and componentId set to the correct IDs.
    + *
  • this.context.item
      When a VLM or VSP has been created, this has the an id and versionId set to the correct IDs.
    + *
  • this.context
      Object with properties that were saved in the steps.
    + *
  • this.context.inputdata
      Automatically updated with the last responseData from the Rest call
      Object with properties that were prepares in the steps.
    + *
  • this.context.responseData
      Response from the last REST call.
    + **/ +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 index 0000000000..6324af4df8 --- /dev/null +++ b/openecomp-bdd/yarn.lock @@ -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" -- 2.16.6