aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLianhao Lu <lianhao.lu@intel.com>2018-08-29 18:17:46 +0800
committerLianhao Lu <lianhao.lu@intel.com>2018-08-29 18:37:48 +0800
commit0af4624891b9de8bd455acd584ea3fa4a87304b8 (patch)
tree736e0379095b69fa0ddaf187a9aabb0d6e23e64d
parent7db9cd91cd0b25000fca4c3ffb5c59cc413ad3f6 (diff)
framework for checking vnf requirement
Implemented the internal code framework to add test cases to check vnf requirements. Use command line parameter '--test-reqs' with the list of vnf requirment IDs to invoke 'vnfsdk csar-validate'. Also implement test case for R-66070: csar manifest metadata Change-Id: I385e515f3e87f1e89fb7baf9ec3e0560f44541cd Issue-ID: VNFSDK-316 Issue-ID: VNFSDK-174 Signed-off-by: Lianhao Lu <lianhao.lu@intel.com>
-rw-r--r--requirements.txt1
-rw-r--r--setup.py5
-rw-r--r--tests/vnfreq/test_pkg_reqs.py27
-rw-r--r--tests/vnfreq/test_vnfreq.py34
-rw-r--r--vnfsdk_pkgtools/cli/__main__.py24
-rw-r--r--vnfsdk_pkgtools/validator/__init__.py4
-rw-r--r--vnfsdk_pkgtools/vnfreq/__init__.py90
-rw-r--r--vnfsdk_pkgtools/vnfreq/pkg_reqs.py37
8 files changed, 216 insertions, 6 deletions
diff --git a/requirements.txt b/requirements.txt
index dbc2a26..fa17a3e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,4 @@ requests>=2.3.0
stevedore>=1.9.0
udatetime<1.0,>=0.0.16
nfv-toscaparser<2.0,>=1.0.1
+prettytable<1.0
diff --git a/setup.py b/setup.py
index 21cad65..cba146a 100644
--- a/setup.py
+++ b/setup.py
@@ -85,7 +85,10 @@ setup(
'vnfsdk = vnfsdk_pkgtools.cli.__main__:main'],
'vnfsdk.pkgtools.validator': [
'toscaparser = vnfsdk_pkgtools.validator.toscaparser_validator:ToscaparserValidator',
- ]
+ ],
+ 'vnfsdk.pkgtools.vnfreq': [
+ 'R-66070 = vnfsdk_pkgtools.vnfreq.pkg_reqs:R66070',
+ ],
},
include_package_data=True,
diff --git a/tests/vnfreq/test_pkg_reqs.py b/tests/vnfreq/test_pkg_reqs.py
new file mode 100644
index 0000000..b712212
--- /dev/null
+++ b/tests/vnfreq/test_pkg_reqs.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2018 Intel Corp. All rights reserved.
+#
+# 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.
+#
+
+import pytest
+
+from vnfsdk_pkgtools import vnfreq
+
+def test_R66070_fail(mocker):
+ reader = mocker.Mock()
+ reader.manifest = None
+
+ tester = vnfreq.get_vnfreq_tester("R-66070")
+ tester.check(reader, None)
+ assert isinstance(tester.err, vnfreq.VnfRequirementError)
+
diff --git a/tests/vnfreq/test_vnfreq.py b/tests/vnfreq/test_vnfreq.py
new file mode 100644
index 0000000..03404fc
--- /dev/null
+++ b/tests/vnfreq/test_vnfreq.py
@@ -0,0 +1,34 @@
+# Copyright (c) 2018 Intel Corp. All rights reserved.
+#
+# 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.
+#
+
+import pytest
+
+from vnfsdk_pkgtools import vnfreq
+
+class FakeTester(vnfreq.TesterBase):
+ ID = 'fake'
+ DESC = 'fake'
+
+ def __init__(self, *args, **kwargs):
+ super(FakeTester, self).__init__()
+
+ def _do_check(self, reader, tosca):
+ return 'error'
+
+
+def test_check_and_print(mocker):
+ mocker.patch('vnfsdk_pkgtools.vnfreq.get_vnfreq_tester', new=FakeTester)
+ ret = vnfreq.check_and_print(['fake'], mocker.Mock(), mocker.Mock())
+ assert ret == 1
diff --git a/vnfsdk_pkgtools/cli/__main__.py b/vnfsdk_pkgtools/cli/__main__.py
index 2b262b9..09896e0 100644
--- a/vnfsdk_pkgtools/cli/__main__.py
+++ b/vnfsdk_pkgtools/cli/__main__.py
@@ -14,7 +14,6 @@
# under the License.
#
-from vnfsdk_pkgtools.packager import csar
import sys
import logging
import argparse
@@ -22,7 +21,12 @@ import os
import shutil
import tempfile
+import pkg_resources
+
+from vnfsdk_pkgtools.packager import csar
from vnfsdk_pkgtools import validator
+from vnfsdk_pkgtools import vnfreq
+
def csar_create_func(namespace):
@@ -39,13 +43,20 @@ def csar_open_func(namespace):
def csar_validate_func(namespace):
workdir = tempfile.mkdtemp()
try:
- reader = None
+ err = 0
reader = csar.read(namespace.source,
workdir,
no_verify_cert=True)
driver = validator.get_validator(namespace.parser)
driver.validate(reader)
+ print("---Basic & HPA validation passed!---")
+ if namespace.test_reqs:
+ print("---Check VNF Requirements---")
+ err = vnfreq.check_and_print(namespace.test_reqs,
+ reader,
+ driver)
+ return err
finally:
shutil.rmtree(workdir, ignore_errors=True)
@@ -121,7 +132,14 @@ def parse_args(args_list):
csar_validate.add_argument(
'-p', '--parser',
default='toscaparser',
+ choices=[ep.name for ep in pkg_resources.iter_entry_points(validator.NS)],
help='use which csar parser to validate')
+ csar_validate.add_argument(
+ '--test-reqs',
+ nargs='*',
+ default=[],
+ choices=[ep.name for ep in pkg_resources.iter_entry_points(vnfreq.NS)],
+ help='list of the ID of VNF Requirements to check, i.e. R-66070')
return parser.parse_args(args_list)
@@ -141,7 +159,7 @@ def init_logging(args):
def main():
args = parse_args(sys.argv[1:])
init_logging(args)
- args.func(args)
+ return args.func(args)
if __name__ == '__main__':
diff --git a/vnfsdk_pkgtools/validator/__init__.py b/vnfsdk_pkgtools/validator/__init__.py
index 730acf6..c072543 100644
--- a/vnfsdk_pkgtools/validator/__init__.py
+++ b/vnfsdk_pkgtools/validator/__init__.py
@@ -19,7 +19,7 @@ import six
from stevedore import driver
-VALIDATOR_NS = "vnfsdk.pkgtools.validator"
+NS = "vnfsdk.pkgtools.validator"
def get_validator(params):
"""Get validate driver and load it.
@@ -27,7 +27,7 @@ def get_validator(params):
:param params: parameters to decide which validator to load
"""
- loaded_driver = driver.DriverManager(VALIDATOR_NS,
+ loaded_driver = driver.DriverManager(NS,
params,
invoke_on_load=True)
return loaded_driver.driver
diff --git a/vnfsdk_pkgtools/vnfreq/__init__.py b/vnfsdk_pkgtools/vnfreq/__init__.py
new file mode 100644
index 0000000..376b519
--- /dev/null
+++ b/vnfsdk_pkgtools/vnfreq/__init__.py
@@ -0,0 +1,90 @@
+# Copyright (c) 2018 Intel Corp. All rights reserved.
+#
+# 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.
+#
+
+import abc
+import textwrap
+
+import prettytable
+import six
+from stevedore import driver
+
+
+NS = "vnfsdk.pkgtools.vnfreq"
+
+def get_vnfreq_tester(name):
+ """Get vnf requirement tester.
+
+ :param name: name of the vnf requirement tester
+ """
+
+ loaded_driver = driver.DriverManager(NS,
+ name,
+ invoke_on_load=True)
+ return loaded_driver.driver
+
+
+def check_and_print(test_reqs, reader, tosca):
+ err = 0
+
+ table = prettytable.PrettyTable(['Req ID', 'Status', 'Description'])
+ table.align = 'l'
+ for t in test_reqs:
+ testor = get_vnfreq_tester(t)
+ testor.check(reader, tosca)
+ if testor.err:
+ status = 'ERROR: ' + str(testor.err)
+ err = 1
+ else:
+ status = 'OK'
+ # wrap the testor description because it's too long
+ lines = textwrap.wrap(testor.DESC, width=40)
+ table.add_row([testor.ID, status, lines.pop(0)])
+ for line in lines:
+ table.add_row(['','',line])
+ if test_reqs:
+ print(table)
+ return err
+
+
+class VnfRequirementError(ValueError):
+ pass
+
+
+@six.add_metaclass(abc.ABCMeta)
+class TesterBase(object):
+ """Base class for vnf requirement tester."""
+
+ ID = None
+ DESC = None
+
+ def __init__(self):
+ self.err = None
+
+ @abc.abstractmethod
+ def _do_check(self, reader, tosca):
+ """Check the vnf requirement meet or not.
+
+ :param reader: instance of package.csar._CSARReader
+ :param tosca: instance of validator.toscaparser_validator.ToscaparserValidator
+
+ return: 0 for success, otherwise failure
+ """
+
+ def check(self, reader, tosca):
+ try:
+ self.err = self._do_check(reader, tosca)
+ except Exception as e:
+ self.err = e
+
diff --git a/vnfsdk_pkgtools/vnfreq/pkg_reqs.py b/vnfsdk_pkgtools/vnfreq/pkg_reqs.py
new file mode 100644
index 0000000..c5b20f7
--- /dev/null
+++ b/vnfsdk_pkgtools/vnfreq/pkg_reqs.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2018 Intel Corp. All rights reserved.
+#
+# 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.
+#
+
+import abc
+
+import six
+from stevedore import driver
+
+from vnfsdk_pkgtools import vnfreq
+
+
+class R66070(vnfreq.TesterBase):
+ ID = "R-66070"
+ DESC = ("The VNF Package MUST include VNF Identification Data to "
+ "uniquely identify the resource for a given VNF provider. "
+ "The identification data must include: an identifier for "
+ "the VNF, the name of the VNF as was given by the VNF "
+ "provider, VNF description, VNF provider, and version.")
+
+ def _do_check(self, reader, tosca):
+ if not reader.manifest:
+ raise vnfreq.VnfRequirementError("No manifest file found")
+ # Existing reader.manifest already means a valid manifest file
+ # no futher check needed.
+ return 0