new api is works, need to refactor some tests

This commit is contained in:
Dmitry Shulyak
2013-07-03 17:28:14 +03:00
parent 3d8dd863a2
commit 47065a71d7
7 changed files with 98 additions and 70 deletions

View File

@@ -1,17 +1,21 @@
{
"five_min": {
"test_path": "fuel_health.tests",
"test_path": "",
"driver": "nose",
"description": "Five min test run"
"description": "Five min test run",
"argv": ["fuel_health.tests"]
},
"fuel_smoke": {
"test_path": "fuel_health.tests.smoke",
"test_path": "",
"driver": "nose",
"description": "Five min test run"
"description": "Five min test run",
"argv": ["fuel_health.tests.smoke"]
},
"fuel_sanity": {
"test_path": "fuel_health.tests.sanity",
"test_path": "",
"driver": "nose",
"description": "Five min test run"
"description": "Five min test run",
"argv": ["fuel_health.tests.sanity", "--collect-only"]
}
}

View File

@@ -37,26 +37,28 @@ class API(object):
def run_multiple(self, test_runs):
for test_run in test_runs:
test_set = test_run['testset']
config = test_run['metadata']['config']
external_id = test_run['metadata']['cluster_id']
self.run(test_set, external_id, config)
metadata = test_run['metadata']
self.run(test_set, metadata)
def run(self, test_set, external_id, config):
log.info('Starting test run with conf %s' %s)
def run(self, test_set, metadata):
log.info('Starting test run with metadata %s' % metadata)
external_id = metadata['cluster_id']
config = metadata['config']
command, transport = self._find_command(test_set)
if not transport.obj.check_current_running(external_id):
test_run = self._storage.add_test_run(test_set, external_id)
transport.obj.run(test_run, config, **command)
return test_run
test_run_id = self._storage.add_test_run(
test_set, external_id, metadata)
transport.obj.run(test_run_id, external_id, config, **command)
def kill_multiple(self, test_runs):
log.info('Trying to stop tests %s' % test_runs)
for test_run in test_runs:
cluster_id = test_run['id']
status = test_run['status']
self.kill(cluster_id)
def kill(self, external_id, data=None):
test_run = self._storage.get_last_test_run(external_id)
def kill(self, test_run_id, data=None):
test_run = self._storage.get_test_run(test_run_id)
command, transport = self._find_command(test_run.type)
if transport.obj.check_current_running(test_run.external_id):
transport.obj.kill(test_run.external_id)
@@ -74,8 +76,12 @@ class API(object):
def _prepare_test_run(self, test_run):
test_run_data = {'id': test_run.id, 'testset': test_run.type,
'metadata': {'stats': json.loads(test_run.stats)},
'metadata': json.loads(test_run.data),
}
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

