Add base and packages for tempest murano scenario tests
This commit adds implementation of methods and resources which are used for tempest app deployment and cinder volumes support tests Change-Id: Ibd70aa56987d8f69547fb9f114b6a1a69cfcbe0c targets: bp normalize-murano-tests
This commit is contained in:
parent
6b66e9914d
commit
36915a927d
@ -49,6 +49,10 @@ ApplicationCatalogGroup = [
|
||||
"If no such region is found in the service catalog, "
|
||||
"the first found one is used."),
|
||||
|
||||
cfg.StrOpt("linux_image",
|
||||
default="debian-8-m-agent.qcow2",
|
||||
help="Image for linux services"),
|
||||
|
||||
cfg.StrOpt("catalog_type",
|
||||
default="application-catalog",
|
||||
help="Catalog type of Application Catalog."),
|
||||
@ -70,7 +74,14 @@ ApplicationCatalogGroup = [
|
||||
cfg.BoolOpt("glare_backend",
|
||||
default=False,
|
||||
help="Tells tempest about murano glare backend "
|
||||
"configuration.")
|
||||
"configuration."),
|
||||
cfg.BoolOpt("cinder_volume_tests",
|
||||
default=False,
|
||||
help="Whether or not cinder volumes attachment tests "
|
||||
"are expected to run"),
|
||||
cfg.BoolOpt("deployment_tests",
|
||||
default=False,
|
||||
help="Whether or not deployment tests are expected to run")
|
||||
]
|
||||
|
||||
ServiceBrokerGroup = [
|
||||
|
@ -0,0 +1,81 @@
|
||||
# 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.
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.apps.test
|
||||
std: io.murano
|
||||
res: io.murano.resources
|
||||
sys: io.murano.system
|
||||
conf: io.murano.configuration
|
||||
|
||||
|
||||
Name: ApacheHttpServerCustom
|
||||
|
||||
Extends: std:Application
|
||||
|
||||
Properties:
|
||||
name:
|
||||
Contract: $.string().notNull()
|
||||
|
||||
instance:
|
||||
Contract: $.class(res:Instance).notNull()
|
||||
|
||||
userName:
|
||||
Contract: $.string()
|
||||
|
||||
Methods:
|
||||
initialize:
|
||||
Body:
|
||||
- $._environment: $.find(std:Environment).require()
|
||||
|
||||
deploy:
|
||||
Body:
|
||||
- If: not $.getAttr(deployed, false)
|
||||
Then:
|
||||
- $._environment.reporter.report($this, 'Creating VM for Apache Server.')
|
||||
- $securityGroupIngress:
|
||||
- ToPort: 80
|
||||
FromPort: 80
|
||||
IpProtocol: tcp
|
||||
External: true
|
||||
- ToPort: 443
|
||||
FromPort: 443
|
||||
IpProtocol: tcp
|
||||
External: true
|
||||
- $._environment.securityGroupManager.addGroupIngress($securityGroupIngress)
|
||||
- $.instance.deploy()
|
||||
- $._environment.reporter.report($this, 'Instance is created. Deploying Apache')
|
||||
|
||||
- $resources: new(sys:Resources)
|
||||
- $linux: new(conf:Linux)
|
||||
|
||||
- $linux.runCommand($.instance.agent, 'apt-get -y install apache2')
|
||||
- $linux.runCommand($.instance.agent, 'iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT')
|
||||
- $linux.runCommand($.instance.agent, 'iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT')
|
||||
- $._environment.reporter.report($this, 'Apache is installed.')
|
||||
|
||||
- If: $.userName != ''
|
||||
Then:
|
||||
- $linux.runCommand($.instance.agent, 'service apache2 stop')
|
||||
- $fileReplacements:
|
||||
"%USER_NAME%": $.userName
|
||||
- $fileContent: $resources.string('index.html').replace($fileReplacements)
|
||||
- $linux.putFile($.instance.agent, $fileContent, '/var/www/html/index.html')
|
||||
- $linux.runCommand($.instance.agent, 'service apache2 start')
|
||||
|
||||
- If: $.instance.assignFloatingIp
|
||||
Then:
|
||||
- $host: $.instance.floatingIpAddress
|
||||
Else:
|
||||
- $host: $.instance.ipAddresses[0]
|
||||
- $._environment.reporter.report($this, format('Apache is available at http://{0}', $host))
|
||||
- $.setAttr(deployed, true)
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> Hello World</title>
|
||||
</head>
|
||||
<body>Hello world. This is my first web page. My name is %USER_NAME%.
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
Format: 1.0
|
||||
Type: Application
|
||||
FullName: io.murano.test.apache.ApacheHttpServerCustom
|
||||
Name: Apache HTTP Server Custom
|
||||
Description: |
|
||||
The Apache HTTP Server Project is an effort to develop and maintain an
|
||||
open-source HTTP server for modern operating systems including UNIX and
|
||||
Windows NT. The goal of this project is to provide a secure, efficient and
|
||||
extensible server that provides HTTP services in sync with the current HTTP
|
||||
standards.
|
||||
Apache httpd has been the most popular web server on the Internet since
|
||||
April 1996, and celebrated its 17th birthday as a project this February.
|
||||
Author: 'Mirantis, Inc'
|
||||
Tags: [HTTP, Server, WebServer, HTML, Apache]
|
||||
Classes:
|
||||
io.murano.apps.test.ApacheHttpServerCustom: ApacheHttpServer.yaml
|
@ -0,0 +1,55 @@
|
||||
# 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.
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.apps.test
|
||||
std: io.murano
|
||||
sys: io.murano.system
|
||||
|
||||
Name: Lighttpd
|
||||
|
||||
Extends: std:Application
|
||||
|
||||
Properties:
|
||||
updater:
|
||||
Contract: $.class(UpdateExecutor).notNull()
|
||||
|
||||
Methods:
|
||||
initialize:
|
||||
Body:
|
||||
- $._environment: $.find(std:Environment).require()
|
||||
|
||||
deploy:
|
||||
Body:
|
||||
- If: not $.getAttr(deployed, false)
|
||||
Then:
|
||||
- $securityGroupIngress:
|
||||
- ToPort: 80
|
||||
FromPort: 80
|
||||
IpProtocol: tcp
|
||||
External: true
|
||||
- ToPort: 443
|
||||
FromPort: 443
|
||||
IpProtocol: tcp
|
||||
External: true
|
||||
- $._environment.securityGroupManager.addGroupIngress($securityGroupIngress)
|
||||
- $._environment.reporter.report($this, 'Ensuring Updater is deployed.')
|
||||
- $.updater.deploy()
|
||||
- $resources: new(sys:Resources)
|
||||
- $template: $resources.yaml('DeployLighttpd.template')
|
||||
- $.updater.instance.agent.call($template, $resources)
|
||||
|
||||
- If: $.updater.instance.assignFloatingIp
|
||||
Then:
|
||||
- $address: $.updater.instance.floatingIpAddress
|
||||
- $._environment.reporter.report($this, format('Running at http://{0}', $address))
|
||||
- $.setAttr(deployed, true)
|
@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
FormatVersion: 2.0.0
|
||||
Version: 1.0.0
|
||||
Name: Deploy Lighttpd
|
||||
|
||||
Body: |
|
||||
deploy()
|
||||
|
||||
Scripts:
|
||||
deploy:
|
||||
Type: Application
|
||||
Version: 1.0.0
|
||||
EntryPoint: deployLighttpd.sh
|
||||
Options:
|
||||
captureStdout: true
|
||||
captureStderr: true
|
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
sudo apt-get -y -q install lighttpd
|
@ -0,0 +1,24 @@
|
||||
# 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.
|
||||
|
||||
Format: 1.0
|
||||
Type: Application
|
||||
FullName: io.murano.apps.test.Lighttpd
|
||||
Name: Lighttpd
|
||||
Description: |
|
||||
Lighttpd... :)
|
||||
Author: 'Mirantis, Inc'
|
||||
Tags: [Web]
|
||||
Classes:
|
||||
io.murano.apps.test.Lighttpd: Lighttpd.yaml
|
||||
Require:
|
||||
io.murano.apps.test.UpdateExecutor:
|
@ -0,0 +1,47 @@
|
||||
# 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.
|
||||
|
||||
Namespaces:
|
||||
=: io.murano.apps.test
|
||||
std: io.murano
|
||||
res: io.murano.resources
|
||||
sys: io.murano.system
|
||||
conf: io.murano.configuration
|
||||
|
||||
|
||||
Name: UpdateExecutor
|
||||
|
||||
Extends: std:Application
|
||||
|
||||
Properties:
|
||||
name:
|
||||
Contract: $.string().notNull()
|
||||
|
||||
instance:
|
||||
Contract: $.class(res:Instance).notNull()
|
||||
|
||||
Methods:
|
||||
initialize:
|
||||
Body:
|
||||
- $._environment: $.find(std:Environment).require()
|
||||
|
||||
deploy:
|
||||
Body:
|
||||
- If: not $.getAttr(deployed, false)
|
||||
Then:
|
||||
- $._environment.reporter.report($this, 'Creating VM.')
|
||||
- $.instance.deploy()
|
||||
- $._environment.reporter.report($this, 'Starting packages updating.')
|
||||
- $file: sys:Resources.string('scripts/update.sh')
|
||||
- conf:Linux.runCommand($.instance.agent, $file)
|
||||
- $._environment.reporter.report($this, 'Update completed.')
|
||||
- $.setAttr(deployed, true)
|
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
sudo apt-get update
|
@ -0,0 +1,22 @@
|
||||
# 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.
|
||||
|
||||
Format: 1.0
|
||||
Type: Application
|
||||
FullName: io.murano.apps.test.UpdateExecutor
|
||||
Name: Update Executor
|
||||
Description: |
|
||||
Test application, which updates packages on VM
|
||||
Author: 'Mirantis, Inc'
|
||||
Tags: [application]
|
||||
Classes:
|
||||
io.murano.apps.test.UpdateExecutor: UpdateExecutor.yaml
|
0
murano_tempest_tests/tests/scenario/__init__.py
Normal file
0
murano_tempest_tests/tests/scenario/__init__.py
Normal file
335
murano_tempest_tests/tests/scenario/application_catalog/base.py
Normal file
335
murano_tempest_tests/tests/scenario/application_catalog/base.py
Normal file
@ -0,0 +1,335 @@
|
||||
# Copyright (c) 2016 Mirantis, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import requests
|
||||
import socket
|
||||
import time
|
||||
|
||||
from tempest.clients import Manager as services_manager
|
||||
from tempest.common import credentials_factory as common_creds
|
||||
from tempest.common import dynamic_creds
|
||||
from tempest.common import waiters
|
||||
from tempest import config
|
||||
from tempest.lib import base
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from murano_tempest_tests import clients
|
||||
from murano_tempest_tests import utils
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class BaseApplicationCatalogScenarioTest(base.BaseTestCase):
|
||||
"""Base test class for Murano Application Catalog Scenario tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(BaseApplicationCatalogScenarioTest, cls).setUpClass()
|
||||
cls.resource_setup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.resource_cleanup()
|
||||
super(BaseApplicationCatalogScenarioTest, cls).tearDownClass()
|
||||
|
||||
@classmethod
|
||||
def get_client_with_isolated_creds(cls, type_of_creds="admin"):
|
||||
|
||||
creds = cls.get_configured_isolated_creds(type_of_creds=type_of_creds)
|
||||
|
||||
os = clients.Manager(credentials=creds)
|
||||
client = os.application_catalog_client
|
||||
|
||||
return client
|
||||
|
||||
@classmethod
|
||||
def get_configured_isolated_creds(cls, type_of_creds='admin'):
|
||||
identity_version = CONF.identity.auth_version
|
||||
if identity_version == 'v3':
|
||||
cls.admin_role = CONF.identity.admin_role
|
||||
else:
|
||||
cls.admin_role = 'admin'
|
||||
if not hasattr(cls, 'dynamic_cred'):
|
||||
cls.dynamic_cred = dynamic_creds.DynamicCredentialProvider(
|
||||
identity_version=CONF.identity.auth_version,
|
||||
name=cls.__name__, admin_role=cls.admin_role,
|
||||
admin_creds=common_creds.get_configured_admin_credentials(
|
||||
'identity_admin'))
|
||||
if type_of_creds == 'primary':
|
||||
creds = cls.dynamic_cred.get_primary_creds()
|
||||
elif type_of_creds == 'admin':
|
||||
creds = cls.dynamic_cred.get_admin_creds()
|
||||
elif type_of_creds == 'alt':
|
||||
creds = cls.dynamic_cred.get_alt_creds()
|
||||
else:
|
||||
creds = cls.dynamic_cred.get_credentials(type_of_creds)
|
||||
cls.dynamic_cred.type_of_creds = type_of_creds
|
||||
|
||||
return creds.credentials
|
||||
|
||||
@classmethod
|
||||
def verify_nonempty(cls, *args):
|
||||
if not all(args):
|
||||
msg = "Missing API credentials in configuration."
|
||||
raise cls.skipException(msg)
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
if not CONF.service_available.murano:
|
||||
skip_msg = "Murano is disabled"
|
||||
raise cls.skipException(skip_msg)
|
||||
if not hasattr(cls, "os"):
|
||||
creds = cls.get_configured_isolated_creds(type_of_creds='primary')
|
||||
cls.os = clients.Manager(credentials=creds)
|
||||
cls.services_manager = services_manager(creds)
|
||||
cls.linux_image = CONF.application_catalog.linux_image
|
||||
cls.application_catalog_client = cls.os.application_catalog_client
|
||||
cls.artifacts_client = cls.os.artifacts_client
|
||||
cls.servers_client = cls.services_manager.servers_client
|
||||
cls.orchestration_client = cls.services_manager.orchestration_client
|
||||
cls.snapshots_client = cls.services_manager.snapshots_client
|
||||
cls.volumes_client = cls.services_manager.volumes_client
|
||||
cls.backups_client = cls.services_manager.backups_client
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
cls.clear_isolated_creds()
|
||||
|
||||
@classmethod
|
||||
def clear_isolated_creds(cls):
|
||||
if hasattr(cls, "dynamic_cred"):
|
||||
cls.dynamic_cred.clear_creds()
|
||||
|
||||
def environment_delete(self, environment_id, timeout=180):
|
||||
self.application_catalog_client.delete_environment(environment_id)
|
||||
|
||||
start_time = time.time()
|
||||
while time.time() - start_time > timeout:
|
||||
try:
|
||||
self.application_catalog_client.get_environment(environment_id)
|
||||
except exceptions.NotFound:
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def purge_stacks(cls):
|
||||
stacks = cls.orchestration_client.list_stacks()['stacks']
|
||||
for stack in stacks:
|
||||
cls.orchestration_client.delete_stack(stack['id'])
|
||||
cls.orchestration_client.wait_for_stack_status(stack['id'],
|
||||
'DELETE_COMPLETE')
|
||||
|
||||
def get_service(self, environment, session, service_name):
|
||||
for service in self.application_catalog_client.get_services_list(
|
||||
environment, session):
|
||||
if service['name'] == service_name:
|
||||
return service
|
||||
|
||||
def get_stack_id(self, environment_id):
|
||||
stacks = self.orchestration_client.list_stacks()['stacks']
|
||||
for stack in stacks:
|
||||
if environment_id in self.orchestration_client.show_stack(
|
||||
stack['id'])['stack']['description']:
|
||||
return stack['id']
|
||||
|
||||
def get_stack_template(self, stack):
|
||||
return self.orchestration_client.show_template(stack)
|
||||
|
||||
def get_instance_id(self, name):
|
||||
instance_list = self.servers_client.list_servers()['servers']
|
||||
for instance in instance_list:
|
||||
if name in instance['name']:
|
||||
return instance['id']
|
||||
|
||||
def apache_cinder(
|
||||
self, attributes=None, userName=None, flavor='m1.medium'):
|
||||
post_body = {
|
||||
"instance": {
|
||||
"flavor": flavor,
|
||||
"image": self.linux_image,
|
||||
"assignFloatingIp": True,
|
||||
"availabilityZone": "nova",
|
||||
"volumes": attributes,
|
||||
"?": {
|
||||
"type": "io.murano.resources.LinuxMuranoInstance",
|
||||
"id": utils.generate_uuid()
|
||||
},
|
||||
"name": utils.generate_name("testMurano")
|
||||
},
|
||||
"name": utils.generate_name("ApacheHTTPServer"),
|
||||
"userName": userName,
|
||||
"?": {
|
||||
"_{id}".format(id=utils.generate_uuid()): {
|
||||
"name": "ApacheHTTPServer"
|
||||
},
|
||||
"type": "io.murano.apps.test.ApacheHttpServerCustom",
|
||||
"id": utils.generate_uuid()
|
||||
}
|
||||
}
|
||||
return post_body
|
||||
|
||||
def update_executor(self, flavor='m1.medium'):
|
||||
post_body = {
|
||||
"instance": {
|
||||
"flavor": flavor,
|
||||
"image": self.linux_image,
|
||||
"assignFloatingIp": True,
|
||||
"?": {
|
||||
"type": "io.murano.resources.LinuxMuranoInstance",
|
||||
"id": utils.generate_uuid()
|
||||
},
|
||||
"name": utils.generate_name('testMurano')
|
||||
},
|
||||
"name": utils.generate_name('dummy'),
|
||||
"?": {
|
||||
"type": "io.murano.apps.test.UpdateExecutor",
|
||||
"id": utils.generate_uuid()
|
||||
}
|
||||
}
|
||||
return post_body
|
||||
|
||||
def deploy_environment(self, environment, session):
|
||||
self.application_catalog_client.deploy_session(environment['id'],
|
||||
session['id'])
|
||||
return self.wait_for_environment_deploy(environment)
|
||||
|
||||
def wait_for_environment_deploy(self, environment):
|
||||
start_time = time.time()
|
||||
status = self.application_catalog_client.\
|
||||
get_environment(environment['id'])['status']
|
||||
while status != 'ready':
|
||||
status = self.application_catalog_client.\
|
||||
get_environment(environment['id'])['status']
|
||||
if time.time() - start_time > 1800:
|
||||
time.sleep(60)
|
||||
self.fail(
|
||||
'Environment deployment is not finished in 1200 seconds')
|
||||
elif status == 'deploy failure':
|
||||
time.sleep(60)
|
||||
self.fail('Environment has incorrect status {0}'.
|
||||
format(status))
|
||||
time.sleep(5)
|
||||
return self.application_catalog_client.\
|
||||
get_environment(environment['id'])
|
||||
|
||||
def status_check(self, environment_id, configurations):
|
||||
for configuration in configurations:
|
||||
inst_name = configuration[0]
|
||||
ports = configuration[1:]
|
||||
ip = self.get_ip_by_instance_name(environment_id, inst_name)
|
||||
if ip and ports:
|
||||
for port in ports:
|
||||
self.check_port_access(ip, port)
|
||||
else:
|
||||
self.fail('Instance does not have floating IP')
|
||||
|
||||
def check_path(self, environment_id, path, inst_name=None):
|
||||
environment = self.application_catalog_client.\
|
||||
get_environment(environment_id)
|
||||
if inst_name:
|
||||
ip = self.get_ip_by_instance_name(environment_id, inst_name)
|
||||
else:
|
||||
ip = environment.services[0]['instance']['floatingIpAddress']
|
||||
resp = requests.get('http://{0}/{1}'.format(ip, path))
|
||||
if resp.status_code == 200:
|
||||
return resp
|
||||
else:
|
||||
self.fail("Service path unavailable")
|
||||
|
||||
def get_ip_by_instance_name(self, environment_id, inst_name):
|
||||
for service in self.application_catalog_client.\
|
||||
get_services_list(environment_id):
|
||||
if inst_name in service['instance']['name']:
|
||||
return service['instance']['floatingIpAddress']
|
||||
|
||||
def check_port_access(self, ip, port):
|
||||
result = 1
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < 600:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex((str(ip), port))
|
||||
sock.close()
|
||||
if result == 0:
|
||||
break
|
||||
time.sleep(5)
|
||||
self.assertEqual(0, result, '%s port is closed on instance' % port)
|
||||
|
||||
@classmethod
|
||||
def create_volume(cls):
|
||||
volume = cls.volumes_client.create_volume()['volume']
|
||||
waiters.wait_for_volume_status(cls.volumes_client,
|
||||
volume['id'], 'available')
|
||||
return volume['id']
|
||||
|
||||
@classmethod
|
||||
def delete_volume(cls, volume_id):
|
||||
cls.volumes_client.delete_volume(volume_id)
|
||||
is_volume_deleted = False
|
||||
while not is_volume_deleted:
|
||||
is_volume_deleted = cls.volumes_client.\
|
||||
is_resource_deleted(volume_id)
|
||||
time.sleep(1)
|
||||
|
||||
def create_snapshot(self, volume_id):
|
||||
snapshot = self.snapshots_client.\
|
||||
create_snapshot(volume_id=volume_id)['snapshot']
|
||||
waiters.wait_for_snapshot_status(self.snapshots_client,
|
||||
snapshot['id'], 'available')
|
||||
return snapshot['id']
|
||||
|
||||
def delete_snapshot(self, snapshot_id):
|
||||
self.snapshots_client.delete_snapshot(snapshot_id)
|
||||
is_snapshot_deleted = False
|
||||
while not is_snapshot_deleted:
|
||||
is_snapshot_deleted = self.snapshots_client.\
|
||||
is_resource_deleted(snapshot_id)
|
||||
time.sleep(1)
|
||||
|
||||
def create_backup(self, volume_id):
|
||||
backup = self.backups_client.create_backup(
|
||||
volume_id=volume_id,
|
||||
force=True)['backup']
|
||||
self.backups_client.wait_for_backup_status(backup['id'], 'available')
|
||||
return backup['id']
|
||||
|
||||
def delete_backup(self, backup_id):
|
||||
self.backups_client.delete_backup(backup_id)
|
||||
return self.backups_client.wait_for_backup_deletion(backup_id)
|
||||
|
||||
def get_volume(self, environment_id):
|
||||
stack = self.get_stack_id(environment_id)
|
||||
stack_outputs = self.orchestration_client.\
|
||||
show_stack(stack)['stack']['outputs']
|
||||
for output in stack_outputs:
|
||||
if 'vol' in output['output_key']:
|
||||
volume_id = output['output_value']
|
||||
return self.volumes_client.show_volume(volume_id)['volume']
|
||||
|
||||
def check_volume_attached(self, name, volume_id):
|
||||
instance_id = self.get_instance_id(name)
|
||||
attached_volumes = self.servers_client.\
|
||||
list_volume_attachments(instance_id)['volumeAttachments']
|
||||
assert attached_volumes[0]['id'] == volume_id
|
||||
|
||||
|
||||
class BaseApplicationCatalogScenarioIsolatedAdminTest(
|
||||
BaseApplicationCatalogScenarioTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
creds = cls.get_configured_isolated_creds(type_of_creds='admin')
|
||||
cls.os = clients.Manager(credentials=creds)
|
||||
cls.services_manager = services_manager(creds)
|
||||
super(BaseApplicationCatalogScenarioIsolatedAdminTest, cls).\
|
||||
resource_setup()
|
@ -34,7 +34,8 @@ MANIFEST = {'Format': 'MuranoPL/1.0',
|
||||
|
||||
|
||||
def compose_package(app_name, manifest, package_dir,
|
||||
require=None, archive_dir=None, add_class_name=False):
|
||||
require=None, archive_dir=None, add_class_name=False,
|
||||
manifest_required=True):
|
||||
"""Composes a murano package
|
||||
|
||||
Composes package `app_name` with `manifest` file as a template for the
|
||||
@ -43,15 +44,16 @@ def compose_package(app_name, manifest, package_dir,
|
||||
Puts the resulting .zip file into `acrhive_dir` if present or in the
|
||||
`package_dir`.
|
||||
"""
|
||||
with open(manifest, 'w') as f:
|
||||
fqn = 'io.murano.apps.' + app_name
|
||||
mfest_copy = MANIFEST.copy()
|
||||
mfest_copy['FullName'] = fqn
|
||||
mfest_copy['Name'] = app_name
|
||||
mfest_copy['Classes'] = {fqn: 'mock_muranopl.yaml'}
|
||||
if require:
|
||||
mfest_copy['Require'] = require
|
||||
f.write(yaml.dump(mfest_copy, default_flow_style=False))
|
||||
if manifest_required:
|
||||
with open(manifest, 'w') as f:
|
||||
fqn = 'io.murano.apps.' + app_name
|
||||
mfest_copy = MANIFEST.copy()
|
||||
mfest_copy['FullName'] = fqn
|
||||
mfest_copy['Name'] = app_name
|
||||
mfest_copy['Classes'] = {fqn: 'mock_muranopl.yaml'}
|
||||
if require:
|
||||
mfest_copy['Require'] = require
|
||||
f.write(yaml.dump(mfest_copy, default_flow_style=False))
|
||||
|
||||
if add_class_name:
|
||||
class_file = os.path.join(package_dir, 'Classes', 'mock_muranopl.yaml')
|
||||
@ -82,7 +84,8 @@ def compose_package(app_name, manifest, package_dir,
|
||||
return archive_path, name
|
||||
|
||||
|
||||
def prepare_package(name, require=None, add_class_name=False):
|
||||
def prepare_package(name, require=None, add_class_name=False,
|
||||
app='MockApp', manifest_required=True):
|
||||
"""Prepare package.
|
||||
|
||||
:param name: Package name to compose
|
||||
@ -90,13 +93,13 @@ def prepare_package(name, require=None, add_class_name=False):
|
||||
:param add_class_name: Option to write class name to class file
|
||||
:return: Path to archive, directory with archive, filename of archive
|
||||
"""
|
||||
app_dir = acquire_package_directory()
|
||||
target_arc_path = app_dir.rsplit('MockApp', 1)[0]
|
||||
app_dir = acquire_package_directory(app=app)
|
||||
target_arc_path = app_dir.rsplit(app, 1)[0]
|
||||
|
||||
arc_path, filename = compose_package(
|
||||
name, os.path.join(app_dir, 'manifest.yaml'),
|
||||
app_dir, require=require, archive_dir=target_arc_path,
|
||||
add_class_name=add_class_name)
|
||||
add_class_name=add_class_name, manifest_required=manifest_required)
|
||||
return arc_path, target_arc_path, filename
|
||||
|
||||
|
||||
@ -111,7 +114,7 @@ def generate_name(prefix):
|
||||
return '{0}_{1}'.format(prefix, suffix)
|
||||
|
||||
|
||||
def acquire_package_directory():
|
||||
def acquire_package_directory(app='MockApp'):
|
||||
"""Obtain absolutely directory with package files.
|
||||
|
||||
Should be called inside tests dir.
|
||||
@ -119,7 +122,7 @@ def acquire_package_directory():
|
||||
"""
|
||||
top_plugin_dir = os.path.realpath(os.path.join(os.getcwd(),
|
||||
os.path.dirname(__file__)))
|
||||
expected_package_dir = '/extras/MockApp'
|
||||
expected_package_dir = '/extras/' + app
|
||||
app_dir = top_plugin_dir + expected_package_dir
|
||||
return app_dir
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user