Summary JSON file

Add support for writing the build summary to a JSON file. This is more
machine-friendly than the current approach of writing to standard output
at the end of the build.

The file is configured via [DEFAULT] summary_json_file.

Change-Id: I9868af5d00977750d0673fc48f8863a99f878dc8
This commit is contained in:
Mark Goddard 2023-04-20 16:32:54 +01:00
parent bc2d3e4ef4
commit a5351473e0
5 changed files with 77 additions and 4 deletions

View File

@ -199,6 +199,10 @@ _CLI_OPTS = [
cfg.StrOpt('format', short='f', default='json',
choices=['json', 'none'],
help='Format to write the final results in.'),
cfg.StrOpt('summary-json-file',
help='Name of a file to write the build summary to when format '
'is json. If unset, the summary will be written to '
'standard output'),
cfg.StrOpt('tarballs-base', default=TARBALLS_BASE,
help='Base url to OpenStack tarballs'),
cfg.IntOpt('threads', short='T', default=8, min=1,

View File

@ -11,7 +11,6 @@
# limitations under the License.
import contextlib
import json
import logging
import queue
import shutil
@ -195,8 +194,6 @@ def run_build():
raise
if conf.summary:
results = kolla.summary()
if conf.format == 'json':
print(json.dumps(results))
kolla.summary()
kolla.cleanup()
return kolla.get_image_statuses()

View File

@ -564,6 +564,26 @@ class KollaWorker(object):
'name': name,
})
if self.conf.format == 'json':
def json_summary(f, **kwargs):
json.dump(results, f, **kwargs)
if self.conf.summary_json_file:
try:
with open(self.conf.summary_json_file, "w") as f:
json_summary(f, indent=4)
except OSError as e:
LOG.error(f'Failed to write JSON build summary to '
'{self.conf.summary_json_file}')
LOG.error(f'Exception caught: {e}')
sys.exit(1)
else:
# NOTE(mgoddard): Keep single line output for
# backwards-compatibility.
json_summary(sys.stdout)
return results
def get_image_statuses(self):

View File

@ -727,6 +727,53 @@ class KollaWorkerTest(base.TestCase):
self.assertEqual('error', results['failed'][0]['status']) # bad
self.assertEqual('error', results['failed'][1]['status']) # bad2
@mock.patch('json.dump')
def test_summary_json_format(self, dump_mock):
self.conf.set_override('format', 'json')
kolla = build.KollaWorker(self.conf)
kolla.images = self.images
kolla.image_statuses_good['good'] = build.Status.BUILT
kolla.image_statuses_bad['bad'] = build.Status.ERROR
kolla.image_statuses_allowed_to_fail['bad2'] = build.Status.ERROR
kolla.image_statuses_unmatched['unmatched'] = build.Status.UNMATCHED
results = kolla.summary()
dump_mock.assert_called_once_with(results, sys.stdout)
@mock.patch('json.dump')
def test_summary_json_format_file(self, dump_mock):
tmpdir = tempfile.mkdtemp()
file_path = os.path.join(tmpdir, 'summary.json')
try:
self.conf.set_override('format', 'json')
self.conf.set_override('summary_json_file', file_path)
kolla = build.KollaWorker(self.conf)
kolla.images = self.images
kolla.image_statuses_good['good'] = build.Status.BUILT
kolla.image_statuses_bad['bad'] = build.Status.ERROR
kolla.image_statuses_allowed_to_fail['bad2'] = build.Status.ERROR
kolla.image_statuses_unmatched['unmatched'] = (
build.Status.UNMATCHED)
results = kolla.summary()
dump_mock.assert_called_once_with(results, mock.ANY, indent=4)
self.assertEqual(dump_mock.call_args[0][1].name, file_path)
finally:
os.remove(file_path)
os.rmdir(tmpdir)
@mock.patch('builtins.open')
def test_summary_json_format_file_error(self, open_mock):
open_mock.side_effect = OSError
self.conf.set_override('format', 'json')
self.conf.set_override('summary_json_file', 'fake-file')
kolla = build.KollaWorker(self.conf)
kolla.images = self.images
kolla.image_statuses_good['good'] = build.Status.BUILT
kolla.image_statuses_bad['bad'] = build.Status.ERROR
kolla.image_statuses_allowed_to_fail['bad2'] = build.Status.ERROR
kolla.image_statuses_unmatched['unmatched'] = (
build.Status.UNMATCHED)
self.assertRaises(SystemExit, kolla.summary)
@mock.patch('shutil.copytree')
def test_work_dir(self, copytree_mock):
self.conf.set_override('work_dir', 'tmp/foo')

View File

@ -0,0 +1,5 @@
---
features:
- |
Adds support for writing the build summary to a JSON file specified via the
``[DEFAULT] summary_json_file`` option.