@@ -28,13 +28,14 @@ class SqlStorage(object):
def get_session(self):
return self._session()
def add_test_run(self, test_run, external_id):
def add_test_run(self, test_run, external_id, data):
log.info('Invoke test run - %s' % test_run)
session = self.get_session()
test_run = models.TestRun(type=test_run, external_id=external_id)
test_run = models.TestRun(type=test_run, external_id=external_id,
data=json.dumps(data))
session.add(test_run)
session.commit()
return test_run
return test_run.id
def add_test_set(self, test_set, test_set_data):
log.info('Inserting test set %s' % test_set)
@@ -106,8 +107,12 @@ class SqlStorage(object):
raise exc.OstfDBException(message=msg)
return test_run
def get_test_result(self, test_run_id):
pass
def get_test_run(self, test_run_id):
session = self.get_session()
test_run = session.query(models.TestRun).\
filter_by(id=test_run_id).first()
session.commit()
return test_run
def add_test_result(self, test_run_id, test_name, data):
log.info('Add test result for: ID: %s\n'
@@ -122,10 +127,11 @@ class SqlStorage(object):
session.commit()
return test
def update_test_run(self, test_run_id, data):
def update_test_run(self, test_run_id, stats):
log.info("Received stats %s" % stats)
session = self.get_session()
test_run = session.query(models.TestRun).\
filter(models.TestRun.id == test_run_id).\
update({'data': json.dumps(data)})
update({'stats': json.dumps(stats)})
session.commit()
return test_run

View File

@@ -21,7 +21,7 @@ class StoragePlugin(Plugin):
name = 'storage'
score = 15000
def __init__(self, test_run_id, storage, discovery=True):
def __init__(self, test_run_id, storage, discovery=False):
self._capture = []
self.test_run_id = test_run_id
self.storage = storage
@@ -41,15 +41,17 @@ class StoragePlugin(Plugin):
'skipped': 0}
def _add_message(self, test, err=None, capt=None, tb_info=None, **kwargs):
data = {}
data = dict()
data['message'] = u""
data['traceback'] = u""
if err:
exc_type, exc_value, exc_traceback = err
data['message'] = exc_value.message
log.info('Error %s' % exc_value)
if hasattr(exc_value, 'message'):
data['message'] = exc_value.message
data['traceback'] = u"".join(
traceback.format_tb(exc_traceback))
else:
data['message'] = u""
data['traceback'] = u""
doc = test.test.shortDescription()
data['name'] = doc if doc else u""
data.update(kwargs)
@@ -106,14 +108,15 @@ class NoseDriver(object):
def check_current_running(self, external_id):
return external_id in self._named_threads
def run(self, test_run, conf, **kwargs):
def run(self, test_run_id, external_id, conf, **kwargs):
if 'config_path' in kwargs:
self.prepare_config(conf, kwargs['config_path'])
argv_add = kwargs.get('argv', [])
log.info('Additional args: %s' % argv_add)
gev = self._pool.spawn(
self._run_tests, test_run.id, kwargs['test_path'], argv_add)
self._named_threads[test_run.external_id] = gev
self._run_tests, test_run_id, external_id,
kwargs['test_path'], argv_add)
self._named_threads[external_id] = gev
def tests_discovery(self, test_set, test_path, argv_add):
try:
@@ -126,7 +129,7 @@ class NoseDriver(object):
except SystemExit:
log.info('Finished tests discovery %s' % test_set)
def _run_tests(self, test_run_id, test_path, argv_add):
def _run_tests(self, test_run_id, external_id, test_path, argv_add):
try:
log.info('Nose Driver spawn green thread for TEST RUN: %s\n'
'TEST PATH: %s\n'
@@ -140,15 +143,15 @@ class NoseDriver(object):
log.info('Close green thread TEST_RUN: %s\n'
'Thread closed with exception: %s' % (test_run_id,
e.message))
del self._named_threads[test_run_id]
del self._named_threads[external_id]
raise gevent.GreenletExit
def kill(self, external_id):
log.info('Trying to stop process %s\n'
'%s' % (external_id, self._named_threads))
if int(external_id) in self._named_threads:
if external_id in self._named_threads:
log.info('Kill green thread: %s' % external_id)
self._named_threads[int(external_id)].kill()
self._named_threads[external_id].kill()
return True
return False

View File

@@ -6,12 +6,15 @@ import io
TEST_RUN_NAME = 'tests'
TEST_RUN_ID = 1
EXTERNAL_ID = 'CLUSTER_ID'
TEST_ID = 'simple.TestSimple'
CONF = {'config': True}
TEST_COMMANDS = {'tests': {
'driver': 'nose',
'test_path': '/home/tests'
}}
TEST_RUN = {'id': TEST_RUN_ID, 'external_id': EXTERNAL_ID,
'type': TEST_RUN_NAME}
class TestApi(unittest.TestCase):
@@ -20,35 +23,35 @@ class TestApi(unittest.TestCase):
self.transport = MagicMock()
self.command = TEST_COMMANDS['tests']
self.storage = MagicMock()
self.test_run = MagicMock(**TEST_RUN)
@patch.object(API, '_discovery')
@patch('ostf_adapter.api.get_storage')
def test_init_api(self, get_storage_mock):
def test_init_api(self, get_storage_mock, discovery_mock):
get_storage_mock.return_value = 'TEST STORAGE'
api = API()
discovery_mock.assert_any_call()
self.assertEqual(api._storage, 'TEST STORAGE')
@patch.object(API, '_discovery')
@patch('ostf_adapter.api.get_storage')
@patch('ostf_adapter.api.parse_json_file')
def test_run(self, commands_mock, get_storage_mock):
def test_run(self, commands_mock, get_storage_mock, discovery_mock):
commands_mock.return_value = TEST_COMMANDS
get_storage_mock.return_value = self.storage
self.storage.add_test_run.return_value = {'type': TEST_RUN_NAME,
'id': TEST_RUN_ID}
self.transport.obj.check_current_running.return_value = False
self.storage.add_test_run.return_value = TEST_RUN_ID
api = API()
discovery_mock.assert_any_call()
with patch.object(api, '_find_command') as find_command_mock:
find_command_mock.return_value = self.command, self.transport
res = api.run(TEST_RUN_NAME, CONF)
res = api.run(TEST_RUN_NAME, EXTERNAL_ID, CONF)
self.transport.obj.run.assert_called_once_with(
TEST_RUN_ID, CONF, driver='nose', test_path='/home/tests')
self.storage.add_test_run.assert_called_once_with(TEST_RUN_NAME)
self.assertEqual(res, {'type': TEST_RUN_NAME, 'id': TEST_RUN_ID})
@patch('ostf_adapter.api.get_storage')
def test_get_info(self, get_storage_mock):
get_storage_mock.return_value = self.storage
api = API()
res = api.get_info(TEST_RUN_NAME, TEST_RUN_ID)
self.storage.get_test_results.assert_called_once_with(TEST_RUN_ID)
TEST_RUN_ID, EXTERNAL_ID,
CONF, driver='nose', test_path='/home/tests')
self.storage.add_test_run.assert_called_once_with(TEST_RUN_NAME,
EXTERNAL_ID)
@patch('__builtin__.open')
def test_parse_commands_file(self, file_mock):
@@ -90,16 +93,21 @@ class TestApi(unittest.TestCase):
}
self.assertEqual(res, expected)
@patch.object(API, '_discovery')
@patch.object(API, '_find_command')
@patch('ostf_adapter.api.get_storage')
@patch('ostf_adapter.api.parse_json_file')
def test_kill_test_run(self, commands_mock, get_storage_mock):
def test_kill_test_run(
self, commands_mock, get_storage_mock, find_mock, discovery_mock):
get_storage_mock.return_value = self.storage
self.transport.check_current_running.return_value = True
find_mock.return_value = self.command, self.transport
self.storage.get_last_test_run.return_value = self.test_run
commands_mock.return_value = TEST_COMMANDS
self.transport.obj.kill.return_value = True
api = API()
with patch.object(api, '_find_command') as find_command_mock:
find_command_mock.return_value = self.command, self.transport
res = api.kill(TEST_RUN_NAME, TEST_RUN_ID)
self.transport.obj.kill.assert_called_once_with(TEST_RUN_ID)
self.assertTrue(res)
res = api.kill(EXTERNAL_ID)
self.transport.obj.kill.assert_called_once_with(EXTERNAL_ID)

