database pool debuging with more functional tests

This commit is contained in:
Dmitry Shulyak
2013-07-06 17:30:07 +03:00
parent b4839e8216
commit 0c27fd3120
11 changed files with 118 additions and 91 deletions

View File

@@ -1,33 +0,0 @@
{
"five_min": {
"test_path": "fuel/tests",
"driver": "nose"
},
"fuel_smoke": {
"test_path": "fuel/tests",
"driver": "nose",
"argv": ["smoke"]
},
"plugin-general": {
"test_path": "tests/functional/dummy_tests/general_test.py",
"driver": "nose"
},
"plugin-stopped": {
"test_path": "tests/functional/dummy_tests/stopped_test.py",
"driver": "nose"
},
"fuel_sanity": {
"test_path": "fuel/tests",
"driver": "nose",
"argv": ["sanity"]
},
"simple": {
"test_path": "/home/u/projects/some_tests",
"driver": "nose"
},
"simple_conf": {
"test_path": "/home/u/projects/some_tests",
"driver": "nose",
"config_path": "/home/u/projects/some_tests/testing.conf"
}
}

View File

@@ -1,30 +1,12 @@
{
"five_min": {
"test_path": "",
"driver": "nose",
"description": "Full five min test run with sanity and fuel",
"argv": ["fuel_health.tests", "--with-xunit"]
},
"fuel_smoke": {
"test_path": "",
"driver": "nose",
"description": "Five min test run",
"argv": ["fuel_health.tests.smoke", "--with-xunit"]
},
"fuel_sanity": {
"test_path": "",
"driver": "nose",
"description": "Five min test run",
"argv": ["fuel_health.tests.sanity", "--with-xunit"]
},
"plugin_general": {
"driver": "nose",
"test_path": "tests/functional/dummy_tests/general_test.py",
"test_path": "functional/dummy_tests/general_test.py",
"description": "General fake tests"
},
"plugin_stopped": {
"driver": "nose",
"test_path": "tests/functional/dummy_tests/stopped_test.py",
"test_path": "functional/dummy_tests/stopped_test.py",
"description": "Long running 25 secs fake tests"
}
}

View File

@@ -5,17 +5,27 @@ import unittest
class Dummy_test(unittest.TestCase):
"""Class docstring is required?
"""
def test_fast_pass(self):
"""Ths tests fast pass OK?
"""
self.assertTrue(True)
def test_long_pass(self):
"""Will sleep 5 sec
"""
time.sleep(5)
self.assertTrue(True)
def test_fast_fail(self):
"""Fust fail
"""
self.assertTrue(False, msg='Something goes wroooong')
def test_fast_error(self):
"""And fust error
"""
conn = httplib.HTTPSConnection('random.random/random')
conn.request("GET", "/random.aspx")

View File

@@ -3,6 +3,21 @@ import unittest
class dummy_tests_stopped(unittest.TestCase):
def test_really_long(self):
"""This is long running tests
"""
time.sleep(25)
self.assertTrue(True)
self.assertTrue(True)
def test_one_no_so_long(self):
"""What i am doing here? You ask me????
"""
time.sleep(10)
self.assertFalse(1 == 2)
def test_not_long_at_all(self):
"""You know.. for testing
"""
self.assertTrue(True)

View File

@@ -0,0 +1,22 @@
import requests
import json
import time
import pprint
def make_requests(claster_id, test_set):
body = [{'testset': test_set,
'metadata': {'config': {},
'cluster_id': claster_id}}]
headers = {'Content-Type': 'application/json'}
response = requests.post('http://localhost:8989/v1/testruns', data=json.dumps(body), headers=headers)
pprint.pprint(response.json())
_id = response.json()[0]['id']
time.sleep(1)
body = [{'id': _id, 'status': 'stopped'}]
update = requests.put('http://localhost:8989/v1/testruns', data=json.dumps(body), headers=headers)
get_resp = requests.get('http://localhost:8989/v1/testruns/last/%s' % claster_id)
data = get_resp.json()
pprint.pprint(data)
if __name__ == '__main__':
make_requests(11, 'plugin_stopped')

View File

@@ -0,0 +1,26 @@
import gevent
from gevent import monkey
monkey.patch_all()
import requests
import json
import time
import pprint
def make_requests(claster_id, test_set):
body = [{'testset': test_set,
'metadata': {'config': {},
'cluster_id': claster_id}}]
headers = {'Content-Type': 'application/json'}
response = requests.post('http://localhost:8989/v1/testruns', data=json.dumps(body), headers=headers)
pprint.pprint(response.json())
status = 'started'
while status == 'started':
time.sleep(5)
get_resp = requests.get('http://localhost:8989/v1/testruns/last/%s' % claster_id)
data = get_resp.json()
status = data['status']
pprint.pprint(data)
if __name__ == '__main__':
gevent.joinall([gevent.spawn(make_requests, i, 'plugin_general') for i in xrange(100)])

