Add support for subunit file uploading

This patch allows subunit files to be uploaded to a RefStack
server using the refstack-client. This adds the new command
'upload-subunit'.

Change-Id: Ie8079c66a732da34d08c46664e441723cf904c3a
This commit is contained in:
Paul Van Eck 2015-12-17 10:17:34 -08:00
parent 2c355b84a4
commit 90a79907c5
3 changed files with 97 additions and 5 deletions

View File

@ -97,6 +97,12 @@ We've created an "easy button" for Ubuntu, Centos, RHEL and openSuSe.
`upload` command, you can also override the RefStack API server uploaded to
with the `--url` option.
Alternatively, you can use the 'upload-subunit' command to upload results
using an existing subunit file. This requires that you pass in the Keystone
endpoint URL for the cloud that was tested to generate the subunit data:
`./refstack-client upload-subunit --keystone-endpoint http://some.url:5000/v3 <Path of subunit file>`
**Note:**
a. Adding `-i <path-to-private-key>` option will upload test results with

View File

@ -280,6 +280,12 @@ class RefstackClient:
else:
return inp.lower() in ('yes', 'y')
def _upload_prompt(self, upload_content):
if self._user_query('Test results will be uploaded to %s. '
'Ok?' % self.args.url):
self.post_results(self.args.url, upload_content,
sign_with=self.args.priv_key)
def get_passed_tests(self, result_file):
'''Get a list of tests IDs that passed Tempest from a subunit file.'''
subunit_processor = SubunitProcessor(result_file)
@ -407,10 +413,23 @@ class RefstackClient:
json_file = open(self.upload_file)
json_data = json.load(json_file)
json_file.close()
if self._user_query('Test results will be uploaded to %s. '
'Ok?' % self.args.url):
self.post_results(self.args.url, json_data,
sign_with=self.args.priv_key)
self._upload_prompt(json_data)
def upload_subunit(self):
'''Perform upload to RefStack URL from a subunit file.'''
self._prep_upload()
cpid = self._generate_cpid_from_endpoint(self.args.keystone_endpoint)
# Forgo the duration for direct subunit uploads.
duration = 0
# Formulate JSON from subunit
results = self.get_passed_tests(self.upload_file)
self.logger.info('Number of passed tests in given subunit '
'file: %d ' % len(results))
content = self._form_result_content(cpid, duration, results)
self._upload_prompt(content)
def yield_results(self, url, start_page=1,
start_date='', end_date='', cpid=''):
@ -542,7 +561,7 @@ def parse_cli_args(args=None):
# Upload command
parser_upload = subparsers.add_parser(
'upload', parents=[shared_args, network_args],
help='Upload an existing result file.'
help='Upload an existing result JSON file.'
)
parser_upload.add_argument('file',
@ -551,6 +570,28 @@ def parse_cli_args(args=None):
parser_upload.set_defaults(func="upload")
# Upload-subunit command
parser_subunit_upload = subparsers.add_parser(
'upload-subunit', parents=[shared_args, network_args],
help='Upload results from a subunit file.'
)
parser_subunit_upload.add_argument('file',
type=str,
help='Path of subunit file.')
parser_subunit_upload.add_argument('--keystone-endpoint',
action='store',
required=True,
dest='keystone_endpoint',
type=str,
help='The Keystone URL of the cloud '
'the subunit results belong to. '
'This is used to generate a Cloud '
'Provider ID.')
parser_subunit_upload.set_defaults(func="upload_subunit")
# Test command
parser_test = subparsers.add_parser(
'test', parents=[shared_args, network_args],

View File

@ -551,6 +551,26 @@ class TestRefstackClient(unittest.TestCase):
mock_input.return_value = 'yes'
self.assertTrue(client._user_query('42?'))
def test_upload_prompt(self):
"""
Test the _upload_prompt method.
"""
client = rc.RefstackClient(rc.parse_cli_args(self.mock_argv()))
# When user says yes.
client._user_query = MagicMock(return_value=True)
client.post_results = MagicMock()
client._upload_prompt({'some': 'data'})
client.post_results.assert_called_with(
'http://127.0.0.1', {'some': 'data'}, sign_with=None
)
# When user says no.
client._user_query = MagicMock(return_value=False)
client.post_results = MagicMock()
client._upload_prompt({'some': 'data'})
self.assertFalse(client.post_results.called)
def test_post_results(self):
"""
Test the post_results method, ensuring a requests call is made.
@ -809,6 +829,31 @@ class TestRefstackClient(unittest.TestCase):
expected_json,
sign_with='rsa_key')
def test_subunit_upload(self):
"""
Test that the subunit upload command runs as expected.
"""
upload_file_path = self.test_path + "/.testrepository/0"
args = rc.parse_cli_args(
self.mock_argv(command='upload-subunit', priv_key='rsa_key')
+ ['--keystone-endpoint', 'http://0.0.0.0:5000/v2.0']
+ [upload_file_path])
client = rc.RefstackClient(args)
client.post_results = MagicMock()
client.upload_subunit()
expected_json = {
'duration_seconds': 0,
'cpid': hashlib.md5('0.0.0.0').hexdigest(),
'results': [
{'name': 'tempest.passed.test'},
{'name': 'tempest.tagged_passed.test',
'uuid': '0146f675-ffbd-4208-b3a4-60eb628dbc5e'}
]
}
client.post_results.assert_called_with('http://127.0.0.1',
expected_json,
sign_with='rsa_key')
def test_upload_nonexisting_file(self):
"""
Test when the file to be uploaded does not exist.