View File

@@ -8,6 +8,7 @@ from gevent import GreenletExit
TEST_RUN_ID = 1
EXTERNAL_ID = 1
CONF = {'keys': 'values'}
@@ -40,20 +41,19 @@ class TestNoseAdapters(unittest.TestCase):
self.assertEqual(string_io.getvalue(),
u'param2 = test\nparam1 = test\n')
def test_run_with_config_path_with_argv(self, get_storage_mock, pool_module):
def test_run_with_config_path_with_argv(
self, get_storage_mock, pool_module):
get_storage_mock.return_value = self.storage_mock
pool_module.Pool.return_value = self.pool_mock
nose_driver = nose_adapter.NoseDriver()
with patch.object(nose_driver, 'prepare_config')\
as prepare_config_mock:
res = nose_driver.run(
TEST_RUN_ID, CONF, config_path='/etc/test.conf', argv=['sanity'],
TEST_RUN_ID, EXTERNAL_ID, CONF, config_path='/etc/test.conf', argv=['sanity'],
test_path='/home/tests')
prepare_config_mock.assert_called_once_with(CONF, '/etc/test.conf')
self.pool_mock.spawn.assert_called_once_with(
nose_driver._run_tests, TEST_RUN_ID, '/home/tests', ['sanity'],
self.storage_mock
nose_driver._run_tests, TEST_RUN_ID, EXTERNAL_ID, '/home/tests', ['sanity']
)
self.assertTrue(1 in nose_driver._named_threads)
@@ -81,11 +81,11 @@ class TestNoseAdapters(unittest.TestCase):
pool_module.Pool.return_value = self.pool_mock
nose_driver = nose_adapter.NoseDriver()
nose_driver._named_threads[TEST_RUN_ID] = 'VALUE'
nose_driver._named_threads[EXTERNAL_ID] = 'VALUE'
nose_test_program_mock.side_effect = raise_system_exit
self.assertRaises(GreenletExit, nose_driver._run_tests,
TEST_RUN_ID, '/home/tests', ['sanity'], self.storage_mock)
TEST_RUN_ID, EXTERNAL_ID,'/home/tests', ['sanity'])
@patch('ostf_adapter.transport.nose_adapter.main')
def test_run_tests_raise_greelet_exit(
@@ -96,11 +96,11 @@ class TestNoseAdapters(unittest.TestCase):
pool_module.Pool.return_value = self.pool_mock
nose_driver = nose_adapter.NoseDriver()
nose_driver._named_threads[TEST_RUN_ID] = 'VALUE'
nose_driver._named_threads[EXTERNAL_ID] = 'VALUE'
nose_test_program_mock.side_effect = raise_greenlet_exit
self.assertRaises(GreenletExit, nose_driver._run_tests,
TEST_RUN_ID, '/home/tests', ['sanity'], self.storage_mock)
TEST_RUN_ID, EXTERNAL_ID, '/home/tests', ['sanity'])
class TestNoseStoragePlugin(unittest.TestCase):

