rework functional tests to be a tempest plugin

Change-Id: Ic38b628a4c17e2a8d307ecdeb08c639975a364aa
This commit is contained in:
Andrey Pavlov 2015-12-21 16:28:05 +03:00
parent 54e55e4b47
commit 01786798d8
10 changed files with 376 additions and 220 deletions

133
devstack/create_config Executable file
View File

@ -0,0 +1,133 @@
#!/bin/bash
#
# create_config script for devstack plugin script
# Build config for run functional tests with or wuthout tempest
set -o xtrace
set +o errexit
TIMEOUT=${TIMEOUT:-180}
GCE_SCHEMA=${GCE_SCHEMA:-etc/gceapi/protocols/v1.json}
GCE_CRED_TYPE=${GCE_CRED_TYPE:-os_token}
GCE_API_PROTOCOL=${GCE_API_PROTOCOL:-http}
GCE_HOST=${GCE_HOST:-localhost}
GCE_PORT=${GCE_PORT:-8787}
GCE_DISCOVERY_URL=${GCE_DISCOVERY_URL:-/discovery/v1/apis/\{api\}/\{apiVersion\}/rest}
ZONE=${ZONE:-nova}
REGION=${REGION:-region-one}
TEST_CONFIG="$1"
if [[ -z "$TEST_CONFIG" ]]; then
die $LINENO "Please pass config name"
fi
sudo rm -f $GCEAPI_DIR/$TEST_CONFIG
if [[ -n "$TOP_DIR" ]]; then
source $TOP_DIR/accrc/admin/admin
unset OS_AUTH_TYPE
fi
openstack endpoint list
if [[ "$?" -ne "0" ]]; then
die $LINENO "OpenStack CLI doesn't work. Looks like credentials are absent."
fi
# create separate user/project
project_name="project-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
eval $(openstack project create -f shell -c id $project_name)
project_id=$id
[[ -n "$project_id" ]] || { echo "Can't create project"; exit 1; }
user_name="user-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
password='password'
eval $(openstack user create "$user_name" --project "$project_id" --password "$password" --email "$user_name@example.com" -f shell -c id)
user_id=$id
[[ -n "$user_id" ]] || { echo "Can't create user"; exit 1; }
# add 'Member' role for swift access
role_id=$(openstack role show Member -c id -f value)
openstack role add --project $project_id --user $user_id $role_id
# prepare flavors
flavor_name="n1.standard.1"
if [[ -z "$(nova flavor-list | grep $flavor_name)" ]]; then
nova flavor-create --is-public True $flavor_name 16 512 0 1
[[ "$?" -eq 0 ]] || { echo "Failed to prepare flavor"; exit 1; }
fi
# create default network
if [[ -n $(openstack service list | grep neutron) ]]; then
# neutron networking
networking="neutron"
net_id=$(neutron net-create --tenant-id $project_id "default" | grep ' id ' | awk '{print $4}')
[[ -n "$net_id" ]] || { echo "net-create failed"; exit 1; }
subnet_id=$(neutron subnet-create --tenant-id $project_id --ip_version 4 --gateway 10.240.0.1 --name "private_subnet" $net_id 10.240.0.0/16 | grep ' id ' | awk '{print $4}')
[[ -n "$subnet_id" ]] || { echo "subnet-create failed"; exit 1; }
router_id=$(neutron router-create --tenant-id $project_id "private_router" | grep ' id ' | awk '{print $4}')
[[ -n "$router_id" ]] || { echo "router-create failed"; exit 1; }
neutron router-interface-add $router_id $subnet_id
[[ "$?" -eq 0 ]] || { echo "router-interface-add failed"; exit 1; }
public_net_id=$(neutron net-list | grep public | awk '{print $2}')
[[ -n "$public_net_id" ]] || { echo "can't find public network"; exit 1; }
neutron router-gateway-set $router_id $public_net_id
[[ "$?" -eq 0 ]] || { echo "router-gateway-set failed"; exit 1; }
else
# nova networking
networking="nova-network"
nova network-create "default" --fixed-range-v4 10.240.0.0/16 --gateway 10.240.0.1
fi
#create image in raw format
os_image_name="cirros-0.3.4-raw-image"
if [[ -z "$(openstack image list | grep $os_image_name)" ]]; then
image_name="cirros-0.3.4-x86_64-disk.img"
cirros_image_url="http://download.cirros-cloud.net/0.3.4/$image_name"
sudo rm -f /tmp/$image_name
wget -nv -P /tmp $cirros_image_url
[[ "$?" -eq 0 ]] || { echo "Failed to download image"; exit 1; }
openstack image create --disk-format raw --container-format bare --public --file "/tmp/$image_name" $os_image_name
[[ "$?" -eq 0 ]] || { echo "Failed to prepare image"; exit 1; }
fi
export OS_PROJECT_NAME=$project_name
export OS_TENANT_NAME=$project_name
export OS_USERNAME=$user_name
export OS_PASSWORD=$password
# convert flavor name: becase GCE dowsn't allows '.' and converts '-' into '.'
flavor_name=${flavor_name//\./-}
sudo bash -c "cat > $GCEAPI_DIR/$TEST_CONFIG <<EOF
[gce]
# Generic options
build_timeout = $TIMEOUT
build_interval = 1
# GCE API schema
schema = $GCE_SCHEMA
# GCE auth options
cred_type = $GCE_CRED_TYPE
auth_url = $OS_AUTH_URL
username = $OS_USERNAME
password = $OS_PASSWORD
# GCE services address
protocol = $GCE_API_PROTOCOL
host = $GCE_HOST
port = $GCE_PORT
# GCE API URLs
discovery_url = $GCE_DISCOVERY_URL
# GCE resource IDs for testing
project_id = $OS_PROJECT_NAME
zone = $ZONE
networking = $networking
region = $REGION
machine_type = $flavor_name
image = $OS_PROJECT_NAME/global/images/$os_image_name
EOF"
sudo chown -f $STACK_USER $GCEAPI_DIR/$TEST_CONFIG

View File

@ -211,14 +211,20 @@ function install_gceapi() {
# start_gceapi() - Start running processes, including screen
function start_gceapi() {
screen_it gce-api "cd $GCEAPI_DIR && $GCEAPI_BIN_DIR/gce-api --config-file $GCEAPI_CONF_DIR/gceapi.conf"
run_process gce-api "$GCEAPI_BIN_DIR/gce-api --config-file $GCEAPI_CONF_DIR/gceapi.conf"
echo "Waiting for GCE API to start..."
if ! wait_for_service $SERVICE_TIMEOUT \
"$SERVICE_PROTOCOL://$SERVICE_HOST:$GCEAPI_SERVICE_PORT/"; then
die $LINENO "GCE API did not start"
fi
}
# stop_gceapi() - Stop running processes
function stop_gceapi() {
# Kill the gceapi screen windows
screen -S $SCREEN_NAME -p gce-api -X kill
stop_process gce-api
}
function cleanup_gceapi() {
@ -227,6 +233,15 @@ function cleanup_gceapi() {
sudo rm -rf $GCEAPI_KEYSTONE_SIGNING_DIR
}
function configure_functional_tests() {
(source $GCEAPI_DIR/devstack/create_config "functional_tests.conf")
if [[ "$?" -ne "0" ]]; then
warn $LINENO "GCE API tests config could not be created."
elif is_service_enabled tempest; then
cat "$GCEAPI_DIR/functional_tests.conf" >> $TEMPEST_CONFIG
fi
}
# main dispatcher
if [[ "$1" == "stack" && "$2" == "install" ]]; then
echo_summary "Installing gce-api"
@ -239,6 +254,7 @@ elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
echo_summary "Initializing gce-api"
init_gceapi
start_gceapi
configure_functional_tests
fi
if [[ "$1" == "unstack" ]]; then

View File

@ -17,18 +17,23 @@
# Sleep some time until all services are starting
sleep 5
export TEST_CONFIG_DIR=$(readlink -f .)
export GCEAPI_DIR=$(readlink -f .)
export TEST_CONFIG="functional_tests.conf"
# save original creds(admin) for later usage
OLD_OS_PROJECT_NAME=$OS_PROJECT_NAME
OLD_OS_USERNAME=$OS_USERNAME
OLD_OS_PASSWORD=$OS_PASSWORD
# bug somewhere
unset OS_AUTH_TYPE
if [[ ! -f $TEST_CONFIG_DIR/$TEST_CONFIG ]]; then
function die() {
echo "ERROR in $1: $2"
exit 1
}
export -f die
function warn() {
echo "WARNING in $1: $2"
}
export -f warn
if [[ ! -f $GCEAPI_DIR/$TEST_CONFIG ]]; then
openstack endpoint list --os-identity-api-version=3
openstack service list --long
@ -37,119 +42,28 @@ if [[ ! -f $TEST_CONFIG_DIR/$TEST_CONFIG ]]; then
exit 1
fi
# create separate user/project
project_name="project-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
eval $(openstack project create -f shell -c id $project_name)
project_id=$id
[[ -n "$project_id" ]] || { echo "Can't create project"; exit 1; }
user_name="user-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
password='password'
eval $(openstack user create "$user_name" --project "$project_id" --password "$password" --email "$user_name@example.com" -f shell -c id)
user_id=$id
[[ -n "$user_id" ]] || { echo "Can't create user"; exit 1; }
# add 'Member' role for swift access
role_id=$(openstack role show Member -c id -f value)
openstack role add --project $project_id --user $user_id $role_id
# prepare flavors
flavor_name="n1.standard.1"
if [[ -z "$(nova flavor-list | grep $flavor_name)" ]]; then
nova flavor-create --is-public True $flavor_name 16 512 0 1
[[ "$?" -eq 0 ]] || { echo "Failed to prepare flavor"; exit 1; }
STACK_USER=$(whoami) $GCEAPI_DIR/devstack/create_config $TEST_CONFIG
if [[ "$?" -ne "0" ]]; then
echo "Config creation has failed."
exit 1
fi
# create default network
if [[ -n $(openstack service list | grep neutron) ]]; then
# neutron networking
networking="neutron"
net_id=$(neutron net-create --tenant-id $project_id "default" | grep ' id ' | awk '{print $4}')
[[ -n "$net_id" ]] || { echo "net-create failed"; exit 1; }
subnet_id=$(neutron subnet-create --tenant-id $project_id --ip_version 4 --gateway 10.240.0.1 --name "private_subnet" $net_id 10.240.0.0/16 | grep ' id ' | awk '{print $4}')
[[ -n "$subnet_id" ]] || { echo "subnet-create failed"; exit 1; }
router_id=$(neutron router-create --tenant-id $project_id "private_router" | grep ' id ' | awk '{print $4}')
[[ -n "$router_id" ]] || { echo "router-create failed"; exit 1; }
neutron router-interface-add $router_id $subnet_id
[[ "$?" -eq 0 ]] || { echo "router-interface-add failed"; exit 1; }
public_net_id=$(neutron net-list | grep public | awk '{print $2}')
[[ -n "$public_net_id" ]] || { echo "can't find public network"; exit 1; }
neutron router-gateway-set $router_id $public_net_id
[[ "$?" -eq 0 ]] || { echo "router-gateway-set failed"; exit 1; }
else
# nova networking
networking="nova-network"
nova network-create "default" --fixed-range-v4 10.240.0.0/16 --gateway 10.240.0.1
fi
#create image in raw format
os_image_name="cirros-0.3.4-raw-image"
if [[ -z "$(openstack image list | grep $os_image_name)" ]]; then
image_name="cirros-0.3.4-x86_64-disk.img"
cirros_image_url="http://download.cirros-cloud.net/0.3.4/$image_name"
sudo rm -f /tmp/$image_name
wget -nv -P /tmp $cirros_image_url
[[ "$?" -eq 0 ]] || { echo "Failed to download image"; exit 1; }
openstack image create --disk-format raw --container-format bare --public --file "/tmp/$image_name" $os_image_name
[[ "$?" -eq 0 ]] || { echo "Failed to prepare image"; exit 1; }
fi
export OS_PROJECT_NAME=$project_name
export OS_TENANT_NAME=$project_name
export OS_USERNAME=$user_name
export OS_PASSWORD=$password
sudo bash -c "cat > $TEST_CONFIG_DIR/$TEST_CONFIG <<EOF
[gce]
# Generic options
build_timeout=${TIMEOUT:-180}
build_interval=1
# GCE API schema
schema=${GCE_SCHEMA:-'etc/gceapi/protocols/v1.json'}
# GCE auth options
cred_type=${GCE_CRED_TYPE:-'os_token'}
auth_url=${OS_AUTH_URL}
username=${OS_USERNAME}
password=${OS_PASSWORD}
# GCE services address
protocol=${GCE_API_PROTOCOL:-'http'}
host=${GCE_HOST:-'localhost'}
port=${GCE_PORT:-8787}
# GCE API URLs
discovery_url=${GCE_DISCOVERY_URL:-'/discovery/v1/apis/{api}/{apiVersion}/rest'}
# GCE resource IDs for testing
project_id=${OS_PROJECT_NAME}
zone=${ZONE:-'nova'}
networking=${networking}
region=${REGION:-'region-one'}
# convert flavor name: becase GCE dowsn't allows '.' and converts '-' into '.'
machine_type=${flavor_name//\./-}
image=${OS_PROJECT_NAME}/global/images/${os_image_name}
EOF"
fi
sudo pip install -r test-requirements.txt
sudo pip install google-api-python-client
sudo pip install virtualenv
sudo rm -rf .venv
sudo virtualenv .venv --system-site-package
sudo chown -R $USER .venv
source .venv/bin/activate
pip install -r test-requirements.txt
pip install google-api-python-client
sudo OS_STDOUT_CAPTURE=-1 OS_STDERR_CAPTURE=-1 OS_TEST_TIMEOUT=500 OS_TEST_LOCK_PATH=${TMPDIR:-'/tmp'} \
python -m subunit.run discover -t ./ ./gceapi/tests/functional/api | subunit-2to1 | tools/colorizer.py
RETVAL=$?
deactivate
# Here can be some commands for log archiving, etc...
echo Enumerate resources to check what left after tests
for i in instances images disks snapshots
do
echo "List of "$i
gcloud compute $i list
echo ""
done
export OS_PROJECT_NAME=$OLD_OS_PROJECT_NAME
export OS_TENANT_NAME=$OLD_OS_PROJECT_NAME
export OS_USERNAME=$OLD_OS_USERNAME
export OS_PASSWORD=$OLD_OS_PASSWORD
openstack flavor list
openstack image list
openstack server list --all-projects

View File

@ -14,84 +14,22 @@
# under the License.
from os import environ
from os import path
import logging as std_logging
import os
from oslo_config import cfg
from oslo_log import log as logging
from gceapi.tests.functional import config_opts
OPTIONS_GROUP = cfg.OptGroup(name='gce', title='GCE options')
OPTIONS = [
# Generic options
cfg.IntOpt('build_timeout',
default=180,
help='Timeout'),
cfg.IntOpt('build_interval',
default=1,
help='Interval'),
LOG = logging.getLogger('gceapi')
# GCE auth options
cfg.StrOpt('cred_type',
default='os_token',
help='Method how to get credentials:'
'\n\tos_token - request token from OS keystone directly'
'\n\tgcloud_auth - use app credentials that should be'
'obtained before via gcloud auth'),
cfg.StrOpt('username',
default='demo',
help='User name'),
cfg.StrOpt('password',
default='password',
help='User password'),
cfg.StrOpt('auth_url',
default='http://localhost:5000/v2.0/',
help='OAuth API relative URL'),
# GCE API schema
cfg.StrOpt('schema',
default='etc/gceapi/protocols/v1.json',
help='Json file with API schema for validation'),
# GCE services address
cfg.StrOpt('protocol',
default='http',
help='GCE protocl (http or https)'),
cfg.StrOpt('host',
default='localhost',
help='GCE service host'),
cfg.IntOpt('port',
default=8787,
help='GCE service port'),
# GCE API URLs
cfg.StrOpt('discovery_url',
default='/discovery/v1/apis/{api}/{apiVersion}/rest',
help='Discovery API relative URL'),
# GCE resource IDs for testing
# Note that Google's project has Name, ID and Number, for project
# identification ID should be used, but in Openstack project has
# Name and ID, where Name is corresponds to Project ID in Google, ID is
# Openstack ID's and has no relation to Google's ID and Number.
cfg.StrOpt('project_id',
default='test',
help='GCE Project ID for testing'),
cfg.StrOpt('zone',
default='nova',
help='GCE Zone for testing'),
cfg.StrOpt('region',
default='us-central1',
help='GCE Region for testing'),
cfg.StrOpt('networking',
default='neutron',
help='Types of OS networking: neutron or nova-network'),
cfg.StrOpt('machine_type',
default='n1-standard-1',
help='Machine type - a type of instance ot be created'),
cfg.StrOpt('image',
default='debian-cloud/global/images/debian-7-wheezy-v20150929',
help='Image to create instances'),
]
def get_base_dir():
cur_dir = os.path.dirname(__file__)
base_dir = os.path.dirname(os.path.dirname(os.path.dirname(cur_dir)))
return os.environ.get('TEST_CONFIG_DIR', base_dir)
# This should never be called outside of this class
@ -101,34 +39,30 @@ class ConfigPrivate(object):
def __init__(self):
"""Initialize a configuration from a conf directory and conf file."""
super(ConfigPrivate, self).__init__()
base_dir = self._get_base_dir()
cfg_file_path = self._get_default_config_path(base_dir)
config_files = []
if path.exists(cfg_file_path):
config_files.append(cfg_file_path)
cfg.CONF.register_group(OPTIONS_GROUP)
cfg.CONF.register_opts(OPTIONS, group=OPTIONS_GROUP)
cfg.CONF([], project='gceapi', default_config_files=config_files)
self.gce = cfg.CONF.gce
# Load API scheme for API calls validation
with open(self._get_default_schema_path(base_dir), 'r') as f:
from json import load
self.gce.schema = load(f)
@staticmethod
def _get_base_dir():
cur_dir = path.dirname(__file__)
base_dir = path.dirname(path.dirname(path.dirname(cur_dir)))
return environ.get('TEST_CONFIG_DIR', base_dir)
# if this was run from tempest runner then config already parsed
if config_opts.OPTIONS_GROUP.name in cfg.CONF:
self.gce = cfg.CONF.gce
return
cfg_file_path = self._get_default_config_path(get_base_dir())
config_files = []
if os.path.exists(cfg_file_path):
config_files.append(cfg_file_path)
conf = cfg.CONF
conf([], project='gceapi', default_config_files=config_files)
conf.register_group(config_opts.OPTIONS_GROUP)
group_name = config_opts.OPTIONS_GROUP.name
for opt in config_opts.OPTIONS:
conf.register_opt(opt, group=group_name)
self.gce = cfg.CONF.gce
conf.log_opt_values(LOG, std_logging.DEBUG)
@staticmethod
def _get_default_config_path(base_dir):
conf_file = environ.get('TEST_CONFIG', 'functional_tests.conf')
return path.join(base_dir, conf_file)
def _get_default_schema_path(self, base_dir):
schema_file = environ.get('TEST_SCHEMA', self.gce.schema)
return path.join(base_dir, schema_file)
conf_file = os.environ.get('TEST_CONFIG', 'functional_tests.conf')
return os.path.join(base_dir, conf_file)
class ConfigProxy(object):

View File

@ -0,0 +1,92 @@
# Copyright 2012 OpenStack Foundation
# 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.
from oslo_config import cfg
OPTIONS_GROUP = cfg.OptGroup(name='gce', title='GCE options')
OPTIONS = [
# Generic options
cfg.IntOpt('build_timeout',
default=180,
help='Timeout'),
cfg.IntOpt('build_interval',
default=1,
help='Interval'),
# GCE auth options
cfg.StrOpt('cred_type',
default='os_token',
help='Method how to get credentials:'
'\n\tos_token - request token from OS keystone directly'
'\n\tgcloud_auth - use app credentials that should be'
'obtained before via gcloud auth'),
cfg.StrOpt('username',
default='demo',
help='User name'),
cfg.StrOpt('password',
default='password',
help='User password'),
cfg.StrOpt('auth_url',
default='http://localhost:5000/v2.0/',
help='OAuth API relative URL'),
# GCE API schema
cfg.StrOpt('schema',
default='etc/gceapi/protocols/v1.json',
help='Json file with API schema for validation'),
# GCE services address
cfg.StrOpt('protocol',
default='http',
help='GCE protocl (http or https)'),
cfg.StrOpt('host',
default='localhost',
help='GCE service host'),
cfg.IntOpt('port',
default=8787,
help='GCE service port'),
# GCE API URLs
cfg.StrOpt('discovery_url',
default='/discovery/v1/apis/{api}/{apiVersion}/rest',
help='Discovery API relative URL'),
# GCE resource IDs for testing
# Note that Google's project has Name, ID and Number, for project
# identification ID should be used, but in Openstack project has
# Name and ID, where Name is corresponds to Project ID in Google, ID is
# Openstack ID's and has no relation to Google's ID and Number.
cfg.StrOpt('project_id',
default='test',
help='GCE Project ID for testing'),
cfg.StrOpt('zone',
default='nova',
help='GCE Zone for testing'),
cfg.StrOpt('region',
default='us-central1',
help='GCE Region for testing'),
cfg.StrOpt('networking',
default='neutron',
help='Types of OS networking: neutron or nova-network'),
cfg.StrOpt('machine_type',
default='n1-standard-1',
help='Machine type - a type of instance ot be created'),
cfg.StrOpt('image',
default='debian-cloud/global/images/debian-7-wheezy-v20150929',
help='Image to create instances'),
]

View File

@ -0,0 +1,38 @@
# Copyright 2012 OpenStack Foundation
# 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 os
from tempest import config
from tempest.test_discover import plugins
from gceapi.tests.functional import config_opts as gce_config
class GCETempestPlugin(plugins.TempestPlugin):
def load_tests(self):
base_path = os.path.split(os.path.dirname(os.path.dirname(
os.path.dirname(os.path.abspath(__file__)))))[0]
test_dir = "gceapi/tests/functional"
full_test_dir = os.path.join(base_path, test_dir)
return full_test_dir, base_path
def register_opts(self, conf):
if gce_config.OPTIONS_GROUP.name not in conf:
config.register_opt_group(conf, gce_config.OPTIONS_GROUP,
gce_config.OPTIONS)
def get_opt_lists(self):
return [(gce_config.OPTIONS_GROUP.name, config.OPTIONS)]

View File

@ -15,6 +15,7 @@
# under the License.
import json
import os
import re
import string
import time
@ -32,7 +33,7 @@ from gceapi.tests.functional import config
from gceapi.tests.functional import credentials
CONF = config.CONF.gce
CONF = config.CONF
LOG = logging.getLogger("gceapi")
API_NAME = 'compute'
API_VER = 'v1'
@ -87,6 +88,30 @@ class LocalRefResolver(jsonschema.RefResolver):
return super(LocalRefResolver, self).resolve_from_url(url)
class SchemaHolder(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(SchemaHolder, cls).__new__(
cls, *args, **kwargs)
return cls._instance
_schema = None
def get_schema(self, schema_file):
if self._schema:
return self._schema
schema_path = os.path.join(config.get_base_dir(), schema_file)
# Load API scheme for API calls validation
with open(schema_path, 'r') as f:
self._schema = json.load(f)
return self._schema
class GCEApi(object):
def __init__(self, cred_provider):
self._compute = None
@ -95,7 +120,8 @@ class GCEApi(object):
self._scheme_ref_resolver = 0
def init(self):
self._schema = schema.Schemas(CONF.schema)
_schema = SchemaHolder().get_schema(CONF.gce.schema)
self._schema = schema.Schemas(_schema)
self._scheme_ref_resolver = LocalRefResolver.from_schema(
self._schema.schemas)
self._build_api()
@ -131,15 +157,15 @@ class GCEApi(object):
@property
def _host_url(self):
cfg = CONF
cfg = CONF.gce
if self._is_standard_port(cfg.protocol, cfg.port):
return '{}://{}'.format(cfg.protocol, cfg.host)
return '{}://{}:{}'.format(cfg.protocol, cfg.host, cfg.port)
@property
def _discovery_url(self):
t = '{}{}' if CONF.discovery_url.startswith('/') else '{}/{}'
return t.format(self._host_url, CONF.discovery_url)
t = '{}{}' if CONF.gce.discovery_url.startswith('/') else '{}/{}'
return t.format(self._host_url, CONF.gce.discovery_url)
@property
def _api_url(self):
@ -147,14 +173,14 @@ class GCEApi(object):
@property
def project_url(self):
return '{}/projects/{}'.format(self._api_url, CONF.project_id)
return '{}/projects/{}'.format(self._api_url, CONF.gce.project_id)
def get_zone_url(self, resource=None, zone=None):
if resource and self._is_absolute_url(resource):
return resource
z = zone
if z is None:
z = CONF.zone
z = CONF.gce.zone
if not self._is_absolute_url(z):
t = '{}/{}' if z.startswith('zones/') else '{}/zones/{}'
z = t.format(self.project_url, z)
@ -167,7 +193,7 @@ class GCEApi(object):
return resource
r = region
if r is None:
r = CONF.region
r = CONF.gce.region
if not self._is_absolute_url(r):
t = '{}/{}' if r.startswith('regions/') else '{}/regions/{}'
r = t.format(self.project_url, r)
@ -197,7 +223,7 @@ class GCETestCase(base.BaseTestCase):
@property
def cfg(self):
return CONF
return CONF.gce
@staticmethod
def trace(msg):
@ -209,7 +235,7 @@ class GCETestCase(base.BaseTestCase):
@classmethod
def setUpClass(cls):
cls._credentials_provider = credentials.CredentialsProvider(CONF)
cls._credentials_provider = credentials.CredentialsProvider(CONF.gce)
cls._api = GCEApi(cls._credentials_provider)
cls._api.init()
super(GCETestCase, cls).setUpClass()

View File

@ -33,6 +33,9 @@ console_scripts =
gce-api=gceapi.cmd.api:main
gce-api-manage=gceapi.cmd.manage:main
tempest.test_plugins =
gce_tests = gceapi.tests.functional.plugin:GCETempestPlugin
[build_sphinx]
all_files = 1
build-dir = doc/build