View File

@@ -35,10 +35,12 @@ class API(object):
self._discovery()
def run_multiple(self, test_runs):
res = []
for test_run in test_runs:
test_set = test_run['testset']
metadata = test_run['metadata']
self.run(test_set, metadata)
res.append(self.run(test_set, metadata))
return res
def run(self, test_set, metadata):
log.info('Starting test run with metadata %s' % metadata)
@@ -46,9 +48,12 @@ class API(object):
config = metadata['config']
command, transport = self._find_command(test_set)
if not transport.obj.check_current_running(external_id):
test_run_id = self._storage.add_test_run(
test_run, session = self._storage.add_test_run(
test_set, external_id, metadata)
transport.obj.run(test_run_id, external_id, config, **command)
transport.obj.run(test_run.id, external_id, config, **command)
data = self._prepare_test_run(test_run)
session.close()
return data
def kill_multiple(self, test_runs):
@@ -60,6 +65,7 @@ class API(object):
def kill(self, test_run_id, status):
test_run = self._storage.get_test_run(test_run_id)
log.info('TRYING TO KILL TEST RUN %s' % test_run)
command, transport = self._find_command(test_run.type)
if transport.obj.check_current_running(test_run.id):
transport.obj.kill(test_run.id)
@@ -86,10 +92,6 @@ class API(object):
'started_at': test_run.started_at,
'ended_at': test_run.ended_at
}
if test_run.stats:
test_run_data['stats'] = json.loads(test_run.stats)
else:
test_run_data['stats'] = {}
tests = []
if test_run.tests:
for test in test_run.tests:

View File

@@ -22,9 +22,10 @@ class SqlStorage(object):
def __init__(self, engine_url):
log.info('Create sqlalchemy engine - %s' % engine_url)
self._engine = create_engine(engine_url, pool_size=20, poolclass=QueuePool)
self._engine = create_engine(
engine_url, pool_size=10, poolclass=QueuePool)
self._engine.pool._use_threadlocal = True
self._session = sessionmaker(bind=self._engine)
self._session = sessionmaker(bind=self._engine, expire_on_commit=False)
def get_session(self):
return self._session()
@@ -43,7 +44,7 @@ class SqlStorage(object):
data=test.data)
session.add(new_test)
session.commit()
return test_run.id
return test_run, session
def add_test_set(self, test_set, test_set_data):
log.info('Inserting test set %s' % test_set)
@@ -55,12 +56,14 @@ class SqlStorage(object):
new_obj = session.merge(test_set_obj)
session.add(new_obj)
session.commit()
session.close()
return True
def get_test_sets(self):
session = self.get_session()
test_sets = session.query(models.TestSet).all()
session.commit()
session.close()
return test_sets
def get_tests(self):
@@ -68,6 +71,7 @@ class SqlStorage(object):
tests = session.query(models.Test).filter_by(test_run_id=None)
log.info('Tests received %s' % tests.count())
session.commit()
session.close()
return [{'id': t.name, 'test_set': t.test_set_id,
'name': json.loads(t.data)['name']} for t in tests]
@@ -84,6 +88,7 @@ class SqlStorage(object):
name=test_name, data=json.dumps(data), test_set_id=test_set)
session.add(test_obj)
session.commit()
session.close()
def get_last_test_run(self, external_id):
session = self.get_session()
@@ -91,6 +96,7 @@ class SqlStorage(object):
filter_by(external_id=external_id).\
order_by(desc(models.TestRun.id)).first()
session.commit()
session.close()
return test_run
def get_test_results(self):
@@ -99,6 +105,7 @@ class SqlStorage(object):
options(joinedload('tests')).\
order_by(desc(models.TestRun.id))
session.commit()
session.close()
return test_runs
def get_last_test_results(self, external_id):
@@ -108,6 +115,7 @@ class SqlStorage(object):
filter_by(external_id=external_id).\
order_by(desc(models.TestRun.id)).first()
session.commit()
session.close()
if not test_run:
msg = 'Database does not contains ' \
'Test Run with ID %s' % external_id
@@ -120,6 +128,7 @@ class SqlStorage(object):
test_run = session.query(models.TestRun).\
filter_by(id=test_run_id).first()
session.commit()
session.close()
return test_run
def add_test_result(
@@ -136,6 +145,7 @@ class SqlStorage(object):
'data': json.dumps(data)
})
session.commit()
session.close()
def update_test_run(self, test_run_id, stats=None, status=None):
session = self.get_session()
@@ -148,6 +158,7 @@ class SqlStorage(object):
filter(models.TestRun.id == test_run_id).\
update(updated_data)
session.commit()
session.close()
return test_run
def update_running_tests(self, test_run_id, status='stopped'):
@@ -157,3 +168,4 @@ class SqlStorage(object):
models.Test.status.in_(('running', 'wait_running'))).\
update({'status': status}, synchronize_session=False)
session.commit()
session.close()

