database pool debuging with more functional tests
This commit is contained in:
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
@@ -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)
|
||||
|
||||
|
||||
22
functional/manual/create_and_kill.py
Normal file
22
functional/manual/create_and_kill.py
Normal 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')
|
||||
26
functional/manual/post_testrun.py
Normal file
26
functional/manual/post_testrun.py
Normal 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)])
|
||||
@@ -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:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user