diff options
author | Zhaoxing Meng <meng.zhaoxing1@zte.com.cn> | 2017-09-22 07:52:14 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2017-09-22 07:52:14 +0000 |
commit | 66eb1510d4ea58713f947255ebdecbd3caedcd88 (patch) | |
tree | 9c200a8a26eadb92ebc9710efb9578e915f26cc0 /nfvparser/toscaparser/tests | |
parent | dde1bd595397c2e06ec897fde81cd4f8be710c5b (diff) | |
parent | 6a3e9d53686eda1d45fb54b97869a594741f089c (diff) |
Merge "Move python files to root dir"
Diffstat (limited to 'nfvparser/toscaparser/tests')
228 files changed, 12429 insertions, 0 deletions
diff --git a/nfvparser/toscaparser/tests/__init__.py b/nfvparser/toscaparser/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/nfvparser/toscaparser/tests/__init__.py diff --git a/nfvparser/toscaparser/tests/artifacts/collectd/config.py b/nfvparser/toscaparser/tests/artifacts/collectd/config.py new file mode 100644 index 0000000..686bbd1 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/collectd/config.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +# 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. + +# This script configures collectd to send metric data to the +# logstash server port 25826 +# The environment variable logstash_ip is expected to be set up +import os +with open("/etc/collectd/collectd.conf.d/tosca_elk.conf", "w") as fh: + fh.write(""" + LoadPlugin network + <Plugin network> + Server "%s" "25826" + </Plugin> + """ % (os.environ['logstash_ip'])) diff --git a/nfvparser/toscaparser/tests/artifacts/collectd/create.sh b/nfvparser/toscaparser/tests/artifacts/collectd/create.sh new file mode 100644 index 0000000..a483b88 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/collectd/create.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# This script install collectd for monitoring data + +apt-get update +apt-get install -y collectd diff --git a/nfvparser/toscaparser/tests/artifacts/collectd/start.sh b/nfvparser/toscaparser/tests/artifacts/collectd/start.sh new file mode 100644 index 0000000..7e8e033 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/collectd/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts collectd as a service in init.d +service collectd stop +service collectd start diff --git a/nfvparser/toscaparser/tests/artifacts/elasticsearch/create.sh b/nfvparser/toscaparser/tests/artifacts/elasticsearch/create.sh new file mode 100644 index 0000000..c34126c --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/elasticsearch/create.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# This script installs java and elasticsearch + +apt-get update +apt-get install -y openjdk-7-jre-headless + +wget -qO - https://packages.elasticsearch.org/GPG-KEY-elasticsearch | apt-key add - +echo "deb http://packages.elasticsearch.org/elasticsearch/1.5/debian stable main" | tee -a /etc/apt/sources.list + +apt-get update +apt-get install -y elasticsearch + +# set up to run as service +update-rc.d elasticsearch defaults 95 10 diff --git a/nfvparser/toscaparser/tests/artifacts/elasticsearch/start.sh b/nfvparser/toscaparser/tests/artifacts/elasticsearch/start.sh new file mode 100644 index 0000000..bbc0347 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/elasticsearch/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts elasticsearch as a service in init.d +service elasticsearch stop +service elasticsearch start diff --git a/nfvparser/toscaparser/tests/artifacts/kibana/config.sh b/nfvparser/toscaparser/tests/artifacts/kibana/config.sh new file mode 100644 index 0000000..f28215a --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/kibana/config.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# This script configures kibana to connect to the elasticsearch server +# to access data and to export the app url on port 5601: +# The environment variable elasticsearch_ip and kibana_ip are expected +# to be set up. +sed -i 's/localhost/'$elasticsearch_ip'/' /opt/kibana/config/kibana.yml +sed -i 's/0.0.0.0/'$kibana_ip'/' /opt/kibana/config/kibana.yml diff --git a/nfvparser/toscaparser/tests/artifacts/kibana/create.sh b/nfvparser/toscaparser/tests/artifacts/kibana/create.sh new file mode 100644 index 0000000..41914b1 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/kibana/create.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# This script installs kibana and sets it up to run as a service in init.d +cd /opt +wget https://download.elastic.co/kibana/kibana/kibana-4.1.0-linux-x64.tar.gz +tar xzvf kibana-4.1.0-linux-x64.tar.gz +mv kibana-4.1.0-linux-x64 kibana + +# set up to run as service +cd /etc/init.d +wget https://gist.githubusercontent.com/thisismitch/8b15ac909aed214ad04a/raw/bce61d85643c2dcdfbc2728c55a41dab444dca20/kibana4 +chmod +x kibana4 +update-rc.d kibana4 defaults 96 9 diff --git a/nfvparser/toscaparser/tests/artifacts/kibana/start.sh b/nfvparser/toscaparser/tests/artifacts/kibana/start.sh new file mode 100644 index 0000000..5149bb3 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/kibana/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts kibana as a service in init.d +service kibana4 stop +service kibana4 start diff --git a/nfvparser/toscaparser/tests/artifacts/logstash/configure_collectd.py b/nfvparser/toscaparser/tests/artifacts/logstash/configure_collectd.py new file mode 100644 index 0000000..18fdacf --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/logstash/configure_collectd.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# 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. + +# This script configures the logstash input using the udp protocol on +# port 25826. This is intended to receive data from collectd from +# any source +with open("/etc/logstash/conf.d/collectd.conf", "w") as fh: + fh.write(""" + input { + udp { + port => 25826 # 25826 is the default for collectd + buffer_size => 1452 # 1452 is the default for collectd + codec => collectd { } + tags => ["metrics"] + type => "collectd" + } + }""") diff --git a/nfvparser/toscaparser/tests/artifacts/logstash/configure_elasticsearch.py b/nfvparser/toscaparser/tests/artifacts/logstash/configure_elasticsearch.py new file mode 100644 index 0000000..2e5389c --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/logstash/configure_elasticsearch.py @@ -0,0 +1,26 @@ +#!/usr/bin/python + +# 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. + +# This script configures the logstash output to forward to elasticsearch +# The environment variable elasticsearch_ip is expected to be set up +import os +with open("/etc/logstash/conf.d/elasticsearch.conf", 'w') as fh: + fh.write(""" + output { + elasticsearch { + action => index + host => "%s" + protocol => "http" + } + }""" % (os.environ['elasticsearch_ip'])) diff --git a/nfvparser/toscaparser/tests/artifacts/logstash/configure_rsyslog.py b/nfvparser/toscaparser/tests/artifacts/logstash/configure_rsyslog.py new file mode 100644 index 0000000..fc610c2 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/logstash/configure_rsyslog.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +# 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. + +# This script configures the logstash input using the RELP protocol on +# port 2514 This is intended to receive logs from rsyslog from +# any source +with open("/etc/logstash/conf.d/rsyslog.conf", "w") as fh: + fh.write(""" + input { + relp { + port => 2514 + tags => ["logs"] + } + }""") diff --git a/nfvparser/toscaparser/tests/artifacts/logstash/create.sh b/nfvparser/toscaparser/tests/artifacts/logstash/create.sh new file mode 100644 index 0000000..77cc8fd --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/logstash/create.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# This script installs java, logstash and the contrib package for logstash +# install java as prereq + +apt-get update +apt-get install -y openjdk-7-jre-headless +mkdir /etc/logstash + +# install by apt-get from repo +wget -O - http://packages.elasticsearch.org/GPG-KEY-elasticsearch | apt-key add - +echo "deb http://packages.elasticsearch.org/logstash/1.4/debian stable main" | tee -a /etc/apt/sources.list + +apt-get update +apt-get install -y logstash + +# install contrib to get the relp plugin +/opt/logstash/bin/plugin install contrib + +# set up to run as service +update-rc.d logstash defaults 95 10 diff --git a/nfvparser/toscaparser/tests/artifacts/logstash/start.sh b/nfvparser/toscaparser/tests/artifacts/logstash/start.sh new file mode 100644 index 0000000..a73cf61 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/logstash/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# Run logstash as service in init.d +service logstash stop +service logstash start diff --git a/nfvparser/toscaparser/tests/artifacts/mongodb/config.sh b/nfvparser/toscaparser/tests/artifacts/mongodb/config.sh new file mode 100644 index 0000000..78f484e --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mongodb/config.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Edit the file /etc/mongod.conf, update with real IP of Mongo server +# This script configures the mongodb server to export its service on +# the server IP +# bind_ip = 127.0.0.1 -> bind_ip = <IP for Mongo server> +# The environment variable mongodb_ip is expected to be set up +sed -i "s/= 127.0.0.1/= $mongodb_ip,127.0.0.1/" /etc/mongod.conf diff --git a/nfvparser/toscaparser/tests/artifacts/mongodb/create.sh b/nfvparser/toscaparser/tests/artifacts/mongodb/create.sh new file mode 100644 index 0000000..d84c275 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mongodb/create.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# This script installs mongodb + +apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 +echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.0.list + +apt-get update +apt-get install -y mongodb-org + +#Wait for mongodb initialization +while [[ ! -d "/var/lib/mongodb/_tmp" ]]; do + echo "Waiting for mongodb initialization ..." + sleep 5 +done diff --git a/nfvparser/toscaparser/tests/artifacts/mongodb/create_database.sh b/nfvparser/toscaparser/tests/artifacts/mongodb/create_database.sh new file mode 100644 index 0000000..16f1358 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mongodb/create_database.sh @@ -0,0 +1,5 @@ +#!/bin/bash +echo "conn = new Mongo();" > setup.js +echo "db = conn.getDB('paypal_pizza');" >> setup.js +echo "db.about.insert({'name': 'PayPal Pizza Store'});" >> setup.js +mongo setup.js diff --git a/nfvparser/toscaparser/tests/artifacts/mongodb/start.sh b/nfvparser/toscaparser/tests/artifacts/mongodb/start.sh new file mode 100644 index 0000000..ac200a5 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mongodb/start.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# This script starts mongodb +service mongod stop +rm /var/lib/mongodb/mongod.lock +service mongod start diff --git a/nfvparser/toscaparser/tests/artifacts/mysql/mysql_database_configure.sh b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_database_configure.sh new file mode 100644 index 0000000..092136a --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_database_configure.sh @@ -0,0 +1,8 @@ +#!/bin/sh +cat << EOF | mysql -u root --password=$db_root_password +CREATE DATABASE $db_name; +GRANT ALL PRIVILEGES ON $db_name.* TO "$db_user"@"localhost" +IDENTIFIED BY "$db_password"; +FLUSH PRIVILEGES; +EXIT +EOF
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_configure.sh b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_configure.sh new file mode 100644 index 0000000..d4ef6b4 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_configure.sh @@ -0,0 +1,5 @@ +#!/bin/sh +sed --regexp-extended "s/(port\s*=\s*)[0-9]*/\1$db_port/g" </etc/mysql/my.cnf >/tmp/my.cnf +mv -f /tmp/my.cnf /etc/mysql/my.cnf +/etc/init.d/mysql stop +/etc/init.d/mysql start
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_install.sh b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_install.sh new file mode 100644 index 0000000..38628b9 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_install.sh @@ -0,0 +1,9 @@ +#!/bin/bash +#This script installs mysql server + +apt-get update + +debconf-set-selections <<< "mysql-server mysql-server/root_password password $db_root_password" +debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $db_root_password" + +apt-get -y install --fix-missing mysql-server
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_start.sh b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_start.sh new file mode 100644 index 0000000..3378670 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/mysql/mysql_dbms_start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +/etc/init.d/mysql start
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/artifacts/nodejs/config.sh b/nfvparser/toscaparser/tests/artifacts/nodejs/config.sh new file mode 100644 index 0000000..1e149a2 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/nodejs/config.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# This script installs an app for nodejs: the app intended is the paypal app +# and it is configured to connect to the mongodb server +# The environment variables github_url and mongodb_ip are expected to be set up +export app_dir=/opt/app +git clone $github_url /opt/app +if [ -f /opt/app/package.json ]; then + cd /opt/app/ && npm install + sed -i "s/localhost/$mongodb_ip/" config.json +fi + +cat > /etc/init/nodeapp.conf <<EOS +description "node.js app" + +start on (net-device-up + and local-filesystems + and runlevel [2345]) +stop on runlevel [!2345] + +expect fork +respawn + +script + export HOME=/ + export NODE_PATH=/usr/lib/node + exec /usr/bin/node ${app_dir}/app.js >> /var/log/nodeapp.log 2>&1 & +end script +EOS diff --git a/nfvparser/toscaparser/tests/artifacts/nodejs/create.sh b/nfvparser/toscaparser/tests/artifacts/nodejs/create.sh new file mode 100644 index 0000000..04fd6c6 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/nodejs/create.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# This script installs nodejs and the prereq + +add-apt-repository ppa:chris-lea/node.js + +apt-get update +apt-get install -y nodejs build-essential diff --git a/nfvparser/toscaparser/tests/artifacts/nodejs/start.sh b/nfvparser/toscaparser/tests/artifacts/nodejs/start.sh new file mode 100644 index 0000000..6939cb7 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/nodejs/start.sh @@ -0,0 +1,3 @@ +#!/bin/bash +# This script starts the nodejs application +start nodeapp diff --git a/nfvparser/toscaparser/tests/artifacts/rsyslog/config.sh b/nfvparser/toscaparser/tests/artifacts/rsyslog/config.sh new file mode 100644 index 0000000..630767d --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/rsyslog/config.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# This script configures the output for rsyslogd to send logs to the +# logstash server port 2514 using the RELP protocol +# The environment variable logstash_ip is expected to be set up +echo "module(load=\"omrelp\") +action(type=\"omrelp\" target=\"$logstash_ip\" port=\"2514\")" > /etc/rsyslog.d/tosca_elk.conf + +# Remove the /dev/xconsole configuration as xconsole +# is not available by default +l=`awk '/=warn.*\|.*\/dev\/xconsole/{print NR - 1}' /etc/rsyslog.d/50-default.conf` +if [ ! -z $l ]; then + l=`expr $l + 1` + line=`cat /etc/rsyslog.d/50-default.conf | head -n $l | tail -1` + if [[ ! $line == \#* ]]; then + l0=`expr $l - 3` + sed -i -r -e "${l0},${l}s/^.{0}/&#/" /etc/rsyslog.d/50-default.conf + fi +fi + +# Enable nodejs logs for rsyslog +if ! grep -q nodeapp "/etc/rsyslog.conf"; then + sed -i 's/\$PrivDropToGroup\ syslog/\$PrivDropToGroup adm/' /etc/rsyslog.conf + echo "\$ModLoad imfile.so +\$InputFileName /var/log/nodeapp.log +\$InputFileTag paypal_pizza: +\$InputFileStateFile stat-nodeapp +\$InputRunFileMonitor +\$InputFilePollInterval 1" >> /etc/rsyslog.conf +fi diff --git a/nfvparser/toscaparser/tests/artifacts/rsyslog/create.sh b/nfvparser/toscaparser/tests/artifacts/rsyslog/create.sh new file mode 100644 index 0000000..affdd6e --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/rsyslog/create.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# This script installs rsyslog and the library for RELP + +apt-get update +apt-get install -y rsyslog rsyslog-relp diff --git a/nfvparser/toscaparser/tests/artifacts/rsyslog/start.sh b/nfvparser/toscaparser/tests/artifacts/rsyslog/start.sh new file mode 100644 index 0000000..3de82d1 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/rsyslog/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts rsyslogd as a service in init.d +service rsyslog stop +service rsyslog start diff --git a/nfvparser/toscaparser/tests/artifacts/webserver/webserver_install.sh b/nfvparser/toscaparser/tests/artifacts/webserver/webserver_install.sh new file mode 100644 index 0000000..4ca9b4e --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/webserver/webserver_install.sh @@ -0,0 +1,5 @@ +#!/bin/sh +#This script installs apache web server + +apt-get update +apt-get install -y apache2
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/artifacts/webserver/webserver_start.sh b/nfvparser/toscaparser/tests/artifacts/webserver/webserver_start.sh new file mode 100644 index 0000000..e962ca5 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/webserver/webserver_start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +service apache2 start
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/artifacts/wordpress/wordpress_configure.sh b/nfvparser/toscaparser/tests/artifacts/wordpress/wordpress_configure.sh new file mode 100644 index 0000000..5598b4f --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/wordpress/wordpress_configure.sh @@ -0,0 +1,4 @@ +#!/bin/sh +ln -s /usr/share/wordpress /var/www/html/wordpress +gzip -d /usr/share/doc/wordpress/examples/setup-mysql.gz +echo $wp_db_password | bash /usr/share/doc/wordpress/examples/setup-mysql -e $wp_db_name -u $wp_db_user localhost
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/artifacts/wordpress/wordpress_install.sh b/nfvparser/toscaparser/tests/artifacts/wordpress/wordpress_install.sh new file mode 100644 index 0000000..1320443 --- /dev/null +++ b/nfvparser/toscaparser/tests/artifacts/wordpress/wordpress_install.sh @@ -0,0 +1,5 @@ +#!/bin/sh +#This script installs wordpress + +apt-get update +apt-get install -y wordpress
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/base.py b/nfvparser/toscaparser/tests/base.py new file mode 100644 index 0000000..2619889 --- /dev/null +++ b/nfvparser/toscaparser/tests/base.py @@ -0,0 +1,65 @@ +# Copyright 2010-2011 OpenStack Foundation +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. +# +# 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 os + +import fixtures +import testscenarios +import testtools + +from toscaparser.tosca_template import ToscaTemplate + +_TRUE_VALUES = ('True', 'true', '1', 'yes') + + +class TestCase(testscenarios.TestWithScenarios, testtools.TestCase): + + """Test case base class for all unit tests.""" + + def setUp(self): + """Run before each test method to initialize test environment.""" + + super(TestCase, self).setUp() + test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) + try: + test_timeout = int(test_timeout) + except ValueError: + # If timeout value is invalid do not set a timeout. + test_timeout = 0 + if test_timeout > 0: + self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) + + self.useFixture(fixtures.NestedTempfile()) + self.useFixture(fixtures.TempHomeDir()) + + if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES: + stdout = self.useFixture(fixtures.StringStream('stdout')).stream + self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) + if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES: + stderr = self.useFixture(fixtures.StringStream('stderr')).stream + self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) + + self.log_fixture = self.useFixture(fixtures.FakeLogger()) + + def _load_template(self, filename): + """Load a Tosca template from tests data folder. + + :param filename: Tosca template file name to load. + :return: ToscaTemplate + """ + return ToscaTemplate(os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'data', + filename)) diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_elk.csar b/nfvparser/toscaparser/tests/data/CSAR/csar_elk.csar Binary files differnew file mode 100644 index 0000000..a514dc6 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_elk.csar diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_elk.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_elk.zip Binary files differnew file mode 100644 index 0000000..0d860d4 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_elk.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_hello_world.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_hello_world.zip Binary files differnew file mode 100644 index 0000000..43ffbbc --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_hello_world.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_invalid_entry_def.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_invalid_entry_def.zip Binary files differnew file mode 100644 index 0000000..382f790 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_invalid_entry_def.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_metadata_not_yaml.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_metadata_not_yaml.zip Binary files differnew file mode 100644 index 0000000..3e6120b --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_metadata_not_yaml.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_missing_metadata.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_missing_metadata.zip Binary files differnew file mode 100644 index 0000000..5ec7a99 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_missing_metadata.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_no_metadata_file.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_no_metadata_file.zip Binary files differnew file mode 100644 index 0000000..b0df9b9 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_no_metadata_file.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_not_zip.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_not_zip.zip new file mode 100644 index 0000000..43b7f5f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_not_zip.zip @@ -0,0 +1 @@ +This is an invalid CSAR file.
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress.zip Binary files differnew file mode 100644 index 0000000..5df7b48 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip Binary files differnew file mode 100644 index 0000000..9dc6c9a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_path.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_url.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_url.zip Binary files differnew file mode 100644 index 0000000..c7a260f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_import_url.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_path.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_path.zip Binary files differnew file mode 100644 index 0000000..5e4f9e0 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_path.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_url.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_url.zip Binary files differnew file mode 100644 index 0000000..b4133b6 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_invalid_script_url.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_with_url_import_and_script.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_with_url_import_and_script.zip Binary files differnew file mode 100644 index 0000000..5dedfcd --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_wordpress_with_url_import_and_script.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/csar_wrong_metadata_file.zip b/nfvparser/toscaparser/tests/data/CSAR/csar_wrong_metadata_file.zip Binary files differnew file mode 100644 index 0000000..85d660a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/csar_wrong_metadata_file.zip diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/collectd.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/collectd.yaml new file mode 100644 index 0000000..1ac0935 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/collectd.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + collectd is a daemon which gathers statistics about the system it is running on. + +node_types: + tosca.nodes.SoftwareComponent.Collectd: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - log_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Logstash + relationship: tosca.relationships.ConnectsTo
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/elasticsearch.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/elasticsearch.yaml new file mode 100644 index 0000000..4a1770f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/elasticsearch.yaml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Elasticsearch is an open-source search engine built on top of Apache Lucene, a full-text search-engine library. + +node_types: + tosca.nodes.SoftwareComponent.Elasticsearch: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + search_endpoint: + type: tosca.capabilities.Endpoint diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/kibana.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/kibana.yaml new file mode 100644 index 0000000..3a4351c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/kibana.yaml @@ -0,0 +1,16 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Kibana is an open source analytics and visualization platform designed to work with Elasticsearch. + You use Kibana to search, view, and interact with data stored in Elasticsearch. + +node_types: + tosca.nodes.SoftwareComponent.Kibana: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - search_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Elasticsearch + relationship: tosca.relationships.ConnectsTo + + diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/logstash.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/logstash.yaml new file mode 100644 index 0000000..8495954 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/logstash.yaml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Logstash is a tool for receiving, processing and outputting logs. All kinds of logs. System logs, webserver logs, + error logs, application logs, and just about anything you can throw at it. + +node_types: + tosca.nodes.SoftwareComponent.Logstash: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - search_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Elasticsearch + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_source: + inputs: + elasticsearch_ip: + type: string + capabilities: + log_endpoint: + type: tosca.capabilities.Endpoint + diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/paypalpizzastore_nodejs_app.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/paypalpizzastore_nodejs_app.yaml new file mode 100644 index 0000000..cdabeae --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/paypalpizzastore_nodejs_app.yaml @@ -0,0 +1,29 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Pizza store app that allows you to explore the features provided by PayPal's REST APIs. + More detail can be found at https://github.com/paypal/rest-api-sample-app-nodejs/ + +node_types: + tosca.nodes.WebApplication.PayPalPizzaStore: + derived_from: tosca.nodes.WebApplication + properties: + github_url: + required: false + type: string + description: location of the application on the github. + default: https://github.com/sample.git + requirements: + #WebApplication inherits Computer, so host implied. + - database_connection: + capability: tosca.capabilities.Endpoint.Database + node: tosca.nodes.Database + relationship: tosca.relationships.ConnectsTo + interfaces: + Standard: + configure: + inputs: + github_url: + type: string + mongodb_ip: + type: string diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/rsyslog.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/rsyslog.yaml new file mode 100644 index 0000000..4614ee7 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/rsyslog.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + RSYSLOG is the Rocket-fast SYStem for LOG processing. + +node_types: + tosca.nodes.SoftwareComponent.Rsyslog: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - log_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Logstash + relationship: tosca.relationships.ConnectsTo diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/tosca_elk.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/tosca_elk.yaml new file mode 100644 index 0000000..932f131 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Definitions/tosca_elk.yaml @@ -0,0 +1,217 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + This TOSCA simple profile deploys nodejs, mongodb, elasticsearch, logstash and kibana each on a separate server + with monitoring enabled for nodejs server where a sample nodejs application is running. The rsyslog and collectd are + installed on a nodejs server. + +imports: + - paypalpizzastore_nodejs_app.yaml + - elasticsearch.yaml + - logstash.yaml + - kibana.yaml + - collectd.yaml + - rsyslog.yaml + +dsl_definitions: + host_capabilities: &host_capabilities + # container properties (flavor) + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os_capabilities: &os_capabilities + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + +topology_template: + inputs: + my_cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + github_url: + type: string + description: The URL to download nodejs. + default: http://github.com/paypal/rest-api-sample-app-nodejs.git + + node_templates: + paypal_pizzastore: + type: tosca.nodes.WebApplication.PayPalPizzaStore + properties: + github_url: { get_input: github_url } + requirements: + - host: nodejs + - database_connection: mongo_db + interfaces: + Standard: + configure: + implementation: ../Scripts/nodejs/config.sh + inputs: + github_url: { get_property: [ SELF, github_url ] } + mongodb_ip: { get_attribute: [mongo_server, private_address] } + start: ../Scripts/nodejs/start.sh + nodejs: + type: tosca.nodes.WebServer + requirements: + - host: + node: app_server + interfaces: + Standard: + create: ../Scripts/nodejs/create.sh + mongo_db: + type: tosca.nodes.Database + requirements: + - host: mongo_dbms + interfaces: + Standard: + create: ../Scripts/mongodb/create_database.sh + mongo_dbms: + type: tosca.nodes.DBMS + requirements: + - host: mongo_server + interfaces: + Standard: + create: ../Scripts/mongodb/create.sh + configure: + implementation: ../Scripts/mongodb/config.sh + inputs: + mongodb_ip: { get_attribute: [mongo_server, private_address] } + start: ../Scripts/mongodb/start.sh + elasticsearch: + type: tosca.nodes.SoftwareComponent.Elasticsearch + requirements: + - host: elasticsearch_server + interfaces: + Standard: + create: ../Scripts/elasticsearch/create.sh + start: ../Scripts/elasticsearch/start.sh + logstash: + type: tosca.nodes.SoftwareComponent.Logstash + requirements: + - host: logstash_server + - search_endpoint: + node: elasticsearch + capability: search_endpoint + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_source: + implementation: ../Python/logstash/configure_elasticsearch.py + inputs: + elasticsearch_ip: { get_attribute: [elasticsearch_server, private_address] } + interfaces: + Standard: + create: ../Scripts/logstash/create.sh + start: ../Scripts/logstash/start.sh + kibana: + type: tosca.nodes.SoftwareComponent.Kibana + requirements: + - host: kibana_server + - search_endpoint: elasticsearch + interfaces: + Standard: + create: ../Scripts/kibana/create.sh + configure: + implementation: ../Scripts/kibana/config.sh + inputs: + elasticsearch_ip: { get_attribute: [elasticsearch_server, private_address] } + kibana_ip: { get_attribute: [kibana_server, private_address] } + start: ../Scripts/kibana/start.sh + app_collectd: + type: tosca.nodes.SoftwareComponent.Collectd + requirements: + - host: app_server + - log_endpoint: + node: logstash + capability: log_endpoint + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_target: + implementation: ../Python/logstash/configure_collectd.py + interfaces: + Standard: + create: ../Scripts/collectd/create.sh + configure: + implementation: ../Python/collectd/config.py + inputs: + logstash_ip: { get_attribute: [logstash_server, private_address] } + start: ../Scripts/collectd/start.sh + app_rsyslog: + type: tosca.nodes.SoftwareComponent.Rsyslog + requirements: + - host: app_server + - log_endpoint: + node: logstash + capability: log_endpoint + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_target: + implementation: ../Python/logstash/configure_rsyslog.py + interfaces: + Standard: + create: ../Scripts/rsyslog/create.sh + configure: + implementation: ../Scripts/rsyslog/config.sh + inputs: + logstash_ip: { get_attribute: [logstash_server, private_address] } + start: ../Scripts/rsyslog/start.sh + app_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + mongo_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + elasticsearch_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + logstash_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + kibana_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + + outputs: + nodejs_url: + description: URL for the nodejs server, http://<IP>:3000 + value: { get_attribute: [ app_server, private_address ] } + mongodb_url: + description: URL for the mongodb server. + value: { get_attribute: [ mongo_server, private_address ] } + elasticsearch_url: + description: URL for the elasticsearch server. + value: { get_attribute: [ elasticsearch_server, private_address ] } + logstash_url: + description: URL for the logstash server. + value: { get_attribute: [ logstash_server, private_address ] } + kibana_url: + description: URL for the kibana server. + value: { get_attribute: [ kibana_server, private_address ] } diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/collectd/config.py b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/collectd/config.py new file mode 100644 index 0000000..686bbd1 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/collectd/config.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +# 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. + +# This script configures collectd to send metric data to the +# logstash server port 25826 +# The environment variable logstash_ip is expected to be set up +import os +with open("/etc/collectd/collectd.conf.d/tosca_elk.conf", "w") as fh: + fh.write(""" + LoadPlugin network + <Plugin network> + Server "%s" "25826" + </Plugin> + """ % (os.environ['logstash_ip'])) diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_collectd.py b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_collectd.py new file mode 100644 index 0000000..18fdacf --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_collectd.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# 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. + +# This script configures the logstash input using the udp protocol on +# port 25826. This is intended to receive data from collectd from +# any source +with open("/etc/logstash/conf.d/collectd.conf", "w") as fh: + fh.write(""" + input { + udp { + port => 25826 # 25826 is the default for collectd + buffer_size => 1452 # 1452 is the default for collectd + codec => collectd { } + tags => ["metrics"] + type => "collectd" + } + }""") diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_elasticsearch.py b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_elasticsearch.py new file mode 100644 index 0000000..2e5389c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_elasticsearch.py @@ -0,0 +1,26 @@ +#!/usr/bin/python + +# 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. + +# This script configures the logstash output to forward to elasticsearch +# The environment variable elasticsearch_ip is expected to be set up +import os +with open("/etc/logstash/conf.d/elasticsearch.conf", 'w') as fh: + fh.write(""" + output { + elasticsearch { + action => index + host => "%s" + protocol => "http" + } + }""" % (os.environ['elasticsearch_ip'])) diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_rsyslog.py b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_rsyslog.py new file mode 100644 index 0000000..fc610c2 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Python/logstash/configure_rsyslog.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +# 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. + +# This script configures the logstash input using the RELP protocol on +# port 2514 This is intended to receive logs from rsyslog from +# any source +with open("/etc/logstash/conf.d/rsyslog.conf", "w") as fh: + fh.write(""" + input { + relp { + port => 2514 + tags => ["logs"] + } + }""") diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/README.txt b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/README.txt new file mode 100644 index 0000000..382c9b0 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/README.txt @@ -0,0 +1,5 @@ +README: + +This TOSCA simple profile deploys nodejs, mongodb, elasticsearch, logstash and kibana each on a separate server with monitoring enabled for nodejs server where a sample nodejs application is running. The syslog and collectd are installed on a nodejs server. + +Entry information for processing through an orchestrator is contained in file TOSCA-Metadata/TOSCA.meta. This file provides high-level information such as CSAR version or creator of the CSAR. Furthermore, it provides pointers to the entry template under 'Entry-Definitions' key. The entry template itself may contain pointers to one or more files that are used to define TOSCA base type, unless provided by orchestrator as built-in TOSCA basetypes, and other non-normative types. These are typically provided under 'imports' section in the entry template file. Those type definitions will be read and processed by orchestrator or TOSCA parser to create an internal graph showing dependencies and relationships between various TOSCA types. The entry template may have references to various artifacts required for deployment and will be processed accordingly. diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/create.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/create.sh new file mode 100644 index 0000000..a483b88 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/create.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# This script install collectd for monitoring data + +apt-get update +apt-get install -y collectd diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/start.sh new file mode 100644 index 0000000..7e8e033 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/collectd/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts collectd as a service in init.d +service collectd stop +service collectd start diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/create.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/create.sh new file mode 100644 index 0000000..c34126c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/create.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# This script installs java and elasticsearch + +apt-get update +apt-get install -y openjdk-7-jre-headless + +wget -qO - https://packages.elasticsearch.org/GPG-KEY-elasticsearch | apt-key add - +echo "deb http://packages.elasticsearch.org/elasticsearch/1.5/debian stable main" | tee -a /etc/apt/sources.list + +apt-get update +apt-get install -y elasticsearch + +# set up to run as service +update-rc.d elasticsearch defaults 95 10 diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/start.sh new file mode 100644 index 0000000..bbc0347 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/elasticsearch/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts elasticsearch as a service in init.d +service elasticsearch stop +service elasticsearch start diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/config.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/config.sh new file mode 100644 index 0000000..f28215a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/config.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# This script configures kibana to connect to the elasticsearch server +# to access data and to export the app url on port 5601: +# The environment variable elasticsearch_ip and kibana_ip are expected +# to be set up. +sed -i 's/localhost/'$elasticsearch_ip'/' /opt/kibana/config/kibana.yml +sed -i 's/0.0.0.0/'$kibana_ip'/' /opt/kibana/config/kibana.yml diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/create.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/create.sh new file mode 100644 index 0000000..41914b1 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/create.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# This script installs kibana and sets it up to run as a service in init.d +cd /opt +wget https://download.elastic.co/kibana/kibana/kibana-4.1.0-linux-x64.tar.gz +tar xzvf kibana-4.1.0-linux-x64.tar.gz +mv kibana-4.1.0-linux-x64 kibana + +# set up to run as service +cd /etc/init.d +wget https://gist.githubusercontent.com/thisismitch/8b15ac909aed214ad04a/raw/bce61d85643c2dcdfbc2728c55a41dab444dca20/kibana4 +chmod +x kibana4 +update-rc.d kibana4 defaults 96 9 diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/start.sh new file mode 100644 index 0000000..5149bb3 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/kibana/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts kibana as a service in init.d +service kibana4 stop +service kibana4 start diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/create.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/create.sh new file mode 100644 index 0000000..77cc8fd --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/create.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# This script installs java, logstash and the contrib package for logstash +# install java as prereq + +apt-get update +apt-get install -y openjdk-7-jre-headless +mkdir /etc/logstash + +# install by apt-get from repo +wget -O - http://packages.elasticsearch.org/GPG-KEY-elasticsearch | apt-key add - +echo "deb http://packages.elasticsearch.org/logstash/1.4/debian stable main" | tee -a /etc/apt/sources.list + +apt-get update +apt-get install -y logstash + +# install contrib to get the relp plugin +/opt/logstash/bin/plugin install contrib + +# set up to run as service +update-rc.d logstash defaults 95 10 diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/start.sh new file mode 100644 index 0000000..a73cf61 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/logstash/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# Run logstash as service in init.d +service logstash stop +service logstash start diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/config.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/config.sh new file mode 100644 index 0000000..78f484e --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/config.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Edit the file /etc/mongod.conf, update with real IP of Mongo server +# This script configures the mongodb server to export its service on +# the server IP +# bind_ip = 127.0.0.1 -> bind_ip = <IP for Mongo server> +# The environment variable mongodb_ip is expected to be set up +sed -i "s/= 127.0.0.1/= $mongodb_ip,127.0.0.1/" /etc/mongod.conf diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create.sh new file mode 100644 index 0000000..d84c275 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# This script installs mongodb + +apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 +echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.0.list + +apt-get update +apt-get install -y mongodb-org + +#Wait for mongodb initialization +while [[ ! -d "/var/lib/mongodb/_tmp" ]]; do + echo "Waiting for mongodb initialization ..." + sleep 5 +done diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create_database.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create_database.sh new file mode 100644 index 0000000..16f1358 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/create_database.sh @@ -0,0 +1,5 @@ +#!/bin/bash +echo "conn = new Mongo();" > setup.js +echo "db = conn.getDB('paypal_pizza');" >> setup.js +echo "db.about.insert({'name': 'PayPal Pizza Store'});" >> setup.js +mongo setup.js diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/start.sh new file mode 100644 index 0000000..ac200a5 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/mongodb/start.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# This script starts mongodb +service mongod stop +rm /var/lib/mongodb/mongod.lock +service mongod start diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/config.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/config.sh new file mode 100644 index 0000000..1e149a2 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/config.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# This script installs an app for nodejs: the app intended is the paypal app +# and it is configured to connect to the mongodb server +# The environment variables github_url and mongodb_ip are expected to be set up +export app_dir=/opt/app +git clone $github_url /opt/app +if [ -f /opt/app/package.json ]; then + cd /opt/app/ && npm install + sed -i "s/localhost/$mongodb_ip/" config.json +fi + +cat > /etc/init/nodeapp.conf <<EOS +description "node.js app" + +start on (net-device-up + and local-filesystems + and runlevel [2345]) +stop on runlevel [!2345] + +expect fork +respawn + +script + export HOME=/ + export NODE_PATH=/usr/lib/node + exec /usr/bin/node ${app_dir}/app.js >> /var/log/nodeapp.log 2>&1 & +end script +EOS diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/create.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/create.sh new file mode 100644 index 0000000..04fd6c6 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/create.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# This script installs nodejs and the prereq + +add-apt-repository ppa:chris-lea/node.js + +apt-get update +apt-get install -y nodejs build-essential diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/start.sh new file mode 100644 index 0000000..6939cb7 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/nodejs/start.sh @@ -0,0 +1,3 @@ +#!/bin/bash +# This script starts the nodejs application +start nodeapp diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/config.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/config.sh new file mode 100644 index 0000000..630767d --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/config.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# This script configures the output for rsyslogd to send logs to the +# logstash server port 2514 using the RELP protocol +# The environment variable logstash_ip is expected to be set up +echo "module(load=\"omrelp\") +action(type=\"omrelp\" target=\"$logstash_ip\" port=\"2514\")" > /etc/rsyslog.d/tosca_elk.conf + +# Remove the /dev/xconsole configuration as xconsole +# is not available by default +l=`awk '/=warn.*\|.*\/dev\/xconsole/{print NR - 1}' /etc/rsyslog.d/50-default.conf` +if [ ! -z $l ]; then + l=`expr $l + 1` + line=`cat /etc/rsyslog.d/50-default.conf | head -n $l | tail -1` + if [[ ! $line == \#* ]]; then + l0=`expr $l - 3` + sed -i -r -e "${l0},${l}s/^.{0}/&#/" /etc/rsyslog.d/50-default.conf + fi +fi + +# Enable nodejs logs for rsyslog +if ! grep -q nodeapp "/etc/rsyslog.conf"; then + sed -i 's/\$PrivDropToGroup\ syslog/\$PrivDropToGroup adm/' /etc/rsyslog.conf + echo "\$ModLoad imfile.so +\$InputFileName /var/log/nodeapp.log +\$InputFileTag paypal_pizza: +\$InputFileStateFile stat-nodeapp +\$InputRunFileMonitor +\$InputFilePollInterval 1" >> /etc/rsyslog.conf +fi diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/create.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/create.sh new file mode 100644 index 0000000..affdd6e --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/create.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# This script installs rsyslog and the library for RELP + +apt-get update +apt-get install -y rsyslog rsyslog-relp diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/start.sh new file mode 100644 index 0000000..3de82d1 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/Scripts/rsyslog/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# This script starts rsyslogd as a service in init.d +service rsyslog stop +service rsyslog start diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/TOSCA-Metadata/TOSCA.meta b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 0000000..feb3d4f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_elk/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: OASIS TOSCA TC +Entry-Definitions: Definitions/tosca_elk.yaml
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/tosca_single_instance_wordpress.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/tosca_single_instance_wordpress.yaml new file mode 100644 index 0000000..1dd195a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/tosca_single_instance_wordpress.yaml @@ -0,0 +1,109 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with wordpress, web server and mysql on the same server. + +imports: + - wordpress.yaml + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + db_name: + type: string + description: The name of the database. + db_user: + type: string + description: The user name of the DB user. + db_pwd: + type: string + description: The WordPress database admin account password. + db_root_pwd: + type: string + description: Root password for MySQL. + db_port: + type: PortDef + description: Port for the MySQL database. + + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standard: + create: ../Scripts/WordPress/install.sh + configure: + implementation: ../Scripts/WordPress/configure.sh + inputs: + wp_db_name: { get_property: [ mysql_database, name ] } + wp_db_user: { get_property: [ mysql_database, user ] } + wp_db_password: { get_property: [ mysql_database, password ] } + + mysql_database: + type: tosca.nodes.Database + properties: + name: { get_input: db_name } + user: { get_input: db_user } + password: { get_input: db_pwd } + requirements: + - host: mysql_dbms + interfaces: + Standard: + configure: + implementation: ../Scripts/MYSQLDatabase/configure.sh + inputs: + db_name: { get_property: [ SELF, name ] } + db_user: { get_property: [ SELF, user ] } + db_password: { get_property: [ SELF, password ] } + db_root_password: { get_property: [ mysql_dbms, root_password ] } + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: { get_input: db_root_pwd } + port: { get_input: db_port } + requirements: + - host: server + interfaces: + Standard: + create: ../Scripts/MYSQLDBMS/install.sh + start: ../Scripts/MYSQLDBMS/start.sh + configure: + implementation: ../Scripts/MYSQLDBMS/configure.sh + inputs: + root_password: { get_property: [ mysql_dbms, root_password ] } + + webserver: + type: tosca.nodes.WebServer + requirements: + - host: server + interfaces: + Standard: + create: ../Scripts/WebServer/install.sh + start: ../Scripts/WebServer/start.sh + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + + outputs: + website_url: + description: IP address for Wordpress wiki. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/wordpress.yaml b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/wordpress.yaml new file mode 100644 index 0000000..5899ed9 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Definitions/wordpress.yaml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + tosca.nodes.WebApplication.WordPress: + derived_from: tosca.nodes.WebApplication + requirements: + - database_endpoint: + capability: tosca.capabilities.Endpoint.Database + node: tosca.nodes.Database + relationship: tosca.relationships.ConnectsTo + interfaces: + Standard: + inputs: + wp_db_name: + type: string + wp_db_user: + type: string + wp_db_password: + type: string diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/README.txt b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/README.txt new file mode 100644 index 0000000..e882ff6 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/README.txt @@ -0,0 +1,22 @@ +README: + +This CSAR contains all definitions that are required for deploying WordPress +and MySQL on a single compute instance. + +Entry information for processing through an orchestrator is contained in file +TOSCA-Metadata/TOSCA.meta. This file provides high-level information such as +CSAR version or creator of the CSAR. Furthermore, it provides pointers to the +various TOSCA definitions files that contain the real details. +The entry 'Entry-Definitions' points to the definitions file which holds the +service template for the workload. +'Entry-Definitions' is optional. An orchestrator can also process the contents +like this: +1) Read in and process each definitions file. +2) For each definitions file: + 2.1) Read in all * type definitions (node types, capability types, etc.) and + store them in an internal map +3) Verify and build dependencies (e.g. inheritance) between all type definitions + previously read in. Orchestrator built-in types (e.g. TOSCA base types) are + also considered in this step. +4) Process the actual service template (the file with a node_templates section). + Validate using previously obtained type information. diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/configure.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/configure.sh new file mode 100644 index 0000000..d4ef6b4 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/configure.sh @@ -0,0 +1,5 @@ +#!/bin/sh +sed --regexp-extended "s/(port\s*=\s*)[0-9]*/\1$db_port/g" </etc/mysql/my.cnf >/tmp/my.cnf +mv -f /tmp/my.cnf /etc/mysql/my.cnf +/etc/init.d/mysql stop +/etc/init.d/mysql start
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/install.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/install.sh new file mode 100644 index 0000000..38628b9 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/install.sh @@ -0,0 +1,9 @@ +#!/bin/bash +#This script installs mysql server + +apt-get update + +debconf-set-selections <<< "mysql-server mysql-server/root_password password $db_root_password" +debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $db_root_password" + +apt-get -y install --fix-missing mysql-server
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/start.sh new file mode 100644 index 0000000..3378670 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDBMS/start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +/etc/init.d/mysql start
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDatabase/configure.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDatabase/configure.sh new file mode 100644 index 0000000..092136a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/MYSQLDatabase/configure.sh @@ -0,0 +1,8 @@ +#!/bin/sh +cat << EOF | mysql -u root --password=$db_root_password +CREATE DATABASE $db_name; +GRANT ALL PRIVILEGES ON $db_name.* TO "$db_user"@"localhost" +IDENTIFIED BY "$db_password"; +FLUSH PRIVILEGES; +EXIT +EOF
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/install.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/install.sh new file mode 100644 index 0000000..4ca9b4e --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/install.sh @@ -0,0 +1,5 @@ +#!/bin/sh +#This script installs apache web server + +apt-get update +apt-get install -y apache2
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/start.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/start.sh new file mode 100644 index 0000000..e962ca5 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WebServer/start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +service apache2 start
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/configure.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/configure.sh new file mode 100644 index 0000000..5598b4f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/configure.sh @@ -0,0 +1,4 @@ +#!/bin/sh +ln -s /usr/share/wordpress /var/www/html/wordpress +gzip -d /usr/share/doc/wordpress/examples/setup-mysql.gz +echo $wp_db_password | bash /usr/share/doc/wordpress/examples/setup-mysql -e $wp_db_name -u $wp_db_user localhost
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/install.sh b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/install.sh new file mode 100644 index 0000000..1320443 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/Scripts/WordPress/install.sh @@ -0,0 +1,5 @@ +#!/bin/sh +#This script installs wordpress + +apt-get update +apt-get install -y wordpress
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/TOSCA-Metadata/TOSCA.meta b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/TOSCA-Metadata/TOSCA.meta new file mode 100644 index 0000000..5208113 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/CSAR/tosca_single_instance_wordpress/TOSCA-Metadata/TOSCA.meta @@ -0,0 +1,5 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-By: OASIS TOSCA TC +Entry-Definitions: Definitions/tosca_single_instance_wordpress.yaml +Content-Type: application/vnd.oasis.tosca.definitions.yaml diff --git a/nfvparser/toscaparser/tests/data/containers/test_container_docker_mysql.yaml b/nfvparser/toscaparser/tests/data/containers/test_container_docker_mysql.yaml new file mode 100644 index 0000000..3fd4466 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/containers/test_container_docker_mysql.yaml @@ -0,0 +1,44 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with mysql docker container. + +# Repositories to retrieve code artifacts from +repositories: + docker_hub: https://registry.hub.docker.com/ + +topology_template: + + inputs: + mysql_root_pwd: + type: string + description: Root password for MySQL. + + node_templates: + # The MYSQL container based on official MySQL image in Docker hub + mysql_container: + type: tosca.nodes.Container.Application.Docker + requirements: + - host: mysql_runtime + artifacts: + my_image: + file: mysql + type: tosca.artifacts.Deployment.Image.Container.Docker + repository: docker_hub + interfaces: + Standard: + create: + implementation: my_image + inputs: + MYSQL_ROOT_PASSWORD: { get_input: mysql_root_pwd } + + # The properties of the runtime to host the container + mysql_runtime: + type: tosca.nodes.Container.Runtime + capabilities: + host: + properties: + num_cpus: 1 + disk_size: 10 GB + mem_size: 2 MB + diff --git a/nfvparser/toscaparser/tests/data/custom_types/collectd.yaml b/nfvparser/toscaparser/tests/data/custom_types/collectd.yaml new file mode 100644 index 0000000..1ac0935 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/collectd.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + collectd is a daemon which gathers statistics about the system it is running on. + +node_types: + tosca.nodes.SoftwareComponent.Collectd: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - log_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Logstash + relationship: tosca.relationships.ConnectsTo
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/custom_types/compute_with_attribute_list.yaml b/nfvparser/toscaparser/tests/data/custom_types/compute_with_attribute_list.yaml new file mode 100644 index 0000000..3487433 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/compute_with_attribute_list.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Compute node type with a list attribute + +node_types: + tosca.nodes.ComputeWithAttrList: + derived_from: tosca.nodes.Compute + attributes: + attr_list: + type: map + entry_schema: + type: string + diff --git a/nfvparser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml b/nfvparser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml new file mode 100644 index 0000000..909a297 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/compute_with_nested_atributes.yaml @@ -0,0 +1,22 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Compute node type with capability with an attribute of type list + +capability_types: + + tosca.capabilities.indigo.Endpoint: + derived_from: tosca.capabilities.Endpoint + attributes: + credential: + type: list + entry_schema: + type: tosca.datatypes.Credential + +node_types: + + tosca.nodes.ComputeWithCapWithAttr: + derived_from: tosca.nodes.Compute + capabilities: + endpoint: + type: tosca.capabilities.indigo.Endpoint + diff --git a/nfvparser/toscaparser/tests/data/custom_types/compute_with_prop.yaml b/nfvparser/toscaparser/tests/data/custom_types/compute_with_prop.yaml new file mode 100644 index 0000000..93a82af --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/compute_with_prop.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Compute node type with a parameter for the get property with host test + +node_types: + tosca.nodes.ComputeWithProp: + derived_from: tosca.nodes.Compute + properties: + test: + required: false + type: integer + diff --git a/nfvparser/toscaparser/tests/data/custom_types/custom_caps_def.yaml b/nfvparser/toscaparser/tests/data/custom_types/custom_caps_def.yaml new file mode 100644 index 0000000..337c38f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/custom_caps_def.yaml @@ -0,0 +1,22 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Definition of a node with a capiblity and a parent capability + defined in an imported file + +capability_types: + + tosca.capabilities.SomeCap: + derived_from: tosca.capabilities.Root + + tosca.capabilities.SomeChildCap: + derived_from: tosca.capabilities.SomeCap + +node_types: + + tosca.nodes.SomeNode: + derived_from: tosca.nodes.Root + capabilities: + lrms: + type: tosca.capabilities.SomeChildCap + diff --git a/nfvparser/toscaparser/tests/data/custom_types/custom_interface.yaml b/nfvparser/toscaparser/tests/data/custom_types/custom_interface.yaml new file mode 100644 index 0000000..2d9bec4 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/custom_interface.yaml @@ -0,0 +1,20 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + This template contains custom defined interface type + and a node type which uses this custom interface + +interface_types: + tosca.interfaces.CustomInterface: + derived_from: tosca.interfaces.Root + CustomOp: + CustomOp2: + +node_types: + tosca.nodes.CustomInterfaceTest: + derived_from: tosca.nodes.WebApplication + interfaces: + CustomInterface: + type: tosca.interfaces.CustomInterface + CustomOp3: + diff --git a/nfvparser/toscaparser/tests/data/custom_types/custom_relationship_type_defs.yaml b/nfvparser/toscaparser/tests/data/custom_types/custom_relationship_type_defs.yaml new file mode 100644 index 0000000..cf5c2b4 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/custom_relationship_type_defs.yaml @@ -0,0 +1,23 @@ +node_types: + tosca.nodes.HACompute: + derived_from: tosca.nodes.Compute + capabilities: + high_availability: + type: tosca.capabilities.HA + requirements: + - high_availability: + capability: tosca.capabilities.HA + relationship: tosca.relationships.HA + node: tosca.nodes.HACompute + occurences: [ 0, 1 ] + +relationship_types: + tosca.relationships.HA: + derived_from: tosca.relationships.Root + valid_target_types: [ tosca.capabilities.HA ] + +capability_types: + tosca.capabilities.HA: + derived_from: tosca.capabilities.Root + valid_source_types: [ tosca.nodes.HACompute ] + diff --git a/nfvparser/toscaparser/tests/data/custom_types/db_with_list_param.yaml b/nfvparser/toscaparser/tests/data/custom_types/db_with_list_param.yaml new file mode 100644 index 0000000..57ce279 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/db_with_list_param.yaml @@ -0,0 +1,10 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + tosca.nodes.DatabaseWithListParam: + derived_from: tosca.nodes.Database + properties: + list_prop: + type: list + entry_schema: + type: integer diff --git a/nfvparser/toscaparser/tests/data/custom_types/elasticsearch.yaml b/nfvparser/toscaparser/tests/data/custom_types/elasticsearch.yaml new file mode 100644 index 0000000..b140a32 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/elasticsearch.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Elasticsearch is an open-source search engine built on top of Apache Lucene, + a full-text search-engine library. + +node_types: + tosca.nodes.SoftwareComponent.Elasticsearch: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + search_endpoint: + type: tosca.capabilities.Endpoint diff --git a/nfvparser/toscaparser/tests/data/custom_types/imported_sample.yaml b/nfvparser/toscaparser/tests/data/custom_types/imported_sample.yaml new file mode 100644 index 0000000..c8e4532 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/imported_sample.yaml @@ -0,0 +1,38 @@ +tosca1_definitions_version: tosca_simple_yaml_1_0 +tosca_definitions_version: tosca_simple_yaml_1_10 + +descriptions: > + Pizza store app that allows you to explore the features provided by PayPal's REST APIs. + More detail can be found at https://github.com/paypal/rest-api-sample-app-nodejs/ + +node_typess: +node_types: + tosca.nodes.SoftwareComponent.Logstash: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - search_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Elasticsearch + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_source: + inputs: + elasticsearch_ip: + type: string + capabilities1: + log_endpoint: + type: tosca.capabilities.Endpoint +policy_types1: +policy_types: + mycompany.mytypes.myScalingPolicy: + derived1_from: tosca.policies.Scaling + metadata: + type: map + entry_schema: + type: string +relationship_types1: +relationship_types: + test.relation.connects: + derived_from4: tosca.relationships.ConnectsTo diff --git a/nfvparser/toscaparser/tests/data/custom_types/kibana.yaml b/nfvparser/toscaparser/tests/data/custom_types/kibana.yaml new file mode 100644 index 0000000..5701e69 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/kibana.yaml @@ -0,0 +1,14 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Kibana is an open source analytics and visualization platform designed to work with Elasticsearch. + You use Kibana to search, view, and interact with data stored in Elasticsearch. + +node_types: + tosca.nodes.SoftwareComponent.Kibana: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - search_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Elasticsearch + relationship: tosca.relationships.ConnectsTo diff --git a/nfvparser/toscaparser/tests/data/custom_types/logstash.yaml b/nfvparser/toscaparser/tests/data/custom_types/logstash.yaml new file mode 100644 index 0000000..cf60521 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/logstash.yaml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Logstash is a tool for receiving, processing and outputting logs. All kinds + of logs. System logs, webserver logs, error logs, application logs, and just + about anything you can throw at it. + +node_types: + tosca.nodes.SoftwareComponent.Logstash: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - search_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Elasticsearch + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_source: + inputs: + elasticsearch_ip: + type: string + capabilities: + log_endpoint: + type: tosca.capabilities.Endpoint diff --git a/nfvparser/toscaparser/tests/data/custom_types/nested_rsyslog.yaml b/nfvparser/toscaparser/tests/data/custom_types/nested_rsyslog.yaml new file mode 100644 index 0000000..8c04171 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/nested_rsyslog.yaml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + RSYSLOG is the Rocket-fast SYStem for LOG processing. + +imports: + - test_import: + file: custom_types/logstash.yaml + +node_types: + Rsyslog: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - log_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Logstash + relationship: tosca.relationships.ConnectsTo diff --git a/nfvparser/toscaparser/tests/data/custom_types/nested_test_wordpress.yaml b/nfvparser/toscaparser/tests/data/custom_types/nested_test_wordpress.yaml new file mode 100644 index 0000000..4df277d --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/nested_test_wordpress.yaml @@ -0,0 +1,32 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 +imports: + - test_prefix_defs: + file: custom_types/nested_rsyslog.yaml + namespace_prefix: test_namespace_prefix + - test_second_time_with_another_prefix: + file: custom_types/nested_rsyslog.yaml + namespace_prefix: test_2nd_namespace_prefix + +node_types: + tosca.nodes.SoftwareComponent.Rsyslog.TestRsyslogType: + derived_from: test_namespace_prefix.Rsyslog + + Test2ndRsyslogType: + derived_from: test_2nd_namespace_prefix.Rsyslog + + tosca.nodes.WebApplication.WordPress: + derived_from: tosca.nodes.WebApplication + requirements: + - database_endpoint: + capability: tosca.capabilities.Endpoint.Database + node: tosca.nodes.Database + relationship: tosca.relationships.ConnectsTo + interfaces: + Standard: + inputs: + wp_db_name: + type: string + wp_db_user: + type: string + wp_db_password: + type: string diff --git a/nfvparser/toscaparser/tests/data/custom_types/node_with_cap.yaml b/nfvparser/toscaparser/tests/data/custom_types/node_with_cap.yaml new file mode 100644 index 0000000..b17513f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/node_with_cap.yaml @@ -0,0 +1,33 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Node type that has a requirement of a capability with a defined value + +capability_types: + + tosca.capabilities.SomeCap: + derived_from: tosca.capabilities.Root + properties: + type: + type: string + required: true + default: someval + constraints: + - equal: someval + +node_types: + + tosca.nodes.SomeNode: + derived_from: tosca.nodes.Root + requirements: + - some_req: + capability: tosca.capabilities.SomeCap + node: tosca.nodes.NodeWithCap + relationship: tosca.relationships.HostedOn + + tosca.nodes.NodeWithCap: + derived_from: tosca.nodes.Root + capabilities: + some_req: + type: tosca.capabilities.SomeCap + diff --git a/nfvparser/toscaparser/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml b/nfvparser/toscaparser/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml new file mode 100644 index 0000000..cdabeae --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/paypalpizzastore_nodejs_app.yaml @@ -0,0 +1,29 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Pizza store app that allows you to explore the features provided by PayPal's REST APIs. + More detail can be found at https://github.com/paypal/rest-api-sample-app-nodejs/ + +node_types: + tosca.nodes.WebApplication.PayPalPizzaStore: + derived_from: tosca.nodes.WebApplication + properties: + github_url: + required: false + type: string + description: location of the application on the github. + default: https://github.com/sample.git + requirements: + #WebApplication inherits Computer, so host implied. + - database_connection: + capability: tosca.capabilities.Endpoint.Database + node: tosca.nodes.Database + relationship: tosca.relationships.ConnectsTo + interfaces: + Standard: + configure: + inputs: + github_url: + type: string + mongodb_ip: + type: string diff --git a/nfvparser/toscaparser/tests/data/custom_types/rsyslog.yaml b/nfvparser/toscaparser/tests/data/custom_types/rsyslog.yaml new file mode 100644 index 0000000..4614ee7 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/rsyslog.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + RSYSLOG is the Rocket-fast SYStem for LOG processing. + +node_types: + tosca.nodes.SoftwareComponent.Rsyslog: + derived_from: tosca.nodes.SoftwareComponent + requirements: + - log_endpoint: + capability: tosca.capabilities.Endpoint + node: tosca.nodes.SoftwareComponent.Logstash + relationship: tosca.relationships.ConnectsTo diff --git a/nfvparser/toscaparser/tests/data/custom_types/wordpress.yaml b/nfvparser/toscaparser/tests/data/custom_types/wordpress.yaml new file mode 100644 index 0000000..5899ed9 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/custom_types/wordpress.yaml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + tosca.nodes.WebApplication.WordPress: + derived_from: tosca.nodes.WebApplication + requirements: + - database_endpoint: + capability: tosca.capabilities.Endpoint.Database + node: tosca.nodes.Database + relationship: tosca.relationships.ConnectsTo + interfaces: + Standard: + inputs: + wp_db_name: + type: string + wp_db_user: + type: string + wp_db_password: + type: string diff --git a/nfvparser/toscaparser/tests/data/datatypes/custom_datatype_def.yaml b/nfvparser/toscaparser/tests/data/datatypes/custom_datatype_def.yaml new file mode 100644 index 0000000..b1fb402 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/datatypes/custom_datatype_def.yaml @@ -0,0 +1,53 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Custom type and node definition used to test custom datatypes. + +node_types: + tosca.nodes.my.SomeNode: + derived_from: tosca.nodes.Root + properties: + people: + type: tosca.my.datatypes.People + +data_types: + tosca.my.datatypes.PeopleBase: + properties: + name: + type: string + required: true + constraints: + - min_length: 2 + gender: + type: string + required: false + default: unknown + + tosca.my.datatypes.People: + derived_from: tosca.my.datatypes.PeopleBase + properties: + addresses: + type: map + required: false + entry_schema: + type: string + contacts: + type: list + required: false + entry_schema: + type: tosca.my.datatypes.ContactInfo + + tosca.my.datatypes.ContactInfo: + description: simple contact information + properties: + contact_name: + type: string + required: true + constraints: + - min_length: 2 + contact_email: + type: string + required: false + contact_phone: + type: string + required: false diff --git a/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_in_current_template.yaml b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_in_current_template.yaml new file mode 100644 index 0000000..befa198 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_in_current_template.yaml @@ -0,0 +1,70 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA templates used to test custom datatypes. + +node_types: + tosca.nodes.my.SomeNode: + derived_from: tosca.nodes.Root + properties: + people: + type: tosca.my.datatypes.People + +data_types: + tosca.my.datatypes.PeopleBase: + properties: + name: + type: string + required: true + constraints: + - min_length: 2 + gender: + type: string + required: false + default: unknown + + tosca.my.datatypes.People: + derived_from: tosca.my.datatypes.PeopleBase + properties: + addresses: + type: map + required: false + entry_schema: + type: string + contacts: + type: list + required: false + entry_schema: + type: tosca.my.datatypes.ContactInfo + + tosca.my.datatypes.ContactInfo: + description: simple contact information + properties: + contact_name: + type: string + required: true + constraints: + - min_length: 2 + contact_email: + type: string + required: false + contact_phone: + type: string + required: false + +topology_template: + node_templates: + positive: + type: tosca.nodes.my.SomeNode + properties: + people: + name: Mike + gender: male + addresses: {Home: 1 foo street, Office: 9 bar avenue} + contacts: + - {contact_name: Tom, + contact_email: tom@email.com, + contact_phone: '123456789'} + - {contact_name: Jerry, + contact_email: jerry@email.com, + contact_phone: '321654987'} diff --git a/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_nested_datatype_error.yaml b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_nested_datatype_error.yaml new file mode 100644 index 0000000..b28f499 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_nested_datatype_error.yaml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA templates used to test custom datatypes. + +imports: + - custom_datatype_def.yaml + +topology_template: + node_templates: + # 123456789 is not a string + error in nested datatype: + type: tosca.nodes.my.SomeNode + properties: + people: + name: Mike + gender: male + addresses: {Home: 1 foo street, Office: 9 bar avenue} + contacts: + - {contact_name: Tom, + contact_email: tom@email.com, + contact_phone: 123456789} + - {contact_name: Jerry, + contact_email: jerry@email.com, + contact_phone: '321654987'} diff --git a/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_positive.yaml b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_positive.yaml new file mode 100644 index 0000000..f1762f4 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_positive.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA templates used to test custom datatypes. + +imports: + - custom_datatype_def.yaml + +topology_template: + node_templates: + positive: + type: tosca.nodes.my.SomeNode + properties: + people: + name: Mike + gender: male + addresses: {Home: 1 foo street, Office: 9 bar avenue} + contacts: + - {contact_name: Tom, + contact_email: tom@email.com, + contact_phone: '123456789'} + - {contact_name: Jerry, + contact_email: jerry@email.com, + contact_phone: '321654987'} diff --git a/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_value_error.yaml b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_value_error.yaml new file mode 100644 index 0000000..31cf681 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/datatypes/test_custom_datatypes_value_error.yaml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA templates used to test custom datatypes. + +imports: + - custom_datatype_def.yaml + +topology_template: + node_templates: + # addresses is not a map + error in field value: + type: tosca.nodes.my.SomeNode + properties: + people: + name: Mike + gender: male + addresses: [1 foo street, 9 bar avenue] diff --git a/nfvparser/toscaparser/tests/data/datatypes/test_datatype_portspec_add_req.yaml b/nfvparser/toscaparser/tests/data/datatypes/test_datatype_portspec_add_req.yaml new file mode 100644 index 0000000..f944927 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/datatypes/test_datatype_portspec_add_req.yaml @@ -0,0 +1,41 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA test PortSpec Additional Requirement clauses + +node_types: + + MyNodeType: + derived_from: Root + properties: + test_port: + type: PortSpec + +topology_template: + + node_templates: + + # Test invalid source value below (default) specified range constraint + test_node2: + type: MyNodeType + properties: + test_port: + protocol: tcp + source: 0 + + # Test invalid source value over specified range + test_node3: + type: MyNodeType + properties: + test_port: + protocol: tcp + source: 65535 + source_range: [ 2, 65534 ] + + # Test invalid source value under specified range + test_node4: + type: MyNodeType + properties: + test_port: + protocol: tcp + source: 1 + source_range: [ 2, 65534 ] diff --git a/nfvparser/toscaparser/tests/data/dsl_definitions/test_nested_dsl_def.yaml b/nfvparser/toscaparser/tests/data/dsl_definitions/test_nested_dsl_def.yaml new file mode 100644 index 0000000..6155595 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/dsl_definitions/test_nested_dsl_def.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Test template demonstrating usage of nested dsl_definitions value. + +dsl_definitions: + caps: &caps + host: + properties: + disk_size: 10 GB + num_cpus: 2 + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + +topology_template: + node_templates: + my_server: + type: tosca.nodes.Compute + capabilities: *caps
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml b/nfvparser/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml new file mode 100644 index 0000000..f0bec84 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_capabilties_inheritance.yaml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile to test the attribute inheritance + +imports: + - ../custom_types/node_with_cap.yaml + +topology_template: + + node_templates: + + some_node: + type: tosca.nodes.SomeNode + requirements: + - some_req: node_cap + interfaces: + Standard: + configure: + implementation: some_script.sh + inputs: + some_input: { get_property: [ SELF, some_req, type ] } + + node_cap: + type: tosca.nodes.NodeWithCap + diff --git a/nfvparser/toscaparser/tests/data/functions/test_concat.yaml b/nfvparser/toscaparser/tests/data/functions/test_concat.yaml new file mode 100644 index 0000000..22fcfb4 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_concat.yaml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template for deploying a single server with concat function. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + # Host container properties + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + # Guest Operating System properties + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: Linux + distribution: RHEL + version: 6.5 + outputs: + url: + description: Concatenate the URL for a server from template values. + value: { concat: [ 'http://', + get_attribute: [ server, public_address ], + ':' , + get_attribute: [ server, port ] ] }
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/functions/test_concat_invalid.yaml b/nfvparser/toscaparser/tests/data/functions/test_concat_invalid.yaml new file mode 100644 index 0000000..7c7b0aa --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_concat_invalid.yaml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template for deploying a single server with invalid concat function. + +topology_template: + outputs: + invalid_concat_syntax: + description: test concat with invalid syntax. + value: { concat: []}
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_host_keyword.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_host_keyword.yaml new file mode 100644 index 0000000..90ffbe2 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_host_keyword.yaml @@ -0,0 +1,33 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_attribute with HOST keyword. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + dbms: + type: tosca.nodes.DBMS + requirements: + - host: server + interfaces: + Standard: + configure: + implementation: configure.sh + inputs: + ip_address: { get_attribute: [ HOST, private_address ] } + database: + type: tosca.nodes.Database + requirements: + - host: dbms + interfaces: + Standard: + configure: + implementation: configure.sh + inputs: + ip_address: { get_attribute: [ HOST, private_address ] } diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_host_not_found.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_host_not_found.yaml new file mode 100644 index 0000000..69679ff --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_host_not_found.yaml @@ -0,0 +1,20 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_attribute with HOST keyword. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + interfaces: + Standard: + configure: + implementation: configure.sh + inputs: + ip_address: { get_attribute: [ HOST, private_address ] } + diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_illegal_host_in_outputs.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_illegal_host_in_outputs.yaml new file mode 100644 index 0000000..6c7d9bb --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_illegal_host_in_outputs.yaml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_attribute with HOST keyword. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + + outputs: + ip_address: + value: { get_attribute: [ HOST, private_address ] } diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_source_target_keywords.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_source_target_keywords.yaml new file mode 100644 index 0000000..047387f --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_source_target_keywords.yaml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_attribute with TARGET ans SOURCE keywords. + +topology_template: + + node_templates: + + mysql: + type: tosca.nodes.DBMS + properties: + root_password: rootpw + port: 3306 + requirements: + - host: + node: db_server + relationship: + type: tosca.relationships.HostedOn + interfaces: + Configure: + pre_configure_source: + implementation: some_script.sh + inputs: + target_test: { get_attribute: [ TARGET, public_address ] } + source_port: { get_attribute: [ SOURCE, tosca_name ] } + + db_server: + type: tosca.nodes.Compute + diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_unknown_attribute_name.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_unknown_attribute_name.yaml new file mode 100644 index 0000000..0570c7c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_unknown_attribute_name.yaml @@ -0,0 +1,28 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for testing unknown attribute name in get_attribute + function. + +topology_template: + inputs: + image_id: + type: string + + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + interfaces: + Standard: + configure: + implementation: start_server.sh + inputs: + image_id: { get_input: image_id } + + outputs: + ip_address: + value: { get_attribute: [ server, unknown_attribute ] } diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml new file mode 100644 index 0000000..34c1c33 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_unknown_node_template_name.yaml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for testing unknown node template name in get_attribute + function. + +topology_template: + inputs: + image_id: + type: string + + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + interfaces: + Standard: + configure: + implementation: start_server.sh + inputs: + image_id: { get_input: image_id } + + outputs: + ip_address: + value: { get_attribute: [ unknown_node_template, private_address ] } + network: + value: { get_attribute: [ unknown_node_template, networks, public ] } diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_index.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_index.yaml new file mode 100644 index 0000000..5766490 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_index.yaml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_attribute with a list attribute and an index + +imports: + - ../custom_types/compute_with_attribute_list.yaml + +topology_template: + node_templates: + server: + type: tosca.nodes.ComputeWithAttrList + interfaces: + Standard: + configure: + implementation: configure.sh + inputs: + ip_address: { get_attribute: [ SELF, attr_list, 0 ] } + diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_index_error.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_index_error.yaml new file mode 100644 index 0000000..7511999 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_index_error.yaml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_attribute with an incorrect index + +imports: + - ../custom_types/compute_with_attribute_list.yaml + +topology_template: + node_templates: + server: + type: tosca.nodes.ComputeWithAttrList + interfaces: + Standard: + configure: + implementation: configure.sh + inputs: + ip_address: { get_attribute: [ SELF, private_address, 0 ] } + diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_nested_params.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_nested_params.yaml new file mode 100644 index 0000000..79e632c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_attribute_with_nested_params.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_attribute with nested attributes + +imports: + - ../custom_types/compute_with_nested_atributes.yaml + +topology_template: + node_templates: + server: + type: tosca.nodes.ComputeWithCapWithAttr + capabilities: + endpoint: + properties: + port: 80 + interfaces: + Standard: + configure: + implementation: configure.sh + inputs: + ip_address: { get_attribute: [ SELF, endpoint, credential, 0, token ] } + diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml new file mode 100644 index 0000000..a269005 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_implicit_attribute.yaml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Attribute can be defined explicitly as part of type definition + or implicitly via property. This TOSCA template tests validation + of attribute name implicitly created as a property and referenced + via get_attribute function. + +node_types: + ServerNode: + derived_from: SoftwareComponent + properties: + notification_port: + type: integer + +topology_template: + node_templates: + my_server: + type: ServerNode + properties: + notification_port: 8000 + + outputs: + ip_address: + value: { get_attribute: [ my_server, notification_port ] }
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_property_source_target_keywords.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_property_source_target_keywords.yaml new file mode 100644 index 0000000..c460257 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_property_source_target_keywords.yaml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA template for testing get_property with TARGET ans SOURCE keywords. + +imports: + - ../custom_types/compute_with_prop.yaml + +topology_template: + + node_templates: + + mysql: + type: tosca.nodes.DBMS + properties: + root_password: rootpw + port: 3306 + requirements: + - host: + node: db_server + relationship: + type: tosca.relationships.HostedOn + interfaces: + Configure: + pre_configure_source: + implementation: some_script.sh + inputs: + target_test: { get_property: [ TARGET, test ] } + source_port: { get_property: [ SOURCE, port ] } + + db_server: + type: tosca.nodes.ComputeWithProp + properties: + test: 1 + diff --git a/nfvparser/toscaparser/tests/data/functions/test_get_property_with_host.yaml b/nfvparser/toscaparser/tests/data/functions/test_get_property_with_host.yaml new file mode 100644 index 0000000..1ca69ca --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_get_property_with_host.yaml @@ -0,0 +1,65 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile to test the get property function with HOST parameter + +imports: + - ../custom_types/compute_with_prop.yaml + +topology_template: + inputs: + db_name: + type: string + description: The name of the database. + default: wordpress + db_user: + type: string + description: The user name of the DB user. + default: wp_user + db_pwd: + type: string + description: The WordPress database admin account password. + default: wp_pass + db_root_pwd: + type: string + description: Root password for MySQL. + db_port: + type: PortDef + description: Port for the MySQL database. + default: 3306 + + node_templates: + + mysql_database: + type: tosca.nodes.Database + properties: + name: { get_input: db_name } + user: { get_input: db_user } + password: { get_input: db_pwd } + capabilities: + database_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: mysql_dbms + interfaces: + Standard: + configure: + implementation: mysql/mysql_database_configure.sh + inputs: + db_port: { get_property: [ HOST, port ] } + test: { get_property: [ HOST, test ] } + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: { get_input: db_root_pwd } + port: { get_input: db_port } + requirements: + - host: server + + server: + type: tosca.nodes.ComputeWithProp + properties: + test: 1 + diff --git a/nfvparser/toscaparser/tests/data/functions/test_invalid_function_signature.yaml b/nfvparser/toscaparser/tests/data/functions/test_invalid_function_signature.yaml new file mode 100644 index 0000000..dde8427 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_invalid_function_signature.yaml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile template to test invalid get_input function. + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + # compute properties (flavor) + disk_size: 10 GB + num_cpus: { get_input: [cpus, cpus] } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + + outputs: + server_address: + description: IP address of server instance. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/functions/test_token.yaml b/nfvparser/toscaparser/tests/data/functions/test_token.yaml new file mode 100644 index 0000000..495a930 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_token.yaml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template for deploying a single server with token function. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + + outputs: + url: + description: Get the first part of the ip + value: { token: [ get_attribute: [ server, public_address ], + '.' , + 0 ] } diff --git a/nfvparser/toscaparser/tests/data/functions/test_token_invalid.yaml b/nfvparser/toscaparser/tests/data/functions/test_token_invalid.yaml new file mode 100644 index 0000000..35ae2ff --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_token_invalid.yaml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template for deploying a single server with invalid token function. + +topology_template: + outputs: + invalid_token_syntax_1: + description: test token with only two paremeters. + value: { token: ["some_string", "_"]} + + invalid_token_syntax_2: + description: test token with invalid string as third argument. + value: { token: ["some_string", "_", "1"]} + + invalid_token_syntax_3: + description: test token with invalid string as second argument. + value: { token: ["some_string", "aa", "1"]} diff --git a/nfvparser/toscaparser/tests/data/functions/test_unknown_capability_property.yaml b/nfvparser/toscaparser/tests/data/functions/test_unknown_capability_property.yaml new file mode 100644 index 0000000..4a92530 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_unknown_capability_property.yaml @@ -0,0 +1,36 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for testing an unknown capability property. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + dbms: + type: tosca.nodes.DBMS + properties: + root_password: 1234 + port: 3672 + database: + type: tosca.nodes.Database + properties: + name: my_db + user: abcd + password: 1234 + capabilities: + database_endpoint: + properties: + port: { get_property: [ dbms, port ] } + requirements: + - host: dbms + interfaces: + Standard: + configure: + implementation: database_configure.sh + inputs: + db_port: { get_property: [ SELF, database_endpoint, unknown ] } diff --git a/nfvparser/toscaparser/tests/data/functions/test_unknown_input_in_interface.yaml b/nfvparser/toscaparser/tests/data/functions/test_unknown_input_in_interface.yaml new file mode 100644 index 0000000..cbfb391 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_unknown_input_in_interface.yaml @@ -0,0 +1,20 @@ + +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for testing an unknown input. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + interfaces: + Standard: + configure: + implementation: start_server.sh + inputs: + image_id: { get_input: image_id } diff --git a/nfvparser/toscaparser/tests/data/functions/test_unknown_input_in_property.yaml b/nfvparser/toscaparser/tests/data/functions/test_unknown_input_in_property.yaml new file mode 100644 index 0000000..9ba7ee5 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/test_unknown_input_in_property.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for testing an unknown input. + +topology_template: + node_templates: + obj_store_server: + type: tosca.nodes.ObjectStorage + properties: + name: { get_input: objectstore_name } + size: 1024 MB + maxsize: 1 GB diff --git a/nfvparser/toscaparser/tests/data/functions/tosca_nested_property_names_indexes.yaml b/nfvparser/toscaparser/tests/data/functions/tosca_nested_property_names_indexes.yaml new file mode 100644 index 0000000..8fb7b96 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/functions/tosca_nested_property_names_indexes.yaml @@ -0,0 +1,47 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile with nested property names or indexes. + +imports: + - ../custom_types/wordpress.yaml + - ../custom_types/db_with_list_param.yaml + +topology_template: + + node_templates: + + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: server + - database_endpoint: mysql_database + interfaces: + Standard: + configure: + implementation: wordpress/wordpress_configure.sh + inputs: + wp_endpoint_protocol: { get_property: [ SELF, database_endpoint, ports, user_port, protocol ] } + wp_list_prop: { get_property: [ mysql_database, list_prop, 2 ] } + + mysql_database: + type: tosca.nodes.DatabaseWithListParam + properties: + list_prop: [1,2,3] + capabilities: + database_endpoint: + properties: + ports: + user_port: + protocol: tcp + target: 50000 + source: 9000 + requirements: + - host: mysql_dbms + + mysql_dbms: + type: tosca.nodes.DBMS + requirements: + - host: server + + server: + type: tosca.nodes.Compute diff --git a/nfvparser/toscaparser/tests/data/groups/definitions.yaml b/nfvparser/toscaparser/tests/data/groups/definitions.yaml new file mode 100644 index 0000000..40c1d8b --- /dev/null +++ b/nfvparser/toscaparser/tests/data/groups/definitions.yaml @@ -0,0 +1,10 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +group_types: + mycompany.mytypes.groups.placement: + description: My company's group type for placing nodes of type Compute + members: [ tosca.nodes.Compute ] + metadata: + type: map + entry_schema: + type: string diff --git a/nfvparser/toscaparser/tests/data/groups/tosca_group_template.yaml b/nfvparser/toscaparser/tests/data/groups/tosca_group_template.yaml new file mode 100644 index 0000000..0e94240 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/groups/tosca_group_template.yaml @@ -0,0 +1,54 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Service template with topology_template, act as a nested system inside another system. + +imports: + - definitions.yaml + +topology_template: + description: Template of a database including its hosting stack. + + inputs: + mq_server_ip: + type: string + description: IP address of the message queuing server to receive messages from. + receiver_port: + type: string + description: Port to be used for receiving messages. + my_cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + node_templates: + websrv: + type: tosca.nodes.WebServer + capabilities: + data_endpoint: + properties: + port_name: { get_input: receiver_port } + requirements: + - host: + node: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + groups: + webserver_group: + type: mycompany.mytypes.groups.placement + members: [ websrv, server ] diff --git a/nfvparser/toscaparser/tests/data/interfaces/test_custom_interface_in_template.yaml b/nfvparser/toscaparser/tests/data/interfaces/test_custom_interface_in_template.yaml new file mode 100644 index 0000000..c23917c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/interfaces/test_custom_interface_in_template.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with valid custom interface and operations. + +imports: + - ../custom_types/custom_interface.yaml + +topology_template: + + node_templates: + customInterfaceTest: + type: tosca.nodes.CustomInterfaceTest + interfaces: + CustomInterface: + CustomOp: # operation from interface_type with additional inputs + inputs: + param: + type: string + CustomOp3: # operation from node_type with additional inputs + inputs: + param3: + type: string diff --git a/nfvparser/toscaparser/tests/data/interfaces/test_custom_interface_invalid_operation.yaml b/nfvparser/toscaparser/tests/data/interfaces/test_custom_interface_invalid_operation.yaml new file mode 100644 index 0000000..d56ad9c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/interfaces/test_custom_interface_invalid_operation.yaml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with invalid custom operation. + +imports: + - ../custom_types/custom_interface.yaml + +topology_template: + + node_templates: + customInterfaceTest: + type: tosca.nodes.CustomInterfaceTest + interfaces: + CustomInterface: + CustomOp4: # invalid operation + inputs: + param3: + type: string diff --git a/nfvparser/toscaparser/tests/data/load_balancer/tosca_load_balancer.yaml b/nfvparser/toscaparser/tests/data/load_balancer/tosca_load_balancer.yaml new file mode 100644 index 0000000..2fcdb48 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/load_balancer/tosca_load_balancer.yaml @@ -0,0 +1,75 @@ +# Note: this could eventually be translated to a Neutron Load Balancer +# However, in Heat/HOT the preferred way of doing this is creating an Autoscale Group +# +#heat_template_version: 2015-04-30 ... +#resources: +#load_bal_resource: +# type: OS::Neutron::Pool +# properties: +# admin_state_up: Boolean +# description: String +# lb_method: String +# monitors: [Value, Value, ...] +# name: String +# protocol: String +# provider: String +# subnet: String +# vip: { +# "description": String, +# "name": String, +# "connection_limit": Integer, +# "protocol_port": Integer, +# "subnet": String, +# "address": String, +# "admin_state_up": Boolean, +# "session_persistence": +# { +# "cookie_name": String, +# "type": String} +# } +# +# example from: https://gist.github.com/therve/9231701 +# +#resources: +# web_server_group: +# type: AWS::AutoScaling::AutoScalingGroup +# properties: +# AvailabilityZones: [nova] +# LaunchConfigurationName: {get_resource: launch_config} +# MinSize: 1 +# MaxSize: 3 +# LoadBalancerNames: +# - {get_resource: mylb} +# mypool: +# type: OS::Neutron::Pool +# properties: +# protocol: HTTP +# monitors: [{get_resource: mymonitor}] +# subnet_id: {get_param: subnet_id} +# lb_method: ROUND_ROBIN +# vip: +# protocol_port: 80 +# mylb: +# type: OS::Neutron::LoadBalancer +# properties: +# protocol_port: 80 +# pool_id: {get_resource: mypool} + +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template for deploying a load balancer with predefined endpoint properties. + +topology_template: + node_templates: + simple_load_balancer: + type: tosca.nodes.LoadBalancer + capabilities: + # properties: + # algorithm: DEFAULT (define new keyword, ROUND_ROBIN?) + # Client, public facing endpoint + client: + properties: + network_name: PUBLIC + floating: true + dns_name: http://mycompany.com/ + diff --git a/nfvparser/toscaparser/tests/data/node_filter/test_node_filter.yaml b/nfvparser/toscaparser/tests/data/node_filter/test_node_filter.yaml new file mode 100644 index 0000000..3dd8e26 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/node_filter/test_node_filter.yaml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template with requirements against hosting infrastructure. + +topology_template: + + node_templates: + test: + type: tosca.nodes.DBMS + requirements: + - host: + node_filter: + capabilities: + - host: + properties: + - num_cpus: { in_range: [ 1, 4 ] } + - mem_size: { greater_or_equal: 2 GB } + diff --git a/nfvparser/toscaparser/tests/data/policies/custom_definitions.yaml b/nfvparser/toscaparser/tests/data/policies/custom_definitions.yaml new file mode 100644 index 0000000..7f15ade --- /dev/null +++ b/nfvparser/toscaparser/tests/data/policies/custom_definitions.yaml @@ -0,0 +1,10 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +policy_types: + mycompany.mytypes.myScalingPolicy: + derived_from: tosca.policies.Scaling + metadata: + type: map + entry_schema: + type: string + diff --git a/nfvparser/toscaparser/tests/data/policies/tacker_defs.yaml b/nfvparser/toscaparser/tests/data/policies/tacker_defs.yaml new file mode 100644 index 0000000..96b0d45 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/policies/tacker_defs.yaml @@ -0,0 +1,183 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +data_types: + tosca.datatypes.tacker.ActionMap: + properties: + trigger: + type: string + required: true + action: + type: string + required: true + params: + type: map + entry_schema: + type: string + required: false + + tosca.datatypes.tacker.MonitoringParams: + properties: + monitoring_delay: + type: int + required: false + count: + type: int + required: false + interval: + type: int + required: false + timeout: + type: int + required: false + retry: + type: int + required: false + port: + type: int + required: false + + tosca.datatypes.tacker.MonitoringType: + properties: + name: + type: string + required: true + actions: + type: map + required: true + parameters: + type: tosca.datatypes.tacker.MonitoringParams + required: false + + tosca.datatypes.compute_properties: + properties: + num_cpus: + type: integer + required: false + mem_size: + type: string + required: false + disk_size: + type: string + required: false + mem_page_size: + type: string + required: false + numa_node_count: + type: integer + constraints: + - greater_or_equal: 2 + required: false + numa_nodes: + type: map + required: false + cpu_allocation: + type: map + required: false + +policy_types: + tosca.policies.tacker.Placement: + derived_from: tosca.policies.Root + + tosca.policies.tacker.Failure: + derived_from: tosca.policies.Root + action: + type: string + + tosca.policies.tacker.Failure.Respawn: + derived_from: tosca.policies.tacker.Failure + action: respawn + + tosca.policies.tacker.Failure.Terminate: + derived_from: tosca.policies.tacker.Failure + action: log_and_kill + + tosca.policies.tacker.Failure.Log: + derived_from: tosca.policies.tacker.Failure + action: log + + tosca.policies.tacker.Monitoring: + derived_from: tosca.policies.Root + properties: + name: + type: string + required: true + parameters: + type: map + entry_schema: + type: string + required: false + actions: + type: map + entry_schema: + type: string + required: true + + tosca.policies.tacker.Monitoring.NoOp: + derived_from: tosca.policies.tacker.Monitoring + properties: + name: noop + + tosca.policies.tacker.Monitoring.Ping: + derived_from: tosca.policies.tacker.Monitoring + properties: + name: ping + + tosca.policies.tacker.Monitoring.HttpPing: + derived_from: tosca.policies.tacker.Monitoring.Ping + properties: + name: http-ping + + tosca.policies.tacker.Alarming: + derived_from: tosca.policies.Monitoring + triggers: + resize_compute: + event_type: + type: map + entry_schema: + type: string + required: true + metrics: + type: string + required: true + condition: + type: map + entry_schema: + type: string + required: false + action: + type: map + entry_schema: + type: string + required: true + + tosca.policies.tacker.Scaling: + derived_from: tosca.policies.Scaling + description: Defines policy for scaling the given targets. + properties: + increment: + type: integer + required: true + description: Number of nodes to add or remove during the scale out/in. + targets: + type: list + entry_schema: + type: string + required: true + description: List of Scaling nodes. + min_instances: + type: integer + required: true + description: Minimum number of instances to scale in. + max_instances: + type: integer + required: true + description: Maximum number of instances to scale out. + default_instances: + type: integer + required: true + description: Initial number of instances. + cooldown: + type: integer + required: false + default: 120 + description: Wait time (in seconds) between consecutive scaling operations. During the cooldown period... diff --git a/nfvparser/toscaparser/tests/data/policies/tacker_nfv_defs.yaml b/nfvparser/toscaparser/tests/data/policies/tacker_nfv_defs.yaml new file mode 100644 index 0000000..1387509 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/policies/tacker_nfv_defs.yaml @@ -0,0 +1,261 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +data_types: + tosca.nfv.datatypes.pathType: + properties: + forwarder: + type: string + required: true + capability: + type: string + required: true + + tosca.nfv.datatypes.aclType: + properties: + eth_type: + type: string + required: false + eth_src: + type: string + required: false + eth_dst: + type: string + required: false + vlan_id: + type: integer + constraints: + - in_range: [ 1, 4094 ] + required: false + vlan_pcp: + type: integer + constraints: + - in_range: [ 0, 7 ] + required: false + mpls_label: + type: integer + constraints: + - in_range: [ 16, 1048575] + required: false + mpls_tc: + type: integer + constraints: + - in_range: [ 0, 7 ] + required: false + ip_dscp: + type: integer + constraints: + - in_range: [ 0, 63 ] + required: false + ip_ecn: + type: integer + constraints: + - in_range: [ 0, 3 ] + required: false + ip_src_prefix: + type: string + required: false + ip_dst_prefix: + type: string + required: false + ip_proto: + type: integer + constraints: + - in_range: [ 1, 254 ] + required: false + destination_port_range: + type: string + required: false + source_port_range: + type: string + required: false + network_src_port_id: + type: string + required: false + network_dst_port_id: + type: string + required: false + network_id: + type: string + required: false + network_name: + type: string + required: false + tenant_id: + type: string + required: false + icmpv4_type: + type: integer + constraints: + - in_range: [ 0, 254 ] + required: false + icmpv4_code: + type: integer + constraints: + - in_range: [ 0, 15 ] + required: false + arp_op: + type: integer + constraints: + - in_range: [ 1, 25 ] + required: false + arp_spa: + type: string + required: false + arp_tpa: + type: string + required: false + arp_sha: + type: string + required: false + arp_tha: + type: string + required: false + ipv6_src: + type: string + required: false + ipv6_dst: + type: string + required: false + ipv6_flabel: + type: integer + constraints: + - in_range: [ 0, 1048575] + required: false + icmpv6_type: + type: integer + constraints: + - in_range: [ 0, 255] + required: false + icmpv6_code: + type: integer + constraints: + - in_range: [ 0, 7] + required: false + ipv6_nd_target: + type: string + required: false + ipv6_nd_sll: + type: string + required: false + ipv6_nd_tll: + type: string + required: false + + tosca.nfv.datatypes.policyType: + properties: + type: + type: string + required: false + constraints: + - valid_values: [ ACL ] + criteria: + type: list + required: true + entry_schema: + type: tosca.nfv.datatypes.aclType + +node_types: + tosca.nodes.nfv.VDU.Tacker: + derived_from: tosca.nodes.nfv.VDU + capabilities: + nfv_compute: + type: tosca.datatypes.compute_properties + properties: + name: + type: string + required: false + image: +# type: tosca.artifacts.Deployment.Image.VM + type: string + required: false + flavor: + type: string + required: false + availability_zone: + type: string + required: false + metadata: + type: map + entry_schema: + type: string + required: false + config_drive: + type: boolean + default: false + required: false + + placement_policy: +# type: tosca.policies.tacker.Placement + type: string + required: false + + monitoring_policy: +# type: tosca.policies.tacker.Monitoring +# type: tosca.datatypes.tacker.MonitoringType + type: map + required: false + + config: + type: string + required: false + + mgmt_driver: + type: string + default: noop + required: false + + service_type: + type: string + required: false + + user_data: + type: string + required: false + + user_data_format: + type: string + required: false + + key_name: + type: string + required: false + + tosca.nodes.nfv.CP.Tacker: + derived_from: tosca.nodes.nfv.CP + properties: + mac_address: + type: string + required: false + name: + type: string + required: false + management: + type: boolean + required: false + anti_spoofing_protection: + type: boolean + required: false + security_groups: + type: list + required: false + type: + type: string + required: false + constraints: + - valid_values: [ sriov, vnic ] + + tosca.nodes.nfv.FP.Tacker: + derived_from: tosca.nodes.Root + properties: + id: + type: integer + required: false + policy: + type: tosca.nfv.datatypes.policyType + required: true + description: policy to use to match traffic for this FP + path: + type: list + required: true + entry_schema: + type: tosca.nfv.datatypes.pathType diff --git a/nfvparser/toscaparser/tests/data/policies/test_tosca_nfv_multiple_policies.yaml b/nfvparser/toscaparser/tests/data/policies/test_tosca_nfv_multiple_policies.yaml new file mode 100644 index 0000000..452dbb5 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/policies/test_tosca_nfv_multiple_policies.yaml @@ -0,0 +1,95 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: sample-tosca-vnfd-scaling + +imports: + - tacker_defs.yaml + - tacker_nfv_defs.yaml + +metadata: + template_name: sample-tosca-vnfd-scaling + +topology_template: + node_templates: + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + properties: + image: cirros-0.3.4-x86_64-uec + mgmt_driver: noop + availability_zone: nova + flavor: m1.tiny + + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + order: 0 + anti_spoofing_protection: false + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU1 + + VDU2: + type: tosca.nodes.nfv.VDU.Tacker + properties: + image: cirros-0.3.4-x86_64-uec + mgmt_driver: noop + availability_zone: nova + flavor: m1.tiny + + CP2: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + order: 0 + anti_spoofing_protection: false + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU2 + + VL1: + type: tosca.nodes.nfv.VL + properties: + network_name: net_mgmt + vendor: Tacker + + policies: + - SP1: + type: tosca.policies.tacker.Scaling + targets: [VDU1] + properties: + increment: 1 + cooldown: 120 + min_instances: 1 + max_instances: 2 + default_instances: 1 + + - SP2: + type: tosca.policies.tacker.Scaling + targets: [VDU2] + properties: + increment: 1 + cooldown: 120 + min_instances: 1 + max_instances: 2 + default_instances: 1 + + - ALRM1: + type: tosca.policies.tacker.Monitoring + triggers: + resize_compute: + event_type: + type: tosca.events.resource.utilization + implementation: ceilometer + condition: + constraint: 50 + period: 600 + evaluations: 1 + method: avg + action: + resize_compute: + action_name: SP1 diff --git a/nfvparser/toscaparser/tests/data/policies/tosca_policy_template.yaml b/nfvparser/toscaparser/tests/data/policies/tosca_policy_template.yaml new file mode 100644 index 0000000..47f7870 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/policies/tosca_policy_template.yaml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Template for deploying servers based on policies. + +imports: + - custom_definitions.yaml + +topology_template: + node_templates: + my_server_1: + type: tosca.nodes.Compute + capabilities: + # Host container properties + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + # Guest Operating System properties + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: Linux + distribution: RHEL + version: 6.5 + + my_server_2: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 2 + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + groups: + webserver_group: + members: [ my_server_1, my_server_2 ] + type: tosca.groups.Root + metadata: { user1: 1008, user2: 1002 } + + + policies: + - my_compute_placement_policy: + type: tosca.policies.Placement + description: Apply placement policy to servers + metadata: { user1: 1001, user2: 1002 } + targets: [ my_server_1, my_server_2 ] + triggers: + resize_compute: + description: trigger + event_type: tosca.events.resource.utilization + schedule: + start_time: "2015-05-07T07:00:00Z" + end_time: "2015-06-07T07:00:00Z" + target_filter: + node: master-container + requirement: host + capability: Container + condition: + constraint: { greater_than: 50 } + period: 60 + evaluations: 1 + method: average + action: + resize: # Operation name + inputs: + strategy: LEAST_USED + implementation: Senlin.webhook() + - my_groups_placement: + type: mycompany.mytypes.myScalingPolicy + targets: [ webserver_group ] + description: my company scaling policy + metadata: + user1: 1001 + user2: 1003 + diff --git a/nfvparser/toscaparser/tests/data/relationship/test_custom_relationship.yaml b/nfvparser/toscaparser/tests/data/relationship/test_custom_relationship.yaml new file mode 100644 index 0000000..81b92b4 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/relationship/test_custom_relationship.yaml @@ -0,0 +1,48 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Test template for deploying a single server with predefined properties and custom relationship types + +imports: + - ../custom_types/custom_relationship_type_defs.yaml + +topology_template: + node_templates: + server1: + type: tosca.nodes.HACompute + capabilities: + # Host container properties + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + # Guest Operating System properties + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: Linux + distribution: RHEL + version: 6.5 + requirements: + - high_availability: server2 + + server2: + type: tosca.nodes.HACompute + capabilities: + # Host container properties + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + # Guest Operating System properties + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: Linux + distribution: RHEL + version: 6.5 + requirements: + - high_availability: server1 diff --git a/nfvparser/toscaparser/tests/data/repositories/test_repositories_definition.yaml b/nfvparser/toscaparser/tests/data/repositories/test_repositories_definition.yaml new file mode 100644 index 0000000..c2856c8 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/repositories/test_repositories_definition.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +repositories: + some_repository: + description: Some repo + url: https://raw.githubusercontent.com/openstack/tosca-parser/master/toscaparser/tests/data/custom_types/ + credential: #type: Credential + token_type: basic_auth + token: myusername:mypassword +imports: + - some_import: + file: compute_with_prop.yaml + repository: some_repository + +description: > + TOSCA test for testing repositories definition + + node_templates: + + server: + type: tosca.nodes.ComputeWithProp + properties: + test: yes diff --git a/nfvparser/toscaparser/tests/data/repositories/tosca_repositories_test_definition.yaml b/nfvparser/toscaparser/tests/data/repositories/tosca_repositories_test_definition.yaml new file mode 100644 index 0000000..0001d06 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/repositories/tosca_repositories_test_definition.yaml @@ -0,0 +1,26 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile with repositories validation and imports. + +repositories: + repo_code0: https://raw.githubusercontent.com/nandinivemula/intern + repo_code1: + description: My project's code Repository in github usercontent. + url: https://raw.githubusercontent.com/nandinivemula/intern/master + credential: #type: Credential + token_type: basic_auth + token: myusername:mypassword + + repo_code2: + description: My Project's code Repository in github. + url: https://github.com/nandinivemula/intern/master + credential: #type: Credential + token_type: basic_auth + token: myusername:mypassword + +imports: + - sample_import: + file: tosca_repository_import.yaml + repository: repo_code1 + namespace_uri: https://github.com/nandinivemula/intern + namespace_prefix: intern diff --git a/nfvparser/toscaparser/tests/data/requirements/test_requirements.yaml b/nfvparser/toscaparser/tests/data/requirements/test_requirements.yaml new file mode 100644 index 0000000..bb67577 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/requirements/test_requirements.yaml @@ -0,0 +1,67 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Test Requirements. + +imports: + - ../custom_types/wordpress.yaml + +topology_template: + node_templates: + my_app: + description: > + Specify multiple requirement via node and relationship keyword, + as an explicit relationship. Also demonstrates relationship with + type keyword and without it as an in-line reference. + type: tosca.nodes.WebApplication.WordPress + requirements: + - req1: + node: my_webserver + relationship: tosca.relationships.HostedOn + - req2: + node: mysql_database + relationship: + type: tosca.relationships.ConnectsTo + mysql_database: + description: Specify requirement via a capability as an implicit relationship. + type: tosca.nodes.Database + requirements: + - host: + node: my_dbms + relationship: tosca.relationships.HostedOn + my_dbms: + type: tosca.nodes.DBMS + my_webserver: + type: tosca.nodes.WebServer + my_server: + description: > + Specify requirement via a relationship template, as an explicit relationship. + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 4 MB + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: linux + distribution: rhel + version: 6.5 + requirements: + - req1: + node: my_storage + relationship: storage_attachment + my_storage: + type: tosca.nodes.BlockStorage + properties: + size: 1 GiB + snapshot_id: id + + relationship_templates: + storage_attachment: + type: tosca.relationships.AttachesTo + properties: + location: /temp diff --git a/nfvparser/toscaparser/tests/data/test_attributes_inheritance.yaml b/nfvparser/toscaparser/tests/data/test_attributes_inheritance.yaml new file mode 100644 index 0000000..0649c11 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_attributes_inheritance.yaml @@ -0,0 +1,28 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile to test the attribute inheritance + +imports: + - custom_types/compute_with_prop.yaml + +topology_template: + + node_templates: + + server: + type: tosca.nodes.ComputeWithProp + properties: + test: yes + capabilities: + host: + properties: + num_cpus: 1 + mem_size: 1 GB + os: + properties: + type: linux + + outputs: + server_ip: + value: { get_attribute: [ server, public_address ] } + diff --git a/nfvparser/toscaparser/tests/data/test_available_rel_tpls.yaml b/nfvparser/toscaparser/tests/data/test_available_rel_tpls.yaml new file mode 100644 index 0000000..e8d9045 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_available_rel_tpls.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA test for bug 1527214 + +topology_template: + + node_templates: + + test_db: + type: tosca.nodes.Database + requirements: + - host: + node: mysql + + mysql: + type: tosca.nodes.DBMS + requirements: + - host: + node: db_server + + db_server: + type: tosca.nodes.Compute + diff --git a/nfvparser/toscaparser/tests/data/test_containers.yaml b/nfvparser/toscaparser/tests/data/test_containers.yaml new file mode 100644 index 0000000..ba1cc16 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_containers.yaml @@ -0,0 +1,44 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with mysql docker container. + +# Repositories to retrieve code artifacts from +repositories: + docker_hub: https://registry.hub.docker.com/ + +topology_template: + + inputs: + mysql_root_pwd: + type: string + description: Root password for MySQL. + + node_templates: + # The MYSQL container based on official MySQL image in Docker hub + mysql_container: + type: tosca.nodes.Container.Application + requirements: + - host: mysql_runtime + artifacts: + my_image: + file: mysql + type: tosca.artifacts.Deployment.Image.Container.Docker + repository: docker_hub + interfaces: + Standard: + create: + implementation: my_image + inputs: + MYSQL_ROOT_PASSWORD: { get_input: mysql_root_pwd } + + # The properties of the runtime to host the container + mysql_runtime: + type: tosca.nodes.Container.Runtime + capabilities: + host: + properties: + num_cpus: 1 + disk_size: 10 GB + mem_size: 2 MB + diff --git a/nfvparser/toscaparser/tests/data/test_credential_datatype.yaml b/nfvparser/toscaparser/tests/data/test_credential_datatype.yaml new file mode 100644 index 0000000..583ec82 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_credential_datatype.yaml @@ -0,0 +1,77 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with to demonstrate the usage of the + TOSCA Credential Data Type. + +imports: + - custom_types/wordpress.yaml + +relationship_types: + my.types.WordpressDbConnection: + derived_from: tosca.relationships.ConnectsTo + properties: + credential: + user: db_user + token: db_pwd + +topology_template: + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: + node: mysql_database + relationship: my.types.WordpressDbConnection + + mysql_database: + type: tosca.nodes.Database + properties: + name: db_name + user: db_user + password: db_pwd + capabilities: + database_endpoint: + properties: + port: 3306 + requirements: + - host: + node: mysql_dbms + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: db_root_pwd + port: 3306 + requirements: + - host: server + + webserver: + type: tosca.nodes.WebServer + properties: + admin_credential: + user: username + token: some_pass + requirements: + - host: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + website_url: + description: URL for Wordpress wiki. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/test_custom_caps_def.yaml b/nfvparser/toscaparser/tests/data/test_custom_caps_def.yaml new file mode 100644 index 0000000..0b0984a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_custom_caps_def.yaml @@ -0,0 +1,13 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile to test a custom defined capability + +imports: + - custom_types/custom_caps_def.yaml + +topology_template: + + node_templates: + + server: + type: tosca.nodes.SomeNode diff --git a/nfvparser/toscaparser/tests/data/test_custom_relationships.yaml b/nfvparser/toscaparser/tests/data/test_custom_relationships.yaml new file mode 100644 index 0000000..9c8171d --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_custom_relationships.yaml @@ -0,0 +1,48 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Test template for deploying a single server with predefined properties and custom relationship types + +imports: + - custom_types/custom_relationship_type_defs.yaml + +topology_template: + node_templates: + server1: + type: tosca.nodes.HACompute + capabilities: + # Host container properties + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + # Guest Operating System properties + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: Linux + distribution: RHEL + version: 6.5 + requirements: + - high_availability: server2 + + server2: + type: tosca.nodes.HACompute + capabilities: + # Host container properties + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + # Guest Operating System properties + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: Linux + distribution: RHEL + version: 6.5 + requirements: + - high_availability: server1 diff --git a/nfvparser/toscaparser/tests/data/test_endpoint_on_compute.yaml b/nfvparser/toscaparser/tests/data/test_endpoint_on_compute.yaml new file mode 100644 index 0000000..cf2ec94 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_endpoint_on_compute.yaml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + endpoint: + properties: + network_name: PUBLIC diff --git a/nfvparser/toscaparser/tests/data/test_instance_nested_imports.yaml b/nfvparser/toscaparser/tests/data/test_instance_nested_imports.yaml new file mode 100644 index 0000000..6aa9307 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_instance_nested_imports.yaml @@ -0,0 +1,22 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with wordpress, web server and mysql on the same server. + +imports: + - wordpress: custom_types/nested_test_wordpress.yaml + +topology_template: + + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + + testrsyslogtype: + type: tosca.nodes.SoftwareComponent.Rsyslog.TestRsyslogType + + rsyslog: + type: Test2ndRsyslogType + + logstash: + type: tosca.nodes.SoftwareComponent.Logstash diff --git a/nfvparser/toscaparser/tests/data/test_invalid_input_defaults.yaml b/nfvparser/toscaparser/tests/data/test_invalid_input_defaults.yaml new file mode 100644 index 0000000..f8f4ae7 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_invalid_input_defaults.yaml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Test template with default not matching required type. + +topology_template: + inputs: + invalid_default: + type: integer + default: two + valid_default: + type: integer + default: 2 diff --git a/nfvparser/toscaparser/tests/data/test_invalid_section_names.yaml b/nfvparser/toscaparser/tests/data/test_invalid_section_names.yaml new file mode 100644 index 0000000..6241585 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_invalid_section_names.yaml @@ -0,0 +1,25 @@ +tosca_definitions_versions: tosca_simple_yaml_1_0 + +descriptions: > + TOSCA profile with invalid top-level section names. + +import: + - imported.yaml + +topology_templates: + + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 diff --git a/nfvparser/toscaparser/tests/data/test_invalid_template_version.yaml b/nfvparser/toscaparser/tests/data/test_invalid_template_version.yaml new file mode 100644 index 0000000..86dce79 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_invalid_template_version.yaml @@ -0,0 +1,14 @@ +tosca_definitions_version: tosca_xyz + +description: > + Test template with an invalid template version. + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + diff --git a/nfvparser/toscaparser/tests/data/test_multiple_validation_errors.yaml b/nfvparser/toscaparser/tests/data/test_multiple_validation_errors.yaml new file mode 100644 index 0000000..479a1ec --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_multiple_validation_errors.yaml @@ -0,0 +1,128 @@ +tosca_definitions_version: tosca_simple_yaml_1 + +description: > + TOSCA simple profile with wordpress, web server and mysql on the same server. + +imports: + - custom_types/not_there.yaml + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + default: 1 + db_name: + type: string + description: The name of the database. + default: wordpress + db_user: + type: string + description: The user name of the DB user. + default: wp_user + db_pwd: + type: string + description: The WordPress database admin account password. + default: wp_pass + db_root_pwd: + type: string + description: Root password for MySQL. + db_port: + type: PortDef + description: Port for the MySQL database. + default: 3306 + + node_templates: + xyz: + type: tosca.nodes.XYZ + + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirement: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standard: + create: wordpress/wordpress_install.sh + configure: + implementation: wordpress/wordpress_configure.sh + inputs: + wp_db_name: { get_property: [ mysql_database, name ] } + wp_db_user: { get_property: [ mysql_database, user ] } + wp_db_password: { get_property: [ mysql_database, password ] } + + mysql_database: + type: tosca.nodes.Database + properties: + name: { get_input: db_name } + user: { get_input: db_user } + password: { get_input: db_pwd } + capabilities: + database_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: mysql_dbms + interfaces: + Standard: + configure: + implementation: mysql/mysql_database_configure.sh + inputs: + db_name: { get_property: [ SELF, name ] } + db_user: { get_property: [ SELF, user ] } + db_password: { get_property: [ SELF, passwords ] } + db_root_password: { get_property: [ mysql_dbms, root_password ] } + + mysql_dbms: + type1: tosca.nodes.DBMS + properties: + root_password: { get_input: db_root_pwd } + port: { get_input: db_port } + requirements: + - host: server + interfaces: + Standard: + create: + implementation: mysql/mysql_dbms_install.sh + inputs: + db_root_password: { get_property: [ mysql_dbms, root_password ] } + start: mysql/mysql_dbms_start.sh + configure: + implementation: mysql/mysql_dbms_configure.sh + inputs: + db_port: { get_property: [ mysql_dbms, port ] } + + webserver: + type: tosca.nodes.WebServer + requirements: + - host: server1 + - database_endpoint: + node: webserver + relationship: + type1: tosca.relationships.ConnectsTo + interfaces: + Standard: + create: webserver/webserver_install.sh + start: webserver/webserver_start.sh + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + website_url: + description: URL for Wordpress wiki. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/test_no_inputs_in_template.yaml b/nfvparser/toscaparser/tests/data/test_no_inputs_in_template.yaml new file mode 100644 index 0000000..0b9da4c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_no_inputs_in_template.yaml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for testing a template with no inputs. + +metadata: test + +topology_template: + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + + outputs: diff --git a/nfvparser/toscaparser/tests/data/test_no_outputs_in_template.yaml b/nfvparser/toscaparser/tests/data/test_no_outputs_in_template.yaml new file mode 100644 index 0000000..51d42ff --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_no_outputs_in_template.yaml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for testing a template with no outputs. + +topology_template: + inputs: + + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 diff --git a/nfvparser/toscaparser/tests/data/test_node_filter.yaml b/nfvparser/toscaparser/tests/data/test_node_filter.yaml new file mode 100644 index 0000000..3dd8e26 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_node_filter.yaml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template with requirements against hosting infrastructure. + +topology_template: + + node_templates: + test: + type: tosca.nodes.DBMS + requirements: + - host: + node_filter: + capabilities: + - host: + properties: + - num_cpus: { in_range: [ 1, 4 ] } + - mem_size: { greater_or_equal: 2 GB } + diff --git a/nfvparser/toscaparser/tests/data/test_normative_type_properties_override.yaml b/nfvparser/toscaparser/tests/data/test_normative_type_properties_override.yaml new file mode 100644 index 0000000..3c3e272 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_normative_type_properties_override.yaml @@ -0,0 +1,37 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Test template for deploying a server with custom properties for image, + flavor and key_name. This template provides an example of how to + override TOSCA normative type's (e.g. Compute) properties. Here new + properties are injected in the tosca.nodes.myserver which derives from + tosca.nodes.Compute. Note that tosca.nodes.myserver can not be a name of + another normative type (e.g. tosca.nodes.WebServer or tosca.nodes.nfv.VDU) + because that will create conflict while resolving type definition by the + TOSCA Parser. + +node_types: + tosca.nodes.myserver: + derived_from: tosca.nodes.Compute + properties: + key_name: + type: string + image: + type: string + flavor: + type: string + +topology_template: + inputs: + key_name: + type: string + default: inputkey + + node_templates: + my_server: + type: tosca.nodes.myserver + properties: + flavor: m1.medium + image: rhel-6.5-test-image + key_name: + get_input: key_name diff --git a/nfvparser/toscaparser/tests/data/test_repositories_definition.yaml b/nfvparser/toscaparser/tests/data/test_repositories_definition.yaml new file mode 100644 index 0000000..c2856c8 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_repositories_definition.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +repositories: + some_repository: + description: Some repo + url: https://raw.githubusercontent.com/openstack/tosca-parser/master/toscaparser/tests/data/custom_types/ + credential: #type: Credential + token_type: basic_auth + token: myusername:mypassword +imports: + - some_import: + file: compute_with_prop.yaml + repository: some_repository + +description: > + TOSCA test for testing repositories definition + + node_templates: + + server: + type: tosca.nodes.ComputeWithProp + properties: + test: yes diff --git a/nfvparser/toscaparser/tests/data/test_requirements.yaml b/nfvparser/toscaparser/tests/data/test_requirements.yaml new file mode 100644 index 0000000..269c46d --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_requirements.yaml @@ -0,0 +1,67 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Test Requirements. + +imports: + - custom_types/wordpress.yaml + +topology_template: + node_templates: + my_app: + description: > + Specify multiple requirement via node and relationship keyword, + as an explicit relationship. Also demonstrates relationship with + type keyword and without it as an in-line reference. + type: tosca.nodes.WebApplication.WordPress + requirements: + - req1: + node: my_webserver + relationship: tosca.relationships.HostedOn + - req2: + node: mysql_database + relationship: + type: tosca.relationships.ConnectsTo + mysql_database: + description: Specify requirement via a capability as an implicit relationship. + type: tosca.nodes.Database + requirements: + - host: + node: my_dbms + relationship: tosca.relationships.HostedOn + my_dbms: + type: tosca.nodes.DBMS + my_webserver: + type: tosca.nodes.WebServer + my_server: + description: > + Specify requirement via a relationship template, as an explicit relationship. + type: tosca.nodes.Compute + capabilities: + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 4 MB + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: linux + distribution: rhel + version: 6.5 + requirements: + - req1: + node: my_storage + relationship: storage_attachment + my_storage: + type: tosca.nodes.BlockStorage + properties: + size: 1 GiB + snapshot_id: id + + relationship_templates: + storage_attachment: + type: tosca.relationships.AttachesTo + properties: + location: /temp diff --git a/nfvparser/toscaparser/tests/data/test_tosca_custom_rel_with_script.yaml b/nfvparser/toscaparser/tests/data/test_tosca_custom_rel_with_script.yaml new file mode 100644 index 0000000..18a94a3 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_tosca_custom_rel_with_script.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Test template of a custom relationship with a configure script + +topology_template: + + node_templates: + apache: + type: tosca.nodes.WebServer + requirements: + - host: + node: web_server + relationship: my_custom_rel + + web_server: + type: tosca.nodes.Compute + + relationship_templates: + my_custom_rel: + type: HostedOn + interfaces: + Configure: + pre_configure_source: scripts/wp_db_configure.sh diff --git a/nfvparser/toscaparser/tests/data/test_tosca_normative_type_by_shortname.yaml b/nfvparser/toscaparser/tests/data/test_tosca_normative_type_by_shortname.yaml new file mode 100644 index 0000000..c0653e7 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_tosca_normative_type_by_shortname.yaml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with short type name for Compute. + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + default: 2 + + node_templates: + server: + type: Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + + outputs: + server_address: + description: IP address of server instance. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/test_tosca_top_level_error1.yaml b/nfvparser/toscaparser/tests/data/test_tosca_top_level_error1.yaml new file mode 100644 index 0000000..d35c022 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_tosca_top_level_error1.yaml @@ -0,0 +1,2 @@ +description: > + TOSCA simple profile missing version section.
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/test_tosca_top_level_error2.yaml b/nfvparser/toscaparser/tests/data/test_tosca_top_level_error2.yaml new file mode 100644 index 0000000..b3e80f9 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/test_tosca_top_level_error2.yaml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with invalid top-level key: 'node_template'. + +topology_template: + + node_template: + server: + type: tosca.nodes.Compute + diff --git a/nfvparser/toscaparser/tests/data/topology_template/databasesubsystem.yaml b/nfvparser/toscaparser/tests/data/topology_template/databasesubsystem.yaml new file mode 100644 index 0000000..b6e9c42 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/databasesubsystem.yaml @@ -0,0 +1,81 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Database subsystem, which is service template with topology_template, + act as a nested system inside another system and also act as stand + alone service template. + +imports: + - definitions.yaml + +topology_template: + description: Template of a database including its hosting stack. + + inputs: + user: + type: string + description: the user name of database. + default: test + port: + type: integer + description: the port of database. + default: 3306 + name: + type: string + description: the name of database. + default: test + my_cpus: + type: integer + description: Number of CPUs for the server. + default: 2 + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + substitution_mappings: + node_type: example.DatabaseSubsystem + capabilities: + database_endpoint: [ db_app, database_endpoint ] + + node_templates: + db_app: + type: tosca.nodes.Database + properties: + user: { get_input: user } + port: { get_input: port } + name: { get_input: name } + capabilities: + database_endpoint: + properties: + port: 1234 + requirements: + - host: + node: dbms + + dbms: + type: tosca.nodes.DBMS + properties: + port: 3306 + root_password: 123456789 + requirements: + - host: + node: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + groups: + dbserver_group: + members: [ dbms, server ] + type: tosca.groups.Root diff --git a/nfvparser/toscaparser/tests/data/topology_template/definitions.yaml b/nfvparser/toscaparser/tests/data/topology_template/definitions.yaml new file mode 100644 index 0000000..ba5eac1 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/definitions.yaml @@ -0,0 +1,74 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +node_types: + example.QueuingSubsystem: + derived_from: tosca.nodes.SoftwareComponent + properties: + server_ip: + type: string + server_port: + type: integer + attributes: + server_ip: + type: string + server_port: + type: integer + requirements: + - receiver1: + node: example.TransactionSubsystem + capability: example.capabilities.Receiver + relationship: tosca.relationships.ConnectsTo + - receiver2: + node: example.TransactionSubsystem + capability: example.capabilities.Receiver + relationship: tosca.relationships.ConnectsTo + + example.TransactionSubsystem: + properties: + mq_server_ip: + type: string + required: False + receiver_port: + type: integer + required: False + attributes: + receiver_ip: + type: string + receiver_port: + type: integer + capabilities: + message_receiver: + type: example.capabilities.Receiver + requirements: + - database_endpoint: + node: tosca.nodes.Database + capability: tosca.capabilities.Endpoint.Database + relationship: tosca.relationships.ConnectsTo + + example.DatabaseSubsystem: + derived_from: tosca.nodes.Database + + example.SomeApp: + derived_from: tosca.nodes.SoftwareComponent + properties: + admin_user: + type: string + required: False + pool_size: + type: integer + required: False + capabilities: + message_receiver: + type: example.capabilities.Receiver + requirements: + - database: + node: tosca.nodes.Database + capability: tosca.capabilities.Endpoint.Database + relationship: tosca.relationships.ConnectsTo + +capability_types: + example.capabilities.Receiver: + derived_from: tosca.capabilities.Endpoint + properties: + server_ip: + type: string diff --git a/nfvparser/toscaparser/tests/data/topology_template/queuingsubsystem.yaml b/nfvparser/toscaparser/tests/data/topology_template/queuingsubsystem.yaml new file mode 100644 index 0000000..578aa4a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/queuingsubsystem.yaml @@ -0,0 +1,75 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Queue subsystem, which is service template with topology_template, + act as a nested system inside another system and also act as stand + alone service template. + +imports: + - definitions.yaml + +topology_template: + description: Template of a database including its hosting stack. + + inputs: + server_ip: + type: string + description: IP address of the message queuing server to receive messages from. + default: 127.0.0.1 + server_port: + type: integer + description: Port to be used for receiving messages. + default: 8080 + my_cpus: + type: integer + description: Number of CPUs for the server. + default: 2 + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + substitution_mappings: + node_type: example.QueuingSubsystem + # capabilities: + # message_receiver: [ app, message_receiver ] + requirements: + receiver1: [ tran_app, receiver1 ] + receiver2: [ tran_app, receiver2 ] + + node_templates: + tran_app: + type: example.QueuingSubsystem + properties: + server_ip: { get_input: server_ip } + server_port: { get_input: server_port } + requirements: + - host: + node: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + server_ip: + description: server_ip of the message receiver application + value: { get_input: server_ip } + + server_port: + description: server_port of the message receiver application + value: { get_input: server_port } + + groups: + tran_server_group: + members: [ tran_app, server ] + type: tosca.groups.Root diff --git a/nfvparser/toscaparser/tests/data/topology_template/system.yaml b/nfvparser/toscaparser/tests/data/topology_template/system.yaml new file mode 100644 index 0000000..f4e10ae --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/system.yaml @@ -0,0 +1,62 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +imports: + - queuingsubsystem.yaml + - transactionsubsystem.yaml + - databasesubsystem.yaml + +topology_template: + description: Template of online transaction processing service. + + inputs: + mq_server_ip: + type: string + default: 127.0.0.1 + description: IP address of the message queuing server to receive messages from. + mq_server_port: + type: integer + default: 8080 + description: Port to be used for receiving messages. + + node_templates: + mq: + type: example.QueuingSubsystem + properties: + server_ip: { get_input: mq_server_ip } + server_port: { get_input: mq_server_port } + # capabilities: + # message_queue_endpoint: + # to be updated when substitution_mapping is validated later + requirements: + - receiver1: trans1 + - receiver2: trans2 + + trans1: + type: example.TransactionSubsystem + properties: + mq_server_ip: { get_attribute: [ mq, server_ip ] } + receiver_port: { get_attribute: [ mq, server_port ] } + # capabilities: + # message_receiver: + # to be updated when substitution_mapping is validated later + requirements: + - database_endpoint: dbsys + + trans2: + type: example.TransactionSubsystem + properties: + mq_server_ip: { get_attribute: [ mq, server_ip ] } + receiver_port: { get_attribute: [ mq, server_port ] } + # capabilities: + # message_receiver: + # to be updated when substitution_mapping is validated later + requirements: + - database_endpoint: dbsys + + dbsys: + type: example.DatabaseSubsystem + # properties: + # to be updated when substitution_mapping is validated later + # capabilities: + # database_endpoint: + # to be updated when substitution_mapping is validated later diff --git a/nfvparser/toscaparser/tests/data/topology_template/transactionsubsystem.yaml b/nfvparser/toscaparser/tests/data/topology_template/transactionsubsystem.yaml new file mode 100644 index 0000000..42e100a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/transactionsubsystem.yaml @@ -0,0 +1,88 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Transaction subsystem, which is service template with topology_template, + act as a nested system inside another system and also act as stand + alone service template. + +imports: + - definitions.yaml + +topology_template: + description: Template of a database including its hosting stack. + + inputs: + mq_server_ip: + type: string + description: IP address of the message queuing server to receive messages from. + default: 127.0.0.1 + receiver_port: + type: integer + description: Port to be used for receiving messages. + default: 8080 + my_cpus: + type: integer + description: Number of CPUs for the server. + default: 2 + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + substitution_mappings: + node_type: example.TransactionSubsystem + capabilities: + message_receiver: [ app, message_receiver ] + requirements: + database_endpoint: [ app, database ] + + node_templates: + app: + type: example.SomeApp + properties: + admin_user: foo + pool_size: 10 + capabilities: + message_receiver: + properties: + server_ip: { get_input: mq_server_ip } + requirements: + - host: + node: websrv + + websrv: + type: tosca.nodes.WebServer + capabilities: + data_endpoint: + properties: + port_name: { get_input: receiver_port } + requirements: + - host: + node: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + receiver_ip: + description: private IP address of the message receiver application + value: { get_attribute: [ server, private_address ] } + + receiver_port: + description: receiver_port of the message receiver application + value: { get_input: receiver_port } + + groups: + webserver_group: + members: [ websrv, server ] + type: tosca.groups.Root diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/queuingsubsystem_invalid_input.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/queuingsubsystem_invalid_input.yaml new file mode 100644 index 0000000..67ef341 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/queuingsubsystem_invalid_input.yaml @@ -0,0 +1,76 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + This template is a test template which contains invalid input needed for substitution mappings. + The required properties without default value in substituted node template which be mapped must be + as inputs of nested service template which defines substutition mappings, and the inputs of nested + service template which are not in the properties of the substituted node template must provide + default values. + This template provides an additional input of server_port1/my_cpus/my_input which are not defined + in example.QueuingSubsystem, and the default value are 8080/2/123, all of these are right. But the + required property of server_port defined in example.QueuingSubsystem is not appeared in inputs + definiton, so will raise excepton of "MissingRequiredInputError". + +imports: + - ../definitions.yaml + +topology_template: + description: Template of a database including its hosting stack. + + inputs: + server_ip: + type: string + description: IP address of the message queuing server to receive messages from. + default: 127.0.0.1 + server_port1: + type: integer + description: Port to be used for receiving messages. + default: 8080 + my_cpus: + type: integer + description: Number of CPUs for the server. + default: 2 + constraints: + - valid_values: [ 1, 2, 4, 8 ] + my_input: + type: integer + description: test for input validation. + default: 123 + + substitution_mappings: + node_type: example.QueuingSubsystem + + node_templates: + tran_app: + type: example.QueuingSubsystem + properties: + server_ip: { get_input: server_ip } + server_port: { get_input: server_port1 } + requirements: + - host: + node: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + receiver_ip: + description: private IP address of the message receiver application + value: { get_attribute: [ server, private_address ] } + + groups: + tran_server_group: + members: [ tran_app, server ] + type: tosca.groups.Root diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_input.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_input.yaml new file mode 100644 index 0000000..e3cdd71 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_input.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +imports: + - queuingsubsystem_invalid_input.yaml + +topology_template: + description: Test template with invalid input. + + inputs: + mq_server_ip: + type: string + default: 127.0.0.1 + description: IP address of the message queuing server to receive messages from. + mq_server_port: + type: integer + default: 8080 + description: Port to be used for receiving messages. + + node_templates: + mq: + type: example.QueuingSubsystem + properties: + server_ip: { get_input: mq_server_ip } + server_port: { get_input: mq_server_port } diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_missing_output.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_missing_output.yaml new file mode 100644 index 0000000..2028c38 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_missing_output.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +imports: + - transactionsubsystem_invalid_missing_output.yaml + +topology_template: + description: Test template with invalid missing output. + + inputs: + mq_server_ip: + type: string + default: 127.0.0.1 + description: IP address of the message queuing server to receive messages from. + mq_server_port: + type: integer + default: 8080 + description: Port to be used for receiving messages. + + node_templates: + trans: + type: example.TransactionSubsystem + properties: + mq_server_ip: { get_input: mq_server_ip } + receiver_port: { get_input: mq_server_port } diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_unknown_output.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_unknown_output.yaml new file mode 100644 index 0000000..de16ca2 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/system_invalid_unknown_output.yaml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +imports: + - transactionsubsystem_invalid_unknown_output.yaml + +topology_template: + description: Test template with invalid unknown output. + + inputs: + mq_server_ip: + type: string + default: 127.0.0.1 + description: IP address of the message queuing server to receive messages from. + mq_server_port: + type: integer + default: 8080 + description: Port to be used for receiving messages. + + node_templates: + trans: + type: example.TransactionSubsystem + properties: + mq_server_ip: { get_input: mq_server_ip } + receiver_port: { get_input: mq_server_port } diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/test_example_app_substitution_mappings.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/test_example_app_substitution_mappings.yaml new file mode 100644 index 0000000..718022a --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/test_example_app_substitution_mappings.yaml @@ -0,0 +1,70 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Template showing an example TOSCA type to demonstrate usage + of output in the substitution mappings. + +node_types: + example.app: + derived_from: tosca.nodes.WebApplication + properties: + mq_server_ip: + type: string + required: False + receiver_port: + type: integer + required: False + attributes: + receiver_ip: + type: string + receiver_port: + type: integer + +topology_template: + inputs: + mq_server_ip: + type: string + description: IP address of the message queuing server to receive messages from. + default: 127.0.0.1 + receiver_port: + type: integer + description: Port to be used for receiving messages. + default: 8080 + my_cpus: + type: integer + description: Number of CPUs for the server. + default: 2 + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + substitution_mappings: + node_type: example.app + + node_templates: + app: + type: example.app + properties: + mq_server_ip: { get_input: mq_server_ip } + receiver_port: { get_input: receiver_port } + requirements: + - host: + node: websrv + websrv: + type: tosca.nodes.WebServer + requirements: + - host: + node: server + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_invalid_output.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_invalid_output.yaml new file mode 100644 index 0000000..ef21811 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_invalid_output.yaml @@ -0,0 +1,31 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +imports: + - test_example_app_substitution_mappings.yaml + +topology_template: + description: > + Test template showing valid output section containing attribute defined + in the substitution mappings in the imported yaml file. + + inputs: + mq_server_ip: + type: string + default: 127.0.0.1 + description: IP address of the message queuing server to receive messages from. + mq_server_port: + type: integer + default: 8080 + description: Port to be used for receiving messages. + + node_templates: + substitute_app: + type: example.app + properties: + mq_server_ip: { get_input: mq_server_ip } + receiver_port: { get_input: mq_server_port } + + outputs: + receiver_ip: + description: private IP address of the message receiver application + value: { get_attribute: [ substitute_app, my_cpu_output ] }
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_valid_output.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_valid_output.yaml new file mode 100644 index 0000000..766ca87 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/test_substitution_mappings_valid_output.yaml @@ -0,0 +1,31 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +imports: + - test_example_app_substitution_mappings.yaml + +topology_template: + description: > + Test template showing valid output section containing attribute defined + in the substitution mappings in the imported yaml file. + + inputs: + mq_server_ip: + type: string + default: 127.0.0.1 + description: IP address of the message queuing server to receive messages from. + mq_server_port: + type: integer + default: 8080 + description: Port to be used for receiving messages. + + node_templates: + sustitute_app: + type: example.app + properties: + mq_server_ip: { get_input: mq_server_ip } + receiver_port: { get_input: mq_server_port } + + outputs: + receiver_ip: + description: private IP address of the message receiver application + value: { get_attribute: [ sustitute_app, receiver_ip ] }
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/transactionsubsystem_invalid_missing_output.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/transactionsubsystem_invalid_missing_output.yaml new file mode 100644 index 0000000..c92e5f8 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/transactionsubsystem_invalid_missing_output.yaml @@ -0,0 +1,92 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + This template is a test template which contains invalid output + needed for substitution mappings. + The outputs defined by the topology template have to match the + attributes of the node type or the substituted node template, + and the observable attributes of the substituted node template + have to be defined as attributes of the node type or outputs in + the topology template. + But this template misses output of receiver_port which is not + defined in node type of example.TransactionSubsystem, so it will + be validated error for substitution mappings. + +imports: + - ../definitions.yaml + +topology_template: + description: Template of a database including its hosting stack. + + inputs: + mq_server_ip: + type: string + description: IP address of the message queuing server to receive messages from. + default: 127.0.0.1 + receiver_port: + type: integer + description: Port to be used for receiving messages. + default: 8080 + my_cpus: + type: integer + description: Number of CPUs for the server. + default: 2 + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + substitution_mappings: + node_type: example.TransactionSubsystem + capabilities: + message_receiver: [ app, message_receiver ] + requirements: + database_endpoint: [ app, database ] + + node_templates: + app: + type: example.SomeApp + properties: + admin_user: foo + pool_size: 10 + capabilities: + message_receiver: + properties: + server_ip: { get_input: mq_server_ip } + requirements: + - host: + node: websrv + + websrv: + type: tosca.nodes.WebServer + capabilities: + data_endpoint: + properties: + port_name: { get_input: receiver_port } + requirements: + - host: + node: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + receiver_ip: + description: private IP address of the message receiver application + value: { get_attribute: [ server, private_address ] } + + # This output is invalid if comment receiver_out out only for + # substituion mappings +# receiver_port: +# description: receiver_port of the message receiver application +# value: { get_input: receiver_port } diff --git a/nfvparser/toscaparser/tests/data/topology_template/validate/transactionsubsystem_invalid_unknown_output.yaml b/nfvparser/toscaparser/tests/data/topology_template/validate/transactionsubsystem_invalid_unknown_output.yaml new file mode 100644 index 0000000..ffca24b --- /dev/null +++ b/nfvparser/toscaparser/tests/data/topology_template/validate/transactionsubsystem_invalid_unknown_output.yaml @@ -0,0 +1,94 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + This template is a test template which contains invalid output + needed for substitution mappings. + The outputs defined by the topology template have to match the + attributes of the node type or the substituted node template, + and the observable attributes of the substituted node template + have to be defined as attributes of the node type or outputs in + the topology template. + But this template contains output of my_cpu_output which is not + defined in node type of example.TransactionSubsystem, so it will + be validated error for substitution mappings. + +imports: + - ../definitions.yaml + +topology_template: + description: Template of a database including its hosting stack. + + inputs: + mq_server_ip: + type: string + description: IP address of the message queuing server to receive messages from. + default: 127.0.0.1 + receiver_port: + type: integer + description: Port to be used for receiving messages. + default: 8080 + my_cpus: + type: integer + description: Number of CPUs for the server. + default: 2 + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + substitution_mappings: + node_type: example.TransactionSubsystem + capabilities: + message_receiver: [ app, message_receiver ] + requirements: + database_endpoint: [ app, database ] + + node_templates: + app: + type: example.SomeApp + properties: + admin_user: foo + pool_size: 10 + capabilities: + message_receiver: + properties: + server_ip: { get_input: mq_server_ip } + requirements: + - host: + node: websrv + + websrv: + type: tosca.nodes.WebServer + capabilities: + data_endpoint: + properties: + port_name: { get_input: receiver_port } + requirements: + - host: + node: server + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + receiver_ip: + description: private IP address of the message receiver application + value: { get_attribute: [ server, private_address ] } + + receiver_port: + description: receiver_port of the message receiver application + value: { get_input: receiver_port } + + my_cpu_output: + description: this output is only invalid for substitution mappings + value: { get_input: my_cpus } diff --git a/nfvparser/toscaparser/tests/data/tosca_elk.yaml b/nfvparser/toscaparser/tests/data/tosca_elk.yaml new file mode 100644 index 0000000..6fc1756 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_elk.yaml @@ -0,0 +1,217 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + This TOSCA simple profile deploys nodejs, mongodb, elasticsearch, logstash + and kibana each on a separate server with monitoring enabled for nodejs + server where a sample nodejs application is running. The rsyslog and collectd + are installed on a nodejs server. + +imports: + - custom_types/paypalpizzastore_nodejs_app.yaml + - custom_types/elasticsearch.yaml + - custom_types/logstash.yaml + - custom_types/kibana.yaml + - custom_types/collectd.yaml + - custom_types/rsyslog.yaml + +dsl_definitions: + host_capabilities: &host_capabilities + disk_size: 10 GB + num_cpus: { get_input: my_cpus } + mem_size: 4096 MB + os_capabilities: &os_capabilities + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + +topology_template: + inputs: + my_cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + default: 1 + github_url: + type: string + description: The URL to download nodejs. + default: http://github.com/paypal/rest-api-sample-app-nodejs.git + + node_templates: + paypal_pizzastore: + type: tosca.nodes.WebApplication.PayPalPizzaStore + properties: + github_url: { get_input: github_url } + requirements: + - host: nodejs + - database_connection: mongo_db + interfaces: + Standard: + configure: + implementation: nodejs/config.sh + inputs: + github_url: { get_property: [ SELF, github_url ] } + mongodb_ip: { get_attribute: [mongo_server, private_address] } + start: nodejs/start.sh + nodejs: + type: tosca.nodes.WebServer + requirements: + - host: app_server + interfaces: + Standard: + create: nodejs/create.sh + mongo_db: + type: tosca.nodes.Database + requirements: + - host: mongo_dbms + interfaces: + Standard: + create: mongodb/create_database.sh + mongo_dbms: + type: tosca.nodes.DBMS + requirements: + - host: mongo_server + interfaces: + Standard: + create: mongodb/create.sh + configure: + implementation: mongodb/config.sh + inputs: + mongodb_ip: { get_attribute: [mongo_server, private_address] } + start: mongodb/start.sh + elasticsearch: + type: tosca.nodes.SoftwareComponent.Elasticsearch + requirements: + - host: elasticsearch_server + interfaces: + Standard: + create: elasticsearch/create.sh + start: elasticsearch/start.sh + logstash: + type: tosca.nodes.SoftwareComponent.Logstash + requirements: + - host: logstash_server + - search_endpoint: + node: elasticsearch + capability: search_endpoint + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_source: + implementation: logstash/configure_elasticsearch.py + inputs: + elasticsearch_ip: { get_attribute: [elasticsearch_server, private_address] } + interfaces: + Standard: + create: logstash/create.sh + start: logstash/start.sh + kibana: + type: tosca.nodes.SoftwareComponent.Kibana + requirements: + - host: kibana_server + - search_endpoint: elasticsearch + interfaces: + Standard: + create: kibana/create.sh + configure: + implementation: kibana/config.sh + inputs: + elasticsearch_ip: { get_attribute: [elasticsearch_server, private_address] } + kibana_ip: { get_attribute: [kibana_server, private_address] } + start: kibana/start.sh + app_collectd: + type: tosca.nodes.SoftwareComponent.Collectd + requirements: + - host: app_server + - log_endpoint: + node: logstash + capability: log_endpoint + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_target: + implementation: logstash/configure_collectd.py + interfaces: + Standard: + create: collectd/create.sh + configure: + implementation: collectd/config.py + inputs: + logstash_ip: { get_attribute: [logstash_server, private_address] } + start: collectd/start.sh + app_rsyslog: + type: tosca.nodes.SoftwareComponent.Rsyslog + requirements: + - host: app_server + - log_endpoint: + node: logstash + capability: log_endpoint + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_target: + implementation: logstash/configure_rsyslog.py + interfaces: + Standard: + create: rsyslog/create.sh + configure: + implementation: rsyslog/config.sh + inputs: + logstash_ip: { get_attribute: [logstash_server, private_address] } + start: rsyslog/start.sh + app_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + mongo_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + elasticsearch_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + logstash_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + kibana_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + + outputs: + nodejs_url: + description: URL for the nodejs server, http://<IP>:3000 + value: { get_attribute: [ app_server, private_address ] } + mongodb_url: + description: URL for the mongodb server. + value: { get_attribute: [ mongo_server, private_address ] } + elasticsearch_url: + description: URL for the elasticsearch server. + value: { get_attribute: [ elasticsearch_server, private_address ] } + logstash_url: + description: URL for the logstash server. + value: { get_attribute: [ logstash_server, private_address ] } + kibana_url: + description: URL for the kibana server. + value: { get_attribute: [ kibana_server, private_address ] } diff --git a/nfvparser/toscaparser/tests/data/tosca_helloworld.yaml b/nfvparser/toscaparser/tests/data/tosca_helloworld.yaml new file mode 100644 index 0000000..5b913ff --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_helloworld.yaml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template for deploying a single server with predefined properties. + +topology_template: + node_templates: + my_server: + type: tosca.nodes.Compute + capabilities: + # Host container properties + host: + properties: + num_cpus: 2 + disk_size: 10 GB + mem_size: 512 MB + # Guest Operating System properties + os: + properties: + # host Operating System image properties + architecture: x86_64 + type: Linux + distribution: RHEL + version: 6.5 diff --git a/nfvparser/toscaparser/tests/data/tosca_imports_validation.yaml b/nfvparser/toscaparser/tests/data/tosca_imports_validation.yaml new file mode 100644 index 0000000..257beb8 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_imports_validation.yaml @@ -0,0 +1,45 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template to test invalid imports. + +imports: + - custom_types/imported_sample.yaml + +topology_template: + node_templates: + logstash: + type: tosca.nodes.SoftwareComponent.Logstash + requirements: + - search_endpoint: + capability: search_endpoint + relationship: + type: tosca.relationships.ConnectsTo + interfaces: + Configure: + pre_configure_source: + implementation: logstash/configure_elasticsearch.py + inputs: + elasticsearch_ip: { get_attribute: [elasticsearch_server, private_address] } + interfaces: + Standard: + create: logstash/create.sh + start: logstash/start.sh + policies: + - my_compute_placement_policy: + type: tosca.policies.Placement + description: Apply placement policy to servers + metadata: { user1: 1001, user2: 1002 } + targets: [ my_server_1, my_server_2 ] + - my_groups_placement: + type: mycompany.mytypes.myScalingPolicy + targets: [ webserver_group ] + description: my company scaling policy + metadata: + user1: 1001 + user2: 1003 + relationship_templates: + my_custom_rel: + type: test.relation.connects + interfaces: + Configure: + pre_configure_source: scripts/wp_db_configure.sh diff --git a/nfvparser/toscaparser/tests/data/tosca_load_balancer.yaml b/nfvparser/toscaparser/tests/data/tosca_load_balancer.yaml new file mode 100644 index 0000000..2fcdb48 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_load_balancer.yaml @@ -0,0 +1,75 @@ +# Note: this could eventually be translated to a Neutron Load Balancer +# However, in Heat/HOT the preferred way of doing this is creating an Autoscale Group +# +#heat_template_version: 2015-04-30 ... +#resources: +#load_bal_resource: +# type: OS::Neutron::Pool +# properties: +# admin_state_up: Boolean +# description: String +# lb_method: String +# monitors: [Value, Value, ...] +# name: String +# protocol: String +# provider: String +# subnet: String +# vip: { +# "description": String, +# "name": String, +# "connection_limit": Integer, +# "protocol_port": Integer, +# "subnet": String, +# "address": String, +# "admin_state_up": Boolean, +# "session_persistence": +# { +# "cookie_name": String, +# "type": String} +# } +# +# example from: https://gist.github.com/therve/9231701 +# +#resources: +# web_server_group: +# type: AWS::AutoScaling::AutoScalingGroup +# properties: +# AvailabilityZones: [nova] +# LaunchConfigurationName: {get_resource: launch_config} +# MinSize: 1 +# MaxSize: 3 +# LoadBalancerNames: +# - {get_resource: mylb} +# mypool: +# type: OS::Neutron::Pool +# properties: +# protocol: HTTP +# monitors: [{get_resource: mymonitor}] +# subnet_id: {get_param: subnet_id} +# lb_method: ROUND_ROBIN +# vip: +# protocol_port: 80 +# mylb: +# type: OS::Neutron::LoadBalancer +# properties: +# protocol_port: 80 +# pool_id: {get_resource: mypool} + +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: Template for deploying a load balancer with predefined endpoint properties. + +topology_template: + node_templates: + simple_load_balancer: + type: tosca.nodes.LoadBalancer + capabilities: + # properties: + # algorithm: DEFAULT (define new keyword, ROUND_ROBIN?) + # Client, public facing endpoint + client: + properties: + network_name: PUBLIC + floating: true + dns_name: http://mycompany.com/ + diff --git a/nfvparser/toscaparser/tests/data/tosca_repositories_test_definition.yaml b/nfvparser/toscaparser/tests/data/tosca_repositories_test_definition.yaml new file mode 100644 index 0000000..0001d06 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_repositories_test_definition.yaml @@ -0,0 +1,26 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile with repositories validation and imports. + +repositories: + repo_code0: https://raw.githubusercontent.com/nandinivemula/intern + repo_code1: + description: My project's code Repository in github usercontent. + url: https://raw.githubusercontent.com/nandinivemula/intern/master + credential: #type: Credential + token_type: basic_auth + token: myusername:mypassword + + repo_code2: + description: My Project's code Repository in github. + url: https://github.com/nandinivemula/intern/master + credential: #type: Credential + token_type: basic_auth + token: myusername:mypassword + +imports: + - sample_import: + file: tosca_repository_import.yaml + repository: repo_code1 + namespace_uri: https://github.com/nandinivemula/intern + namespace_prefix: intern diff --git a/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml b/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml new file mode 100644 index 0000000..9e686ab --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress.yaml @@ -0,0 +1,121 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with wordpress, web server and mysql on the same server. + +imports: + - custom_types/wordpress.yaml + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + default: 1 + db_name: + type: string + description: The name of the database. + default: wordpress + db_user: + type: string + description: The user name of the DB user. + default: wp_user + db_pwd: + type: string + description: The WordPress database admin account password. + default: wp_pass + db_root_pwd: + type: string + description: Root password for MySQL. + db_port: + type: PortDef + description: Port for the MySQL database. + default: 3306 + + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standard: + create: wordpress/wordpress_install.sh + configure: + implementation: wordpress/wordpress_configure.sh + inputs: + wp_db_name: { get_property: [ mysql_database, name ] } + wp_db_user: { get_property: [ mysql_database, user ] } + wp_db_password: { get_property: [ mysql_database, password ] } + + mysql_database: + type: tosca.nodes.Database + properties: + name: { get_input: db_name } + user: { get_input: db_user } + password: { get_input: db_pwd } + capabilities: + database_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: mysql_dbms + interfaces: + Standard: + configure: + implementation: mysql/mysql_database_configure.sh + inputs: + db_name: { get_property: [ SELF, name ] } + db_user: { get_property: [ SELF, user ] } + db_password: { get_property: [ SELF, password ] } + db_root_password: { get_property: [ mysql_dbms, root_password ] } + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: { get_input: db_root_pwd } + port: { get_input: db_port } + requirements: + - host: server + interfaces: + Standard: + create: + implementation: mysql/mysql_dbms_install.sh + inputs: + db_root_password: { get_property: [ mysql_dbms, root_password ] } + start: mysql/mysql_dbms_start.sh + configure: + implementation: mysql/mysql_dbms_configure.sh + inputs: + db_port: { get_property: [ mysql_dbms, port ] } + + webserver: + type: tosca.nodes.WebServer + requirements: + - host: server + interfaces: + Standard: + create: webserver/webserver_install.sh + start: webserver/webserver_start.sh + + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + website_url: + description: URL for Wordpress wiki. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml b/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml new file mode 100644 index 0000000..6caac11 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress_with_local_abspath_import.yaml @@ -0,0 +1,122 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with wordpress, web server and mysql on the same server. + Parsing of this test template will fail with errors if provided imports does + not refer to a valid absolute path. + +imports: + - /tmp/tosca-parser/toscaparser/tests/data/custom_types/wordpress.yaml + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + default: 1 + db_name: + type: string + description: The name of the database. + default: wordpress + db_user: + type: string + description: The user name of the DB user. + default: wp_user + db_pwd: + type: string + description: The WordPress database admin account password. + default: wp_pass + db_root_pwd: + type: string + description: Root password for MySQL. + db_port: + type: PortDef + description: Port for the MySQL database. + default: 3306 + + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standard: + create: wordpress/wordpress_install.sh + configure: + implementation: wordpress/wordpress_configure.sh + inputs: + wp_db_name: wordpress + wp_db_user: wp_user + wp_db_password: wp_pass + + mysql_database: + type: tosca.nodes.Database + properties: + name: { get_input: db_name } + user: { get_input: db_user } + password: { get_input: db_pwd } + capabilities: + database_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: + node: mysql_dbms + interfaces: + Standard: + configure: + implementation: mysql/mysql_database_configure.sh + inputs: + db_name: wordpress + db_user: wp_user + db_password: wp_pass + db_root_password: passw0rd + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: { get_input: db_root_pwd } + port: { get_input: db_port } + requirements: + - host: server + interfaces: + Standard: + create: + implementation: mysql/mysql_dbms_install.sh + inputs: + db_root_password: passw0rd + start: mysql/mysql_dbms_start.sh + configure: + implementation: mysql/mysql_dbms_configure.sh + inputs: + db_port: 3366 + + webserver: + type: tosca.nodes.WebServer + requirements: + - host: server + interfaces: + Standard: + create: webserver/webserver_install.sh + start: webserver/webserver_start.sh + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + website_url: + description: URL for Wordpress wiki. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml b/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml new file mode 100644 index 0000000..e5f1580 --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_single_instance_wordpress_with_url_import.yaml @@ -0,0 +1,120 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with wordpress, web server and mysql on the same server. + +imports: + - https://raw.githubusercontent.com/openstack/heat-translator/master/translator/tests/data/custom_types/wordpress.yaml + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + default: 1 + db_name: + type: string + description: The name of the database. + default: wordpress + db_user: + type: string + description: The user name of the DB user. + default: wp_user + db_pwd: + type: string + description: The WordPress database admin account password. + default: wp_pass + db_root_pwd: + type: string + description: Root password for MySQL. + db_port: + type: PortDef + description: Port for the MySQL database. + default: 3306 + + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standard: + create: wordpress/wordpress_install.sh + configure: + implementation: wordpress/wordpress_configure.sh + inputs: + wp_db_name: wordpress + wp_db_user: wp_user + wp_db_password: wp_pass + + mysql_database: + type: tosca.nodes.Database + properties: + name: { get_input: db_name } + user: { get_input: db_user } + password: { get_input: db_pwd } + capabilities: + database_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: + node: mysql_dbms + interfaces: + Standard: + configure: + implementation: mysql/mysql_database_configure.sh + inputs: + db_name: wordpress + db_user: wp_user + db_password: wp_pass + db_root_password: passw0rd + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: { get_input: db_root_pwd } + port: { get_input: db_port } + requirements: + - host: server + interfaces: + Standard: + create: + implementation: mysql/mysql_dbms_install.sh + inputs: + db_root_password: passw0rd + start: mysql/mysql_dbms_start.sh + configure: + implementation: mysql/mysql_dbms_configure.sh + inputs: + db_port: 3366 + + webserver: + type: tosca.nodes.WebServer + requirements: + - host: server + interfaces: + Standard: + create: webserver/webserver_install.sh + start: webserver/webserver_start.sh + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + + outputs: + website_url: + description: URL for Wordpress wiki. + value: { get_attribute: [server, private_address] } diff --git a/nfvparser/toscaparser/tests/data/tosca_test_get_operation_output.yaml b/nfvparser/toscaparser/tests/data/tosca_test_get_operation_output.yaml new file mode 100644 index 0000000..f47f33c --- /dev/null +++ b/nfvparser/toscaparser/tests/data/tosca_test_get_operation_output.yaml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: TOSCA simple profile to test the GET OPERATION OUTPUT functionality + +imports: + - custom_types/compute_with_prop.yaml + +topology_template: + + node_templates: + + front_end: + type: tosca.nodes.ComputeWithProp + interfaces: + Standard: + create: + implementation: nodejs/create.sh + inputs: + data_dir: {get_operation_output: [front_end,Standard,create,data_dir]} diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_one_network.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_one_network.yaml new file mode 100644 index 0000000..8e58fa9 --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_one_network.yaml @@ -0,0 +1,43 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with 1 server bound to a new network + +topology_template: + + inputs: + network_name: + type: string + description: Network name + + node_templates: + my_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 512 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: CirrOS + version: 0.3.2 + + my_network: + type: tosca.nodes.network.Network + properties: + network_name: { get_input: network_name } + ip_version: 4 + cidr: '192.168.0.0/24' + start_ip: '192.168.0.50' + end_ip: '192.168.0.200' + gateway_ip: '192.168.0.1' + + my_port: + type: tosca.nodes.network.Port + requirements: + - binding: my_server + - link: my_network diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_three_networks.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_three_networks.yaml new file mode 100644 index 0000000..d791b17 --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_one_server_three_networks.yaml @@ -0,0 +1,64 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with 1 server bound to 3 networks + +topology_template: + + node_templates: + my_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 512 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: CirrOS + version: 0.3.2 + + my_network1: + type: tosca.nodes.network.Network + properties: + cidr: '192.168.1.0/24' + network_name: net1 + + my_network2: + type: tosca.nodes.network.Network + properties: + cidr: '192.168.2.0/24' + network_name: net2 + + my_network3: + type: tosca.nodes.network.Network + properties: + cidr: '192.168.3.0/24' + network_name: net3 + + my_port1: + type: tosca.nodes.network.Port + properties: + order: 0 + requirements: + - binding: my_server + - link: my_network1 + + my_port2: + type: tosca.nodes.network.Port + properties: + order: 1 + requirements: + - binding: my_server + - link: my_network2 + + my_port3: + type: tosca.nodes.network.Port + properties: + order: 2 + requirements: + - binding: my_server + - link: my_network3 diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_server_on_existing_network.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_server_on_existing_network.yaml new file mode 100644 index 0000000..7fedc13 --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_server_on_existing_network.yaml @@ -0,0 +1,39 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with 1 server bound to an existing network + +topology_template: + inputs: + network_name: + type: string + description: Network name + + node_templates: + my_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 512 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: CirrOS + version: 0.3.2 + + my_network: + type: tosca.nodes.network.Network + properties: + network_name: { get_input: network_name } + + my_port: + type: tosca.nodes.network.Port + requirements: + - binding: + node: my_server + - link: + node: my_network diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_two_servers_one_network.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_two_servers_one_network.yaml new file mode 100644 index 0000000..1473a8d --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/network/tosca_two_servers_one_network.yaml @@ -0,0 +1,79 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with 2 servers bound to the 1 network + +topology_template: + + inputs: + network_name: + type: string + description: Network name + network_cidr: + type: string + default: 10.0.0.0/24 + description: CIDR for the network + network_start_ip: + type: string + default: 10.0.0.100 + description: Start IP for the allocation pool + network_end_ip: + type: string + default: 10.0.0.150 + description: End IP for the allocation pool + + node_templates: + my_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 512 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: CirrOS + version: 0.3.2 + + my_server2: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: 1 + mem_size: 512 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: CirrOS + version: 0.3.2 + + my_network: + type: tosca.nodes.network.Network + properties: + ip_version: 4 + cidr: { get_input: network_cidr } + network_name: { get_input: network_name } + start_ip: { get_input: network_start_ip } + end_ip: { get_input: network_end_ip } + + my_port: + type: tosca.nodes.network.Port + requirements: + - binding: + node: my_server + - link: + node: my_network + + my_port2: + type: tosca.nodes.network.Port + requirements: + - binding: + node: my_server2 + - link: + node: my_network diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment.yaml new file mode 100644 index 0000000..460fa4c --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment.yaml @@ -0,0 +1,61 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with server and attached block storage using the normative AttachesTo Relationship Type. + +topology_template: + + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + storage_size: + type: scalar-unit.size + description: Size of the storage to be created. + default: 1 GB + storage_snapshot_id: + type: string + description: > + Optional identifier for an existing snapshot to use when creating storage. + storage_location: + type: string + description: Block storage mount point (filesystem path). + + node_templates: + my_server: + type: Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 kB + os: + properties: + architecture: x86_64 + type: linux + distribution: fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + relationship: + type: AttachesTo + properties: + location: { get_input: storage_location } + + my_storage: + type: BlockStorage + properties: + size: { get_input: storage_size } + snapshot_id: { get_input: storage_snapshot_id } + + outputs: + private_ip: + description: The private IP address of the newly created compute instance. + value: { get_attribute: [my_server, private_address] } + volume_id: + description: The volume id of the block storage instance. + value: { get_attribute: [my_storage, volume_id] } diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation1.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation1.yaml new file mode 100644 index 0000000..df22d72 --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation1.yaml @@ -0,0 +1,87 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with a Single Block Storage node shared by 2-Tier Application with custom AttachesTo Type and implied relationships. + +relationship_types: + MyAttachesTo: + derived_from: tosca.relationships.AttachesTo + properties: + location: + type: string + default: /default_location + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + storage_size: + type: scalar-unit.size + default: 1 GB + description: Size of the storage to be created. + storage_snapshot_id: + type: string + description: > + Optional identifier for an existing snapshot to use when creating storage. + + node_templates: + my_web_app_tier_1: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + relationship: MyAttachesTo + + my_web_app_tier_2: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + relationship: + type: MyAttachesTo + properties: + location: /some_other_data_location + + my_storage: + type: tosca.nodes.BlockStorage + properties: + size: { get_input: storage_size } + snapshot_id: { get_input: storage_snapshot_id } + + outputs: + private_ip_1: + description: The private IP address of the application's first tier. + value: { get_attribute: [my_web_app_tier_1, private_address] } + private_ip_2: + description: The private IP address of the application's second tier. + value: { get_attribute: [my_web_app_tier_2, private_address] } + volume_id: + description: The volume id of the block storage instance. + value: { get_attribute: [my_storage, volume_id] } diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation2.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation2.yaml new file mode 100644 index 0000000..cb1c17a --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_attachment_notation2.yaml @@ -0,0 +1,99 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with a single Block Storage node shared by 2-Tier Application with custom AttachesTo Type and explicit Relationship Templates. + +relationship_types: + MyAttachesTo: + derived_from: tosca.relationships.AttachesTo + properties: + location: + type: string + default: /default_location + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + storage_size: + type: scalar-unit.size + default: 1 GB + description: Size of the storage to be created. + storage_snapshot_id: + type: string + description: > + Optional identifier for an existing snapshot to use when creating storage. + storage_location: + type: string + description: > + Block storage mount point (filesystem path). + + node_templates: + + my_web_app_tier_1: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 kB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + relationship: storage_attachesto_1 + + my_web_app_tier_2: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 kB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + relationship: storage_attachesto_2 + + my_storage: + type: tosca.nodes.BlockStorage + properties: + size: { get_input: storage_size } + snapshot_id: { get_input: storage_snapshot_id } + + relationship_templates: + storage_attachesto_1: + type: MyAttachesTo + properties: + location: /my_data_location + + storage_attachesto_2: + type: MyAttachesTo + properties: + location: /some_other_data_location + outputs: + private_ip_1: + description: The private IP address of the application's first tier. + value: { get_attribute: [my_web_app_tier_1, private_address] } + private_ip_2: + description: The private IP address of the application's second tier. + value: { get_attribute: [my_web_app_tier_2, private_address] } + volume_id: + description: The volume id of the block storage instance. + value: { get_attribute: [my_storage, volume_id] } diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_custom_relationship_type.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_custom_relationship_type.yaml new file mode 100644 index 0000000..932f89e --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_custom_relationship_type.yaml @@ -0,0 +1,64 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with server and attached block storage using a custom AttachesTo Relationship Type. + +relationship_types: + MyCustomAttachesTo: + derived_from: AttachesTo + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + storage_size: + type: scalar-unit.size + description: Size of the storage to be created. + default: 1 GB + storage_snapshot_id: + type: string + description: > + Optional identifier for an existing snapshot to use when creating storage. + storage_location: + type: string + description: Block storage mount point (filesystem path). + + node_templates: + my_server: + type: Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + # Declare custom AttachesTo type using the 'relationship' keyword + relationship: + type: MyCustomAttachesTo + properties: + location: { get_input: storage_location } + my_storage: + type: BlockStorage + properties: + size: { get_input: storage_size } + snapshot_id: { get_input: storage_snapshot_id } + + outputs: + private_ip: + description: The private IP address of the newly created compute instance. + value: { get_attribute: [my_server, private_address] } + volume_id: + description: The volume id of the block storage instance. + value: { get_attribute: [my_storage, volume_id] } diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_relationship_template.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_relationship_template.yaml new file mode 100644 index 0000000..c31a4da --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_blockstorage_with_relationship_template.yaml @@ -0,0 +1,59 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with server and attached block storage using a named Relationship Template for the storage attachment. + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + storage_size: + type: scalar-unit.size + description: Size of the storage to be created. + default: 1 GB + storage_location: + type: string + description: Block storage mount point (filesystem path). + + node_templates: + my_server: + type: Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + # Declare template to use with 'relationship' keyword + relationship: storage_attachment + + my_storage: + type: BlockStorage + properties: + size: { get_input: storage_size } + + relationship_templates: + storage_attachment: + type: AttachesTo + properties: + location: { get_input: storage_location } + + outputs: + private_ip: + description: The private IP address of the newly created compute instance. + value: { get_attribute: [my_server, private_address] } + volume_id: + description: The volume id of the block storage instance. + value: { get_attribute: [my_storage, volume_id] } diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_multiple_blockstorage_with_attachment.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_multiple_blockstorage_with_attachment.yaml new file mode 100644 index 0000000..aa4647e --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_multiple_blockstorage_with_attachment.yaml @@ -0,0 +1,93 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with 2 servers each with different attached block storage. + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + storage_size: + type: scalar-unit.size + default: 1 GB + description: Size of the storage to be created. + storage_snapshot_id: + type: string + description: > + Optional identifier for an existing snapshot to use when creating storage. + storage_location: + type: string + description: > + Block storage mount point (filesystem path). + + node_templates: + my_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage + relationship: + type: AttachesTo + properties: + location: { get_input: storage_location } + my_storage: + type: tosca.nodes.BlockStorage + properties: + size: { get_input: storage_size } + snapshot_id: { get_input: storage_snapshot_id } + + my_server2: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + requirements: + - local_storage: + node: my_storage2 + relationship: + type: AttachesTo + properties: + location: { get_input: storage_location } + my_storage2: + type: tosca.nodes.BlockStorage + properties: + size: { get_input: storage_size } + snapshot_id: { get_input: storage_snapshot_id } + + outputs: + server_ip_1: + description: The private IP address of the application's first server. + value: { get_attribute: [my_server, private_address] } + server_ip_2: + description: The private IP address of the application's second server. + value: { get_attribute: [my_server2, private_address] } + volume_id_1: + description: The volume id of the first block storage instance. + value: { get_attribute: [my_storage, volume_id] } + volume_id_2: + description: The volume id of the second block storage instance. + value: { get_attribute: [my_storage2, volume_id] } diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_single_object_store.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_single_object_store.yaml new file mode 100644 index 0000000..869af48 --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/storage/tosca_single_object_store.yaml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + Tosca template for creating an object storage service. + +topology_template: + inputs: + objectstore_name: + type: string + + node_templates: + obj_store_server: + type: tosca.nodes.ObjectStorage + properties: + name: { get_input: objectstore_name } + size: 1024 kB + maxsize: 1 GB diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/tosca_nodejs_mongodb_two_instances.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/tosca_nodejs_mongodb_two_instances.yaml new file mode 100644 index 0000000..f611071 --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/tosca_nodejs_mongodb_two_instances.yaml @@ -0,0 +1,96 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile with nodejs and mongodb. + +imports: + - custom_types/paypalpizzastore_nodejs_app.yaml + +dsl_definitions: + host_capabilities: &host_capabilities + disk_size: 10 GB + num_cpus: 1 + mem_size: 4096 MB + os_capabilities: &os_capabilities + architecture: x86_64 + type: Linux + distribution: Ubuntu + version: 14.04 + +topology_template: + inputs: + my_cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + default: 1 + github_url: + type: string + description: The URL to download nodejs. + default: http://github.com/paypal/rest-api-sample-app-nodejs.git + + node_templates: + paypal_pizzastore: + type: tosca.nodes.WebApplication.PayPalPizzaStore + properties: + github_url: { get_input: github_url } + requirements: + - host: nodejs + - database_connection: mongo_db + interfaces: + Standard: + configure: + implementation: nodejs/config.sh + inputs: + github_url: http://github.com/paypal/rest-api-sample-app-nodejs.git + mongodb_ip: { get_attribute: [mongo_server, private_address] } + start: nodejs/start.sh + nodejs: + type: tosca.nodes.WebServer + requirements: + - host: app_server + interfaces: + Standard: + create: nodejs/create.sh + mongo_db: + type: tosca.nodes.Database + requirements: + - host: mongo_dbms + interfaces: + Standard: + create: mongodb/create_database.sh + mongo_dbms: + type: tosca.nodes.DBMS + requirements: + - host: mongo_server + interfaces: + Standard: + create: mongodb/create.sh + configure: + implementation: mongodb/config.sh + inputs: + mongodb_ip: { get_attribute: [mongo_server, private_address] } + start: mongodb/start.sh + mongo_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + app_server: + type: tosca.nodes.Compute + capabilities: + host: + properties: *host_capabilities + os: + properties: *os_capabilities + + outputs: + nodejs_url: + description: URL for the nodejs server, http://<IP>:3000 + value: { get_attribute: [app_server, private_address] } + mongodb_url: + description: URL for the mongodb server. + value: { get_attribute: [mongo_server, private_address] } diff --git a/nfvparser/toscaparser/tests/spec_samples/v1.0/tosca_single_server.yaml b/nfvparser/toscaparser/tests/spec_samples/v1.0/tosca_single_server.yaml new file mode 100644 index 0000000..c4cce9d --- /dev/null +++ b/nfvparser/toscaparser/tests/spec_samples/v1.0/tosca_single_server.yaml @@ -0,0 +1,32 @@ +tosca_definitions_version: tosca_simple_yaml_1_0 + +description: > + TOSCA simple profile that just defines a single compute instance and selects a (guest) host Operating System from the Compute node's properties. Note, this example does not include default values on inputs properties. + +topology_template: + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4, 8 ] + + node_templates: + my_server: + type: Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: ubuntu + version: 12.04 + outputs: + private_ip: + description: The private IP address of the deployed server instance. + value: { get_attribute: [my_server, private_address] }
\ No newline at end of file diff --git a/nfvparser/toscaparser/tests/test_constraints.py b/nfvparser/toscaparser/tests/test_constraints.py new file mode 100644 index 0000000..07cb910 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_constraints.py @@ -0,0 +1,373 @@ +# 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 datetime +import yaml + +from toscaparser.common import exception +from toscaparser.elements.constraints import Constraint +from toscaparser.elements.constraints import Schema +from toscaparser.tests.base import TestCase +from toscaparser.utils.gettextutils import _ +from toscaparser.utils import yamlparser + + +class ConstraintTest(TestCase): + + def test_schema_dict(self): + tpl_snippet = ''' + cpus: + type: integer + description: Number of CPUs for the server. + ''' + schema = yamlparser.simple_parse(tpl_snippet) + cpus_schema = Schema('cpus', schema['cpus']) + self.assertEqual(len(cpus_schema), 2) + self.assertEqual('integer', cpus_schema.type) + self.assertEqual('Number of CPUs for the server.', + cpus_schema.description) + self.assertEqual(True, cpus_schema.required) + self.assertIsNone(cpus_schema.default) + + def test_schema_not_dict(self): + tpl_snippet = ''' + cpus: + - type: integer + - description: Number of CPUs for the server. + ''' + schema = yamlparser.simple_parse(tpl_snippet) + error = self.assertRaises(exception.InvalidSchemaError, Schema, + 'cpus', schema['cpus']) + self.assertEqual(_('Schema definition of "cpus" must be a dict.'), + str(error)) + + def test_schema_miss_type(self): + tpl_snippet = ''' + cpus: + description: Number of CPUs for the server. + ''' + schema = yamlparser.simple_parse(tpl_snippet) + error = self.assertRaises(exception.InvalidSchemaError, Schema, + 'cpus', schema['cpus']) + self.assertEqual(_('Schema definition of "cpus" must have a "type" ' + 'attribute.'), str(error)) + + def test_schema_none_description(self): + tpl_snippet = ''' + cpus: + type: integer + ''' + schema = yamlparser.simple_parse(tpl_snippet) + cpus_schema = Schema('cpus', schema['cpus']) + self.assertEqual('', cpus_schema.description) + + def test_invalid_constraint_type(self): + schema = {'invalid_type': 2} + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('Invalid property "invalid_type".'), + str(error)) + + def test_invalid_prop_type(self): + schema = {'length': 5} + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('Property "length" is not valid for data type ' + '"integer".'), str(error)) + + def test_invalid_validvalues(self): + schema = {'valid_values': 2} + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('The property "valid_values" expects a list.'), + str(error)) + + def test_validvalues_validate(self): + schema = {'valid_values': [2, 4, 6, 8]} + constraint = Constraint('prop', Schema.INTEGER, schema) + self.assertIsNone(constraint.validate(4)) + + def test_validvalues_validate_fail(self): + schema = {'valid_values': [2, 4, 6, 8]} + constraint = Constraint('prop', Schema.INTEGER, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 5) + self.assertEqual(_('The value "5" of property "prop" is not valid. ' + 'Expected a value from "[2, 4, 6, 8]".'), + str(error)) + + def test_invalid_in_range(self): + snippet = 'in_range: {2, 6}' + schema = yaml.load(snippet) + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('The property "in_range" expects a list.'), + str(error)) + + def test_in_range_min_max(self): + schema = {'in_range': [2, 6]} + constraint = Constraint('prop', Schema.INTEGER, schema) + self.assertEqual(2, constraint.min) + self.assertEqual(6, constraint.max) + + def test_in_range_validate(self): + schema = {'in_range': [2, 6]} + constraint = Constraint('prop', Schema.INTEGER, schema) + self.assertIsNone(constraint.validate(2)) + self.assertIsNone(constraint.validate(4)) + self.assertIsNone(constraint.validate(6)) + + def test_in_range_validate_fail(self): + schema = {'in_range': [2, 6]} + constraint = Constraint('prop', Schema.INTEGER, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 8) + self.assertEqual(_('The value "8" of property "prop" is out of range ' + '"(min:2, max:6)".'), str(error)) + + def test_equal_validate(self): + schema = {'equal': 4} + constraint = Constraint('prop', Schema.INTEGER, schema) + self.assertIsNone(constraint.validate(4)) + + def test_equal_validate_fail(self): + schema = {'equal': 4} + constraint = Constraint('prop', Schema.INTEGER, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 8) + self.assertEqual('The value "8" of property "prop" is not equal to ' + '"4".', str(error)) + + def test_greater_than_validate(self): + schema = {'greater_than': 4} + constraint = Constraint('prop', Schema.INTEGER, schema) + self.assertIsNone(constraint.validate(6)) + + def test_greater_than_validate_fail(self): + schema = {'greater_than': 4} + constraint = Constraint('prop', Schema.INTEGER, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 3) + self.assertEqual(_('The value "3" of property "prop" must be greater ' + 'than "4".'), str(error)) + + error = self.assertRaises(exception.ValidationError, + constraint.validate, 4) + self.assertEqual(_('The value "4" of property "prop" must be greater ' + 'than "4".'), str(error)) + + def test_greater_than_invalid(self): + snippet = 'greater_than: {4}' + schema = yaml.load(snippet) + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('The property "greater_than" expects comparable ' + 'values.'), str(error)) + + def test_greater_or_equal_validate(self): + schema = {'greater_or_equal': 3.9} + constraint = Constraint('prop', Schema.FLOAT, schema) + self.assertIsNone(constraint.validate(3.9)) + self.assertIsNone(constraint.validate(4.0)) + + def test_greater_or_equal_validate_fail(self): + schema = {'greater_or_equal': 3.9} + constraint = Constraint('prop', Schema.FLOAT, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 3.0) + self.assertEqual(_('The value "3.0" of property "prop" must be ' + 'greater than or equal to "3.9".'), + str(error)) + + error = self.assertRaises(exception.ValidationError, + constraint.validate, 3.8) + self.assertEqual(_('The value "3.8" of property "prop" must be ' + 'greater than or equal to "3.9".'), + str(error)) + + def test_greater_or_equal_invalid(self): + snippet = 'greater_or_equal: {3.9}' + schema = yaml.load(snippet) + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('The property "greater_or_equal" expects ' + 'comparable values.'), str(error)) + + def test_less_than_validate(self): + schema = {'less_than': datetime.date(2014, 0o7, 25)} + constraint = Constraint('prop', Schema.TIMESTAMP, schema) + self.assertIsNone(constraint.validate(datetime.date(2014, 0o7, 20))) + self.assertIsNone(constraint.validate(datetime.date(2014, 0o7, 24))) + + def test_less_than_validate_fail(self): + schema = {'less_than': datetime.date(2014, 0o7, 25)} + constraint = Constraint('prop', Schema.TIMESTAMP, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, + datetime.date(2014, 0o7, 25)) + self.assertEqual(_('The value "2014-07-25" of property "prop" must be ' + 'less than "2014-07-25".'), + str(error)) + + error = self.assertRaises(exception.ValidationError, + constraint.validate, + datetime.date(2014, 0o7, 27)) + self.assertEqual(_('The value "2014-07-27" of property "prop" must be ' + 'less than "2014-07-25".'), + str(error)) + + def test_less_than_invalid(self): + snippet = 'less_than: {3.9}' + schema = yaml.load(snippet) + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('The property "less_than" expects comparable ' + 'values.'), str(error)) + + def test_less_or_equal_validate(self): + schema = {'less_or_equal': 4} + constraint = Constraint('prop', Schema.INTEGER, schema) + self.assertIsNone(constraint.validate(4)) + self.assertIsNone(constraint.validate(3)) + + def test_less_or_equal_validate_fail(self): + schema = {'less_or_equal': 4} + constraint = Constraint('prop', Schema.INTEGER, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 5) + self.assertEqual(_('The value "5" of property "prop" must be less ' + 'than or equal to "4".'), str(error)) + + def test_less_or_equal_invalid(self): + snippet = 'less_or_equal: {3.9}' + schema = yaml.load(snippet) + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.INTEGER, + schema) + self.assertEqual(_('The property "less_or_equal" expects comparable ' + 'values.'), str(error)) + + def test_invalid_length(self): + schema = {'length': 'four'} + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.STRING, + schema) + self.assertEqual(_('The property "length" expects an integer.'), + str(error)) + + schema = {'length': 4.5} + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.STRING, + schema) + self.assertEqual(_('The property "length" expects an integer.'), + str(error)) + + def test_length_validate(self): + schema = {'length': 4} + constraint = Constraint('prop', Schema.STRING, schema) + self.assertIsNone(constraint.validate('abcd')) + + def test_length_validate_fail(self): + schema = {'length': 4} + constraint = Constraint('prop', Schema.STRING, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 'abc') + self.assertEqual(_('Length of value "abc" of property "prop" must ' + 'be equal to "4".'), str(error)) + + error = self.assertRaises(exception.ValidationError, + constraint.validate, + 'abcde') + self.assertEqual(_('Length of value "abcde" of property "prop" must ' + 'be equal to "4".'), str(error)) + + def test_invalid_min_length(self): + schema = {'min_length': 'four'} + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.STRING, + schema) + self.assertEqual(_('The property "min_length" expects an integer.'), + str(error)) + + def test_min_length_validate(self): + schema = {'min_length': 4} + constraint = Constraint('prop', Schema.STRING, schema) + self.assertIsNone(constraint.validate('abcd')) + self.assertIsNone(constraint.validate('abcde')) + + def test_min_length_validate_fail(self): + schema = {'min_length': 4} + constraint = Constraint('prop', Schema.STRING, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 'abc') + self.assertEqual(_('Length of value "abc" of property "prop" must ' + 'be at least "4".'), str(error)) + + def test_invalid_max_length(self): + schema = {'max_length': 'four'} + error = self.assertRaises(exception.InvalidSchemaError, Constraint, + 'prop', Schema.STRING, + schema) + self.assertEqual(_('The property "max_length" expects an integer.'), + str(error)) + + def test_max_length_validate(self): + schema = {'max_length': 4} + constraint = Constraint('prop', Schema.STRING, schema) + self.assertIsNone(constraint.validate('abcd')) + self.assertIsNone(constraint.validate('abc')) + + def test_max_length_validate_fail(self): + schema = {'max_length': 4} + constraint = Constraint('prop', Schema.STRING, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, + 'abcde') + self.assertEqual(_('Length of value "abcde" of property "prop" ' + 'must be no greater than "4".'), + str(error)) + + def test_pattern_validate(self): + schema = {'pattern': '[0-9]*'} + constraint = Constraint('prop', Schema.STRING, schema) + self.assertIsNone(constraint.validate('123')) + + def test_pattern_validate_fail(self): + schema = {'pattern': '[0-9]*'} + constraint = Constraint('prop', Schema.STRING, schema) + error = self.assertRaises(exception.ValidationError, + constraint.validate, 'abc') + self.assertEqual(_('The value "abc" of property "prop" does not ' + 'match pattern "[0-9]*".'), str(error)) + + def test_min_length_with_map(self): + schema = {'min_length': 1} + constraint = Constraint('prop', Schema.MAP, schema) + try: + constraint.validate({"k": "v"}) + except Exception as ex: + self.fail(ex) + + def test_max_length_with_map(self): + schema = {'max_length': 1} + constraint = Constraint('prop', Schema.MAP, schema) + try: + constraint.validate({"k": "v"}) + except Exception as ex: + self.fail(ex) diff --git a/nfvparser/toscaparser/tests/test_custom_relationships.py b/nfvparser/toscaparser/tests/test_custom_relationships.py new file mode 100644 index 0000000..9ae85d5 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_custom_relationships.py @@ -0,0 +1,35 @@ +# 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 os + +from toscaparser.tests.base import TestCase +from toscaparser.tosca_template import ToscaTemplate + + +class CustomRelationshipTypesTest(TestCase): + + '''TOSCA template.''' + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/relationship/test_custom_relationship.yaml") + tosca = ToscaTemplate(tosca_tpl) + + def test_version(self): + self.assertEqual(self.tosca.version, "tosca_simple_yaml_1_0") + + def test_custom_types(self): + expected_custom_types = ['tosca.capabilities.HA', + 'tosca.nodes.HACompute', + 'tosca.relationships.HA'] + self.assertItemsEqual(self.tosca.topology_template.custom_defs.keys(), + expected_custom_types) diff --git a/nfvparser/toscaparser/tests/test_datatypes.py b/nfvparser/toscaparser/tests/test_datatypes.py new file mode 100644 index 0000000..0a6cfe0 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_datatypes.py @@ -0,0 +1,517 @@ +# 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 os + +from testtools.testcase import skip +from toscaparser.common import exception +from toscaparser.dataentity import DataEntity +from toscaparser.elements.datatype import DataType +from toscaparser.parameters import Input +from toscaparser.tests.base import TestCase +from toscaparser.tosca_template import ToscaTemplate +from toscaparser.utils.gettextutils import _ +from toscaparser.utils import yamlparser + + +class DataTypeTest(TestCase): + + custom_type_schema = ''' + tosca.my.datatypes.PeopleBase: + properties: + name: + type: string + required: true + constraints: + - min_length: 2 + gender: + type: string + default: unknown + + tosca.my.datatypes.People: + derived_from: tosca.my.datatypes.PeopleBase + properties: + addresses: + type: map + required: false + entry_schema: + type: string + contacts: + type: list + required: false + entry_schema: + type: tosca.my.datatypes.ContactInfo + + tosca.my.datatypes.ContactInfo: + description: simple contact information + properties: + contact_name: + type: string + required: true + constraints: + - min_length: 2 + contact_email: + type: string + contact_phone: + type: string + + tosca.my.datatypes.TestLab: + properties: + humidity: + type: range + required: false + constraints: + - in_range: [-256, INFINITY] + temperature1: + type: range + required: false + constraints: + - in_range: [-256, UNBOUNDED] + temperature2: + type: range + required: false + constraints: + - in_range: [UNBOUNDED, 256] + ''' + custom_type_def = yamlparser.simple_parse(custom_type_schema) + + def test_empty_template(self): + value_snippet = '' + value = yamlparser.simple_parse(value_snippet) + self.assertEqual(value, {}) + + def test_built_in_datatype(self): + value_snippet = ''' + private_network: + network_name: private + network_id: 3e54214f-5c09-1bc9-9999-44100326da1b + addresses: [ 10.111.128.10 ] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.datatypes.network.NetworkInfo', + value.get('private_network')) + self.assertIsNotNone(data.validate()) + + value_snippet = ''' + portspec_valid: + protocol: tcp + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.datatypes.network.PortSpec', + value.get('portspec_valid')) + self.assertIsNotNone(data.validate()) + + value_snippet = ''' + portspec_invalid: + protocol: xyz + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.datatypes.network.PortSpec', + value.get('portspec_invalid')) + err = self.assertRaises(exception.ValidationError, data.validate) + self.assertEqual(_('The value "xyz" of property "protocol" is not ' + 'valid. Expected a value from "[udp, tcp, igmp]".' + ), + err.__str__()) + + def test_built_in_datatype_with_short_name(self): + value_snippet = ''' + ethernet_port: + port_name: port1 + port_id: 2c0c7a37-691a-23a6-7709-2d10ad041467 + network_id: 3e54214f-5c09-1bc9-9999-44100326da1b + mac_address: f1:18:3b:41:92:1e + addresses: [ 172.24.9.102 ] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('PortInfo', value.get('ethernet_port')) + self.assertIsNotNone(data.validate()) + + # Test normative PortSpec datatype's additional requirements + # TODO(Matt) - opened as bug 1555300 + # Need a test for PortSpec normative data type + # that tests the spec. requirement: "A valid PortSpec + # must have at least one of the following properties: + # target, target_range, source or source_range." + # TODO(Matt) - opened as bug 1555310 + # test PortSpec value for source and target + # against the source_range and target_range + # when specified. + def test_port_spec_addl_reqs(self): + value_snippet = ''' + test_port: + protocol: tcp + target: 65535 + target_range: [ 1, 65535 ] + source: 1 + source_range: [ 1, 65535 ] + + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.datatypes.network.PortSpec', + value.get('test_port')) + self.assertIsNotNone(data.validate()) + + def test_built_in_datatype_without_properties(self): + value_snippet = ''' + 2 + ''' + value = yamlparser.simple_parse(value_snippet) + datatype = DataType('PortDef') + self.assertEqual('integer', datatype.value_type) + data = DataEntity('PortDef', value) + self.assertIsNotNone(data.validate()) + + @skip('The example in TOSCA spec may have some problem.') + def test_built_in_nested_datatype(self): + value_snippet = ''' + user_port: + protocol: tcp + target: [50000] + source: [9000] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('PortSpec', value.get('user_port')) + self.assertIsNotNone(data.validate()) + + def test_built_in_nested_datatype_portdef(self): + tpl_snippet = ''' + inputs: + db_port: + type: PortDef + description: Port for the MySQL database + ''' + inputs = yamlparser.simple_parse(tpl_snippet)['inputs'] + name, attrs = list(inputs.items())[0] + input = Input(name, attrs) + self.assertIsNone(input.validate(3360)) + err = self.assertRaises(exception.ValidationError, input.validate, + 336000) + self.assertEqual(_('The value "336000" of property "None" is out of ' + 'range "(min:1, max:65535)".'), + err.__str__()) + + def test_custom_datatype(self): + value_snippet = ''' + name: Mike + gender: male + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.PeopleBase', value, + DataTypeTest.custom_type_def) + self.assertIsNotNone(data.validate()) + + def test_custom_datatype_with_parent(self): + value_snippet = ''' + name: Mike + gender: male + contacts: + - {contact_name: Tom, + contact_email: tom@email.com, + contact_phone: '123456789'} + - {contact_name: Jerry, + contact_email: jerry@email.com, + contact_phone: '321654987'} + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.People', value, + DataTypeTest.custom_type_def) + self.assertIsNotNone(data.validate()) + + # [Tom, Jerry] is not a dict, it can't be a value of datatype PeopleBase + def test_non_dict_value_for_datatype(self): + value_snippet = ''' + [Tom, Jerry] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.PeopleBase', value, + DataTypeTest.custom_type_def) + error = self.assertRaises(exception.TypeMismatchError, data.validate) + self.assertEqual(_('[\'Tom\', \'Jerry\'] must be of type ' + '"tosca.my.datatypes.PeopleBase".'), + error.__str__()) + + # 'nema' is an invalid field name + def test_field_error_in_dataentity(self): + value_snippet = ''' + nema: Mike + gender: male + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.PeopleBase', value, + DataTypeTest.custom_type_def) + error = self.assertRaises(exception.UnknownFieldError, data.validate) + self.assertEqual(_('Data value of type ' + '"tosca.my.datatypes.PeopleBase" contains unknown ' + 'field "nema". Refer to the definition to verify ' + 'valid values.'), + error.__str__()) + + def test_default_field_in_dataentity(self): + value_snippet = ''' + name: Mike + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.PeopleBase', value, + DataTypeTest.custom_type_def) + data = data.validate() + self.assertEqual('unknown', data.get('gender')) + + # required field 'name' is missing + def test_missing_field_in_dataentity(self): + value_snippet = ''' + gender: male + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.PeopleBase', value, + DataTypeTest.custom_type_def) + error = self.assertRaises(exception.MissingRequiredFieldError, + data.validate) + self.assertEqual(_('Data value of type ' + '"tosca.my.datatypes.PeopleBase" is missing ' + 'required field "[\'name\']".'), + error.__str__()) + + # the value of name field is not a string + def test_type_error_in_dataentity(self): + value_snippet = ''' + name: 123 + gender: male + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.PeopleBase', value, + DataTypeTest.custom_type_def) + error = self.assertRaises(ValueError, data.validate) + self.assertEqual(_('"123" is not a string.'), error.__str__()) + + # the value of name doesn't meet the defined constraint + def test_value_error_in_dataentity(self): + value_snippet = ''' + name: M + gender: male + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.PeopleBase', value, + DataTypeTest.custom_type_def) + error = self.assertRaises(exception.ValidationError, data.validate) + self.assertEqual(_('Length of value "M" of property "name" must be ' + 'at least "2".'), error.__str__()) + + # value of addresses doesn't fit the entry_schema + def test_validation_in_collection_entry(self): + value_snippet = ''' + name: Mike + gender: male + addresses: {Home: 1, Office: 9 bar avenue} + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.People', value, + DataTypeTest.custom_type_def) + error = self.assertRaises(ValueError, data.validate) + self.assertEqual(_('"1" is not a string.'), error.__str__()) + + # 'contact_pone' is an invalid attribute name in nested datatype below + def test_validation_in_nested_datatype(self): + value_snippet = ''' + name: Mike + gender: male + contacts: + - {contact_name: Tom, + contact_email: tom@email.com, + contact_pone: '123456789'} + - {contact_name: Jerry, + contact_email: jerry@email.com, + contact_phone: '321654987'} + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.People', value, + DataTypeTest.custom_type_def) + error = self.assertRaises(exception.UnknownFieldError, data.validate) + self.assertEqual(_('Data value of type ' + '"tosca.my.datatypes.ContactInfo" contains unknown ' + 'field "contact_pone". Refer to the definition to ' + 'verify valid values.'), + error.__str__()) + + def test_datatype_in_current_template(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/datatypes/test_custom_datatypes_in_current_template.yaml") + self.assertIsNotNone(ToscaTemplate(tpl_path)) + + def test_datatype_in_template_positive(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/datatypes/test_custom_datatypes_positive.yaml") + self.assertIsNotNone(ToscaTemplate(tpl_path)) + + def test_datatype_in_template_invalid_value(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/datatypes/test_custom_datatypes_value_error.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path) + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('"[\'1 foo street\', \'9 bar avenue\']" is not a map.')) + + def test_datatype_in_template_nested_datatype_error(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/datatypes/test_custom_datatypes_nested_datatype_error.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path) + exception.ExceptionCollector.assertExceptionMessage( + ValueError, _('"123456789" is not a string.')) + + def test_valid_range_type(self): + value_snippet = ''' + user_port: + protocol: tcp + target_range: [20000, 60000] + source_range: [1000, 3000] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('PortSpec', value.get('user_port')) + self.assertIsNotNone(data.validate()) + + def test_invalid_range_datatype(self): + value_snippet = ''' + user_port: + protocol: tcp + target: 1 + target_range: [20000] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('PortSpec', value.get('user_port')) + err = self.assertRaises(ValueError, data.validate) + self.assertEqual(_('"[20000]" is not a valid range.' + ), + err.__str__()) + + value_snippet = ''' + user_port: + protocol: tcp + target: 1 + target_range: [20000, 3000] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('PortSpec', value.get('user_port')) + err = self.assertRaises(ValueError, data.validate) + self.assertEqual(_('"[20000, 3000]" is not a valid range.' + ), + err.__str__()) + + value_snippet = ''' + humidity: [-100, 100] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.TestLab', + value, DataTypeTest.custom_type_def) + err = self.assertRaises(exception.InvalidSchemaError, + lambda: data.validate()) + self.assertEqual(_('The property "in_range" expects comparable values.' + ), + err.__str__()) + + def test_range_unbounded(self): + value_snippet = ''' + humidity: [-100, 100] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.TestLab', + value, DataTypeTest.custom_type_def) + err = self.assertRaises(exception.InvalidSchemaError, + lambda: data.validate()) + self.assertEqual(_('The property "in_range" expects comparable values.' + ), + err.__str__()) + + def test_invalid_ranges_against_constraints(self): + # The TestLab range type has min=-256, max=UNBOUNDED + value_snippet = ''' + temperature1: [-257, 999999] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.TestLab', value, + DataTypeTest.custom_type_def) + err = self.assertRaises(exception.ValidationError, data.validate) + self.assertEqual(_('The value "-257" of property "temperature1" is ' + 'out of range "(min:-256, max:UNBOUNDED)".'), + err.__str__()) + + value_snippet = ''' + temperature2: [-999999, 257] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.TestLab', value, + DataTypeTest.custom_type_def) + err = self.assertRaises(exception.ValidationError, data.validate) + self.assertEqual(_('The value "257" of property "temperature2" is ' + 'out of range "(min:UNBOUNDED, max:256)".'), + err.__str__()) + + def test_valid_ranges_against_constraints(self): + + # The TestLab range type has max=UNBOUNDED + value_snippet = ''' + temperature1: [-255, 999999] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.TestLab', value, + DataTypeTest.custom_type_def) + self.assertIsNotNone(data.validate()) + + # The TestLab range type has min=UNBOUNDED + value_snippet = ''' + temperature2: [-999999, 255] + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.my.datatypes.TestLab', value, + DataTypeTest.custom_type_def) + self.assertIsNotNone(data.validate()) + + def test_incorrect_field_in_datatype(self): + tpl_snippet = ''' + tosca_definitions_version: tosca_simple_yaml_1_0 + topology_template: + node_templates: + server: + type: tosca.nodes.Compute + + webserver: + type: tosca.nodes.WebServer + properties: + admin_credential: + user: username + token: some_pass + some_field: value + requirements: + - host: server + ''' + tpl = yamlparser.simple_parse(tpl_snippet) + err = self.assertRaises(exception.ValidationError, ToscaTemplate, + None, None, None, tpl) + self.assertIn(_('The pre-parsed input failed validation with the ' + 'following error(s): \n\n\tUnknownFieldError: Data ' + 'value of type "tosca.datatypes.Credential" contains' + ' unknown field "some_field". Refer to the definition' + ' to verify valid values'), err.__str__()) + + def test_functions_datatype(self): + value_snippet = ''' + admin_credential: + user: username + token: { get_input: password } + ''' + value = yamlparser.simple_parse(value_snippet) + data = DataEntity('tosca.datatypes.Credential', + value.get('admin_credential')) + self.assertIsNotNone(data.validate()) diff --git a/nfvparser/toscaparser/tests/test_exception.py b/nfvparser/toscaparser/tests/test_exception.py new file mode 100644 index 0000000..a404f4f --- /dev/null +++ b/nfvparser/toscaparser/tests/test_exception.py @@ -0,0 +1,42 @@ +# 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. + +from toscaparser.common import exception +from toscaparser.tests.base import TestCase +from toscaparser.utils.gettextutils import _ + + +class ExceptionTest(TestCase): + + def setUp(self): + super(TestCase, self).setUp() + exception.TOSCAException.set_fatal_format_exception(False) + + def test_message(self): + ex = exception.MissingRequiredFieldError(what='Template', + required='type') + self.assertEqual(_('Template is missing required field "type".'), + ex.__str__()) + + def test_set_flag(self): + exception.TOSCAException.set_fatal_format_exception('True') + self.assertFalse( + exception.TOSCAException._FATAL_EXCEPTION_FORMAT_ERRORS) + + def test_format_error(self): + ex = exception.UnknownFieldError(what='Template') + self.assertEqual(_('An unknown exception occurred.'), ex.__str__(),) + self.assertRaises(KeyError, self._formate_exception) + + def _formate_exception(self): + exception.UnknownFieldError.set_fatal_format_exception(True) + raise exception.UnknownFieldError(what='Template') diff --git a/nfvparser/toscaparser/tests/test_functions.py b/nfvparser/toscaparser/tests/test_functions.py new file mode 100644 index 0000000..fa60140 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_functions.py @@ -0,0 +1,373 @@ +# 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 os +import six +from toscaparser.common import exception +from toscaparser import functions +from toscaparser.tests.base import TestCase +from toscaparser.tosca_template import ToscaTemplate +from toscaparser.utils.gettextutils import _ + + +class IntrinsicFunctionsTest(TestCase): + + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress.yaml") + params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user', + 'db_root_pwd': '12345678'} + tosca = ToscaTemplate(tosca_tpl, parsed_params=params) + + def _get_node(self, node_name, tosca=None): + if tosca is None: + tosca = self.tosca + return [ + node for node in tosca.nodetemplates + if node.name == node_name][0] + + def _get_operation(self, interfaces, operation): + return [ + interface for interface in interfaces + if interface.name == operation][0] + + def _get_property(self, node_template, property_name): + return [prop.value for prop in node_template.get_properties_objects() + if prop.name == property_name][0] + + def _get_inputs_dict(self): + inputs = {} + for input in self.tosca.inputs: + inputs[input.name] = input.default + return inputs + + def _get_input(self, name): + self._get_inputs_dict()[name] + + def test_get_property(self): + wordpress = self._get_node('wordpress') + operation = self._get_operation(wordpress.interfaces, 'configure') + wp_db_password = operation.inputs['wp_db_password'] + self.assertIsInstance(wp_db_password, functions.GetProperty) + result = wp_db_password.result() + self.assertEqual('wp_pass', result) + + def test_get_property_with_input_param(self): + wordpress = self._get_node('wordpress') + operation = self._get_operation(wordpress.interfaces, 'configure') + wp_db_user = operation.inputs['wp_db_user'] + self.assertIsInstance(wp_db_user, functions.GetProperty) + result = wp_db_user.result() + self.assertEqual('my_db_user', result) + + def test_unknown_capability_property(self): + self.assertRaises(exception.ValidationError, self._load_template, + 'functions/test_unknown_capability_property.yaml') + exception.ExceptionCollector.assertExceptionMessage( + KeyError, + _('\'Property "unknown" was not found in capability ' + '"database_endpoint" of node template "database" referenced ' + 'from node template "database".\'')) + + def test_get_input_in_properties(self): + mysql_dbms = self._get_node('mysql_dbms') + expected_inputs = ['db_root_pwd', 'db_port'] + props = mysql_dbms.get_properties() + for key in props.keys(): + prop = props[key] + self.assertIsInstance(prop.value, functions.GetInput) + expected_inputs.remove(prop.value.input_name) + self.assertListEqual(expected_inputs, []) + + def test_get_input_validation(self): + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_unknown_input_in_property.yaml') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownInputError, + _('Unknown input "objectstore_name".')) + + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_unknown_input_in_interface.yaml') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownInputError, + _('Unknown input "image_id".')) + + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_invalid_function_signature.yaml') + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('Expected one argument for function "get_input" but received ' + '"[\'cpus\', \'cpus\']".')) + + def test_get_input_default_value_result(self): + mysql_dbms = self._get_node('mysql_dbms') + dbms_port = self._get_property(mysql_dbms, 'port') + self.assertEqual(3306, dbms_port.result()) + dbms_root_password = self._get_property(mysql_dbms, + 'root_password') + self.assertEqual(dbms_root_password.result(), '12345678') + + def test_get_property_with_host(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/functions/test_get_property_with_host.yaml") + mysql_database = self._get_node('mysql_database', + ToscaTemplate(tosca_tpl, + parsed_params={ + 'db_root_pwd': '123' + })) + operation = self._get_operation(mysql_database.interfaces, 'configure') + db_port = operation.inputs['db_port'] + self.assertIsInstance(db_port, functions.GetProperty) + result = db_port.result() + self.assertEqual(3306, result) + test = operation.inputs['test'] + self.assertIsInstance(test, functions.GetProperty) + result = test.result() + self.assertEqual(1, result) + + def test_get_property_with_nested_params(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/functions/tosca_nested_property_names_indexes.yaml") + webserver = self._get_node('wordpress', + ToscaTemplate(tosca_tpl, + parsed_params={ + 'db_root_pwd': '1234'})) + operation = self._get_operation(webserver.interfaces, 'configure') + wp_endpoint_prot = operation.inputs['wp_endpoint_protocol'] + self.assertIsInstance(wp_endpoint_prot, functions.GetProperty) + self.assertEqual('tcp', wp_endpoint_prot.result()) + wp_list_prop = operation.inputs['wp_list_prop'] + self.assertIsInstance(wp_list_prop, functions.GetProperty) + self.assertEqual(3, wp_list_prop.result()) + + def test_get_property_with_capabilties_inheritance(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/functions/test_capabilties_inheritance.yaml") + some_node = self._get_node('some_node', + ToscaTemplate(tosca_tpl, + parsed_params={ + 'db_root_pwd': '1234'})) + operation = self._get_operation(some_node.interfaces, 'configure') + some_input = operation.inputs['some_input'] + self.assertIsInstance(some_input, functions.GetProperty) + self.assertEqual('someval', some_input.result()) + + def test_get_property_source_target_keywords(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/functions/test_get_property_source_target_keywords.yaml") + tosca = ToscaTemplate(tosca_tpl, + parsed_params={'db_root_pwd': '1234'}) + + for node in tosca.nodetemplates: + for relationship, trgt in node.relationships.items(): + rel_template = trgt.get_relationship_template()[0] + break + + operation = self._get_operation(rel_template.interfaces, + 'pre_configure_source') + target_test = operation.inputs['target_test'] + self.assertIsInstance(target_test, functions.GetProperty) + self.assertEqual(1, target_test.result()) + source_port = operation.inputs['source_port'] + self.assertIsInstance(source_port, functions.GetProperty) + self.assertEqual(3306, source_port.result()) + + +class GetAttributeTest(TestCase): + + def _load_template(self, filename): + return ToscaTemplate(os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'data', + filename), + parsed_params={'db_root_pwd': '1234'}) + + def _get_operation(self, interfaces, operation): + return [ + interface for interface in interfaces + if interface.name == operation][0] + + def test_get_attribute_in_outputs(self): + tpl = self._load_template('tosca_single_instance_wordpress.yaml') + website_url_output = [ + x for x in tpl.outputs if x.name == 'website_url'][0] + self.assertIsInstance(website_url_output.value, functions.GetAttribute) + self.assertEqual('server', website_url_output.value.node_template_name) + self.assertEqual('private_address', + website_url_output.value.attribute_name) + + def test_get_attribute_invalid_args(self): + expected_msg = _('Illegal arguments for function "get_attribute".' + ' Expected arguments: "node-template-name", ' + '"req-or-cap"(optional), "property name"') + err = self.assertRaises(ValueError, + functions.get_function, None, None, + {'get_attribute': []}) + self.assertIn(expected_msg, six.text_type(err)) + err = self.assertRaises(ValueError, + functions.get_function, None, None, + {'get_attribute': ['x']}) + self.assertIn(expected_msg, six.text_type(err)) + + def test_get_attribute_unknown_node_template_name(self): + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_get_attribute_unknown_node_template_name.yaml') + exception.ExceptionCollector.assertExceptionMessage( + KeyError, + _('\'Node template "unknown_node_template" was not found.\'')) + + def test_get_attribute_unknown_attribute(self): + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_get_attribute_unknown_attribute_name.yaml') + exception.ExceptionCollector.assertExceptionMessage( + KeyError, + _('\'Attribute "unknown_attribute" was not found in node template ' + '"server".\'')) + + def test_get_attribute_host_keyword(self): + tpl = self._load_template( + 'functions/test_get_attribute_host_keyword.yaml') + + def assert_get_attribute_host_functionality(node_template_name): + node = [x for x in tpl.nodetemplates + if x.name == node_template_name][0] + configure_op = [ + x for x in node.interfaces if x.name == 'configure'][0] + ip_addr_input = configure_op.inputs['ip_address'] + self.assertIsInstance(ip_addr_input, functions.GetAttribute) + self.assertEqual('server', + ip_addr_input.get_referenced_node_template().name) + + assert_get_attribute_host_functionality('dbms') + assert_get_attribute_host_functionality('database') + + def test_get_attribute_host_not_found(self): + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_get_attribute_host_not_found.yaml') + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('"get_attribute: [ HOST, ... ]" was used in node template ' + '"server" but "tosca.relationships.HostedOn" was not found in ' + 'the relationship chain.')) + + def test_get_attribute_illegal_host_in_outputs(self): + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_get_attribute_illegal_host_in_outputs.yaml') + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('"get_attribute: [ HOST, ... ]" is not allowed in "outputs" ' + 'section of the TOSCA template.')) + + def test_get_attribute_with_index(self): + self._load_template( + 'functions/test_get_attribute_with_index.yaml') + + def test_get_attribute_with_index_error(self): + self.assertRaises( + exception.ValidationError, self._load_template, + 'functions/test_get_attribute_with_index_error.yaml') + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('Illegal arguments for function "get_attribute". ' + 'Unexpected attribute/index value "0"')) + + def test_get_attribute_source_target_keywords(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/functions/test_get_attribute_source_target_keywords.yaml") + tosca = ToscaTemplate(tosca_tpl, + parsed_params={'db_root_pwd': '12345678'}) + + for node in tosca.nodetemplates: + for relationship, trgt in node.relationships.items(): + rel_template = trgt.get_relationship_template()[0] + break + + operation = self._get_operation(rel_template.interfaces, + 'pre_configure_source') + target_test = operation.inputs['target_test'] + self.assertIsInstance(target_test, functions.GetAttribute) + source_port = operation.inputs['source_port'] + self.assertIsInstance(source_port, functions.GetAttribute) + + def test_get_attribute_with_nested_params(self): + self._load_template( + 'functions/test_get_attribute_with_nested_params.yaml') + + def test_implicit_attribute(self): + self.assertIsNotNone(self._load_template( + 'functions/test_get_implicit_attribute.yaml')) + + +class ConcatTest(TestCase): + + def _load_template(self, filename): + return ToscaTemplate(os.path.join( + os.path.dirname(os.path.abspath(__file__)), + filename)) + + def test_validate_concat(self): + tosca = self._load_template("data/functions/test_concat.yaml") + server_url_output = [ + output for output in tosca.outputs if output.name == 'url'][0] + func = functions.get_function(self, tosca.outputs, + server_url_output.value) + self.assertIsInstance(func, functions.Concat) + + self.assertRaises(exception.ValidationError, self._load_template, + 'data/functions/test_concat_invalid.yaml') + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('Invalid arguments for function "concat". Expected at least ' + 'one arguments.')) + + +class TokenTest(TestCase): + + def _load_template(self, filename): + return ToscaTemplate(os.path.join( + os.path.dirname(os.path.abspath(__file__)), + filename)) + + def test_validate_token(self): + tosca = self._load_template("data/functions/test_token.yaml") + server_url_output = [ + output for output in tosca.outputs if output.name == 'url'][0] + func = functions.get_function(self, tosca.outputs, + server_url_output.value) + self.assertIsInstance(func, functions.Token) + + self.assertRaises(exception.ValidationError, self._load_template, + 'data/functions/test_token_invalid.yaml') + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('Invalid arguments for function "token". Expected at least ' + 'three arguments.')) + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('Invalid arguments for function "token". Expected ' + 'integer value as third argument.')) + exception.ExceptionCollector.assertExceptionMessage( + ValueError, + _('Invalid arguments for function "token". Expected ' + 'single char value as second argument.')) diff --git a/nfvparser/toscaparser/tests/test_prereq.py b/nfvparser/toscaparser/tests/test_prereq.py new file mode 100644 index 0000000..11f4471 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_prereq.py @@ -0,0 +1,230 @@ +# 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 os +import shutil +import zipfile + +from toscaparser.common.exception import URLException +from toscaparser.common.exception import ValidationError +from toscaparser.prereq.csar import CSAR +from toscaparser.tests.base import TestCase +import toscaparser.utils +from toscaparser.utils.gettextutils import _ + + +class CSARPrereqTest(TestCase): + + base_path = os.path.dirname(os.path.abspath(__file__)) + + def test_file_exists(self): + path = os.path.join(self.base_path, "data/CSAR/csar_not_there.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('"%s" does not exist.') % path, str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_file_is_zip(self): + path = os.path.join(self.base_path, "data/CSAR/csar_not_zip.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('"%s" is not a valid zip file.') % path, str(error)) + + def test_url_is_zip(self): + path = "https://github.com/openstack/tosca-parser/raw/master/" \ + "toscaparser/tests/data/CSAR/csar_not_zip.zip" + csar = CSAR(path, False) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('"%s" is not a valid zip file.') % path, str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_metadata_file_exists(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_no_metadata_file.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('"%s" is not a valid CSAR as it does not contain ' + 'the required file "TOSCA.meta" in the folder ' + '"TOSCA-Metadata".') % path, str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_valid_metadata_file_exists(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_wrong_metadata_file.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('"%s" is not a valid CSAR as it does not contain ' + 'the required file "TOSCA.meta" in the folder ' + '"TOSCA-Metadata".') % path, str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_metadata_is_yaml(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_metadata_not_yaml.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('The file "TOSCA-Metadata/TOSCA.meta" in the CSAR ' + '"%s" does not contain valid YAML content.') % path, + str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_metadata_exists(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_missing_metadata.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('The CSAR "%s" is missing the required metadata ' + '"Entry-Definitions" in ' + '"TOSCA-Metadata/TOSCA.meta".') % path, str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_entry_def_exists(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_invalid_entry_def.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('The "Entry-Definitions" file defined in the CSAR ' + '"%s" does not exist.') % path, str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_csar_invalid_import_path(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_wordpress_invalid_import_path.zip") + csar = CSAR(path) + error = self.assertRaises(ImportError, csar.validate) + self.assertEqual(_('Import "Invalid_import_path/wordpress.yaml" is' + ' not valid.'), str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_csar_invalid_import_url(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_wordpress_invalid_import_url.zip") + csar = CSAR(path) + error = self.assertRaises(URLException, csar.validate) + self.assertEqual(_('Failed to reach server ' + '"https://raw.githubusercontent.com/openstack/' + 'tosca-parser/master/toscaparser/tests/data/CSAR/' + 'tosca_single_instance_wordpress/Definitions/' + 'wordpress1.yaml". Reason is: Not Found.'), + str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_csar_invalid_script_path(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_wordpress_invalid_script_path.zip") + csar = CSAR(path) + error = self.assertRaises(ValueError, csar.validate) + self.assertTrue( + str(error) == _('The resource "Scripts/WordPress/install.sh" does ' + 'not exist.') or + str(error) == _('The resource "Scripts/WordPress/configure.sh" ' + 'does not exist.')) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_csar_invalid_script_url(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_wordpress_invalid_script_url.zip") + csar = CSAR(path) + error = self.assertRaises(URLException, csar.validate) + self.assertEqual(_('The resource at ' + '"https://raw.githubusercontent.com/openstack/' + 'tosca-parser/master/toscaparser/tests/data/CSAR/' + 'tosca_single_instance_wordpress/Scripts/WordPress/' + 'install1.sh" cannot be accessed.'), + str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_valid_csar(self): + path = os.path.join(self.base_path, "data/CSAR/csar_hello_world.zip") + csar = CSAR(path) + self.assertTrue(csar.validate()) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_valid_csar_with_url_import_and_script(self): + path = os.path.join(self.base_path, "data/CSAR/csar_wordpress_with_url" + "_import_and_script.zip") + csar = CSAR(path) + self.assertTrue(csar.validate()) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_metadata_invalid_csar(self): + path = os.path.join(self.base_path, + "data/CSAR/csar_metadata_not_yaml.zip") + csar = CSAR(path) + error = self.assertRaises(ValidationError, csar.get_author) + self.assertEqual(_('The file "TOSCA-Metadata/TOSCA.meta" in the CSAR ' + '"%s" does not contain valid YAML content.') % path, + str(error)) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_metadata_valid_csar(self): + path = os.path.join(self.base_path, "data/CSAR/csar_hello_world.zip") + csar = CSAR(path) + expected_meta = {'TOSCA-Meta-File-Version': 1.0, + 'CSAR-Version': 1.1, + 'Created-By': 'OASIS TOSCA TC', + 'Entry-Definitions': 'tosca_helloworld.yaml'} + self.assertEqual(expected_meta, csar.get_metadata(), + 'The extracted metadata of the CSAR %(csar)s does ' + 'not match the expected metadata %(meta)s' + % {'csar': path, 'meta': expected_meta.__str__()}) + self.assertEqual(1.1, csar.get_version()) + self.assertEqual('OASIS TOSCA TC', csar.get_author()) + self.assertEqual('tosca_helloworld.yaml', csar.get_main_template()) + self.assertEqual('Template for deploying a single server with ' + 'predefined properties.', csar.get_description()) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_csar_main_template(self): + path = os.path.join(self.base_path, "data/CSAR/csar_hello_world.zip") + csar = CSAR(path) + yaml_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), + "data/tosca_helloworld.yaml") + expected_yaml = toscaparser.utils.yamlparser.load_yaml(yaml_file) + self.assertEqual(expected_yaml, csar.get_main_template_yaml()) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_decompress(self): + path = os.path.join(self.base_path, "data/CSAR/csar_hello_world.zip") + csar = CSAR(path) + csar.decompress() + zf = zipfile.ZipFile(path) + for name in zf.namelist(): + tmp_path = os.path.join(csar.temp_dir, name) + self.assertTrue(os.path.isdir(tmp_path) or + os.path.isfile(tmp_path)) + shutil.rmtree(csar.temp_dir) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) + + def test_alternate_csar_extension(self): + path = os.path.join(self.base_path, "data/CSAR/csar_elk.csar") + csar = CSAR(path) + self.assertTrue(csar.validate()) + self.assertTrue(csar.temp_dir is None or + not os.path.exists(csar.temp_dir)) diff --git a/nfvparser/toscaparser/tests/test_properties.py b/nfvparser/toscaparser/tests/test_properties.py new file mode 100644 index 0000000..6b95537 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_properties.py @@ -0,0 +1,368 @@ +# 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. + +from testtools import matchers + +from toscaparser.common import exception +from toscaparser.elements.property_definition import PropertyDef +from toscaparser.nodetemplate import NodeTemplate +from toscaparser.properties import Property +from toscaparser.tests.base import TestCase +from toscaparser.utils.gettextutils import _ +from toscaparser.utils import yamlparser + + +class PropertyTest(TestCase): + + def test_type(self): + test_property_schema = {'type': 'string'} + propertyInstance = Property('test_property', 'Hughes', + test_property_schema) + self.assertEqual('string', propertyInstance.type) + + def test_type_invalid(self): + test_property_schema = {'type': 'Fish'} + propertyInstance = Property('test_property', 'Hughes', + test_property_schema) + error = self.assertRaises(exception.InvalidTypeError, + propertyInstance.validate) + self.assertEqual(_('Type "Fish" is not a valid type.'), str(error)) + + def test_list(self): + test_property_schema = {'type': 'list'} + propertyInstance = Property('test_property', ['a', 'b'], + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual(['a', 'b'], propertyInstance.value) + + def test_list_invalid(self): + test_property_schema = {'type': 'list'} + propertyInstance = Property('test_property', 'a', + test_property_schema) + error = self.assertRaises(ValueError, propertyInstance.validate) + self.assertEqual(_('"a" is not a list.'), str(error)) + + def test_list_entry_schema(self): + test_property_schema = {'type': 'list', + 'entry_schema': {'type': 'string'}} + propertyInstance = Property('test_property', ['a', 'b'], + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual(['a', 'b'], propertyInstance.value) + + schema_snippet = ''' + type: list + entry_schema: + type: string + constraints: + - min_length: 2 + ''' + test_property_schema = yamlparser.simple_parse(schema_snippet) + propertyInstance = Property('test_property', ['ab', 'cd'], + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual(['ab', 'cd'], propertyInstance.value) + + def test_list_entry_schema_invalid(self): + test_property_schema = {'type': 'list', + 'entry_schema': {'type': 'integer'}} + propertyInstance = Property('test_property', [1, 'b'], + test_property_schema) + error = self.assertRaises(ValueError, propertyInstance.validate) + self.assertEqual(_('"b" is not an integer.'), str(error)) + + def test_map(self): + test_property_schema = {'type': 'map'} + propertyInstance = Property('test_property', {'a': 'b'}, + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual({'a': 'b'}, propertyInstance.value) + + def test_map_invalid(self): + test_property_schema = {'type': 'map'} + propertyInstance = Property('test_property', 12, + test_property_schema) + error = self.assertRaises(ValueError, propertyInstance.validate) + self.assertEqual(_('"12" is not a map.'), str(error)) + + def test_map_entry_schema(self): + test_property_schema = {'type': 'map', + 'entry_schema': {'type': 'boolean'}} + propertyInstance = Property('test_property', + {'valid': True, 'required': True}, + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual({'valid': True, 'required': True}, + propertyInstance.value) + + def test_map_entry_schema_invalid(self): + test_property_schema = {'type': 'map', + 'entry_schema': {'type': 'boolean'}} + propertyInstance = Property('test_property', + {'valid': True, 'contact_name': 123}, + test_property_schema) + error = self.assertRaises(ValueError, propertyInstance.validate) + self.assertEqual(_('"123" is not a boolean.'), str(error)) + + def test_boolean(self): + test_property_schema = {'type': 'boolean'} + propertyInstance = Property('test_property', 'true', + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + propertyInstance = Property('test_property', True, + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual(True, propertyInstance.value) + + def test_boolean_invalid(self): + test_property_schema = {'type': 'boolean'} + propertyInstance = Property('test_property', 12, + test_property_schema) + error = self.assertRaises(ValueError, propertyInstance.validate) + self.assertEqual(_('"12" is not a boolean.'), str(error)) + + def test_float(self): + test_property_schema = {'type': 'float'} + propertyInstance = Property('test_property', 0.1, + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual(0.1, propertyInstance.value) + + def test_float_invalid(self): + test_property_schema = {'type': 'float'} + propertyInstance = Property('test_property', 12, + test_property_schema) + error = self.assertRaises(ValueError, propertyInstance.validate) + self.assertEqual(_('"12" is not a float.'), str(error)) + + def test_timestamp(self): + test_property_schema = {'type': 'timestamp'} + # canonical timestamp + propertyInstance = Property('test_property', '2015-04-01T02:59:43.1Z', + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual("2015-04-01T02:59:43.1Z", propertyInstance.value) + + # iso8601 timestamp + propertyInstance = Property('test_property', + '2015-04-01t21:59:43.10-05:00', + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual("2015-04-01t21:59:43.10-05:00", + propertyInstance.value) + + # space separated timestamp + propertyInstance = Property('test_property', + '2015-04-01 21:59:43.10 -5', + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual("2015-04-01 21:59:43.10 -5", propertyInstance.value) + + # no time zone timestamp + propertyInstance = Property('test_property', '2015-04-01 21:59:43.10', + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual("2015-04-01 21:59:43.10", propertyInstance.value) + + # date (00:00:00Z) + propertyInstance = Property('test_property', '2015-04-01', + test_property_schema) + self.assertIsNone(propertyInstance.validate()) + self.assertEqual("2015-04-01", propertyInstance.value) + + def test_timestamp_invalid(self): + test_property_schema = {'type': 'timestamp'} + # invalid timestamp - day out of range + value = '2015-04-115T02:59:43.1Z' + propertyInstance = Property('test_property', value, + test_property_schema) + error = self.assertRaises(ValueError, propertyInstance.validate) + expected_message = (_('"%s" is not a valid timestamp.') % value) + self.assertThat(str(error), matchers.StartsWith(expected_message)) + + def test_required(self): + test_property_schema = {'type': 'string'} + propertyInstance = Property('test_property', 'Foo', + test_property_schema) + self.assertEqual(True, propertyInstance.required) + + def test_proprety_inheritance(self): + + tosca_custom_def = ''' + tosca.nodes.SoftwareComponent.MySoftware: + derived_from: SoftwareComponent + properties: + install_path: + required: false + type: string + default: /opt/mysoftware + ''' + + tosca_node_template = ''' + node_templates: + mysoftware_instance: + type: tosca.nodes.SoftwareComponent.MySoftware + properties: + component_version: 3.1 + ''' + + expected_properties = ['component_version', + 'install_path'] + + tpl = self._get_nodetemplate(tosca_node_template, tosca_custom_def) + self.assertIsNone(tpl.validate()) + self.assertEqual(expected_properties, + sorted(tpl.get_properties().keys())) + + def test_missing_property_type(self): + tpl_snippet = ''' + properties: + prop: + typo: tosca.mytesttype.Test + ''' + schema = yamlparser.simple_parse(tpl_snippet) + error = self.assertRaises(exception.InvalidSchemaError, PropertyDef, + 'prop', None, schema['properties']['prop']) + self.assertEqual(_('Schema definition of "prop" must have a "type" ' + 'attribute.'), str(error)) + + def test_invalid_required_value(self): + tpl_snippet = ''' + properties: + prop: + type: tosca.mytesttype.Test + required: dunno + ''' + schema = yamlparser.simple_parse(tpl_snippet) + error = self.assertRaises(exception.InvalidSchemaError, PropertyDef, + 'prop', None, schema['properties']['prop']) + + valid_values = ', '.join(PropertyDef.VALID_REQUIRED_VALUES) + expected_message = (_('Schema definition of "prop" has "required" ' + 'attribute with invalid value "dunno". The ' + 'value must be one of "%s".') % valid_values) + self.assertEqual(expected_message, str(error)) + + def test_invalid_property_status(self): + tpl_snippet = ''' + properties: + prop: + type: string + status: unknown + ''' + schema = yamlparser.simple_parse(tpl_snippet) + error = self.assertRaises(exception.InvalidSchemaError, PropertyDef, + 'prop', None, schema['properties']['prop']) + + valid_values = ', '.join(PropertyDef.VALID_STATUS_VALUES) + expected_message = (_('Schema definition of "prop" has "status" ' + 'attribute with invalid value "unknown". The ' + 'value must be one of "%s".') % valid_values) + self.assertEqual(expected_message, str(error)) + + def test_capability_proprety_inheritance(self): + tosca_custom_def_example1 = ''' + tosca.capabilities.ScalableNew: + derived_from: tosca.capabilities.Scalable + properties: + max_instances: + type: integer + default: 0 + required: no + + tosca.nodes.ComputeNew: + derived_from: tosca.nodes.Compute + capabilities: + scalable: + type: tosca.capabilities.ScalableNew + ''' + + tosca_node_template_example1 = ''' + node_templates: + compute_instance: + type: tosca.nodes.ComputeNew + capabilities: + scalable: + properties: + min_instances: 1 + ''' + + tosca_custom_def_example2 = ''' + tosca.nodes.ComputeNew: + derived_from: tosca.nodes.Compute + capabilities: + new_cap: + type: tosca.capabilities.Scalable + ''' + + tosca_node_template_example2 = ''' + node_templates: + db_server: + type: tosca.nodes.ComputeNew + capabilities: + host: + properties: + num_cpus: 1 + ''' + + tpl1 = self._get_nodetemplate(tosca_node_template_example1, + tosca_custom_def_example1) + self.assertIsNone(tpl1.validate()) + + tpl2 = self._get_nodetemplate(tosca_node_template_example2, + tosca_custom_def_example2) + self.assertIsNone(tpl2.validate()) + + def _get_nodetemplate(self, tpl_snippet, + custom_def_snippet=None): + nodetemplates = yamlparser.\ + simple_parse(tpl_snippet)['node_templates'] + custom_def = [] + if custom_def_snippet: + custom_def = yamlparser.simple_parse(custom_def_snippet) + name = list(nodetemplates.keys())[0] + tpl = NodeTemplate(name, nodetemplates, custom_def) + return tpl + + def test_explicit_relationship_proprety(self): + + tosca_node_template = ''' + node_templates: + + client_node: + type: tosca.nodes.Compute + requirements: + - local_storage: + node: my_storage + relationship: + type: AttachesTo + properties: + location: /mnt/disk + + my_storage: + type: tosca.nodes.BlockStorage + properties: + size: 1 GB + ''' + + expected_properties = ['location'] + + nodetemplates = yamlparser.\ + simple_parse(tosca_node_template)['node_templates'] + tpl = NodeTemplate('client_node', nodetemplates, []) + + self.assertIsNone(tpl.validate()) + rel_tpls = [] + for relationship, trgt in tpl.relationships.items(): + rel_tpls.extend(trgt.get_relationship_template()) + self.assertEqual(expected_properties, + sorted(rel_tpls[0].get_properties().keys())) diff --git a/nfvparser/toscaparser/tests/test_scalarunit.py b/nfvparser/toscaparser/tests/test_scalarunit.py new file mode 100644 index 0000000..09a24b6 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_scalarunit.py @@ -0,0 +1,355 @@ +# 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. + +from toscaparser.common import exception +from toscaparser.elements.scalarunit import ScalarUnit_Frequency +from toscaparser.elements.scalarunit import ScalarUnit_Size +from toscaparser.elements.scalarunit import ScalarUnit_Time +from toscaparser.nodetemplate import NodeTemplate +from toscaparser.tests.base import TestCase +from toscaparser.utils.gettextutils import _ +from toscaparser.utils import yamlparser + + +class ScalarUnitPositiveTest(TestCase): + + scenarios = [ + ( + # tpl_snippet with mem_size given as number+space+MB + 'mem_size_is_number_Space_MB', + dict(tpl_snippet=''' + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + mem_size: 1024 MB + ''', + property='mem_size', + expected='1024 MB') + ), + ( + # tpl_snippet with mem_size given as number+spaces+GB + 'mem_size_is_number_Space_GB', + dict(tpl_snippet=''' + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + mem_size: 1 GB + ''', + property='mem_size', + expected='1 GB') + ), + ( + # tpl_snippet with mem_size given as number+tiB + 'mem_size_is_number_NoSpace_GB', + dict(tpl_snippet=''' + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + mem_size: 1tiB + ''', + property='mem_size', + expected='1 TiB') + ), + ( + # tpl_snippet with mem_size given as number+Spaces+GIB + 'mem_size_is_number_Spaces_GB', + dict(tpl_snippet=''' + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + mem_size: 1 GIB + ''', + property='mem_size', + expected='1 GiB') + ), + ( + # tpl_snippet with mem_size given as number+Space+tib + 'mem_size_is_number_Spaces_GB', + dict(tpl_snippet=''' + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + mem_size: 1 tib + ''', + property='mem_size', + expected='1 TiB') + ), + ( + 'cpu_frequency_is_float_Space_GHz', + dict(tpl_snippet=''' + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + cpu_frequency: 2.5 GHz + ''', + property='cpu_frequency', + expected='2.5 GHz') + ), + ( + 'cpu_frequency_is_float_Space_MHz', + dict(tpl_snippet=''' + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + cpu_frequency: 800 MHz + ''', + property='cpu_frequency', + expected='800 MHz') + ), + ] + + def test_scenario_scalar_unit_positive(self): + tpl = self.tpl_snippet + nodetemplates = yamlparser.simple_parse(tpl) + nodetemplate = NodeTemplate('server', nodetemplates) + props = nodetemplate.get_capability('host').get_properties() + prop_name = self.property + if props and prop_name in props.keys(): + prop = props[prop_name] + self.assertIsNone(prop.validate()) + resolved = prop.value + self.assertEqual(resolved, self.expected) + + +class GetNumFromScalarUnitSizePositive(TestCase): + + scenarios = [ + ( # Note that (1 TB) / (1 GB) = 1000 + 'Input is TB, user input is GB', + dict(InputMemSize='1 TB', + UserInputUnit='gB', + expected=1000) + ), + ( # Note that (1 Tib)/ (1 GB) = 1099 + 'Input is TiB, user input is GB', + dict(InputMemSize='1 TiB', + UserInputUnit='gB', + expected=1099.511627776) + ), + ] + + def test_scenario_get_num_from_scalar_unit_size(self): + resolved = (ScalarUnit_Size(self.InputMemSize). + get_num_from_scalar_unit(self.UserInputUnit)) + self.assertEqual(resolved, self.expected) + + +class GetNumFromScalarUnitFrequencyPositive(TestCase): + + scenarios = [ + ( # Note that (1 GHz) / (1 Hz) = 1000000000 + 'Input is GHz, user input is Hz', + dict(InputMemSize='1 GHz', + UserInputUnit='Hz', + expected=1000000000) + ), + ( + 'Input is GHz, user input is Hz', + dict(InputMemSize='2.4 GHz', + UserInputUnit='Hz', + expected=2400000000) + ), + ( # Note that (1 GHz)/ (1 MHz) = 1000 + 'Input is MHz, user input is GHz', + dict(InputMemSize='800 MHz', + UserInputUnit='GHz', + expected=0.8) + ), + ( + 'Input is GHz, user input is Hz', + dict(InputMemSize='0.9 GHz', + UserInputUnit='MHz', + expected=900) + ), + ( + 'Input is GHz, user input is Hz', + dict(InputMemSize='2.7GHz', + UserInputUnit='MHz', + expected=2700) + ), + ] + + def test_scenario_get_num_from_scalar_unit_frequency(self): + resolved = (ScalarUnit_Frequency(self.InputMemSize). + get_num_from_scalar_unit(self.UserInputUnit)) + self.assertEqual(resolved, self.expected) + + +class GetNumFromScalarUnitTimePositive(TestCase): + + scenarios = [ + ( # Note that (1 s) / (1 ms) = 1000 + 'Input is 500ms, user input is s', + dict(InputMemSize='500 ms', + UserInputUnit='s', + expected=0.5) + ), + ( # Note that (1 h)/ (1 s) = 3600 + 'Input is h, user input is s', + dict(InputMemSize='1 h', + UserInputUnit='s', + expected=3600) + ), + ( # Note that (1 m)/ (1 s) = 60 + 'Input is m, user input is s', + dict(InputMemSize='0.5 m', + UserInputUnit='s', + expected=30) + ), + ( # Note that (1 d)/ (1 h) = 24 + 'Input is d, user input is h', + dict(InputMemSize='1 d', + UserInputUnit='h', + expected=24) + ), + ] + + def test_scenario_get_num_from_scalar_unit_time(self): + resolved = (ScalarUnit_Time(self.InputMemSize). + get_num_from_scalar_unit(self.UserInputUnit)) + self.assertEqual(resolved, self.expected) + + +class GetNumFromScalarUnitSizeNegative(TestCase): + + InputMemSize = '1 GB' + UserInputUnit = 'qB' + + def test_get_num_from_scalar_unit_size_negative(self): + try: + (ScalarUnit_Size(self.InputMemSize). + get_num_from_scalar_unit(self.UserInputUnit)) + except Exception as error: + self.assertIsInstance(error, ValueError) + self.assertEqual(_('The unit "qB" is not valid. Valid units are ' + '"[\'B\', \'GB\', \'GiB\', \'KiB\', \'MB\', ' + '\'MiB\', \'TB\', \'TiB\', \'kB\']".'), + error.__str__()) + + +class GetNumFromScalarUnitFrequencyNegative(TestCase): + + InputFrequency = '2.7 GHz' + UserInputUnit = 'Jz' + + def test_get_num_from_scalar_unit_frequency_negative(self): + try: + (ScalarUnit_Frequency(self.InputFrequency). + get_num_from_scalar_unit(self.UserInputUnit)) + except Exception as error: + self.assertIsInstance(error, ValueError) + self.assertEqual(_('The unit "Jz" is not valid. Valid units are ' + '"[\'GHz\', \'Hz\', \'MHz\', \'kHz\']".'), + error.__str__()) + + +class GetNumFromScalarUnitTimeNegative(TestCase): + + InputTime = '5 ms' + UserInputUnit = 'D' + + def test_get_num_from_scalar_unit_frequency_negative(self): + try: + (ScalarUnit_Time(self.InputTime). + get_num_from_scalar_unit(self.UserInputUnit)) + except Exception as error: + self.assertIsInstance(error, ValueError) + self.assertEqual(_('"Jz" is not a valid scalar-unit.'), + error.__str__()) + + +class ScalarUnitNegativeTest(TestCase): + + custom_def_snippet = ''' + tosca.my.nodes.Compute: + derived_from: tosca.nodes.Root + properties: + cpu_frequency: + required: false + type: scalar-unit.frequency + constraints: + - greater_or_equal: 0.1 GHz + disk_size: + required: false + type: scalar-unit.size + constraints: + - greater_or_equal: 1 GB + mem_size: + required: false + type: scalar-unit.size + constraints: + - in_range: [1 MiB, 1 GiB] + ''' + custom_def = yamlparser.simple_parse(custom_def_snippet) + + # disk_size doesn't provide a value, mem_size uses an invalid unit. + def test_invalid_scalar_unit(self): + tpl_snippet = ''' + server: + type: tosca.my.nodes.Compute + properties: + cpu_frequency: 50.3.6 GHZ + disk_size: MB + mem_size: 1 QB + ''' + nodetemplates = yamlparser.simple_parse(tpl_snippet) + nodetemplate = NodeTemplate('server', nodetemplates, self.custom_def) + for p in nodetemplate.get_properties_objects(): + self.assertRaises(ValueError, p.validate) + + # disk_size is less than 1 GB, mem_size is not in the required range. + # Note: in the spec, the minimum value of mem_size is 1 MiB (> 1 MB) + def test_constraint_for_scalar_unit(self): + tpl_snippet = ''' + server: + type: tosca.my.nodes.Compute + properties: + cpu_frequency: 0.05 GHz + disk_size: 500 MB + mem_size: 1 MB + ''' + nodetemplates = yamlparser.simple_parse(tpl_snippet) + nodetemplate = NodeTemplate('server', nodetemplates, self.custom_def) + props = nodetemplate.get_properties() + if 'cpu_frequency' in props.keys(): + error = self.assertRaises(exception.ValidationError, + props['cpu_frequency'].validate) + self.assertEqual(_('The value "0.05 GHz" of property ' + '"cpu_frequency" must be greater than or equal ' + 'to "0.1 GHz".'), error.__str__()) + if 'disk_size' in props.keys(): + error = self.assertRaises(exception.ValidationError, + props['disk_size'].validate) + self.assertEqual(_('The value "500 MB" of property "disk_size" ' + 'must be greater than or equal to "1 GB".'), + error.__str__()) + + if 'mem_size' in props.keys(): + error = self.assertRaises(exception.ValidationError, + props['mem_size'].validate) + self.assertEqual(_('The value "1 MB" of property "mem_size" is ' + 'out of range "(min:1 MiB, max:1 GiB)".'), + error.__str__()) diff --git a/nfvparser/toscaparser/tests/test_shell.py b/nfvparser/toscaparser/tests/test_shell.py new file mode 100644 index 0000000..bb163ff --- /dev/null +++ b/nfvparser/toscaparser/tests/test_shell.py @@ -0,0 +1,51 @@ +# 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 os + +from toscaparser.common import exception +import toscaparser.shell as shell +from toscaparser.tests.base import TestCase +from toscaparser.utils.gettextutils import _ + + +class ShellTest(TestCase): + + tosca_helloworld = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_helloworld.yaml") + + errornous_template = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_multiple_validation_errors.yaml") + + def test_missing_arg(self): + self.assertRaises(SystemExit, shell.main, '') + + def test_invalid_arg(self): + self.assertRaises(SystemExit, shell.main, 'parse me') + + def test_template_not_exist(self): + error = self.assertRaises( + ValueError, shell.main, ['--template-file=template.txt']) + self.assertEqual(_('"template.txt" is not a valid file.'), str(error)) + + def test_template_invalid(self): + arg = '--template-file=' + self.errornous_template + self.assertRaises(exception.ValidationError, shell.main, [arg]) + + def test_template_valid(self): + arg = '--template-file=' + self.tosca_helloworld + try: + shell.main([arg]) + except Exception: + self.fail(_('The program raised an exception unexpectedly.')) diff --git a/nfvparser/toscaparser/tests/test_topology_template.py b/nfvparser/toscaparser/tests/test_topology_template.py new file mode 100644 index 0000000..3aabc9b --- /dev/null +++ b/nfvparser/toscaparser/tests/test_topology_template.py @@ -0,0 +1,313 @@ +# 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 os + +from toscaparser.common import exception +from toscaparser.substitution_mappings import SubstitutionMappings +from toscaparser.tests.base import TestCase +from toscaparser.topology_template import TopologyTemplate +from toscaparser.tosca_template import ToscaTemplate +from toscaparser.utils.gettextutils import _ +import toscaparser.utils.yamlparser + +YAML_LOADER = toscaparser.utils.yamlparser.load_yaml + + +class TopologyTemplateTest(TestCase): + + def setUp(self): + TestCase.setUp(self) + '''TOSCA template.''' + self.tosca_tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/transactionsubsystem.yaml") + self.tpl = YAML_LOADER(self.tosca_tpl_path) + self.topo_tpl = self.tpl.get('topology_template') + self.imports = self.tpl.get('imports') + self.topo = TopologyTemplate(self.topo_tpl, + self._get_all_custom_def()) + + def _get_custom_def(self, type_definition): + custom_defs = {} + for definition in self.imports: + if os.path.isabs(definition): + def_file = definition + else: + tpl_dir = os.path.dirname(os.path.abspath(self.tosca_tpl_path)) + def_file = os.path.join(tpl_dir, definition) + custom_type = YAML_LOADER(def_file) + custom_defs.update(custom_type.get(type_definition)) + return custom_defs + + def _get_all_custom_def(self): + custom_defs = {} + custom_defs.update(self._get_custom_def('node_types')) + custom_defs.update(self._get_custom_def('capability_types')) + return custom_defs + + def _get_custom_types(self): + custom_types = {} + def_file = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/definitions.yaml") + custom_type = YAML_LOADER(def_file) + node_types = custom_type['node_types'] + for name in node_types: + defintion = node_types[name] + custom_types[name] = defintion + return custom_types + + def test_description(self): + expected_desc = 'Template of a database including its hosting stack.' + self.assertEqual(expected_desc, self.topo.description) + + def test_inputs(self): + self.assertEqual( + ['mq_server_ip', 'my_cpus', 'receiver_port'], + sorted([input.name for input in self.topo.inputs])) + + input_name = "receiver_port" + expected_description = "Port to be used for receiving messages." + for input in self.topo.inputs: + if input.name == input_name: + self.assertEqual(expected_description, input.description) + + def test_node_tpls(self): + '''Test nodetemplate names.''' + self.assertEqual( + ['app', 'server', 'websrv'], + sorted([tpl.name for tpl in self.topo.nodetemplates])) + + tpl_name = "app" + expected_type = "example.SomeApp" + expected_properties = ['admin_user', 'pool_size'] + expected_capabilities = ['feature', 'message_receiver'] + expected_requirements = [{'host': {'node': 'websrv'}}] + expected_relationshp = ['tosca.relationships.HostedOn'] + expected_host = ['websrv'] + for tpl in self.topo.nodetemplates: + if tpl_name == tpl.name: + '''Test node type.''' + self.assertEqual(tpl.type, expected_type) + + '''Test properties.''' + self.assertEqual( + expected_properties, + sorted(tpl.get_properties().keys())) + + '''Test capabilities.''' + self.assertEqual( + expected_capabilities, + sorted(tpl.get_capabilities().keys())) + + '''Test requirements.''' + self.assertEqual( + expected_requirements, tpl.requirements) + + '''Test relationship.''' + ''' TODO : skip tempororily. need to fix it + ''' + self.assertEqual( + expected_relationshp, + [x.type for x in tpl.relationships.keys()]) + self.assertEqual( + expected_host, + [y.name for y in tpl.relationships.values()]) + '''Test interfaces.''' + # TODO(hurf) add interface test when new template is available + + if tpl.name == 'server': + '''Test property value''' + props = tpl.get_properties() + if props and 'mem_size' in props.keys(): + self.assertEqual(props['mem_size'].value, '4096 MB') + '''Test capability''' + caps = tpl.get_capabilities() + self.assertIn('os', caps.keys()) + os_props_objs = None + os_props = None + os_type_prop = None + if caps and 'os' in caps.keys(): + capability = caps['os'] + os_props_objs = capability.get_properties_objects() + os_props = capability.get_properties() + os_type_prop = capability.get_property_value('type') + break + self.assertEqual( + ['Linux'], + [p.value for p in os_props_objs if p.name == 'type']) + self.assertEqual( + 'Linux', + os_props['type'].value if 'type' in os_props else '') + self.assertEqual('Linux', os_props['type'].value) + self.assertEqual('Linux', os_type_prop) + + def test_outputs(self): + self.assertEqual( + sorted(['receiver_ip', 'receiver_port']), + sorted([output.name for output in self.topo.outputs])) + + def test_groups(self): + group = self.topo.groups[0] + self.assertEqual('webserver_group', group.name) + self.assertEqual(['websrv', 'server'], group.members) + for node in group.get_member_nodes(): + if node.name == 'server': + '''Test property value''' + props = node.get_properties() + if props and 'mem_size' in props.keys(): + self.assertEqual(props['mem_size'].value, '4096 MB') + + def test_system_template(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/system.yaml") + system_tosca_template = ToscaTemplate(tpl_path) + self.assertIsNotNone(system_tosca_template) + self.assertEqual( + len(system_tosca_template. + nested_tosca_templates_with_topology), 4) + self.assertTrue(system_tosca_template.has_nested_templates()) + + def test_invalid_keyname(self): + tpl_snippet = ''' + substitution_mappings: + node_type: example.DatabaseSubsystem + capabilities: + database_endpoint: [ db_app, database_endpoint ] + requirements: + receiver1: [ tran_app, receiver1 ] + invalid_key: 123 + ''' + sub_mappings = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['substitution_mappings'] + expected_message = _( + 'SubstitutionMappings contains unknown field ' + '"invalid_key". Refer to the definition ' + 'to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: SubstitutionMappings(sub_mappings, None, None, + None, None, None)) + self.assertEqual(expected_message, err.__str__()) + + def test_missing_required_keyname(self): + tpl_snippet = ''' + substitution_mappings: + capabilities: + database_endpoint: [ db_app, database_endpoint ] + requirements: + receiver1: [ tran_app, receiver1 ] + ''' + sub_mappings = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['substitution_mappings'] + expected_message = _('SubstitutionMappings used in topology_template ' + 'is missing required field "node_type".') + err = self.assertRaises( + exception.MissingRequiredFieldError, + lambda: SubstitutionMappings(sub_mappings, None, None, + None, None, None)) + self.assertEqual(expected_message, err.__str__()) + + def test_invalid_nodetype(self): + tpl_snippet = ''' + substitution_mappings: + node_type: example.DatabaseSubsystem1 + capabilities: + database_endpoint: [ db_app, database_endpoint ] + requirements: + receiver1: [ tran_app, receiver1 ] + ''' + sub_mappings = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['substitution_mappings'] + custom_defs = self._get_custom_types() + expected_message = _('Node type "example.DatabaseSubsystem1" ' + 'is not a valid type.') + err = self.assertRaises( + exception.InvalidNodeTypeError, + lambda: SubstitutionMappings(sub_mappings, None, None, + None, None, custom_defs)) + self.assertEqual(expected_message, err.__str__()) + + def test_system_with_input_validation(self): + tpl_path0 = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/validate/system_invalid_input.yaml") + tpl_path1 = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/validate/" + "queuingsubsystem_invalid_input.yaml") + errormsg = _('SubstitutionMappings with node_type ' + 'example.QueuingSubsystem is missing ' + 'required input definition of input "server_port".') + + # It's invalid in nested template. + self.assertRaises(exception.ValidationError, + lambda: ToscaTemplate(tpl_path0)) + exception.ExceptionCollector.assertExceptionMessage( + exception.MissingRequiredInputError, errormsg) + + # Subtemplate deploy standaolone is also invalid. + self.assertRaises(exception.ValidationError, + lambda: ToscaTemplate(tpl_path1)) + exception.ExceptionCollector.assertExceptionMessage( + exception.MissingRequiredInputError, errormsg) + + def test_system_with_unknown_output_validation(self): + tpl_path0 = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/validate/" + "system_invalid_unknown_output.yaml") + tpl_path1 = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/validate/" + "transactionsubsystem_invalid_unknown_output.yaml") + errormsg = _('Unknown output "my_cpu_output" in SubstitutionMappings ' + 'with node_type example.TransactionSubsystem.') + + # It's invalid in nested template. + self.assertRaises(exception.ValidationError, + lambda: ToscaTemplate(tpl_path0)) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownOutputError, errormsg) + + # Subtemplate deploy standaolone is invalid. + self.assertRaises(exception.ValidationError, + lambda: ToscaTemplate(tpl_path1)) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownOutputError, errormsg) + + def test_system_with_missing_output_validation(self): + tpl_path0 = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/validate/" + "system_invalid_missing_output.yaml") + tpl_path1 = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/topology_template/validate/" + "transactionsubsystem_invalid_missing_output.yaml") + errormsg = _('SubstitutionMappings with node_type ' + 'example.TransactionSubsystem is missing ' + 'required output definition of output "receiver_port".') + + # It's invalid in nested template. + self.assertRaises(exception.ValidationError, + lambda: ToscaTemplate(tpl_path0)) + exception.ExceptionCollector.assertExceptionMessage( + exception.MissingRequiredOutputError, errormsg) + + # Subtemplate deploy standaolone is invalid. + self.assertRaises(exception.ValidationError, + lambda: ToscaTemplate(tpl_path1)) + exception.ExceptionCollector.assertExceptionMessage( + exception.MissingRequiredOutputError, errormsg) diff --git a/nfvparser/toscaparser/tests/test_toscadef.py b/nfvparser/toscaparser/tests/test_toscadef.py new file mode 100644 index 0000000..2e97b0e --- /dev/null +++ b/nfvparser/toscaparser/tests/test_toscadef.py @@ -0,0 +1,346 @@ +# 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. + +from toscaparser.common import exception +from toscaparser.elements.artifacttype import ArtifactTypeDef +from toscaparser.elements.entity_type import EntityType +from toscaparser.elements.grouptype import GroupType +import toscaparser.elements.interfaces as ifaces +from toscaparser.elements.nodetype import NodeType +from toscaparser.elements.policytype import PolicyType +from toscaparser.tests.base import TestCase + +compute_type = NodeType('tosca.nodes.Compute') +component_type = NodeType('tosca.nodes.SoftwareComponent') +network_type = NodeType('tosca.nodes.network.Network') +network_port_type = NodeType('tosca.nodes.network.Port') +webserver_type = NodeType('tosca.nodes.WebServer') +database_type = NodeType('tosca.nodes.Database') +artif_root_type = ArtifactTypeDef('tosca.artifacts.Root') +artif_file_type = ArtifactTypeDef('tosca.artifacts.File') +artif_bash_type = ArtifactTypeDef('tosca.artifacts.Implementation.Bash') +artif_python_type = ArtifactTypeDef('tosca.artifacts.Implementation.Python') +artif_container_docker_type = ArtifactTypeDef('tosca.artifacts.' + 'Deployment.Image.' + 'Container.Docker') +artif_vm_iso_type = ArtifactTypeDef('tosca.artifacts.' + 'Deployment.Image.VM.ISO') +artif_vm_qcow2_type = ArtifactTypeDef('tosca.artifacts.' + 'Deployment.Image.VM.QCOW2') +policy_root_type = PolicyType('tosca.policies.Root') +policy_placement_type = PolicyType('tosca.policies.Placement') +policy_scaling_type = PolicyType('tosca.policies.Scaling') +policy_update_type = PolicyType('tosca.policies.Update') +policy_performance_type = PolicyType('tosca.policies.Performance') +group_type = GroupType('tosca.groups.Root') + + +class ToscaDefTest(TestCase): + def test_type(self): + self.assertEqual(compute_type.type, "tosca.nodes.Compute") + self.assertRaises(exception.InvalidTypeError, NodeType, + 'tosca.nodes.Invalid') + self.assertEqual(network_type.type, "tosca.nodes.network.Network") + self.assertEqual(network_port_type.type, "tosca.nodes.network.Port") + + def test_parent_type(self): + self.assertEqual(compute_type.parent_type.type, "tosca.nodes.Root") + self.assertEqual(network_type.parent_type.type, "tosca.nodes.Root") + self.assertEqual(network_port_type.parent_type.type, + "tosca.nodes.Root") + + def test_group(self): + self.assertEqual(group_type.type, "tosca.groups.Root") + self.assertIsNone(group_type.parent_type) + self.assertIn(ifaces.LIFECYCLE_SHORTNAME, group_type.interfaces) + + def test_capabilities(self): + # Assure the normative Compute node type + # has all the required Capability types + # regardless of symbloc name + # TODO(Matt) - since Compute IS a normative node type + # we SHOULD test symbolic capability names as well + self.assertEqual( + ['tosca.capabilities.Container', + 'tosca.capabilities.Endpoint.Admin', + 'tosca.capabilities.Node', + 'tosca.capabilities.OperatingSystem', + 'tosca.capabilities.Scalable', + 'tosca.capabilities.network.Bindable'], + sorted([c.type for c in compute_type.get_capabilities_objects()])) + # Assure the normative Network node type + # hsa all the required Capability types + # TODO(Matt) - since Network IS a normative node type + # we SHOULD test symbolic capability names as well + self.assertEqual( + ['tosca.capabilities.Node', + 'tosca.capabilities.network.Linkable'], + sorted([c.type for c in network_type.get_capabilities_objects()])) + + # Assure the normative WebServer node type's + # Endpoint cap. has all required property names + # Note: we are testing them in alphabetic sort order + endpoint_props_def_objects = \ + self._get_capability_properties_def_objects( + webserver_type.get_capabilities_objects(), + 'tosca.capabilities.Endpoint') + # Assure WebServer's Endpoint capability's properties have their + # required keyname value set correctly + self.assertEqual( + [('initiator', False), ('network_name', False), ('port', False), + ('port_name', False), ('ports', False), ('protocol', True), + ('secure', False), ('url_path', False)], + sorted([(p.name, p.required) for p in endpoint_props_def_objects])) + + os_props = self._get_capability_properties_def_objects( + compute_type.get_capabilities_objects(), + 'tosca.capabilities.OperatingSystem') + self.assertEqual( + [('architecture', False), ('distribution', False), ('type', False), + ('version', False)], + sorted([(p.name, p.required) for p in os_props])) + + host_props = self._get_capability_properties_def_objects( + compute_type.get_capabilities_objects(), + 'tosca.capabilities.Container') + self.assertEqual( + [('cpu_frequency', False), ('disk_size', False), + ('mem_size', False), ('num_cpus', False)], + sorted([(p.name, p.required) for p in host_props])) + endpoint_admin_properties = 'secure' + endpoint_admin_props_def_objects = \ + self._get_capability_properties_def_objects( + webserver_type.get_capabilities_objects(), + 'tosca.capabilities.Endpoint.Admin') + self.assertIn( + endpoint_admin_properties, + sorted([p.name for p in endpoint_admin_props_def_objects])) + + def _get_capability_properties_def_objects(self, caps, type): + properties_def = None + for cap in caps: + if cap.type == type: + properties_def = cap.get_properties_def_objects() + break + return properties_def + + def _get_capability_properties_def(self, caps, type): + properties_def = None + for cap in caps: + if cap.type == type: + properties_def = cap.get_properties_def() + break + return properties_def + + def test_properties_def(self): + self.assertEqual( + ['name', 'password', 'port', 'user'], + sorted(database_type.get_properties_def().keys())) + + def test_attributes_def(self): + self.assertEqual( + ['networks', 'ports', 'private_address', 'public_address', + 'state', 'tosca_id', 'tosca_name'], + sorted(compute_type.get_attributes_def().keys())) + + def test_requirements(self): + self.assertEqual( + [{'host': {'capability': 'tosca.capabilities.Container', + 'node': 'tosca.nodes.Compute', + 'relationship': 'tosca.relationships.HostedOn'}}, + {'dependency': {'capability': 'tosca.capabilities.Node', + 'node': 'tosca.nodes.Root', + 'occurrences': [0, 'UNBOUNDED'], + 'relationship': 'tosca.relationships.DependsOn'}} + ], + [r for r in component_type.requirements]) + + def test_relationship(self): + self.assertEqual( + [('tosca.relationships.DependsOn', 'tosca.nodes.Root'), + ('tosca.relationships.HostedOn', 'tosca.nodes.Compute')], + sorted([(relation.type, node.type) for + relation, node in component_type.relationship.items()])) + self.assertIn( + ('tosca.relationships.HostedOn', ['tosca.capabilities.Container']), + [(relation.type, relation.valid_target_types) for + relation in list(component_type.relationship.keys())]) + self.assertIn( + ('tosca.relationships.network.BindsTo', 'tosca.nodes.Compute'), + [(relation.type, node.type) for + relation, node in network_port_type.relationship.items()]) + self.assertIn( + ('tosca.relationships.network.LinksTo', + 'tosca.nodes.network.Network'), + [(relation.type, node.type) for + relation, node in network_port_type.relationship.items()]) + + def test_interfaces(self): + self.assertIsNone(compute_type.interfaces) + root_node = NodeType('tosca.nodes.Root') + self.assertIn(ifaces.LIFECYCLE_SHORTNAME, root_node.interfaces) + + def test_artifacts(self): + self.assertIsNone(artif_root_type.parent_type) + self.assertEqual('tosca.artifacts.Root', + artif_file_type.parent_type.type) + self.assertEqual({}, artif_file_type.parent_artifacts) + self.assertEqual(sorted(['tosca.artifacts.Root'], + key=lambda x: str(x)), + sorted([artif_file_type.get_artifact(name) + for name in artif_file_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.artifacts.Implementation', + artif_bash_type.parent_type.type) + self.assertEqual({'tosca.artifacts.Implementation': + {'derived_from': 'tosca.artifacts.Root', + 'description': + 'TOSCA base type for implementation artifacts'}}, + artif_bash_type.parent_artifacts) + self.assertEqual(sorted([['sh'], 'tosca.artifacts.Implementation', + 'Script artifact for the Unix Bash shell', + 'application/x-sh'], key=lambda x: str(x)), + sorted([artif_bash_type.get_artifact(name) + for name in artif_bash_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.artifacts.Implementation', + artif_python_type.parent_type.type) + self.assertEqual({'tosca.artifacts.Implementation': + {'derived_from': 'tosca.artifacts.Root', + 'description': + 'TOSCA base type for implementation artifacts'}}, + artif_python_type.parent_artifacts) + self.assertEqual(sorted([['py'], 'tosca.artifacts.Implementation', + 'Artifact for the interpreted Python' + ' language', 'application/x-python'], + key=lambda x: str(x)), + sorted([artif_python_type.get_artifact(name) + for name in artif_python_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.artifacts.Deployment.Image', + artif_container_docker_type.parent_type.type) + self.assertEqual({'tosca.artifacts.Deployment': + {'derived_from': 'tosca.artifacts.Root', + 'description': + 'TOSCA base type for deployment artifacts'}, + 'tosca.artifacts.Deployment.Image': + {'derived_from': 'tosca.artifacts.Deployment'}}, + artif_container_docker_type.parent_artifacts) + self.assertEqual(sorted(['tosca.artifacts.Deployment.Image', + 'Docker container image'], + key=lambda x: str(x)), + sorted([artif_container_docker_type. + get_artifact(name) for name in + artif_container_docker_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.artifacts.Deployment.Image', + artif_vm_iso_type.parent_type.type) + self.assertEqual({'tosca.artifacts.Deployment': + {'derived_from': 'tosca.artifacts.Root', + 'description': + 'TOSCA base type for deployment artifacts'}, + 'tosca.artifacts.Deployment.Image': + {'derived_from': 'tosca.artifacts.Deployment'}}, + artif_vm_iso_type.parent_artifacts) + self.assertEqual(sorted(['tosca.artifacts.Deployment.Image', + 'Virtual Machine (VM) image in ' + 'ISO disk format', + 'application/octet-stream', ['iso']], + key=lambda x: str(x)), + sorted([artif_vm_iso_type. + get_artifact(name) for name in + artif_vm_iso_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.artifacts.Deployment.Image', + artif_vm_qcow2_type.parent_type.type) + self.assertEqual({'tosca.artifacts.Deployment': + {'derived_from': 'tosca.artifacts.Root', + 'description': + 'TOSCA base type for deployment artifacts'}, + 'tosca.artifacts.Deployment.Image': + {'derived_from': 'tosca.artifacts.Deployment'}}, + artif_vm_qcow2_type.parent_artifacts) + self.assertEqual(sorted(['tosca.artifacts.Deployment.Image', + 'Virtual Machine (VM) image in QCOW v2 ' + 'standard disk format', + 'application/octet-stream', ['qcow2']], + key=lambda x: str(x)), + sorted([artif_vm_qcow2_type. + get_artifact(name) for name in + artif_vm_qcow2_type.defs], + key=lambda x: str(x))) + + def test_policies(self): + self.assertIsNone(policy_root_type.parent_type) + self.assertEqual('tosca.policies.Root', + policy_placement_type.parent_type.type) + self.assertEqual({}, policy_placement_type.parent_policies) + self.assertEqual(sorted(['tosca.policies.Root', + 'The TOSCA Policy Type definition that is ' + 'used to govern placement of TOSCA nodes or ' + 'groups of nodes.'], + key=lambda x: str(x)), + sorted([policy_placement_type.get_policy(name) + for name in policy_placement_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.policies.Root', + policy_scaling_type.parent_type.type) + self.assertEqual({}, policy_scaling_type.parent_policies) + self.assertEqual(sorted(['tosca.policies.Root', + 'The TOSCA Policy Type definition that is ' + 'used to govern scaling of TOSCA nodes or ' + 'groups of nodes.'], + key=lambda x: str(x)), + sorted([policy_scaling_type.get_policy(name) + for name in policy_scaling_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.policies.Root', + policy_update_type.parent_type.type) + self.assertEqual({}, policy_update_type.parent_policies) + self.assertEqual(sorted(['tosca.policies.Root', + 'The TOSCA Policy Type definition that is ' + 'used to govern update of TOSCA nodes or ' + 'groups of nodes.'], + key=lambda x: str(x)), + sorted([policy_update_type.get_policy(name) + for name in policy_update_type.defs], + key=lambda x: str(x))) + + self.assertEqual('tosca.policies.Root', + policy_performance_type.parent_type.type) + self.assertEqual({}, policy_performance_type.parent_policies) + self.assertEqual(sorted(['tosca.policies.Root', + 'The TOSCA Policy Type definition that is ' + 'used to declare performance requirements ' + 'for TOSCA nodes or groups of nodes.'], + key=lambda x: str(x)), + sorted([policy_performance_type.get_policy(name) + for name in policy_performance_type.defs], + key=lambda x: str(x))) + + def test_port_spec(self): + tosca_def = EntityType.TOSCA_DEF + port_spec = tosca_def.get('tosca.datatypes.network.PortSpec') + self.assertEqual(port_spec.get('derived_from'), + 'tosca.datatypes.Root') + properties = port_spec.get('properties') + self.assertEqual( + sorted(['protocol', 'target', 'target_range', 'source', + 'source_range']), + sorted(properties.keys())) diff --git a/nfvparser/toscaparser/tests/test_toscatpl.py b/nfvparser/toscaparser/tests/test_toscatpl.py new file mode 100644 index 0000000..fac8687 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_toscatpl.py @@ -0,0 +1,854 @@ +# 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 os +import six +from toscaparser.common import exception +import toscaparser.elements.interfaces as ifaces +from toscaparser.elements.nodetype import NodeType +from toscaparser.elements.portspectype import PortSpec +from toscaparser.functions import GetInput +from toscaparser.functions import GetProperty +from toscaparser.nodetemplate import NodeTemplate +from toscaparser.tests.base import TestCase +from toscaparser.tosca_template import ToscaTemplate +from toscaparser.utils.gettextutils import _ +import toscaparser.utils.yamlparser + + +class ToscaTemplateTest(TestCase): + '''TOSCA template.''' + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress.yaml") + params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user', + 'db_root_pwd': '12345678'} + tosca = ToscaTemplate(tosca_tpl, parsed_params=params) + tosca_elk_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_elk.yaml") + tosca_repo_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/repositories/tosca_repositories_test_definition.yaml") + + def test_version(self): + self.assertEqual(self.tosca.version, "tosca_simple_yaml_1_0") + + def test_description(self): + expected_description = "TOSCA simple profile with wordpress, " \ + "web server and mysql on the same server." + self.assertEqual(self.tosca.description, expected_description) + + def test_inputs(self): + self.assertEqual( + ['cpus', 'db_name', 'db_port', + 'db_pwd', 'db_root_pwd', 'db_user'], + sorted([input.name for input in self.tosca.inputs])) + + input_name = "db_port" + expected_description = "Port for the MySQL database." + for input in self.tosca.inputs: + if input.name == input_name: + self.assertEqual(input.description, expected_description) + + def test_node_tpls(self): + '''Test nodetemplate names.''' + self.assertEqual( + ['mysql_database', 'mysql_dbms', 'server', + 'webserver', 'wordpress'], + sorted([tpl.name for tpl in self.tosca.nodetemplates])) + + tpl_name = "mysql_database" + expected_type = "tosca.nodes.Database" + expected_properties = ['name', 'password', 'user'] + expected_capabilities = ['database_endpoint', 'feature'] + expected_requirements = [{'host': 'mysql_dbms'}] + ''' TODO: needs enhancement in tosca_elk.yaml.. + expected_relationshp = ['tosca.relationships.HostedOn'] + expected_host = ['mysql_dbms'] + ''' + expected_interface = [ifaces.LIFECYCLE_SHORTNAME] + + for tpl in self.tosca.nodetemplates: + if tpl_name == tpl.name: + '''Test node type.''' + self.assertEqual(tpl.type, expected_type) + + '''Test properties.''' + self.assertEqual( + expected_properties, + sorted(tpl.get_properties().keys())) + + '''Test capabilities.''' + self.assertEqual( + expected_capabilities, + sorted(tpl.get_capabilities().keys())) + + '''Test requirements.''' + self.assertEqual( + expected_requirements, tpl.requirements) + + '''Test relationship.''' + ''' needs enhancements in tosca_elk.yaml + self.assertEqual( + expected_relationshp, + [x.type for x in tpl.relationships.keys()]) + self.assertEqual( + expected_host, + [y.name for y in tpl.relationships.values()]) + ''' + '''Test interfaces.''' + self.assertEqual( + expected_interface, + [x.type for x in tpl.interfaces]) + + if tpl.name == 'server': + '''Test property value''' + props = tpl.get_properties() + if props and 'mem_size' in props.keys(): + self.assertEqual(props['mem_size'].value, '4096 MB') + '''Test capability''' + caps = tpl.get_capabilities() + self.assertIn('os', caps.keys()) + os_props_objs = None + os_props = None + os_type_prop = None + if caps and 'os' in caps.keys(): + capability = caps['os'] + os_props_objs = capability.get_properties_objects() + os_props = capability.get_properties() + os_type_prop = capability.get_property_value('type') + break + self.assertEqual( + ['Linux'], + [p.value for p in os_props_objs if p.name == 'type']) + self.assertEqual( + 'Linux', + os_props['type'].value if 'type' in os_props else '') + self.assertEqual('Linux', os_props['type'].value) + self.assertEqual('Linux', os_type_prop) + + def test_node_inheritance_type(self): + wordpress_node = [ + node for node in self.tosca.nodetemplates + if node.name == 'wordpress'][0] + self.assertTrue( + wordpress_node.is_derived_from("tosca.nodes.WebApplication")) + self.assertTrue( + wordpress_node.is_derived_from("tosca.nodes.Root")) + self.assertFalse( + wordpress_node.is_derived_from("tosca.policies.Root")) + + def test_outputs(self): + self.assertEqual( + ['website_url'], + sorted([output.name for output in self.tosca.outputs])) + + def test_interfaces(self): + wordpress_node = [ + node for node in self.tosca.nodetemplates + if node.name == 'wordpress'][0] + interfaces = wordpress_node.interfaces + self.assertEqual(2, len(interfaces)) + for interface in interfaces: + if interface.name == 'create': + self.assertEqual(ifaces.LIFECYCLE_SHORTNAME, + interface.type) + self.assertEqual('wordpress/wordpress_install.sh', + interface.implementation) + self.assertIsNone(interface.inputs) + elif interface.name == 'configure': + self.assertEqual(ifaces.LIFECYCLE_SHORTNAME, + interface.type) + self.assertEqual('wordpress/wordpress_configure.sh', + interface.implementation) + self.assertEqual(3, len(interface.inputs)) + TestCase.skip(self, 'bug #1440247') + wp_db_port = interface.inputs['wp_db_port'] + self.assertIsInstance(wp_db_port, GetProperty) + self.assertEqual('get_property', wp_db_port.name) + self.assertEqual(['SELF', + 'database_endpoint', + 'port'], + wp_db_port.args) + result = wp_db_port.result() + self.assertIsInstance(result, GetInput) + else: + raise AssertionError( + 'Unexpected interface: {0}'.format(interface.name)) + + def test_normative_type_by_short_name(self): + # test template with a short name Compute + template = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_tosca_normative_type_by_shortname.yaml") + + tosca_tpl = ToscaTemplate(template) + expected_type = "tosca.nodes.Compute" + for tpl in tosca_tpl.nodetemplates: + self.assertEqual(tpl.type, expected_type) + for tpl in tosca_tpl.nodetemplates: + compute_type = NodeType(tpl.type) + self.assertEqual( + sorted(['tosca.capabilities.Container', + 'tosca.capabilities.Endpoint.Admin', + 'tosca.capabilities.Node', + 'tosca.capabilities.OperatingSystem', + 'tosca.capabilities.network.Bindable', + 'tosca.capabilities.Scalable']), + sorted([c.type + for c in compute_type.get_capabilities_objects()])) + + def test_template_with_no_inputs(self): + tosca_tpl = self._load_template('test_no_inputs_in_template.yaml') + self.assertEqual(0, len(tosca_tpl.inputs)) + + def test_template_with_no_outputs(self): + tosca_tpl = self._load_template('test_no_outputs_in_template.yaml') + self.assertEqual(0, len(tosca_tpl.outputs)) + + def test_relationship_interface(self): + template = ToscaTemplate(self.tosca_elk_tpl) + for node_tpl in template.nodetemplates: + if node_tpl.name == 'logstash': + config_interface = 'Configure' + artifact = 'logstash/configure_elasticsearch.py' + relation = node_tpl.relationships + for key in relation.keys(): + rel_tpl = relation.get(key).get_relationship_template() + if rel_tpl: + self.assertTrue(rel_tpl[0].is_derived_from( + "tosca.relationships.Root")) + interfaces = rel_tpl[0].interfaces + for interface in interfaces: + self.assertEqual(config_interface, + interface.type) + self.assertEqual('pre_configure_source', + interface.name) + self.assertEqual(artifact, + interface.implementation) + + def test_relationship(self): + template = ToscaTemplate(self.tosca_elk_tpl) + for node_tpl in template.nodetemplates: + if node_tpl.name == 'paypal_pizzastore': + expected_relationships = ['tosca.relationships.ConnectsTo', + 'tosca.relationships.HostedOn'] + expected_hosts = ['tosca.nodes.Database', + 'tosca.nodes.WebServer'] + self.assertEqual(len(node_tpl.relationships), 2) + self.assertEqual( + expected_relationships, + sorted([k.type for k in node_tpl.relationships.keys()])) + self.assertEqual( + expected_hosts, + sorted([v.type for v in node_tpl.relationships.values()])) + + def test_repositories(self): + template = ToscaTemplate(self.tosca_repo_tpl) + self.assertEqual( + ['repo_code0', 'repo_code1', 'repo_code2'], + sorted([input.name for input in template.repositories])) + + input_name = "repo_code2" + expected_url = "https://github.com/nandinivemula/intern/master" + for input in template.repositories: + if input.name == input_name: + self.assertEqual(input.url, expected_url) + + def test_template_macro(self): + template = ToscaTemplate(self.tosca_elk_tpl) + for node_tpl in template.nodetemplates: + if node_tpl.name == 'mongo_server': + self.assertEqual( + ['disk_size', 'mem_size', 'num_cpus'], + sorted(node_tpl.get_capability('host'). + get_properties().keys())) + + def test_template_requirements(self): + """Test different formats of requirements + + The requirements can be defined in few different ways, + 1. Requirement expressed as a capability with an implicit relationship. + 2. Requirement expressed with explicit relationship. + 3. Requirement expressed with a relationship template. + 4. Requirement expressed via TOSCA types to provision a node + with explicit relationship. + 5. Requirement expressed via TOSCA types with a filter. + """ + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/requirements/test_requirements.yaml") + tosca = ToscaTemplate(tosca_tpl) + for node_tpl in tosca.nodetemplates: + if node_tpl.name == 'my_app': + expected_relationship = [ + ('tosca.relationships.ConnectsTo', 'mysql_database'), + ('tosca.relationships.HostedOn', 'my_webserver')] + actual_relationship = sorted([ + (relation.type, node.name) for + relation, node in node_tpl.relationships.items()]) + self.assertEqual(expected_relationship, actual_relationship) + if node_tpl.name == 'mysql_database': + self.assertEqual( + [('tosca.relationships.HostedOn', 'my_dbms')], + [(relation.type, node.name) for + relation, + node in node_tpl.relationships.items()]) + if node_tpl.name == 'my_server': + self.assertEqual( + [('tosca.relationships.AttachesTo', 'my_storage')], + [(relation.type, node.name) for + relation, + node in node_tpl.relationships.items()]) + + def test_template_requirements_not_implemented(self): + # TODO(spzala): replace this test with new one once TOSCA types look up + # support is implemented. + """Requirements that yet need to be implemented + + The following requirement formats are not yet implemented, + due to look up dependency: + 1. Requirement expressed via TOSCA types to provision a node + with explicit relationship. + 2. Requirement expressed via TOSCA types with a filter. + """ + tpl_snippet_1 = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + description: Requires a particular node type and relationship. + To be full-filled via lookup into node repository. + requirements: + - req1: + node: tosca.nodes.DBMS + relationship: tosca.relationships.HostedOn + ''' + + tpl_snippet_2 = ''' + node_templates: + my_webserver: + type: tosca.nodes.WebServer + description: Requires a particular node type with a filter. + To be full-filled via lookup into node repository. + requirements: + - req1: + node: tosca.nodes.Compute + target_filter: + properties: + num_cpus: { in_range: [ 1, 4 ] } + mem_size: { greater_or_equal: 2 } + capabilities: + - tosca.capabilities.OS: + properties: + architecture: x86_64 + type: linux + ''' + + tpl_snippet_3 = ''' + node_templates: + my_webserver2: + type: tosca.nodes.WebServer + description: Requires a node type with a particular capability. + To be full-filled via lookup into node repository. + requirements: + - req1: + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn + capability: tosca.capabilities.Container + ''' + self._requirements_not_implemented(tpl_snippet_1, 'mysql_database') + self._requirements_not_implemented(tpl_snippet_2, 'my_webserver') + self._requirements_not_implemented(tpl_snippet_3, 'my_webserver2') + + def _requirements_not_implemented(self, tpl_snippet, tpl_name): + nodetemplates = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['node_templates'] + self.assertRaises( + NotImplementedError, + lambda: NodeTemplate(tpl_name, nodetemplates).relationships) + + # Test the following: + # 1. Custom node type derived from 'WebApplication' named 'TestApp' + # with a custom Capability Type 'TestCapability' + # 2. Same as #1, but referencing a custom 'TestCapability' Capability Type + # that is not defined + def test_custom_capability_type_definition(self): + tpl_snippet = ''' + node_templates: + test_app: + type: tosca.nodes.WebApplication.TestApp + capabilities: + test_cap: + properties: + test: 1 + ''' + # custom node type definition with custom capability type definition + custom_def = ''' + tosca.nodes.WebApplication.TestApp: + derived_from: tosca.nodes.WebApplication + capabilities: + test_cap: + type: tosca.capabilities.TestCapability + tosca.capabilities.TestCapability: + derived_from: tosca.capabilities.Root + properties: + test: + type: integer + required: false + ''' + expected_capabilities = ['app_endpoint', 'feature', 'test_cap'] + nodetemplates = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['node_templates'] + custom_def = (toscaparser.utils.yamlparser. + simple_parse(custom_def)) + name = list(nodetemplates.keys())[0] + tpl = NodeTemplate(name, nodetemplates, custom_def) + self.assertEqual( + expected_capabilities, + sorted(tpl.get_capabilities().keys())) + + # custom definition without valid capability type definition + custom_def = ''' + tosca.nodes.WebApplication.TestApp: + derived_from: tosca.nodes.WebApplication + capabilities: + test_cap: + type: tosca.capabilities.TestCapability + ''' + custom_def = (toscaparser.utils.yamlparser. + simple_parse(custom_def)) + tpl = NodeTemplate(name, nodetemplates, custom_def) + err = self.assertRaises( + exception.InvalidTypeError, + lambda: NodeTemplate(name, nodetemplates, + custom_def).get_capabilities_objects()) + self.assertEqual('Type "tosca.capabilities.TestCapability" is not ' + 'a valid type.', six.text_type(err)) + + def test_local_template_with_local_relpath_import(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress.yaml") + params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user', + 'db_root_pwd': '12345678'} + tosca = ToscaTemplate(tosca_tpl, parsed_params=params) + self.assertTrue(tosca.topology_template.custom_defs) + + def test_local_template_with_url_import(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress_with_url_import.yaml") + tosca = ToscaTemplate(tosca_tpl, + parsed_params={'db_root_pwd': '123456'}) + self.assertTrue(tosca.topology_template.custom_defs) + + def test_url_template_with_local_relpath_import(self): + tosca_tpl = ('https://raw.githubusercontent.com/openstack/' + 'tosca-parser/master/toscaparser/tests/data/' + 'tosca_single_instance_wordpress.yaml') + tosca = ToscaTemplate(tosca_tpl, a_file=False, + parsed_params={"db_name": "mysql", + "db_user": "mysql", + "db_root_pwd": "1234", + "db_pwd": "5678", + "db_port": 3306, + "cpus": 4}) + self.assertTrue(tosca.topology_template.custom_defs) + + def test_url_template_with_local_abspath_import(self): + tosca_tpl = ('https://raw.githubusercontent.com/openstack/' + 'tosca-parser/master/toscaparser/tests/data/' + 'tosca_single_instance_wordpress_with_local_abspath_' + 'import.yaml') + self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl, + None, False) + err_msg = (_('Absolute file name "/tmp/tosca-parser/toscaparser/tests' + '/data/custom_types/wordpress.yaml" cannot be used in a ' + 'URL-based input template "%(tpl)s".') + % {'tpl': tosca_tpl}) + exception.ExceptionCollector.assertExceptionMessage(ImportError, + err_msg) + + def test_url_template_with_url_import(self): + tosca_tpl = ('https://raw.githubusercontent.com/openstack/' + 'tosca-parser/master/toscaparser/tests/data/' + 'tosca_single_instance_wordpress_with_url_import.yaml') + tosca = ToscaTemplate(tosca_tpl, a_file=False, + parsed_params={"db_root_pwd": "1234"}) + self.assertTrue(tosca.topology_template.custom_defs) + + def test_csar_parsing_wordpress(self): + csar_archive = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'data/CSAR/csar_wordpress.zip') + self.assertTrue(ToscaTemplate(csar_archive, + parsed_params={"db_name": "mysql", + "db_user": "mysql", + "db_root_pwd": "1234", + "db_pwd": "5678", + "db_port": 3306, + "cpus": 4})) + + def test_csar_parsing_elk_url_based(self): + csar_archive = ('https://github.com/openstack/tosca-parser/raw/master/' + 'toscaparser/tests/data/CSAR/csar_elk.zip') + self.assertTrue(ToscaTemplate(csar_archive, a_file=False, + parsed_params={"my_cpus": 4})) + + def test_nested_imports_in_templates(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_instance_nested_imports.yaml") + tosca = ToscaTemplate(tosca_tpl) + expected_custom_types = ['tosca.nodes.WebApplication.WordPress', + 'test_namespace_prefix.Rsyslog', + 'Test2ndRsyslogType', + 'test_2nd_namespace_prefix.Rsyslog', + 'tosca.nodes.SoftwareComponent.Logstash', + 'tosca.nodes.SoftwareComponent.Rsyslog.' + 'TestRsyslogType'] + self.assertItemsEqual(tosca.topology_template.custom_defs.keys(), + expected_custom_types) + + def test_invalid_template_file(self): + template_file = 'invalid template file' + expected_msg = (_('"%s" is not a valid file.') % template_file) + self.assertRaises( + exception.ValidationError, + ToscaTemplate, template_file, None, False) + exception.ExceptionCollector.assertExceptionMessage(ValueError, + expected_msg) + + def test_multiple_validation_errors(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_multiple_validation_errors.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl, + None) + valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS) + err1_msg = (_('The template version "tosca_simple_yaml_1" is invalid. ' + 'Valid versions are "%s".') % valid_versions) + exception.ExceptionCollector.assertExceptionMessage( + exception.InvalidTemplateVersion, err1_msg) + + err2_msg = _('Import "custom_types/not_there.yaml" is not valid.') + exception.ExceptionCollector.assertExceptionMessage( + ImportError, err2_msg) + + err3_msg = _('Type "tosca.nodes.WebApplication.WordPress" is not a ' + 'valid type.') + exception.ExceptionCollector.assertExceptionMessage( + exception.InvalidTypeError, err3_msg) + + err4_msg = _('Node template "wordpress" contains unknown field ' + '"requirement". Refer to the definition to verify valid ' + 'values.') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, err4_msg) + + err5_msg = _('\'Property "passwords" was not found in node template ' + '"mysql_database".\'') + exception.ExceptionCollector.assertExceptionMessage( + KeyError, err5_msg) + + err6_msg = _('Template "mysql_dbms" is missing required field "type".') + exception.ExceptionCollector.assertExceptionMessage( + exception.MissingRequiredFieldError, err6_msg) + + err7_msg = _('Node template "mysql_dbms" contains unknown field ' + '"type1". Refer to the definition to verify valid ' + 'values.') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, err7_msg) + + err8_msg = _('\'Node template "server1" was not found in ' + '"webserver".\'') + exception.ExceptionCollector.assertExceptionMessage( + KeyError, err8_msg) + + err9_msg = _('"relationship" used in template "webserver" is missing ' + 'required field "type".') + exception.ExceptionCollector.assertExceptionMessage( + exception.MissingRequiredFieldError, err9_msg) + + err10_msg = _('Type "tosca.nodes.XYZ" is not a valid type.') + exception.ExceptionCollector.assertExceptionMessage( + exception.InvalidTypeError, err10_msg) + + def test_invalid_section_names(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_invalid_section_names.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl, + None) + err1_msg = _('Template contains unknown field ' + '"tosca_definitions_versions". Refer to the definition ' + 'to verify valid values.') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, err1_msg) + + err2_msg = _('Template contains unknown field "descriptions". ' + 'Refer to the definition to verify valid values.') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, err2_msg) + + err3_msg = _('Template contains unknown field "import". Refer to ' + 'the definition to verify valid values.') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, err3_msg) + + err4_msg = _('Template contains unknown field "topology_templates". ' + 'Refer to the definition to verify valid values.') + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, err4_msg) + + def test_csar_with_alternate_extenstion(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/CSAR/csar_elk.csar") + tosca = ToscaTemplate(tosca_tpl, parsed_params={"my_cpus": 2}) + self.assertTrue(tosca.topology_template.custom_defs) + + def test_available_rel_tpls(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_available_rel_tpls.yaml") + tosca = ToscaTemplate(tosca_tpl) + for node in tosca.nodetemplates: + for relationship, target in node.relationships.items(): + try: + target.relationships + except TypeError as error: + self.fail(error) + + def test_no_input(self): + self.assertRaises(exception.ValidationError, ToscaTemplate, None, + None, False, None) + err_msg = (('No path or yaml_dict_tpl was provided. ' + 'There is nothing to parse.')) + exception.ExceptionCollector.assertExceptionMessage(ValueError, + err_msg) + + def test_path_and_yaml_dict_tpl_input(self): + test_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_helloworld.yaml") + + yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl) + + tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl) + + self.assertEqual(tosca.version, "tosca_simple_yaml_1_0") + + def test_yaml_dict_tpl_input(self): + test_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_helloworld.yaml") + + yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl) + + tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl) + + self.assertEqual(tosca.version, "tosca_simple_yaml_1_0") + + def test_yaml_dict_tpl_with_params_and_url_import(self): + test_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress_with_url_import.yaml") + + yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl) + + params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user', + 'db_root_pwd': 'mypasswd'} + + tosca = ToscaTemplate(parsed_params=params, + yaml_dict_tpl=yaml_dict_tpl) + + self.assertEqual(tosca.version, "tosca_simple_yaml_1_0") + + def test_yaml_dict_tpl_with_rel_import(self): + test_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress.yaml") + + yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl) + params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user', + 'db_root_pwd': '12345678'} + self.assertRaises(exception.ValidationError, ToscaTemplate, None, + params, False, yaml_dict_tpl) + err_msg = (_('Relative file name "custom_types/wordpress.yaml" ' + 'cannot be used in a pre-parsed input template.')) + exception.ExceptionCollector.assertExceptionMessage(ImportError, + err_msg) + + def test_yaml_dict_tpl_with_fullpath_import(self): + test_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress.yaml") + + yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl) + + yaml_dict_tpl['imports'] = [os.path.join(os.path.dirname( + os.path.abspath(__file__)), "data/custom_types/wordpress.yaml")] + + params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user', + 'db_root_pwd': 'mypasswd'} + + tosca = ToscaTemplate(parsed_params=params, + yaml_dict_tpl=yaml_dict_tpl) + + self.assertEqual(tosca.version, "tosca_simple_yaml_1_0") + + def test_policies_for_node_templates(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/policies/tosca_policy_template.yaml") + tosca = ToscaTemplate(tosca_tpl) + + for policy in tosca.topology_template.policies: + self.assertTrue( + policy.is_derived_from("tosca.policies.Root")) + if policy.name == 'my_compute_placement_policy': + self.assertEqual('tosca.policies.Placement', policy.type) + self.assertEqual(['my_server_1', 'my_server_2'], + policy.targets) + self.assertEqual('node_templates', policy.get_targets_type()) + for node in policy.targets_list: + if node.name == 'my_server_1': + '''Test property value''' + props = node.get_properties() + if props and 'mem_size' in props.keys(): + self.assertEqual(props['mem_size'].value, + '4096 MB') + + def test_policies_for_groups(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/policies/tosca_policy_template.yaml") + tosca = ToscaTemplate(tosca_tpl) + + for policy in tosca.topology_template.policies: + self.assertTrue( + policy.is_derived_from("tosca.policies.Root")) + if policy.name == 'my_groups_placement': + self.assertEqual('mycompany.mytypes.myScalingPolicy', + policy.type) + self.assertEqual(['webserver_group'], policy.targets) + self.assertEqual('groups', policy.get_targets_type()) + group = policy.get_targets_list()[0] + for node in group.get_member_nodes(): + if node.name == 'my_server_2': + '''Test property value''' + props = node.get_properties() + if props and 'mem_size' in props.keys(): + self.assertEqual(props['mem_size'].value, + '4096 MB') + + def test_node_filter(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/node_filter/test_node_filter.yaml") + ToscaTemplate(tosca_tpl) + + def test_attributes_inheritance(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_attributes_inheritance.yaml") + ToscaTemplate(tosca_tpl) + + def test_repositories_definition(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/repositories/test_repositories_definition.yaml") + ToscaTemplate(tosca_tpl) + + def test_custom_caps_def(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_custom_caps_def.yaml") + ToscaTemplate(tosca_tpl) + + def test_custom_rel_with_script(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_tosca_custom_rel_with_script.yaml") + tosca = ToscaTemplate(tosca_tpl) + rel = tosca.relationship_templates[0] + self.assertEqual(rel.type, "tosca.relationships.HostedOn") + self.assertTrue(rel.is_derived_from("tosca.relationships.Root")) + self.assertEqual(len(rel.interfaces), 1) + self.assertEqual(rel.interfaces[0].type, "Configure") + + def test_various_portspec_errors(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/datatypes/test_datatype_portspec_add_req.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl, + None) + + # TODO(TBD) find way to reuse error messages from constraints.py + msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of ' + 'range "(min:%(vmin)s, max:%(vmax)s)".') % + dict(pname=PortSpec.SOURCE, + pvalue='0', + vmin='1', + vmax='65535')) + exception.ExceptionCollector.assertExceptionMessage( + exception.ValidationError, msg) + + # Test value below range min. + msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of ' + 'range "(min:%(vmin)s, max:%(vmax)s)".') % + dict(pname=PortSpec.SOURCE, + pvalue='1', + vmin='2', + vmax='65534')) + exception.ExceptionCollector.assertExceptionMessage( + exception.RangeValueError, msg) + + # Test value above range max. + msg = (_('The value "%(pvalue)s" of property "%(pname)s" is out of ' + 'range "(min:%(vmin)s, max:%(vmax)s)".') % + dict(pname=PortSpec.SOURCE, + pvalue='65535', + vmin='2', + vmax='65534')) + exception.ExceptionCollector.assertExceptionMessage( + exception.RangeValueError, msg) + + def test_containers(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/containers/test_container_docker_mysql.yaml") + ToscaTemplate(tosca_tpl, parsed_params={"mysql_root_pwd": "12345678"}) + + def test_endpoint_on_compute(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_endpoint_on_compute.yaml") + ToscaTemplate(tosca_tpl) + + def test_nested_dsl_def(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/dsl_definitions/test_nested_dsl_def.yaml") + self.assertIsNotNone(ToscaTemplate(tosca_tpl)) + + def test_multiple_policies(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/policies/test_tosca_nfv_multiple_policies.yaml") + tosca = ToscaTemplate(tosca_tpl) + self.assertEqual( + ['ALRM1', 'SP1', 'SP2'], + sorted([policy.name for policy in tosca.policies])) diff --git a/nfvparser/toscaparser/tests/test_toscatplvalidation.py b/nfvparser/toscaparser/tests/test_toscatplvalidation.py new file mode 100644 index 0000000..911867f --- /dev/null +++ b/nfvparser/toscaparser/tests/test_toscatplvalidation.py @@ -0,0 +1,1784 @@ +# 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 os +import six + +from toscaparser.common import exception +from toscaparser.imports import ImportsLoader +from toscaparser.nodetemplate import NodeTemplate +from toscaparser.parameters import Input +from toscaparser.parameters import Output +from toscaparser.policy import Policy +from toscaparser.relationship_template import RelationshipTemplate +from toscaparser.repositories import Repository +from toscaparser.tests.base import TestCase +from toscaparser.topology_template import TopologyTemplate +from toscaparser.tosca_template import ToscaTemplate +from toscaparser.triggers import Triggers +from toscaparser.utils.gettextutils import _ +import toscaparser.utils.yamlparser + + +class ToscaTemplateValidationTest(TestCase): + + def test_well_defined_template(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_single_instance_wordpress.yaml") + params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user', + 'db_root_pwd': '12345678'} + self.assertIsNotNone(ToscaTemplate(tpl_path, params)) + + def test_custom_interface_allowed(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/interfaces/test_custom_interface_in_template.yaml") + self.assertIsNotNone(ToscaTemplate(tpl_path)) + + def test_custom_interface_invalid_operation(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/interfaces/test_custom_interface_invalid_operation.yaml") + self.assertRaises(exception.ValidationError, + ToscaTemplate, tpl_path) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('"interfaces" of template "customInterfaceTest" ' + 'contains unknown field "CustomOp4". ' + 'Refer to the definition to verify valid values.')) + + def test_first_level_sections(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_tosca_top_level_error1.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path) + exception.ExceptionCollector.assertExceptionMessage( + exception.MissingRequiredFieldError, + _('Template is missing required field ' + '"tosca_definitions_version".')) + + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_tosca_top_level_error2.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Template contains unknown field "node_template". Refer to the ' + 'definition to verify valid values.')) + + def test_template_with_imports_validation(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/tosca_imports_validation.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Template custom_types/imported_sample.yaml contains unknown ' + 'field "descriptions". Refer to the definition' + ' to verify valid values.')) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Template custom_types/imported_sample.yaml contains unknown ' + 'field "node_typess". Refer to the definition to ' + 'verify valid values.')) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Template custom_types/imported_sample.yaml contains unknown ' + 'field "tosca1_definitions_version". Refer to the definition' + ' to verify valid values.')) + exception.ExceptionCollector.assertExceptionMessage( + exception.InvalidTemplateVersion, + _('The template version "tosca_simple_yaml_1_10 in ' + 'custom_types/imported_sample.yaml" is invalid. ' + 'Valid versions are "tosca_simple_yaml_1_0, ' + 'tosca_simple_profile_for_nfv_1_0_0".')) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Template custom_types/imported_sample.yaml contains unknown ' + 'field "policy_types1". Refer to the definition to ' + 'verify valid values.')) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Nodetype"tosca.nodes.SoftwareComponent.Logstash" contains ' + 'unknown field "capabilities1". Refer to the definition ' + 'to verify valid values.')) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Policy "mycompany.mytypes.myScalingPolicy" contains unknown ' + 'field "derived1_from". Refer to the definition to ' + 'verify valid values.')) + exception.ExceptionCollector.assertExceptionMessage( + exception.UnknownFieldError, + _('Relationshiptype "test.relation.connects" contains unknown ' + 'field "derived_from4". Refer to the definition to ' + 'verify valid values.')) + + def test_getoperation_IncorrectValue(self): + # test case 1 + tpl_snippet = ''' + node_templates: + front_end: + type: tosca.nodes.Compute + interfaces: + Standard: + create: + implementation: scripts/frontend/create.sh + configure: + implementation: scripts/frontend/configure.sh + inputs: + data_dir: {get_operation_output: [front_end,Standard1, + create,data_dir]} + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + err = self.assertRaises(ValueError, + TopologyTemplate, tpl, None) + expectedmessage = _('Enter a valid interface name') + self.assertEqual(expectedmessage, err.__str__()) + # test case 2 + tpl_snippet2 = ''' + node_templates: + front_end: + type: tosca.nodes.Compute + interfaces: + Standard: + create: + implementation: scripts/frontend/create.sh + configure: + implementation: scripts/frontend/configure.sh + inputs: + data_dir: {get_operation_output: [front_end1,Standard, + create,data_dir]} + ''' + tpl2 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet2)) + err2 = self.assertRaises(KeyError, + TopologyTemplate, tpl2, None) + expectedmessage2 = _('\'Node template "front_end1" was not found.\'') + self.assertEqual(expectedmessage2, err2.__str__()) + # test case 3 + tpl_snippet3 = ''' + node_templates: + front_end: + type: tosca.nodes.Compute + interfaces: + Standard: + create: + implementation: scripts/frontend/create.sh + configure: + implementation: scripts/frontend/configure.sh + inputs: + data_dir: {get_operation_output: [front_end,Standard, + get_target,data_dir]} + ''' + tpl3 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet3)) + err3 = self.assertRaises(ValueError, + TopologyTemplate, tpl3, None) + expectedmessage3 = _('Enter an operation of Standard interface') + self.assertEqual(expectedmessage3, err3.__str__()) + # test case 4 + tpl_snippet4 = ''' + node_templates: + front_end: + type: tosca.nodes.Compute + interfaces: + Standard: + create: + implementation: scripts/frontend/create.sh + configure: + implementation: scripts/frontend/configure.sh + inputs: + data_dir: {get_operation_output: [front_end,Configure, + create,data_dir]} + ''' + tpl4 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet4)) + err4 = self.assertRaises(ValueError, + TopologyTemplate, tpl4, None) + expectedmessage4 = _('Enter an operation of Configure interface') + self.assertEqual(expectedmessage4, err4.__str__()) + # test case 5 + tpl_snippet5 = ''' + node_templates: + front_end: + type: tosca.nodes.Compute + interfaces: + Standard: + create: + implementation: scripts/frontend/create.sh + configure: + implementation: scripts/frontend/configure.sh + inputs: + data_dir: {get_operation_output: [front_end,Standard, + create]} + ''' + tpl5 = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet5)) + err5 = self.assertRaises(ValueError, + TopologyTemplate, tpl5, None) + expectedmessage5 = _('Illegal arguments for function' + ' "get_operation_output".' + ' Expected arguments: "template_name",' + '"interface_name",' + '"operation_name","output_variable_name"') + self.assertEqual(expectedmessage5, err5.__str__()) + + def test_unsupported_type(self): + tpl_snippet = ''' + node_templates: + invalid_type: + type: tosca.test.invalidtype + properties: + size: { get_input: storage_size } + snapshot_id: { get_input: storage_snapshot_id } + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + err = self.assertRaises(exception.UnsupportedTypeError, + TopologyTemplate, tpl, None) + expectedmessage = _('Type "tosca.test.invalidtype" is valid' + ' TOSCA type but not supported at this time.') + self.assertEqual(expectedmessage, err.__str__()) + + def test_inputs(self): + tpl_snippet1 = ''' + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraint: + - valid_values: [ 1, 2, 4 ] + required: yes + status: supported + ''' + tpl_snippet2 = ''' + inputs: + cpus: + type: integer + description: Number of CPUs for the server. + constraints: + - valid_values: [ 1, 2, 4 ] + required: yes + status: supported + ''' + tpl_snippet3 = ''' + inputs: + some_list: + type: list + description: List of items + entry_schema: + type: string + default: [] + ''' + inputs1 = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet1)['inputs']) + name1, attrs1 = list(inputs1.items())[0] + inputs2 = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet2)['inputs']) + name2, attrs2 = list(inputs2.items())[0] + try: + Input(name1, attrs1) + except Exception as err: + self.assertEqual(_('Input "cpus" contains unknown field ' + '"constraint". Refer to the definition to ' + 'verify valid values.'), + err.__str__()) + input2 = Input(name2, attrs2) + self.assertTrue(input2.required) + toscaparser.utils.yamlparser.simple_parse(tpl_snippet3)['inputs'] + + def _imports_content_test(self, tpl_snippet, path, custom_type_def): + imports = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet)['imports']) + loader = ImportsLoader(imports, path, custom_type_def) + return loader.get_custom_defs() + + def test_imports_without_templates(self): + tpl_snippet = ''' + imports: + # omitted here for brevity + ''' + path = 'toscaparser/tests/data/tosca_elk.yaml' + errormsg = _('"imports" keyname is defined without including ' + 'templates.') + err = self.assertRaises(exception.ValidationError, + self._imports_content_test, + tpl_snippet, + path, + "node_types") + self.assertEqual(errormsg, err.__str__()) + + def test_imports_with_name_without_templates(self): + tpl_snippet = ''' + imports: + - some_definitions: + ''' + path = 'toscaparser/tests/data/tosca_elk.yaml' + errormsg = _('A template file name is not provided with import ' + 'definition "some_definitions".') + err = self.assertRaises(exception.ValidationError, + self._imports_content_test, + tpl_snippet, path, None) + self.assertEqual(errormsg, err.__str__()) + + def test_imports_without_import_name(self): + tpl_snippet = ''' + imports: + - custom_types/paypalpizzastore_nodejs_app.yaml + - https://raw.githubusercontent.com/openstack/\ +tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml + ''' + path = 'toscaparser/tests/data/tosca_elk.yaml' + custom_defs = self._imports_content_test(tpl_snippet, + path, + "node_types") + self.assertTrue(custom_defs) + + def test_imports_wth_import_name(self): + tpl_snippet = ''' + imports: + - some_definitions: custom_types/paypalpizzastore_nodejs_app.yaml + - more_definitions: + file: 'https://raw.githubusercontent.com/openstack/tosca-parser\ +/master/toscaparser/tests/data/custom_types/wordpress.yaml' + namespace_prefix: single_instance_wordpress + ''' + path = 'toscaparser/tests/data/tosca_elk.yaml' + custom_defs = self._imports_content_test(tpl_snippet, + path, + "node_types") + self.assertTrue(custom_defs.get("single_instance_wordpress.tosca." + "nodes.WebApplication.WordPress")) + + def test_imports_wth_namespace_prefix(self): + tpl_snippet = ''' + imports: + - more_definitions: + file: custom_types/nested_rsyslog.yaml + namespace_prefix: testprefix + ''' + path = 'toscaparser/tests/data/tosca_elk.yaml' + custom_defs = self._imports_content_test(tpl_snippet, + path, + "node_types") + self.assertTrue(custom_defs.get("testprefix.Rsyslog")) + + def test_imports_with_no_main_template(self): + tpl_snippet = ''' + imports: + - some_definitions: https://raw.githubusercontent.com/openstack/\ +tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml + - some_definitions: + file: my_defns/my_typesdefs_n.yaml + ''' + errormsg = _('Input tosca template is not provided.') + err = self.assertRaises(exception.ValidationError, + self._imports_content_test, + tpl_snippet, None, None) + self.assertEqual(errormsg, err.__str__()) + + def test_imports_duplicate_name(self): + tpl_snippet = ''' + imports: + - some_definitions: https://raw.githubusercontent.com/openstack/\ +tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml + - some_definitions: + file: my_defns/my_typesdefs_n.yaml + ''' + errormsg = _('Duplicate import name "some_definitions" was found.') + path = 'toscaparser/tests/data/tosca_elk.yaml' + err = self.assertRaises(exception.ValidationError, + self._imports_content_test, + tpl_snippet, path, None) + self.assertEqual(errormsg, err.__str__()) + + def test_imports_missing_req_field_in_def(self): + tpl_snippet = ''' + imports: + - more_definitions: + file1: my_defns/my_typesdefs_n.yaml + repository: my_company_repo + namespace_uri: http://mycompany.com/ns/tosca/2.0 + namespace_prefix: mycompany + ''' + errormsg = _('Import of template "more_definitions" is missing ' + 'required field "file".') + path = 'toscaparser/tests/data/tosca_elk.yaml' + err = self.assertRaises(exception.MissingRequiredFieldError, + self._imports_content_test, + tpl_snippet, path, None) + self.assertEqual(errormsg, err.__str__()) + + def test_imports_file_with_uri(self): + tpl_snippet = ''' + imports: + - more_definitions: + file: https://raw.githubusercontent.com/openstack/\ +tosca-parser/master/toscaparser/tests/data/custom_types/wordpress.yaml + ''' + path = 'https://raw.githubusercontent.com/openstack/\ +tosca-parser/master/toscaparser/tests/data/\ +tosca_single_instance_wordpress_with_url_import.yaml' + custom_defs = self._imports_content_test(tpl_snippet, + path, + "node_types") + self.assertTrue(custom_defs.get("tosca.nodes." + "WebApplication.WordPress")) + + def test_imports_file_namespace_fields(self): + tpl_snippet = ''' + imports: + - more_definitions: + file: https://raw.githubusercontent.com/openstack/\ +heat-translator/master/translator/tests/data/custom_types/wordpress.yaml + namespace_prefix: mycompany + namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0 + ''' + path = 'toscaparser/tests/data/tosca_elk.yaml' + custom_defs = self._imports_content_test(tpl_snippet, + path, + "node_types") + self.assertTrue(custom_defs.get("mycompany.tosca.nodes." + "WebApplication.WordPress")) + + def test_import_error_file_uri(self): + tpl_snippet = ''' + imports: + - more_definitions: + file: mycompany.com/ns/tosca/2.0/toscaparser/tests/data\ +/tosca_elk.yaml + namespace_prefix: mycompany + namespace_uri: http://docs.oasis-open.org/tosca/ns/simple/yaml/1.0 + ''' + path = 'toscaparser/tests/data/tosca_elk.yaml' + self.assertRaises(ImportError, + self._imports_content_test, + tpl_snippet, path, None) + + def test_import_single_line_error(self): + tpl_snippet = ''' + imports: + - some_definitions: abc.com/tests/data/tosca_elk.yaml + ''' + errormsg = _('Import "abc.com/tests/data/tosca_elk.yaml" is not ' + 'valid.') + path = 'toscaparser/tests/data/tosca_elk.yaml' + err = self.assertRaises(ImportError, + self._imports_content_test, + tpl_snippet, path, None) + self.assertEqual(errormsg, err.__str__()) + + def test_outputs(self): + tpl_snippet = ''' + outputs: + server_address: + description: IP address of server instance. + values: { get_property: [server, private_address] } + ''' + outputs = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet)['outputs']) + name, attrs = list(outputs.items())[0] + output = Output(name, attrs) + try: + output.validate() + except Exception as err: + self.assertTrue( + isinstance(err, exception.MissingRequiredFieldError)) + self.assertEqual(_('Output "server_address" is missing required ' + 'field "value".'), err.__str__()) + + tpl_snippet = ''' + outputs: + server_address: + descriptions: IP address of server instance. + value: { get_property: [server, private_address] } + ''' + outputs = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet)['outputs']) + name, attrs = list(outputs.items())[0] + output = Output(name, attrs) + try: + output.validate() + except Exception as err: + self.assertIsInstance(err, exception.UnknownFieldError) + self.assertEqual(_('Output "server_address" contains unknown ' + 'field "descriptions". Refer to the definition ' + 'to verify valid values.'), + err.__str__()) + + def _repo_content(self, path): + repositories = path['repositories'] + reposit = [] + for name, val in repositories.items(): + reposits = Repository(name, val) + reposit.append(reposits) + return reposit + + def test_repositories(self): + tpl_snippet = ''' + repositories: + repo_code0: https://raw.githubusercontent.com/nandinivemula/intern + repo_code1: + description: My project's code Repository in github usercontent. + url: https://github.com/nandinivemula/intern + credential: + user: nandini + password: tcs@12345 + repo_code2: + description: My Project's code Repository in github. + url: https://github.com/nandinivemula/intern + credential: + user: xyzw + password: xyz@123 + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + repoobject = self._repo_content(tpl) + actualrepo_names = [] + for repo in repoobject: + repos = repo.name + actualrepo_names.append(repos) + reposname = list(tpl.values()) + reposnames = reposname[0] + expected_reponames = list(reposnames.keys()) + self.assertEqual(expected_reponames, actualrepo_names) + + def test_repositories_with_missing_required_field(self): + tpl_snippet = ''' + repositories: + repo_code0: https://raw.githubusercontent.com/nandinivemula/intern + repo_code1: + description: My project's code Repository in github usercontent. + credential: + user: nandini + password: tcs@12345 + repo_code2: + description: My Project's code Repository in github. + url: https://github.com/nandinivemula/intern + credential: + user: xyzw + password: xyz@123 + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + err = self.assertRaises(exception.MissingRequiredFieldError, + self._repo_content, tpl) + expectedmessage = _('Repository "repo_code1" is missing ' + 'required field "url".') + self.assertEqual(expectedmessage, err.__str__()) + + def test_repositories_with_unknown_field(self): + tpl_snippet = ''' + repositories: + repo_code0: https://raw.githubusercontent.com/nandinivemula/intern + repo_code1: + description: My project's code Repository in github usercontent. + url: https://github.com/nandinivemula/intern + credential: + user: nandini + password: tcs@12345 + repo_code2: + descripton: My Project's code Repository in github. + url: https://github.com/nandinivemula/intern + credential: + user: xyzw + password: xyz@123 + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + err = self.assertRaises(exception.UnknownFieldError, + self._repo_content, tpl) + expectedmessage = _('repositories "repo_code2" contains unknown field' + ' "descripton". Refer to the definition to verify' + ' valid values.') + self.assertEqual(expectedmessage, err.__str__()) + + def test_repositories_with_invalid_url(self): + tpl_snippet = ''' + repositories: + repo_code0: https://raw.githubusercontent.com/nandinivemula/intern + repo_code1: + description: My project's code Repository in github usercontent. + url: h + credential: + user: nandini + password: tcs@12345 + repo_code2: + description: My Project's code Repository in github. + url: https://github.com/nandinivemula/intern + credential: + user: xyzw + password: xyz@123 + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + err = self.assertRaises(exception.URLException, + self._repo_content, tpl) + expectedmessage = _('repsositories "repo_code1" Invalid Url') + self.assertEqual(expectedmessage, err.__str__()) + + def test_groups(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: aaa + port: 3376 + + groups: + webserver_group: + type: tosca.groups.Root + members: [ server, mysql_dbms ] + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + TopologyTemplate(tpl, None) + + def test_groups_with_missing_required_field(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: aaa + port: 3376 + + groups: + webserver_group: + members: ['server', 'mysql_dbms'] + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + err = self.assertRaises(exception.MissingRequiredFieldError, + TopologyTemplate, tpl, None) + expectedmessage = _('Template "webserver_group" is missing ' + 'required field "type".') + self.assertEqual(expectedmessage, err.__str__()) + + def test_groups_with_unknown_target(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: aaa + port: 3376 + + groups: + webserver_group: + type: tosca.groups.Root + members: [ serv, mysql_dbms ] + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + expectedmessage = _('"Target member "serv" is not found in ' + 'node_templates"') + err = self.assertRaises(exception.InvalidGroupTargetException, + TopologyTemplate, tpl, None) + self.assertEqual(expectedmessage, err.__str__()) + + def test_groups_with_repeated_targets(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: aaa + port: 3376 + + groups: + webserver_group: + type: tosca.groups.Root + members: [ server, server, mysql_dbms ] + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + expectedmessage = _('"Member nodes ' + '"[\'server\', \'server\', \'mysql_dbms\']" ' + 'should be >= 1 and not repeated"') + err = self.assertRaises(exception.InvalidGroupTargetException, + TopologyTemplate, tpl, None) + self.assertEqual(expectedmessage, err.__str__()) + + def test_groups_with_only_one_target(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: aaa + port: 3376 + + groups: + webserver_group: + type: tosca.groups.Root + members: [] + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + expectedmessage = _('"Member nodes "[]" should be >= 1 ' + 'and not repeated"') + err = self.assertRaises(exception.InvalidGroupTargetException, + TopologyTemplate, tpl, None) + self.assertEqual(expectedmessage, err.__str__()) + + def _custom_types(self): + custom_types = {} + def_file = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/custom_types/wordpress.yaml") + custom_type = toscaparser.utils.yamlparser.load_yaml(def_file) + node_types = custom_type['node_types'] + for name in node_types: + defintion = node_types[name] + custom_types[name] = defintion + return custom_types + + def _single_node_template_content_test(self, tpl_snippet): + nodetemplates = (toscaparser.utils.yamlparser. + simple_ordered_parse(tpl_snippet))['node_templates'] + name = list(nodetemplates.keys())[0] + nodetemplate = NodeTemplate(name, nodetemplates, + self._custom_types()) + nodetemplate.validate() + nodetemplate.requirements + nodetemplate.get_capabilities_objects() + nodetemplate.get_properties_objects() + nodetemplate.interfaces + + def test_node_templates(self): + tpl_snippet = ''' + node_templates: + server: + capabilities: + host: + properties: + disk_size: 10 + num_cpus: 4 + mem_size: 4096 + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + ''' + expectedmessage = _('Template "server" is missing required field ' + '"type".') + err = self.assertRaises( + exception.MissingRequiredFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_with_wrong_properties_keyname(self): + """Node template keyname 'properties' given as 'propertiessss'.""" + tpl_snippet = ''' + node_templates: + mysql_dbms: + type: tosca.nodes.DBMS + propertiessss: + root_password: aaa + port: 3376 + ''' + expectedmessage = _('Node template "mysql_dbms" contains unknown ' + 'field "propertiessss". Refer to the definition ' + 'to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_with_wrong_requirements_keyname(self): + """Node template keyname 'requirements' given as 'requirement'.""" + tpl_snippet = ''' + node_templates: + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: aaa + port: 3376 + requirement: + - host: server + ''' + expectedmessage = _('Node template "mysql_dbms" contains unknown ' + 'field "requirement". Refer to the definition to ' + 'verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_with_wrong_interfaces_keyname(self): + """Node template keyname 'interfaces' given as 'interfac'.""" + tpl_snippet = ''' + node_templates: + mysql_dbms: + type: tosca.nodes.DBMS + properties: + root_password: aaa + port: 3376 + requirements: + - host: server + interfac: + Standard: + configure: mysql_database_configure.sh + ''' + expectedmessage = _('Node template "mysql_dbms" contains unknown ' + 'field "interfac". Refer to the definition to ' + 'verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_with_wrong_capabilities_keyname(self): + """Node template keyname 'capabilities' given as 'capabilitiis'.""" + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + properties: + db_name: { get_input: db_name } + db_user: { get_input: db_user } + db_password: { get_input: db_pwd } + capabilitiis: + database_endpoint: + properties: + port: { get_input: db_port } + ''' + expectedmessage = _('Node template "mysql_database" contains unknown ' + 'field "capabilitiis". Refer to the definition to ' + 'verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_with_wrong_artifacts_keyname(self): + """Node template keyname 'artifacts' given as 'artifactsss'.""" + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + artifactsss: + db_content: + implementation: files/my_db_content.txt + type: tosca.artifacts.File + ''' + expectedmessage = _('Node template "mysql_database" contains unknown ' + 'field "artifactsss". Refer to the definition to ' + 'verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_with_multiple_wrong_keynames(self): + """Node templates given with multiple wrong keynames.""" + tpl_snippet = ''' + node_templates: + mysql_dbms: + type: tosca.nodes.DBMS + propertieees: + root_password: aaa + port: 3376 + requirements: + - host: server + interfacs: + Standard: + configure: mysql_database_configure.sh + ''' + expectedmessage = _('Node template "mysql_dbms" contains unknown ' + 'field "propertieees". Refer to the definition to ' + 'verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + properties: + name: { get_input: db_name } + user: { get_input: db_user } + password: { get_input: db_pwd } + capabilitiiiies: + database_endpoint: + properties: + port: { get_input: db_port } + requirementsss: + - host: + node: mysql_dbms + interfac: + Standard: + configure: mysql_database_configure.sh + + ''' + expectedmessage = _('Node template "mysql_database" contains unknown ' + 'field "capabilitiiiies". Refer to the definition ' + 'to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_type(self): + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Databases + properties: + db_name: { get_input: db_name } + db_user: { get_input: db_user } + db_password: { get_input: db_pwd } + capabilities: + database_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: mysql_dbms + interfaces: + Standard: + configure: mysql_database_configure.sh + ''' + expectedmessage = _('Type "tosca.nodes.Databases" is not ' + 'a valid type.') + err = self.assertRaises( + exception.InvalidTypeError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements(self): + tpl_snippet = ''' + node_templates: + webserver: + type: tosca.nodes.WebServer + requirements: + host: server + interfaces: + Standard: + create: webserver_install.sh + start: d.sh + ''' + expectedmessage = _('"requirements" of template "webserver" must be ' + 'of type "list".') + err = self.assertRaises( + exception.TypeMismatchError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + properties: + db_name: { get_input: db_name } + db_user: { get_input: db_user } + db_password: { get_input: db_pwd } + capabilities: + database_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: mysql_dbms + - database_endpoint: mysql_database + interfaces: + Standard: + configure: mysql_database_configure.sh + ''' + expectedmessage = _('"requirements" of template "mysql_database" ' + 'contains unknown field "database_endpoint". ' + 'Refer to the definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements_with_wrong_node_keyname(self): + """Node template requirements keyname 'node' given as 'nodes'.""" + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + requirements: + - host: + nodes: mysql_dbms + + ''' + expectedmessage = _('"requirements" of template "mysql_database" ' + 'contains unknown field "nodes". Refer to the ' + 'definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements_with_wrong_capability_keyname(self): + """Incorrect node template requirements keyname + + Node template requirements keyname 'capability' given as + 'capabilityy'. + """ + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + requirements: + - host: + node: mysql_dbms + - log_endpoint: + node: logstash + capabilityy: log_endpoint + relationship: + type: tosca.relationships.ConnectsTo + + ''' + expectedmessage = _('"requirements" of template "mysql_database" ' + 'contains unknown field "capabilityy". Refer to ' + 'the definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements_with_wrong_relationship_keyname(self): + """Incorrect node template requirements keyname + + Node template requirements keyname 'relationship' given as + 'relationshipppp'. + """ + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + requirements: + - host: + node: mysql_dbms + - log_endpoint: + node: logstash + capability: log_endpoint + relationshipppp: + type: tosca.relationships.ConnectsTo + + ''' + expectedmessage = _('"requirements" of template "mysql_database" ' + 'contains unknown field "relationshipppp". Refer ' + 'to the definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements_with_wrong_occurrences_keyname(self): + """Incorrect node template requirements keyname + + Node template requirements keyname 'occurrences' given as + 'occurences'. + """ + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + requirements: + - host: + node: mysql_dbms + - log_endpoint: + node: logstash + capability: log_endpoint + relationship: + type: tosca.relationships.ConnectsTo + occurences: [0, UNBOUNDED] + ''' + expectedmessage = _('"requirements" of template "mysql_database" ' + 'contains unknown field "occurences". Refer to ' + 'the definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements_with_multiple_wrong_keynames(self): + """Node templates given with multiple wrong requirements keynames.""" + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + requirements: + - host: + node: mysql_dbms + - log_endpoint: + nod: logstash + capabilit: log_endpoint + relationshipppp: + type: tosca.relationships.ConnectsTo + + ''' + expectedmessage = _('"requirements" of template "mysql_database" ' + 'contains unknown field "nod". Refer to the ' + 'definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + requirements: + - host: + node: mysql_dbms + - log_endpoint: + node: logstash + capabilit: log_endpoint + relationshipppp: + type: tosca.relationships.ConnectsTo + + ''' + expectedmessage = _('"requirements" of template "mysql_database" ' + 'contains unknown field "capabilit". Refer to the ' + 'definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements_invalid_occurrences(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + occurrences: [0, -1] + ''' + expectedmessage = _('Value of property "[0, -1]" is invalid.') + err = self.assertRaises( + exception.InvalidPropertyValueError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + occurrences: [a, w] + ''' + expectedmessage = _('"a" is not an integer.') + err = self.assertRaises( + ValueError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + occurrences: -1 + ''' + expectedmessage = _('"-1" is not a list.') + err = self.assertRaises( + ValueError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + occurrences: [5, 1] + ''' + expectedmessage = _('Value of property "[5, 1]" is invalid.') + err = self.assertRaises( + exception.InvalidPropertyValueError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + occurrences: [0, 0] + ''' + expectedmessage = _('Value of property "[0, 0]" is invalid.') + err = self.assertRaises( + exception.InvalidPropertyValueError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_requirements_valid_occurrences(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + requirements: + - log_endpoint: + capability: log_endpoint + occurrences: [2, 2] + ''' + self._single_node_template_content_test(tpl_snippet) + + def test_node_template_capabilities(self): + tpl_snippet = ''' + node_templates: + mysql_database: + type: tosca.nodes.Database + properties: + db_name: { get_input: db_name } + db_user: { get_input: db_user } + db_password: { get_input: db_pwd } + capabilities: + http_endpoint: + properties: + port: { get_input: db_port } + requirements: + - host: mysql_dbms + interfaces: + Standard: + configure: mysql_database_configure.sh + ''' + expectedmessage = _('"capabilities" of template "mysql_database" ' + 'contains unknown field "http_endpoint". Refer to ' + 'the definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_properties(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + properties: + os_image: F18_x86_64 + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + ''' + expectedmessage = _('"properties" of template "server" contains ' + 'unknown field "os_image". Refer to the ' + 'definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_interfaces(self): + tpl_snippet = ''' + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standards: + create: wordpress_install.sh + configure: + implementation: wordpress_configure.sh + inputs: + wp_db_name: { get_property: [ mysql_database, db_name ] } + wp_db_user: { get_property: [ mysql_database, db_user ] } + wp_db_password: { get_property: [ mysql_database, \ + db_password ] } + wp_db_port: { get_property: [ SELF, \ + database_endpoint, port ] } + ''' + expectedmessage = _('"interfaces" of template "wordpress" contains ' + 'unknown field "Standards". Refer to the ' + 'definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standard: + create: wordpress_install.sh + config: + implementation: wordpress_configure.sh + inputs: + wp_db_name: { get_property: [ mysql_database, db_name ] } + wp_db_user: { get_property: [ mysql_database, db_user ] } + wp_db_password: { get_property: [ mysql_database, \ + db_password ] } + wp_db_port: { get_property: [ SELF, \ + database_endpoint, port ] } + ''' + expectedmessage = _('"interfaces" of template "wordpress" contains ' + 'unknown field "config". Refer to the definition ' + 'to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + wordpress: + type: tosca.nodes.WebApplication.WordPress + requirements: + - host: webserver + - database_endpoint: mysql_database + interfaces: + Standard: + create: wordpress_install.sh + configure: + implementation: wordpress_configure.sh + input: + wp_db_name: { get_property: [ mysql_database, db_name ] } + wp_db_user: { get_property: [ mysql_database, db_user ] } + wp_db_password: { get_property: [ mysql_database, \ + db_password ] } + wp_db_port: { get_ref_property: [ database_endpoint, \ + database_endpoint, port ] } + ''' + expectedmessage = _('"interfaces" of template "wordpress" contains ' + 'unknown field "input". Refer to the definition ' + 'to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_relationship_template_properties(self): + tpl_snippet = ''' + relationship_templates: + storage_attachto: + type: AttachesTo + properties: + device: test_device + ''' + expectedmessage = _('"properties" of template "storage_attachto" is ' + 'missing required field "[\'location\']".') + rel_template = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['relationship_templates'] + name = list(rel_template.keys())[0] + rel_template = RelationshipTemplate(rel_template[name], name) + err = self.assertRaises(exception.MissingRequiredFieldError, + rel_template.validate) + self.assertEqual(expectedmessage, six.text_type(err)) + + def test_invalid_template_version(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_invalid_template_version.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tosca_tpl) + valid_versions = ', '.join(ToscaTemplate.VALID_TEMPLATE_VERSIONS) + exception.ExceptionCollector.assertExceptionMessage( + exception.InvalidTemplateVersion, + (_('The template version "tosca_xyz" is invalid. Valid versions ' + 'are "%s".') % valid_versions)) + + def test_node_template_capabilities_properties(self): + # validating capability property values + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.WebServer + capabilities: + data_endpoint: + properties: + initiator: test + ''' + expectedmessage = _('The value "test" of property "initiator" is ' + 'not valid. Expected a value from "[source, ' + 'target, peer]".') + + err = self.assertRaises( + exception.ValidationError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + host: + properties: + disk_size: 10 GB + num_cpus: { get_input: cpus } + mem_size: 4096 MB + os: + properties: + architecture: x86_64 + type: Linux + distribution: Fedora + version: 18.0 + scalable: + properties: + min_instances: 1 + max_instances: 3 + default_instances: 5 + ''' + expectedmessage = _('"properties" of template "server": ' + '"default_instances" value is not between ' + '"min_instances" and "max_instances".') + err = self.assertRaises( + exception.ValidationError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_objectstorage_without_required_property(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.ObjectStorage + properties: + maxsize: 1 GB + ''' + expectedmessage = _('"properties" of template "server" is missing ' + 'required field "[\'name\']".') + err = self.assertRaises( + exception.MissingRequiredFieldError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_objectstorage_with_invalid_scalar_unit(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.ObjectStorage + properties: + name: test + maxsize: -1 + ''' + expectedmessage = _('"-1" is not a valid scalar-unit.') + err = self.assertRaises( + ValueError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_node_template_objectstorage_with_invalid_scalar_type(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.ObjectStorage + properties: + name: test + maxsize: 1 XB + ''' + expectedmessage = _('"1 XB" is not a valid scalar-unit.') + err = self.assertRaises( + ValueError, + lambda: self._single_node_template_content_test(tpl_snippet)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_special_keywords(self): + """Test special keywords + + Test that special keywords, e.g. metadata, which are not part + of specification do not throw any validation error. + """ + tpl_snippet_metadata_map = ''' + node_templates: + server: + type: tosca.nodes.Compute + metadata: + name: server A + role: master + ''' + self._single_node_template_content_test(tpl_snippet_metadata_map) + + tpl_snippet_metadata_inline = ''' + node_templates: + server: + type: tosca.nodes.Compute + metadata: none + ''' + self._single_node_template_content_test(tpl_snippet_metadata_inline) + + def test_policy_valid_keynames(self): + tpl_snippet = ''' + policies: + - servers_placement: + type: tosca.policies.Placement + description: Apply placement policy to servers + metadata: { user1: 1001, user2: 1002 } + targets: [ serv1, serv2 ] + ''' + policies = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['policies'][0] + name = list(policies.keys())[0] + Policy(name, policies[name], None, None) + + def test_policy_invalid_keyname(self): + tpl_snippet = ''' + policies: + - servers_placement: + type: tosca.policies.Placement + testkey: testvalue + ''' + policies = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['policies'][0] + name = list(policies.keys())[0] + + expectedmessage = _('Policy "servers_placement" contains ' + 'unknown field "testkey". Refer to the ' + 'definition to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: Policy(name, policies[name], None, None)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_policy_trigger_valid_keyname(self): + tpl_snippet = ''' + triggers: + - resize_compute: + description: trigger + event_type: tosca.events.resource.utilization + schedule: + start_time: "2015-05-07T07:00:00Z" + end_time: "2015-06-07T07:00:00Z" + target_filter: + node: master-container + requirement: host + capability: Container + condition: + constraint: { greater_than: 50 } + period: 60 + evaluations: 1 + method : average + action: + resize: # Operation name + inputs: + strategy: LEAST_USED + implementation: Senlin.webhook() + ''' + triggers = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['triggers'][0] + name = list(triggers.keys())[0] + Triggers(name, triggers[name]) + + def test_policy_trigger_invalid_keyname(self): + tpl_snippet = ''' + triggers: + - resize_compute: + description: trigger + event_type: tosca.events.resource.utilization + schedule: + start_time: "2015-05-07T07:00:00Z" + end_time: "2015-06-07T07:00:00Z" + target_filter1: + node: master-container + requirement: host + capability: Container + condition: + constraint: utilization greater_than 50% + period1: 60 + evaluations: 1 + method: average + action: + resize: # Operation name + inputs: + strategy: LEAST_USED + implementation: Senlin.webhook() + ''' + triggers = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['triggers'][0] + name = list(triggers.keys())[0] + expectedmessage = _( + 'Triggers "resize_compute" contains unknown field ' + '"target_filter1". Refer to the definition ' + 'to verify valid values.') + err = self.assertRaises( + exception.UnknownFieldError, + lambda: Triggers(name, triggers[name])) + self.assertEqual(expectedmessage, err.__str__()) + + def test_policy_missing_required_keyname(self): + tpl_snippet = ''' + policies: + - servers_placement: + description: test description + ''' + policies = (toscaparser.utils.yamlparser. + simple_parse(tpl_snippet))['policies'][0] + name = list(policies.keys())[0] + + expectedmessage = _('Template "servers_placement" is missing ' + 'required field "type".') + err = self.assertRaises( + exception.MissingRequiredFieldError, + lambda: Policy(name, policies[name], None, None)) + self.assertEqual(expectedmessage, err.__str__()) + + def test_credential_datatype(self): + tosca_tpl = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_credential_datatype.yaml") + self.assertIsNotNone(ToscaTemplate(tosca_tpl)) + + def test_invalid_default_value(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_invalid_input_defaults.yaml") + self.assertRaises(exception.ValidationError, ToscaTemplate, tpl_path) + exception.ExceptionCollector.assertExceptionMessage( + ValueError, _('"two" is not an integer.')) + + def test_invalid_capability(self): + tpl_snippet = ''' + node_templates: + server: + type: tosca.nodes.Compute + capabilities: + oss: + properties: + architecture: x86_64 + ''' + tpl = (toscaparser.utils.yamlparser.simple_parse(tpl_snippet)) + err = self.assertRaises(exception.UnknownFieldError, + TopologyTemplate, tpl, None) + expectedmessage = _('"capabilities" of template "server" contains ' + 'unknown field "oss". Refer to the definition ' + 'to verify valid values.') + self.assertEqual(expectedmessage, err.__str__()) + + def test_qualified_name(self): + tpl_snippet_full_name = ''' + node_templates: + supported_type: + type: tosca.nodes.Compute + ''' + tpl = ( + toscaparser.utils.yamlparser.simple_parse( + tpl_snippet_full_name)) + TopologyTemplate(tpl, None) + + tpl_snippet_short_name = ''' + node_templates: + supported_type: + type: Compute + ''' + tpl = ( + toscaparser.utils.yamlparser.simple_parse( + tpl_snippet_short_name)) + TopologyTemplate(tpl, None) + + tpl_snippet_qualified_name = ''' + node_templates: + supported_type: + type: tosca:Compute + ''' + tpl = ( + toscaparser.utils.yamlparser.simple_parse( + tpl_snippet_qualified_name)) + TopologyTemplate(tpl, None) + + def test_requirements_as_list(self): + """Node template with requirements provided with or without list + + Node template requirements are required to be provided as list. + """ + + expectedmessage = _('"requirements" of template "my_webserver"' + ' must be of type "list".') + + # requirements provided as dictionary + tpl_snippet1 = ''' + node_templates: + my_webserver: + type: tosca.nodes.WebServer + requirements: + host: server + server: + type: tosca.nodes.Compute + ''' + err1 = self.assertRaises( + exception.TypeMismatchError, + lambda: self._single_node_template_content_test(tpl_snippet1)) + self.assertEqual(expectedmessage, err1.__str__()) + + # requirements provided as string + tpl_snippet2 = ''' + node_templates: + my_webserver: + type: tosca.nodes.WebServer + requirements: server + server: + type: tosca.nodes.Compute + ''' + err2 = self.assertRaises( + exception.TypeMismatchError, + lambda: self._single_node_template_content_test(tpl_snippet2)) + self.assertEqual(expectedmessage, err2.__str__()) + + # requirements provided as list + tpl_snippet3 = ''' + node_templates: + my_webserver: + type: tosca.nodes.WebServer + requirements: + - host: server + server: + type: tosca.nodes.Compute + ''' + self.assertIsNone( + self._single_node_template_content_test(tpl_snippet3)) + + def test_properties_override_with_flavor_and_image(self): + tpl_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "data/test_normative_type_properties_override.yaml") + self.assertIsNotNone(ToscaTemplate(tpl_path)) diff --git a/nfvparser/toscaparser/tests/test_utils.py b/nfvparser/toscaparser/tests/test_utils.py new file mode 100644 index 0000000..fca024d --- /dev/null +++ b/nfvparser/toscaparser/tests/test_utils.py @@ -0,0 +1,48 @@ +# 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. + +from toscaparser.tests.base import TestCase +import toscaparser.utils.urlutils +import toscaparser.utils.yamlparser + +YAML_LOADER = toscaparser.utils.yamlparser.load_yaml + + +class UrlUtilsTest(TestCase): + + url_utils = toscaparser.utils.urlutils.UrlUtils + + def test_urlutils_validate_url(self): + self.assertTrue(self.url_utils.validate_url("http://www.github.com/")) + self.assertTrue( + self.url_utils.validate_url("https://github.com:81/a/2/a.b")) + self.assertTrue(self.url_utils.validate_url("ftp://github.com")) + self.assertFalse(self.url_utils.validate_url("github.com")) + self.assertFalse(self.url_utils.validate_url("123")) + self.assertFalse(self.url_utils.validate_url("a/b/c")) + self.assertTrue(self.url_utils.validate_url("file:///dir/file.ext")) + + def test_urlutils_join_url(self): + self.assertEqual( + self.url_utils.join_url("http://github.com/proj1", "proj2"), + "http://github.com/proj2") + self.assertEqual( + self.url_utils.join_url("http://github.com/proj1/scripts/a.js", + "b.js"), + "http://github.com/proj1/scripts/b.js") + self.assertEqual( + self.url_utils.join_url("http://github.com/proj1/scripts", "b.js"), + "http://github.com/proj1/b.js") + self.assertEqual( + self.url_utils.join_url("http://github.com/proj1/scripts", + "scripts/b.js"), + "http://github.com/proj1/scripts/b.js") diff --git a/nfvparser/toscaparser/tests/test_validate_tosca_version.py b/nfvparser/toscaparser/tests/test_validate_tosca_version.py new file mode 100644 index 0000000..e9a8ac2 --- /dev/null +++ b/nfvparser/toscaparser/tests/test_validate_tosca_version.py @@ -0,0 +1,132 @@ +# 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. + +from toscaparser.common.exception import ( + InvalidTOSCAVersionPropertyException) +from toscaparser.tests.base import TestCase +from toscaparser.utils.gettextutils import _ +from toscaparser.utils.validateutils import TOSCAVersionProperty + + +class TOSCAVersionPropertyTest(TestCase): + + def test_tosca_version_property(self): + version = '18.0.3.beta-1' + expected_output = '18.0.3.beta-1' + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = 18 + expected_output = '18.0' + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = 18.0 + expected_output = '18.0' + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = '18.0.3' + expected_output = '18.0.3' + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = 0 + expected_output = None + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = 00 + expected_output = None + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = 0.0 + expected_output = None + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = 00.00 + expected_output = None + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + version = '0.0.0' + expected_output = None + output = TOSCAVersionProperty(version).get_version() + self.assertEqual(output, expected_output) + + def test_tosca_version_property_invalid_major_version(self): + + version = 'x' + exp_msg = _('Value of TOSCA version property "x" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + def test_tosca_version_property_invalid_minor_version(self): + + version = '18.x' + exp_msg = _('Value of TOSCA version property "18.x" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + version = '18.x.y' + exp_msg = _('Value of TOSCA version property "18.x.y" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + version = '18-2' + exp_msg = _('Value of TOSCA version property "18-2" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + def test_tosca_version_property_invalid_fix_version(self): + + version = '18.0.a' + exp_msg = _('Value of TOSCA version property "18.0.a" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + def test_tosca_version_property_invalid_qualifier(self): + + version = '18.0.1-xyz' + exp_msg = _('Value of TOSCA version property "18.0.1-xyz" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + version = '0.0.0.abc' + exp_msg = _('Value of TOSCA version property "0.0.0.abc" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + def test_tosca_version_property_invalid_build_version(self): + + version = '18.0.1.abc-x' + exp_msg = _('Value of TOSCA version property ' + '"18.0.1.abc-x" is invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) + + version = '0.0.0.abc-x' + exp_msg = _('Value of TOSCA version property "0.0.0.abc-x" is ' + 'invalid.') + err = self.assertRaises(InvalidTOSCAVersionPropertyException, + TOSCAVersionProperty, version) + self.assertEqual(exp_msg, err.__str__()) |