View File

@@ -7,7 +7,6 @@ import gevent
from gevent import pool
from time import time
import logging
import traceback
from ostf_adapter import exceptions as exc
@@ -47,10 +46,6 @@ class StoragePlugin(Plugin):
def configure(self, options, conf):
self.conf = conf
self.stats = {'errors': 0,
'failures': 0,
'passes': 0,
'skipped': 0}
def _add_message(
self, test, err=None, capt=None,
@@ -59,19 +54,14 @@ class StoragePlugin(Plugin):
if err:
exc_type, exc_value, exc_traceback = err
log.info('Error %s' % exc_value)
log.info('TYPE OF EXCEPTION %s'
'EXCEPTION VALUE %s'
'WTF %s' % (exc_type, exc_value, dir(exc_value)))
log.info('TRACEBACK %s' % exc_traceback)
data['message'] = get_exc_message(exc_value)
data['traceback'] = u"".join(
traceback.format_tb(exc_traceback) or traceback.format_exception(*err))
else:
data['message'] = u""
data['traceback'] = u""
data['message'] = u''
if isinstance(test, Test):
log.info('DOCSTRING FOR TEST %s IS %s' % (test.id(), test.test.__doc__))
data['name'] = test.test.__doc__
data['name'] = test.shortDescription()
else:
data['name'] = test.id()
self.storage.add_test_result(
self.test_parent_id, test.id(), status, taken, data)
@@ -79,30 +69,22 @@ class StoragePlugin(Plugin):
log.info('SUCCESS for %s' % test)
if self.discovery:
data = {}
data['name'] = test.test.__doc__
data['name'] = test.shortDescription()
data['message'] = u''
log.info('DISCOVERY FOR %s WITH DATA %s' % (test.id(), data))
self.storage.add_sets_test(self.test_parent_id, test.id(), data)
else:
self.stats['passes'] += 1
self._add_message(test, status='success', taken=self.taken)
def addFailure(self, test, err, capt=None, tb_info=None):
log.info('FAILURE for %s' % test)
self.stats['failures'] += 1
self._add_message(test, err=err, status='failure', taken=self.taken)
def addError(self, test, err, capt=None, tb_info=None):
log.info('TEST NAME: %s\n'
'ERROR: %s' % (test, err))
self.stats['errors'] += 1
self._add_message(test, err=err, status='error', taken=self.taken)
def report(self, stream):
log.info('REPORT')
if not self.discovery:
stats_values = sum(self.stats.values())
self.stats['total'] = stats_values
self.storage.update_test_run(self.test_parent_id, stats=self.stats)
def beforeTest(self, test):
self._start_time = time()
self._add_message(test, status='running')

View File

@@ -45,6 +45,10 @@ class V1Controller(BaseRestController):
'testruns_last': ['GET']
}
@expose('json')
def index(self):
return {}
@expose('json')
def get_testsets(self):
return self.api.get_test_sets()
@@ -64,8 +68,7 @@ class V1Controller(BaseRestController):
@expose('json')
def post_testruns(self):
test_runs = json.loads(request.body)
self.api.run_multiple(test_runs)
return
return self.api.run_multiple(test_runs)
@expose('json')
def put_testruns(self):

View File

@@ -44,6 +44,8 @@ class ApiV1Tests(unittest.TestCase):
self.assertEqual(json.loads(resp.text), expected)
def test_get_test_runs(self):
"""Simply get all test runs
"""
expected = [
{'id': '1', 'testset': "testset-keystone-222", 'metadata':
{'stats':
@@ -97,6 +99,10 @@ class ApiV1Tests(unittest.TestCase):
self.assertEqual(resp.status, '200 OK')
def test_index_v1(self):
resp = self.app.get('/v1/')
self.assertEqual(resp.status, '200 OK')
@classmethod
def tearDownClass(cls):
cls.patcher.stop()