View File

@@ -14,15 +14,15 @@ class SqlStorageTests(unittest.TestCase):
'skipped': 0}
self.storage = SqlStorage('sqlite://')
models.Base.metadata.create_all(self.storage._engine)
self.storage.add_test_run('test')
self.storage.add_test_run('test', 1)
self.storage.add_test_result(
'1', self.fixture['id'], self.fixture)
self.storage.update_test_run(
'1', self.stats)
def test_add_test_run(self):
res = self.storage.add_test_run('test')
self.assertEqual(res, {'type': 'test', 'id': 2})
res = self.storage.add_test_run('test', 1)
self.assertEqual(res, 2)
def test_add_test_result(self):
data = {'type': 'success', 'taken': 10.5,
@@ -32,11 +32,12 @@ class SqlStorageTests(unittest.TestCase):
self.assertTrue(test.id)
def test_get_test_results(self):
test_run_result = self.storage.get_test_results(1)
result = self.storage.get_test_results()
expected = {'type': 'test', 'id': 1, 'stats': self.stats,
'tests': {self.fixture['id']: self.fixture,
}}
self.assertEqual(test_run_result, expected)
self.assertEqual(result.count(), 1)
self.assertEqual(result[0].id, expected['id'])
def test_update_test_run(self):
res = self.storage.update_test_run(1, {'passes': 1})