pep8 cleanup
This commit is contained in:
parent
14b0810030
commit
0bd1399735
4
alembic/versions/1d6540fc6279_added_vendor_contact.py
Normal file → Executable file
4
alembic/versions/1d6540fc6279_added_vendor_contact.py
Normal file → Executable file
@ -16,7 +16,9 @@ import sqlalchemy as sa
|
||||
|
||||
def upgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('vendor', sa.Column('contact_name', sa.String(length=120), nullable=True))
|
||||
op.add_column(
|
||||
'vendor',
|
||||
sa.Column('contact_name', sa.String(length=120), nullable=True))
|
||||
### end Alembic commands ###
|
||||
|
||||
|
||||
|
110
alembic/versions/3790aed42558_from_scratch.py
Normal file → Executable file
110
alembic/versions/3790aed42558_from_scratch.py
Normal file → Executable file
@ -16,63 +16,69 @@ import sqlalchemy as sa
|
||||
|
||||
def upgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('cloud',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('label', sa.String(length=60), nullable=True),
|
||||
sa.Column('endpoint', sa.String(length=120), nullable=True),
|
||||
sa.Column('test_user', sa.String(length=80), nullable=True),
|
||||
sa.Column('test_key', sa.String(length=80), nullable=True),
|
||||
sa.Column('admin_endpoint', sa.String(length=120), nullable=True),
|
||||
sa.Column('admin_user', sa.String(length=80), nullable=True),
|
||||
sa.Column('admin_key', sa.String(length=80), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('endpoint')
|
||||
op.create_table(
|
||||
'cloud',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('label', sa.String(length=60), nullable=True),
|
||||
sa.Column('endpoint', sa.String(length=120), nullable=True),
|
||||
sa.Column('test_user', sa.String(length=80), nullable=True),
|
||||
sa.Column('test_key', sa.String(length=80), nullable=True),
|
||||
sa.Column('admin_endpoint', sa.String(length=120), nullable=True),
|
||||
sa.Column('admin_user', sa.String(length=80), nullable=True),
|
||||
sa.Column('admin_key', sa.String(length=80), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('endpoint')
|
||||
)
|
||||
op.create_table('vendor',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('vendor_name', sa.String(length=80), nullable=True),
|
||||
sa.Column('contact_email', sa.String(length=120), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('contact_email'),
|
||||
sa.UniqueConstraint('vendor_name')
|
||||
op.create_table(
|
||||
'vendor',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('vendor_name', sa.String(length=80), nullable=True),
|
||||
sa.Column('contact_email', sa.String(length=120), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('contact_email'),
|
||||
sa.UniqueConstraint('vendor_name')
|
||||
)
|
||||
op.create_table('user',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('vendor_id', sa.Integer(), nullable=True),
|
||||
sa.Column('name', sa.String(length=60), nullable=True),
|
||||
sa.Column('email', sa.String(length=200), nullable=True),
|
||||
sa.Column('email_verified', sa.Boolean(), nullable=True),
|
||||
sa.Column('openid', sa.String(length=200), nullable=True),
|
||||
sa.Column('authorized', sa.Boolean(), nullable=True),
|
||||
sa.Column('su', sa.Boolean(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['vendor_id'], ['vendor.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('email'),
|
||||
sa.UniqueConstraint('openid')
|
||||
op.create_table(
|
||||
'user',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('vendor_id', sa.Integer(), nullable=True),
|
||||
sa.Column('name', sa.String(length=60), nullable=True),
|
||||
sa.Column('email', sa.String(length=200), nullable=True),
|
||||
sa.Column('email_verified', sa.Boolean(), nullable=True),
|
||||
sa.Column('openid', sa.String(length=200), nullable=True),
|
||||
sa.Column('authorized', sa.Boolean(), nullable=True),
|
||||
sa.Column('su', sa.Boolean(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['vendor_id'], ['vendor.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('email'),
|
||||
sa.UniqueConstraint('openid')
|
||||
)
|
||||
op.create_table('test',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('cloud_id', sa.Integer(), nullable=True),
|
||||
sa.Column('config', sa.String(length=4096), nullable=True),
|
||||
sa.ForeignKeyConstraint(['cloud_id'], ['cloud.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
op.create_table(
|
||||
'test',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('cloud_id', sa.Integer(), nullable=True),
|
||||
sa.Column('config', sa.String(length=4096), nullable=True),
|
||||
sa.ForeignKeyConstraint(['cloud_id'], ['cloud.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('test_results',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('test_id', sa.Integer(), nullable=True),
|
||||
sa.Column('timestamp', sa.DateTime(), nullable=True),
|
||||
sa.Column('blob', sa.Binary(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['test_id'], ['test.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
op.create_table(
|
||||
'test_results',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('test_id', sa.Integer(), nullable=True),
|
||||
sa.Column('timestamp', sa.DateTime(), nullable=True),
|
||||
sa.Column('blob', sa.Binary(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['test_id'], ['test.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('test_status',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('test_id', sa.Integer(), nullable=True),
|
||||
sa.Column('message', sa.String(length=1024), nullable=True),
|
||||
sa.Column('finished', sa.Boolean(), nullable=True),
|
||||
sa.Column('timestamp', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['test_id'], ['test.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
op.create_table(
|
||||
'test_status',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('test_id', sa.Integer(), nullable=True),
|
||||
sa.Column('message', sa.String(length=1024), nullable=True),
|
||||
sa.Column('finished', sa.Boolean(), nullable=True),
|
||||
sa.Column('timestamp', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['test_id'], ['test.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
### end Alembic commands ###
|
||||
|
||||
|
3
alembic/versions/4288db006e5_added_user_cloud_rel.py
Normal file → Executable file
3
alembic/versions/4288db006e5_added_user_cloud_rel.py
Normal file → Executable file
@ -10,9 +10,6 @@ Create Date: 2013-10-31 21:00:27.473833
|
||||
revision = '4288db006e5'
|
||||
down_revision = '1d6540fc6279'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
|
5
alembic/versions/449461dbc725_add_apikey.py
Normal file → Executable file
5
alembic/versions/449461dbc725_add_apikey.py
Normal file → Executable file
@ -15,7 +15,8 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.create_table('apikey',
|
||||
op.create_table(
|
||||
'apikey',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=60), nullable=True),
|
||||
sa.Column('key', sa.String(length=200), nullable=True),
|
||||
@ -24,7 +25,7 @@ def upgrade():
|
||||
sa.Column('timestamp', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
|
5
alembic/versions/59e15d864941_added_subunit_output.py
Normal file → Executable file
5
alembic/versions/59e15d864941_added_subunit_output.py
Normal file → Executable file
@ -16,7 +16,10 @@ import sqlalchemy as sa
|
||||
|
||||
def upgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('test_results', sa.Column('subunit', sa.String(length=8192), nullable=True))
|
||||
op.add_column(
|
||||
'test_results',
|
||||
sa.Column('subunit', sa.String(length=8192), nullable=True)
|
||||
)
|
||||
### end Alembic commands ###
|
||||
|
||||
|
||||
|
17
refstack/api.py
Normal file → Executable file
17
refstack/api.py
Normal file → Executable file
@ -1,3 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2013 Piston Cloud Computing, 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.
|
||||
#
|
||||
"""Basic API code.
|
||||
|
||||
This is using Flask-Restless at the moment because it is super simple,
|
||||
@ -47,8 +62,6 @@ def _not_authorized():
|
||||
status_code=401)
|
||||
|
||||
|
||||
|
||||
|
||||
def authenticate():
|
||||
# If we're already authenticated, we can ignore this
|
||||
if flask.g.user:
|
||||
|
38
refstack/app.py
Normal file → Executable file
38
refstack/app.py
Normal file → Executable file
@ -1,19 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This file based on MIT licensed code at: https://github.com/imwilsonxu/fbone
|
||||
|
||||
#
|
||||
# Copyright (c) 2013 Piston Cloud Computing, 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 os
|
||||
|
||||
from flask import Flask, request, render_template
|
||||
#from flask.ext.babel import Babel
|
||||
|
||||
from flask import Flask, render_template
|
||||
from .config import DefaultConfig
|
||||
#from .user import User, user
|
||||
#from .settings import settings
|
||||
#from .frontend import frontend
|
||||
#from .api import api
|
||||
#from .admin import admin
|
||||
#from .extensions import db, mail, cache, login_manager, oid
|
||||
from refstack import admin
|
||||
from refstack import api
|
||||
from .extensions import db
|
||||
@ -55,8 +57,6 @@ def create_app(config=None, app_name=None, blueprints=None):
|
||||
instance_path=INSTANCE_FOLDER_PATH,
|
||||
instance_relative_config=True)
|
||||
|
||||
|
||||
|
||||
configure_app(app, config)
|
||||
configure_hook(app)
|
||||
configure_blueprints(app, blueprints)
|
||||
@ -85,9 +85,6 @@ def configure_app(app, config=None):
|
||||
if config:
|
||||
app.config.from_object(config)
|
||||
|
||||
# Use instance folder instead of env variables to make deployment easier.
|
||||
#app.config.from_envvar('%s_APP_CONFIG' % DefaultConfig.PROJECT.upper(), silent=True)
|
||||
|
||||
|
||||
def configure_extensions(app):
|
||||
# flask-sqlalchemy
|
||||
@ -161,7 +158,8 @@ def configure_logging(app):
|
||||
app.logger.setLevel(logging.INFO)
|
||||
|
||||
info_log = os.path.join(app.config['LOG_FOLDER'], 'info.log')
|
||||
info_file_handler = logging.handlers.RotatingFileHandler(info_log, maxBytes=100000, backupCount=10)
|
||||
info_file_handler = logging.handlers.RotatingFileHandler(
|
||||
info_log, maxBytes=100000, backupCount=10)
|
||||
info_file_handler.setLevel(logging.INFO)
|
||||
info_file_handler.setFormatter(logging.Formatter(
|
||||
'%(asctime)s %(levelname)s: %(message)s '
|
||||
|
@ -14,7 +14,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from keystoneclient.v2_0 import client
|
||||
from refstack.models import *
|
||||
from refstack.models import db, Cloud
|
||||
|
||||
|
||||
class TempestConfig(object):
|
||||
@ -24,14 +24,13 @@ class TempestConfig(object):
|
||||
def output(self):
|
||||
"""outputs config in propper format"""
|
||||
output = ''
|
||||
for k,v in self.config.items():
|
||||
for k, v in self.config.items():
|
||||
output += '[%s] \n' % k
|
||||
for sk,sv in v.items():
|
||||
output += '%s = %s \n' % (sk,sv)
|
||||
for sk, sv in v.items():
|
||||
output += '%s = %s \n' % (sk, sv)
|
||||
output += '\n'
|
||||
return output
|
||||
|
||||
|
||||
def build_config_from_keystone(self):
|
||||
"""uses the keystoneclient libs to query a clouds endpoint and
|
||||
retrive a service catelog. that it then uses to populate the
|
||||
@ -65,9 +64,11 @@ class TempestConfig(object):
|
||||
|
||||
self._keystone.management_url = self._cloud.admin_endpoint
|
||||
|
||||
# make sure this keystone server can list services using has_service_catalog
|
||||
# make sure this keystone server can list services
|
||||
# using has_service_catalog
|
||||
if not self._keystone.has_service_catalog():
|
||||
# we have no service catelog all tests are fail because we can't build a config
|
||||
# we have no service catelog all tests are fail
|
||||
# because we can't build a config
|
||||
print "fail "
|
||||
#else:
|
||||
# print "has service catalog"
|
||||
@ -76,13 +77,12 @@ class TempestConfig(object):
|
||||
|
||||
# make a local dict of the service catalog
|
||||
for item in self._keystone.service_catalog.catalog['serviceCatalog']:
|
||||
self.service_catalog[item['name']]=item['endpoints'][0]['publicURL']
|
||||
|
||||
#print "%s : %s" % (item['name'],item['endpoints'][0]['publicURL'])
|
||||
self.service_catalog[item['name']] = \
|
||||
item['endpoints'][0]['publicURL']
|
||||
|
||||
# setup output service_available
|
||||
for service in self.config['service_available'].keys():
|
||||
if self.service_catalog.has_key(service):
|
||||
if service in self.service_catalog:
|
||||
self.config['service_available'][service] = True
|
||||
|
||||
# boto settings
|
||||
@ -92,17 +92,16 @@ class TempestConfig(object):
|
||||
# return the actual config
|
||||
return self.output()
|
||||
|
||||
|
||||
def __init__(self, cloud_id):
|
||||
""" sets up the default configs"""
|
||||
self.cloud_id = cloud_id
|
||||
|
||||
self.config['DEFAULT'] = {
|
||||
'debug':True,
|
||||
'use_stderr':False,
|
||||
'log_file':'output',
|
||||
'debug': True,
|
||||
'use_stderr': False,
|
||||
'log_file': 'output',
|
||||
'lock_path': '/tmp/'+str(cloud_id)+'/',
|
||||
'default_log_levels':"""tempest.stress=INFO,amqplib=WARN,
|
||||
'default_log_levels': """tempest.stress=INFO,amqplib=WARN,
|
||||
sqlalchemy=WARN,boto=WARN,suds=INFO,keystone=INFO,
|
||||
eventlet.wsgi.server=WARN"""}
|
||||
|
||||
@ -123,7 +122,6 @@ class TempestConfig(object):
|
||||
'admin_tenant_name': '',
|
||||
'admin_role': ''}
|
||||
|
||||
|
||||
self.config['compute'] = {
|
||||
'catalog_type': 'compute',
|
||||
'allow_tenant_isolation': True,
|
||||
@ -166,7 +164,7 @@ class TempestConfig(object):
|
||||
self.config['image'] = {
|
||||
'catalog_type': 'image',
|
||||
'api_version': 1,
|
||||
'http_image': 'ttp://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz'}
|
||||
'http_image': ''}
|
||||
|
||||
self.config['network'] = {
|
||||
'catalog_type': 'network',
|
||||
@ -175,7 +173,7 @@ class TempestConfig(object):
|
||||
'tenant_network_mask_bits': 28,
|
||||
'tenant_networks_reachable': False,
|
||||
'public_network_id': '',
|
||||
'public_router_id': '' }
|
||||
'public_router_id': ''}
|
||||
|
||||
self.config['volume'] = {
|
||||
'catalog_type': 'volume',
|
||||
@ -186,14 +184,14 @@ class TempestConfig(object):
|
||||
'backend1_name': 'BACKEND_1',
|
||||
'backend2_name': 'BACKEND_2',
|
||||
'storage_protocol': 'iSCSI',
|
||||
'vendor_name': 'Open Source' }
|
||||
'vendor_name': 'Open Source'}
|
||||
|
||||
self.config['object-storage'] = {
|
||||
'catalog_type': 'object-store',
|
||||
'container_sync_timeout': 120,
|
||||
'container_sync_interval': 5,
|
||||
'accounts_quotas_available': True,
|
||||
'operator_role': 'Member' }
|
||||
'operator_role': 'Member'}
|
||||
|
||||
self.config['boto'] = {
|
||||
'ssh_user': 'cirros',
|
||||
@ -209,7 +207,7 @@ class TempestConfig(object):
|
||||
'http_socket_timeout': 30,
|
||||
'num_retries': 1,
|
||||
'build_timeout': 400,
|
||||
'build_interval': 1 }
|
||||
'build_interval': 1}
|
||||
|
||||
self.config['orchestration'] = {
|
||||
'catalog_type': 'orchestration',
|
||||
@ -229,12 +227,12 @@ class TempestConfig(object):
|
||||
'ari_img_file': 'cirros-0.3.1-x86_64-initrd',
|
||||
'aki_img_file': 'cirros-0.3.1-x86_64-vmlinuz',
|
||||
'ssh_user': 'cirros',
|
||||
'large_ops_number': 0 }
|
||||
'large_ops_number': 0}
|
||||
|
||||
self.config['cli'] = {
|
||||
'enabled': True,
|
||||
'cli_dir': '/usr/local/bin',
|
||||
'timeout': 15 }
|
||||
'timeout': 15}
|
||||
|
||||
self.config['service_available'] = {
|
||||
'cinder': False,
|
||||
@ -243,9 +241,9 @@ class TempestConfig(object):
|
||||
'swift': False,
|
||||
'nova': False,
|
||||
'heat': False,
|
||||
'horizon': False }
|
||||
'horizon': False}
|
||||
|
||||
self.config['stress'] = {
|
||||
'max_instances': 32,
|
||||
'log_check_interval': 60,
|
||||
'default_thread_number_per_action': 4 }
|
||||
'default_thread_number_per_action': 4}
|
||||
|
@ -18,7 +18,7 @@ from subprocess import call
|
||||
from refstack.common.tempest_config import TempestConfig
|
||||
import testrepository.repository.file
|
||||
from testrepository import ui
|
||||
#from testrepository.commands import run
|
||||
from testrepository.commands import run
|
||||
from testrepository.commands import init
|
||||
|
||||
import gear
|
||||
@ -26,17 +26,15 @@ import gear
|
||||
|
||||
class TesterWorker(object):
|
||||
"""gearman worker code"""
|
||||
def __init__(self,app):
|
||||
def __init__(self, app):
|
||||
self.worker = gear.Worker('run_remote_test')
|
||||
|
||||
self.worker.addServer(app.gearman_server)
|
||||
self.worker.registerFunction('run_remote_test')
|
||||
|
||||
|
||||
def run_remote_test(self):
|
||||
pass
|
||||
|
||||
|
||||
def run_job(self):
|
||||
while True:
|
||||
job = self.worker.getJob()
|
||||
@ -68,13 +66,11 @@ class TestRepositorySource(object):
|
||||
|
||||
self.init_repo()
|
||||
|
||||
|
||||
def get_subunit_stream(self):
|
||||
try:
|
||||
return self.testrepository_last_stream()
|
||||
except KeyError:
|
||||
raise NoStreamPresent()
|
||||
|
||||
pass # raise NoStreamPresent()
|
||||
|
||||
def init_repo(self):
|
||||
"""inits a new testrepository repo in the supplied path"""
|
||||
@ -86,16 +82,14 @@ class TestRepositorySource(object):
|
||||
# if this happens its fine .. just means the repo is already there
|
||||
pass
|
||||
|
||||
|
||||
def run(self):
|
||||
here = os.getcwd()
|
||||
os.getcwd()
|
||||
os.chdir(self.testr_directory)
|
||||
self._ui.c = self.testr_directory+'tempest.conf'
|
||||
|
||||
cmd = run.run(self._ui)
|
||||
|
||||
res = cmd.execute()
|
||||
|
||||
return cmd.execute()
|
||||
|
||||
def testrepository_last_stream(self):
|
||||
factory = testrepository.repository.file.RepositoryFactory()
|
||||
@ -113,8 +107,7 @@ class Tester(object):
|
||||
cloud_id = None
|
||||
_status = None
|
||||
|
||||
|
||||
def __init__(self,cloud_id=None,test_id=None,sha=None):
|
||||
def __init__(self, cloud_id=None, test_id=None, sha=None):
|
||||
""" init method loads specified id or fails"""
|
||||
if not test_id:
|
||||
#create a new test id
|
||||
@ -128,7 +121,6 @@ class Tester(object):
|
||||
self.sha = sha
|
||||
self.test_path = "/tmp/%s/" % cloud_id
|
||||
|
||||
|
||||
def run_remote(self):
|
||||
"""triggers remote run"""
|
||||
# install tempest in virt env
|
||||
@ -144,27 +136,28 @@ class Tester(object):
|
||||
# write the tempest config to that folder
|
||||
self.write_config(self.test_path)
|
||||
|
||||
# setup the repo wrapper.. this creates the repo if its not already there
|
||||
# setup the repo wrapper..
|
||||
# this creates the repo if its not already there
|
||||
tr = TestRepositorySource(self.test_path)
|
||||
|
||||
"""TODO: So this is supposed to use the testr wrapper to trigger a run.. however..
|
||||
I am completly blocked on how to make it work the right way.. so I am moving on
|
||||
for now once the congigs are setup and repo initiated it will call a subprocess
|
||||
run the command .. THEN query the repo for the last set of results and store the
|
||||
subunit stream.
|
||||
"""TODO: So this is supposed to use the testr wrapper to trigger a run.
|
||||
however.. I am completly blocked on how to make it work the right way..
|
||||
so I am moving on for now once the congigs are setup and repo initiated
|
||||
it will call a subprocess run the command .. THEN query the repo for
|
||||
the last set of results and store the subunit stream.
|
||||
|
||||
# run tests
|
||||
#tr.run()
|
||||
"""
|
||||
|
||||
print "starting test"
|
||||
call([self.test_path+'runtests.sh']) # replace this
|
||||
call([self.test_path+'runtests.sh']) # replace this
|
||||
print "finished with tests"
|
||||
|
||||
# get back the results
|
||||
result = tr.testrepository_last_stream()
|
||||
|
||||
# write results to database maybe .. or return them .. not sure which ..
|
||||
# write results to database maybe ..
|
||||
return result.read()
|
||||
#return None
|
||||
|
||||
@ -185,7 +178,8 @@ exit $?""" % path
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \
|
||||
${PYTHON:-python} -m subunit.run discover tempest.api $LISTOPT $IDOPTION
|
||||
${PYTHON:-python} -m subunit.run discover \
|
||||
tempest.api $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
||||
group_regex=([^\.]*\.)*"""
|
||||
@ -209,14 +203,16 @@ group_regex=([^\.]*\.)*"""
|
||||
"""The status property."""
|
||||
def fget(self):
|
||||
return self._status
|
||||
|
||||
def fset(self, value):
|
||||
self._status = value
|
||||
|
||||
def fdel(self):
|
||||
del self._status
|
||||
|
||||
return locals()
|
||||
|
||||
@property
|
||||
def config(self):
|
||||
"""The config property. outputs a tempest config based on settings"""
|
||||
return self.tempest_config.output()
|
||||
|
||||
|
33
refstack/config.py
Normal file → Executable file
33
refstack/config.py
Normal file → Executable file
@ -1,14 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This file based on MIT licensed code at: https://github.com/imwilsonxu/fbone
|
||||
|
||||
#
|
||||
# Copyright (c) 2013 Piston Cloud Computing, 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 os
|
||||
|
||||
from utils import make_dir, INSTANCE_FOLDER_PATH, PROJECT_ROOT
|
||||
|
||||
|
||||
class BaseConfig(object):
|
||||
|
||||
"""base config object"""
|
||||
PROJECT = "refstack"
|
||||
|
||||
# The app root path, also can use flask.root_path.
|
||||
@ -34,15 +45,17 @@ class BaseConfig(object):
|
||||
|
||||
|
||||
class DefaultConfig(BaseConfig):
|
||||
|
||||
"""default config thing"""
|
||||
DEBUG = True
|
||||
|
||||
# Flask-Sqlalchemy: http://packages.python.org/Flask-SQLAlchemy/config.html
|
||||
SQLALCHEMY_ECHO = True
|
||||
# SQLITE for prototyping.
|
||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + INSTANCE_FOLDER_PATH + '/db.sqlite'
|
||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + \
|
||||
INSTANCE_FOLDER_PATH + '/db.sqlite'
|
||||
# MYSQL for production.
|
||||
#SQLALCHEMY_DATABASE_URI = 'mysql://username:password@server/db?charset=utf8'
|
||||
#SQLALCHEMY_DATABASE_URI = \
|
||||
# 'mysql://username:password@server/db?charset=utf8'
|
||||
|
||||
# Flask-babel: http://pythonhosted.org/Flask-Babel/
|
||||
ACCEPT_LANGUAGES = ['zh']
|
||||
@ -53,13 +66,13 @@ class DefaultConfig(BaseConfig):
|
||||
CACHE_DEFAULT_TIMEOUT = 60
|
||||
|
||||
# Flask-mail: http://pythonhosted.org/flask-mail/
|
||||
# https://bitbucket.org/danjac/flask-mail/issue/3/problem-with-gmails-smtp-server
|
||||
MAIL_DEBUG = DEBUG
|
||||
MAIL_SERVER = 'smtp.gmail.com'
|
||||
MAIL_PORT = 587
|
||||
MAIL_USE_TLS = True
|
||||
MAIL_USE_SSL = False
|
||||
# Should put MAIL_USERNAME and MAIL_PASSWORD in production under instance folder.
|
||||
# Should put MAIL_USERNAME and MAIL_PASSWORD
|
||||
# in production under instance folder.
|
||||
MAIL_USERNAME = 'yourmail@gmail.com'
|
||||
MAIL_PASSWORD = 'yourpass'
|
||||
MAIL_DEFAULT_SENDER = MAIL_USERNAME
|
||||
|
2
refstack/default_settings.py
Normal file → Executable file
2
refstack/default_settings.py
Normal file → Executable file
@ -32,7 +32,7 @@ class Default(object):
|
||||
MAILGUN_DOMAIN = 'refstack.org'
|
||||
SECRET_KEY = '#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@'
|
||||
SQLALCHEMY_DATABASE_URI = os.environ.get(
|
||||
'DATABASE_URL', 'sqlite:///%s/refstack.db' % (db_path))
|
||||
'DATABASE_URL', 'sqlite:///%s/refstack.db' % (db_path))
|
||||
DEBUG = True
|
||||
SECURITY_PASSWORD_HASH = 'sha512_crypt'
|
||||
SECURITY_PASSWORD_SALT = SECRET_KEY
|
||||
|
@ -55,12 +55,11 @@ class ApiKey(db.Model):
|
||||
backref=db.backref('apikeys', lazy='dynamic'))
|
||||
|
||||
|
||||
"""
|
||||
Note: The vendor list will be pre-populated from the sponsoring company database.
|
||||
TODO: better define the vendor object and its relationship with user
|
||||
it needs the ability to facilitate a login.
|
||||
"""
|
||||
class Vendor(db.Model):
|
||||
"""Note: The vendor list will be pre-populated from the
|
||||
sponsoring company database.
|
||||
TODO: better define the vendor object and its relationship with user
|
||||
it needs the ability to facilitate a login."""
|
||||
__tablename__ = 'vendor'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
vendor_name = db.Column(db.String(80), unique=True)
|
||||
@ -87,7 +86,7 @@ class Cloud(db.Model):
|
||||
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
user = db.relationship('User',
|
||||
backref=db.backref('clouds',lazy='dynamic'))
|
||||
backref=db.backref('clouds', lazy='dynamic'))
|
||||
|
||||
|
||||
class Test(db.Model):
|
||||
@ -95,10 +94,9 @@ class Test(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
cloud_id = db.Column(db.Integer, db.ForeignKey('cloud.id'))
|
||||
cloud = db.relationship('Cloud',
|
||||
backref=db.backref('tests',lazy='dynamic'))
|
||||
backref=db.backref('tests', lazy='dynamic'))
|
||||
config = db.Column(db.String(4096))
|
||||
|
||||
|
||||
def __init__(self, cloud_id):
|
||||
self.cloud_id = cloud_id
|
||||
|
||||
@ -108,13 +106,12 @@ class TestStatus(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
test_id = db.Column(db.Integer, db.ForeignKey('test.id'))
|
||||
test = db.relationship('Test',
|
||||
backref=db.backref('status',lazy='dynamic'))
|
||||
backref=db.backref('status', lazy='dynamic'))
|
||||
message = db.Column(db.String(1024))
|
||||
finished = db.Column(db.Boolean, default=False)
|
||||
timestamp = db.Column(db.DateTime, default=datetime.now)
|
||||
|
||||
|
||||
def __init__(self,test_id, message, finished=False):
|
||||
def __init__(self, test_id, message, finished=False):
|
||||
self.test_id = test_id
|
||||
self.message = message
|
||||
self.finished = finished
|
||||
@ -125,9 +122,7 @@ class TestResults(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
test_id = db.Column(db.Integer, db.ForeignKey('test.id'))
|
||||
test = db.relationship('Test',
|
||||
backref=db.backref('results',lazy='dynamic'))
|
||||
backref=db.backref('results', lazy='dynamic'))
|
||||
timestamp = db.Column(db.DateTime, default=datetime.now)
|
||||
subunit = db.Column(db.String(8192))
|
||||
blob = db.Column(db.Binary)
|
||||
|
||||
|
||||
|
23
refstack/utils.py
Normal file → Executable file
23
refstack/utils.py
Normal file → Executable file
@ -1,13 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This file based on MIT licensed code at: https://github.com/imwilsonxu/fbone
|
||||
|
||||
#
|
||||
# Copyright (c) 2013 Piston Cloud Computing, 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.
|
||||
"""
|
||||
Utils has nothing to do with models and views.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
import logging
|
||||
import os
|
||||
import pprint
|
||||
import random
|
||||
@ -92,7 +102,8 @@ def pretty_date(dt, default=None):
|
||||
|
||||
|
||||
def allowed_file(filename):
|
||||
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_AVATAR_EXTENSIONS
|
||||
return '.' in filename and \
|
||||
filename.rsplit('.', 1)[1] in ALLOWED_AVATAR_EXTENSIONS
|
||||
|
||||
|
||||
def id_generator(size=10, chars=string.ascii_letters + string.digits):
|
||||
|
@ -1,6 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013 Piston Cloud Computing, Inc.
|
||||
# All Rights Reserved.
|
||||
# Copyright (c) 2013 Piston Cloud Computing, 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
|
||||
@ -13,30 +12,26 @@
|
||||
# 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 logging
|
||||
|
||||
import flask
|
||||
from flask import Flask, abort, flash, request, redirect, url_for, \
|
||||
render_template, g, session
|
||||
from flask_openid import OpenID
|
||||
from flask.ext.admin import Admin, BaseView, expose, AdminIndexView
|
||||
from flask.ext.admin.contrib.sqlamodel import ModelView
|
||||
from flask.ext.security import Security, SQLAlchemyUserDatastore, \
|
||||
UserMixin, RoleMixin, login_required
|
||||
from wtforms import Form, BooleanField, TextField, \
|
||||
PasswordField, validators
|
||||
#
|
||||
from flask import abort, flash, request, redirect, url_for, \
|
||||
render_template, g, session, flask
|
||||
#from flask_openid import OpenID
|
||||
#from flask.ext.admin import Admin, BaseView, expose, AdminIndexView
|
||||
#from flask.ext.admin.contrib.sqlamodel import ModelView
|
||||
#from flask.ext.security import Security, \
|
||||
# UserMixin, login_required
|
||||
#from wtforms import TextField
|
||||
from flask_mail import Mail
|
||||
|
||||
from refstack import app as base_app
|
||||
from refstack.extensions import db
|
||||
from refstack.extensions import oid
|
||||
from refstack import api
|
||||
from refstack.models import ApiKey
|
||||
from refstack.models import Cloud
|
||||
from refstack.models import Test
|
||||
from refstack.models import TestResults
|
||||
from refstack.models import TestStatus
|
||||
#from refstack import api
|
||||
#from refstack.models import ApiKey
|
||||
#from refstack.models import Cloud
|
||||
#from refstack.models import Test
|
||||
#from refstack.models import TestResults
|
||||
#from refstack.models import TestStatus
|
||||
from refstack.models import User
|
||||
from refstack.models import Vendor
|
||||
|
||||
@ -62,7 +57,7 @@ def index():
|
||||
"""Index view."""
|
||||
if g.user is not None:
|
||||
# something else
|
||||
clouds = Cloud.query.filter_by(user_id=g.user.id).all()
|
||||
clouds = db.Cloud.query.filter_by(user_id=g.user.id).all()
|
||||
return render_template('home.html', clouds=clouds)
|
||||
else:
|
||||
vendors = Vendor.query.all()
|
||||
@ -79,8 +74,9 @@ def login():
|
||||
# if we are already logged in, go back to were we came from
|
||||
if g.user is not None:
|
||||
return redirect(oid.get_next_url())
|
||||
return oid.try_login("https://login.launchpad.net/",
|
||||
ask_for=['email', 'nickname'])
|
||||
return oid.try_login(
|
||||
"https://login.launchpad.net/",
|
||||
ask_for=['email', 'nickname'])
|
||||
|
||||
|
||||
@oid.after_login
|
||||
@ -127,7 +123,7 @@ def create_profile():
|
||||
@app.route('/delete-cloud/<int:cloud_id>', methods=['GET', 'POST'])
|
||||
def delete_cloud(cloud_id):
|
||||
"""Delete function for clouds."""
|
||||
c = Cloud.query.filter_by(id=cloud_id).first()
|
||||
c = db.Cloud.query.filter_by(id=cloud_id).first()
|
||||
|
||||
if not c:
|
||||
flash(u'Not a valid Cloud ID!')
|
||||
@ -142,7 +138,7 @@ def delete_cloud(cloud_id):
|
||||
|
||||
@app.route('/edit-cloud/<int:cloud_id>', methods=['GET', 'POST'])
|
||||
def edit_cloud(cloud_id):
|
||||
c = Cloud.query.filter_by(id=cloud_id).first()
|
||||
c = db.Cloud.query.filter_by(id=cloud_id).first()
|
||||
|
||||
if not c:
|
||||
flash(u'Not a valid Cloud ID!')
|
||||
@ -188,9 +184,7 @@ def edit_cloud(cloud_id):
|
||||
admin_user=c.admin_user,
|
||||
admin_key=c.admin_key)
|
||||
|
||||
|
||||
|
||||
return render_template('edit_cloud.html',form=form)
|
||||
return render_template('edit_cloud.html', form=form)
|
||||
|
||||
|
||||
@app.route('/create-cloud', methods=['GET', 'POST'])
|
||||
@ -215,7 +209,7 @@ def create_cloud():
|
||||
elif not request.form['admin_key']:
|
||||
flash(u'Error: All fields are required')
|
||||
else:
|
||||
c = Cloud()
|
||||
c = db.Cloud()
|
||||
c.user_id = g.user.id
|
||||
c.label = request.form['label']
|
||||
c.endpoint = request.form['endpoint']
|
||||
|
@ -14,9 +14,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
"""Simple script for importing the vendor
|
||||
"""Simple script for importing the vendor
|
||||
list csv file provided by the foundation"""
|
||||
from refstack.models import *
|
||||
from refstack.models import db, Vendor
|
||||
import csv
|
||||
|
||||
_file = 'members_sponsors_20131030.csv'
|
||||
|
Loading…
Reference in New Issue
Block a user