Skip to content

Commit a535147

Browse files
committed
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
1 parent bc2d3e4 commit a535147

File tree

5 files changed

+77
-4
lines changed

5 files changed

+77
-4
lines changed

kolla/common/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@
199199
cfg.StrOpt('format', short='f', default='json',
200200
choices=['json', 'none'],
201201
help='Format to write the final results in.'),
202+
cfg.StrOpt('summary-json-file',
203+
help='Name of a file to write the build summary to when format '
204+
'is json. If unset, the summary will be written to '
205+
'standard output'),
202206
cfg.StrOpt('tarballs-base', default=TARBALLS_BASE,
203207
help='Base url to OpenStack tarballs'),
204208
cfg.IntOpt('threads', short='T', default=8, min=1,

kolla/image/build.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
# limitations under the License.
1212

1313
import contextlib
14-
import json
1514
import logging
1615
import queue
1716
import shutil
@@ -195,8 +194,6 @@ def run_build():
195194
raise
196195

197196
if conf.summary:
198-
results = kolla.summary()
199-
if conf.format == 'json':
200-
print(json.dumps(results))
197+
kolla.summary()
201198
kolla.cleanup()
202199
return kolla.get_image_statuses()

kolla/image/kolla_worker.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,26 @@ def summary(self):
564564
'name': name,
565565
})
566566

567+
if self.conf.format == 'json':
568+
569+
def json_summary(f, **kwargs):
570+
json.dump(results, f, **kwargs)
571+
572+
if self.conf.summary_json_file:
573+
try:
574+
with open(self.conf.summary_json_file, "w") as f:
575+
json_summary(f, indent=4)
576+
except OSError as e:
577+
LOG.error(f'Failed to write JSON build summary to '
578+
'{self.conf.summary_json_file}')
579+
LOG.error(f'Exception caught: {e}')
580+
sys.exit(1)
581+
582+
else:
583+
# NOTE(mgoddard): Keep single line output for
584+
# backwards-compatibility.
585+
json_summary(sys.stdout)
586+
567587
return results
568588

569589
def get_image_statuses(self):

kolla/tests/test_build.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,53 @@ def test_summary(self):
727727
self.assertEqual('error', results['failed'][0]['status']) # bad
728728
self.assertEqual('error', results['failed'][1]['status']) # bad2
729729

730+
@mock.patch('json.dump')
731+
def test_summary_json_format(self, dump_mock):
732+
self.conf.set_override('format', 'json')
733+
kolla = build.KollaWorker(self.conf)
734+
kolla.images = self.images
735+
kolla.image_statuses_good['good'] = build.Status.BUILT
736+
kolla.image_statuses_bad['bad'] = build.Status.ERROR
737+
kolla.image_statuses_allowed_to_fail['bad2'] = build.Status.ERROR
738+
kolla.image_statuses_unmatched['unmatched'] = build.Status.UNMATCHED
739+
results = kolla.summary()
740+
dump_mock.assert_called_once_with(results, sys.stdout)
741+
742+
@mock.patch('json.dump')
743+
def test_summary_json_format_file(self, dump_mock):
744+
tmpdir = tempfile.mkdtemp()
745+
file_path = os.path.join(tmpdir, 'summary.json')
746+
try:
747+
self.conf.set_override('format', 'json')
748+
self.conf.set_override('summary_json_file', file_path)
749+
kolla = build.KollaWorker(self.conf)
750+
kolla.images = self.images
751+
kolla.image_statuses_good['good'] = build.Status.BUILT
752+
kolla.image_statuses_bad['bad'] = build.Status.ERROR
753+
kolla.image_statuses_allowed_to_fail['bad2'] = build.Status.ERROR
754+
kolla.image_statuses_unmatched['unmatched'] = (
755+
build.Status.UNMATCHED)
756+
results = kolla.summary()
757+
dump_mock.assert_called_once_with(results, mock.ANY, indent=4)
758+
self.assertEqual(dump_mock.call_args[0][1].name, file_path)
759+
finally:
760+
os.remove(file_path)
761+
os.rmdir(tmpdir)
762+
763+
@mock.patch('builtins.open')
764+
def test_summary_json_format_file_error(self, open_mock):
765+
open_mock.side_effect = OSError
766+
self.conf.set_override('format', 'json')
767+
self.conf.set_override('summary_json_file', 'fake-file')
768+
kolla = build.KollaWorker(self.conf)
769+
kolla.images = self.images
770+
kolla.image_statuses_good['good'] = build.Status.BUILT
771+
kolla.image_statuses_bad['bad'] = build.Status.ERROR
772+
kolla.image_statuses_allowed_to_fail['bad2'] = build.Status.ERROR
773+
kolla.image_statuses_unmatched['unmatched'] = (
774+
build.Status.UNMATCHED)
775+
self.assertRaises(SystemExit, kolla.summary)
776+
730777
@mock.patch('shutil.copytree')
731778
def test_work_dir(self, copytree_mock):
732779
self.conf.set_override('work_dir', 'tmp/foo')
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
features:
3+
- |
4+
Adds support for writing the build summary to a JSON file specified via the
5+
``[DEFAULT] summary_json_file`` option.

0 commit comments

Comments
 (0)